diff --git a/src/app/[locale]/pages/violations/[id]/page.tsx b/src/app/[locale]/pages/violations/[id]/page.tsx new file mode 100644 index 0000000..a1be5f4 --- /dev/null +++ b/src/app/[locale]/pages/violations/[id]/page.tsx @@ -0,0 +1,39 @@ +'use client' + +import { useParams } from 'next/navigation' +import ViolationPageTitle from '@/app/ui/violations/file-page/violation-page-title'; +import ViolationPageViolationInfo from '@/app/ui/violations/file-page/violation-page-violation-info'; +import ViolationPpageFileStatistic from '@/app/ui/violations/file-page/violation-page-file-statistic'; +import ViolationPageFileInfo from '@/app/ui/violations/file-page/violation-page-file-info'; +import ViolationPageActions from '@/app/ui/violations/file-page/violation-page-actions'; +import ViolationPageViolationsList from '@/app/ui/violations/file-page/violation-page-violations-list'; +import ViolationPageNote from '@/app/ui/violations/file-page/violation-page-note'; + +/* violation-details */ +export default function Page() { + const params = useParams() + const id = params.id + + return ( +
+ +
+
+ + + +
+
+ + + +
+
+ +
+ ) +} \ No newline at end of file diff --git a/src/app/styles/pages-styles.scss b/src/app/styles/pages-styles.scss index bdeaef7..f8e49a5 100644 --- a/src/app/styles/pages-styles.scss +++ b/src/app/styles/pages-styles.scss @@ -4137,4 +4137,347 @@ } } } +} + +.violation-details { + .page-title-color-frame { + display: flex; + gap: 10px; + + .violation-page-icon { + width: 80px; + height: 80px; + border-radius: 20px; + display: flex; + align-items: center; + justify-content: center; + font-size: 40px; + background: rgba(255, 255, 255, 0.2); + backdrop-filter: blur(10px); + border: 2px solid rgba(255, 255, 255, 0.3); + overflow: hidden; + + .icon { + width: 100%; + height: 100%; + } + } + + .violation-page-info { + display: flex; + gap: 10px; + } + } + + .card-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 20px; + padding-bottom: 15px; + border-bottom: 2px solid #f1f5f9; + } + + .info-row { + display: flex; + justify-content: space-between; + padding: 12px 0; + border-bottom: 1px solid #f8fafc; + } + + .info-label { + color: #64748b; + font-size: 14px; + } + + .info-value { + color: #1e293b; + font-weight: 600; + font-size: 14px; + text-align: right; + } + + .violation-source { + margin-top: 15px; + + &-title { + font-size: 14px; + color: #64748b; + margin-bottom: 8px; + font-weight: 600; + } + + .url-display { + background: #f8fafc; + padding: 12px; + border-radius: 8px; + border: 1px solid #e2e8f0; + margin-top: 10px; + word-break: break-all; + + .url-link { + color: #6366f1; + text-decoration: none; + font-weight: 600; + } + } + } + + .notes-section { + background: #f8fafc; + padding: 15px; + border-radius: 12px; + margin-top: 15px; + border: 1px solid #e2e8f0; + text-align: left; + + .notes-title { + font-size: 14px; + font-weight: 600; + color: #1e293b; + margin-bottom: 10px; + text-align: left; + } + + .notes-content { + font-size: 13px; + color: #475569; + line-height: 1.6; + white-space: pre-line; + max-height: 200px; + overflow-y: auto; + text-align: left; + word-wrap: break-word; + margin: 0; + padding: 0; + } + } + + .stats-mini-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 15px; + margin-bottom: 20px; + + .stat-mini-card { + background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); + padding: 15px; + border-radius: 12px; + text-align: center; + border: 1px solid #e2e8f0; + } + + .stat-mini-value { + font-size: 28px; + font-weight: 700; + color: #1e293b; + margin-bottom: 5px; + } + + .stat-mini-label { + font-size: 12px; + color: #64748b; + } + } + + .action-buttons { + display: flex; + gap: 10px; + flex-wrap: wrap; + + .btn-action { + flex: 1; + min-width: 150px; + padding: 12px 20px; + border-radius: 12px; + font-weight: 600; + border: none; + cursor: pointer; + transition: all 0.3s ease; + font-size: 14px; + } + + .btn-warning { + background: linear-gradient(135deg, #f59e0b, #d97706); + color: white; + + &:hover { + transform: translateY(-2px); + box-shadow: 0 8px 20px rgba(245, 158, 11, 0.4); + } + } + + .btn-success { + background: linear-gradient(135deg, #10b981, #059669); + color: white; + + &:hover { + transform: translateY(-2px); + box-shadow: 0 8px 20px rgba(16, 185, 129, 0.4); + } + } + + .btn-secondary { + background: linear-gradient(135deg, #64748b, #475569); + color: white; + + &:hover { + transform: translateY(-2px); + box-shadow: 0 8px 20px rgba(100, 116, 139, 0.4); + } + } + } + + .btn-small { + padding: 6px 12px; + border-radius: 8px; + font-size: 12px; + font-weight: 600; + border: none; + cursor: pointer; + transition: all 0.3s ease; + text-decoration: none; + display: inline-block; + } + + .btn-primary-small { + background: linear-gradient(135deg, #6366f1, #8b5cf6); + color: white; + + &:hover { + box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4); + } + } + + .btn-secondary-small { + background: #f1f5f9; + color: #64748b; + + &:hover { + background: #e2e8f0; + } + } + + .sources-list { + display: flex; + flex-direction: column; + gap: 15px; + + .source-card { + background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); + border-radius: 12px; + padding: 15px; + border: 1px solid #e2e8f0; + transition: all 0.3s ease; + + &:hover { + transform: translateY(-2px); + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1); + border-color: #cbd5e1; + } + } + + .source-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 10px; + } + + .source-url { + color: #6366f1; + font-weight: 600; + font-size: 14px; + text-decoration: none; + word-break: break-all; + flex: 1; + } + + .source-status { + padding: 4px 10px; + border-radius: 6px; + font-size: 11px; + font-weight: 600; + white-space: nowrap; + margin-left: 10px; + + &.new { + background: #fef2f2; + color: #dc2626; + } + } + + .source-meta { + display: flex; + gap: 15px; + font-size: 12px; + color: #64748b; + margin-bottom: 10px; + flex-wrap: wrap; + } + + .source-actions { + display: flex; + gap: 10px; + flex-wrap: wrap; + margin-top: 10px; + } + } + + .pagination { + margin-top: 20px; + display: flex; + justify-content: center; + gap: 4px; + + &__item { + padding: 8px 12px; + border-radius: 8px; + text-decoration: none; + font-weight: 600; + background: white; + color: #374151; + border: 2px solid #e5e7eb; + transition: all 0.2s ease; + + &:hover { + border-color: #667eea; + } + + &--active { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + border: 2px solid #667eea; + + &:hover { + border-color: #667eea; + } + } + } + } + + .note-form { + margin-top: 0; + border: none; + padding: 0; + background: #f8fafc; + } + + .note-textarea { + width: 100%; + min-height: 80px; + padding: 12px; + border: 1px solid #e2e8f0; + border-radius: 8px; + font-size: 14px; + font-family: inherit; + resize: vertical; + box-sizing: border-box; + + &:focus { + outline: none; + border-color: #6366f1; + box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1); + } + } } \ No newline at end of file diff --git a/src/app/ui/icons/icons.tsx b/src/app/ui/icons/icons.tsx index 6e2f52c..b8a8d65 100644 --- a/src/app/ui/icons/icons.tsx +++ b/src/app/ui/icons/icons.tsx @@ -64,6 +64,16 @@ export function IconEye() { ) } +export function IconEyeDashed() { + return ( + + + + + + ) +} + export function IconDoubleArrowRight() { return ( @@ -186,6 +196,6 @@ export function IconWarning() { export function IconGraph() { return ( - + ) } \ No newline at end of file diff --git a/src/app/ui/violations/file-page/violation-page-actions.tsx b/src/app/ui/violations/file-page/violation-page-actions.tsx new file mode 100644 index 0000000..f4962f0 --- /dev/null +++ b/src/app/ui/violations/file-page/violation-page-actions.tsx @@ -0,0 +1,33 @@ +export default function ViolationPageActions() { + return ( +
+
+

+ Действия +

+
+ +
+
+ +
+ +
+ +
+ +
+ +
+
+
+ ) +} \ No newline at end of file diff --git a/src/app/ui/violations/file-page/violation-page-file-info.tsx b/src/app/ui/violations/file-page/violation-page-file-info.tsx new file mode 100644 index 0000000..f67f2ea --- /dev/null +++ b/src/app/ui/violations/file-page/violation-page-file-info.tsx @@ -0,0 +1,40 @@ +export default function ViolationPageFileInfo() { + return ( +
+
+
+

+ 📄 Информация о файле +

+
+ +
+ Тип файла + fileType +
+
+ Размер + 0 КБ +
+
+ Загружен + 0 +
+
+ Водяной знак + + Применен + +
+
+ Уровень защиты + + Максимальный + +
+
+
+ ) +} \ No newline at end of file diff --git a/src/app/ui/violations/file-page/violation-page-file-statistic.tsx b/src/app/ui/violations/file-page/violation-page-file-statistic.tsx new file mode 100644 index 0000000..e28de7b --- /dev/null +++ b/src/app/ui/violations/file-page/violation-page-file-statistic.tsx @@ -0,0 +1,52 @@ +export default function ViolationPpageFileStatistic() { + return ( +
+
+

+ Статистика по файлу +

+
+ +
+
+
+ 0 +
+
Новых
+
+
+
+ 0 +
+
В работе
+
+
+
+ 0 +
+
Решено
+
+
+
+ 0 +
+
Всего
+
+
+
+ ) +} \ No newline at end of file diff --git a/src/app/ui/violations/file-page/violation-page-note.tsx b/src/app/ui/violations/file-page/violation-page-note.tsx new file mode 100644 index 0000000..4c721c6 --- /dev/null +++ b/src/app/ui/violations/file-page/violation-page-note.tsx @@ -0,0 +1,24 @@ +export default function ViolationPageNote() { + return ( +
+ +
+

+ ✏️ Добавить заметку +

+
+ +
+
+ + + +
+
+
+ ) +} \ No newline at end of file diff --git a/src/app/ui/violations/file-page/violation-page-title.tsx b/src/app/ui/violations/file-page/violation-page-title.tsx new file mode 100644 index 0000000..0c1bcf5 --- /dev/null +++ b/src/app/ui/violations/file-page/violation-page-title.tsx @@ -0,0 +1,43 @@ +import { useTranslations } from 'next-intl'; +import { useParams } from 'next/navigation' +import { IconEyeDashed } from '@/app/ui/icons/icons'; + +export default function ViolationPageTitle() { + const t = useTranslations('Global'); + const params = useParams() + const id = params.id + + return ( +
+
+ +
+
+

+ file id: {id} +

+
+ + fileType + + + + fileSize + + + + fileViolationDate + + + + fileViolationType + +
+
+
+ ) +} \ No newline at end of file diff --git a/src/app/ui/violations/file-page/violation-page-violation-info.tsx b/src/app/ui/violations/file-page/violation-page-violation-info.tsx new file mode 100644 index 0000000..6226146 --- /dev/null +++ b/src/app/ui/violations/file-page/violation-page-violation-info.tsx @@ -0,0 +1,50 @@ +export default function ViolationPageViolationInfo() { + return ( +
+
+

+ Информация о нарушении +

+
+ +
+ Тип нарушения + Неавторизованное использование +
+ +
+ Дата обнаружения + 28.02.2026 07:48 +
+ +
+ Уверенность + 85% +
+ +
+
+ Источник нарушения: +
+
+ + url + +
+
+ +
+
📝 Заметки:
+
+ Заметок пока нет. Вы можете добавить первую заметку ниже. +
+
+
+ ) +} \ No newline at end of file diff --git a/src/app/ui/violations/file-page/violation-page-violations-list.tsx b/src/app/ui/violations/file-page/violation-page-violations-list.tsx new file mode 100644 index 0000000..1dd2ec4 --- /dev/null +++ b/src/app/ui/violations/file-page/violation-page-violations-list.tsx @@ -0,0 +1,52 @@ +export default function ViolationPageViolationsList() { + return ( +
+
+

+ Все нарушения этого файла +

+ + Всего: 0 | Страница 0 из 0 + +
+ + {/* это нужно будет сделать отдельным компонентом */} +
+
+
+ + artdraw.org + + + Новое + +
+
+ 28.02.2026 07:48 + Неавторизованное использование + 85% +
+
+ + Посмотреть + + + Открыть + +
+
+
+ +
+ 1 + 2 + 3 + Следующая +
+
+ ) +} \ No newline at end of file