history compolated
This commit is contained in:
@@ -208,5 +208,7 @@
|
|||||||
"total": "Total",
|
"total": "Total",
|
||||||
"connecting": "Connecting to Payme…",
|
"connecting": "Connecting to Payme…",
|
||||||
"payButton": "Pay with Payme"
|
"payButton": "Pay with Payme"
|
||||||
}
|
},
|
||||||
|
"unknownUser": "Username not found",
|
||||||
|
"file": "File"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -208,5 +208,7 @@
|
|||||||
"total": "Итого",
|
"total": "Итого",
|
||||||
"connecting": "Подключение к Payme…",
|
"connecting": "Подключение к Payme…",
|
||||||
"payButton": "Оплатить через Payme"
|
"payButton": "Оплатить через Payme"
|
||||||
}
|
},
|
||||||
|
"unknownUser": "Имя пользователя не найдено",
|
||||||
|
"file":"Файл"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -212,5 +212,7 @@ declare const messages: {
|
|||||||
connecting: 'Paymega ulanmoqda…';
|
connecting: 'Paymega ulanmoqda…';
|
||||||
payButton: "Payme orqali to'lash";
|
payButton: "Payme orqali to'lash";
|
||||||
};
|
};
|
||||||
|
unknownUser: 'Foydalanuvchi topilmadi';
|
||||||
|
file: 'Fayl';
|
||||||
};
|
};
|
||||||
export default messages;
|
export default messages;
|
||||||
|
|||||||
@@ -208,5 +208,7 @@
|
|||||||
"total": "Jami",
|
"total": "Jami",
|
||||||
"connecting": "Paymega ulanmoqda…",
|
"connecting": "Paymega ulanmoqda…",
|
||||||
"payButton": "Payme orqali to'lash"
|
"payButton": "Payme orqali to'lash"
|
||||||
}
|
},
|
||||||
|
"unknownUser":"Foydalanuvchi topilmadi",
|
||||||
|
"file":"Fayl"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ export const TABLE_COLUMNS = [
|
|||||||
{ key: 'senderFullName', labelKey: 'sender' },
|
{ key: 'senderFullName', labelKey: 'sender' },
|
||||||
{ key: 'fileName', labelKey: 'file' },
|
{ key: 'fileName', labelKey: 'file' },
|
||||||
{ key: 'date', labelKey: 'date' },
|
{ key: 'date', labelKey: 'date' },
|
||||||
{ key: 'paymentAmount', labelKey: 'amount' },
|
|
||||||
{ key: 'result', labelKey: 'result' },
|
{ key: 'result', labelKey: 'result' },
|
||||||
{ key: 'actions', labelKey: 'actions' },
|
{ key: 'actions', labelKey: 'actions' },
|
||||||
] as const;
|
] as const;
|
||||||
@@ -38,10 +37,3 @@ export const RESULT_CONFIG: Record<
|
|||||||
// ─── Pagination ────────────────────────────────────────────────────────────────
|
// ─── Pagination ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
export const DEFAULT_PAGE_SIZE = 10;
|
export const DEFAULT_PAGE_SIZE = 10;
|
||||||
|
|
||||||
// ─── API ───────────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
export const API_ENDPOINTS = {
|
|
||||||
HISTORY: '/api/plagiarism/history',
|
|
||||||
DETAIL: (id: string) => `/api/plagiarism/${id}`,
|
|
||||||
} as const;
|
|
||||||
|
|||||||
@@ -1,71 +1,69 @@
|
|||||||
import { PlagiarismCheck } from './types';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default mock items used to preview the history table design.
|
* Default mock items used to preview the history table design.
|
||||||
* Replace with real API data in production via useHistory() hook.
|
* Replace with real API data in production via useHistory() hook.
|
||||||
*/
|
*/
|
||||||
export const DEFAULT_HISTORY_ITEMS: PlagiarismCheck[] = [
|
// export const DEFAULT_HISTORY_ITEMS: PlagiarismCheck[] = [
|
||||||
{
|
// {
|
||||||
id: '1',
|
// id: '1',
|
||||||
senderFullName: 'Alijon Toshmatov',
|
// senderFullName: 'Alijon Toshmatov',
|
||||||
fileName: 'thesis-final-v3.pdf',
|
// fileName: 'thesis-final-v3.pdf',
|
||||||
date: '2024-03-15T10:30:00Z',
|
// date: '2024-03-15T10:30:00Z',
|
||||||
paymentAmount: 45000,
|
// paymentAmount: 45000,
|
||||||
currency: 'UZS',
|
// currency: 'UZS',
|
||||||
result: 'clean',
|
// result: 'clean',
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
id: '2',
|
// id: '2',
|
||||||
senderFullName: 'Malika Yusupova',
|
// senderFullName: 'Malika Yusupova',
|
||||||
fileName: 'research-paper-2024.docx',
|
// fileName: 'research-paper-2024.docx',
|
||||||
date: '2024-03-14T09:15:00Z',
|
// date: '2024-03-14T09:15:00Z',
|
||||||
paymentAmount: 60000,
|
// paymentAmount: 60000,
|
||||||
currency: 'UZS',
|
// currency: 'UZS',
|
||||||
result: 'plagiarism_found',
|
// result: 'plagiarism_found',
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
id: '3',
|
// id: '3',
|
||||||
senderFullName: 'Bobur Rahimov',
|
// senderFullName: 'Bobur Rahimov',
|
||||||
fileName: 'coursework-economics.pdf',
|
// fileName: 'coursework-economics.pdf',
|
||||||
date: '2024-03-13T14:45:00Z',
|
// date: '2024-03-13T14:45:00Z',
|
||||||
paymentAmount: 45000,
|
// paymentAmount: 45000,
|
||||||
currency: 'UZS',
|
// currency: 'UZS',
|
||||||
result: 'pending',
|
// result: 'pending',
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
id: '4',
|
// id: '4',
|
||||||
senderFullName: 'Zulfiya Nazarova',
|
// senderFullName: 'Zulfiya Nazarova',
|
||||||
fileName: 'dissertation-chapter1.pdf',
|
// fileName: 'dissertation-chapter1.pdf',
|
||||||
date: '2024-03-12T11:20:00Z',
|
// date: '2024-03-12T11:20:00Z',
|
||||||
paymentAmount: 60000,
|
// paymentAmount: 60000,
|
||||||
currency: 'UZS',
|
// currency: 'UZS',
|
||||||
result: 'clean',
|
// result: 'clean',
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
id: '5',
|
// id: '5',
|
||||||
senderFullName: 'Jasur Mirzayev',
|
// senderFullName: 'Jasur Mirzayev',
|
||||||
fileName: 'lab-report-chemistry.docx',
|
// fileName: 'lab-report-chemistry.docx',
|
||||||
date: '2024-03-11T16:10:00Z',
|
// date: '2024-03-11T16:10:00Z',
|
||||||
paymentAmount: 45000,
|
// paymentAmount: 45000,
|
||||||
currency: 'UZS',
|
// currency: 'UZS',
|
||||||
result: 'failed',
|
// result: 'failed',
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
id: '6',
|
// id: '6',
|
||||||
senderFullName: 'Nilufar Karimova',
|
// senderFullName: 'Nilufar Karimova',
|
||||||
fileName: 'bachelor-thesis-law.pdf',
|
// fileName: 'bachelor-thesis-law.pdf',
|
||||||
date: '2024-03-10T08:55:00Z',
|
// date: '2024-03-10T08:55:00Z',
|
||||||
paymentAmount: 60000,
|
// paymentAmount: 60000,
|
||||||
currency: 'UZS',
|
// currency: 'UZS',
|
||||||
result: 'plagiarism_found',
|
// result: 'plagiarism_found',
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
id: '7',
|
// id: '7',
|
||||||
senderFullName: 'Dilnoza Ergasheva',
|
// senderFullName: 'Dilnoza Ergasheva',
|
||||||
fileName: 'essay-history-uzbekistan.pdf',
|
// fileName: 'essay-history-uzbekistan.pdf',
|
||||||
date: '2024-03-09T13:40:00Z',
|
// date: '2024-03-09T13:40:00Z',
|
||||||
paymentAmount: 45000,
|
// paymentAmount: 45000,
|
||||||
currency: 'UZS',
|
// currency: 'UZS',
|
||||||
result: 'clean',
|
// result: 'clean',
|
||||||
},
|
// },
|
||||||
];
|
// ];
|
||||||
|
|||||||
@@ -2,17 +2,18 @@
|
|||||||
|
|
||||||
export type CheckResult = 'clean' | 'plagiarism_found' | 'pending' | 'failed';
|
export type CheckResult = 'clean' | 'plagiarism_found' | 'pending' | 'failed';
|
||||||
|
|
||||||
export interface PlagiarismCheck {
|
export interface DocumentData {
|
||||||
id: string;
|
id: number;
|
||||||
senderFullName: string;
|
title: string;
|
||||||
fileName: string;
|
text: string;
|
||||||
date: string; // ISO 8601
|
file: string;
|
||||||
paymentAmount: number;
|
certificate: boolean;
|
||||||
currency: string;
|
created_at: string;
|
||||||
result: CheckResult;
|
updated_at: string;
|
||||||
|
results: [];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PlagiarismCheckDetail extends PlagiarismCheck {
|
export interface PlagiarismCheckDetail extends DocumentData {
|
||||||
topic: string;
|
topic: string;
|
||||||
plagiarismPercentage?: number;
|
plagiarismPercentage?: number;
|
||||||
reportUrl?: string;
|
reportUrl?: string;
|
||||||
@@ -22,7 +23,7 @@ export interface PlagiarismCheckDetail extends PlagiarismCheck {
|
|||||||
// ─── API Response Types ────────────────────────────────────────────────────────
|
// ─── API Response Types ────────────────────────────────────────────────────────
|
||||||
|
|
||||||
export interface HistoryApiResponse {
|
export interface HistoryApiResponse {
|
||||||
items: PlagiarismCheck[];
|
items: DocumentData[];
|
||||||
total: number;
|
total: number;
|
||||||
page: number;
|
page: number;
|
||||||
pageSize: number;
|
pageSize: number;
|
||||||
@@ -31,12 +32,12 @@ export interface HistoryApiResponse {
|
|||||||
// ─── Component Props ───────────────────────────────────────────────────────────
|
// ─── Component Props ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
export interface HistoryTableProps {
|
export interface HistoryTableProps {
|
||||||
items: PlagiarismCheck[];
|
items: DocumentData[];
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HistoryTableRowProps {
|
export interface HistoryTableRowProps {
|
||||||
item: PlagiarismCheck;
|
item: DocumentData;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResultBadgeProps {
|
export interface ResultBadgeProps {
|
||||||
@@ -56,7 +57,7 @@ export interface SkeletonRowProps {
|
|||||||
export type FetchStatus = 'idle' | 'loading' | 'success' | 'error';
|
export type FetchStatus = 'idle' | 'loading' | 'success' | 'error';
|
||||||
|
|
||||||
export interface HistoryState {
|
export interface HistoryState {
|
||||||
items: PlagiarismCheck[];
|
items: DocumentData[];
|
||||||
status: FetchStatus;
|
status: FetchStatus;
|
||||||
error: string | null;
|
error: string | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import { DEFAULT_PAGE_SIZE } from './constants';
|
import { DEFAULT_PAGE_SIZE } from './constants';
|
||||||
import { HistoryState } from './types';
|
import { DocumentData, HistoryState } from './types';
|
||||||
import { DEFAULT_HISTORY_ITEMS } from './mock';
|
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { links } from '@/shared/request/links';
|
import { links } from '@/shared/request/links';
|
||||||
import { apiRequest } from '@/shared/request/apiRequest';
|
import { apiRequest } from '@/shared/request/apiRequest';
|
||||||
|
import { useUserPlagiatStore } from '@/shared/zustand/user';
|
||||||
|
|
||||||
interface UseHistoryReturn extends HistoryState {
|
interface UseHistoryReturn extends HistoryState {
|
||||||
refetch: () => void;
|
refetch: () => void;
|
||||||
@@ -16,22 +16,21 @@ interface UseHistoryReturn extends HistoryState {
|
|||||||
|
|
||||||
export const useHistory = (pageSize = DEFAULT_PAGE_SIZE): UseHistoryReturn => {
|
export const useHistory = (pageSize = DEFAULT_PAGE_SIZE): UseHistoryReturn => {
|
||||||
const [state, setState] = useState<HistoryState>({
|
const [state, setState] = useState<HistoryState>({
|
||||||
items: DEFAULT_HISTORY_ITEMS,
|
items: [],
|
||||||
status: 'idle',
|
status: 'idle',
|
||||||
error: null,
|
error: null,
|
||||||
});
|
});
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
|
const user = useUserPlagiatStore((state) => state.user);
|
||||||
|
|
||||||
const { data, refetch } = useQuery({
|
const { data, refetch } = useQuery({
|
||||||
queryKey: ['history'],
|
queryKey: ['history'],
|
||||||
queryFn: () => apiRequest('GET', links.history),
|
queryFn: () => apiRequest('GET', links.history),
|
||||||
select: (response) => {
|
select: (response) => {
|
||||||
const { results, total } = response.data as {
|
console.log(response);
|
||||||
results: [];
|
const results = response?.data as DocumentData[];
|
||||||
total: number;
|
return { results, total: results.length };
|
||||||
};
|
|
||||||
return { results, total };
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -42,13 +41,13 @@ export const useHistory = (pageSize = DEFAULT_PAGE_SIZE): UseHistoryReturn => {
|
|||||||
status: 'success',
|
status: 'success',
|
||||||
error: null,
|
error: null,
|
||||||
});
|
});
|
||||||
setTotal(data?.total || 0);
|
setTotal(data.total || 0);
|
||||||
}
|
}
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
refetch();
|
refetch();
|
||||||
}, [currentPage]);
|
}, [currentPage, user]);
|
||||||
|
|
||||||
const goToPage = useCallback((page: number) => {
|
const goToPage = useCallback((page: number) => {
|
||||||
setCurrentPage(page);
|
setCurrentPage(page);
|
||||||
|
|||||||
@@ -1,43 +1,3 @@
|
|||||||
// ─── API Functions ─────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
import { API_ENDPOINTS } from './constants';
|
|
||||||
import { HistoryApiResponse, PlagiarismCheckDetail } from './types';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches the paginated list of plagiarism checks for the current user.
|
|
||||||
*/
|
|
||||||
export const fetchPlagiarismHistory = async (
|
|
||||||
page = 1,
|
|
||||||
pageSize = 10,
|
|
||||||
): Promise<HistoryApiResponse> => {
|
|
||||||
const url = new URL(API_ENDPOINTS.HISTORY, window.location.origin);
|
|
||||||
url.searchParams.set('page', String(page));
|
|
||||||
url.searchParams.set('pageSize', String(pageSize));
|
|
||||||
|
|
||||||
const response = await fetch(url.toString());
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Failed to load history (${response.status})`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.json() as Promise<HistoryApiResponse>;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches the full detail for a single plagiarism check.
|
|
||||||
*/
|
|
||||||
export const fetchPlagiarismDetail = async (
|
|
||||||
id: string,
|
|
||||||
): Promise<PlagiarismCheckDetail> => {
|
|
||||||
const response = await fetch(API_ENDPOINTS.DETAIL(id));
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Failed to load record (${response.status})`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.json() as Promise<PlagiarismCheckDetail>;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ─── Formatting Utilities ──────────────────────────────────────────────────────
|
// ─── Formatting Utilities ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,26 +2,37 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import { HistoryTableRowProps } from '../lib/types';
|
import { HistoryTableRowProps } from '../lib/types';
|
||||||
import { formatDate, truncateFileName } from '../lib/utils';
|
import { formatDate } from '../lib/utils';
|
||||||
import { ResultBadge } from './resultBadge';
|
import { ResultBadge } from './resultBadge';
|
||||||
import { useRouter } from '@/shared/config/i18n/navigation';
|
import { useRouter } from '@/shared/config/i18n/navigation';
|
||||||
|
import { useUserPlagiatStore } from '@/shared/zustand/user';
|
||||||
|
|
||||||
export const HistoryTableRow: React.FC<HistoryTableRowProps> = ({ item }) => {
|
export const HistoryTableRow: React.FC<HistoryTableRowProps> = ({ item }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const t = useTranslations('HistoryPage');
|
const t = useTranslations('HistoryPage');
|
||||||
|
const tUnknown = useTranslations();
|
||||||
|
const user = useUserPlagiatStore((state) => state.user);
|
||||||
|
|
||||||
|
const userName = user
|
||||||
|
? `${user.name} ${user.surname}`
|
||||||
|
: tUnknown('unknownUser');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr className="border-b border-slate-100 hover:bg-slate-50/70 transition-colors duration-100 group">
|
<tr className="border-b border-slate-100 hover:bg-slate-50/70 transition-colors duration-100 group">
|
||||||
{/* Sender */}
|
{/* Sender */}
|
||||||
<td className="px-4 py-3.5">
|
<td className="px-4 py-3.5">
|
||||||
<span className="text-sm font-medium text-slate-800 whitespace-nowrap">
|
<span className="text-sm font-medium text-slate-800 whitespace-nowrap">
|
||||||
{item.senderFullName}
|
{userName}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
{/* File Name */}
|
{/* File Name */}
|
||||||
<td className="px-4 py-3.5">
|
<td className="px-4 py-3.5">
|
||||||
<div className="flex items-center gap-2">
|
<a
|
||||||
|
href={item.file}
|
||||||
|
target="_blank"
|
||||||
|
className="flex items-center gap-2 underline"
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
width="14"
|
width="14"
|
||||||
height="14"
|
height="14"
|
||||||
@@ -33,39 +44,36 @@ export const HistoryTableRow: React.FC<HistoryTableRowProps> = ({ item }) => {
|
|||||||
>
|
>
|
||||||
<path d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
<path d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span
|
<span className="text-sm text-slate-600 font-mono" title={item.file}>
|
||||||
className="text-sm text-slate-600 font-mono"
|
{tUnknown('file')}
|
||||||
title={item.fileName}
|
|
||||||
>
|
|
||||||
{truncateFileName(item.fileName)}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
{/* Date */}
|
{/* Date */}
|
||||||
<td className="px-4 py-3.5">
|
<td className="px-4 py-3.5">
|
||||||
<span className="text-sm text-slate-500 whitespace-nowrap">
|
<span className="text-sm text-slate-500 whitespace-nowrap">
|
||||||
{formatDate(item.date)}
|
{formatDate(item.created_at)}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
{/* Amount */}
|
{/* Amount */}
|
||||||
<td className="px-4 py-3.5">
|
{/* <td className="px-4 py-3.5">
|
||||||
<span className="text-sm font-medium text-slate-700 whitespace-nowrap tabular-nums">
|
<span className="text-sm font-medium text-slate-700 whitespace-nowrap tabular-nums">
|
||||||
{item.paymentAmount}
|
{item.} UZS
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td> */}
|
||||||
|
|
||||||
{/* Result */}
|
{/* Result */}
|
||||||
<td className="px-4 py-3.5">
|
<td className="px-4 py-3.5">
|
||||||
<ResultBadge result={item.result} />
|
<ResultBadge result={'clean'} />
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
{/* View Button */}
|
{/* View Button */}
|
||||||
<td className="px-4 py-3.5 text-right">
|
<td className="px-4 py-3.5 text-right">
|
||||||
<button
|
<button
|
||||||
onClick={() => router.push(`/${item.id}`)}
|
onClick={() => router.push(`/${item.id}`)}
|
||||||
aria-label={t('viewDetails', { sender: item.senderFullName })}
|
aria-label={t('viewDetails', { sender: item.title })}
|
||||||
className="
|
className="
|
||||||
inline-flex items-center gap-1.5 px-3 py-1.5
|
inline-flex items-center gap-1.5 px-3 py-1.5
|
||||||
text-xs font-medium text-slate-600
|
text-xs font-medium text-slate-600
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { ChangeLang } from './ChangeLang';
|
|||||||
import { useLoginModal, useRegisterModal } from '@/shared/zustand/auth';
|
import { useLoginModal, useRegisterModal } from '@/shared/zustand/auth';
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import { useUserPlagiatStore } from '@/shared/zustand/user';
|
import { useUserPlagiatStore } from '@/shared/zustand/user';
|
||||||
|
import { LogOut } from 'lucide-react';
|
||||||
|
|
||||||
function AuthButtons() {
|
function AuthButtons() {
|
||||||
const t = useTranslations('Navbar');
|
const t = useTranslations('Navbar');
|
||||||
@@ -22,13 +23,19 @@ function AuthButtons() {
|
|||||||
signup: { title: t('signup'), url: '#' },
|
signup: { title: t('signup'), url: '#' },
|
||||||
};
|
};
|
||||||
|
|
||||||
const userItem = [{ title: t('logout'), url: '#' }];
|
const userItem = [{ title: t('logout'), url: '/', icon: LogOut }];
|
||||||
|
|
||||||
const toggleLoginModal = useLoginModal((state) => state.toggleLoginModal);
|
const toggleLoginModal = useLoginModal((state) => state.toggleLoginModal);
|
||||||
const toggleRegisterModal = useRegisterModal(
|
const toggleRegisterModal = useRegisterModal(
|
||||||
(state) => state.toggleRegisterModal,
|
(state) => state.toggleRegisterModal,
|
||||||
);
|
);
|
||||||
const user = useUserPlagiatStore((state) => state.user);
|
const user = useUserPlagiatStore((state) => state.user);
|
||||||
|
const clearUser = useUserPlagiatStore((state) => state.clearUser);
|
||||||
|
const clearTokens = () => {
|
||||||
|
localStorage.removeItem('access');
|
||||||
|
localStorage.removeItem('refresh');
|
||||||
|
localStorage.removeItem('user');
|
||||||
|
};
|
||||||
console.log('Current user:', user);
|
console.log('Current user:', user);
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
@@ -48,6 +55,10 @@ function AuthButtons() {
|
|||||||
asChild
|
asChild
|
||||||
key={subItem.title}
|
key={subItem.title}
|
||||||
className="w-80"
|
className="w-80"
|
||||||
|
onClick={() => {
|
||||||
|
clearTokens();
|
||||||
|
clearUser();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<SubMenuLink item={subItem} />
|
<SubMenuLink item={subItem} />
|
||||||
</NavigationMenuLink>
|
</NavigationMenuLink>
|
||||||
|
|||||||
Reference in New Issue
Block a user