This commit is contained in:
smanylov
2025-12-18 17:21:18 +07:00
parent a538fe1684
commit 7540dd57de
8 changed files with 201 additions and 46 deletions
@@ -18,8 +18,10 @@ export default function Page() {
<h1 className="page-title"> <h1 className="page-title">
{t("statistics")} {t("statistics")}
</h1> </h1>
<div className="flex justify-between flex-wrap gap-8">
<ProtectionOverview /> <ProtectionOverview />
<StatsGrid /> <StatsGrid />
</div>
<FilesTable /> <FilesTable />
</Suspense> </Suspense>
</div> </div>
+32
View File
@@ -0,0 +1,32 @@
import React, { ReactNode } from 'react';
interface ModalWindowtProps {
children: ReactNode;
state: boolean;
callBack: (value: boolean) => void;
}
export default function ModalWindow({ children, state, callBack }: ModalWindowtProps) {
console.log(state);
return (
<>
{state && (
<div
className="modal-wrapper"
onClick={() => {
callBack(false);
}}
>
<div
className="modal-window"
onClick={(e) => e.stopPropagation()}
>
{children}
</div>
</div>
)
}
</>
)
}
+22
View File
@@ -126,3 +126,25 @@
margin: 0 auto; margin: 0 auto;
} }
} }
.modal-wrapper {
position: fixed;
z-index: 101;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: #0000007a;
.modal-window {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 20px;
background: #fff;
color: #000;
border-radius: 20px;
box-shadow: rgba(0, 0, 0, 0.08) 0px 4px 20px;
}
}
+47 -2
View File
@@ -112,6 +112,10 @@
font-size: 28px; font-size: 28px;
font-weight: 700; font-weight: 700;
margin-bottom: 5px; margin-bottom: 5px;
&.btn {
user-select: none;
}
} }
&-label { &-label {
@@ -136,6 +140,38 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
&-drop-down-list {
position: absolute;
left: 80%;
top: 50%;
max-height: 0;
color: #fff;
font-size: 16px;
border-radius: 20px;
padding: 0;
border: none;
width: 200px;
z-index: 1;
font-weight: 500;
background: #ffffff00;
overflow: hidden;
transition: all 0.5s ease;
transform: translateY(-50%);
&.opened {
max-height: 500px;
padding: 20px;
box-shadow: 0 4px 20px #ffffff34;
background: #7165b6;
}
a:hover {
font-size: 17px;
transition: all 0.3s ease;
}
}
} }
&-switch { &-switch {
@@ -156,6 +192,8 @@
display: grid; display: grid;
grid-template-columns: repeat(5, 1fr); grid-template-columns: repeat(5, 1fr);
--boder-collor: #f3f4f6; --boder-collor: #f3f4f6;
border-bottom: 1px solid var(--boder-collor);
align-items: center;
.stats-item.images { .stats-item.images {
--card-color-1: #f08c00; --card-color-1: #f08c00;
@@ -199,8 +237,8 @@
} }
} }
&.last-row { &.second-row {
border-bottom: 1px solid var(--boder-collor); border-top: none;
} }
&.left-top-corner { &.left-top-corner {
@@ -652,3 +690,10 @@
margin-left: 5px; margin-left: 5px;
} }
} }
.page-row {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 20px;
}
+52 -2
View File
@@ -1,8 +1,10 @@
'use client' 'use client'
import { useState } from 'react'; import { useState, useRef } from 'react';
import { PieChartComponent } from '@/app/components/PieChartComponent'; import { PieChartComponent } from '@/app/components/PieChartComponent';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import Link from 'next/link';
import { useClickOutside } from '@/app/hooks/useClickOutside';
const data = [ const data = [
@@ -11,15 +13,27 @@ const data = [
{ name: 'audios', value: 25, color: '#1971c2' }, { name: 'audios', value: 25, color: '#1971c2' },
]; ];
/* нужно что бы включать выключать кнопки добавления маркировок */
const totalFiles = 1;
export default function ProtectionOverview() { export default function ProtectionOverview() {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const t = useTranslations('Global'); const t = useTranslations('Global');
const [openDropDownList, setOpenDropDownList] = useState(false);
const dropDownList = useRef(null);
useClickOutside(dropDownList, () => {
setOpenDropDownList(false)
});
return ( return (
<div className="protection-overview"> <div className="protection-overview grow">
<h3>{t('protecting-your-content')}</h3> <h3>{t('protecting-your-content')}</h3>
<p>{t('current-status-of')}</p> <p>{t('current-status-of')}</p>
<div className={`protection-stats ${isOpen ? "opened" : ""}`}> <div className={`protection-stats ${isOpen ? "opened" : ""}`}>
{totalFiles ? (
<>
<div className="protection-stat total-files"> <div className="protection-stat total-files">
<div className="protection-stat-value">0</div> <div className="protection-stat-value">0</div>
<div className="protection-stat-label">{t('total-files')}</div> <div className="protection-stat-label">{t('total-files')}</div>
@@ -35,6 +49,40 @@ export default function ProtectionOverview() {
<div className="protection-stat-label">{t('violations')}</div> <div className="protection-stat-label">{t('violations')}</div>
</div> </div>
</div> </div>
</>
) : (
<div className="protection-stat total-files relative">
<div className="protection-stat-label">
{t('there-are-no-files-yet')}
</div>
<div
className="protection-stat-value btn"
onClick={() => {
setOpenDropDownList(!openDropDownList);
}}
ref={dropDownList}
>
{t('add')}
<div
className={`protection-stat-drop-down-list ${openDropDownList ? 'opened' : ''}`}
>
<div
className="flex flex-col text-center"
>
<Link href='/pages/marking-photo'>
{t('photo-marking')}
</Link>
<Link href='/pages/marking-video'>
{t('video-marking')}
</Link>
<Link href='/pages/marking-audio'>
{t('audio-marking')}
</Link>
</div>
</div>
</div>
</div>
)}
{isOpen ? ( {isOpen ? (
<div className="protection-stat total-usage"> <div className="protection-stat total-usage">
<PieChartComponent data={data} /> <PieChartComponent data={data} />
@@ -48,6 +96,7 @@ export default function ProtectionOverview() {
</div> </div>
)} )}
</div> </div>
{!!totalFiles && (
<button <button
className="protection-overview-switch cursor-pointer" className="protection-overview-switch cursor-pointer"
onClick={() => { onClick={() => {
@@ -67,6 +116,7 @@ export default function ProtectionOverview() {
/> />
</svg> </svg>
</button> </button>
)}
</div> </div>
) )
} }
+6 -6
View File
@@ -4,7 +4,7 @@ export default function StatsGrid() {
const t = useTranslations("Global"); const t = useTranslations("Global");
return ( return (
<div className="block-wrapper stats-wrapper"> <div className="block-wrapper stats-wrapper grow">
<h3> <h3>
{t('your-content')} {t('your-content')}
</h3> </h3>
@@ -25,20 +25,20 @@ export default function StatsGrid() {
{t('checks')} {t('checks')}
</div> </div>
<div className="stats-item first-column images"> <div className="stats-item first-column second-row images">
<IconImageFile /> <IconImageFile />
{t('images')} {t('images')}
</div> </div>
<div className="stats-item"> <div className="stats-item second-row">
0 0
</div> </div>
<div className="stats-item"> <div className="stats-item second-row">
0 0
</div> </div>
<div className="stats-item"> <div className="stats-item second-row">
0 0
</div> </div>
<div className="stats-item last-column"> <div className="stats-item second-row last-column">
0 0
</div> </div>
+3 -1
View File
@@ -114,7 +114,9 @@
"added": "Added", "added": "Added",
"no-data": "No data", "no-data": "No data",
"view-all": "View all", "view-all": "View all",
"days-ago": "days ago" "days-ago": "days ago",
"there-are-no-files-yet": "There are no files yet",
"add": "Add"
}, },
"Login-register-form": { "Login-register-form": {
"and": "and", "and": "and",
+3 -1
View File
@@ -114,7 +114,9 @@
"added": "Добавлено", "added": "Добавлено",
"no-data": "Нет данных", "no-data": "Нет данных",
"view-all": "Посмотреть все", "view-all": "Посмотреть все",
"days-ago": "дней назад" "days-ago": "дней назад",
"there-are-no-files-yet": "Файлов пока нет",
"add": "Добавить"
}, },
"Login-register-form": { "Login-register-form": {
"and": "и", "and": "и",