change match table styles and notification styles

This commit is contained in:
smanylov
2026-04-16 17:07:14 +07:00
parent 365aeded43
commit 839dd8cf94
14 changed files with 247 additions and 146 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "no-copy-frontend", "name": "no-copy-frontend",
"version": "0.89.0", "version": "0.90.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev -p 2999", "dev": "next dev -p 2999",
+35
View File
@@ -159,6 +159,41 @@
} }
} }
.btn,
.btn-s,
.btn-m {
border: none;
cursor: pointer;
font-weight: 600;
transition: all 0.3s;
text-decoration: none;
display: inline-flex;
align-items: center;
justify-content: center;
&:disabled {
opacity: 0.5;
}
}
.btn {
padding: 12px 24px;
font-size: 14px;
border-radius: 10px;
}
.btn-s {
padding: 6px 12px;
font-size: 12px;
border-radius: 6px;
}
.btn-l {
padding: 16px 32px;
font-size: 16px;
border-radius: 12px;
}
.btn-primary { .btn-primary {
background: linear-gradient(135deg, v.$p-color, v.$s-color); background: linear-gradient(135deg, v.$p-color, v.$s-color);
color: v.$white; color: v.$white;
+3 -1
View File
@@ -170,7 +170,7 @@
&-item { &-item {
display: flex; display: flex;
gap: 4px; gap: 0px;
padding: 10px 14px; padding: 10px 14px;
border-bottom: 1px solid v.$b-color-1; border-bottom: 1px solid v.$b-color-1;
transition: background-color 0.2s; transition: background-color 0.2s;
@@ -216,6 +216,8 @@
cursor: pointer; cursor: pointer;
height: max-content; height: max-content;
color: v.$p-color; color: v.$p-color;
align-self: start;
padding-top: 5px;
svg { svg {
fill: v.$p-color; fill: v.$p-color;
+1 -2
View File
@@ -28,8 +28,7 @@ $color-document: #a561e6;
$status-new: #fab005; $status-new: #fab005;
$status-showed: #5a6e8a; $status-showed: #5a6e8a;
/* $status-in-work: #3b82f6; */ $status-in-work: #3b82f6;
$status-in-work: #6366f1;
$authorized-use: #2ecc71; $authorized-use: #2ecc71;
:root { :root {
+72 -67
View File
@@ -141,26 +141,7 @@
} }
} }
.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;
&:disabled {
opacity: 0.6;
}
}
.btn-primary-small { .btn-primary-small {
/* background: linear-gradient(135deg, #6366f1, #8b5cf6);
color: white; */
border: 2px solid v.$status-in-work; border: 2px solid v.$status-in-work;
color: v.$status-in-work; color: v.$status-in-work;
@@ -216,7 +197,7 @@
&.selected { &.selected {
opacity: 1; opacity: 1;
border: 1px solid #6366f1; border-color: #cbd5e1;
background: linear-gradient(180deg, #ffffff 0%, #e6eaf3 100%); background: linear-gradient(180deg, #ffffff 0%, #e6eaf3 100%);
} }
} }
@@ -251,6 +232,7 @@
border-radius: 8px; border-radius: 8px;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
box-shadow: 4px 4px 7px v.$bg-darkening;
img { img {
object-fit: contain; object-fit: contain;
@@ -264,7 +246,7 @@
} }
.source-url { .source-url {
color: v.$status-in-work; color: #000;
font-weight: 600; font-weight: 600;
font-size: 14px; font-size: 14px;
text-decoration: none; text-decoration: none;
@@ -286,6 +268,22 @@
gap: 10px; gap: 10px;
flex-wrap: wrap; flex-wrap: wrap;
margin-top: auto; margin-top: auto;
a {
font-weight: 600;
&:hover {
text-decoration: underline;
}
}
svg {
fill: #64748b;
&:hover {
fill: #000;
}
}
} }
} }
} }
@@ -330,23 +328,6 @@
} }
} }
.btn-action {
flex: 1;
width: 100%;
padding: 12px 20px;
border-radius: 12px;
font-weight: 600;
border: none;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
max-width: 300px;
&:disabled {
opacity: 0.5;
}
}
.btn-case { .btn-case {
background: linear-gradient(135deg, #6366f1, #8b5cf6); background: linear-gradient(135deg, #6366f1, #8b5cf6);
color: white; color: white;
@@ -358,10 +339,6 @@
} }
.btn-resolve { .btn-resolve {
/* background: linear-gradient(135deg, #10b981, #059669); */
/* background: #10b981;
color: white; */
padding: 12px 30px;
white-space: nowrap; white-space: nowrap;
color: #10b981; color: #10b981;
border: 2px solid #10b981; border: 2px solid #10b981;
@@ -410,7 +387,8 @@
} }
&-title { &-title {
border-bottom: 1px solid v.$border-color-1; /* border-bottom: 1px solid v.$border-color-1; */
font-size: 18px;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 5px; margin-bottom: 5px;
@@ -432,6 +410,7 @@
background: #f5f5f5; background: #f5f5f5;
border-radius: 8px; border-radius: 8px;
overflow: hidden; overflow: hidden;
box-shadow: 4px 4px 10px v.$bg-darkening;
img { img {
width: 100%; width: 100%;
@@ -475,6 +454,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
padding-left: 16px;
/* gap: 10px; */ /* gap: 10px; */
} }
@@ -485,15 +465,31 @@
margin-right: 5px; margin-right: 5px;
} }
a { .source {
color: v.$p-color; color: #000;
word-break: break-all; word-break: break-all;
font-weight: 500; font-weight: 500;
}
}
&-icon {
svg {
display: inline;
width: 20px;
height: 20px;
margin-left: 3px;
fill: v.$text-s;
cursor: pointer;
padding-bottom: 4px;
&:hover { &:hover {
text-decoration: underline; fill: #000;
} }
} }
&.hiden {
display: none;
}
} }
&-status { &-status {
@@ -514,7 +510,7 @@
font-weight: 600; font-weight: 600;
div { div {
color: v.$p-color; color: #000;
} }
} }
@@ -535,6 +531,8 @@
&-header { &-header {
flex-shrink: 0; flex-shrink: 0;
padding-bottom: 5px; padding-bottom: 5px;
padding-right: 16px;
padding-left: 10px;
border-bottom: 1px solid rgb(226, 232, 240); border-bottom: 1px solid rgb(226, 232, 240);
&-grid { &-grid {
@@ -580,6 +578,7 @@
.btn { .btn {
min-width: 180px; min-width: 180px;
background: v.$status-showed;
} }
} }
} }
@@ -644,6 +643,17 @@
background: v.$status-in-work; background: v.$status-in-work;
} }
&.action {
color: v.$status-showed;
border: 2px solid v.$status-showed;
}
&.action.active {
color: v.$white;
border: 2px solid v.$status-showed;
background: v.$status-showed;
}
} }
} }
@@ -737,17 +747,24 @@
&:first-child { &:first-child {
font-weight: 700; font-weight: 700;
color: v.$p-color; color: v.$status-in-work;
.complaint-details-header { .complaint-details-header {
background-color: #fff; background-color: #fff;
} }
} }
&:nth-child(even) {
background-color: v.$b-color-1;
}
&:nth-child(odd) {
background-color: #fff;
}
} }
&-header { &-header {
background-color: #f8f9fa; /* background-color: v.$b-color-1; */
background-color: v.$b-color-1;
padding: 10px 16px; padding: 10px 16px;
border-bottom: 1px solid #e9ecef; border-bottom: 1px solid #e9ecef;
} }
@@ -756,19 +773,10 @@
color: #495057; color: #495057;
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
text-transform: uppercase; /* text-transform: uppercase; */
letter-spacing: 0.5px; letter-spacing: 0.5px;
} }
&-content {
padding: 12px 16px;
color: #212529;
font-size: 15px;
font-weight: 400;
line-height: 1.5;
background-color: #ffffff;
}
strong { strong {
font-weight: 600; font-weight: 600;
color: #212529; color: #212529;
@@ -796,10 +804,9 @@
.note-textarea { .note-textarea {
width: 100%; width: 100%;
min-height: 80px; min-height: 80px;
padding: 12px; padding: 10px 20px;
border: 1px solid v.$border-color-1; border: 1px solid v.$border-color-1;
border-radius: 8px; border-radius: 8px;
font-size: 14px;
font-family: inherit; font-family: inherit;
resize: vertical; resize: vertical;
box-sizing: border-box; box-sizing: border-box;
@@ -807,8 +814,7 @@
&:focus { &:focus {
outline: none; outline: none;
border-color: #6366f1; box-shadow: 2px 2px 4px v.$shadow-1;
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
} }
&-wrapper { &-wrapper {
@@ -829,7 +835,7 @@
border-radius: 8px; border-radius: 8px;
box-sizing: border-box; box-sizing: border-box;
background: #f8fafc; background: #f8fafc;
padding: 5px; padding: 10px 20px;
&::-webkit-outer-spin-button, &::-webkit-outer-spin-button,
&::-webkit-inner-spin-button { &::-webkit-inner-spin-button {
@@ -839,8 +845,7 @@
&:focus { &:focus {
outline: none; outline: none;
border-color: #6366f1; box-shadow: 2px 2px 4px v.$shadow-1;
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
} }
&::placeholder { &::placeholder {
+1 -1
View File
@@ -14,7 +14,7 @@ export default function FilePageNote() {
<form method="POST"> <form method="POST">
<input type="hidden" name="action" value="add_note" /> <input type="hidden" name="action" value="add_note" />
<textarea name="note" className="note-textarea" placeholder="Добавить заметку к этому нарушению..." ></textarea> <textarea name="note" className="note-textarea" placeholder="Добавить заметку к этому нарушению..." ></textarea>
<button type="submit" className="btn-small btn-primary-small"> <button type="submit" className="btn-s btn-primary-small">
Сохранить заметку Сохранить заметку
</button> </button>
</form> </form>
@@ -86,10 +86,16 @@ export default function CaseComplaint({ selectedViolation, updateStatusHandler }
<div className="note-form"> <div className="note-form">
<form action={formAction}> <form action={formAction}>
<input type="hidden" name="violationId" value={localViolation.id} /> <input type="hidden" name="violationId" value={localViolation.id} />
<label
className="note-case-label"
htmlFor="note"
>
{t('text-of-the-complaint')}
</label>
<textarea <textarea
name="note" name="note"
className="note-textarea" className="note-textarea"
placeholder={`${t('text-of-the-complaint')}...`} placeholder={`${t('text-area-error-fill-complaint-text')}...`}
value={noteText} value={noteText}
onChange={(e) => setNoteText(e.target.value)} onChange={(e) => setNoteText(e.target.value)}
> >
@@ -99,7 +105,7 @@ export default function CaseComplaint({ selectedViolation, updateStatusHandler }
> >
<button <button
type="submit" type="submit"
className="btn-small btn-primary-small" className="btn-s btn-primary-small"
disabled={isPending} disabled={isPending}
onClick={(e) => { onClick={(e) => {
e.preventDefault(); e.preventDefault();
@@ -110,7 +116,7 @@ export default function CaseComplaint({ selectedViolation, updateStatusHandler }
<button <button
type="submit" type="submit"
className="btn-small btn-primary-small" className="btn-s btn-primary-small"
disabled={isPending} disabled={isPending}
> >
{t('submit-violation')} {t('submit-violation')}
@@ -262,40 +268,35 @@ export default function CaseComplaint({ selectedViolation, updateStatusHandler }
<div className="complaint-details"> <div className="complaint-details">
<div className="complaint-details-item"> <div className="complaint-details-item">
<div className="complaint-details-header"> <div className="complaint-details-header">
<h5>ID: {item.id}</h5> <h5>COM-{item.id}</h5>
</div> </div>
</div> </div>
<div className="complaint-details-item"> <div className="complaint-details-item">
<div className="complaint-details-header"> <div className="complaint-details-header">
<span className="complaint-details-title">{t('status')}:</span> <span className="complaint-details-title">{t('Status')}:</span> {item.status}
</div>
<div className="complaint-details-content">{item.status}</div>
</div>
<div className="complaint-details-item">
<div className="complaint-details-header">
<span className="complaint-details-title">{t('date-of-creation')}:</span>
</div>
<div className="complaint-details-content">
{item.created_at ? `${formatDate(item.created_at)}: ${formatDateTime(item.created_at)}` : '---'}
</div> </div>
</div> </div>
<div className="complaint-details-item"> <div className="complaint-details-item">
<div className="complaint-details-header"> <div className="complaint-details-header">
<span className="complaint-details-title">{t('date-of-update')}:</span> <span className="complaint-details-title">{t('date-of-creation')}: {item.created_at ? `${formatDate(item.created_at)}: ${formatDateTime(item.created_at)}` : '---'}</span>
</div>
<div className="complaint-details-content">
{item.updated_at ? `${formatDate(item.updated_at)}: ${formatDateTime(item.updated_at)}` : '---'}
</div> </div>
</div> </div>
<div className="complaint-details-item"> <div className="complaint-details-item">
<div className="complaint-details-header"> <div className="complaint-details-header">
<span className="complaint-details-title">{t('text-of-the-complaint')}:</span> <span className="complaint-details-title">{t('date-of-update')}: {item.updated_at ? `${formatDate(item.updated_at)}: ${formatDateTime(item.updated_at)}` : '---'}</span>
</div>
</div>
<div className="complaint-details-item">
<div className="complaint-details-header">
<span className="complaint-details-title">{t('text-of-the-complaint')}:
<br />
{item.complaint_text}
</span>
</div> </div>
<div className="complaint-details-content">{item.complaint_text}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -149,6 +149,12 @@ export default function CaseViolation({ selectedViolation, updateStatusHandler }
<section <section
className="note-textarea-wrapper" className="note-textarea-wrapper"
> >
<label
className="note-case-label"
htmlFor="note"
>
{t('text-of-the-case')}
</label>
<textarea <textarea
name="note" name="note"
className="note-textarea" className="note-textarea"
@@ -177,7 +183,7 @@ export default function CaseViolation({ selectedViolation, updateStatusHandler }
> >
<button <button
type="submit" type="submit"
className="btn-small btn-primary-small" className="btn-s btn-primary-small"
disabled={isPending} disabled={isPending}
> >
{t('submit-violation')} {t('submit-violation')}
@@ -220,48 +226,41 @@ export default function CaseViolation({ selectedViolation, updateStatusHandler }
<div className="complaint-details-item"> <div className="complaint-details-item">
<div className="complaint-details-header"> <div className="complaint-details-header">
<span className="complaint-details-title">{t('status')}:</span> <span className="complaint-details-title">{t('Status')}: {item.type}</span>
</div>
<div className="complaint-details-content">{item.type}</div>
</div>
<div className="complaint-details-item">
<div className="complaint-details-header">
<span className="complaint-details-title">{t('date-of-creation')}:</span>
</div>
<div className="complaint-details-content">
{item.createdAt ? `${formatDate(item.createdAt)}: ${formatDateTime(item.createdAt)}` : '---'}
</div> </div>
</div> </div>
<div className="complaint-details-item"> <div className="complaint-details-item">
<div className="complaint-details-header"> <div className="complaint-details-header">
<span className="complaint-details-title">{t('date-of-update')}:</span> <span className="complaint-details-title">{t('date-of-creation')}: {item.createdAt ? `${formatDate(item.createdAt)}: ${formatDateTime(item.createdAt)}` : '---'}</span>
</div>
<div className="complaint-details-content">
{item.updatedAt ? `${formatDate(item.updatedAt)}: ${formatDateTime(item.updatedAt)}` : '---'}
</div> </div>
</div> </div>
<div className="complaint-details-item"> <div className="complaint-details-item">
<div className="complaint-details-header"> <div className="complaint-details-header">
<span className="complaint-details-title">{t('description')}:</span> <span className="complaint-details-title">{t('date-of-update')}: {item.updatedAt ? `${formatDate(item.updatedAt)}: ${formatDateTime(item.updatedAt)}` : '---'}</span>
</div> </div>
<div className="complaint-details-content">{item.description}</div>
</div> </div>
<div className="complaint-details-item"> <div className="complaint-details-item">
<div className="complaint-details-header"> <div className="complaint-details-header">
<span className="complaint-details-title">{t('amount-of-damage')}:</span> <span className="complaint-details-title">{t('amount-of-damage')}: {item.amount}</span>
</div> </div>
<div className="complaint-details-content">{item.amount}</div>
</div> </div>
<div className="complaint-details-item"> <div className="complaint-details-item">
<div className="complaint-details-header"> <div className="complaint-details-header">
<span className="complaint-details-title">{t('lawyer')}:</span> <span className="complaint-details-title">{t('lawyer')}: {item.lawyer}</span>
</div>
</div>
<div className="complaint-details-item">
<div className="complaint-details-header">
<span className="complaint-details-title">{t('description')}:
<br />
{item.description}
</span>
</div> </div>
<div className="complaint-details-content">{item.lawyer}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -68,13 +68,13 @@ export default function FilePageViolationInfoTabs({ selectedViolation, updateSta
<div className="violation-info-tabs-wrapper"> <div className="violation-info-tabs-wrapper">
<div className="violation-info-tabs"> <div className="violation-info-tabs">
<button <button
className={`btn btn-primary ${activeTab === 'complaint' ? 'active' : ''}`} className={`btn-s btn-primary ${activeTab === 'complaint' ? 'active' : ''} ${localViolation.status === 'COMPLAINT_IN_WORK' || localViolation.status === 'COMPLAINT_AND_LEGAL_IN_WORK' ? '' : 'action'}`}
onClick={() => setActiveTab('complaint')} onClick={() => setActiveTab('complaint')}
> >
{localViolation.status === 'COMPLAINT_IN_WORK' || localViolation.status === 'COMPLAINT_AND_LEGAL_IN_WORK' ? 'Жалоба' : 'Подать жалобу'} {localViolation.status === 'COMPLAINT_IN_WORK' || localViolation.status === 'COMPLAINT_AND_LEGAL_IN_WORK' ? 'Жалоба' : 'Подать жалобу'}
</button> </button>
<button <button
className={`btn btn-primary ${activeTab === 'legal' ? 'active' : ''}`} className={`btn-s btn-primary ${activeTab === 'legal' ? 'active' : ''} ${localViolation.status === 'LEGAL_IN_WORK' || localViolation.status === 'COMPLAINT_AND_LEGAL_IN_WORK' ? '' : 'action'}`}
onClick={() => setActiveTab('legal')} onClick={() => setActiveTab('legal')}
> >
{localViolation.status === 'LEGAL_IN_WORK' || localViolation.status === 'COMPLAINT_AND_LEGAL_IN_WORK' ? 'Претензия' : 'Подать претензию'} {localViolation.status === 'LEGAL_IN_WORK' || localViolation.status === 'COMPLAINT_AND_LEGAL_IN_WORK' ? 'Претензия' : 'Подать претензию'}
@@ -15,6 +15,7 @@ import FilePageViolationEpmtyScreen from '@/app/ui/file-page/violation-table/fil
import Image from 'next/image'; import Image from 'next/image';
import FilePageViolationInfoTabs from '@/app/ui/file-page/violation-table/file-page-violation-info-tabs'; import FilePageViolationInfoTabs from '@/app/ui/file-page/violation-table/file-page-violation-info-tabs';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import { IconContentCopy, IconFollowToLink, IconFullScreen } from '@/app/ui/icons/icons';
export default function FilePageViolationInfo({ selectedViolation }: { selectedViolation: ViolationFileDetail | null }) { export default function FilePageViolationInfo({ selectedViolation }: { selectedViolation: ViolationFileDetail | null }) {
const t = useTranslations('Global'); const t = useTranslations('Global');
@@ -23,6 +24,8 @@ export default function FilePageViolationInfo({ selectedViolation }: { selectedV
const [localViolation, setLocalViolation] = useState<ViolationFileDetail | null>(null); const [localViolation, setLocalViolation] = useState<ViolationFileDetail | null>(null);
const [isUpdating, setIsUpdating] = useState(false); const [isUpdating, setIsUpdating] = useState(false);
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
const [isHovered, setIsHovered] = useState(false);
const [copied, setCopied] = useState(false);
const openInNewTab = () => { const openInNewTab = () => {
if (selectedViolation?.url) { if (selectedViolation?.url) {
@@ -95,6 +98,32 @@ export default function FilePageViolationInfo({ selectedViolation }: { selectedV
); );
}; };
const handleCopyLink = () => {
if (!selectedViolation?.page_url) return;
const linkToCopy = cleanUrlForDisplay(selectedViolation.page_url);
if (!navigator.clipboard) {
const textarea = document.createElement('textarea');
textarea.value = linkToCopy;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
toast.success(`${t('copied')}: ${linkToCopy}`)
return;
}
navigator.clipboard.writeText(linkToCopy)
.then(() => {
setCopied(true);
setTimeout(() => setCopied(false), 2000);
toast.success(`${t('copied')}: ${linkToCopy}`)
})
.catch();
};
return ( return (
<div <div
@@ -139,23 +168,14 @@ export default function FilePageViolationInfo({ selectedViolation }: { selectedV
onClick={() => setIsModalOpen(true)} onClick={() => setIsModalOpen(true)}
title="Увеличить" title="Увеличить"
> >
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"> <IconFullScreen />
<circle cx="11" cy="11" r="8" />
<line x1="21" y1="21" x2="16.65" y2="16.65" />
<line x1="11" y1="8" x2="11" y2="14" />
<line x1="8" y1="11" x2="14" y2="11" />
</svg>
</button> </button>
<button <button
className="image-btn image-btn-open" className="image-btn image-btn-open"
onClick={openInNewTab} onClick={openInNewTab}
title="Открыть в новой вкладке" title="Открыть в новой вкладке"
> >
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"> <IconFollowToLink />
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
<polyline points="15 3 21 3 21 9" />
<line x1="10" y1="14" x2="21" y2="3" />
</svg>
</button> </button>
</div> </div>
</div> </div>
@@ -172,18 +192,35 @@ export default function FilePageViolationInfo({ selectedViolation }: { selectedV
className="violation-info-source" className="violation-info-source"
> >
<span> <span>
{t('source')}: {t('full-link')}:
</span> </span>
<br /> <div
<Link onMouseEnter={() => setIsHovered(true)}
href={selectedViolation?.page_url ? selectedViolation?.page_url : '#'} onMouseLeave={() => setIsHovered(false)}
>
<span
className="source" className="source"
>
{selectedViolation?.page_url ? cleanUrlForDisplay(selectedViolation?.page_url) : selectedViolation?.page_url}
</span>
<span
className={`violation-info-icon ${!isHovered ? 'hiden' : ''}`}
onClick={handleCopyLink}
>
<IconContentCopy />
</span>
<Link
className={`violation-info-icon ${!isHovered ? 'hiden' : ''}`}
href={selectedViolation?.page_url ? cleanUrlForDisplay(selectedViolation?.page_url) : '#'}
target="_blank" target="_blank"
scroll={false} scroll={false}
> >
{selectedViolation?.page_url ? cleanUrlForDisplay(selectedViolation?.page_url) : selectedViolation?.page_url} <IconFollowToLink />
</Link> </Link>
</div> </div>
</div>
<div <div
className="violation-info-status" className="violation-info-status"
@@ -216,7 +253,7 @@ export default function FilePageViolationInfo({ selectedViolation }: { selectedV
className="violation-info-date" className="violation-info-date"
> >
<span> <span>
{t('date-of-creation')}: {t('date-of-discovery')}:
</span> </span>
<div <div
className="violation-info-date-value" className="violation-info-date-value"
@@ -235,7 +272,7 @@ export default function FilePageViolationInfo({ selectedViolation }: { selectedV
className="violation-info-action" className="violation-info-action"
> >
<button <button
className="btn-action btn-resolve" className="btn-s btn-resolve"
onClick={() => { onClick={() => {
if (selectedViolation?.id) { if (selectedViolation?.id) {
updateStatusHandler(selectedViolation.id, 'AUTHORIZED_USE'); updateStatusHandler(selectedViolation.id, 'AUTHORIZED_USE');
@@ -8,7 +8,7 @@ import FilePageViolationInfo from '@/app/ui/file-page/violation-table/file-page-
import { useFileViolations } from '@/app/hooks/react-query/useFileViolations'; import { useFileViolations } from '@/app/hooks/react-query/useFileViolations';
import { ViolationFileDetail } from '@/app/hooks/react-query/useFileViolations'; import { ViolationFileDetail } from '@/app/hooks/react-query/useFileViolations';
import DropDownList from '@/app/components/DropDownList'; import DropDownList from '@/app/components/DropDownList';
import { IconArrowLeft, IconArrowRight, IconDoubleArrowLeft, IconDoubleArrowRight } from '@/app/ui/icons/icons'; import { IconArrowLeft, IconArrowRight, IconDoubleArrowLeft, IconDoubleArrowRight, IconFollowToLink } from '@/app/ui/icons/icons';
import FilePageViolationsLoadingList from '@/app/ui/file-page/violation-table/file-page-violations-loading-list'; import FilePageViolationsLoadingList from '@/app/ui/file-page/violation-table/file-page-violations-loading-list';
import Image from 'next/image'; import Image from 'next/image';
@@ -194,11 +194,10 @@ export default function FilePageViolationsList({
<div className="source-actions"> <div className="source-actions">
<Link <Link
href={item.page_url} href={item.page_url}
className="btn-small btn-primary-small"
target="_blank" target="_blank"
scroll={false} scroll={false}
> >
{t('open')} <IconFollowToLink />
</Link> </Link>
</div> </div>
</div> </div>
+18
View File
@@ -243,3 +243,21 @@ export function IconInfoMessage() {
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" ><path d="M440-280h80v-240h-80v240Zm68.5-331.5Q520-623 520-640t-11.5-28.5Q497-680 480-680t-28.5 11.5Q440-657 440-640t11.5 28.5Q463-600 480-600t28.5-11.5ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z" /></svg> <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" ><path d="M440-280h80v-240h-80v240Zm68.5-331.5Q520-623 520-640t-11.5-28.5Q497-680 480-680t-28.5 11.5Q440-657 440-640t11.5 28.5Q463-600 480-600t28.5-11.5ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z" /></svg>
) )
} }
export function IconContentCopy() {
return (
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M360-240q-33 0-56.5-23.5T280-320v-480q0-33 23.5-56.5T360-880h360q33 0 56.5 23.5T800-800v480q0 33-23.5 56.5T720-240H360Zm0-80h360v-480H360v480ZM200-80q-33 0-56.5-23.5T120-160v-560h80v560h440v80H200Zm160-240v-480 480Z" /></svg>
)
}
export function IconFollowToLink() {
return (
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h280v80H200v560h560v-280h80v280q0 33-23.5 56.5T760-120H200Zm188-212-56-56 372-372H560v-80h280v280h-80v-144L388-332Z" /></svg>
)
}
export function IconFullScreen() {
return (
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#000000"><path d="M120-120v-200h80v120h120v80H120Zm520 0v-80h120v-120h80v200H640ZM120-640v-200h200v80H200v120h-80Zm640 0v-120H640v-80h200v200h-80Z"/></svg>
)
}
+4 -1
View File
@@ -421,7 +421,10 @@
"protected-files": "Protected files", "protected-files": "Protected files",
"storage": "Storage", "storage": "Storage",
"Status": "Status", "Status": "Status",
"under-moderation": "Under moderation" "under-moderation": "Under moderation",
"full-link": "Full link",
"follow-the-link": "Follow the link",
"date-of-discovery": "Date of discovery"
}, },
"Login-register-form": { "Login-register-form": {
"and": "and", "and": "and",
+6 -3
View File
@@ -421,7 +421,10 @@
"protected-files": "Защищено файлов", "protected-files": "Защищено файлов",
"storage": "Хранилище", "storage": "Хранилище",
"Status": "Статус", "Status": "Статус",
"under-moderation": "На модерации" "under-moderation": "На модерации",
"full-link": "Полная ссылка",
"follow-the-link": "Перейти",
"date-of-discovery": "Дата обнаружения"
}, },
"Login-register-form": { "Login-register-form": {
"and": "и", "and": "и",
@@ -527,8 +530,8 @@
"Match-status": { "Match-status": {
"NEW": "Новый", "NEW": "Новый",
"SHOWED": "Просмотрен", "SHOWED": "Просмотрен",
"LEGAL_IN_WORK": "Дело в работе", "LEGAL_IN_WORK": "Претензия в работе",
"COMPLAINT_IN_WORK": "Претензия в работе", "COMPLAINT_IN_WORK": "Жалоба в работе",
"COMPLAINT_AND_LEGAL_IN_WORK": "Дело и претензия в работе", "COMPLAINT_AND_LEGAL_IN_WORK": "Дело и претензия в работе",
"AUTHORIZED_USE": "Разрешенное использование", "AUTHORIZED_USE": "Разрешенное использование",
"CREATED": "Новый" "CREATED": "Новый"