From 6041e6a719a4b044085561f1412cf2d862a32ecd Mon Sep 17 00:00:00 2001 From: "nabijonovdavronbek619@gmail.com" Date: Wed, 1 Apr 2026 10:53:42 +0500 Subject: [PATCH] translation added --- src/features/auth/login/ui/form.tsx | 30 ++--- src/features/auth/register/ui/form.tsx | 52 +++----- src/shared/config/i18n/messages/en.json | 103 ++++++++++++++++ src/shared/config/i18n/messages/ru.json | 103 ++++++++++++++++ src/shared/config/i18n/messages/uz.d.json.ts | 105 +++++++++++++++- src/shared/config/i18n/messages/uz.json | 105 +++++++++++++++- src/widgets/home/components/Hero.tsx | 43 +++++-- src/widgets/home/components/InfoSection.tsx | 119 ++++++++++++------- src/widgets/home/components/StartButton.tsx | 4 +- src/widgets/home/components/StepCard.tsx | 44 ++++++- src/widgets/home/components/StepsSection.tsx | 12 +- src/widgets/home/components/Ticker.tsx | 24 +++- src/widgets/paymentModal/ui/Paymebutton.tsx | 6 +- src/widgets/paymentModal/ui/Paymentmodal.tsx | 22 ++-- src/widgets/paymentModal/ui/Pricesummary.tsx | 8 +- 15 files changed, 650 insertions(+), 130 deletions(-) diff --git a/src/features/auth/login/ui/form.tsx b/src/features/auth/login/ui/form.tsx index ab00bd1..67d567a 100644 --- a/src/features/auth/login/ui/form.tsx +++ b/src/features/auth/login/ui/form.tsx @@ -11,9 +11,12 @@ import { MotionWrapper } from '../../../../shared/ui/motion'; import { useLoginForm } from '../lib/useLoginForm'; import { useLoginModal } from '@/shared/zustand/auth'; import Link from 'next/link'; +import { useTranslations } from 'next-intl'; export function LoginForm() { const [isFocused, setIsFocused] = useState(false); + const t = useTranslations('Auth.Login'); + const tCommon = useTranslations('Common'); const { phone, setPhone, submit, error, loading } = useLoginForm(); const toggleLoginModal = useLoginModal((state) => state.toggleLoginModal); @@ -49,14 +52,12 @@ export function LoginForm() { {/* Header */}

- Xush kelibsiz + {t('welcome')}

- Kirish + {t('title')}

-

- Telefon raqamingizni kiriting. -

+

{t('description')}

{/* Phone field */} @@ -65,7 +66,7 @@ export function LoginForm() { htmlFor="phone" className="text-[0.7rem] font-medium tracking-widest uppercase text-stone-500" > - Telefon raqam + {t('phoneLabel')}
setIsFocused(true)} @@ -98,11 +99,12 @@ export function LoginForm() { {/* Digit counter / complete hint */}
- {phone.length > 0 && `${phone.length} ta raqam kiritildi`} + {phone.length > 0 && + t('digitsEntered', { count: phone.length })} {phone.length === 9 && ( - ✓ To‘liq + {tCommon('complete')} )}
@@ -130,10 +132,10 @@ export function LoginForm() { {loading ? ( - Yuborilmoqda… + {t('sending')} ) : ( - 'Kodni yuborish' + t('sendCode') )} @@ -141,19 +143,19 @@ export function LoginForm() {
- yoki + {tCommon('or')}
{/* Register hint */}

- Hisobingiz yo‘qmi? + {t('registerPrompt')} - Ro‘yxatdan o‘tish + {t('registerLink')}

diff --git a/src/features/auth/register/ui/form.tsx b/src/features/auth/register/ui/form.tsx index 0269f5f..61a3b7d 100644 --- a/src/features/auth/register/ui/form.tsx +++ b/src/features/auth/register/ui/form.tsx @@ -4,6 +4,7 @@ import React, { useCallback } from 'react'; import { useRegisterForm } from '../lib/useRegisterForm'; import { formatPhone, normalizeDigits } from '@/shared/lib/formatPhone'; import PhonePrefix from '@/shared/ui/phonePrefix'; +import { useTranslations } from 'next-intl'; function Field({ id, @@ -64,6 +65,8 @@ function Field({ export function RegisterFormUI() { const [phone, setPhone] = React.useState(''); + const t = useTranslations('Auth.Register'); + const tCommon = useTranslations('Common'); const { registerData, errors, @@ -97,11 +100,9 @@ export function RegisterFormUI() { ✓

- You‘re registered + {t('successTitle')}

-

- We‘ll be in touch shortly. -

+

{t('successMessage')}

); @@ -112,14 +113,12 @@ export function RegisterFormUI() {
{/* Header */}

- Create account + {t('headerLabel')}

- Register + {t('title')}

-

- Fill in your details to get started. -

+

{t('description')}

{/* Name + Surname row */} @@ -128,7 +127,7 @@ export function RegisterFormUI() { id="name" name="name" label="Name" - placeholder="Ali" + placeholder={t('namePlaceholder')} value={registerData.name} onChange={handleChange} error={errors.name} @@ -137,7 +136,7 @@ export function RegisterFormUI() { id="surname" name="surname" label="Surname" - placeholder="Karimov" + placeholder={t('surnamePlaceholder')} value={registerData.surname} onChange={handleChange} error={errors.surname} @@ -150,7 +149,7 @@ export function RegisterFormUI() { htmlFor="phone" className="text-[0.7rem] font-medium tracking-widest uppercase text-stone-500" > - Telefon raqam + {t('phoneLabel')}
setIsFocused(true)} @@ -180,11 +179,11 @@ export function RegisterFormUI() { {/* Digit counter / complete hint */}
- {phone.length > 0 && `${phone.length} ta raqam kiritildi`} + {phone.length > 0 && t('digitsEntered', { count: phone.length })} {phone.length === 9 && ( - ✓ To‘liq + {tCommon('complete')} )}
@@ -204,24 +203,7 @@ export function RegisterFormUI() { htmlFor="oferta" className="cursor-pointer text-[0.78rem] leading-relaxed text-stone-500" > - I agree to the - - Terms of Service - - and - - Privacy Policy - + {t('terms')}
{errors.oferta && ( @@ -244,10 +226,10 @@ export function RegisterFormUI() { {loading ? ( - Submitting… + {tCommon('submitting')} ) : ( - 'Create account' + t('submitButton') )} diff --git a/src/shared/config/i18n/messages/en.json b/src/shared/config/i18n/messages/en.json index 49410a8..86f1d54 100644 --- a/src/shared/config/i18n/messages/en.json +++ b/src/shared/config/i18n/messages/en.json @@ -100,5 +100,108 @@ "downloadCertificate": "Download Certificate", "unknownError": "Unknown error", "words": "words" + }, + "Hero": { + "badge": "Academic Integrity Platform", + "mainHeading": "Is Your Work", + "mainHeadingItalic": "Truly Original?", + "description": "Plagiarism is presenting someone else's ideas or words as your own. In academia and professional life, it carries serious consequences. Our platform detects it in seconds — so you can submit with full confidence.", + "certificateNote": "Certificate issued within 24h" + }, + "Common": { + "startButton": "Start Checking →", + "complete": "✓ Complete", + "or": "or", + "submitting": "Submitting…", + "autoFilled": "Auto-filled", + "removeFile": "Remove file" + }, + "InfoSection": { + "label": "Why It Matters", + "heading": "Understanding Plagiarism" + }, + "StepsSection": { + "label": "Process", + "heading": "How It Works", + "description": "Six simple steps from upload to certified report.", + "ctaHeading": "Ready to verify your document?", + "ctaDescription": "Get your originality certificate in under 24 hours." + }, + "Steps": { + "step1Title": "Click Start", + "step1Desc": "Begin your plagiarism check journey", + "step2Title": "Register or Log In", + "step2Desc": "Create an account or sign in to your existing one", + "step3Title": "Upload Document", + "step3Desc": "Upload your PDF, DOC, DOCX, or TXT file (max 20MB)", + "step4Title": "Send for Check", + "step4Desc": "Submit your document for comprehensive analysis", + "step5Title": "Complete Payment", + "step5Desc": "Pay securely for your plagiarism check service", + "step6Title": "Get Your Report", + "step6Desc": "Receive detailed results and certificate within 24 hours" + }, + "Stats": { + "accuracy": "Detection accuracy", + "documents": "Documents checked", + "formats": "Supported formats", + "turnaround": "Report turnaround" + }, + "InfoCards": { + "card1Title": "What is Plagiarism?", + "card1Desc": "Plagiarism occurs when someone uses another person's ideas, words, or work without proper credit. It can be intentional or unintentional.", + "card2Title": "Why Check Your Document?", + "card2Desc": "Ensure academic integrity, avoid penalties, and maintain your reputation. Our service provides comprehensive plagiarism detection.", + "card3Title": "What You Get", + "card3Desc": "Detailed plagiarism report, similarity percentage, matched sources, and an official certificate of originality." + }, + "Ticker": { + "item1": "Originality Verified", + "item2": "Academic Integrity", + "item3": "Trusted Reports", + "item4": "Deep Analysis", + "item5": "Fast Results", + "item6": "Official Certificate" + }, + "Auth": { + "Login": { + "welcome": "Welcome back", + "title": "Login", + "description": "Enter your phone number to continue.", + "phoneLabel": "Phone number", + "phonePlaceholder": "90 123 45 67", + "digitsEntered": "{count} digits entered", + "sending": "Sending…", + "sendCode": "Send code", + "registerPrompt": "Don't have an account?", + "registerLink": "Register" + }, + "Register": { + "successTitle": "You're registered", + "successMessage": "We'll be in touch shortly.", + "headerLabel": "Create account", + "title": "Register", + "description": "Fill in your details to get started.", + "phoneLabel": "Phone number", + "phonePlaceholder": "90 123 45 67", + "digitsEntered": "{count} digits entered", + "namePlaceholder": "Ali", + "surnamePlaceholder": "Karimov", + "terms": "I agree to the Terms of Service and Privacy Policy", + "submitButton": "Create account" + } + }, + "Payment": { + "title": "Payment", + "description": "Review your order and pay securely", + "orderSummary": "Order Summary", + "certificateIncluded": "Certificate of completion included", + "paymentMethod": "Payment Method", + "security": "Secured by Payme · SSL encrypted", + "serviceFee": "Service fee", + "certificateLabel": "Certificate", + "total": "Total", + "connecting": "Connecting to Payme…", + "payButton": "Pay with Payme" } } diff --git a/src/shared/config/i18n/messages/ru.json b/src/shared/config/i18n/messages/ru.json index 13ae46a..ee3c5ce 100644 --- a/src/shared/config/i18n/messages/ru.json +++ b/src/shared/config/i18n/messages/ru.json @@ -100,5 +100,108 @@ "downloadCertificate": "Скачать сертификат", "unknownError": "Неизвестная ошибка", "words": "слов" + }, + "Hero": { + "badge": "Платформа академической честности", + "mainHeading": "Ваша работа", + "mainHeadingItalic": "Действительно оригинальна?", + "description": "Плагиат - это представление идей или слов другого человека как своих собственных. В академической и профессиональной жизни это несет серьезные последствия. Наша платформа обнаруживает его за секунды — чтобы вы могли отправлять с полной уверенностью.", + "certificateNote": "Сертификат выдается в течение 24 часов" + }, + "Common": { + "startButton": "Начать проверку →", + "complete": "✓ Завершено", + "or": "или", + "submitting": "Отправка…", + "autoFilled": "Автозаполнено", + "removeFile": "Удалить файл" + }, + "InfoSection": { + "label": "Почему это важно", + "heading": "Понимание плагиата" + }, + "StepsSection": { + "label": "Процесс", + "heading": "Как это работает", + "description": "Шесть простых шагов от загрузки до сертифицированного отчета.", + "ctaHeading": "Готовы проверить ваш документ?", + "ctaDescription": "Получите сертификат оригинальности менее чем за 24 часа." + }, + "Steps": { + "step1Title": "Нажмите Начать", + "step1Desc": "Начните ваше путешествие по проверке на плагиат", + "step2Title": "Зарегистрируйтесь или войдите", + "step2Desc": "Создайте аккаунт или войдите в существующий", + "step3Title": "Загрузите документ", + "step3Desc": "Загрузите ваш PDF, DOC, DOCX или TXT файл (макс 20МБ)", + "step4Title": "Отправьте на проверку", + "step4Desc": "Отправьте ваш документ на комплексный анализ", + "step5Title": "Завершите оплату", + "step5Desc": "Оплатите безопасно услугу проверки на плагиат", + "step6Title": "Получите ваш отчет", + "step6Desc": "Получите подробные результаты и сертификат в течение 24 часов" + }, + "Stats": { + "accuracy": "Точность обнаружения", + "documents": "Проверено документов", + "formats": "Поддерживаемые форматы", + "turnaround": "Время выполнения отчета" + }, + "InfoCards": { + "card1Title": "Что такое плагиат?", + "card1Desc": "Плагиат происходит, когда кто-то использует идеи, слова или работу другого человека без надлежащего указания. Это может быть преднамеренным или непреднамеренным.", + "card2Title": "Почему проверять ваш документ?", + "card2Desc": "Обеспечьте академическую честность, избегайте штрафов и поддерживайте вашу репутацию. Наш сервис предоставляет комплексное обнаружение плагиата.", + "card3Title": "Что вы получаете", + "card3Desc": "Подробный отчет о плагиате, процент схожести, найденные источники и официальный сертификат оригинальности." + }, + "Ticker": { + "item1": "Оригинальность подтверждена", + "item2": "Академическая честность", + "item3": "Надежные отчеты", + "item4": "Глубокий анализ", + "item5": "Быстрые результаты", + "item6": "Официальный сертификат" + }, + "Auth": { + "Login": { + "welcome": "Добро пожаловать обратно", + "title": "Вход", + "description": "Введите ваш номер телефона для продолжения.", + "phoneLabel": "Номер телефона", + "phonePlaceholder": "90 123 45 67", + "digitsEntered": "Введено {count} цифр", + "sending": "Отправка…", + "sendCode": "Отправить код", + "registerPrompt": "Нет аккаунта?", + "registerLink": "Зарегистрироваться" + }, + "Register": { + "successTitle": "Вы зарегистрированы", + "successMessage": "Мы свяжемся с вами в ближайшее время.", + "headerLabel": "Создать аккаунт", + "title": "Регистрация", + "description": "Заполните ваши данные, чтобы начать.", + "phoneLabel": "Номер телефона", + "phonePlaceholder": "90 123 45 67", + "digitsEntered": "Введено {count} цифр", + "namePlaceholder": "Али", + "surnamePlaceholder": "Каримов", + "terms": "Я согласен с Условиями обслуживания и Политикой конфиденциальности", + "submitButton": "Создать аккаунт" + } + }, + "Payment": { + "title": "Оплата", + "description": "Просмотрите ваш заказ и оплатите безопасно", + "orderSummary": "Сводка заказа", + "certificateIncluded": "Включен сертификат завершения", + "paymentMethod": "Способ оплаты", + "security": "Защищено Payme · SSL шифрование", + "serviceFee": "Стоимость услуги", + "certificateLabel": "Сертификат", + "total": "Итого", + "connecting": "Подключение к Payme…", + "payButton": "Оплатить через Payme" } } diff --git a/src/shared/config/i18n/messages/uz.d.json.ts b/src/shared/config/i18n/messages/uz.d.json.ts index 7b0caa8..709d3f1 100644 --- a/src/shared/config/i18n/messages/uz.d.json.ts +++ b/src/shared/config/i18n/messages/uz.d.json.ts @@ -95,7 +95,7 @@ declare const messages: { processedAt: 'Qayta ishlangan'; certificate: 'Sertifikat'; noCertificate: 'Bu tekshiruv uchun sertifikat berilmagan.'; - noCertificateHighSimilarity: "Yuoqori o'xshashlik natijasida sertifikatlar berilmaydi."; + noCertificateHighSimilarity: "Yuqori o'xshashlik natijasida sertifikatlar berilmaydi."; issued: 'Berilgan'; expires: 'Muddati tugaydi'; issuer: 'Beruvchi'; @@ -104,5 +104,108 @@ declare const messages: { unknownError: "Noma'lum xato"; words: "so'z"; }; + Hero: { + badge: 'Akademik halollik platformasi'; + mainHeading: 'Sizning ishingiz'; + mainHeadingItalic: 'Haqiqatan ham originalmi?'; + description: "Plagiat - bu boshqa birovning g'oyalarini yoki so'zlarini o'z g'oyalar yoki so'zlari sifatida taqdim etish. Akademik va professional hayotda bu jiddiy oqibatlarga olib keladi. Bizning platformamiz buni soniyalar ichida aniqlaydi — shuning uchun siz to'liq ishonch bilan yuborishingiz mumkin."; + certificateNote: 'Sertifikat 24 soat ichida beriladi'; + }; + Common: { + startButton: 'Tekshirishni boshlash →'; + complete: "✓ To'liq"; + or: 'yoki'; + submitting: 'Yuborilmoqda…'; + autoFilled: "Avto-to'ldirilgan"; + removeFile: 'Faylni olib tashlash'; + }; + InfoSection: { + label: 'Nima uchun bu muhim'; + heading: 'Plagiatni tushunish'; + }; + StepsSection: { + label: 'Jarayon'; + heading: 'Bu qanday ishlaydi'; + description: 'Yuklashdan sertifikatlangan hisobotgacha oltita oddiy qadam.'; + ctaHeading: 'Hujjatingizni tekshirishga tayyormisiz?'; + ctaDescription: '24 soat ichida orijinallik sertifikatini oling.'; + }; + Steps: { + step1Title: 'Boshlash tugmasini bosing'; + step1Desc: 'Plagiat tekshiruvi sayohatini boshlang'; + step2Title: "Ro'yxatdan o'ting yoki kiring"; + step2Desc: 'Hisob yarating yoki mavjud hisobingizga kiring'; + step3Title: 'Hujjatni yuklang'; + step3Desc: 'PDF, DOC, DOCX yoki TXT faylingizni yuklang (maks 20MB)'; + step4Title: 'Tekshirish uchun yuboring'; + step4Desc: 'Hujjatingizni kompleks tahlil uchun yuboring'; + step5Title: "To'lovni amalga oshiring"; + step5Desc: "Plagiat tekshiruvi xizmatini xavfsiz to'lang"; + step6Title: 'Hisobotingizni oling'; + step6Desc: '24 soat ichida batafsil natijalar va sertifikatni oling'; + }; + Stats: { + accuracy: 'Aniqlash aniqligi'; + documents: 'Tekshirilgan hujjatlar'; + formats: "Qo'llab-quvvatlangan formatlar"; + turnaround: 'Hisobot tayyorlanish vaqti'; + }; + InfoCards: { + card1Title: 'Plagiat nima?'; + card1Desc: "Plagiat - bu kimdir boshqa birovning g'oyalarini, so'zlarini yoki ishini tegishli kredit bermay ishlatganda yuzaga keladi. Bu qasddan yoki qasdsiz bo'lishi mumkin."; + card2Title: 'Nima uchun hujjatingizni tekshirish kerak?'; + card2Desc: "Akademik halollikni ta'minlang, jarimalardan qoching va obro'ingizni saqlang. Bizning xizmatimiz kompleks plagiat aniqlashni taqdim etadi."; + card3Title: 'Siz nima olasiz'; + card3Desc: "Batafsil plagiat hisoboti, o'xshashlik foizi, topilgan manbalar va orijinallikning rasmiy sertifikati."; + }; + Ticker: { + item1: 'Orijinallik tasdiqlangan'; + item2: 'Akademik halollik'; + item3: 'Ishonchli hisobotlar'; + item4: 'Chuqur tahlil'; + item5: 'Tez natijalar'; + item6: 'Rasmiy sertifikat'; + }; + Auth: { + Login: { + welcome: 'Xush kelibsiz'; + title: 'Kirish'; + description: 'Davomini davom ettirish uchun telefon raqamingizni kiriting.'; + phoneLabel: 'Telefon raqami'; + phonePlaceholder: '90 123 45 67'; + digitsEntered: '{count} ta raqam kiritildi'; + sending: 'Yuborilmoqda…'; + sendCode: 'Kodni yuborish'; + registerPrompt: "Hisobingiz yo'qmi?"; + registerLink: "Ro'yxatdan o'tish"; + }; + Register: { + successTitle: "Siz ro'yxatdan o'tdingiz"; + successMessage: "Tez orada siz bilan bog'lanamiz."; + headerLabel: 'Hisob yaratish'; + title: "Ro'yxatdan o'tish"; + description: "Boshlash uchun ma'lumotlaringizni to'ldiring."; + phoneLabel: 'Telefon raqami'; + phonePlaceholder: '90 123 45 67'; + digitsEntered: '{count} ta raqam kiritildi'; + namePlaceholder: 'Ali'; + surnamePlaceholder: 'Karimov'; + terms: "Men Xizmat ko'rsatish shartlari va Maxfiylik siyosatiga roziman"; + submitButton: 'Hisob yaratish'; + }; + }; + Payment: { + title: "To'lov"; + description: "Buyurtmangizni ko'rib chiqing va xavfsiz to'lang"; + orderSummary: "Buyurtma umumiy ko'rinishi"; + certificateIncluded: 'Tugallanish sertifikati kiritilgan'; + paymentMethod: "To'lov usuli"; + security: 'Payme tomonidan himoyalangan · SSL shifrlash'; + serviceFee: "Xizmat to'lovi"; + certificateLabel: 'Sertifikat'; + total: 'Jami'; + connecting: 'Paymega ulanmoqda…'; + payButton: "Payme orqali to'lash"; + }; }; export default messages; diff --git a/src/shared/config/i18n/messages/uz.json b/src/shared/config/i18n/messages/uz.json index c6aecb0..bf1078e 100644 --- a/src/shared/config/i18n/messages/uz.json +++ b/src/shared/config/i18n/messages/uz.json @@ -92,7 +92,7 @@ "processedAt": "Qayta ishlangan", "certificate": "Sertifikat", "noCertificate": "Bu tekshiruv uchun sertifikat berilmagan.", - "noCertificateHighSimilarity": "Yuoqori o'xshashlik natijasida sertifikatlar berilmaydi.", + "noCertificateHighSimilarity": "Yuqori o'xshashlik natijasida sertifikatlar berilmaydi.", "issued": "Berilgan", "expires": "Muddati tugaydi", "issuer": "Beruvchi", @@ -100,5 +100,108 @@ "downloadCertificate": "Sertifikatni yuklab olish", "unknownError": "Noma'lum xato", "words": "so'z" + }, + "Hero": { + "badge": "Akademik halollik platformasi", + "mainHeading": "Sizning ishingiz", + "mainHeadingItalic": "Haqiqatan ham originalmi?", + "description": "Plagiat - bu boshqa birovning g'oyalarini yoki so'zlarini o'z g'oyalar yoki so'zlari sifatida taqdim etish. Akademik va professional hayotda bu jiddiy oqibatlarga olib keladi. Bizning platformamiz buni soniyalar ichida aniqlaydi — shuning uchun siz to'liq ishonch bilan yuborishingiz mumkin.", + "certificateNote": "Sertifikat 24 soat ichida beriladi" + }, + "Common": { + "startButton": "Tekshirishni boshlash →", + "complete": "✓ To'liq", + "or": "yoki", + "submitting": "Yuborilmoqda…", + "autoFilled": "Avto-to'ldirilgan", + "removeFile": "Faylni olib tashlash" + }, + "InfoSection": { + "label": "Nima uchun bu muhim", + "heading": "Plagiatni tushunish" + }, + "StepsSection": { + "label": "Jarayon", + "heading": "Bu qanday ishlaydi", + "description": "Yuklashdan sertifikatlangan hisobotgacha oltita oddiy qadam.", + "ctaHeading": "Hujjatingizni tekshirishga tayyormisiz?", + "ctaDescription": "24 soat ichida orijinallik sertifikatini oling." + }, + "Steps": { + "step1Title": "Boshlash tugmasini bosing", + "step1Desc": "Plagiat tekshiruvi sayohatini boshlang", + "step2Title": "Ro'yxatdan o'ting yoki kiring", + "step2Desc": "Hisob yarating yoki mavjud hisobingizga kiring", + "step3Title": "Hujjatni yuklang", + "step3Desc": "PDF, DOC, DOCX yoki TXT faylingizni yuklang (maks 20MB)", + "step4Title": "Tekshirish uchun yuboring", + "step4Desc": "Hujjatingizni kompleks tahlil uchun yuboring", + "step5Title": "To'lovni amalga oshiring", + "step5Desc": "Plagiat tekshiruvi xizmatini xavfsiz to'lang", + "step6Title": "Hisobotingizni oling", + "step6Desc": "24 soat ichida batafsil natijalar va sertifikatni oling" + }, + "Stats": { + "accuracy": "Aniqlash aniqligi", + "documents": "Tekshirilgan hujjatlar", + "formats": "Qo'llab-quvvatlangan formatlar", + "turnaround": "Hisobot tayyorlanish vaqti" + }, + "InfoCards": { + "card1Title": "Plagiat nima?", + "card1Desc": "Plagiat - bu kimdir boshqa birovning g'oyalarini, so'zlarini yoki ishini tegishli kredit bermay ishlatganda yuzaga keladi. Bu qasddan yoki qasdsiz bo'lishi mumkin.", + "card2Title": "Nima uchun hujjatingizni tekshirish kerak?", + "card2Desc": "Akademik halollikni ta'minlang, jarimalardan qoching va obro'ingizni saqlang. Bizning xizmatimiz kompleks plagiat aniqlashni taqdim etadi.", + "card3Title": "Siz nima olasiz", + "card3Desc": "Batafsil plagiat hisoboti, o'xshashlik foizi, topilgan manbalar va orijinallikning rasmiy sertifikati." + }, + "Ticker": { + "item1": "Orijinallik tasdiqlangan", + "item2": "Akademik halollik", + "item3": "Ishonchli hisobotlar", + "item4": "Chuqur tahlil", + "item5": "Tez natijalar", + "item6": "Rasmiy sertifikat" + }, + "Auth": { + "Login": { + "welcome": "Xush kelibsiz", + "title": "Kirish", + "description": "Davomini davom ettirish uchun telefon raqamingizni kiriting.", + "phoneLabel": "Telefon raqami", + "phonePlaceholder": "90 123 45 67", + "digitsEntered": "{count} ta raqam kiritildi", + "sending": "Yuborilmoqda…", + "sendCode": "Kodni yuborish", + "registerPrompt": "Hisobingiz yo'qmi?", + "registerLink": "Ro'yxatdan o'tish" + }, + "Register": { + "successTitle": "Siz ro'yxatdan o'tdingiz", + "successMessage": "Tez orada siz bilan bog'lanamiz.", + "headerLabel": "Hisob yaratish", + "title": "Ro'yxatdan o'tish", + "description": "Boshlash uchun ma'lumotlaringizni to'ldiring.", + "phoneLabel": "Telefon raqami", + "phonePlaceholder": "90 123 45 67", + "digitsEntered": "{count} ta raqam kiritildi", + "namePlaceholder": "Ali", + "surnamePlaceholder": "Karimov", + "terms": "Men Xizmat ko'rsatish shartlari va Maxfiylik siyosatiga roziman", + "submitButton": "Hisob yaratish" + } + }, + "Payment": { + "title": "To'lov", + "description": "Buyurtmangizni ko'rib chiqing va xavfsiz to'lang", + "orderSummary": "Buyurtma umumiy ko'rinishi", + "certificateIncluded": "Tugallanish sertifikati kiritilgan", + "paymentMethod": "To'lov usuli", + "security": "Payme tomonidan himoyalangan · SSL shifrlash", + "serviceFee": "Xizmat to'lovi", + "certificateLabel": "Sertifikat", + "total": "Jami", + "connecting": "Paymega ulanmoqda…", + "payButton": "Payme orqali to'lash" } } diff --git a/src/widgets/home/components/Hero.tsx b/src/widgets/home/components/Hero.tsx index 3b88a6a..612be62 100644 --- a/src/widgets/home/components/Hero.tsx +++ b/src/widgets/home/components/Hero.tsx @@ -9,6 +9,7 @@ import DocIllustration from './DocIllustration'; import Section from './Section'; import Stat from './Stat'; import StartButton from './StartButton'; +import { useTranslations } from 'next-intl'; interface HeroProps { onStart: () => void; @@ -17,6 +18,23 @@ interface HeroProps { const Hero: FC = ({ onStart, blobY }) => { const isMobile = useIsMobile(); + const t = useTranslations('Hero'); + const tStats = useTranslations('Stats'); + + const getTranslatedLabel = (label: string) => { + switch (label) { + case 'Detection accuracy': + return tStats('accuracy'); + case 'Documents checked': + return tStats('documents'); + case 'Supported formats': + return tStats('formats'); + case 'Report turnaround': + return tStats('turnaround'); + default: + return label; + } + }; return (
@@ -71,7 +89,7 @@ const Hero: FC = ({ onStart, blobY }) => { > {/* Text block */}
- Academic Integrity Platform + {t('badge')} = ({ onStart, blobY }) => { marginBottom: 4, }} > - Is Your Work + {t('mainHeading')} = ({ onStart, blobY }) => { marginBottom: 28, }} > - Truly Original? + {t('mainHeadingItalic')} @@ -117,10 +135,7 @@ const Hero: FC = ({ onStart, blobY }) => { marginBottom: 40, }} > - Plagiarism is presenting someone else‘s ideas or words as - your own. In academia and professional life, it carries serious - consequences. Our platform detects it in seconds — so you can - submit with full confidence. + {t('description')} = ({ onStart, blobY }) => { fontFamily: "'DM Mono', monospace", }} > - Certificate issued within 24h + {t('certificateNote')}
@@ -165,9 +180,15 @@ const Hero: FC = ({ onStart, blobY }) => { borderTop: `1px solid ${C.border}`, }} > - {STATS.map((s) => ( - - ))} + {STATS.map((s) => { + return ( + + ); + })}
diff --git a/src/widgets/home/components/InfoSection.tsx b/src/widgets/home/components/InfoSection.tsx index 35ca690..eaffb4a 100644 --- a/src/widgets/home/components/InfoSection.tsx +++ b/src/widgets/home/components/InfoSection.tsx @@ -5,51 +5,82 @@ import { C } from '../tokens'; import { INFO_CARDS } from '../constants'; import InfoCard from './InfoCard'; import Section from './Section'; +import { useTranslations } from 'next-intl'; -const InfoSection: FC = () => ( -
-
- {/* Heading */} - -

- Why It Matters -

-

- Understanding Plagiarism -

-
+const InfoSection: FC = () => { + const t = useTranslations('InfoSection'); + const tCards = useTranslations('InfoCards'); - {/* Cards */} -
- {INFO_CARDS.map((card) => ( - - ))} -
-
-
-); + const getTranslatedCard = (card: (typeof INFO_CARDS)[0]) => { + switch (card.title) { + case 'What is Plagiarism?': + return { + ...card, + title: tCards('card1Title'), + text: tCards('card1Desc'), + }; + case 'Why Check Your Document?': + return { + ...card, + title: tCards('card2Title'), + text: tCards('card2Desc'), + }; + case 'What You Get': + return { + ...card, + title: tCards('card3Title'), + text: tCards('card3Desc'), + }; + default: + return card; + } + }; + + return ( +
+
+ {/* Heading */} + +

+ {t('label')} +

+

+ {t('heading')} +

+
+ + {/* Cards */} +
+ {INFO_CARDS.map((card) => ( + + ))} +
+
+
+ ); +}; export default InfoSection; diff --git a/src/widgets/home/components/StartButton.tsx b/src/widgets/home/components/StartButton.tsx index 4d2bde4..8e796c3 100644 --- a/src/widgets/home/components/StartButton.tsx +++ b/src/widgets/home/components/StartButton.tsx @@ -2,6 +2,7 @@ import { useState, type FC } from 'react'; import { motion } from 'framer-motion'; import { C } from '../tokens'; +import { useTranslations } from 'next-intl'; interface StartButtonProps { onClick: () => void; @@ -10,6 +11,7 @@ interface StartButtonProps { const StartButton: FC = ({ onClick, small = false }) => { const [hovered, setHovered] = useState(false); + const t = useTranslations('Common'); return ( = ({ onClick, small = false }) => { : `0 2px 8px ${C.accent}22`, }} > - Start Checking → + {t('startButton')} ); }; diff --git a/src/widgets/home/components/StepCard.tsx b/src/widgets/home/components/StepCard.tsx index 2fc7b39..e874d34 100644 --- a/src/widgets/home/components/StepCard.tsx +++ b/src/widgets/home/components/StepCard.tsx @@ -4,6 +4,7 @@ import { fadeUp } from '../animations'; import { C } from '../tokens'; import { STEPS } from '../constants'; import type { Step } from '../types'; +import { useTranslations } from 'next-intl'; interface StepCardProps { step: Step; @@ -14,6 +15,45 @@ const StepCard: FC = ({ step, index }) => { const ref = useRef(null); const inView = useInView(ref, { once: true, margin: '-50px' }); const isLast = index === STEPS.length - 1; + const t = useTranslations('Steps'); + + const getStepTitle = (num: string) => { + switch (num) { + case '01': + return t('step1Title'); + case '02': + return t('step2Title'); + case '03': + return t('step3Title'); + case '04': + return t('step4Title'); + case '05': + return t('step5Title'); + case '06': + return t('step6Title'); + default: + return step.title; + } + }; + + const getStepDesc = (num: string) => { + switch (num) { + case '01': + return t('step1Desc'); + case '02': + return t('step2Desc'); + case '03': + return t('step3Desc'); + case '04': + return t('step4Desc'); + case '05': + return t('step5Desc'); + case '06': + return t('step6Desc'); + default: + return step.desc; + } + }; return ( = ({ step, index }) => { fontWeight: 700, }} > - {step.title} + {getStepTitle(step.num)}

= ({ step, index }) => { margin: 0, }} > - {step.desc} + {getStepDesc(step.num)}

diff --git a/src/widgets/home/components/StepsSection.tsx b/src/widgets/home/components/StepsSection.tsx index f203ff7..6872a92 100644 --- a/src/widgets/home/components/StepsSection.tsx +++ b/src/widgets/home/components/StepsSection.tsx @@ -7,6 +7,7 @@ import { useIsMobile } from '../hooks/useIsMobile'; import Section from './Section'; import StartButton from './StartButton'; import StepCard from './StepCard'; +import { useTranslations } from 'next-intl'; interface StepsSectionProps { stepsRef: React.RefObject; @@ -15,6 +16,7 @@ interface StepsSectionProps { const StepsSection: FC = ({ stepsRef, onScrollTop }) => { const isMobile = useIsMobile(); + const t = useTranslations('StepsSection'); return (
= ({ stepsRef, onScrollTop }) => { marginBottom: 10, }} > - Process + {t('label')}

= ({ stepsRef, onScrollTop }) => { lineHeight: 1.2, }} > - How It Works + {t('heading')}

= ({ stepsRef, onScrollTop }) => { lineHeight: 1.75, }} > - Six simple steps from upload to certified report. + {t('description')}

@@ -112,10 +114,10 @@ const StepsSection: FC = ({ stepsRef, onScrollTop }) => { fontWeight: 700, }} > - Ready to verify your document? + {t('ctaHeading')}

- Get your originality certificate in under 24 hours. + {t('ctaDescription')}

diff --git a/src/widgets/home/components/Ticker.tsx b/src/widgets/home/components/Ticker.tsx index 688396b..65d9a7b 100644 --- a/src/widgets/home/components/Ticker.tsx +++ b/src/widgets/home/components/Ticker.tsx @@ -2,10 +2,32 @@ import type { FC } from 'react'; import { motion } from 'framer-motion'; import { C } from '../tokens'; import { TICKER_ITEMS } from '../constants'; +import { useTranslations } from 'next-intl'; const Ticker: FC = () => { + const t = useTranslations('Ticker'); const doubled = [...TICKER_ITEMS, ...TICKER_ITEMS]; + const getTranslatedItem = (item: string, index: number) => { + const itemIndex = index % TICKER_ITEMS.length; + switch (itemIndex) { + case 0: + return t('item1'); + case 1: + return t('item2'); + case 2: + return t('item3'); + case 3: + return t('item4'); + case 4: + return t('item5'); + case 5: + return t('item6'); + default: + return item; + } + }; + return (
{ color: i % 3 === 0 ? C.textMid : C.textMuted, }} > - {item} + {getTranslatedItem(item, i)} diff --git a/src/widgets/paymentModal/ui/Paymebutton.tsx b/src/widgets/paymentModal/ui/Paymebutton.tsx index 2a0d18a..f22cccc 100644 --- a/src/widgets/paymentModal/ui/Paymebutton.tsx +++ b/src/widgets/paymentModal/ui/Paymebutton.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { PaymentStatus } from '../lib/types'; +import { useTranslations } from 'next-intl'; // ─── Payme Logo SVG ──────────────────────────────────────────────────────────── @@ -64,13 +65,14 @@ export const PaymeButton: React.FC = ({ status, }) => { const isLoading = status === 'loading'; + const t = useTranslations('Payment'); return (
@@ -170,7 +172,7 @@ export const PaymentModal: React.FC = ({ {/* Order details */}

- Order Summary + {t('orderSummary')}

@@ -187,20 +189,20 @@ export const PaymentModal: React.FC = ({ > - Certificate of completion included + {t('certificateIncluded')} )} {/* Payment method label */}

- Payment Method + {t('paymentMethod')}

{/* Security note */} - + diff --git a/src/widgets/paymentModal/ui/Pricesummary.tsx b/src/widgets/paymentModal/ui/Pricesummary.tsx index 975404d..9ac44e5 100644 --- a/src/widgets/paymentModal/ui/Pricesummary.tsx +++ b/src/widgets/paymentModal/ui/Pricesummary.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { formatPrice } from '../lib/utils'; import { PriceSummaryProps } from '../lib/types'; +import { useTranslations } from 'next-intl'; // ─── Price Row ───────────────────────────────────────────────────────────────── @@ -53,25 +54,26 @@ export const PriceSummary: React.FC = ({ const total = hasCertificate ? pricing.serviceFee + pricing.certificateFee : pricing.serviceFee; + const t = useTranslations('Payment'); return (
{hasCertificate && ( )}