diff --git a/DASHBOARD_API_DOCUMENTATION.md b/DASHBOARD_API_DOCUMENTATION.md
new file mode 100644
index 0000000..af063ad
--- /dev/null
+++ b/DASHBOARD_API_DOCUMENTATION.md
@@ -0,0 +1,653 @@
+# مستندات API داشبورد Farm (Farm Dashboard)
+
+این سند شامل توضیحات کل داشبورد، APIهای تنظیمات (disable/enable/move کارتها) و ساختار پیشنهادی ریسپانس برای محتوای کارتها است.
+
+---
+
+## ۱. نمای کلی داشبورد
+
+داشبورد Farm از کامپوننت `FarmDashboardWrapper` استفاده میکند و شامل ردیفها (rows) و کارتهای (cards) زیر است:
+
+| Row ID | Row Label | کارتها |
+|--------|-----------|---------|
+| `overviewKpis` | Overview KPIs | `farmOverviewKpis` |
+| `weatherAlerts` | Weather & Alerts | `farmWeatherCard`, `farmAlertsTracker` |
+| `sensorMonitoring` | Sensor Monitoring | `sensorValuesList`, `sensorRadarChart` |
+| `sensorCharts` | Sensor Charts | `sensorComparisonChart`, `anomalyDetectionCard` |
+| `alertsWater` | Alerts & Water Prediction | `farmAlertsTimeline`, `waterNeedPrediction` |
+| `predictions` | Predictions | `harvestPredictionCard`, `yieldPredictionChart` |
+| `soilHeatmap` | Soil Moisture Heatmap | `soilMoistureHeatmap` |
+| `ndviRecommendations` | NDVI & Recommendations | `ndviHealthCard`, `recommendationsList` |
+| `economic` | Economic Overview | `economicOverview` |
+
+---
+
+## ۲. APIهای تنظیمات داشبورد
+
+### ۲.۱ دریافت تنظیمات داشبورد (Get Config)
+
+```
+GET /api/farm-dashboard-config
+```
+
+**توضیح:** تنظیمات شخصیسازی داشبورد کاربر لاگینشده را برمیگرداند.
+
+**Response:**
+```json
+{
+ "code": 200,
+ "msg": "OK",
+ "data": {
+ "disabled_card_ids": ["farmWeatherCard", "sensorRadarChart"],
+ "row_order": [
+ "overviewKpis",
+ "weatherAlerts",
+ "sensorMonitoring",
+ "sensorCharts",
+ "alertsWater",
+ "predictions",
+ "soilHeatmap",
+ "ndviRecommendations",
+ "economic"
+ ],
+ "enable_drag_reorder": true
+ }
+}
+```
+
+**فیلدها:**
+| فیلد | نوع | توضیح |
+|------|-----|-------|
+| `disabled_card_ids` | `string[]` | لیست شناسه کارتهای غیرفعال (hidden) |
+| `row_order` | `string[]` | ترتیب نمایش ردیفها |
+| `enable_drag_reorder` | `boolean` | امکان جابجایی ردیفها با drag |
+
+---
+
+### ۲.۲ غیرفعال کردن کارت (Disable Card)
+
+```
+PATCH /api/farm-dashboard-config
+```
+
+**Request Body:**
+```json
+{
+ "disabled_card_ids": ["farmWeatherCard", "sensorRadarChart"]
+}
+```
+
+کارت با شناسه `cardId` به لیست `disabled_card_ids` اضافه میشود و در داشبورد نمایش داده نمیشود.
+
+---
+
+### ۲.۳ فعال کردن کارت (Enable Card)
+
+```
+PATCH /api/farm-dashboard-config
+```
+
+**Request Body:**
+```json
+{
+ "disabled_card_ids": ["farmWeatherCard"]
+}
+```
+
+شناسه کارت از لیست `disabled_card_ids` حذف میشود و کارت دوباره نمایش داده میشود.
+
+**نکته:** کل لیست `disabled_card_ids` جدید ارسال میشود؛ برای enable باید آرایه بدون آن کارت فرستاده شود.
+
+---
+
+### ۲.۴ جابجایی ردیفها (Move Rows)
+
+```
+PATCH /api/farm-dashboard-config
+```
+
+**Request Body:**
+```json
+{
+ "row_order": [
+ "overviewKpis",
+ "weatherAlerts",
+ "sensorMonitoring",
+ "predictions",
+ "sensorCharts",
+ "alertsWater",
+ "soilHeatmap",
+ "ndviRecommendations",
+ "economic"
+ ]
+}
+```
+
+ترتیب ردیفها طبق آرایه `row_order` ذخیره میشود.
+
+---
+
+### ۲.۵ تغییر وضعیت Drag Reorder
+
+```
+PATCH /api/farm-dashboard-config
+```
+
+**Request Body:**
+```json
+{
+ "enable_drag_reorder": false
+}
+```
+
+---
+
+## ۳. API دریافت همه دیتای کارتها
+
+### Endpoint پیشنهادی
+
+```
+GET /api/farm-dashboard
+```
+
+یا به تفکیک کارت:
+```
+GET /api/farm-dashboard/cards
+```
+
+---
+
+## ۴. لیست کامل ریسپانس هر کارت
+
+ساختار پیشنهادی response برای محتوای هر کارت (بر اساس دادههای mock فعلی در فرانت):
+
+### ۴.۱ farmOverviewKpis
+
+```json
+{
+ "kpis": [
+ {
+ "id": "farm_health_score",
+ "title": "Farm Health Score",
+ "subtitle": "AI Analysis",
+ "stats": "87%",
+ "avatarColor": "success",
+ "avatarIcon": "tabler-heartbeat",
+ "chipText": "Good",
+ "chipColor": "success"
+ },
+ {
+ "id": "water_stress_index",
+ "title": "Water Stress Index",
+ "subtitle": "Current",
+ "stats": "12%",
+ "avatarColor": "info",
+ "avatarIcon": "tabler-droplet",
+ "chipText": "Low",
+ "chipColor": "success"
+ },
+ {
+ "id": "disease_risk",
+ "title": "Disease Risk",
+ "subtitle": "Last 7 Days",
+ "stats": "Low",
+ "avatarColor": "success",
+ "avatarIcon": "tabler-bug",
+ "chipText": "5%",
+ "chipColor": "success"
+ },
+ {
+ "id": "avg_soil_moisture",
+ "title": "Avg Soil Moisture",
+ "subtitle": "Field-wide",
+ "stats": "65%",
+ "avatarColor": "primary",
+ "avatarIcon": "tabler-plant-2",
+ "chipText": "Optimal",
+ "chipColor": "success"
+ },
+ {
+ "id": "yield_prediction",
+ "title": "Yield Prediction",
+ "subtitle": "This Season",
+ "stats": "42 ton",
+ "avatarColor": "secondary",
+ "avatarIcon": "tabler-chart-bar",
+ "chipText": "+8%",
+ "chipColor": "success"
+ },
+ {
+ "id": "pest_risk",
+ "title": "Pest Risk",
+ "subtitle": "AI Forecast",
+ "stats": "15%",
+ "avatarColor": "warning",
+ "avatarIcon": "tabler-bug-off",
+ "chipText": "Monitor",
+ "chipColor": "warning"
+ }
+ ]
+}
+```
+
+---
+
+### ۴.۲ farmWeatherCard
+
+```json
+{
+ "condition": "Clear",
+ "temperature": 24,
+ "unit": "°C",
+ "humidity": 45,
+ "windSpeed": 12,
+ "windUnit": "km/h",
+ "chartData": {
+ "labels": ["6am", "9am", "12pm", "3pm", "6pm", "9pm", "12am"],
+ "series": [[18, 22, 26, 28, 25, 20, 18]]
+ }
+}
+```
+
+---
+
+### ۴.۳ farmAlertsTracker
+
+```json
+{
+ "totalAlerts": 3,
+ "radialBarValue": 30,
+ "alertStats": [
+ {
+ "title": "Water Shortage",
+ "count": "2",
+ "avatarColor": "error",
+ "avatarIcon": "tabler-droplet-half-2"
+ },
+ {
+ "title": "Fungal Risk",
+ "count": "1",
+ "avatarColor": "warning",
+ "avatarIcon": "tabler-mushroom"
+ },
+ {
+ "title": "Frost Alert",
+ "count": "0",
+ "avatarColor": "info",
+ "avatarIcon": "tabler-snowflake"
+ }
+ ]
+}
+```
+
+---
+
+### ۴.۴ sensorValuesList
+
+```json
+{
+ "sensors": [
+ {
+ "title": "28°C",
+ "subtitle": "Air Temperature",
+ "trendNumber": 2.1,
+ "trend": "positive",
+ "unit": "°C"
+ },
+ {
+ "title": "24°C",
+ "subtitle": "Soil Temperature",
+ "trendNumber": -0.5,
+ "trend": "negative",
+ "unit": "°C"
+ },
+ {
+ "title": "65%",
+ "subtitle": "Air Humidity",
+ "trendNumber": 3.2,
+ "trend": "positive",
+ "unit": "%"
+ },
+ {
+ "title": "42%",
+ "subtitle": "Soil Moisture (10cm)",
+ "trendNumber": -1.8,
+ "trend": "negative",
+ "unit": "%"
+ },
+ {
+ "title": "6.8",
+ "subtitle": "Soil pH",
+ "trendNumber": 0.2,
+ "trend": "positive",
+ "unit": "pH"
+ },
+ {
+ "title": "1.2",
+ "subtitle": "EC (dS/m)",
+ "trendNumber": 0.1,
+ "trend": "positive",
+ "unit": "dS/m"
+ },
+ {
+ "title": "850",
+ "subtitle": "Light Intensity (lux)",
+ "trendNumber": 15.3,
+ "trend": "positive",
+ "unit": "lux"
+ },
+ {
+ "title": "12",
+ "subtitle": "Wind Speed (km/h)",
+ "trendNumber": -2.4,
+ "trend": "negative",
+ "unit": "km/h"
+ }
+ ]
+}
+```
+
+---
+
+### ۴.۵ sensorRadarChart
+
+```json
+{
+ "labels": ["Temp", "Humidity", "pH", "EC", "Light", "Wind"],
+ "series": [
+ { "name": "Today", "data": [75, 65, 80, 70, 85, 60] },
+ { "name": "Ideal", "data": [80, 70, 75, 75, 90, 50] }
+ ]
+}
+```
+
+---
+
+### ۴.۶ sensorComparisonChart
+
+```json
+{
+ "currentValue": 48,
+ "vsLastWeek": "+5%",
+ "vsLastWeekValue": 5,
+ "categories": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
+ "series": [
+ { "name": "Today", "data": [42, 45, 48, 52, 50, 48, 46] },
+ { "name": "Last Week", "data": [38, 40, 42, 45, 43, 40, 38] }
+ ]
+}
+```
+
+---
+
+### ۴.۷ anomalyDetectionCard
+
+```json
+{
+ "anomalies": [
+ {
+ "sensor": "Soil Moisture Z3",
+ "value": "38%",
+ "expected": "45-65%",
+ "deviation": "-12%",
+ "severity": "warning"
+ },
+ {
+ "sensor": "pH Sector 2",
+ "value": "5.2",
+ "expected": "6.0-7.0",
+ "deviation": "-0.8",
+ "severity": "error"
+ }
+ ]
+}
+```
+
+---
+
+### ۴.۸ farmAlertsTimeline
+
+```json
+{
+ "alerts": [
+ {
+ "title": "Water Shortage Risk",
+ "description": "Soil moisture at 10cm depth (42%) is below optimal. AI predicts stress in 2-3 days if no irrigation. Recommended: irrigate within 24h.",
+ "time": "15 min ago",
+ "color": "warning"
+ },
+ {
+ "title": "Fungal Disease Risk",
+ "description": "High humidity (65%) + temp 24°C creates favorable conditions for fungal growth. Consider preventive fungicide or reduce irrigation.",
+ "time": "1 hour ago",
+ "color": "error"
+ },
+ {
+ "title": "Irrigation Suggestion",
+ "description": "Optimal watering window: 6:00-8:00 AM. Suggested amount: 450 m³ for Zone A. Expected efficiency gain: 12%.",
+ "time": "2 hours ago",
+ "color": "info"
+ },
+ {
+ "title": "Soil Salinity Check",
+ "description": "EC reading 1.2 dS/m is within range. No action needed. Next check recommended in 5 days.",
+ "time": "4 hours ago",
+ "color": "success"
+ }
+ ]
+}
+```
+
+---
+
+### ۴.۹ waterNeedPrediction
+
+```json
+{
+ "totalNext7Days": 3290,
+ "unit": "m³",
+ "categories": ["Day 1", "Day 2", "Day 3", "Day 4", "Day 5", "Day 6", "Day 7"],
+ "series": [{ "name": "Water Need", "data": [420, 450, 480, 460, 490, 510, 480] }]
+}
+```
+
+---
+
+### ۴.۱۰ harvestPredictionCard
+
+```json
+{
+ "date": "2025-10-15",
+ "dateFormatted": "Oct 15, 2025",
+ "daysUntil": 58,
+ "description": "Based on current GDD accumulation and weather forecast. Optimal harvest window: Oct 12-18.",
+ "optimalWindowStart": "2025-10-12",
+ "optimalWindowEnd": "2025-10-18"
+}
+```
+
+---
+
+### ۴.۱۱ yieldPredictionChart
+
+```json
+{
+ "categories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
+ "series": [
+ { "name": "This Year", "data": [35, 38, 40, 42, 45, 48, 50, 48, 46, 44, 42, 42] },
+ { "name": "Last Year", "data": [32, 34, 36, 38, 40, 42, 44, 42, 40, 38, 36, 38] }
+ ],
+ "summary": [
+ { "title": "Predicted Yield", "subtitle": "This Season", "amount": "42 ton", "avatarColor": "primary", "avatarIcon": "tabler-chart-bar" },
+ { "title": "Harvest Date", "subtitle": "Est. Oct 15", "amount": "+8%", "avatarColor": "success", "avatarIcon": "tabler-calendar" }
+ ]
+}
+```
+
+---
+
+### ۴.۱۲ soilMoistureHeatmap
+
+```json
+{
+ "zones": ["Z1", "Z2", "Z3", "Z4", "Z5", "Z6", "Z7"],
+ "hours": ["6h", "8h", "10h", "12h", "14h", "16h", "18h"],
+ "series": [
+ { "name": "Z1", "data": [{"x": "6h", "y": 52}, {"x": "8h", "y": 48}, {"x": "10h", "y": 55}, {"x": "12h", "y": 60}, {"x": "14h", "y": 58}, {"x": "16h", "y": 54}, {"x": "18h", "y": 50}] },
+ { "name": "Z2", "data": [{"x": "6h", "y": 45}, {"x": "8h", "y": 42}, {"x": "10h", "y": 48}, {"x": "12h", "y": 52}, {"x": "14h", "y": 50}, {"x": "16h", "y": 47}, {"x": "18h", "y": 44}] }
+ ]
+}
+```
+
+---
+
+### ۴.۱۳ ndviHealthCard
+
+```json
+{
+ "ndviIndex": 0.78,
+ "healthData": [
+ { "title": "Nitrogen Stress", "value": "Low", "color": "success", "icon": "tabler-leaf" },
+ { "title": "Crop Health", "value": "Good", "color": "success", "icon": "tabler-plant" }
+ ]
+}
+```
+
+---
+
+### ۴.۱۴ recommendationsList
+
+```json
+{
+ "recommendations": [
+ {
+ "title": "Irrigation: 6:00-8:00 AM",
+ "subtitle": "450 m³ for Zone A. Without irrigation, yield may drop ~8%.",
+ "avatarIcon": "tabler-droplet",
+ "avatarColor": "primary"
+ },
+ {
+ "title": "Fertilizer: NPK 20-20-20",
+ "subtitle": "Apply 25 kg/ha in 7 days. Current N deficiency in sector 2.",
+ "avatarIcon": "tabler-leaf",
+ "avatarColor": "success"
+ },
+ {
+ "title": "Fungicide: Preventive",
+ "subtitle": "Humidity + temp favor fungi. Consider copper-based spray.",
+ "avatarIcon": "tabler-mushroom",
+ "avatarColor": "warning"
+ },
+ {
+ "title": "Harvest Window: Oct 12-18",
+ "subtitle": "Peak ripeness expected Oct 15. Plan labor accordingly.",
+ "avatarIcon": "tabler-calendar-event",
+ "avatarColor": "info"
+ }
+ ]
+}
+```
+
+---
+
+### ۴.۱۵ economicOverview
+
+```json
+{
+ "economicData": [
+ { "title": "Water Cost", "value": "€720", "subtitle": "This month", "avatarIcon": "tabler-droplet", "avatarColor": "primary" },
+ { "title": "AI Water Savings", "value": "€156", "subtitle": "18% saved", "avatarIcon": "tabler-bulb", "avatarColor": "success" },
+ { "title": "Platform ROI", "value": "127%", "subtitle": "vs last year", "avatarIcon": "tabler-chart-line", "avatarColor": "info" },
+ { "title": "Income Forecast", "value": "€42k", "subtitle": "This season", "avatarIcon": "tabler-currency-euro", "avatarColor": "success" }
+ ],
+ "chartSeries": [
+ { "name": "Water Cost", "data": [120, 115, 110, 125, 118, 122] },
+ { "name": "Fertilizer", "data": [80, 85, 90, 75, 82, 78] }
+ ],
+ "chartCategories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
+}
+```
+
+---
+
+## ۵. Response یکپارچه همه کارتها
+
+اگر یک endpoint برای کل دیتای داشبورد داشته باشید:
+
+```
+GET /api/farm-dashboard
+```
+
+**Response پیشنهادی:**
+```json
+{
+ "code": 200,
+ "msg": "OK",
+ "data": {
+ "farmOverviewKpis": { ... },
+ "farmWeatherCard": { ... },
+ "farmAlertsTracker": { ... },
+ "sensorValuesList": { ... },
+ "sensorRadarChart": { ... },
+ "sensorComparisonChart": { ... },
+ "anomalyDetectionCard": { ... },
+ "farmAlertsTimeline": { ... },
+ "waterNeedPrediction": { ... },
+ "harvestPredictionCard": { ... },
+ "yieldPredictionChart": { ... },
+ "soilMoistureHeatmap": { ... },
+ "ndviHealthCard": { ... },
+ "recommendationsList": { ... },
+ "economicOverview": { ... }
+ }
+}
+```
+
+---
+
+## ۶. خلاصه Endpoints
+
+| عملیات | Method | Endpoint | Body |
+|--------|--------|----------|------|
+| دریافت تنظیمات | GET | `/api/farm-dashboard-config` | - |
+| غیرفعال کردن کارت | PATCH | `/api/farm-dashboard-config` | `{ "disabled_card_ids": [...] }` |
+| فعال کردن کارت | PATCH | `/api/farm-dashboard-config` | `{ "disabled_card_ids": [...] }` |
+| جابجایی ردیفها | PATCH | `/api/farm-dashboard-config` | `{ "row_order": [...] }` |
+| Enable/Disable Drag | PATCH | `/api/farm-dashboard-config` | `{ "enable_drag_reorder": boolean }` |
+| دیتای همه کارتها | GET | `/api/farm-dashboard` یا `/api/farm-dashboard/cards` | - |
+
+---
+
+## ۷. Card IDs معتبر
+
+```
+farmOverviewKpis
+farmWeatherCard
+farmAlertsTracker
+sensorValuesList
+sensorRadarChart
+sensorComparisonChart
+anomalyDetectionCard
+farmAlertsTimeline
+waterNeedPrediction
+harvestPredictionCard
+yieldPredictionChart
+soilMoistureHeatmap
+ndviHealthCard
+recommendationsList
+economicOverview
+```
+
+## ۸. Row IDs معتبر
+
+```
+overviewKpis
+weatherAlerts
+sensorMonitoring
+sensorCharts
+alertsWater
+predictions
+soilHeatmap
+ndviRecommendations
+economic
+```
diff --git a/messages/fa.json b/messages/fa.json
new file mode 100644
index 0000000..715e69c
--- /dev/null
+++ b/messages/fa.json
@@ -0,0 +1,216 @@
+{
+ "common": {
+ "cancel": "انصراف",
+ "save": "ذخیره",
+ "back": "بازگشت",
+ "close": "بستن"
+ },
+ "login": {
+ "welcome": "خوش آمدید به {templateName}! 👋🏻",
+ "phoneStep": "شماره موبایل خود را برای دریافت کد OTP وارد کنید",
+ "otpStep": "کد OTP ارسال شده به موبایل خود را وارد کنید",
+ "phoneNumber": "شماره موبایل",
+ "placeholderPhone": "شماره موبایل خود را وارد کنید",
+ "sendOtp": "ارسال OTP",
+ "verifyOtp": "تایید OTP",
+ "backToPhone": "بازگشت به شماره موبایل",
+ "newUser": "جدید هستید؟",
+ "createAccount": "ثبت نام کنید",
+ "otpSent": "کد OTP به {phone} ارسال شد",
+ "validation": {
+ "phoneRequired": "شماره موبایل الزامی است",
+ "phoneMinLength": "شماره موبایل باید حداقل ۱۰ رقم باشد",
+ "phoneMaxLength": "شماره موبایل باید حداکثر ۱۵ رقم باشد",
+ "phoneDigitsOnly": "شماره موبایل باید فقط عدد باشد"
+ },
+ "errors": {
+ "sendOtpFailed": "ارسال OTP ناموفق بود",
+ "incompleteOtp": "لطفاً کد ۶ رقمی OTP را کامل وارد کنید",
+ "otpVerificationFailed": "تایید OTP ناموفق بود"
+ }
+ },
+ "navigation": {
+ "dashboards": "داشبوردها",
+ "crm": "مدیریت ارتباط با مشتری",
+ "analytics": "تحلیلها",
+ "eCommerce": "فروشگاه",
+ "academy": "آکادمی",
+ "logistics": "لجستیک",
+ "frontPages": "صفحات فرانت",
+ "landing": "صفحه اصلی",
+ "pricing": "قیمتگذاری",
+ "payment": "پرداخت",
+ "checkout": "تسویه حساب",
+ "helpCenter": "مرکز راهنمایی",
+ "appsPages": "اپلیکیشنها و صفحات",
+ "apps": "اپلیکیشنها",
+ "dashboard": "داشبورد",
+ "products": "محصولات",
+ "list": "فهرست",
+ "add": "افزودن",
+ "category": "دستهبندی",
+ "orders": "سفارشات",
+ "details": "جزئیات",
+ "customers": "مشتریان",
+ "manageReviews": "مدیریت نظرات",
+ "referrals": "معرفی",
+ "settings": "تنظیمات",
+ "myCourses": "دورههای من",
+ "courseDetails": "جزئیات دوره",
+ "fleet": "ناوگان",
+ "email": "ایمیل",
+ "chat": "چت",
+ "calendar": "تقویم",
+ "kanban": "کانبان",
+ "todo": "وظایف",
+ "invoice": "فاکتور",
+ "preview": "پیشنمایش",
+ "edit": "ویرایش",
+ "user": "کاربر",
+ "view": "مشاهده",
+ "rolesPermissions": "نقشها و دسترسیها",
+ "roles": "نقشها",
+ "permissions": "دسترسیها",
+ "pages": "صفحات",
+ "userProfile": "پروفایل کاربر",
+ "accountSettings": "تنظیمات حساب",
+ "faq": "سوالات متداول",
+ "miscellaneous": "متفرقه",
+ "comingSoon": "به زودی",
+ "underMaintenance": "در حال تعمیر",
+ "pageNotFound404": "صفحه یافت نشد - 404",
+ "notAuthorized401": "غیرمجاز - 401",
+ "authPages": "صفحات احراز هویت",
+ "login": "ورود",
+ "loginV1": "ورود نسخه 1",
+ "loginV2": "ورود نسخه 2",
+ "register": "ثبت نام",
+ "registerV1": "ثبت نام نسخه 1",
+ "registerV2": "ثبت نام نسخه 2",
+ "registerMultiSteps": "ثبت نام چند مرحلهای",
+ "verifyEmail": "تایید ایمیل",
+ "verifyEmailV1": "تایید ایمیل نسخه 1",
+ "verifyEmailV2": "تایید ایمیل نسخه 2",
+ "forgotPassword": "فراموشی رمز عبور",
+ "forgotPasswordV1": "فراموشی رمز عبور نسخه 1",
+ "forgotPasswordV2": "فراموشی رمز عبور نسخه 2",
+ "resetPassword": "بازنشانی رمز عبور",
+ "resetPasswordV1": "بازنشانی رمز عبور نسخه 1",
+ "resetPasswordV2": "بازنشانی رمز عبور نسخه 2",
+ "twoSteps": "دو مرحلهای",
+ "twoStepsV1": "دو مرحلهای نسخه 1",
+ "twoStepsV2": "دو مرحلهای نسخه 2",
+ "wizardExamples": "مثالهای ویزارد",
+ "propertyListing": "فهرست املاک",
+ "createDeal": "ایجاد معامله",
+ "dialogExamples": "مثالهای دیالوگ",
+ "widgetExamples": "مثالهای ویجت",
+ "basic": "پایه",
+ "advanced": "پیشرفته",
+ "statistics": "آمار",
+ "actions": "عملیات",
+ "charts": "چارتها",
+ "formsAndTables": "فرمها و جداول",
+ "formLayouts": "چیدمان فرمها",
+ "formValidation": "اعتبارسنجی فرم",
+ "formWizard": "ویزارد فرم",
+ "reactTable": "جدول React",
+ "formELements": "عناصر فرم",
+ "muiTables": "جداول MUI",
+ "chartsMisc": "چارتها و متفرقه",
+ "recharts": "Recharts",
+ "apex": "Apex",
+ "foundation": "پایه",
+ "components": "کامپوننتها",
+ "menuExamples": "مثالهای منو",
+ "raiseSupport": "درخواست پشتیبانی",
+ "documentation": "مستندات",
+ "others": "سایر",
+ "itemWithBadge": "آیتم با نشان",
+ "externalLink": "لینک خارجی",
+ "menuLevels": "سطحهای منو",
+ "menuLevel2": "سطح منو 2",
+ "menuLevel3": "سطح منو 3",
+ "disabledMenu": "منوی غیرفعال"
+ },
+ "farmDashboard": {
+ "settings": {
+ "title": "تنظیمات داشبورد",
+ "toggleCards": "کارتها را نمایش دهید یا مخفی کنید",
+ "enableDragReorder": "فعالسازی کشیدن و مرتبسازی ردیفها",
+ "ariaLabel": "تنظیمات داشبورد",
+ "dragRow": "کشیدن {row}"
+ },
+ "cards": {
+ "farmOverviewKpis": "خلاصه شاخصها",
+ "farmWeatherCard": "آب و هوا",
+ "farmAlertsTracker": "پیامهای هشدار",
+ "sensorValuesList": "مقادیر سنسور",
+ "sensorRadarChart": "نمودار راداری سنسور",
+ "sensorComparisonChart": "مقایسه سنسور",
+ "anomalyDetectionCard": "تشخیص ناهنجاری",
+ "farmAlertsTimeline": "خط زمانی هشدارها",
+ "waterNeedPrediction": "پیشبینی نیاز آبی",
+ "harvestPredictionCard": "پیشبینی برداشت",
+ "yieldPredictionChart": "پیشبینی عملکرد",
+ "soilMoistureHeatmap": "نقشه حرارتی رطوبت خاک",
+ "ndviHealthCard": "سلامت NDVI",
+ "recommendationsList": "توصیهها",
+ "economicOverview": "خلاصه اقتصادی"
+ },
+ "rows": {
+ "overviewKpis": "خلاصه شاخصها",
+ "weatherAlerts": "آب و هوا و هشدارها",
+ "sensorMonitoring": "پایش سنسور",
+ "sensorCharts": "نمودارهای سنسور",
+ "alertsWater": "هشدارها و پیشبینی آب",
+ "predictions": "پیشبینیها",
+ "soilHeatmap": "نقشه حرارتی رطوبت خاک",
+ "ndviRecommendations": "NDVI و توصیهها",
+ "economic": "خلاصه اقتصادی"
+ }
+ },
+ "sensorHub": {
+ "title": "مرکز سنسور",
+ "cancel": "انصراف",
+ "selectSensor": "انتخاب سنسور",
+ "selectSensorDescription": "سنسور مورد نظر را انتخاب کنید یا سنسور جدید اضافه کنید",
+ "addSensor": "اضافه کردن سنسور",
+ "sensorData": "داده سنسور",
+ "back": "بازگشت",
+ "sensorName": "نام سنسور",
+ "sensorUuid": "شناسه سنسور (UUID)",
+ "placeholderName": "نام سنسور را وارد کنید",
+ "placeholderUuid": "شناسه سنسور را وارد کنید",
+ "saveSensor": "ذخیره سنسور",
+ "saving": "در حال ذخیره...",
+ "errorSave": "خطا در ذخیره سنسور",
+ "columns": {
+ "name": "نام",
+ "lastUpdate": "آخرین بروزرسانی",
+ "uuid": "شناسه یکتا"
+ },
+ "ariaClose": "بستن",
+ "errorLoad": "خطا در بارگذاری سنسورها"
+ },
+ "accountSettings": {
+ "account": "حساب کاربری",
+ "sensorHub": "مرکز سنسور",
+ "firstName": "نام",
+ "lastName": "نام خانوادگی",
+ "email": "ایمیل",
+ "phoneNumber": "شماره موبایل",
+ "placeholderFirstName": "نام",
+ "placeholderLastName": "نام خانوادگی",
+ "placeholderEmail": "example@email.com",
+ "placeholderPhone": "+۹۸ ۹۱۲ ۳۴۵ ۶۷۸۹",
+ "errorSave": "خطا در ذخیره تغییرات",
+ "deleteAccount": "حذف حساب",
+ "confirmDeactivation": "تایید میکنم که میخواهم حساب من غیرفعال شود",
+ "deactivateAccount": "غیرفعال کردن حساب",
+ "confirmDelete": "لطفاً تایید کنید که میخواهید حساب را حذف کنید",
+ "saveChanges": "ذخیره تغییرات",
+ "saving": "در حال ذخیره...",
+ "reset": "بازنشانی"
+ }
+}
diff --git a/next.config.ts b/next.config.ts
index cce0450..1d536bd 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -1,8 +1,11 @@
import type { NextConfig } from 'next'
+import createNextIntlPlugin from 'next-intl/plugin'
+
+const withNextIntl = createNextIntlPlugin('./src/i18n/request.ts')
const nextConfig: NextConfig = {
basePath: process.env.BASEPATH,
output: 'standalone'
}
-export default nextConfig
+export default withNextIntl(nextConfig)
diff --git a/package-lock.json b/package-lock.json
index d79b1df..4d4b4e4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -54,9 +54,11 @@
"mapbox-gl": "3.9.0",
"negotiator": "1.0.0",
"next": "15.1.2",
+ "next-intl": "3.25.2",
"react": "18.3.1",
"react-apexcharts": "1.4.1",
"react-colorful": "5.6.1",
+ "react-date-object": "1.1.9",
"react-datepicker": "7.3.0",
"react-dom": "18.3.1",
"react-dropzone": "14.3.5",
@@ -1026,6 +1028,57 @@
"version": "0.2.8",
"license": "MIT"
},
+ "node_modules/@formatjs/ecma402-abstract": {
+ "version": "2.3.6",
+ "resolved": "https://mirror-npm.runflare.com/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.6.tgz",
+ "integrity": "sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw==",
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/fast-memoize": "2.2.7",
+ "@formatjs/intl-localematcher": "0.6.2",
+ "decimal.js": "^10.4.3",
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@formatjs/ecma402-abstract/node_modules/@formatjs/intl-localematcher": {
+ "version": "0.6.2",
+ "resolved": "https://mirror-npm.runflare.com/@formatjs/intl-localematcher/-/intl-localematcher-0.6.2.tgz",
+ "integrity": "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@formatjs/fast-memoize": {
+ "version": "2.2.7",
+ "resolved": "https://mirror-npm.runflare.com/@formatjs/fast-memoize/-/fast-memoize-2.2.7.tgz",
+ "integrity": "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@formatjs/icu-messageformat-parser": {
+ "version": "2.11.4",
+ "resolved": "https://mirror-npm.runflare.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.4.tgz",
+ "integrity": "sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw==",
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "2.3.6",
+ "@formatjs/icu-skeleton-parser": "1.8.16",
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@formatjs/icu-skeleton-parser": {
+ "version": "1.8.16",
+ "resolved": "https://mirror-npm.runflare.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.16.tgz",
+ "integrity": "sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "2.3.6",
+ "tslib": "^2.8.0"
+ }
+ },
"node_modules/@formatjs/intl-localematcher": {
"version": "0.5.9",
"license": "MIT",
@@ -4702,6 +4755,12 @@
}
}
},
+ "node_modules/decimal.js": {
+ "version": "10.6.0",
+ "resolved": "https://mirror-npm.runflare.com/decimal.js/-/decimal.js-10.6.0.tgz",
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
+ "license": "MIT"
+ },
"node_modules/decimal.js-light": {
"version": "2.5.1",
"license": "MIT"
@@ -6491,6 +6550,18 @@
"node": ">=12"
}
},
+ "node_modules/intl-messageformat": {
+ "version": "10.7.18",
+ "resolved": "https://mirror-npm.runflare.com/intl-messageformat/-/intl-messageformat-10.7.18.tgz",
+ "integrity": "sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "2.3.6",
+ "@formatjs/fast-memoize": "2.2.7",
+ "@formatjs/icu-messageformat-parser": "2.11.4",
+ "tslib": "^2.8.0"
+ }
+ },
"node_modules/is-array-buffer": {
"version": "3.0.5",
"dev": true,
@@ -7529,6 +7600,27 @@
}
}
},
+ "node_modules/next-intl": {
+ "version": "3.25.2",
+ "resolved": "https://mirror-npm.runflare.com/next-intl/-/next-intl-3.25.2.tgz",
+ "integrity": "sha512-C2BoRMX3h+KxCf5TC6BjlnZie2EOCK+QZz4C9A7xGf++1E/r1uD25wT8EZBaQAkO2uKKhBoZg78X8j8r2HPsag==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/amannn"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/intl-localematcher": "^0.5.4",
+ "negotiator": "^1.0.0",
+ "use-intl": "^3.25.2"
+ },
+ "peerDependencies": {
+ "next": "^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0"
+ }
+ },
"node_modules/next/node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://mirror-npm.runflare.com/postcss/-/postcss-8.4.31.tgz",
@@ -8486,6 +8578,12 @@
"react-dom": ">=16.8.0"
}
},
+ "node_modules/react-date-object": {
+ "version": "1.1.9",
+ "resolved": "https://mirror-npm.runflare.com/react-date-object/-/react-date-object-1.1.9.tgz",
+ "integrity": "sha512-NEbp/JSqwpF3nm4bXcez9XGwmlpOjSPJSYoRyPC1XOxzRHHaijp6xjMbYpyKB3O4yrluxsbwBHbO1WgeFKip3Q==",
+ "license": "MIT"
+ },
"node_modules/react-datepicker": {
"version": "7.3.0",
"license": "MIT",
@@ -10702,6 +10800,19 @@
}
}
},
+ "node_modules/use-intl": {
+ "version": "3.26.5",
+ "resolved": "https://mirror-npm.runflare.com/use-intl/-/use-intl-3.26.5.tgz",
+ "integrity": "sha512-OdsJnC/znPvHCHLQH/duvQNXnP1w0hPfS+tkSi3mAbfjYBGh4JnyfdwkQBfIVf7t8gs9eSX/CntxUMvtKdG2MQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/fast-memoize": "^2.2.0",
+ "intl-messageformat": "^10.5.14"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0"
+ }
+ },
"node_modules/use-sidecar": {
"version": "1.1.3",
"license": "MIT",
diff --git a/package.json b/package.json
index 76bf1b0..0b0e53e 100644
--- a/package.json
+++ b/package.json
@@ -59,13 +59,13 @@
"mapbox-gl": "3.9.0",
"negotiator": "1.0.0",
"next": "15.1.2",
+ "next-intl": "3.25.2",
"react": "18.3.1",
"react-apexcharts": "1.4.1",
"react-colorful": "5.6.1",
"react-date-object": "1.1.9",
"react-datepicker": "7.3.0",
"react-dom": "18.3.1",
- "react-multi-date-picker": "4.4.2",
"react-dropzone": "14.3.5",
"react-hook-form": "7.54.1",
"react-map-gl": "7.1.8",
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 1f9f344..d8dd802 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -2,6 +2,8 @@
import InitColorSchemeScript from '@mui/material/InitColorSchemeScript'
// Third-party Imports
+import { NextIntlClientProvider } from 'next-intl'
+import { getLocale, getMessages } from 'next-intl/server'
import 'react-perfect-scrollbar/dist/css/styles.css'
// Type Imports
@@ -26,17 +28,21 @@ export const metadata = getMetadata()
const RootLayout = async (props: ChildrenType) => {
const { children } = props
-
+
+ const locale = await getLocale()
+ const messages = await getMessages()
// Vars
const systemMode = await getSystemMode()
const direction = 'rtl' // Fixed RTL direction
return (
-
+
- {children}
+
+ {children}
+
)
diff --git a/src/components/layout/horizontal/HorizontalMenu.tsx b/src/components/layout/horizontal/HorizontalMenu.tsx
index a9d4f8f..9ff6e4f 100644
--- a/src/components/layout/horizontal/HorizontalMenu.tsx
+++ b/src/components/layout/horizontal/HorizontalMenu.tsx
@@ -1,3 +1,6 @@
+// React Imports
+import { useTranslations } from 'next-intl'
+
// MUI Imports
import { useTheme } from '@mui/material/styles'
@@ -9,11 +12,6 @@ import HorizontalNav, { Menu, SubMenu, MenuItem } from '@menu/horizontal-menu'
import VerticalNavContent from './VerticalNavContent'
import CustomChip from '@core/components/mui/Chip'
-// Constants
-import { navigationLabels } from '@/constants/navigation'
-
-// import { GenerateHorizontalMenu } from '@components/GenerateMenu'
-
// Hook Imports
import useVerticalNav from '@menu/hooks/useVerticalNav'
@@ -53,7 +51,7 @@ const RenderVerticalExpandIcon = ({ open, transitionDuration }: RenderVerticalEx
)
const HorizontalMenu = () => {
- // Hooks
+ const t = useTranslations('navigation')
const verticalNavOptions = useVerticalNav()
const theme = useTheme()
@@ -87,67 +85,67 @@ const HorizontalMenu = () => {
menuSectionStyles: verticalMenuSectionStyles(verticalNavOptions, theme)
}}
>
- }>
+ }>
}>
- {navigationLabels.analytics}
+ {t('analytics')}
}>
- {navigationLabels.eCommerce}
+ {t('eCommerce')}
}>
- {navigationLabels.academy}
+ {t('academy')}
}>
- {navigationLabels.logistics}
+ {t('logistics')}
- }>
- }>
-
-
-
-
+ }>
+ }>
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
- }>
-
-
+ }>
+
+
- }>
-
-
+ }>
+
+
}>
- {navigationLabels.chat}
+ {t('chat')}
}>
- {navigationLabels.calendar}
+ {t('calendar')}
}>
- {navigationLabels.kanban}
+ {t('kanban')}
- }>
-
+ }>
+
-
+
- }>
-
-
+ }>
+
+
- }>
-
-
+ }>
+
+
- }>
+ }>
}>
- {navigationLabels.userProfile}
+ {t('userProfile')}
- }>
+ }>
- }>
-
+ }>
+
-
+
-
+
-
+
-
+
-
+
- }>
-
+ }>
+
}>
- {navigationLabels.dialogExamples}
+ {t('dialogExamples')}
- }>
-
-
+ }>
+
+
-
-
+
+
- }>
+ }>
- }>
+ }>
}>
- {navigationLabels.formLayouts}
+ {t('formLayouts')}
}>
- {navigationLabels.formValidation}
+ {t('formValidation')}
}>
- {navigationLabels.formWizard}
+ {t('formWizard')}
}>
- {navigationLabels.reactTable}
+ {t('reactTable')}
}
@@ -318,7 +316,7 @@ const HorizontalMenu = () => {
suffix={}
target='_blank'
>
- {navigationLabels.formELements}
+ {t('formELements')}
}
@@ -326,25 +324,25 @@ const HorizontalMenu = () => {
suffix={}
target='_blank'
>
- {navigationLabels.muiTables}
+ {t('muiTables')}
- }>
+ }>
}>
- {navigationLabels.apex}
+ {t('apex')}
}>
- {navigationLabels.recharts}
+ {t('recharts')}
- }>
+ }>
}
href={`${process.env.NEXT_PUBLIC_DOCS_URL}/docs/user-interface/foundation`}
suffix={}
target='_blank'
>
- {navigationLabels.foundation}
+ {t('foundation')}
}
@@ -352,7 +350,7 @@ const HorizontalMenu = () => {
suffix={}
target='_blank'
>
- {navigationLabels.components}
+ {t('components')}
}
@@ -360,7 +358,7 @@ const HorizontalMenu = () => {
suffix={}
target='_blank'
>
- {navigationLabels.menuExamples}
+ {t('menuExamples')}
}
@@ -368,7 +366,7 @@ const HorizontalMenu = () => {
href='https://pixinvent.ticksy.com'
icon={}
>
- {navigationLabels.raiseSupport}
+ {t('raiseSupport')}
}
@@ -376,13 +374,13 @@ const HorizontalMenu = () => {
icon={}
href={`${process.env.NEXT_PUBLIC_DOCS_URL}`}
>
- {navigationLabels.documentation}
+ {t('documentation')}
}
icon={}
>
- {navigationLabels.itemWithBadge}
+ {t('itemWithBadge')}
}
@@ -390,16 +388,16 @@ const HorizontalMenu = () => {
target='_blank'
suffix={}
>
- {navigationLabels.externalLink}
+ {t('externalLink')}
- }>
-
-
-
-
+ }>
+
+
+
+
-
+
{/*