add resolved button for matched file

This commit is contained in:
smanylov
2026-03-27 13:50:41 +07:00
parent 6453e8402e
commit 9128c0e298
6 changed files with 158 additions and 95 deletions
+5 -2
View File
@@ -355,8 +355,11 @@ export async function fetchComplainInfo(id: number) {
} }
} }
export async function updateMatchStatus(id: number, status: string) { export type MatchStatus = 'NEW' | 'SHOWED' | 'LEGAL_IN_WORK' | 'COMPLAINT_IN_WORK' | 'COMPLAINT_AND_LEGAL_IN_WORK' | 'AUTHORIZED_USE';
export async function updateMatchStatus(id: number, status: MatchStatus) {
const token = await getSessionData('token'); const token = await getSessionData('token');
console.log('updateMatchStatus');
try { try {
const response = await fetch(`${API_BASE_URL}/api/v1/data`, { const response = await fetch(`${API_BASE_URL}/api/v1/data`, {
@@ -380,7 +383,7 @@ export async function updateMatchStatus(id: number, status: string) {
if (response.ok) { if (response.ok) {
let parsed = await response.json(); let parsed = await response.json();
if (parsed?.message_body.status === 'SHOWED') { if (parsed?.message_body.status) {
return true return true
} else { } else {
throw parsed; throw parsed;
+83 -63
View File
@@ -4468,6 +4468,24 @@
flex: 1; flex: 1;
} }
.source-meta {
gap: 15px;
font-size: 12px;
color: #64748b;
margin-bottom: 10px;
flex-wrap: wrap;
margin-right: 5px;
}
.source-actions {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-top: auto;
}
}
}
.source-status { .source-status {
padding: 4px 10px; padding: 4px 10px;
border-radius: 6px; border-radius: 6px;
@@ -4475,6 +4493,7 @@
font-weight: 600; font-weight: 600;
white-space: nowrap; white-space: nowrap;
margin-bottom: 5px; margin-bottom: 5px;
user-select: none;
&.new, &.new,
&.created { &.created {
@@ -4496,23 +4515,55 @@
} }
} }
.source-meta { .btn-action {
gap: 15px; flex: 1;
font-size: 12px; width: 100%;
color: #64748b; padding: 12px 20px;
margin-bottom: 10px; border-radius: 12px;
flex-wrap: wrap; font-weight: 600;
margin-right: 5px; border: none;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
max-width: 300px;
} }
.source-actions { .btn-case {
display: flex; background: linear-gradient(135deg, #6366f1, #8b5cf6);
gap: 10px; color: white;
flex-wrap: wrap; margin-bottom: 20px;
margin-top: auto;
&:hover {
transform: translateY(-2px);
} }
} }
.btn-success {
background: linear-gradient(135deg, #10b981, #059669);
color: white;
max-width: 200px;
padding: 6px 10px;
&:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(16, 185, 129, 0.4);
} }
}
/* .btn-warning {
background: linear-gradient(135deg, #f59e0b, #d97706);
color: white;
}
.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);
}
} */
.violation-info { .violation-info {
background: #fff; background: #fff;
@@ -4550,7 +4601,6 @@
} }
&-image { &-image {
margin-bottom: 20px;
width: 300px; width: 300px;
height: 200px; height: 200px;
@@ -4561,9 +4611,13 @@
} }
} }
&-source { &-right-side {
margin-bottom: 20px; display: flex;
flex-direction: column;
gap: 10px;
}
&-source {
span { span {
color: #64748b; color: #64748b;
margin-right: 5px; margin-right: 5px;
@@ -4574,6 +4628,19 @@
} }
} }
&-date-status {
display: flex;
gap: 10px;
.source-status {
margin-bottom: 0;
}
}
&-action {
margin-top: auto;
}
&-actions { &-actions {
border-left: 1px solid #e2e8f0; border-left: 1px solid #e2e8f0;
padding-left: 15px; padding-left: 15px;
@@ -4584,6 +4651,7 @@
grid-template-columns: 300px auto; grid-template-columns: 300px auto;
gap: 10px; gap: 10px;
flex-shrink: 0; flex-shrink: 0;
padding-bottom: 20px;
border-bottom: 1px solid rgb(226, 232, 240); border-bottom: 1px solid rgb(226, 232, 240);
} }
@@ -4604,54 +4672,6 @@
border-bottom: 1px solid rgb(226, 232, 240); border-bottom: 1px solid rgb(226, 232, 240);
padding-bottom: 10px; padding-bottom: 10px;
} }
.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;
}
.btn-case {
background: linear-gradient(135deg, #6366f1, #8b5cf6);
color: white;
margin-bottom: 20px;
&:hover {
transform: translateY(-2px);
}
}
/* .btn-warning {
background: linear-gradient(135deg, #f59e0b, #d97706);
color: white;
}
.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);
}
} */
} }
} }
@@ -8,24 +8,36 @@ import CaseComplaint from '@/app/ui/file-page/violation-table/case-complaint';
import CaseViolation from '@/app/ui/file-page/violation-table/case-violation'; import CaseViolation from '@/app/ui/file-page/violation-table/case-violation';
import { updateMatchStatus } from '@/app/actions/violationActions'; import { updateMatchStatus } from '@/app/actions/violationActions';
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import { useEffect, useRef } from 'react'; import { useCallback, useEffect } from 'react';
import { MatchStatus } from '@/app/actions/violationActions';
import { toast } from 'sonner';
export default function FilePageViolationInfo({ selectedViolation }: { selectedViolation: ViolationFileDetail | null }) { export default function FilePageViolationInfo({ selectedViolation }: { selectedViolation: ViolationFileDetail | null }) {
const t = useTranslations('Global'); const t = useTranslations('Global');
const tStatus = useTranslations('Match-status');
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const updateStatusHandler = useCallback(async (id: number, status: MatchStatus) => {
const response = await updateMatchStatus(id, status);
if (response) {
if (status === 'AUTHORIZED_USE') {
toast.success('Статус обновлен');
}
queryClient.invalidateQueries({ queryKey: ['fileViolations'] });
return true;
}
return false;
}, [queryClient]);
useEffect(() => { useEffect(() => {
const updateStatus = async () => { const updateStatus = async () => {
if (selectedViolation && (selectedViolation.status === 'CREATED' || selectedViolation.status === 'NEW')) { if (selectedViolation && (selectedViolation.status === 'CREATED' || selectedViolation.status === 'NEW')) {
const response = await updateMatchStatus(selectedViolation.id, 'SHOWED'); await updateStatusHandler(selectedViolation.id, 'SHOWED');
if (response) {
queryClient.invalidateQueries({ queryKey: ['fileViolations'] });
}
} }
}; };
updateStatus(); updateStatus();
}, [selectedViolation, queryClient]); }, [selectedViolation, updateStatusHandler]);
if (!selectedViolation) { if (!selectedViolation) {
return ( return (
@@ -57,7 +69,9 @@ export default function FilePageViolationInfo({ selectedViolation }: { selectedV
<img src={selectedViolation?.url} alt={selectedViolation?.page_title} /> <img src={selectedViolation?.url} alt={selectedViolation?.page_title} />
</div> </div>
<div> <div
className="violation-info-right-side"
>
<div <div
className="violation-info-source" className="violation-info-source"
> >
@@ -74,14 +88,38 @@ export default function FilePageViolationInfo({ selectedViolation }: { selectedV
</Link> </Link>
</div> </div>
<div <div
className="violation-info-source" className="violation-info-date-status"
> >
<span> <span>
{t('date')} {selectedViolation?.created_date ? formatDate(selectedViolation?.created_date) : '#'} {t('date')} {selectedViolation?.created_date ? formatDate(selectedViolation?.created_date) : '#'}
</span> </span>
{/* COMPLAINT_IN_WORK COMPLAINT_AND_LEGAL_IN_WORK*/}
{selectedViolation?.status === "COMPLAINT_AND_LEGAL_IN_WORK" ? (
<>
<span className="source-status legal_in_work">
{tStatus('LEGAL_IN_WORK')}
</span>
<span className="source-status complaint_in_work">
{tStatus('COMPLAINT_IN_WORK')}
</span>
</>
) : (
<span className={`source-status ${selectedViolation?.status.toLowerCase()}`}>
{tStatus(selectedViolation?.status)}
</span>
)}
</div> </div>
<div> <div
{selectedViolation?.status} className="violation-info-action"
>
<button
className="btn-action btn-success"
onClick={() => {
updateStatusHandler(selectedViolation?.id, 'AUTHORIZED_USE');
}}
>
{t('mark-as-solved')}
</button>
</div> </div>
</div> </div>
</div> </div>
@@ -108,10 +108,10 @@ export default function FilePageViolationsList({
{item.status === "COMPLAINT_AND_LEGAL_IN_WORK" ? ( {item.status === "COMPLAINT_AND_LEGAL_IN_WORK" ? (
<> <>
<span className="source-status legal_in_work"> <span className="source-status legal_in_work">
{t('legal_in_work')} {tStatus('LEGAL_IN_WORK')}
</span> </span>
<span className="source-status complaint_in_work"> <span className="source-status complaint_in_work">
{t('complaint_in_work')} {tStatus('COMPLAINT_IN_WORK')}
</span> </span>
</> </>
) : ( ) : (
+2 -1
View File
@@ -368,7 +368,8 @@
"how-does-search-work": "How does search work?", "how-does-search-work": "How does search work?",
"search-info-description-text": "Our system analyzes the uploaded file and compares it with your protected files, using computer vision and digital fingerprinting algorithms.", "search-info-description-text": "Our system analyzes the uploaded file and compares it with your protected files, using computer vision and digital fingerprinting algorithms.",
"documents-few": "Documents", "documents-few": "Documents",
"change": "Change" "change": "Change",
"mark-as-solved": "Mark as solved"
}, },
"Login-register-form": { "Login-register-form": {
"and": "and", "and": "and",
+2 -1
View File
@@ -368,7 +368,8 @@
"how-does-search-work": "Как работает поиск?", "how-does-search-work": "Как работает поиск?",
"search-info-description-text": "Наша система анализирует загруженный файл и сравнивает его с вашими защищенными файлами, используя алгоритмы компьютерного зрения и цифровых отпечатков.", "search-info-description-text": "Наша система анализирует загруженный файл и сравнивает его с вашими защищенными файлами, используя алгоритмы компьютерного зрения и цифровых отпечатков.",
"documents-few": "Документов", "documents-few": "Документов",
"change": "Изменить" "change": "Изменить",
"mark-as-solved": "Отметить решенным"
}, },
"Login-register-form": { "Login-register-form": {
"and": "и", "and": "и",