From 6185cdc4d3bf807f9c0cd295f67a22dcd34c1570 Mon Sep 17 00:00:00 2001 From: elnatansamuel25 Date: Tue, 17 Mar 2026 09:57:10 +0300 Subject: [PATCH] before locale --- locales/en.json | 418 ++++++++++++++++++++++++++++++++++++++++++++ localey.config.json | 4 + src/i18n/config.ts | 19 ++ src/i18n/hooks.ts | 10 ++ src/i18n/store.ts | 15 ++ 5 files changed, 466 insertions(+) create mode 100644 locales/en.json create mode 100644 localey.config.json create mode 100644 src/i18n/config.ts create mode 100644 src/i18n/hooks.ts create mode 100644 src/i18n/store.ts diff --git a/locales/en.json b/locales/en.json new file mode 100644 index 0000000..cf44a7c --- /dev/null +++ b/locales/en.json @@ -0,0 +1,418 @@ +{ + "app": { + "yaltopia_tickets_app": "Yaltopia Tickets App", + "scan_send_reconcile": "Scan. Send. Reconcile.", + "get_started": "Get started" + }, + "index": { + "available_balance": "Available Balance", + "": "·", + "pending": "Pending", + "income": "Income", + "company": "Company", + "scan_sms": "Scan SMS", + "create_proforma": "Create Proforma", + "history": "History", + "recent_activity": "Recent Activity", + "view_all": "View all", + "proforma": "·\n Proforma", + "no_transactions_yet": "No transactions yet", + "create_a_proforma_invoice_to": "Create a proforma invoice to get started.", + "documents": "Documents", + "uploaded_invoices_scans_and_attachments": "Uploaded invoices, scans, and attachments. Synced with your account.", + "upload_document": "Upload document", + "back": "Back", + "notifications": "Notifications", + "no_notifications": "No notifications", + "pull_to_refresh_to_check": "Pull to refresh to check for new notifications.", + "reports": "Reports", + "monthly_reports_and_pdf_exports": "Monthly reports and PDF exports. Generate from the web app or view here.", + "generated": "Generated" + }, + "news": { + "tap_to_read_more": "Tap to read more", + "latest_news": "Latest News", + "no_latest_updates": "No latest updates", + "pull_to_refresh_to_check": "Pull to refresh to check again.", + "all_news": "All News", + "load_more": "Load More", + "no_news_yet": "No news yet", + "pull_to_refresh_to_fetch": "Pull to refresh to fetch the latest posts." + }, + "payments": { + "": "·", + "flagged": "Flagged", + "match": "Match", + "create_payment_request": "Create Payment Request", + "flagged_payments": "Flagged Payments", + "pending_match": "Pending Match", + "no_pending_payments": "No pending payments", + "upload_receipts_or_scan_sms": "Upload receipts or scan SMS to add payments.", + "reconciled": "Reconciled", + "no_reconciled_payments": "No reconciled payments", + "match_pending_payments_to_invoices": "Match pending payments to invoices for reconciliation." + }, + "proforma": { + "issued": "Issued:", + "due": "| Due:", + "": "|", + "item": "item", + "create_new_proforma": "Create New Proforma", + "no_proformas_yet": "No proformas yet", + "tap_the_button_above_to": "Tap the button above to create a new proforma." + }, + "scan": { + "camera_access": "Camera Access", + "we_need_your_permission_to": "We need your permission to use the camera to scan invoices and\n receipts automatically.", + "enable_camera": "Enable Camera", + "go_back": "Go Back", + "align_invoice_within_frame": "Align Invoice Within Frame" + }, + "company-details": { + "company_details": "Company details", + "company_name": "Company Name", + "tin": "TIN", + "contact_information": "Contact Information", + "phone": "Phone", + "email": "Email", + "website": "Website", + "address": "Address", + "street_address": "Street Address", + "city": "City", + "state": "State", + "zip_code": "Zip Code", + "country": "Country", + "system_information": "System Information", + "user_id": "User ID", + "created": "Created", + "last_updated": "Last Updated" + }, + "company": { + "company": "Company", + "search_workers": "Search workers...", + "workers": "Workers (", + "": ")", + "no_workers_found": "No workers found" + }, + "edit-profile": { + "edit_profile": "Edit Profile", + "first_name": "First Name", + "enter_first_name": "Enter first name", + "last_name": "Last Name", + "enter_last_name": "Enter last name", + "save_changes": "Save Changes", + "cancel": "Cancel" + }, + "help": { + "help_support": "Help & Support", + "faq": "FAQ", + "quick_answers_to_common_questions": "Quick answers to common questions.", + "need_more_help": "Need more help?", + "placeholder_add_contact_info_emailphonewhatsapp": "Placeholder — add contact info (email/phone/WhatsApp) or a support chat link here." + }, + "history": { + "activity_history": "Activity History", + "total_inflow": "Total Inflow", + "": "$", + "pending": "Pending", + "all_activity": "All Activity", + "proforma": "·\n Proforma", + "no_activity_yet": "No activity yet", + "create_a_proforma_invoice_to": "Create a proforma invoice to generate your first activity." + }, + "[id]": { + "200000": "$2,000.00", + "invoice_details": "Invoice Details", + "invoice_not_found": "Invoice not found", + "total_amount": "Total Amount", + "": "-", + "due": "Due", + "recipient": "Recipient", + "category": "Category", + "general": "General", + "billing_summary": "Billing Summary", + "subtotal": "Subtotal", + "tax": "Tax", + "total_balance": "Total Balance", + "additional_notes": "Additional Notes", + "created": "Created", + "last_updated": "Last Updated", + "share_sms": "Share SMS", + "get_pdf": "Get PDF", + "payment_match": "Payment Match", + "pending_match": "Pending Match", + "received_amount": "Received Amount", + "txn9982734": "TXN-9982734", + "telebirr_sms": "Telebirr SMS", + "transaction_details": "Transaction Details", + "received_on": "Received On", + "sep_11_2022_1430": "Sep 11, 2022 · 14:30", + "status": "Status", + "awaiting_link": "Awaiting Link", + "original_sms": "Original SMS", + "payment_received_from_elnatan_jansen": "\"Payment received from Elnatan Jansen for order #2322 via\n Telebirr. Amount: $2,000. Ref: B88-22X7.\"", + "associate_to_invoice": "Associate to Invoice", + "proforma": "Proforma", + "proforma_not_found": "Proforma not found", + "proforma_details": "Proforma Details", + "proforma_number": "Proforma Number", + "issued_date": "Issued Date", + "due_date": "Due Date", + "currency": "Currency", + "description": "Description", + "customer_information": "Customer Information", + "name": "Name", + "email": "Email", + "phone": "Phone", + "line_items": "Line Items", + "discount": "Discount", + "edit": "Edit" + }, + "login": { + "login": "Login", + "sign_in_to_manage_your": "Sign in to manage your tickets & invoices", + "email_or_phone_number": "Email or Phone Number", + "johnexamplecom_or_251": "john@example.com or +251...", + "password": "Password", + "": "••••••••", + "sign_in": "Sign In", + "or": "or", + "continue_with_google": "Continue with Google", + "dont_have_an_account": "Don't have an account?", + "create_one": "Create one" + }, + "settings": { + "notification_settings": "Notification settings", + "preferences": "Preferences", + "invoice_reminders": "Invoice reminders", + "get_reminders_before_invoices_are": "Get reminders before invoices are due", + "days_before_due_date": "Days before due date", + "currently": "Currently:", + "days": "days", + "news_alerts": "News alerts", + "product_updates_and_announcements": "Product updates and announcements", + "report_ready": "Report ready", + "notify_when_reports_are_generated": "Notify when reports are generated", + "select_days": "Select Days", + "settings": "Settings", + "notifications": "Notifications", + "language": "Language", + "english": "English", + "about": "About", + "yaltopia_tickets_app_v10_scan": "Yaltopia Tickets App v1.0 — Scan. Send. Reconcile.", + "api_invoices_proforma_payments_reports": "API: Invoices, Proforma, Payments, Reports, Documents, Notifications —\n see swagger.json and README for integration.", + "back": "Back" + }, + "create": { + "0": "0", + "1": "1", + "251": "+251...", + "1500": "1500", + "123456789": "123456789", + "create_payment_request": "Create Payment Request", + "general_information": "General Information", + "payment_request_number": "Payment Request Number", + "eg_payreq2024001": "e.g. PAYREQ-2024-001", + "description": "Description", + "eg_payment_request_for_services": "e.g. Payment request for services", + "customer_details": "Customer Details", + "customer_name": "Customer Name", + "eg_acme_corporation": "e.g. Acme Corporation", + "email": "Email", + "billingacmecom": "billing@acme.com", + "phone": "Phone", + "customer_id": "Customer ID", + "optional": "Optional", + "schedule_currency": "Schedule & Currency", + "issue_date": "Issue Date", + "due_date": "Due Date", + "currency": "Currency", + "status": "Status", + "amount": "Amount", + "payment_id": "Payment ID", + "pay123456": "PAY-123456", + "items": "Items", + "add_item": "Add Item", + "item": "Item", + "eg_web_development_service": "e.g. Web Development Service", + "qty": "Qty", + "unit_price": "Unit Price", + "000": "0.00", + "total": "Total", + "accounts": "Accounts", + "add_account": "Add Account", + "account": "Account", + "bank_name": "Bank Name", + "eg_yaltopia_bank": "e.g. Yaltopia Bank", + "account_name": "Account Name", + "eg_yaltopia_tech_plc": "e.g. Yaltopia Tech PLC", + "account_number": "Account Number", + "etb": "ETB", + "totals_taxes": "Totals & Taxes", + "subtotal": "Subtotal", + "tax": "Tax", + "discount": "Discount", + "notes": "Notes", + "eg_payment_terms_net_30": "e.g. Payment terms: Net 30", + "total_amount": "Total Amount", + "discard": "Discard", + "create_request": "Create Request", + "select_currency": "Select Currency", + "select_status": "Select Status", + "select_issue_date": "Select Issue Date", + "select_due_date": "Select Due Date", + "create_proforma": "Create Proforma", + "proforma_number": "Proforma Number", + "eg_prof2024001": "e.g. PROF-2024-001", + "project_description": "Project Description", + "eg_web_development_services": "e.g. Web Development Services", + "eg_acme_corp": "e.g. Acme Corp", + "billable_items": "Billable Items", + "eg_ui_design": "e.g. UI Design", + "price": "Price", + "eg_payment_due_within_30": "e.g. Payment due within 30 days", + "add_new_user": "Add New User", + "user_details": "User Details", + "configure_credentials_and_system_access": "Configure credentials and system access", + "first_name": "First Name", + "last_name": "Last Name", + "email_address": "Email Address", + "emailcompanycom": "email@company.com", + "phone_number": "Phone Number", + "911_234_567": "911 234 567", + "system_role": "System Role", + "initial_password": "Initial Password", + "": "••••••••", + "create_user": "Create User", + "select_system_role": "Select System Role" + }, + "privacy": { + "privacy_policy": "Privacy Policy", + "last_updated_march_10_2026": "Last updated: March 10, 2026", + "1_introduction": "1. Introduction", + "this_privacy_policy_describes_how": "This Privacy Policy describes how we collect, use, and share your personal information when you use our mobile application (\"App\").", + "2_information_we_collect": "2. Information We Collect", + "we_may_collect_information_about": "We may collect information about you in various ways, including:", + "personal_information_you_provide_directly": "• Personal information you provide directly to us", + "information_we_collect_automatically_when": "• Information we collect automatically when you use the App", + "information_from_thirdparty_services": "• Information from third-party services", + "3_how_we_use_your": "3. How We Use Your Information", + "we_use_the_information_we": "We use the information we collect to:", + "provide_and_maintain_our_services": "• Provide and maintain our services", + "process_transactions_and_send_related": "• Process transactions and send related information", + "communicate_with_you_about_our": "• Communicate with you about our services", + "4_information_sharing": "4. Information Sharing", + "we_do_not_sell_trade": "We do not sell, trade, or otherwise transfer your personal information to third parties without your consent, except as described in this policy.", + "5_data_security": "5. Data Security", + "we_implement_appropriate_security_measures": "We implement appropriate security measures to protect your personal information against unauthorized access, alteration, disclosure, or destruction.", + "6_contact_us": "6. Contact Us", + "if_you_have_any_questions": "If you have any questions about this Privacy Policy, please contact us at privacy@example.com." + }, + "profile": { + "profile": "Profile", + "account": "Account", + "transaction_history": "Transaction History", + "preferences": "Preferences", + "appearance": "Appearance", + "language": "Language", + "security": "Security", + "support_legal": "Support & Legal", + "help_support": "Help & Support", + "privacy_policy": "Privacy Policy", + "terms_of_use": "Terms of Use", + "log_out": "Log Out" + }, + "edit": { + "0": "0", + "proforma_details": "Proforma Details", + "proforma_number": "Proforma Number", + "enter_proforma_number": "Enter proforma number", + "description": "Description", + "brief_description": "Brief description", + "notes": "Notes", + "additional_notes": "Additional notes", + "customer_details": "Customer Details", + "customer_name": "Customer Name", + "enter_customer_name": "Enter customer name", + "customer_email": "Customer Email", + "enter_customer_email": "Enter customer email", + "customer_phone": "Customer Phone", + "enter_customer_phone": "Enter customer phone", + "dates": "Dates", + "issue_date": "Issue Date:", + "due_date": "Due Date:", + "items": "Items", + "add_item": "Add Item", + "item_description": "Item description", + "qty": "Qty", + "price": "Price", + "000": "0.00", + "totals": "Totals", + "subtotal": "Subtotal", + "tax_amount": "Tax Amount", + "discount_amount": "Discount Amount", + "total": "Total", + "currency": "Currency", + "select_currency": "Select Currency", + "tsignore": "// @ts-ignore" + }, + "register": { + "251": "+251", + "create_account": "Create Account", + "join_yaltopia_and_start_managing": "Join Yaltopia and start managing your business", + "first_name": "First Name", + "john": "John", + "last_name": "Last Name", + "doe": "Doe", + "email_address": "Email Address", + "johnexamplecom": "john@example.com", + "phone_number": "Phone Number", + "911_234_567": "911 234 567", + "password": "Password", + "": "••••••••", + "already_have_an_account": "Already have an account?", + "sign_in": "Sign In" + }, + "sms-scan": { + "scan_sms": "Scan SMS", + "finds_banking_messages_from_the": "Finds banking messages from the last 5 minutes", + "tap_scan_now_to_search": "Tap \"Scan Now\" to search for CBE, Dashen Bank, and Telebirr\n messages from the last 5 minutes.", + "no_banking_messages_found_in": "No banking messages found in the last 5 minutes.", + "amount": "Amount", + "etb": "ETB", + "reference": "Reference", + "": "\"" + }, + "terms": { + "terms_of_service": "Terms of Service", + "last_updated_march_10_2026": "Last updated: March 10, 2026", + "1_acceptance_of_terms": "1. Acceptance of Terms", + "by_accessing_and_using_our": "By accessing and using our mobile application, you accept and agree to be bound by the terms and provision of this agreement.", + "2_use_of_service": "2. Use of Service", + "our_service_is_provided_as": "Our service is provided \"as is\" and \"as available\" without warranties of any kind. You agree to use the service at your own risk.", + "3_user_accounts": "3. User Accounts", + "when_you_create_an_account": "When you create an account with us, you must provide information that is accurate, complete, and current at all times.", + "4_prohibited_uses": "4. Prohibited Uses", + "you_may_not_use_our": "You may not use our service:", + "for_any_unlawful_purpose_or": "• For any unlawful purpose or to solicit others to perform unlawful acts", + "to_violate_any_international_federal": "• To violate any international, federal, provincial, or state regulations, rules, laws, or local ordinances", + "to_infringe_upon_or_violate": "• To infringe upon or violate our intellectual property rights or the intellectual property rights of others", + "5_termination": "5. Termination", + "we_may_terminate_or_suspend": "We may terminate or suspend your account and bar access to the service immediately, without prior notice or liability, under our sole discretion.", + "6_limitation_of_liability": "6. Limitation of Liability", + "in_no_event_shall_our": "In no event shall our company, nor its directors, employees, partners, agents, suppliers, or affiliates, be liable for any indirect, incidental, special, consequential, or punitive damages.", + "7_changes_to_terms": "7. Changes to Terms", + "we_reserve_the_right_at": "We reserve the right, at our sole discretion, to modify or replace these Terms at any time. If a revision is material, we will try to provide at least 30 days notice prior to any new terms taking effect.", + "8_contact_information": "8. Contact Information", + "if_you_have_any_questions": "If you have any questions about these Terms of Service, please contact us at terms@example.com." + }, + "languagemodal": { + "language": "Language" + }, + "standardheader": { + "welcome_back": "Welcome back," + }, + "thememodal": { + "appearance": "Appearance" + } +} \ No newline at end of file diff --git a/localey.config.json b/localey.config.json new file mode 100644 index 0000000..d61d1ba --- /dev/null +++ b/localey.config.json @@ -0,0 +1,4 @@ +{ + "frameworks": ["react"], + "localesDir": "./locales" +} diff --git a/src/i18n/config.ts b/src/i18n/config.ts new file mode 100644 index 0000000..f7318b2 --- /dev/null +++ b/src/i18n/config.ts @@ -0,0 +1,19 @@ +import i18n from 'i18next'; +import { initReactI18next } from 'react-i18next'; +import en from '../../locales/en.json'; + +// Localey Professional Initialization +i18n + .use(initReactI18next) + .init({ + resources: { + en: { translation: en }, + }, + lng: 'en', + fallbackLng: 'en', + interpolation: { + escapeValue: false, // React already safes from XSS + }, + }); + +export default i18n; diff --git a/src/i18n/hooks.ts b/src/i18n/hooks.ts new file mode 100644 index 0000000..9162c56 --- /dev/null +++ b/src/i18n/hooks.ts @@ -0,0 +1,10 @@ +import { useTranslation } from 'react-i18next'; +import { useI18nStore } from './store'; + +export const useLocaley = () => { + const { t } = useTranslation(); + const locale = useI18nStore((state) => state.locale); + const setLocale = useI18nStore((state) => state.setLocale); + + return { t, locale, setLocale }; +}; diff --git a/src/i18n/store.ts b/src/i18n/store.ts new file mode 100644 index 0000000..712004f --- /dev/null +++ b/src/i18n/store.ts @@ -0,0 +1,15 @@ +import { create } from 'zustand'; +import i18n from './config'; + +interface I18nState { + locale: string; + setLocale: (locale: string) => void; +} + +export const useI18nStore = create((set) => ({ + locale: i18n.language || 'en', + setLocale: (locale: string) => { + i18n.changeLanguage(locale); + set({ locale }); + }, +}));