diff --git a/src/shared/config/i18n/messages/en.json b/src/shared/config/i18n/messages/en.json index 1ba37ea..ec26c51 100644 --- a/src/shared/config/i18n/messages/en.json +++ b/src/shared/config/i18n/messages/en.json @@ -34,6 +34,8 @@ "PlagiarismCheck": { "badge": "Originality Check", "title": "Submit Your Document", + "submissionSuccess": "Submission successful! ID", + "secureNote": "Your document is processed securely and not stored beyond the analysis period.", "description": "Upload a document to verify its originality. Results are typically ready within a few minutes.", "documentTopic": "Document Topic", "topicPlaceholder": "e.g. The Impact of Artificial Intelligence on Education", @@ -80,6 +82,26 @@ "fileName": "File Name", "fileSize": "File Size", "submitted": "Submitted", + "failedToLoadDocument": "Failed to load document", + "unexpectedError": "An unexpected error occurred.", + "documentNumber": "Document #{{id}}", + "downloadPdf": "Download PDF", + "created": "Created", + "updated": "Updated", + "hash": "Hash", + "analysisScores": "Analysis Scores", + "documentText": "Document Text", + "plagiarismHighlights": "Plagiarism Highlights", + "plainText": "Plain Text", + "highlightedHint": "Highlighted fragments indicate potential plagiarism matches", + "textStatistics": "Text Statistics", + "detectionFlags": "Detection Flags", + "topWords": "Top Words", + "aiContentDetected": "AI Content Detected", + "possibleAiContent": "Possible AI Content", + "likelyOriginal": "Likely Original", + "aiProbabilityText": "AI probability score: {{score}}% — content may have been generated or assisted by an AI model.", + "resultFooter": "Result ID #{{id}} · Analyzed {{date}}", "payment": "Payment", "resultTitle": "Result", "analysisInProgress": "Analysis in progress", @@ -211,5 +233,5 @@ }, "unknownUser": "Username not found", "file": "File", - "upload":"Download certificate" + "upload": "Download certificate" } diff --git a/src/shared/config/i18n/messages/ru.json b/src/shared/config/i18n/messages/ru.json index 534d693..91d5918 100644 --- a/src/shared/config/i18n/messages/ru.json +++ b/src/shared/config/i18n/messages/ru.json @@ -34,6 +34,8 @@ "PlagiarismCheck": { "badge": "Проверка оригинальности", "title": "Отправьте ваш документ", + "submissionSuccess": "Отправка прошла успешно! ID", + "secureNote": "Ваш документ обрабатывается безопасно и не хранится после периода анализа.", "description": "Загрузите документ для проверки его оригинальности. Результаты обычно готовы в течение нескольких минут.", "documentTopic": "Тема документа", "topicPlaceholder": "например: Влияние искусственного интеллекта на образование", @@ -80,6 +82,26 @@ "fileName": "Имя файла", "fileSize": "Размер файла", "submitted": "Отправлено", + "failedToLoadDocument": "Не удалось загрузить документ", + "unexpectedError": "Произошла непредвиденная ошибка.", + "documentNumber": "Документ №{{id}}", + "downloadPdf": "Скачать PDF", + "created": "Создан", + "updated": "Обновлен", + "hash": "Hash", + "analysisScores": "Оценки анализа", + "documentText": "Текст документа", + "plagiarismHighlights": "Выделения плагиата", + "plainText": "Обычный текст", + "highlightedHint": "Выделенные фрагменты указывают на возможный плагиат", + "textStatistics": "Статистика текста", + "detectionFlags": "Флаги обнаружения", + "topWords": "Топ слова", + "aiContentDetected": "Обнаружен AI-контент", + "possibleAiContent": "Возможный AI-контент", + "likelyOriginal": "Вероятно оригинал", + "aiProbabilityText": "Вероятность AI: {{score}}% — контент может быть создан или сгенерирован AI.", + "resultFooter": "Результат ID #{{id}} · Анализирован {{date}}", "payment": "Оплата", "resultTitle": "Результат", "analysisInProgress": "Анализ выполняется", @@ -210,6 +232,6 @@ "payButton": "Оплатить через Payme" }, "unknownUser": "Имя пользователя не найдено", - "file":"Файл", - "upload":"Скачать сертификат" + "file": "Файл", + "upload": "Скачать сертификат" } diff --git a/src/shared/config/i18n/messages/uz.d.json.ts b/src/shared/config/i18n/messages/uz.d.json.ts index fbaa83c..adaa47b 100644 --- a/src/shared/config/i18n/messages/uz.d.json.ts +++ b/src/shared/config/i18n/messages/uz.d.json.ts @@ -37,6 +37,8 @@ declare const messages: { PlagiarismCheck: { badge: 'Orijinallik tekshiruvi'; title: 'Hujjatni yuboring'; + submissionSuccess: 'Yuborish muvaffaqiyatli yakunlandi! ID'; + secureNote: 'Hujjatingiz xavfsiz qayta ishlanadi va tahlil muddati tugagach saqlanmaydi.'; description: "Hujjatning orijinalligini tekshirish uchun yuklang. Natijalar odatda bir necha daqiqada tayyor bo'ladi."; documentTopic: 'Hujjat mavzusi'; topicPlaceholder: "masalan: Sun'iy intellektning ta'limga ta'siri"; @@ -87,6 +89,26 @@ declare const messages: { resultTitle: 'Natija'; analysisInProgress: 'Tahlil davom etmoqda'; resultsReadyAfterProcessing: "Natijalar qayta ishlash tugagach paydo bo'ladi."; + failedToLoadDocument: 'Hujjatni yuklash muvaffaqiyatsiz tugadi'; + unexpectedError: 'Kutilmagan xatolik yuz berdi.'; + documentNumber: 'Hujjat №{{id}}'; + downloadPdf: 'PDFni yuklab olish'; + created: 'Yaratilgan'; + updated: 'Yangilangan'; + hash: 'Hash'; + analysisScores: 'Tahlil ballari'; + documentText: 'Hujjat matni'; + plagiarismHighlights: 'Plagiat belgilari'; + plainText: 'Oddiy matn'; + highlightedHint: 'Belgilangan bo‘limlar plagiat ehtimolini ko‘rsatadi'; + textStatistics: 'Matn statistikalari'; + detectionFlags: 'Aniqlash bayroqlari'; + topWords: 'Top so‘zlar'; + aiContentDetected: 'AI kontent aniqlandi'; + possibleAiContent: 'Ehtimoliy AI kontent'; + likelyOriginal: 'Ehtimol original'; + aiProbabilityText: 'AI ehtimollik balli: {{score}}% — kontent AI model tomonidan yaratilgan yoki yordam berilgan bo‘lishi mumkin.'; + resultFooter: 'Natija ID #{{id}} · Tahlil qilingan {{date}}'; noResultAvailable: 'Natija mavjud emas.'; plagiarismResult: 'Plagiat natijasi'; wordsChecked: "Tekshirilgan so'zlar"; diff --git a/src/shared/config/i18n/messages/uz.json b/src/shared/config/i18n/messages/uz.json index 46511de..0e787fb 100644 --- a/src/shared/config/i18n/messages/uz.json +++ b/src/shared/config/i18n/messages/uz.json @@ -34,6 +34,8 @@ "PlagiarismCheck": { "badge": "Orijinallik tekshiruvi", "title": "Hujjatni yuboring", + "submissionSuccess": "Yuborish muvaffaqiyatli yakunlandi! ID", + "secureNote": "Hujjatingiz xavfsiz qayta ishlanadi va tahlil muddati tugagach saqlanmaydi.", "description": "Hujjatning orijinalligini tekshirish uchun yuklang. Natijalar odatda bir necha daqiqada tayyor bo'ladi.", "documentTopic": "Hujjat mavzusi", "topicPlaceholder": "masalan: Sun'iy intellektning ta'limga ta'siri", @@ -84,6 +86,26 @@ "resultTitle": "Natija", "analysisInProgress": "Tahlil davom etmoqda", "resultsReadyAfterProcessing": "Natijalar qayta ishlash tugagach paydo bo'ladi.", + "failedToLoadDocument": "Hujjatni yuklash muvaffaqiyatsiz tugadi", + "unexpectedError": "Kutilmagan xatolik yuz berdi.", + "documentNumber": "Hujjat №{{id}}", + "downloadPdf": "PDFni yuklab olish", + "created": "Yaratilgan", + "updated": "Yangilangan", + "hash": "Hash", + "analysisScores": "Tahlil ballari", + "documentText": "Hujjat matni", + "plagiarismHighlights": "Plagiat belgilari", + "plainText": "Oddiy matn", + "highlightedHint": "Belgilangan bo‘limlar plagiat ehtimolini ko‘rsatadi", + "textStatistics": "Matn statistikalari", + "detectionFlags": "Aniqlash bayroqlari", + "topWords": "Top so‘zlar", + "aiContentDetected": "AI kontent aniqlandi", + "possibleAiContent": "Ehtimoliy AI kontent", + "likelyOriginal": "Ehtimol original", + "aiProbabilityText": "AI ehtimollik balli: {{score}}% — kontent AI model tomonidan yaratilgan yoki yordam berilgan bo‘lishi mumkin.", + "resultFooter": "Natija ID #{{id}} · Tahlil qilingan {{date}}", "noResultAvailable": "Natija mavjud emas.", "plagiarismResult": "Plagiat natijasi", "wordsChecked": "Tekshirilgan so'zlar", @@ -209,7 +231,7 @@ "connecting": "Paymega ulanmoqda…", "payButton": "Payme orqali to'lash" }, - "unknownUser":"Foydalanuvchi topilmadi", - "file":"Fayl", - "upload":"Sertifikatni yuklab olish" + "unknownUser": "Foydalanuvchi topilmadi", + "file": "Fayl", + "upload": "Sertifikatni yuklab olish" } diff --git a/src/widgets/detail/pageDetail.tsx b/src/widgets/detail/pageDetail.tsx index b1d0306..1d4ba32 100644 --- a/src/widgets/detail/pageDetail.tsx +++ b/src/widgets/detail/pageDetail.tsx @@ -2,6 +2,8 @@ import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; +import { useTranslations } from 'next-intl'; +import { useParams } from 'next/navigation'; import { links } from '@/shared/request/links'; import { apiRequest } from '@/shared/request/apiRequest'; import Sertifikat from './sertifikat'; @@ -69,8 +71,8 @@ function parseHighlightedText(text_res: string): React.ReactNode[] { }); } -function formatDate(iso: string): string { - return new Date(iso).toLocaleString('uz-UZ', { +function formatDate(iso: string, locale: string): string { + return new Date(iso).toLocaleString(locale, { year: 'numeric', month: '2-digit', day: '2-digit', @@ -243,8 +245,9 @@ function LoadingSkeleton() { } // ── Error State ─────────────────────────────────────────────────────────────── +type TFunction = ReturnType; -function ErrorState({ message }: { message?: string }) { +function ErrorState({ message, t }: { message?: string; t: TFunction }) { return (
@@ -262,9 +265,11 @@ function ErrorState({ message }: { message?: string }) { />
-

Failed to load document

+

+ {t('failedToLoadDocument')} +

- {message ?? 'An unexpected error occurred.'} + {message ?? t('unexpectedError')}

); @@ -273,6 +278,9 @@ function ErrorState({ message }: { message?: string }) { // ── Main Page ───────────────────────────────────────────────────────────────── export default function DocumentDetailPage({ id }: { id: number }) { + const t = useTranslations('DetailPage'); + const { locale } = useParams() as { locale: string }; + const { data: doc, isLoading, @@ -305,7 +313,7 @@ export default function DocumentDetailPage({ id }: { id: number }) { return (
- +
); } @@ -329,9 +337,9 @@ export default function DocumentDetailPage({ id }: { id: number }) { low: 'text-emerald-600 bg-emerald-50 border-emerald-200', }; const aiLabel: Record = { - high: 'AI Content Detected', - medium: 'Possible AI Content', - low: 'Likely Original', + high: t('aiContentDetected'), + medium: t('possibleAiContent'), + low: t('likelyOriginal'), }; // Partition analyze_text dynamically: @@ -377,7 +385,7 @@ export default function DocumentDetailPage({ id }: { id: number }) {

- Document #{doc.id} + {t('documentNumber', { id: doc.id })}

{doc.title} @@ -407,7 +415,7 @@ export default function DocumentDetailPage({ id }: { id: number }) { d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /> - Download PDF + {t('downloadPdf')} )}

@@ -431,7 +439,7 @@ export default function DocumentDetailPage({ id }: { id: number }) { d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /> - Created: {formatDate(doc.created_at)} + {t('created')}: {formatDate(doc.created_at, locale)} - Updated: {formatDate(doc.updated_at)} + {t('updated')}: {formatDate(doc.updated_at, locale)} {res?.hash && ( @@ -464,14 +472,14 @@ export default function DocumentDetailPage({ id }: { id: number }) { d="M7 20l4-16m2 16l4-16M6 9h14M4 15h14" /> - Hash: {res.hash} + {t('hash')}: {res.hash} )} {/* ── Score Overview ── */} {res && ( -
+

{aiLabel[aiRisk]}

- AI probability score: {res.ai}% — content - may have been generated or assisted by an AI model. + {t('aiProbabilityText', { score: res.ai })}

@@ -522,7 +529,7 @@ export default function DocumentDetailPage({ id }: { id: number }) { {/* ── Document Text ── */} {(res?.text || textRes) && ( -
+
{(['highlighted', 'plain'] as const).map((tab) => ( @@ -536,8 +543,8 @@ export default function DocumentDetailPage({ id }: { id: number }) { }`} > {tab === 'highlighted' - ? 'Plagiarism Highlights' - : 'Plain Text'} + ? t('plagiarismHighlights') + : t('plainText')} ))}
@@ -553,7 +560,7 @@ export default function DocumentDetailPage({ id }: { id: number }) { {activeTab === 'highlighted' && (
- Highlighted fragments indicate potential plagiarism matches + {t('highlightedHint')}
)}
@@ -562,7 +569,7 @@ export default function DocumentDetailPage({ id }: { id: number }) { {/* ── Text Statistics (all numeric / non-boolean keys) ── */} {statKeys.length > 0 && ( -
+
{statKeys.map((key) => ( @@ -573,7 +580,7 @@ export default function DocumentDetailPage({ id }: { id: number }) { {/* ── Detection Flags (all boolean Yes/No keys) ── */} {flagKeys.length > 0 && ( -
+
{flagKeys.map((key) => { const val = analyze[key]; @@ -607,7 +614,7 @@ export default function DocumentDetailPage({ id }: { id: number }) { {/* ── Top Words (key detected by "топ"/"top" substring) ── */} {topWordsValue && ( -
+
{topWordsValue @@ -639,7 +646,10 @@ export default function DocumentDetailPage({ id }: { id: number }) { {/* ── Footer ── */} {result && (
- Result ID #{result.id} · Analyzed {formatDate(result.created_at)} + {t('resultFooter', { + id: result.id, + date: formatDate(result.created_at, locale), + })}
)} diff --git a/src/widgets/fileUpload/ui/Plagiraismcheckform.tsx b/src/widgets/fileUpload/ui/Plagiraismcheckform.tsx index 23ead3c..7cf519a 100644 --- a/src/widgets/fileUpload/ui/Plagiraismcheckform.tsx +++ b/src/widgets/fileUpload/ui/Plagiraismcheckform.tsx @@ -86,7 +86,7 @@ export function PlagiarismCheckForm() { {submission.status === 'success' && ( @@ -177,8 +177,7 @@ export function PlagiarismCheckForm() { {/* Footer note */}

- Your document is processed securely and not stored beyond the - analysis period. + {t('secureNote')}