add resolved button for matched file
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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": "и",
|
||||||
|
|||||||
Reference in New Issue
Block a user