| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890 |
- import {
- createContext,
- useCallback,
- useContext,
- useMemo,
- useState,
- type ReactNode,
- } from 'react';
- type Language = 'en' | 'th';
- type Params = Record<string, string | number>;
- const strings: Record<Language, Record<string, string>> = {
- en: {
- 'tabs.home': 'Home',
- 'tabs.explore': 'Explore',
- 'tabs.onnx': 'Leaf Scan',
- 'tabs.setup': 'Setup',
- 'tabs.blog': 'Blog',
- 'tabs.tasks': 'Tasks',
- 'tabs.fields': 'Fields',
- 'tabs.logbook': 'Logbook',
- 'tabs.taskHistory': 'History',
- 'setup.title': 'User Setup',
- 'setup.profile': 'Profile',
- 'setup.loading': 'Loading...',
- 'setup.loaded': 'Loaded saved profile.',
- 'setup.none': 'No profile yet. Fill the form and save.',
- 'setup.saving': 'Saving...',
- 'setup.saved': 'Saved locally.',
- 'setup.photo': 'Profile photo',
- 'setup.noPhoto': 'No photo selected.',
- 'setup.uploadPhoto': 'Upload photo',
- 'setup.exportTitle': 'Export data',
- 'setup.exportHint': 'Download your local data as a CSV file.',
- 'setup.exportButton': 'Export data',
- 'setup.exported': 'Exported data.',
- 'setup.exportError': 'Export failed.',
- 'setup.name': 'Name',
- 'setup.farmName': 'Farm name',
- 'setup.location': 'Location',
- 'setup.save': 'Save locally',
- 'setup.saveIndicator': 'Saved!',
- 'setup.language': 'Language',
- 'setup.lang.en': 'English',
- 'setup.lang.th': 'Thai',
- 'setup.currency': 'Default currency',
- 'setup.currencyPlaceholder': 'e.g. THB',
- 'setup.currency.thb': 'THB',
- 'setup.currency.usd': 'USD',
- 'setup.currency.eur': 'EUR',
- 'setup.currency.jpy': 'JPY',
- 'setup.demoTitle': 'Demo Data',
- 'setup.demoHint': 'Insert sample fields, crops, observations, and task history.',
- 'setup.demoButton': 'Insert demo data',
- 'setup.demoInserting': 'Inserting demo data...',
- 'setup.demoInserted': 'Demo data inserted.',
- 'setup.demoExists': 'Demo data already exists.',
- 'setup.demoError': 'Demo insert failed.',
- 'setup.demoClearButton': 'Clear demo data',
- 'setup.demoClearing': 'Clearing demo data...',
- 'setup.demoCleared': 'Demo data cleared.',
- 'setup.demoClearError': 'Clear demo failed.',
- 'setup.demoClearedUndo': 'Demo data cleared.',
- 'setup.demoUndo': 'Undo',
- 'setup.demoUndoDone': 'Demo data restored.',
- 'setup.demoUndoError': 'Undo failed.',
- 'onnx.title': 'Leaf Classifier',
- 'onnx.howTitle': 'How to use the ONNX model',
- 'onnx.howBody':
- 'This page loads the PlantVillage MobileNetV3-Small model and runs inference on a 224x224 RGB tensor. The input is normalized to 0..1 per channel.',
- 'onnx.sampleTitle': 'Sample code',
- 'onnx.testTitle': 'Test the model',
- 'onnx.pickImage': 'Pick image',
- 'onnx.runModel': 'Run model',
- 'onnx.status.pick': 'Pick an image to run the model.',
- 'onnx.status.ready': 'Ready. Tap "Run model" to classify.',
- 'onnx.status.preprocessing': 'Preprocessing image...',
- 'onnx.status.running': 'Running PlantVillage model...',
- 'onnx.status.done': 'Done.',
- 'onnx.status.nativeMissing': 'ONNX runtime not available. Use a dev build.',
- 'onnx.topPredictions': 'Top predictions',
- 'blog.title': 'Blog Posts',
- 'blog.loading': 'Loading posts...',
- 'blog.error': 'Failed to load posts.',
- 'blog.empty': 'No posts found.',
- 'blog.loadMore': 'Load more',
- 'blog.loadingMore': 'Loading more...',
- 'blog.language': 'Language',
- 'blog.lang.en': 'English',
- 'blog.lang.th': 'Thai',
- 'blog.lang.ja': 'Japanese',
- 'blog.lang.zh': 'Chinese',
- 'home.badge': 'Smartfarming Lite',
- 'home.title': 'Track fields, crops, and observations without leaving the farm.',
- 'home.subtitle': 'Offline-first records for daily work, photos, and crop history.',
- 'home.openLogbook': 'Open Logbook',
- 'home.todayTasks': "Today’s Tasks",
- 'home.quickActions': 'Quick Actions',
- 'home.fields': 'Fields',
- 'home.fieldsHint': 'Add area, notes, photos.',
- 'home.crops': 'Crops',
- 'home.cropsHint': 'Planting and harvest dates.',
- 'home.observations': 'Observations',
- 'home.observationsHint': 'Notes, severity, images.',
- 'home.onnx': 'Leaf Scan',
- 'home.onnxHint': 'Run leaf classifier.',
- 'home.harvests': 'Harvests',
- 'home.harvestsHint': 'Yield and harvest records.',
- 'home.sales': 'Sales',
- 'home.salesHint': 'Sales records and buyers.',
- 'home.costs': 'Costs',
- 'home.costsHint': 'Record expenses.',
- 'home.todayTitle': 'Today',
- 'home.todayCardTitle': 'Log your field routine',
- 'home.todayCardBody':
- 'Capture scouting notes, attach photos, and keep a clean history for the next visit.',
- 'home.openTasks': 'Open Tasks',
- 'home.taskHistory': 'Task History',
- 'home.learnAnalyze': 'Learn & Analyze',
- 'home.blogs': 'Blogs',
- 'home.blogsHint': 'Latest smart farming posts.',
- 'home.profile': 'Profile',
- 'home.profileHint': 'Farm info and language.',
- 'home.count.tasks': 'Tasks',
- 'home.count.history': 'History',
- 'tasks.title': 'Daily Tasks',
- 'tasks.subtitle': 'Log today’s field routine.',
- 'tasks.loading': 'Loading tasks...',
- 'tasks.empty': 'No tasks configured yet.',
- 'tasks.pending': 'Pending',
- 'tasks.done': 'Done',
- 'tasks.complete': 'Mark done',
- 'tasks.undo': 'Undo',
- 'tasks.notePlaceholder': 'Add notes for today...',
- 'tasks.photo': 'Task photo',
- 'tasks.pickPhoto': 'Pick photo',
- 'tasks.takePhoto': 'Take photo',
- 'tasks.cameraDenied': 'Camera permission denied.',
- 'tasks.cameraError': 'Camera is not available.',
- 'tasks.historyTitle': 'Task History',
- 'tasks.historyEmpty': 'No task history yet.',
- 'tasks.back': 'Back to Tasks',
- 'tasks.default.fieldCheck': 'Field check-in',
- 'tasks.default.fieldCheckDesc': 'Quick field condition and notes.',
- 'tasks.default.scouting': 'Pest/Disease scouting',
- 'tasks.default.scoutingDesc': 'Inspect leaves and record severity.',
- 'tasks.default.sensors': 'Sensor readings',
- 'tasks.default.sensorsDesc': 'Log soil moisture or weather snapshot.',
- 'fields.title': 'Fields',
- 'fields.loading': 'Loading fields...',
- 'fields.empty': 'No fields yet.',
- 'fields.nameRequired': 'Field name is required.',
- 'fields.areaInvalid': 'Area must be a number.',
- 'fields.saved': 'Saved.',
- 'fields.name': 'Field name',
- 'fields.area': 'Area (ha)',
- 'fields.areaPlaceholder': 'e.g. 1.5',
- 'fields.notes': 'Notes',
- 'fields.notesPlaceholder': 'Soil, irrigation, landmarks...',
- 'fields.save': 'Save field',
- 'fields.update': 'Update field',
- 'fields.cancel': 'Cancel',
- 'fields.edit': 'Edit',
- 'fields.delete': 'Delete',
- 'fields.deleteTitle': 'Delete field?',
- 'fields.deleteMessage': 'This action cannot be undone.',
- 'fields.new': 'New field',
- 'fields.unnamed': 'Unnamed field',
- 'fields.areaLabel': 'Area:',
- 'fields.photo': 'Field photo',
- 'fields.pickPhoto': 'Pick photo',
- 'fields.takePhoto': 'Take photo',
- 'fields.noPhoto': 'No photo selected.',
- 'fields.updatedAt': 'Updated:',
- 'logbook.title': 'Logbook',
- 'logbook.subtitle': 'Manage your core records.',
- 'logbook.fields': 'Fields',
- 'logbook.fieldsHint': 'Land area, notes, boundaries.',
- 'logbook.observations': 'Observations',
- 'logbook.observationsHint': 'Scouting notes and severity.',
- 'logbook.crops': 'Crops',
- 'logbook.cropsHint': 'Crop info by field.',
- 'logbook.tasks': 'Daily Tasks',
- 'logbook.tasksHint': 'Notes, photos, status.',
- 'logbook.history': 'Task History',
- 'logbook.historyHint': 'Completed entries by date.',
- 'logbook.harvests': 'Harvests',
- 'logbook.harvestsHint': 'Yield and harvest details.',
- 'logbook.sales': 'Sales',
- 'logbook.salesHint': 'Sales records and buyers.',
- 'logbook.costs': 'Costs',
- 'logbook.costsHint': 'Expenses and receipts.',
- 'observations.title': 'Observations',
- 'observations.loading': 'Loading observations...',
- 'observations.empty': 'No observations yet.',
- 'observations.saved': 'Saved.',
- 'observations.field': 'Field',
- 'observations.crop': 'Crop',
- 'observations.type': 'Type',
- 'observations.note': 'Note',
- 'observations.severity': 'Severity',
- 'observations.severityLabel': 'Severity:',
- 'observations.selectField': 'Select field',
- 'observations.selectCrop': 'Select crop',
- 'observations.typePlaceholder': 'e.g. scouting',
- 'observations.notePlaceholder': 'What did you observe?',
- 'observations.severityPlaceholder': '0-10',
- 'observations.fieldRequired': 'Field is required.',
- 'observations.severityInvalid': 'Severity must be a number.',
- 'observations.delete': 'Delete',
- 'observations.noField': 'No field',
- 'observations.noCrop': 'No crop',
- 'observations.untitled': 'Observation',
- 'observations.save': 'Save observation',
- 'observations.new': 'New observation',
- 'observations.cancel': 'Cancel',
- 'observations.edit': 'Edit observation',
- 'observations.update': 'Update observation',
- 'observations.photo': 'Observation photo',
- 'observations.pickPhoto': 'Pick photo',
- 'observations.takePhoto': 'Take photo',
- 'observations.noPhoto': 'No photo selected.',
- 'harvests.title': 'Harvest Records',
- 'harvests.loading': 'Loading harvest records...',
- 'harvests.empty': 'No harvest records yet.',
- 'harvests.saved': 'Saved.',
- 'harvests.new': 'New harvest',
- 'harvests.field': 'Field',
- 'harvests.crop': 'Crop',
- 'harvests.selectField': 'Select field',
- 'harvests.selectCrop': 'Select crop',
- 'harvests.date': 'Harvest date',
- 'harvests.datePlaceholder': 'YYYY-MM-DD',
- 'harvests.quantity': 'Quantity',
- 'harvests.quantityPlaceholder': 'e.g. 120',
- 'harvests.unit': 'Unit',
- 'harvests.unitPlaceholder': 'kg',
- 'harvests.notes': 'Notes',
- 'harvests.notesPlaceholder': 'Quality, weather, labor notes...',
- 'harvests.photo': 'Harvest photo',
- 'harvests.pickPhoto': 'Pick photo',
- 'harvests.takePhoto': 'Take photo',
- 'harvests.noPhoto': 'No photo selected.',
- 'harvests.fieldRequired': 'Field is required.',
- 'harvests.cropRequired': 'Crop is required.',
- 'harvests.quantityInvalid': 'Quantity must be a number.',
- 'harvests.delete': 'Delete',
- 'harvests.deleteTitle': 'Delete harvest record?',
- 'harvests.deleteMessage': 'This action cannot be undone.',
- 'harvests.cancel': 'Cancel',
- 'harvests.save': 'Save harvest',
- 'harvests.untitled': 'Harvest',
- 'harvests.noField': 'No field',
- 'harvests.noCrop': 'No crop',
- 'harvests.edit': 'Edit harvest',
- 'harvests.update': 'Update harvest',
- 'units.kg': 'kg',
- 'units.g': 'g',
- 'units.ton': 'ton',
- 'units.pcs': 'pcs',
- 'sales.title': 'Sales Records',
- 'sales.loading': 'Loading sales records...',
- 'sales.empty': 'No sales records yet.',
- 'sales.saved': 'Saved.',
- 'sales.new': 'New sale',
- 'sales.field': 'Field',
- 'sales.crop': 'Crop',
- 'sales.harvest': 'Harvest (optional)',
- 'sales.selectField': 'Select field',
- 'sales.selectCrop': 'Select crop',
- 'sales.selectHarvest': 'Select harvest',
- 'sales.noHarvest': 'No harvest records',
- 'sales.date': 'Sale date',
- 'sales.datePlaceholder': 'YYYY-MM-DD',
- 'sales.quantity': 'Quantity',
- 'sales.quantityPlaceholder': 'e.g. 50',
- 'sales.unit': 'Unit',
- 'sales.unitPlaceholder': 'kg',
- 'sales.price': 'Price',
- 'sales.pricePlaceholder': 'e.g. 35',
- 'sales.priceLabel': 'Price:',
- 'sales.buyer': 'Buyer',
- 'sales.buyerPlaceholder': 'e.g. Local market',
- 'sales.notes': 'Notes',
- 'sales.notesPlaceholder': 'Payment, transport, quality...',
- 'sales.fieldRequired': 'Field is required.',
- 'sales.cropRequired': 'Crop is required.',
- 'sales.quantityInvalid': 'Quantity must be a number.',
- 'sales.delete': 'Delete',
- 'sales.deleteTitle': 'Delete sales record?',
- 'sales.deleteMessage': 'This action cannot be undone.',
- 'sales.cancel': 'Cancel',
- 'sales.save': 'Save sale',
- 'sales.untitled': 'Sale',
- 'sales.noField': 'No field',
- 'sales.noCrop': 'No crop',
- 'sales.edit': 'Edit sale',
- 'sales.update': 'Update sale',
- 'costs.title': 'Cost Records',
- 'costs.loading': 'Loading costs...',
- 'costs.empty': 'No cost records yet.',
- 'costs.saved': 'Saved.',
- 'costs.new': 'New cost',
- 'costs.field': 'Field',
- 'costs.crop': 'Crop (optional)',
- 'costs.selectField': 'Select field',
- 'costs.selectCrop': 'Select crop',
- 'costs.category': 'Category',
- 'costs.category.seed': 'Seed',
- 'costs.category.fertilizer': 'Fertilizer',
- 'costs.category.labor': 'Labor',
- 'costs.category.fuel': 'Fuel',
- 'costs.category.equipment': 'Equipment',
- 'costs.category.transport': 'Transport',
- 'costs.category.misc': 'Misc',
- 'costs.categoryPlaceholder': 'e.g. Seed',
- 'costs.amount': 'Amount',
- 'costs.amountPlaceholder': 'e.g. 1200',
- 'costs.vendor': 'Vendor',
- 'costs.vendorPlaceholder': 'e.g. Local supplier',
- 'costs.date': 'Date',
- 'costs.datePlaceholder': 'YYYY-MM-DD',
- 'costs.notes': 'Notes',
- 'costs.notesPlaceholder': 'Receipt, usage, purpose...',
- 'costs.photo': 'Receipt photo',
- 'costs.pickPhoto': 'Pick photo',
- 'costs.takePhoto': 'Take photo',
- 'costs.noPhoto': 'No photo selected.',
- 'costs.fieldRequired': 'Field is required.',
- 'costs.amountInvalid': 'Amount must be a number.',
- 'costs.delete': 'Delete',
- 'costs.deleteTitle': 'Delete cost record?',
- 'costs.deleteMessage': 'This action cannot be undone.',
- 'costs.cancel': 'Cancel',
- 'costs.save': 'Save cost',
- 'costs.edit': 'Edit cost',
- 'costs.update': 'Update cost',
- 'costs.untitled': 'Cost',
- 'costs.noField': 'No field',
- 'costs.noCrop': 'No crop',
- 'units.kg': 'กก.',
- 'units.g': 'กรัม',
- 'units.ton': 'ตัน',
- 'units.pcs': 'ชิ้น',
- 'demo.field.north': 'North Field',
- 'demo.field.northNote': 'Loamy soil · drip irrigation',
- 'demo.field.river': 'River Plot',
- 'demo.field.riverNote': 'Lowland area near canal',
- 'demo.field.greenhouse': 'Greenhouse',
- 'demo.field.greenhouseNote': 'Shaded beds, irrigation daily',
- 'demo.field.orchard': 'Orchard Block',
- 'demo.field.orchardNote': 'Raised rows, windbreak on east side',
- 'demo.field.terrace': 'Terrace Plot',
- 'demo.field.terraceNote': 'Stepped slope with drip lines',
- 'demo.crop.tomato': 'Tomato',
- 'demo.crop.tomatoVariety': 'Cherry',
- 'demo.crop.rice': 'Rice',
- 'demo.crop.riceVariety': 'Jasmine',
- 'demo.crop.lettuce': 'Lettuce',
- 'demo.crop.lettuceVariety': 'Butterhead',
- 'demo.crop.chili': 'Chili',
- 'demo.crop.chiliVariety': 'Bird’s eye',
- 'demo.crop.cabbage': 'Cabbage',
- 'demo.crop.cabbageVariety': 'Green cabbage',
- 'demo.observation.scoutingNote': 'Early leaf spot found on edge rows.',
- 'demo.observation.diseaseNote': 'Disease patches visible after rain.',
- 'demo.observation.irrigationNote': 'Adjusted irrigation timing to evening.',
- 'demo.observation.pestNote': 'Aphids spotted on new growth.',
- 'demo.observation.nutrientNote': 'Lower leaves pale, applied foliar feed.',
- 'demo.task.note': 'Completed as scheduled.',
- 'demo.task.note2': 'Followed standard checklist.',
- 'demo.task.note3': 'Checked equipment and logged readings.',
- 'demo.harvest.note1': 'Morning harvest, good quality.',
- 'demo.harvest.note2': 'Harvested after light rain.',
- 'demo.harvest.note3': 'Sorted by size for market.',
- 'demo.sale.buyer1': 'Local market',
- 'demo.sale.buyer2': 'Wholesale buyer',
- 'demo.sale.buyer3': 'Restaurant partner',
- 'demo.sale.note1': 'Delivered same day.',
- 'demo.sale.note2': 'Paid in full.',
- 'demo.sale.note3': 'Requested weekly supply.',
- 'demo.cost.vendor1': 'Agro supply',
- 'demo.cost.vendor2': 'Fertilizer store',
- 'demo.cost.vendor3': 'Labor crew',
- 'demo.cost.note1': 'Tomato seeds and trays.',
- 'demo.cost.note2': 'Base fertilizer for rice plot.',
- 'demo.cost.note3': 'Harvest helpers (half day).',
- 'observations.type.scouting': 'Scouting',
- 'observations.type.pest': 'Pest',
- 'observations.type.disease': 'Disease',
- 'observations.type.irrigation': 'Irrigation',
- 'observations.type.weeds': 'Weeds',
- 'observations.type.nutrients': 'Nutrients',
- 'crops.title': 'Crops',
- 'crops.loading': 'Loading crops...',
- 'crops.empty': 'No crops yet.',
- 'crops.saved': 'Saved.',
- 'crops.field': 'Field',
- 'crops.selectField': 'Select field',
- 'crops.name': 'Crop name',
- 'crops.variety': 'Variety',
- 'crops.planting': 'Planting date',
- 'crops.harvest': 'Expected harvest',
- 'crops.namePlaceholder': 'e.g. Tomato',
- 'crops.varietyPlaceholder': 'e.g. Cherry',
- 'crops.plantingPlaceholder': 'YYYY-MM-DD',
- 'crops.harvestPlaceholder': 'YYYY-MM-DD',
- 'crops.fieldRequired': 'Field is required.',
- 'crops.nameRequired': 'Crop name is required.',
- 'crops.delete': 'Delete',
- 'crops.deleteTitle': 'Delete crop?',
- 'crops.deleteMessage': 'This action cannot be undone.',
- 'crops.noField': 'No field',
- 'crops.untitled': 'Crop',
- 'crops.plantingLabel': 'Planted:',
- 'crops.harvestLabel': 'Harvest:',
- 'crops.save': 'Save crop',
- 'crops.new': 'New crop',
- 'crops.photo': 'Crop photo',
- 'crops.pickPhoto': 'Pick photo',
- 'crops.takePhoto': 'Take photo',
- 'crops.noPhoto': 'No photo selected.',
- 'crops.today': 'Today',
- 'crops.done': 'Done',
- 'crops.edit': 'Edit crop',
- 'crops.update': 'Update crop',
- 'crops.cancel': 'Cancel',
- },
- th: {
- 'tabs.home': 'หน้าแรก',
- 'tabs.explore': 'สำรวจ',
- 'tabs.onnx': 'สแกนใบ',
- 'tabs.setup': 'ตั้งค่า',
- 'tabs.blog': 'บล็อก',
- 'tabs.tasks': 'งานประจำวัน',
- 'tabs.fields': 'แปลง',
- 'tabs.logbook': 'บันทึก',
- 'tabs.taskHistory': 'ประวัติ',
- 'setup.title': 'ตั้งค่าผู้ใช้',
- 'setup.profile': 'โปรไฟล์',
- 'setup.loading': 'กำลังโหลด...',
- 'setup.loaded': 'โหลดโปรไฟล์ที่บันทึกไว้แล้ว',
- 'setup.none': 'ยังไม่มีโปรไฟล์ กรอกข้อมูลแล้วกดบันทึก',
- 'setup.saving': 'กำลังบันทึก...',
- 'setup.saved': 'บันทึกไว้ในเครื่องแล้ว',
- 'setup.photo': 'รูปโปรไฟล์',
- 'setup.noPhoto': 'ยังไม่ได้เลือกรูป',
- 'setup.uploadPhoto': 'อัปโหลดรูป',
- 'setup.exportTitle': 'ส่งออกข้อมูล',
- 'setup.exportHint': 'ดาวน์โหลดข้อมูลในเครื่องเป็นไฟล์ CSV',
- 'setup.exportButton': 'ส่งออกข้อมูล',
- 'setup.exported': 'ส่งออกข้อมูลแล้ว',
- 'setup.exportError': 'ส่งออกข้อมูลไม่สำเร็จ',
- 'setup.name': 'ชื่อ',
- 'setup.farmName': 'ชื่อฟาร์ม',
- 'setup.location': 'ที่ตั้ง',
- 'setup.save': 'บันทึกในเครื่อง',
- 'setup.saveIndicator': 'บันทึกแล้ว',
- 'setup.language': 'ภาษา',
- 'setup.lang.en': 'English',
- 'setup.lang.th': 'ไทย',
- 'setup.currency': 'สกุลเงินเริ่มต้น',
- 'setup.currencyPlaceholder': 'เช่น THB',
- 'setup.currency.thb': 'บาท (THB)',
- 'setup.currency.usd': 'ดอลลาร์ (USD)',
- 'setup.currency.eur': 'ยูโร (EUR)',
- 'setup.currency.jpy': 'เยน (JPY)',
- 'setup.demoTitle': 'ข้อมูลตัวอย่าง',
- 'setup.demoHint': 'เพิ่มข้อมูลตัวอย่าง: แปลง พืช บันทึกสำรวจ และประวัติงาน',
- 'setup.demoButton': 'เพิ่มข้อมูลตัวอย่าง',
- 'setup.demoInserting': 'กำลังเพิ่มข้อมูลตัวอย่าง...',
- 'setup.demoInserted': 'เพิ่มข้อมูลตัวอย่างแล้ว',
- 'setup.demoExists': 'มีข้อมูลอยู่แล้ว',
- 'setup.demoError': 'เพิ่มข้อมูลไม่สำเร็จ',
- 'setup.demoClearButton': 'ลบข้อมูลตัวอย่าง',
- 'setup.demoClearing': 'กำลังลบข้อมูลตัวอย่าง...',
- 'setup.demoCleared': 'ลบข้อมูลตัวอย่างแล้ว',
- 'setup.demoClearError': 'ลบข้อมูลไม่สำเร็จ',
- 'setup.demoClearedUndo': 'ลบข้อมูลตัวอย่างแล้ว',
- 'setup.demoUndo': 'ย้อนกลับ',
- 'setup.demoUndoDone': 'กู้คืนข้อมูลตัวอย่างแล้ว',
- 'setup.demoUndoError': 'ย้อนกลับไม่สำเร็จ',
- 'onnx.title': 'จำแนกโรคใบพืช',
- 'onnx.howTitle': 'วิธีใช้โมเดล ONNX',
- 'onnx.howBody':
- 'หน้านี้โหลดโมเดล PlantVillage MobileNetV3-Small และรันอินเฟอเรนซ์ด้วยเทนเซอร์ RGB ขนาด 224x224 อินพุตถูกทำให้อยู่ในช่วง 0..1 ต่อช่องสี',
- 'onnx.sampleTitle': 'ตัวอย่างโค้ด',
- 'onnx.testTitle': 'ทดสอบโมเดล',
- 'onnx.pickImage': 'เลือกรูป',
- 'onnx.runModel': 'รันโมเดล',
- 'onnx.status.pick': 'เลือกรูปเพื่อรันโมเดล',
- 'onnx.status.ready': 'พร้อมแล้ว กด "รันโมเดล" เพื่อจำแนก',
- 'onnx.status.preprocessing': 'กำลังเตรียมรูป...',
- 'onnx.status.running': 'กำลังรันโมเดล PlantVillage...',
- 'onnx.status.done': 'เสร็จแล้ว',
- 'onnx.status.nativeMissing': 'ไม่พบ ONNX runtime โปรดใช้ dev build',
- 'onnx.topPredictions': 'ผลลัพธ์สูงสุด',
- 'blog.title': 'บทความล่าสุด',
- 'blog.loading': 'กำลังโหลดบทความ...',
- 'blog.error': 'โหลดบทความไม่สำเร็จ',
- 'blog.empty': 'ไม่พบบทความ',
- 'blog.loadMore': 'โหลดเพิ่มเติม',
- 'blog.loadingMore': 'กำลังโหลดเพิ่มเติม...',
- 'blog.language': 'ภาษา',
- 'blog.lang.en': 'English',
- 'blog.lang.th': 'ไทย',
- 'blog.lang.ja': 'ญี่ปุ่น',
- 'blog.lang.zh': 'จีน',
- 'home.badge': 'สมาร์ทฟาร์มมิ่ง ไลต์',
- 'home.title': 'ติดตามแปลง พืช และบันทึกสำรวจได้ทันทีในฟาร์ม',
- 'home.subtitle': 'บันทึกแบบออฟไลน์สำหรับงานประจำวัน รูปภาพ และประวัติพืช',
- 'home.openLogbook': 'เปิดบันทึก',
- 'home.todayTasks': 'งานวันนี้',
- 'home.quickActions': 'ทางลัด',
- 'home.fields': 'แปลง',
- 'home.fieldsHint': 'เพิ่มพื้นที่ บันทึก และรูปภาพ',
- 'home.crops': 'พืช',
- 'home.cropsHint': 'วันที่ปลูกและเก็บเกี่ยว',
- 'home.observations': 'บันทึกสำรวจ',
- 'home.observationsHint': 'บันทึก ความรุนแรง และรูปภาพ',
- 'home.onnx': 'สแกนใบ',
- 'home.onnxHint': 'รันโมเดลจำแนกใบพืช',
- 'home.harvests': 'เก็บเกี่ยว',
- 'home.harvestsHint': 'ผลผลิตและบันทึกการเก็บเกี่ยว',
- 'home.sales': 'ขายผลผลิต',
- 'home.salesHint': 'บันทึกการขายและผู้ซื้อ',
- 'home.costs': 'ต้นทุน',
- 'home.costsHint': 'บันทึกค่าใช้จ่าย',
- 'home.todayTitle': 'วันนี้',
- 'home.todayCardTitle': 'บันทึกงานประจำแปลง',
- 'home.todayCardBody':
- 'บันทึกการสำรวจ ถ่ายรูป และเก็บประวัติให้พร้อมสำหรับครั้งถัดไป',
- 'home.openTasks': 'เปิดงานประจำวัน',
- 'home.taskHistory': 'ประวัติงาน',
- 'home.learnAnalyze': 'เรียนรู้และวิเคราะห์',
- 'home.blogs': 'บล็อก',
- 'home.blogsHint': 'บทความสมาร์ทฟาร์มมิ่งล่าสุด',
- 'home.profile': 'โปรไฟล์',
- 'home.profileHint': 'ข้อมูลฟาร์มและภาษา',
- 'home.count.tasks': 'งาน',
- 'home.count.history': 'ประวัติ',
- 'tasks.title': 'งานประจำวัน',
- 'tasks.subtitle': 'บันทึกงานประจำวันของแปลงวันนี้',
- 'tasks.loading': 'กำลังโหลดงาน...',
- 'tasks.empty': 'ยังไม่มีงานที่ตั้งไว้',
- 'tasks.pending': 'รอดำเนินการ',
- 'tasks.done': 'เสร็จแล้ว',
- 'tasks.complete': 'ทำเสร็จแล้ว',
- 'tasks.undo': 'ย้อนกลับ',
- 'tasks.notePlaceholder': 'เพิ่มบันทึกสำหรับวันนี้...',
- 'tasks.photo': 'รูปงาน',
- 'tasks.pickPhoto': 'เลือกรูป',
- 'tasks.takePhoto': 'ถ่ายรูป',
- 'tasks.cameraDenied': 'ไม่ได้รับอนุญาตให้ใช้กล้อง',
- 'tasks.cameraError': 'ไม่สามารถใช้งานกล้องได้',
- 'tasks.historyTitle': 'ประวัติงานประจำวัน',
- 'tasks.historyEmpty': 'ยังไม่มีประวัติงาน',
- 'tasks.back': 'กลับไปงานประจำวัน',
- 'tasks.default.fieldCheck': 'ตรวจแปลง',
- 'tasks.default.fieldCheckDesc': 'เช็คสภาพแปลงและบันทึกสั้น ๆ',
- 'tasks.default.scouting': 'สำรวจแมลง/โรค',
- 'tasks.default.scoutingDesc': 'ตรวจใบและบันทึกความรุนแรง',
- 'tasks.default.sensors': 'อ่านค่าจากเซนเซอร์',
- 'tasks.default.sensorsDesc': 'บันทึกความชื้นดินหรือสภาพอากาศ',
- 'fields.title': 'แปลง',
- 'fields.loading': 'กำลังโหลดแปลง...',
- 'fields.empty': 'ยังไม่มีแปลง',
- 'fields.nameRequired': 'ต้องระบุชื่อแปลง',
- 'fields.areaInvalid': 'พื้นที่ต้องเป็นตัวเลข',
- 'fields.saved': 'บันทึกแล้ว',
- 'fields.name': 'ชื่อแปลง',
- 'fields.area': 'พื้นที่ (ไร่)',
- 'fields.areaPlaceholder': 'เช่น 1.5',
- 'fields.notes': 'บันทึก',
- 'fields.notesPlaceholder': 'ดิน น้ำ จุดสังเกต...',
- 'fields.save': 'บันทึกแปลง',
- 'fields.update': 'อัปเดตแปลง',
- 'fields.cancel': 'ยกเลิก',
- 'fields.edit': 'แก้ไข',
- 'fields.delete': 'ลบ',
- 'fields.deleteTitle': 'ลบแปลงนี้ไหม?',
- 'fields.deleteMessage': 'การลบไม่สามารถย้อนกลับได้',
- 'fields.new': 'เพิ่มแปลง',
- 'fields.unnamed': 'แปลงไม่มีชื่อ',
- 'fields.areaLabel': 'พื้นที่:',
- 'fields.photo': 'รูปแปลง',
- 'fields.pickPhoto': 'เลือกรูป',
- 'fields.takePhoto': 'ถ่ายรูป',
- 'fields.noPhoto': 'ยังไม่ได้เลือกรูป',
- 'fields.updatedAt': 'อัปเดตเมื่อ:',
- 'logbook.title': 'บันทึก',
- 'logbook.subtitle': 'จัดการข้อมูลหลักของคุณ',
- 'logbook.fields': 'แปลง',
- 'logbook.fieldsHint': 'พื้นที่ บันทึก ขอบเขต',
- 'logbook.observations': 'บันทึกสำรวจ',
- 'logbook.observationsHint': 'บันทึกสำรวจและความรุนแรง',
- 'logbook.crops': 'พืช',
- 'logbook.cropsHint': 'ข้อมูลพืชตามแปลง',
- 'logbook.tasks': 'งานประจำวัน',
- 'logbook.tasksHint': 'บันทึก รูปภาพ สถานะ',
- 'logbook.history': 'ประวัติงาน',
- 'logbook.historyHint': 'รายการที่เสร็จแล้วตามวันที่',
- 'logbook.harvests': 'เก็บเกี่ยว',
- 'logbook.harvestsHint': 'ผลผลิตและรายละเอียดการเก็บเกี่ยว',
- 'logbook.sales': 'ขายผลผลิต',
- 'logbook.salesHint': 'บันทึกการขายและผู้ซื้อ',
- 'logbook.costs': 'ต้นทุน',
- 'logbook.costsHint': 'ค่าใช้จ่ายและใบเสร็จ',
- 'observations.title': 'บันทึกสำรวจ',
- 'observations.loading': 'กำลังโหลดบันทึก...',
- 'observations.empty': 'ยังไม่มีบันทึก',
- 'observations.saved': 'บันทึกแล้ว',
- 'observations.field': 'แปลง',
- 'observations.crop': 'พืช',
- 'observations.type': 'ประเภท',
- 'observations.note': 'บันทึก',
- 'observations.severity': 'ความรุนแรง',
- 'observations.severityLabel': 'ความรุนแรง:',
- 'observations.selectField': 'เลือกแปลง',
- 'observations.selectCrop': 'เลือกพืช',
- 'observations.typePlaceholder': 'เช่น สำรวจโรค',
- 'observations.notePlaceholder': 'สังเกตอะไรบ้าง?',
- 'observations.severityPlaceholder': '0-10',
- 'observations.fieldRequired': 'ต้องเลือกแปลง',
- 'observations.severityInvalid': 'ความรุนแรงต้องเป็นตัวเลข',
- 'observations.delete': 'ลบ',
- 'observations.noField': 'ไม่มีแปลง',
- 'observations.noCrop': 'ไม่มีพืช',
- 'observations.untitled': 'บันทึกสำรวจ',
- 'observations.save': 'บันทึกข้อมูล',
- 'observations.new': 'เพิ่มบันทึก',
- 'observations.cancel': 'ยกเลิก',
- 'observations.edit': 'แก้ไขบันทึก',
- 'observations.update': 'อัปเดตบันทึก',
- 'observations.photo': 'รูปประกอบ',
- 'observations.pickPhoto': 'เลือกรูป',
- 'observations.takePhoto': 'ถ่ายรูป',
- 'observations.noPhoto': 'ยังไม่ได้เลือกรูป',
- 'harvests.title': 'บันทึกการเก็บเกี่ยว',
- 'harvests.loading': 'กำลังโหลดการเก็บเกี่ยว...',
- 'harvests.empty': 'ยังไม่มีบันทึกการเก็บเกี่ยว',
- 'harvests.saved': 'บันทึกแล้ว',
- 'harvests.new': 'เพิ่มการเก็บเกี่ยว',
- 'harvests.field': 'แปลง',
- 'harvests.crop': 'พืช',
- 'harvests.selectField': 'เลือกแปลง',
- 'harvests.selectCrop': 'เลือกพืช',
- 'harvests.date': 'วันที่เก็บเกี่ยว',
- 'harvests.datePlaceholder': 'YYYY-MM-DD',
- 'harvests.quantity': 'ปริมาณ',
- 'harvests.quantityPlaceholder': 'เช่น 120',
- 'harvests.unit': 'หน่วย',
- 'harvests.unitPlaceholder': 'กก.',
- 'harvests.notes': 'บันทึก',
- 'harvests.notesPlaceholder': 'คุณภาพ สภาพอากาศ แรงงาน...',
- 'harvests.photo': 'รูปการเก็บเกี่ยว',
- 'harvests.pickPhoto': 'เลือกรูป',
- 'harvests.takePhoto': 'ถ่ายรูป',
- 'harvests.noPhoto': 'ยังไม่ได้เลือกรูป',
- 'harvests.fieldRequired': 'ต้องเลือกแปลง',
- 'harvests.cropRequired': 'ต้องเลือกพืช',
- 'harvests.quantityInvalid': 'ปริมาณต้องเป็นตัวเลข',
- 'harvests.delete': 'ลบ',
- 'harvests.deleteTitle': 'ลบบันทึกการเก็บเกี่ยว?',
- 'harvests.deleteMessage': 'การลบไม่สามารถย้อนกลับได้',
- 'harvests.cancel': 'ยกเลิก',
- 'harvests.save': 'บันทึกการเก็บเกี่ยว',
- 'harvests.untitled': 'เก็บเกี่ยว',
- 'harvests.noField': 'ไม่มีแปลง',
- 'harvests.noCrop': 'ไม่มีพืช',
- 'harvests.edit': 'แก้ไขการเก็บเกี่ยว',
- 'harvests.update': 'อัปเดตการเก็บเกี่ยว',
- 'sales.title': 'บันทึกการขาย',
- 'sales.loading': 'กำลังโหลดการขาย...',
- 'sales.empty': 'ยังไม่มีบันทึกการขาย',
- 'sales.saved': 'บันทึกแล้ว',
- 'sales.new': 'เพิ่มการขาย',
- 'sales.field': 'แปลง',
- 'sales.crop': 'พืช',
- 'sales.harvest': 'เก็บเกี่ยว (ไม่บังคับ)',
- 'sales.selectField': 'เลือกแปลง',
- 'sales.selectCrop': 'เลือกพืช',
- 'sales.selectHarvest': 'เลือกการเก็บเกี่ยว',
- 'sales.noHarvest': 'ยังไม่มีการเก็บเกี่ยว',
- 'sales.date': 'วันที่ขาย',
- 'sales.datePlaceholder': 'YYYY-MM-DD',
- 'sales.quantity': 'ปริมาณ',
- 'sales.quantityPlaceholder': 'เช่น 50',
- 'sales.unit': 'หน่วย',
- 'sales.unitPlaceholder': 'กก.',
- 'sales.price': 'ราคา',
- 'sales.pricePlaceholder': 'เช่น 35',
- 'sales.priceLabel': 'ราคา:',
- 'sales.buyer': 'ผู้ซื้อ',
- 'sales.buyerPlaceholder': 'เช่น ตลาดท้องถิ่น',
- 'sales.notes': 'บันทึก',
- 'sales.notesPlaceholder': 'การชำระเงิน ขนส่ง คุณภาพ...',
- 'sales.fieldRequired': 'ต้องเลือกแปลง',
- 'sales.cropRequired': 'ต้องเลือกพืช',
- 'sales.quantityInvalid': 'ปริมาณต้องเป็นตัวเลข',
- 'sales.delete': 'ลบ',
- 'sales.deleteTitle': 'ลบบันทึกการขาย?',
- 'sales.deleteMessage': 'การลบไม่สามารถย้อนกลับได้',
- 'sales.cancel': 'ยกเลิก',
- 'sales.save': 'บันทึกการขาย',
- 'sales.untitled': 'การขาย',
- 'sales.noField': 'ไม่มีแปลง',
- 'sales.noCrop': 'ไม่มีพืช',
- 'sales.edit': 'แก้ไขการขาย',
- 'sales.update': 'อัปเดตการขาย',
- 'costs.title': 'บันทึกต้นทุน',
- 'costs.loading': 'กำลังโหลดต้นทุน...',
- 'costs.empty': 'ยังไม่มีบันทึกต้นทุน',
- 'costs.saved': 'บันทึกแล้ว',
- 'costs.new': 'เพิ่มต้นทุน',
- 'costs.field': 'แปลง',
- 'costs.crop': 'พืช (ไม่บังคับ)',
- 'costs.selectField': 'เลือกแปลง',
- 'costs.selectCrop': 'เลือกพืช',
- 'costs.category': 'หมวดหมู่',
- 'costs.category.seed': 'เมล็ดพันธุ์',
- 'costs.category.fertilizer': 'ปุ๋ย',
- 'costs.category.labor': 'แรงงาน',
- 'costs.category.fuel': 'เชื้อเพลิง',
- 'costs.category.equipment': 'อุปกรณ์',
- 'costs.category.transport': 'ขนส่ง',
- 'costs.category.misc': 'อื่น ๆ',
- 'costs.categoryPlaceholder': 'เช่น เมล็ดพันธุ์',
- 'costs.amount': 'จำนวนเงิน',
- 'costs.amountPlaceholder': 'เช่น 1200',
- 'costs.vendor': 'ผู้ขาย',
- 'costs.vendorPlaceholder': 'เช่น ร้านวัสดุเกษตร',
- 'costs.date': 'วันที่',
- 'costs.datePlaceholder': 'YYYY-MM-DD',
- 'costs.notes': 'บันทึก',
- 'costs.notesPlaceholder': 'ใบเสร็จ การใช้งาน วัตถุประสงค์...',
- 'costs.photo': 'รูปใบเสร็จ',
- 'costs.pickPhoto': 'เลือกรูป',
- 'costs.takePhoto': 'ถ่ายรูป',
- 'costs.noPhoto': 'ยังไม่ได้เลือกรูป',
- 'costs.fieldRequired': 'ต้องเลือกแปลง',
- 'costs.amountInvalid': 'จำนวนเงินต้องเป็นตัวเลข',
- 'costs.delete': 'ลบ',
- 'costs.deleteTitle': 'ลบบันทึกต้นทุน?',
- 'costs.deleteMessage': 'การลบไม่สามารถย้อนกลับได้',
- 'costs.cancel': 'ยกเลิก',
- 'costs.save': 'บันทึกต้นทุน',
- 'costs.edit': 'แก้ไขต้นทุน',
- 'costs.update': 'อัปเดตต้นทุน',
- 'costs.untitled': 'ต้นทุน',
- 'costs.noField': 'ไม่มีแปลง',
- 'costs.noCrop': 'ไม่มีพืช',
- 'demo.field.north': 'แปลงเหนือ',
- 'demo.field.northNote': 'ดินร่วน · น้ำหยด',
- 'demo.field.river': 'แปลงริมน้ำ',
- 'demo.field.riverNote': 'พื้นที่ลุ่มใกล้คลอง',
- 'demo.field.greenhouse': 'โรงเรือน',
- 'demo.field.greenhouseNote': 'แปลงในร่ม รดน้ำทุกวัน',
- 'demo.field.orchard': 'แปลงสวนผลไม้',
- 'demo.field.orchardNote': 'ยกร่องและมีแนวกันลมด้านตะวันออก',
- 'demo.field.terrace': 'แปลงขั้นบันได',
- 'demo.field.terraceNote': 'พื้นที่ลาดชันแบ่งขั้น พร้อมน้ำหยด',
- 'demo.crop.tomato': 'มะเขือเทศ',
- 'demo.crop.tomatoVariety': 'เชอรี่',
- 'demo.crop.rice': 'ข้าว',
- 'demo.crop.riceVariety': 'หอมมะลิ',
- 'demo.crop.lettuce': 'ผักกาดหอม',
- 'demo.crop.lettuceVariety': 'บัตเตอร์เฮด',
- 'demo.crop.chili': 'พริก',
- 'demo.crop.chiliVariety': 'พริกขี้หนู',
- 'demo.crop.cabbage': 'กะหล่ำปลี',
- 'demo.crop.cabbageVariety': 'กะหล่ำปลีเขียว',
- 'demo.observation.scoutingNote': 'พบบางส่วนใบเป็นจุดเริ่มต้นตามขอบแปลง',
- 'demo.observation.diseaseNote': 'พบรอยโรคหลังฝนตก',
- 'demo.observation.irrigationNote': 'ปรับเวลารดน้ำเป็นช่วงเย็น',
- 'demo.observation.pestNote': 'พบเพลี้ยอ่อนตามยอดอ่อน',
- 'demo.observation.nutrientNote': 'ใบล่างซีด ให้ปุ๋ยทางใบเพิ่ม',
- 'demo.task.note': 'ทำงานเสร็จตามแผน',
- 'demo.task.note2': 'ทำตามเช็กลิสต์มาตรฐาน',
- 'demo.task.note3': 'ตรวจอุปกรณ์และบันทึกค่าแล้ว',
- 'demo.harvest.note1': 'เก็บช่วงเช้า คุณภาพดี',
- 'demo.harvest.note2': 'เก็บหลังฝนตกเล็กน้อย',
- 'demo.harvest.note3': 'คัดขนาดเพื่อขาย',
- 'demo.sale.buyer1': 'ตลาดท้องถิ่น',
- 'demo.sale.buyer2': 'ผู้ซื้อส่ง',
- 'demo.sale.buyer3': 'คู่ค้าร้านอาหาร',
- 'demo.sale.note1': 'ส่งของในวันเดียวกัน',
- 'demo.sale.note2': 'ชำระเงินครบถ้วน',
- 'demo.sale.note3': 'ขอสั่งประจำทุกสัปดาห์',
- 'demo.cost.vendor1': 'ร้านวัสดุเกษตร',
- 'demo.cost.vendor2': 'ร้านปุ๋ย',
- 'demo.cost.vendor3': 'ทีมแรงงาน',
- 'demo.cost.note1': 'เมล็ดมะเขือเทศและถาดเพาะ',
- 'demo.cost.note2': 'ปุ๋ยรองพื้นแปลงข้าว',
- 'demo.cost.note3': 'แรงงานช่วยเก็บเกี่ยว (ครึ่งวัน)',
- 'observations.type.scouting': 'สำรวจ',
- 'observations.type.pest': 'แมลง',
- 'observations.type.disease': 'โรค',
- 'observations.type.irrigation': 'ให้น้ำ',
- 'observations.type.weeds': 'วัชพืช',
- 'observations.type.nutrients': 'ธาตุอาหาร',
- 'crops.title': 'พืช',
- 'crops.loading': 'กำลังโหลดพืช...',
- 'crops.empty': 'ยังไม่มีพืช',
- 'crops.saved': 'บันทึกแล้ว',
- 'crops.field': 'แปลง',
- 'crops.selectField': 'เลือกแปลง',
- 'crops.name': 'ชื่อพืช',
- 'crops.variety': 'สายพันธุ์',
- 'crops.planting': 'วันที่ปลูก',
- 'crops.harvest': 'คาดว่าจะเก็บเกี่ยว',
- 'crops.namePlaceholder': 'เช่น มะเขือเทศ',
- 'crops.varietyPlaceholder': 'เช่น เชอรี่',
- 'crops.plantingPlaceholder': 'YYYY-MM-DD',
- 'crops.harvestPlaceholder': 'YYYY-MM-DD',
- 'crops.fieldRequired': 'ต้องเลือกแปลง',
- 'crops.nameRequired': 'ต้องกรอกชื่อพืช',
- 'crops.delete': 'ลบ',
- 'crops.deleteTitle': 'ลบพืชนี้ไหม?',
- 'crops.deleteMessage': 'การลบไม่สามารถย้อนกลับได้',
- 'crops.noField': 'ไม่มีแปลง',
- 'crops.untitled': 'พืช',
- 'crops.plantingLabel': 'ปลูก:',
- 'crops.harvestLabel': 'เก็บเกี่ยว:',
- 'crops.save': 'บันทึกพืช',
- 'crops.new': 'เพิ่มพืช',
- 'crops.photo': 'รูปพืช',
- 'crops.pickPhoto': 'เลือกรูป',
- 'crops.takePhoto': 'ถ่ายรูป',
- 'crops.noPhoto': 'ยังไม่ได้เลือกรูป',
- 'crops.today': 'วันนี้',
- 'crops.done': 'เสร็จ',
- 'crops.edit': 'แก้ไขพืช',
- 'crops.update': 'อัปเดตพืช',
- 'crops.cancel': 'ยกเลิก',
- },
- };
- function getDeviceLanguage(): Language {
- try {
- const locale = Intl.DateTimeFormat().resolvedOptions().locale;
- if (locale.toLowerCase().startsWith('th')) return 'th';
- } catch {
- // fall through
- }
- return 'en';
- }
- type LocalizationContextValue = {
- language: Language;
- setLanguage: (language: Language) => void;
- t: (key: string, params?: Params) => string;
- };
- const LocalizationContext = createContext<LocalizationContextValue | null>(null);
- export function LocalizationProvider({ children }: { children: ReactNode }) {
- const [language, setLanguage] = useState<Language>(getDeviceLanguage());
- const t = useCallback(
- (key: string, params?: Params) => {
- const template = strings[language][key] ?? strings.en[key] ?? key;
- if (!params) return template;
- return Object.keys(params).reduce((result, paramKey) => {
- return result.replace(
- new RegExp(`{{${paramKey}}}`, 'g'),
- String(params[paramKey])
- );
- }, template);
- },
- [language]
- );
- const value = useMemo(
- () => ({ language, setLanguage, t }),
- [language, setLanguage, t]
- );
- return <LocalizationContext.Provider value={value}>{children}</LocalizationContext.Provider>;
- }
- export function useTranslation() {
- const ctx = useContext(LocalizationContext);
- if (!ctx) {
- throw new Error('useTranslation must be used within LocalizationProvider');
- }
- return ctx;
- }
|