develop
This commit is contained in:
@@ -3,7 +3,7 @@ import { Suspense } from 'react';
|
||||
import ProtectionOverview from '@/app/ui/dashboard/protection-overview';
|
||||
import StatsGrid from '@/app/ui/dashboard/stats-grid';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import FilesTable from '@/app/ui/dashboard/files-table';
|
||||
import FilesTable from '@/app/ui/dashboard/files-table';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Dashboard',
|
||||
@@ -18,8 +18,10 @@ export default function Page() {
|
||||
<h1 className="page-title">
|
||||
{t("statistics")}
|
||||
</h1>
|
||||
<ProtectionOverview />
|
||||
<StatsGrid />
|
||||
<div className="flex justify-between flex-wrap gap-8">
|
||||
<ProtectionOverview />
|
||||
<StatsGrid />
|
||||
</div>
|
||||
<FilesTable />
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -125,4 +125,26 @@
|
||||
max-width: 500px;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -112,6 +112,10 @@
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 5px;
|
||||
|
||||
&.btn {
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-label {
|
||||
@@ -136,6 +140,38 @@
|
||||
display: flex;
|
||||
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 {
|
||||
@@ -156,6 +192,8 @@
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
--boder-collor: #f3f4f6;
|
||||
border-bottom: 1px solid var(--boder-collor);
|
||||
align-items: center;
|
||||
|
||||
.stats-item.images {
|
||||
--card-color-1: #f08c00;
|
||||
@@ -199,8 +237,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.last-row {
|
||||
border-bottom: 1px solid var(--boder-collor);
|
||||
&.second-row {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
&.left-top-corner {
|
||||
@@ -651,4 +689,11 @@
|
||||
font-weight: bold;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.page-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useState, useRef } from 'react';
|
||||
import { PieChartComponent } from '@/app/components/PieChartComponent';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import Link from 'next/link';
|
||||
import { useClickOutside } from '@/app/hooks/useClickOutside';
|
||||
|
||||
|
||||
const data = [
|
||||
@@ -11,30 +13,76 @@ const data = [
|
||||
{ name: 'audios', value: 25, color: '#1971c2' },
|
||||
];
|
||||
|
||||
/* нужно что бы включать выключать кнопки добавления маркировок */
|
||||
const totalFiles = 1;
|
||||
|
||||
export default function ProtectionOverview() {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const t = useTranslations('Global');
|
||||
const [openDropDownList, setOpenDropDownList] = useState(false);
|
||||
const dropDownList = useRef(null);
|
||||
useClickOutside(dropDownList, () => {
|
||||
setOpenDropDownList(false)
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="protection-overview">
|
||||
<div className="protection-overview grow">
|
||||
<h3>{t('protecting-your-content')}</h3>
|
||||
<p>{t('current-status-of')}</p>
|
||||
<div className={`protection-stats ${isOpen ? "opened" : ""}`}>
|
||||
<div className="protection-stat total-files">
|
||||
<div className="protection-stat-value">0</div>
|
||||
<div className="protection-stat-label">{t('total-files')}</div>
|
||||
</div>
|
||||
|
||||
<div className="protection-stat total-checks">
|
||||
<div className="protection-stat-row">
|
||||
<div className="protection-stat-value">0</div>
|
||||
<div className="protection-stat-label">{t('check')}</div>
|
||||
|
||||
{totalFiles ? (
|
||||
<>
|
||||
<div className="protection-stat total-files">
|
||||
<div className="protection-stat-value">0</div>
|
||||
<div className="protection-stat-label">{t('total-files')}</div>
|
||||
</div>
|
||||
|
||||
<div className="protection-stat total-checks">
|
||||
<div className="protection-stat-row">
|
||||
<div className="protection-stat-value">0</div>
|
||||
<div className="protection-stat-label">{t('check')}</div>
|
||||
</div>
|
||||
<div className="protection-stat-row">
|
||||
<div className="protection-stat-value">0</div>
|
||||
<div className="protection-stat-label">{t('violations')}</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>
|
||||
<div className="protection-stat-row">
|
||||
<div className="protection-stat-value">0</div>
|
||||
<div className="protection-stat-label">{t('violations')}</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{isOpen ? (
|
||||
<div className="protection-stat total-usage">
|
||||
<PieChartComponent data={data} />
|
||||
@@ -48,25 +96,27 @@ export default function ProtectionOverview() {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
className="protection-overview-switch cursor-pointer"
|
||||
onClick={() => {
|
||||
setIsOpen(!isOpen);
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
className={`w-5 h-5 ml-2 transition-transform ${isOpen ? 'rotate-180' : ''}`}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
{!!totalFiles && (
|
||||
<button
|
||||
className="protection-overview-switch cursor-pointer"
|
||||
onClick={() => {
|
||||
setIsOpen(!isOpen);
|
||||
}}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<svg
|
||||
className={`w-5 h-5 ml-2 transition-transform ${isOpen ? 'rotate-180' : ''}`}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -4,7 +4,7 @@ export default function StatsGrid() {
|
||||
const t = useTranslations("Global");
|
||||
|
||||
return (
|
||||
<div className="block-wrapper stats-wrapper">
|
||||
<div className="block-wrapper stats-wrapper grow">
|
||||
<h3>
|
||||
{t('your-content')}
|
||||
</h3>
|
||||
@@ -25,20 +25,20 @@ export default function StatsGrid() {
|
||||
{t('checks')}
|
||||
</div>
|
||||
|
||||
<div className="stats-item first-column images">
|
||||
<div className="stats-item first-column second-row images">
|
||||
<IconImageFile />
|
||||
{t('images')}
|
||||
</div>
|
||||
<div className="stats-item">
|
||||
<div className="stats-item second-row">
|
||||
0
|
||||
</div>
|
||||
<div className="stats-item">
|
||||
<div className="stats-item second-row">
|
||||
0
|
||||
</div>
|
||||
<div className="stats-item">
|
||||
<div className="stats-item second-row">
|
||||
0
|
||||
</div>
|
||||
<div className="stats-item last-column">
|
||||
<div className="stats-item second-row last-column">
|
||||
0
|
||||
</div>
|
||||
|
||||
|
||||
@@ -114,7 +114,9 @@
|
||||
"added": "Added",
|
||||
"no-data": "No data",
|
||||
"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": {
|
||||
"and": "and",
|
||||
|
||||
@@ -114,7 +114,9 @@
|
||||
"added": "Добавлено",
|
||||
"no-data": "Нет данных",
|
||||
"view-all": "Посмотреть все",
|
||||
"days-ago": "дней назад"
|
||||
"days-ago": "дней назад",
|
||||
"there-are-no-files-yet": "Файлов пока нет",
|
||||
"add": "Добавить"
|
||||
},
|
||||
"Login-register-form": {
|
||||
"and": "и",
|
||||
|
||||
Reference in New Issue
Block a user