diff --git a/package.json b/package.json index e7a05ae..1d02bd3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "no-copy-frontend", - "version": "0.2.0", + "version": "0.3.0", "private": true, "scripts": { "dev": "next dev -p 2999", diff --git a/src/app/[locale]/pages/marking-photo/page.tsx b/src/app/[locale]/pages/marking-photo/page.tsx index 9d2b8cf..3d23083 100644 --- a/src/app/[locale]/pages/marking-photo/page.tsx +++ b/src/app/[locale]/pages/marking-photo/page.tsx @@ -2,18 +2,23 @@ import ProtectedFilesTable from '@/app/ui/marking-page/protected-files-table'; import ProtectionSummary from '@/app/ui/marking-page/protection-summary'; import TestSection from '@/app/ui/marking-page/test-section'; import UploadSectionImage from '@/app/ui/marking-page/upload-section-image'; -import { IconImageFile } from '@/app/ui/icons/icons'; +import TanstakFilesTable from '@/app/components/tanstakTable'; +import { useTranslations } from 'next-intl'; export default function Page() { + const t = useTranslations('Global'); return (
-

Защита изображений

+

+ {t('image-protection')} +

- + + {/* */}
) } \ No newline at end of file diff --git a/src/app/components/StackedBarChart.tsx b/src/app/components/StackedBarChart.tsx new file mode 100644 index 0000000..c4ba70f --- /dev/null +++ b/src/app/components/StackedBarChart.tsx @@ -0,0 +1,204 @@ +import { useTranslations } from 'next-intl'; +import { BarChart, Bar, Cell, XAxis, Tooltip } from 'recharts'; + +type Files = { + data: { + name: string, + checks: number, + violations: number + }[] +} + +interface BarShapeProps { + x: number; + y: number; + width: number; + height: number; + fill: string; + radius?: number[]; +} + +export const StackedBarChart = ({ data }: Files) => { + const t = useTranslations('Global'); + + const editedData = data.map(e => { + return { + name: e.name, + checks: e.checks - e.violations, + violations: e.violations + } + }) + + const mainColors = ['#0088FE20', '#00C49F20', '#FFBB2820', '#FF804220', '#FF000020', '#FFC0CB20']; + const secondColors = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042', 'red', 'pink']; + + const strokeColor = "#fff"; + const strokeWidth = 1; + + const renderBarWithPartialBorder = (props: BarShapeProps) => { + const { x, y, width, height, fill } = props; + + return ( + <> + {/* Основной прямоугольник без обводки */} + + + {/* Левая граница */} + + + {/* Правая граница */} + + + {/* Нижняя граница */} + + + ); + }; + + const renderBarWithTopBorder = (props: BarShapeProps) => { + const { x, y, width, height, fill } = props; + const borderRadius = 10; + + if (height <= 0 || width <= 0) return null; + + return ( + <> + {/* Основной прямоугольник с закруглением ТОЛЬКО ВЕРХНИХ углов */} + + + {/* Верхняя граница */} + + + {/* Левая граница */} + + + {/* Правая граница */} + + + {/* Левый верхний закругленный угол */} + + + {/* Правый верхний закругленный угол */} + + + ) as any; + }; + + return ( + + {/* */} + + + {data.map((_entry, index) => ( + + ))} + + + {data.map((_entry, index) => ( + + ))} + + + ); +}; \ No newline at end of file diff --git a/src/app/styles/marking-pages.scss b/src/app/styles/marking-pages.scss index ffd72bc..a36fb5c 100644 --- a/src/app/styles/marking-pages.scss +++ b/src/app/styles/marking-pages.scss @@ -61,19 +61,28 @@ margin-bottom: 20px; transition: all 0.3s ease; + .icon { + width: 70px; + height: 70px; + margin: 0 auto; + color: #6366f1; + } + h4 { color: #6366f1; - margin-bottom: 10px; + margin-bottom: 5px; + font-size: 22px; } .description { color: #6b7280; - margin-bottom: 20px; + margin-bottom: 5px; + text-align: start; } .btn-primary { - background: linear-gradient(45deg, #6566f1, #01579b); - margin-bottom: 20px; + background: linear-gradient(45deg, #6566f1, #5a5ce9); + margin-bottom: 40px; } } diff --git a/src/app/ui/icons/icons.tsx b/src/app/ui/icons/icons.tsx index dd5572d..8840b9c 100644 --- a/src/app/ui/icons/icons.tsx +++ b/src/app/ui/icons/icons.tsx @@ -26,7 +26,17 @@ export function IconAudioFile() { export function IconShield() { return ( - + + + + ) +} + +export function IconShieldAdd() { + return ( + + + ) } diff --git a/src/app/ui/marking-page/protected-files-table.tsx b/src/app/ui/marking-page/protected-files-table.tsx index 987854f..e968f0a 100644 --- a/src/app/ui/marking-page/protected-files-table.tsx +++ b/src/app/ui/marking-page/protected-files-table.tsx @@ -1,3 +1,5 @@ +/* removed */ + import { IconShield, IconDownload } from '@/app/ui/icons/icons'; export default function ProtectedFilesTable() { return ( diff --git a/src/app/ui/marking-page/protection-summary.tsx b/src/app/ui/marking-page/protection-summary.tsx index 30a560b..8bda875 100644 --- a/src/app/ui/marking-page/protection-summary.tsx +++ b/src/app/ui/marking-page/protection-summary.tsx @@ -1,21 +1,92 @@ +'use client' + +import { useState } from 'react'; +import { StackedBarChart } from '@/app/components/StackedBarChart'; +import { useTranslations } from 'next-intl'; + +const data = [ + { + name: 'Page A', + checks: 4000, + violations: 2000 + }, + { + name: 'Page B', + checks: 3000, + violations: 1398 + }, + { + name: 'Page C', + checks: 2000, + violations: 1000 + }, + { + name: 'Page D', + checks: 2780, + violations: 1000 + }, + { + name: 'Page E', + checks: 5090, + violations: 4800 + }, + { + name: 'Page F', + checks: 5390, + violations: 3800 + } +]; + export default function ProtectionSummary() { + const [isOpen, setIsOpen] = useState(false); + const t = useTranslations('Global'); + return ( -
-

Статистика защиты

-
-
-
0
-
Всего файлов
+
+

{t('protecting-your-content')}

+

{t('current-status-of')}

+
+
+
0
+
{t('total-files')}
-
-
0
-
Общий размер
-
-
-
0
-
Проверки/нарушения
+ +
+
0
+
{t('size')}
+ {isOpen ? ( +
+ +
+ ) : ( +
+
0
+
+ {t('size')} +
+
+ )}
+
) } \ No newline at end of file diff --git a/src/app/ui/marking-page/upload-section-image.tsx b/src/app/ui/marking-page/upload-section-image.tsx index 1cf0bf0..fba6005 100644 --- a/src/app/ui/marking-page/upload-section-image.tsx +++ b/src/app/ui/marking-page/upload-section-image.tsx @@ -1,6 +1,7 @@ 'use client' import React, { useRef, useState, useCallback, ChangeEvent, DragEvent } from 'react'; +import {IconShieldAdd} from '@/app/ui/icons/icons'; interface SelectedFile { file: File; @@ -188,11 +189,9 @@ export default function UploadSectionImage() { transition: 'all .2s ease-in-out' }} > +

Перетащите изображения сюда

-

- Размер: 150x150 - 4000x4000 пикселей, форматы: JPG, PNG, GIF, BMP (WEBP НЕ поддерживается) -

- +

или

+

+ Разрешение изображение: 100x100 - 10000x10000 пикселей +

+

+ Размер файла: до 20 МБ +

+

+ Формат файла: JPG, PNG, GIF, BMP (WEBP НЕ поддерживается) +

+ {error && (

❌ {error}

diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index bfddbfb..82831e7 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -53,7 +53,8 @@ "shown": "Shown", "date-filter": "Date filter", "type-filter": "Type filter", - "items-per-page": "Items per page" + "items-per-page": "Items per page", + "image-protection": "Защита изображений" }, "Login-register-form": { "and": "and", diff --git a/src/i18n/messages/ru.json b/src/i18n/messages/ru.json index e4adcc1..041ad37 100644 --- a/src/i18n/messages/ru.json +++ b/src/i18n/messages/ru.json @@ -53,7 +53,8 @@ "shown": "Показано", "date-filter": "Фильтр по дате", "type-filter": "Фильтр по типу", - "items-per-page": "Записей на странице" + "items-per-page": "Записей на странице", + "image-protection": "Защита изображений" }, "Login-register-form": { "and": "и",