MICRA 1.0

This commit is contained in:
Flatlogic Bot 2026-06-29 06:18:56 +00:00
parent 0c89516ec1
commit da3c00f31c
77 changed files with 2114 additions and 895 deletions

View File

@ -0,0 +1,483 @@
{
"language": {
"id": "Bahasa Indonesia",
"en-GB": "English UK"
},
"app": {
"title": "Aquaculture Ops CRUD",
"description": "Multi-tenant aquaculture operations and marketplace CRUD with RBAC, orders, transactions, audit logs, and APIs."
},
"pages": {
"dashboard": {
"pageTitle": "Dashboard",
"overview": "Overview",
"loadingWidgets": "Loading widgets...",
"loading": "Loading..."
},
"login": {
"pageTitle": "Login",
"sampleCredentialsAdmin": "Use {{email}} / {{password}} to log in as Administrator",
"sampleCredentialsUser": "Use {{email}} / {{password}} to log in as User",
"form": {
"loginLabel": "Login",
"loginHelp": "Please enter your login",
"passwordLabel": "Password",
"passwordHelp": "Please enter your password",
"remember": "Remember",
"forgotPassword": "Forgot password?",
"loginButton": "Login",
"loading": "Loading...",
"noAccountYet": "Dont have an account yet?",
"newAccount": "New account"
},
"pexels": {
"photoCredit": "Photo by {{photographer}} on Pexels",
"videoCredit": "Video by {{name}} on Pexels",
"videoUnsupported": "Your browser does not support the video tag."
},
"footer": {
"copyright": "© {{year}} {{title}}. All rights reserved",
"privacy": "Privacy Policy"
}
}
},
"components": {
"widgetCreator": {
"title": "Create chart or widget",
"helpText": "Describe your new widget or chart in natural language. For example: \"Number of admin users\" OR \"red chart with number of closed contracts grouped by month\"",
"settingsTitle": "Widget Creator settings",
"settingsDescription": "What role are we showing and creating widgets for?",
"doneButton": "Done",
"loading": "Loading..."
},
"search": {
"placeholder": "Search",
"required": "Required",
"minLength": "Minimum length: {{count}} characters"
}
},
"labels": {
"overview": "Overview",
"dashboard": "Dashboard",
"farm_ops_command_center": "Farm Ops Command Centre",
"multi_tenant_aquaculture_workflow": "Multi-tenant aquaculture workflow",
"record_feed_monitor_appetite_and_keep_the_farm_team_aligned": "Record feed, monitor appetite, and keep the farm team aligned.",
"a_focused_daily_operations_slice_built_on_top_of_your_generated_crud_entities_batches_feed_products_and_feeding_logs": "A focused daily operations slice built on top of your generated CRUD entities: batches, feed products, and feeding logs.",
"fed_today": "Fed today",
"active_batches": "Active batches",
"latest_appetite": "Latest appetite",
"quick_feed_entry": "Quick feed entry",
"record_the_most_common_daily_farm_action_without_leaving_the_operations_context": "Record the most common daily farm action without leaving the operations context.",
"saving": "Saving...",
"loading_farm_data": "Loading farm data...",
"recent_activity": "Recent activity",
"latest_feeding_logs_from_the_generated_crud_api": "Latest feeding logs from the generated CRUD API.",
"record_snapshot": "Record snapshot",
"detail": "Detail",
"batch_context": "Batch context",
"daily_rhythm": "Daily rhythm",
"marketplace_ready": "Marketplace ready",
"every_record_is_tied_to_generated_batch_crud_for_traceability": "Every record is tied to generated batch CRUD for traceability.",
"fast_input_supports_the_staff_workflow_farmers_repeat_every_shift": "Fast input supports the staff workflow farmers repeat every shift.",
"operational_records_are_one_step_away_from_harvest_listing_order_and_transaction_flows": "Operational records are one step away from harvest, listing, order, and transaction flows.",
"no_feeding_logs_yet": "No feeding logs yet",
"use_the_quick_entry_form_to_create_the_first_daily_operation_record": "Use the quick entry form to create the first daily operation record.",
"select_a_feeding_log_to_inspect_its_farm_ready_details": "Select a feeding log to inspect its farm-ready details.",
"no_notes_added_for_this_operation": "No notes added for this operation.",
"team_member": "Team member",
"unassigned_batch": "Unassigned batch",
"not_specified": "Not specified",
"not_scheduled": "Not scheduled",
"batch_before_recording_feed": "Choose a batch before recording feed.",
"add_the_feeding_time": "Add the feeding time.",
"feed_quantity_must_be_greater_than_0_kg": "Feed quantity must be greater than 0 kg.",
"feeding_record_saved_the_latest_activity_list_has_been_refreshed": "Feeding record saved. The latest activity list has been refreshed.",
"could_not_load_the_farm_operations_workspace_please_refresh_or_check_your_permissions": "Could not load the farm operations workspace. Please refresh or check your permissions.",
"could_not_save_the_feeding_record_please_check_the_values_and_try_again": "Could not save the feeding record. Please check the values and try again.",
"you_can_view_existing_data_but_need_create_feeding_logs_permission_to_save_new_records": "You can view existing data, but need Create Feeding Logs permission to save new records.",
"create_your_first_batch_before_recording_feed": "Create your first batch before recording feed.",
"select_a_batch": "Select a batch",
"select_feed_product_optional": "Select feed product (optional)",
"optional_notes_for_the_next_shift": "Optional notes for the next shift",
"page": "Page",
"of": "of",
"please_confirm": "Please confirm",
"are_you_sure_you_want_to_delete_this_item": "Are you sure you want to delete this item?",
"allowed_formats": "Allowed formats: {{formats}}",
"click_to_upload": "Click to upload",
"or_drag_and_drop": "or drag and drop",
"switch_to_table": "Switch to table",
"switch_to_cards": "Switch to cards",
"users_widgets": "{{role}}'s widgets",
"no_data": "No data",
"matches_with": "Matches with: {{query}}",
"no_matches": "No matches",
"quick_input": "Quick input",
"log_a_feeding": "Log a feeding",
"capture_the_minimum_operational_data_and_confirm_it_immediately": "Capture the minimum operational data and confirm it immediately.",
"loading_batches_and_feed_products": "Loading batches and feed products...",
"no_batches_available_yet": "No batches available yet.",
"create_a_batch_first_then_return_here_to_record_daily_feeding_activity": "Create a batch first, then return here to record daily feeding activity.",
"optional_observation_e_g_fish_surfaced_quickly_mild_leftovers_weather_change": "Optional observation, e.g. fish surfaced quickly, mild leftovers, weather change...",
"your_role_can_view_feeding_logs_but_cannot_create_new_records": "Your role can view feeding logs but cannot create new records.",
"activity_stream": "Activity stream",
"latest_feeding_logs": "Latest feeding logs",
"loading_latest_records": "Loading latest records...",
"use_the_quick_input_form_to_create_the_first_daily_operation_record": "Use the quick input form to create the first daily operation record.",
"by": "by",
"recorded": "Recorded",
"feed": "Feed",
"method": "Method",
"choose_a_batch_before_recording_feed": "Choose a batch before recording feed.",
"login": "Login",
"password": "Password",
"please_enter_your_login": "Please enter your login",
"please_enter_your_password": "Please enter your password",
"remember": "Remember",
"loading": "Loading..."
},
"crud": {
"actions": {
"new": "New",
"view": "View",
"edit": "Edit",
"delete": "Delete",
"submit": "Submit",
"reset": "Reset",
"cancel": "Cancel",
"confirm": "Confirm",
"filter": "Filter",
"apply": "Apply",
"download_csv": "Download CSV",
"upload_csv": "Upload CSV",
"new_item": "New item",
"open_full_crud": "Open full CRUD",
"open_detail": "Open detail",
"marketplace": "Marketplace",
"delete_rows": "Delete {{count}} row(s)",
"deleting": "Deleting...",
"select_value": "Select value",
"from": "From",
"to": "To",
"contains": "Contains",
"contained": "Contained",
"value": "Value",
"action": "Action",
"create_batch": "Create batch",
"save_feeding_record": "Save feeding record",
"advanced_form": "Advanced form",
"refresh": "Refresh"
}
},
"fields": {
"id": "ID",
"name": "Name",
"first_name": "First name",
"lastname": "Last name",
"last_name": "Last name",
"phone_number": "Phone number",
"email": "Email",
"disabled": "Disabled",
"password": "Password",
"provider": "Provider",
"custom_permissions": "Custom permissions",
"custom_permissions_filter": "Custom permissions filter",
"email_verified": "Email verified",
"email_verification_token": "Email verification token",
"email_verification_token_expires_at": "Email verification token expires at",
"password_reset_token": "Password reset token",
"password_reset_token_expires_at": "Password reset token expires at",
"app_role": "App role",
"avatar": "Avatar",
"created_by": "Created by",
"updated_by": "Updated by",
"created_at": "Created at",
"updated_at": "Updated at",
"organizations": "Organisations",
"organization": "Organisation",
"tenant": "Tenant",
"location": "Location",
"pond": "Pond",
"batch": "Batch",
"species": "Species",
"user": "User",
"role": "Role",
"permissions": "Permissions",
"permission": "Permission",
"pond_name": "Pond name",
"pond_type": "Pond type",
"area_sq_m": "Area (sq m)",
"average_depth_m": "Average depth (m)",
"avg_depth_m": "Average depth (m)",
"notes": "Notes",
"status": "Status",
"species_name": "Species name",
"scientific_name": "Scientific name",
"typical_harvest_size": "Typical harvest size",
"batch_code": "Batch code",
"stocked_at": "Stocked at",
"initial_count": "Initial count",
"initial_avg_weight_g": "Initial average weight (g)",
"initial_average_weight_g": "Initial average weight (g)",
"batch_status": "Batch status",
"expected_harvest_at": "Expected harvest at",
"product_name": "Product name",
"brand": "Brand",
"feed_type": "Feed type",
"protein_percent": "Protein %",
"fat_percent": "Fat %",
"pellet_size_mm": "Pellet size (mm)",
"fed_at": "Fed at",
"quantity_kg": "Quantity (kg)",
"feeding_method": "Feeding method",
"appetite": "Appetite",
"recorded_by": "Recorded by",
"sampled_at": "Sampled at",
"temperature_c": "Temperature (°C)",
"ph": "pH",
"dissolved_oxygen_mg_l": "Dissolved oxygen (mg/L)",
"salinity_ppt": "Salinity (ppt)",
"ammonia_mg_l": "Ammonia (mg/L)",
"nitrite_mg_l": "Nitrite (mg/L)",
"nitrate_mg_l": "Nitrate (mg/L)",
"turbidity_ntu": "Turbidity (NTU)",
"observed_at": "Observed at",
"event_type": "Event type",
"severity": "Severity",
"mortality_count": "Mortality count",
"symptoms": "Symptoms",
"treatment": "Treatment",
"resolution_status": "Resolution status",
"resolved_at": "Resolved at",
"reported_by": "Reported by",
"attachments": "Attachments",
"item_category": "Item category",
"item_name": "Item name",
"sku": "SKU",
"unit": "Unit",
"quantity_on_hand": "Quantity on hand",
"reorder_level": "Reorder level",
"unit_cost": "Unit cost",
"inventory_item": "Inventory item",
"feed_product": "Feed product",
"movement_type": "Movement type",
"quantity": "Quantity",
"moved_at": "Moved at",
"reference": "Reference",
"source": "Source",
"destination": "Destination",
"harvested_at": "Harvested at",
"total_weight_kg": "Total weight (kg)",
"total_count": "Total count",
"avg_weight_g": "Average weight (g)",
"grade": "Grade",
"listing_title": "Listing title",
"description": "Description",
"product_form": "Product form",
"available_quantity_kg": "Available quantity (kg)",
"price_per_kg": "Price per kg",
"currency": "Currency",
"available_from": "Available from",
"expires_at": "Expires at",
"listing_status": "Listing status",
"seller_tenant": "Seller tenant",
"buyer_tenant": "Buyer tenant",
"farm_tenant": "Farm tenant",
"investor_tenant": "Investor tenant",
"harvest": "Harvest",
"fulfillment_location": "Fulfilment location",
"photos": "Photos",
"order_number": "Order number",
"ordered_at": "Ordered at",
"order_status": "Order status",
"subtotal_amount": "Subtotal amount",
"tax_amount": "Tax amount",
"shipping_amount": "Shipping amount",
"total_amount": "Total amount",
"delivery_address": "Delivery address",
"buyer_notes": "Buyer notes",
"expected_delivery_at": "Expected delivery at",
"listing": "Listing",
"order": "Order",
"unit_price": "Unit price",
"line_total": "Line total",
"transaction_type": "Transaction type",
"transaction_status": "Transaction status",
"amount": "Amount",
"provider_reference": "Provider reference",
"processed_at": "Processed at",
"failure_reason": "Failure reason",
"shipment_status": "Shipment status",
"carrier": "Carrier",
"tracking_number": "Tracking number",
"status_at": "Status at",
"status_details": "Status details",
"investment_name": "Investment name",
"instrument_type": "Instrument type",
"amount_committed": "Amount committed",
"amount_funded": "Amount funded",
"committed_at": "Committed at",
"funded_at": "Funded at",
"investment_status": "Investment status",
"to_email": "To email",
"subject": "Subject",
"template_key": "Template key",
"payload": "Payload",
"send_status": "Send status",
"sent_at": "Sent at",
"recipient_user": "Recipient user",
"action": "Action",
"entity_name": "Entity name",
"entity_reference": "Entity reference",
"occurred_at": "Occurred at",
"ip_address": "IP address",
"user_agent": "User agent",
"change_summary": "Change summary",
"actor_user": "Actor user",
"key_name": "Key name",
"key_prefix": "Key prefix",
"access_level": "Access level",
"last_used_at": "Last used at",
"is_revoked": "Is revoked",
"endpoint_name": "Endpoint name",
"url": "URL",
"secret": "Secret",
"is_enabled": "Is enabled",
"event_types": "Event types",
"last_delivery_at": "Last delivery at",
"endpoint": "Endpoint",
"event_reference": "Event reference",
"delivered_at": "Delivered at",
"delivery_status": "Delivery status",
"http_status": "HTTP status",
"request_payload": "Request payload",
"response_body": "Response body",
"attempt_count": "Attempt count",
"job_type": "Job type",
"job_status": "Job status",
"total_rows": "Total rows",
"processed_rows": "Processed rows",
"error_rows": "Error rows",
"error_report": "Error report",
"started_at": "Started at",
"finished_at": "Finished at",
"requested_by": "Requested by",
"source_file": "Source file",
"result_file": "Result file",
"membership_status": "Membership status",
"joined_at": "Joined at",
"tenant_name": "Tenant name",
"slug": "Slug",
"tenant_type": "Tenant type",
"contact_email": "Contact email",
"contact_phone": "Contact phone",
"billing_address": "Billing address",
"subscription_status": "Subscription status",
"trial_ends_at": "Trial ends at",
"location_name": "Location name",
"address": "Address",
"latitude": "Latitude",
"longitude": "Longitude",
"timezone": "Time zone",
"is_primary": "Is primary",
"role_customization": "Role customisation",
"global_access": "Global access",
"permissions_filter": "Permissions filter",
"multi_text": "Multi text"
},
"entities": {
"dashboard": "Dashboard",
"farm_ops": "Farm Ops",
"users": "Users",
"user": "User",
"roles": "Roles",
"role": "Role",
"permissions": "Permissions",
"permission": "Permission",
"organizations": "Organisations",
"organization": "Organisation",
"tenants": "Tenants",
"tenant": "Tenant",
"user_memberships": "User memberships",
"user_membership": "User membership",
"tenant_locations": "Tenant locations",
"tenant_location": "Tenant location",
"ponds": "Ponds",
"pond": "Pond",
"species": "Species",
"batches": "Batches",
"batch": "Batch",
"feed_products": "Feed products",
"feed_product": "Feed product",
"feeding_logs": "Feeding logs",
"feeding_log": "Feeding log",
"water_quality_logs": "Water quality logs",
"water_quality_log": "Water quality log",
"health_events": "Health events",
"health_event": "Health event",
"inventory_items": "Inventory items",
"inventory_item": "Inventory item",
"inventory_movements": "Inventory movements",
"inventory_movement": "Inventory movement",
"harvests": "Harvests",
"harvest": "Harvest",
"marketplace_listings": "Marketplace listings",
"marketplace_listing": "Marketplace listing",
"orders": "Orders",
"order": "Order",
"order_items": "Order items",
"order_item": "Order item",
"payment_transactions": "Payment transactions",
"payment_transaction": "Payment transaction",
"shipment_updates": "Shipment updates",
"shipment_update": "Shipment update",
"investments": "Investments",
"investment": "Investment",
"email_notifications": "Email notifications",
"email_notification": "Email notification",
"audit_logs": "Audit logs",
"audit_log": "Audit log",
"api_keys": "API keys",
"api_key": "API key",
"webhook_endpoints": "Webhook endpoints",
"webhook_endpoint": "Webhook endpoint",
"webhook_deliveries": "Webhook deliveries",
"webhook_delivery": "Webhook delivery",
"csv_jobs": "CSV jobs",
"csv_job": "CSV job"
},
"enums": {
"active": "Active",
"inactive": "Inactive",
"maintenance": "Maintenance",
"planned": "Planned",
"harvested": "Harvested",
"closed": "Closed",
"lost": "Lost",
"manual": "Manual",
"auto_feeder": "Auto feeder",
"broadcast": "Broadcast",
"tray": "Tray",
"low": "Low",
"normal": "Normal",
"high": "High",
"pending": "Pending",
"confirmed": "Confirmed",
"packed": "Packed",
"shipped": "Shipped",
"delivered": "Delivered",
"canceled": "Cancelled",
"refunded": "Refunded",
"draft": "Draft",
"paused": "Paused",
"sold_out": "Sold out",
"expired": "Expired",
"removed": "Removed",
"earthen": "Earthen",
"lined": "Lined",
"tank": "Tank",
"cage": "Cage",
"raceway": "Raceway",
"other": "Other"
}
}

View File

@ -0,0 +1,484 @@
{
"language": {
"id": "Bahasa Indonesia",
"en-GB": "English UK"
},
"app": {
"title": "CRUD Operasi Akuakultur",
"description": "CRUD operasi akuakultur dan marketplace multi-tenant dengan RBAC, pesanan, transaksi, log audit, dan API."
},
"pages": {
"dashboard": {
"pageTitle": "Dasbor",
"overview": "Ringkasan",
"loadingWidgets": "Memuat widget...",
"loading": "Memuat..."
},
"login": {
"pageTitle": "Masuk",
"sampleCredentialsAdmin": "Gunakan {{email}} / {{password}} untuk masuk sebagai Administrator",
"sampleCredentialsUser": "Gunakan {{email}} / {{password}} untuk masuk sebagai Pengguna",
"form": {
"loginLabel": "Login",
"loginHelp": "Masukkan login Anda",
"passwordLabel": "Kata sandi",
"passwordHelp": "Masukkan kata sandi Anda",
"remember": "Ingat saya",
"forgotPassword": "Lupa kata sandi?",
"loginButton": "Masuk",
"loading": "Memuat...",
"noAccountYet": "Belum punya akun?",
"newAccount": "Akun baru"
},
"pexels": {
"photoCredit": "Foto oleh {{photographer}} di Pexels",
"videoCredit": "Video oleh {{name}} di Pexels",
"videoUnsupported": "Browser Anda tidak mendukung tag video."
},
"footer": {
"copyright": "© {{year}} {{title}}. Semua hak dilindungi",
"privacy": "Kebijakan Privasi"
}
}
},
"components": {
"widgetCreator": {
"title": "Buat grafik atau widget",
"helpText": "Jelaskan widget atau grafik baru dengan bahasa natural. Contoh: \"Jumlah pengguna admin\" ATAU \"grafik merah berisi jumlah kontrak selesai dikelompokkan per bulan\"",
"settingsTitle": "Pengaturan pembuat widget",
"settingsDescription": "Widget ditampilkan dan dibuat untuk peran apa?",
"doneButton": "Selesai",
"loading": "Memuat..."
},
"search": {
"placeholder": "Cari",
"required": "Wajib",
"minLength": "Panjang minimum: {{count}} karakter"
}
},
"labels": {
"overview": "Ringkasan",
"dashboard": "Dasbor",
"farm_ops_command_center": "Pusat Komando Operasi Tambak",
"multi_tenant_aquaculture_workflow": "Alur kerja akuakultur multi-tenant",
"record_feed_monitor_appetite_and_keep_the_farm_team_aligned": "Catat pakan, pantau nafsu makan, dan selaraskan tim tambak.",
"a_focused_daily_operations_slice_built_on_top_of_your_generated_crud_entities_batches_feed_products_and_feeding_logs": "Bagian operasi harian yang fokus, dibangun di atas entitas CRUD yang sudah dibuat: batch, produk pakan, dan log pemberian pakan.",
"fed_today": "Pakan hari ini",
"active_batches": "Batch aktif",
"latest_appetite": "Nafsu makan terbaru",
"quick_feed_entry": "Input pakan cepat",
"record_the_most_common_daily_farm_action_without_leaving_the_operations_context": "Catat aktivitas harian tambak yang paling umum tanpa keluar dari konteks operasi.",
"saving": "Menyimpan...",
"loading_farm_data": "Memuat data tambak...",
"recent_activity": "Aktivitas terbaru",
"latest_feeding_logs_from_the_generated_crud_api": "Log pemberian pakan terbaru dari API CRUD yang sudah dibuat.",
"record_snapshot": "Ringkasan catatan",
"detail": "Detail",
"batch_context": "Konteks batch",
"daily_rhythm": "Ritme harian",
"marketplace_ready": "Siap marketplace",
"every_record_is_tied_to_generated_batch_crud_for_traceability": "Setiap catatan terhubung ke CRUD batch untuk keterlacakan.",
"fast_input_supports_the_staff_workflow_farmers_repeat_every_shift": "Input cepat mendukung alur kerja staf yang diulang petani setiap shift.",
"operational_records_are_one_step_away_from_harvest_listing_order_and_transaction_flows": "Catatan operasi selangkah lagi dari alur panen, listing, pesanan, dan transaksi.",
"no_feeding_logs_yet": "Belum ada log pemberian pakan",
"use_the_quick_entry_form_to_create_the_first_daily_operation_record": "Gunakan formulir input cepat untuk membuat catatan operasi harian pertama.",
"select_a_feeding_log_to_inspect_its_farm_ready_details": "Pilih log pemberian pakan untuk melihat detail siap pakai di tambak.",
"no_notes_added_for_this_operation": "Belum ada catatan untuk operasi ini.",
"team_member": "Anggota tim",
"unassigned_batch": "Batch belum ditetapkan",
"not_specified": "Belum ditentukan",
"not_scheduled": "Belum dijadwalkan",
"batch_before_recording_feed": "Pilih batch sebelum mencatat pakan.",
"add_the_feeding_time": "Tambahkan waktu pemberian pakan.",
"feed_quantity_must_be_greater_than_0_kg": "Jumlah pakan harus lebih dari 0 kg.",
"feeding_record_saved_the_latest_activity_list_has_been_refreshed": "Catatan pakan tersimpan. Daftar aktivitas terbaru telah diperbarui.",
"could_not_load_the_farm_operations_workspace_please_refresh_or_check_your_permissions": "Tidak dapat memuat ruang kerja operasi tambak. Silakan muat ulang atau periksa izin Anda.",
"could_not_save_the_feeding_record_please_check_the_values_and_try_again": "Tidak dapat menyimpan catatan pakan. Periksa nilai yang diisi lalu coba lagi.",
"you_can_view_existing_data_but_need_create_feeding_logs_permission_to_save_new_records": "Anda dapat melihat data yang ada, tetapi perlu izin Buat Log Pemberian Pakan untuk menyimpan catatan baru.",
"create_your_first_batch_before_recording_feed": "Buat batch pertama sebelum mencatat pakan.",
"select_a_batch": "Pilih batch",
"select_feed_product_optional": "Pilih produk pakan (opsional)",
"optional_notes_for_the_next_shift": "Catatan opsional untuk shift berikutnya",
"page": "Halaman",
"of": "dari",
"please_confirm": "Mohon konfirmasi",
"are_you_sure_you_want_to_delete_this_item": "Apakah Anda yakin ingin menghapus item ini?",
"allowed_formats": "Format yang diizinkan: {{formats}}",
"click_to_upload": "Klik untuk mengunggah",
"or_drag_and_drop": "atau seret dan lepas",
"switch_to_table": "Beralih ke tabel",
"switch_to_cards": "Beralih ke kartu",
"users_widgets": "Widget milik {{role}}",
"no_data": "Tidak ada data",
"matches_with": "Cocok dengan: {{query}}",
"no_matches": "Tidak ada hasil",
"quick_input": "Input cepat",
"log_a_feeding": "Catat pemberian pakan",
"capture_the_minimum_operational_data_and_confirm_it_immediately": "Isi data operasi minimum dan konfirmasi langsung.",
"loading_batches_and_feed_products": "Memuat batch dan produk pakan...",
"no_batches_available_yet": "Belum ada batch.",
"create_a_batch_first_then_return_here_to_record_daily_feeding_activity": "Buat batch terlebih dahulu, lalu kembali ke sini untuk mencatat aktivitas pakan harian.",
"optional_observation_e_g_fish_surfaced_quickly_mild_leftovers_weather_change": "Observasi opsional, mis. ikan cepat naik, sedikit sisa pakan, perubahan cuaca...",
"your_role_can_view_feeding_logs_but_cannot_create_new_records": "Peran Anda dapat melihat log pakan, tetapi tidak dapat membuat catatan baru.",
"activity_stream": "Alur aktivitas",
"latest_feeding_logs": "Log pakan terbaru",
"loading_latest_records": "Memuat catatan terbaru...",
"use_the_quick_input_form_to_create_the_first_daily_operation_record": "Gunakan formulir input cepat untuk membuat catatan operasi harian pertama.",
"by": "oleh",
"recorded": "Dicatat",
"feed": "Pakan",
"method": "Metode",
"choose_a_batch_before_recording_feed": "Pilih batch sebelum mencatat pakan.",
"login": "Masuk",
"password": "Kata sandi",
"please_enter_your_login": "Masukkan login Anda",
"please_enter_your_password": "Masukkan kata sandi Anda",
"remember": "Ingat saya",
"loading": "Memuat..."
},
"crud": {
"actions": {
"new": "Buat",
"view": "Lihat",
"edit": "Edit",
"delete": "Hapus",
"submit": "Simpan",
"reset": "Reset",
"cancel": "Batal",
"confirm": "Konfirmasi",
"filter": "Filter",
"apply": "Terapkan",
"download_csv": "Unduh CSV",
"upload_csv": "Unggah CSV",
"new_item": "Item baru",
"open_full_crud": "Buka CRUD lengkap",
"open_detail": "Buka detail",
"marketplace": "Marketplace",
"delete_rows": "Hapus {{count}} baris",
"deleting": "Menghapus...",
"select_value": "Pilih nilai",
"from": "Dari",
"to": "Sampai",
"contains": "Berisi",
"contained": "Berisi",
"value": "Nilai",
"action": "Aksi",
"create_batch": "Buat batch",
"save_feeding_record": "Simpan catatan pakan",
"advanced_form": "Form lanjutan",
"refresh": "Segarkan"
}
},
"fields": {
"id": "ID",
"name": "Nama",
"first_name": "Nama depan",
"firstname": "Nama depan",
"last_name": "Nama belakang",
"lastname": "Nama belakang",
"phone_number": "Nomor telepon",
"email": "Email",
"disabled": "Dinonaktifkan",
"password": "Kata sandi",
"provider": "Penyedia",
"custom_permissions": "Izin khusus",
"custom_permissions_filter": "Filter izin khusus",
"email_verified": "Email terverifikasi",
"email_verification_token": "Token verifikasi email",
"email_verification_token_expires_at": "Token verifikasi email kedaluwarsa pada",
"password_reset_token": "Token reset kata sandi",
"password_reset_token_expires_at": "Token reset kata sandi kedaluwarsa pada",
"app_role": "Peran aplikasi",
"avatar": "Avatar",
"created_by": "Dibuat oleh",
"updated_by": "Diperbarui oleh",
"created_at": "Dibuat pada",
"updated_at": "Diperbarui pada",
"organizations": "Organisasi",
"organization": "Organisasi",
"tenant": "Tenant",
"location": "Lokasi",
"pond": "Kolam",
"batch": "Batch",
"species": "Spesies",
"user": "Pengguna",
"role": "Peran",
"permissions": "Izin",
"permission": "Izin",
"pond_name": "Nama kolam",
"pond_type": "Tipe kolam",
"area_sq_m": "Luas (m²)",
"average_depth_m": "Kedalaman rata-rata (m)",
"avg_depth_m": "Kedalaman rata-rata (m)",
"notes": "Catatan",
"status": "Status",
"species_name": "Nama spesies",
"scientific_name": "Nama ilmiah",
"typical_harvest_size": "Ukuran panen umum",
"batch_code": "Kode batch",
"stocked_at": "Tanggal tebar",
"initial_count": "Jumlah awal",
"initial_avg_weight_g": "Bobot rata-rata awal (g)",
"initial_average_weight_g": "Bobot rata-rata awal (g)",
"batch_status": "Status batch",
"expected_harvest_at": "Perkiraan panen pada",
"product_name": "Nama produk",
"brand": "Merek",
"feed_type": "Jenis pakan",
"protein_percent": "Protein %",
"fat_percent": "Lemak %",
"pellet_size_mm": "Ukuran pelet (mm)",
"fed_at": "Waktu pemberian pakan",
"quantity_kg": "Jumlah (kg)",
"feeding_method": "Metode pemberian pakan",
"appetite": "Nafsu makan",
"recorded_by": "Dicatat oleh",
"sampled_at": "Waktu sampel",
"temperature_c": "Suhu (°C)",
"ph": "pH",
"dissolved_oxygen_mg_l": "Oksigen terlarut (mg/L)",
"salinity_ppt": "Salinitas (ppt)",
"ammonia_mg_l": "Amonia (mg/L)",
"nitrite_mg_l": "Nitrit (mg/L)",
"nitrate_mg_l": "Nitrat (mg/L)",
"turbidity_ntu": "Kekeruhan (NTU)",
"observed_at": "Diamati pada",
"event_type": "Jenis kejadian",
"severity": "Tingkat keparahan",
"mortality_count": "Jumlah kematian",
"symptoms": "Gejala",
"treatment": "Penanganan",
"resolution_status": "Status penyelesaian",
"resolved_at": "Diselesaikan pada",
"reported_by": "Dilaporkan oleh",
"attachments": "Lampiran",
"item_category": "Kategori item",
"item_name": "Nama item",
"sku": "SKU",
"unit": "Satuan",
"quantity_on_hand": "Stok tersedia",
"reorder_level": "Batas pemesanan ulang",
"unit_cost": "Biaya satuan",
"inventory_item": "Item inventaris",
"feed_product": "Produk pakan",
"movement_type": "Jenis pergerakan",
"quantity": "Jumlah",
"moved_at": "Dipindahkan pada",
"reference": "Referensi",
"source": "Sumber",
"destination": "Tujuan",
"harvested_at": "Dipanen pada",
"total_weight_kg": "Berat total (kg)",
"total_count": "Jumlah total",
"avg_weight_g": "Bobot rata-rata (g)",
"grade": "Grade",
"listing_title": "Judul listing",
"description": "Deskripsi",
"product_form": "Bentuk produk",
"available_quantity_kg": "Jumlah tersedia (kg)",
"price_per_kg": "Harga per kg",
"currency": "Mata uang",
"available_from": "Tersedia mulai",
"expires_at": "Kedaluwarsa pada",
"listing_status": "Status listing",
"seller_tenant": "Tenant penjual",
"buyer_tenant": "Tenant pembeli",
"farm_tenant": "Tenant tambak",
"investor_tenant": "Tenant investor",
"harvest": "Panen",
"fulfillment_location": "Lokasi pemenuhan",
"photos": "Foto",
"order_number": "Nomor pesanan",
"ordered_at": "Dipesan pada",
"order_status": "Status pesanan",
"subtotal_amount": "Subtotal",
"tax_amount": "Pajak",
"shipping_amount": "Biaya pengiriman",
"total_amount": "Total",
"delivery_address": "Alamat pengiriman",
"buyer_notes": "Catatan pembeli",
"expected_delivery_at": "Perkiraan pengiriman pada",
"listing": "Listing",
"order": "Pesanan",
"unit_price": "Harga satuan",
"line_total": "Total baris",
"transaction_type": "Jenis transaksi",
"transaction_status": "Status transaksi",
"amount": "Jumlah",
"provider_reference": "Referensi penyedia",
"processed_at": "Diproses pada",
"failure_reason": "Alasan gagal",
"shipment_status": "Status pengiriman",
"carrier": "Kurir",
"tracking_number": "Nomor resi",
"status_at": "Status pada",
"status_details": "Detail status",
"investment_name": "Nama investasi",
"instrument_type": "Jenis instrumen",
"amount_committed": "Jumlah komitmen",
"amount_funded": "Jumlah didanai",
"committed_at": "Dikomitmenkan pada",
"funded_at": "Didanai pada",
"investment_status": "Status investasi",
"to_email": "Email tujuan",
"subject": "Subjek",
"template_key": "Kunci template",
"payload": "Payload",
"send_status": "Status kirim",
"sent_at": "Dikirim pada",
"recipient_user": "Pengguna penerima",
"action": "Aksi",
"entity_name": "Nama entitas",
"entity_reference": "Referensi entitas",
"occurred_at": "Terjadi pada",
"ip_address": "Alamat IP",
"user_agent": "User agent",
"change_summary": "Ringkasan perubahan",
"actor_user": "Pengguna pelaku",
"key_name": "Nama kunci",
"key_prefix": "Awalan kunci",
"access_level": "Level akses",
"last_used_at": "Terakhir digunakan pada",
"is_revoked": "Dicabut",
"endpoint_name": "Nama endpoint",
"url": "URL",
"secret": "Rahasia",
"is_enabled": "Aktif",
"event_types": "Jenis event",
"last_delivery_at": "Pengiriman terakhir pada",
"endpoint": "Endpoint",
"event_reference": "Referensi event",
"delivered_at": "Dikirim pada",
"delivery_status": "Status pengiriman",
"http_status": "Status HTTP",
"request_payload": "Payload permintaan",
"response_body": "Isi respons",
"attempt_count": "Jumlah percobaan",
"job_type": "Jenis pekerjaan",
"job_status": "Status pekerjaan",
"total_rows": "Total baris",
"processed_rows": "Baris diproses",
"error_rows": "Baris error",
"error_report": "Laporan error",
"started_at": "Dimulai pada",
"finished_at": "Selesai pada",
"requested_by": "Diminta oleh",
"source_file": "File sumber",
"result_file": "File hasil",
"membership_status": "Status keanggotaan",
"joined_at": "Bergabung pada",
"tenant_name": "Nama tenant",
"slug": "Slug",
"tenant_type": "Jenis tenant",
"contact_email": "Email kontak",
"contact_phone": "Telepon kontak",
"billing_address": "Alamat penagihan",
"subscription_status": "Status langganan",
"trial_ends_at": "Masa uji coba berakhir pada",
"location_name": "Nama lokasi",
"address": "Alamat",
"latitude": "Lintang",
"longitude": "Bujur",
"timezone": "Zona waktu",
"is_primary": "Utama",
"role_customization": "Kustomisasi peran",
"global_access": "Akses global",
"permissions_filter": "Filter izin",
"multi_text": "Teks tambahan"
},
"entities": {
"dashboard": "Dasbor",
"farm_ops": "Operasi Tambak",
"users": "Pengguna",
"user": "Pengguna",
"roles": "Peran",
"role": "Peran",
"permissions": "Izin",
"permission": "Izin",
"organizations": "Organisasi",
"organization": "Organisasi",
"tenants": "Tenant",
"tenant": "Tenant",
"user_memberships": "Keanggotaan Pengguna",
"user_membership": "Keanggotaan Pengguna",
"tenant_locations": "Lokasi Tenant",
"tenant_location": "Lokasi Tenant",
"ponds": "Kolam",
"pond": "Kolam",
"species": "Spesies",
"batches": "Batch",
"batch": "Batch",
"feed_products": "Produk Pakan",
"feed_product": "Produk Pakan",
"feeding_logs": "Log Pemberian Pakan",
"feeding_log": "Log Pemberian Pakan",
"water_quality_logs": "Log Kualitas Air",
"water_quality_log": "Log Kualitas Air",
"health_events": "Kejadian Kesehatan",
"health_event": "Kejadian Kesehatan",
"inventory_items": "Item Inventaris",
"inventory_item": "Item Inventaris",
"inventory_movements": "Pergerakan Inventaris",
"inventory_movement": "Pergerakan Inventaris",
"harvests": "Panen",
"harvest": "Panen",
"marketplace_listings": "Listing Marketplace",
"marketplace_listing": "Listing Marketplace",
"orders": "Pesanan",
"order": "Pesanan",
"order_items": "Item Pesanan",
"order_item": "Item Pesanan",
"payment_transactions": "Transaksi Pembayaran",
"payment_transaction": "Transaksi Pembayaran",
"shipment_updates": "Pembaruan Pengiriman",
"shipment_update": "Pembaruan Pengiriman",
"investments": "Investasi",
"investment": "Investasi",
"email_notifications": "Notifikasi Email",
"email_notification": "Notifikasi Email",
"audit_logs": "Log Audit",
"audit_log": "Log Audit",
"api_keys": "Kunci API",
"api_key": "Kunci API",
"webhook_endpoints": "Endpoint Webhook",
"webhook_endpoint": "Endpoint Webhook",
"webhook_deliveries": "Pengiriman Webhook",
"webhook_delivery": "Pengiriman Webhook",
"csv_jobs": "Pekerjaan CSV",
"csv_job": "Pekerjaan CSV"
},
"enums": {
"active": "Aktif",
"inactive": "Tidak aktif",
"maintenance": "Perawatan",
"planned": "Direncanakan",
"harvested": "Dipanen",
"closed": "Ditutup",
"lost": "Hilang",
"manual": "Manual",
"auto_feeder": "Pemberi pakan otomatis",
"broadcast": "Sebar",
"tray": "Tray",
"low": "Rendah",
"normal": "Normal",
"high": "Tinggi",
"pending": "Menunggu",
"confirmed": "Dikonfirmasi",
"packed": "Dikemas",
"shipped": "Dikirim",
"delivered": "Terkirim",
"canceled": "Dibatalkan",
"refunded": "Dikembalikan dana",
"draft": "Draf",
"paused": "Dijeda",
"sold_out": "Habis terjual",
"expired": "Kedaluwarsa",
"removed": "Dihapus",
"earthen": "Tanah",
"lined": "Berlapis",
"tank": "Tangki",
"cage": "Keramba",
"raceway": "Raceway",
"other": "Lainnya"
}
}

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureApi_keysCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleApi_keys = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleApi_keys = ({ filterItems, setFilterItems, filters, showGrid })
`api_keys`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleApi_keys = ({ filterItems, setFilterItems, filters, showGrid })
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleApi_keys = ({ filterItems, setFilterItems, filters, showGrid })
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleApi_keys = ({ filterItems, setFilterItems, filters, showGrid })
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleApi_keys = ({ filterItems, setFilterItems, filters, showGrid })
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleApi_keys = ({ filterItems, setFilterItems, filters, showGrid })
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleApi_keys = ({ filterItems, setFilterItems, filters, showGrid })
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleApi_keys = ({ filterItems, setFilterItems, filters, showGrid })
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleApi_keys = ({ filterItems, setFilterItems, filters, showGrid })
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleApi_keys = ({ filterItems, setFilterItems, filters, showGrid })
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleApi_keys = ({ filterItems, setFilterItems, filters, showGrid })
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'key_name',
headerName: 'KeyName',
headerName: translateCrudLabel('KeyName'),
flex: 1,
minWidth: 120,
filterable: false,
@ -80,7 +81,7 @@ export const loadColumns = async (
{
field: 'key_prefix',
headerName: 'KeyPrefix',
headerName: translateCrudLabel('KeyPrefix'),
flex: 1,
minWidth: 120,
filterable: false,
@ -95,7 +96,7 @@ export const loadColumns = async (
{
field: 'access_level',
headerName: 'AccessLevel',
headerName: translateCrudLabel('AccessLevel'),
flex: 1,
minWidth: 120,
filterable: false,
@ -110,7 +111,7 @@ export const loadColumns = async (
{
field: 'last_used_at',
headerName: 'LastUsedAt',
headerName: translateCrudLabel('LastUsedAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -128,7 +129,7 @@ export const loadColumns = async (
{
field: 'expires_at',
headerName: 'ExpiresAt',
headerName: translateCrudLabel('ExpiresAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -146,7 +147,7 @@ export const loadColumns = async (
{
field: 'is_revoked',
headerName: 'IsRevoked',
headerName: translateCrudLabel('IsRevoked'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -7,6 +7,8 @@ import AsideMenuList from './AsideMenuList'
import { MenuAsideItem } from '../interfaces'
import { useAppSelector } from '../stores/hooks'
import { useRouter } from 'next/router'
import { useTranslation } from 'react-i18next'
import { translateCrudLabel } from '../helpers/translateCrudLabel'
type Props = {
item: MenuAsideItem
@ -14,6 +16,7 @@ type Props = {
}
const AsideMenuItem = ({ item, isDropdownList = false }: Props) => {
const { t } = useTranslation('common')
const [isLinkActive, setIsLinkActive] = useState(false)
const [isDropdownActive, setIsDropdownActive] = useState(false)
@ -50,7 +53,7 @@ const AsideMenuItem = ({ item, isDropdownList = false }: Props) => {
item.menu ? '' : 'pr-12'
} ${activeClassAddon}`}
>
{item.label}
{translateCrudLabel(item.label, t)}
</span>
{item.menu && (
<BaseIcon

View File

@ -8,6 +8,7 @@ import Link from 'next/link';
import { createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
import { useTranslation } from 'react-i18next';
type Props = {
@ -17,6 +18,7 @@ type Props = {
}
export default function AsideMenuLayer({ menu, className = '', ...props }: Props) {
const { t } = useTranslation('common');
const corners = useAppSelector((state) => state.style.corners);
const asideStyle = useAppSelector((state) => state.style.asideStyle)
const asideBrandStyle = useAppSelector((state) => state.style.asideBrandStyle)
@ -67,7 +69,7 @@ export default function AsideMenuLayer({ menu, className = '', ...props }: Props
>
<div className="text-center flex-1 lg:text-left lg:pl-6 xl:text-center xl:pl-0">
<b className="font-black">Aquaculture Ops CRUD</b>
<b className="font-black">{t('app.title')}</b>
{organizationName && <p>{organizationName}</p>}

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureAudit_logsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleAudit_logs = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleAudit_logs = ({ filterItems, setFilterItems, filters, showGrid
`audit_logs`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleAudit_logs = ({ filterItems, setFilterItems, filters, showGrid
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleAudit_logs = ({ filterItems, setFilterItems, filters, showGrid
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleAudit_logs = ({ filterItems, setFilterItems, filters, showGrid
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleAudit_logs = ({ filterItems, setFilterItems, filters, showGrid
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleAudit_logs = ({ filterItems, setFilterItems, filters, showGrid
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleAudit_logs = ({ filterItems, setFilterItems, filters, showGrid
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleAudit_logs = ({ filterItems, setFilterItems, filters, showGrid
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleAudit_logs = ({ filterItems, setFilterItems, filters, showGrid
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleAudit_logs = ({ filterItems, setFilterItems, filters, showGrid
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleAudit_logs = ({ filterItems, setFilterItems, filters, showGrid
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'actor_user',
headerName: 'ActorUser',
headerName: translateCrudLabel('ActorUser'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'action',
headerName: 'Action',
headerName: translateCrudLabel('Action'),
flex: 1,
minWidth: 120,
filterable: false,
@ -102,7 +103,7 @@ export const loadColumns = async (
{
field: 'entity_name',
headerName: 'EntityName',
headerName: translateCrudLabel('EntityName'),
flex: 1,
minWidth: 120,
filterable: false,
@ -117,7 +118,7 @@ export const loadColumns = async (
{
field: 'entity_reference',
headerName: 'EntityReference',
headerName: translateCrudLabel('EntityReference'),
flex: 1,
minWidth: 120,
filterable: false,
@ -132,7 +133,7 @@ export const loadColumns = async (
{
field: 'occurred_at',
headerName: 'OccurredAt',
headerName: translateCrudLabel('OccurredAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -150,7 +151,7 @@ export const loadColumns = async (
{
field: 'ip_address',
headerName: 'IPAddress',
headerName: translateCrudLabel('IPAddress'),
flex: 1,
minWidth: 120,
filterable: false,
@ -165,7 +166,7 @@ export const loadColumns = async (
{
field: 'user_agent',
headerName: 'UserAgent',
headerName: translateCrudLabel('UserAgent'),
flex: 1,
minWidth: 120,
filterable: false,
@ -180,7 +181,7 @@ export const loadColumns = async (
{
field: 'change_summary',
headerName: 'ChangeSummary',
headerName: translateCrudLabel('ChangeSummary'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -4,6 +4,8 @@ import { getButtonColor } from '../colors'
import BaseIcon from './BaseIcon'
import type { ColorButtonKey } from '../interfaces'
import { useAppSelector } from '../stores/hooks';
import { useTranslation } from 'react-i18next';
import { translateCrudLabel } from '../helpers/translateCrudLabel';
type Props = {
label?: string
@ -42,7 +44,9 @@ export default function BaseButton({
roundedFull = false,
onClick,
}: Props) {
const { t } = useTranslation('common');
const corners = useAppSelector((state) => state.style.corners);
const translatedLabel = label ? translateCrudLabel(label, t) : '';
const componentClass = [
'inline-flex',
'justify-center',
@ -76,7 +80,7 @@ export default function BaseButton({
const componentChildren = (
<>
{icon && <BaseIcon path={icon} size={iconSize} className={iconClassName} />}
{label && <span className={small && icon ? 'px-1' : 'px-2'}>{label}</span>}
{label && <span className={small && icon ? 'px-1' : 'px-2'}>{translatedLabel}</span>}
</>
)

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -20,11 +21,13 @@ import {dataGridStyles} from "../../styles";
import KanbanBoard from '../KanbanBoard/KanbanBoard';
import axios from 'axios';
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleBatches = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -213,7 +216,7 @@ const TableSampleBatches = ({ filterItems, setFilterItems, filters, showGrid })
`batches`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -310,7 +313,7 @@ const TableSampleBatches = ({ filterItems, setFilterItems, filters, showGrid })
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -324,7 +327,7 @@ const TableSampleBatches = ({ filterItems, setFilterItems, filters, showGrid })
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -334,7 +337,7 @@ const TableSampleBatches = ({ filterItems, setFilterItems, filters, showGrid })
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -344,12 +347,12 @@ const TableSampleBatches = ({ filterItems, setFilterItems, filters, showGrid })
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -359,22 +362,22 @@ const TableSampleBatches = ({ filterItems, setFilterItems, filters, showGrid })
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -389,12 +392,12 @@ const TableSampleBatches = ({ filterItems, setFilterItems, filters, showGrid })
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -402,11 +405,11 @@ const TableSampleBatches = ({ filterItems, setFilterItems, filters, showGrid })
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -416,11 +419,11 @@ const TableSampleBatches = ({ filterItems, setFilterItems, filters, showGrid })
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -428,7 +431,7 @@ const TableSampleBatches = ({ filterItems, setFilterItems, filters, showGrid })
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -469,7 +472,7 @@ const TableSampleBatches = ({ filterItems, setFilterItems, filters, showGrid })
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'pond',
headerName: 'Pond',
headerName: translateCrudLabel('Pond'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'species',
headerName: 'Species',
headerName: translateCrudLabel('Species'),
flex: 1,
minWidth: 120,
filterable: false,
@ -109,7 +110,7 @@ export const loadColumns = async (
{
field: 'batch_code',
headerName: 'BatchCode',
headerName: translateCrudLabel('BatchCode'),
flex: 1,
minWidth: 120,
filterable: false,
@ -124,7 +125,7 @@ export const loadColumns = async (
{
field: 'stocked_at',
headerName: 'StockedAt',
headerName: translateCrudLabel('StockedAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -142,7 +143,7 @@ export const loadColumns = async (
{
field: 'initial_count',
headerName: 'InitialCount',
headerName: translateCrudLabel('InitialCount'),
flex: 1,
minWidth: 120,
filterable: false,
@ -158,7 +159,7 @@ export const loadColumns = async (
{
field: 'initial_avg_weight_g',
headerName: 'InitialAverageWeightG',
headerName: translateCrudLabel('InitialAverageWeightG'),
flex: 1,
minWidth: 120,
filterable: false,
@ -174,7 +175,7 @@ export const loadColumns = async (
{
field: 'batch_status',
headerName: 'BatchStatus',
headerName: translateCrudLabel('BatchStatus'),
flex: 1,
minWidth: 120,
filterable: false,
@ -189,7 +190,7 @@ export const loadColumns = async (
{
field: 'expected_harvest_at',
headerName: 'ExpectedHarvestAt',
headerName: translateCrudLabel('ExpectedHarvestAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -207,7 +208,7 @@ export const loadColumns = async (
{
field: 'notes',
headerName: 'Notes',
headerName: translateCrudLabel('Notes'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,6 @@
import React, { ReactNode } from 'react'
import { useTranslation } from 'react-i18next'
import { translateCrudLabel } from '../helpers/translateCrudLabel'
type Props = {
title: string
@ -6,9 +8,11 @@ type Props = {
}
const CardBoxComponentTitle = ({ title, children }: Props) => {
const { t } = useTranslation('common')
return (
<div className="flex items-center justify-center mb-3">
<h1 className="text-2xl">{title}</h1>
<h1 className="text-2xl">{translateCrudLabel(title, t)}</h1>
{children}
</div>
)

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -20,11 +21,13 @@ import {dataGridStyles} from "../../styles";
import KanbanBoard from '../KanbanBoard/KanbanBoard';
import axios from 'axios';
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleCsv_jobs = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -211,7 +214,7 @@ const TableSampleCsv_jobs = ({ filterItems, setFilterItems, filters, showGrid })
`csv_jobs`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -308,7 +311,7 @@ const TableSampleCsv_jobs = ({ filterItems, setFilterItems, filters, showGrid })
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -322,7 +325,7 @@ const TableSampleCsv_jobs = ({ filterItems, setFilterItems, filters, showGrid })
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -332,7 +335,7 @@ const TableSampleCsv_jobs = ({ filterItems, setFilterItems, filters, showGrid })
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -342,12 +345,12 @@ const TableSampleCsv_jobs = ({ filterItems, setFilterItems, filters, showGrid })
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -357,22 +360,22 @@ const TableSampleCsv_jobs = ({ filterItems, setFilterItems, filters, showGrid })
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -387,12 +390,12 @@ const TableSampleCsv_jobs = ({ filterItems, setFilterItems, filters, showGrid })
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -400,11 +403,11 @@ const TableSampleCsv_jobs = ({ filterItems, setFilterItems, filters, showGrid })
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -414,11 +417,11 @@ const TableSampleCsv_jobs = ({ filterItems, setFilterItems, filters, showGrid })
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -426,7 +429,7 @@ const TableSampleCsv_jobs = ({ filterItems, setFilterItems, filters, showGrid })
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -467,7 +470,7 @@ const TableSampleCsv_jobs = ({ filterItems, setFilterItems, filters, showGrid })
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'job_type',
headerName: 'JobType',
headerName: translateCrudLabel('JobType'),
flex: 1,
minWidth: 120,
filterable: false,
@ -80,7 +81,7 @@ export const loadColumns = async (
{
field: 'entity_name',
headerName: 'EntityName',
headerName: translateCrudLabel('EntityName'),
flex: 1,
minWidth: 120,
filterable: false,
@ -95,7 +96,7 @@ export const loadColumns = async (
{
field: 'job_status',
headerName: 'JobStatus',
headerName: translateCrudLabel('JobStatus'),
flex: 1,
minWidth: 120,
filterable: false,
@ -110,7 +111,7 @@ export const loadColumns = async (
{
field: 'source_file',
headerName: 'SourceFile',
headerName: translateCrudLabel('SourceFile'),
flex: 1,
minWidth: 120,
filterable: false,
@ -136,7 +137,7 @@ export const loadColumns = async (
{
field: 'result_file',
headerName: 'ResultFile',
headerName: translateCrudLabel('ResultFile'),
flex: 1,
minWidth: 120,
filterable: false,
@ -162,7 +163,7 @@ export const loadColumns = async (
{
field: 'total_rows',
headerName: 'TotalRows',
headerName: translateCrudLabel('TotalRows'),
flex: 1,
minWidth: 120,
filterable: false,
@ -178,7 +179,7 @@ export const loadColumns = async (
{
field: 'processed_rows',
headerName: 'ProcessedRows',
headerName: translateCrudLabel('ProcessedRows'),
flex: 1,
minWidth: 120,
filterable: false,
@ -194,7 +195,7 @@ export const loadColumns = async (
{
field: 'error_rows',
headerName: 'ErrorRows',
headerName: translateCrudLabel('ErrorRows'),
flex: 1,
minWidth: 120,
filterable: false,
@ -210,7 +211,7 @@ export const loadColumns = async (
{
field: 'error_report',
headerName: 'ErrorReport',
headerName: translateCrudLabel('ErrorReport'),
flex: 1,
minWidth: 120,
filterable: false,
@ -225,7 +226,7 @@ export const loadColumns = async (
{
field: 'requested_by',
headerName: 'RequestedBy',
headerName: translateCrudLabel('RequestedBy'),
flex: 1,
minWidth: 120,
filterable: false,
@ -247,7 +248,7 @@ export const loadColumns = async (
{
field: 'started_at',
headerName: 'StartedAt',
headerName: translateCrudLabel('StartedAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -265,7 +266,7 @@ export const loadColumns = async (
{
field: 'finished_at',
headerName: 'FinishedAt',
headerName: translateCrudLabel('FinishedAt'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,6 +1,7 @@
import React, { ChangeEvent, useEffect, useState } from 'react';
import BaseIcon from './BaseIcon';
import { mdiFileUploadOutline } from '@mdi/js';
import { useTranslation } from 'react-i18next';
type Props = {
file: File | null;
@ -9,6 +10,7 @@ type Props = {
};
const DragDropFilePicker = ({ file, setFile, formats = '' }: Props) => {
const { t } = useTranslation('common');
const [highlight, setHighlight] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
const fileInput = React.createRef<HTMLInputElement>();
@ -26,7 +28,7 @@ const DragDropFilePicker = ({ file, setFile, formats = '' }: Props) => {
setFile(newFile);
setErrorMessage('');
} else {
setErrorMessage(`Allowed formats: ${formats}`);
setErrorMessage(t('labels.allowed_formats', { formats }));
}
}
}
@ -97,8 +99,7 @@ const DragDropFilePicker = ({ file, setFile, formats = '' }: Props) => {
) : (
<>
<p className='mb-2 text-sm text-gray-500 dark:text-gray-400'>
<span className='font-semibold'>Click to upload</span> or drag
and drop
<span className='font-semibold'>{t('labels.click_to_upload')}</span> {t('labels.or_drag_and_drop')}
</p>
{formats && (
<p className='text-xs text-gray-500 dark:text-gray-400'>

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureEmail_notificationsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleEmail_notifications = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleEmail_notifications = ({ filterItems, setFilterItems, filters,
`email_notifications`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleEmail_notifications = ({ filterItems, setFilterItems, filters,
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleEmail_notifications = ({ filterItems, setFilterItems, filters,
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleEmail_notifications = ({ filterItems, setFilterItems, filters,
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleEmail_notifications = ({ filterItems, setFilterItems, filters,
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleEmail_notifications = ({ filterItems, setFilterItems, filters,
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleEmail_notifications = ({ filterItems, setFilterItems, filters,
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleEmail_notifications = ({ filterItems, setFilterItems, filters,
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleEmail_notifications = ({ filterItems, setFilterItems, filters,
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleEmail_notifications = ({ filterItems, setFilterItems, filters,
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleEmail_notifications = ({ filterItems, setFilterItems, filters,
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'recipient_user',
headerName: 'RecipientUser',
headerName: translateCrudLabel('RecipientUser'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'to_email',
headerName: 'ToEmail',
headerName: translateCrudLabel('ToEmail'),
flex: 1,
minWidth: 120,
filterable: false,
@ -102,7 +103,7 @@ export const loadColumns = async (
{
field: 'subject',
headerName: 'Subject',
headerName: translateCrudLabel('Subject'),
flex: 1,
minWidth: 120,
filterable: false,
@ -117,7 +118,7 @@ export const loadColumns = async (
{
field: 'template_key',
headerName: 'TemplateKey',
headerName: translateCrudLabel('TemplateKey'),
flex: 1,
minWidth: 120,
filterable: false,
@ -132,7 +133,7 @@ export const loadColumns = async (
{
field: 'payload',
headerName: 'Payload',
headerName: translateCrudLabel('Payload'),
flex: 1,
minWidth: 120,
filterable: false,
@ -147,7 +148,7 @@ export const loadColumns = async (
{
field: 'send_status',
headerName: 'SendStatus',
headerName: translateCrudLabel('SendStatus'),
flex: 1,
minWidth: 120,
filterable: false,
@ -162,7 +163,7 @@ export const loadColumns = async (
{
field: 'sent_at',
headerName: 'SentAt',
headerName: translateCrudLabel('SentAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -180,7 +181,7 @@ export const loadColumns = async (
{
field: 'failure_reason',
headerName: 'FailureReason',
headerName: translateCrudLabel('FailureReason'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureFeed_productsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleFeed_products = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleFeed_products = ({ filterItems, setFilterItems, filters, showGr
`feed_products`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleFeed_products = ({ filterItems, setFilterItems, filters, showGr
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleFeed_products = ({ filterItems, setFilterItems, filters, showGr
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleFeed_products = ({ filterItems, setFilterItems, filters, showGr
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleFeed_products = ({ filterItems, setFilterItems, filters, showGr
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleFeed_products = ({ filterItems, setFilterItems, filters, showGr
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleFeed_products = ({ filterItems, setFilterItems, filters, showGr
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleFeed_products = ({ filterItems, setFilterItems, filters, showGr
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleFeed_products = ({ filterItems, setFilterItems, filters, showGr
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleFeed_products = ({ filterItems, setFilterItems, filters, showGr
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleFeed_products = ({ filterItems, setFilterItems, filters, showGr
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'product_name',
headerName: 'ProductName',
headerName: translateCrudLabel('ProductName'),
flex: 1,
minWidth: 120,
filterable: false,
@ -80,7 +81,7 @@ export const loadColumns = async (
{
field: 'brand',
headerName: 'Brand',
headerName: translateCrudLabel('Brand'),
flex: 1,
minWidth: 120,
filterable: false,
@ -95,7 +96,7 @@ export const loadColumns = async (
{
field: 'feed_type',
headerName: 'FeedType',
headerName: translateCrudLabel('FeedType'),
flex: 1,
minWidth: 120,
filterable: false,
@ -110,7 +111,7 @@ export const loadColumns = async (
{
field: 'protein_percent',
headerName: 'ProteinPercent',
headerName: translateCrudLabel('ProteinPercent'),
flex: 1,
minWidth: 120,
filterable: false,
@ -126,7 +127,7 @@ export const loadColumns = async (
{
field: 'fat_percent',
headerName: 'FatPercent',
headerName: translateCrudLabel('FatPercent'),
flex: 1,
minWidth: 120,
filterable: false,
@ -142,7 +143,7 @@ export const loadColumns = async (
{
field: 'pellet_size_mm',
headerName: 'PelletSizeMm',
headerName: translateCrudLabel('PelletSizeMm'),
flex: 1,
minWidth: 120,
filterable: false,
@ -158,7 +159,7 @@ export const loadColumns = async (
{
field: 'notes',
headerName: 'Notes',
headerName: translateCrudLabel('Notes'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,6 +17,7 @@ import {loadColumns} from "./configureFeeding_logsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
import BigCalendar from "../BigCalendar";
@ -25,6 +27,7 @@ import { SlotInfo } from 'react-big-calendar';
const perPage = 100
const TableSampleFeeding_logs = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -183,7 +186,7 @@ const TableSampleFeeding_logs = ({ filterItems, setFilterItems, filters, showGri
`feeding_logs`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -280,7 +283,7 @@ const TableSampleFeeding_logs = ({ filterItems, setFilterItems, filters, showGri
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -294,7 +297,7 @@ const TableSampleFeeding_logs = ({ filterItems, setFilterItems, filters, showGri
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -304,7 +307,7 @@ const TableSampleFeeding_logs = ({ filterItems, setFilterItems, filters, showGri
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -314,12 +317,12 @@ const TableSampleFeeding_logs = ({ filterItems, setFilterItems, filters, showGri
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -329,22 +332,22 @@ const TableSampleFeeding_logs = ({ filterItems, setFilterItems, filters, showGri
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -359,12 +362,12 @@ const TableSampleFeeding_logs = ({ filterItems, setFilterItems, filters, showGri
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -372,11 +375,11 @@ const TableSampleFeeding_logs = ({ filterItems, setFilterItems, filters, showGri
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -386,11 +389,11 @@ const TableSampleFeeding_logs = ({ filterItems, setFilterItems, filters, showGri
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -398,7 +401,7 @@ const TableSampleFeeding_logs = ({ filterItems, setFilterItems, filters, showGri
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -439,7 +442,7 @@ const TableSampleFeeding_logs = ({ filterItems, setFilterItems, filters, showGri
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'batch',
headerName: 'Batch',
headerName: translateCrudLabel('Batch'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'feed_product',
headerName: 'FeedProduct',
headerName: translateCrudLabel('FeedProduct'),
flex: 1,
minWidth: 120,
filterable: false,
@ -109,7 +110,7 @@ export const loadColumns = async (
{
field: 'fed_at',
headerName: 'FedAt',
headerName: translateCrudLabel('FedAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -127,7 +128,7 @@ export const loadColumns = async (
{
field: 'quantity_kg',
headerName: 'QuantityKg',
headerName: translateCrudLabel('QuantityKg'),
flex: 1,
minWidth: 120,
filterable: false,
@ -143,7 +144,7 @@ export const loadColumns = async (
{
field: 'feeding_method',
headerName: 'FeedingMethod',
headerName: translateCrudLabel('FeedingMethod'),
flex: 1,
minWidth: 120,
filterable: false,
@ -158,7 +159,7 @@ export const loadColumns = async (
{
field: 'appetite',
headerName: 'Appetite',
headerName: translateCrudLabel('Appetite'),
flex: 1,
minWidth: 120,
filterable: false,
@ -173,7 +174,7 @@ export const loadColumns = async (
{
field: 'notes',
headerName: 'Notes',
headerName: translateCrudLabel('Notes'),
flex: 1,
minWidth: 120,
filterable: false,
@ -188,7 +189,7 @@ export const loadColumns = async (
{
field: 'recorded_by',
headerName: 'RecordedBy',
headerName: translateCrudLabel('RecordedBy'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,6 @@
import { ReactNode } from 'react'
import { useTranslation } from 'react-i18next'
import { translateCrudLabel } from '../helpers/translateCrudLabel'
type Props = {
children: ReactNode
@ -8,11 +10,13 @@ type Props = {
}
const FormCheckRadio = (props: Props) => {
const { t } = useTranslation('common')
return (
<label className={`${props.type} ${props.className}`}>
{props.children}
<span className="check" />
<span className="pl-2">{props.label}</span>
<span className="pl-2">{translateCrudLabel(props.label, t)}</span>
</label>
)
}

View File

@ -1,6 +1,8 @@
import { Children, cloneElement, ReactElement, ReactNode } from 'react'
import BaseIcon from './BaseIcon'
import { useAppSelector } from '../stores/hooks';
import { useTranslation } from 'react-i18next';
import { translateCrudLabel } from '../helpers/translateCrudLabel';
type Props = {
label?: string
@ -18,6 +20,7 @@ type Props = {
}
const FormField = ({ icons = [], ...props }: Props) => {
const { t } = useTranslation('common')
const childrenCount = Children.count(props.children)
const bgColor = useAppSelector((state) => state.style.cardsColor);
const focusRing = useAppSelector((state) => state.style.focusRingColor);
@ -50,7 +53,7 @@ const FormField = ({ icons = [], ...props }: Props) => {
htmlFor={props.labelFor}
className={`block font-bold mb-2 ${props.labelFor ? 'cursor-pointer' : ''}`}
>
{props.label}
{translateCrudLabel(props.label, t)}
</label>
)}
<div className={`${elementWrapperClass}`}>
@ -71,7 +74,7 @@ const FormField = ({ icons = [], ...props }: Props) => {
))}
</div>
{props.help && (
<div className='text-xs text-gray-500 dark:text-dark-600 mt-1'>{props.help}</div>
<div className='text-xs text-gray-500 dark:text-dark-600 mt-1'>{translateCrudLabel(props.help, t)}</div>
)}
</div>
)

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureHarvestsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleHarvests = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleHarvests = ({ filterItems, setFilterItems, filters, showGrid })
`harvests`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleHarvests = ({ filterItems, setFilterItems, filters, showGrid })
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleHarvests = ({ filterItems, setFilterItems, filters, showGrid })
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleHarvests = ({ filterItems, setFilterItems, filters, showGrid })
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleHarvests = ({ filterItems, setFilterItems, filters, showGrid })
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleHarvests = ({ filterItems, setFilterItems, filters, showGrid })
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleHarvests = ({ filterItems, setFilterItems, filters, showGrid })
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleHarvests = ({ filterItems, setFilterItems, filters, showGrid })
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleHarvests = ({ filterItems, setFilterItems, filters, showGrid })
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleHarvests = ({ filterItems, setFilterItems, filters, showGrid })
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleHarvests = ({ filterItems, setFilterItems, filters, showGrid })
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'batch',
headerName: 'Batch',
headerName: translateCrudLabel('Batch'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'harvested_at',
headerName: 'HarvestedAt',
headerName: translateCrudLabel('HarvestedAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -105,7 +106,7 @@ export const loadColumns = async (
{
field: 'total_weight_kg',
headerName: 'TotalWeightKg',
headerName: translateCrudLabel('TotalWeightKg'),
flex: 1,
minWidth: 120,
filterable: false,
@ -121,7 +122,7 @@ export const loadColumns = async (
{
field: 'total_count',
headerName: 'TotalCount',
headerName: translateCrudLabel('TotalCount'),
flex: 1,
minWidth: 120,
filterable: false,
@ -137,7 +138,7 @@ export const loadColumns = async (
{
field: 'avg_weight_g',
headerName: 'AverageWeightG',
headerName: translateCrudLabel('AverageWeightG'),
flex: 1,
minWidth: 120,
filterable: false,
@ -153,7 +154,7 @@ export const loadColumns = async (
{
field: 'grade',
headerName: 'Grade',
headerName: translateCrudLabel('Grade'),
flex: 1,
minWidth: 120,
filterable: false,
@ -168,7 +169,7 @@ export const loadColumns = async (
{
field: 'notes',
headerName: 'Notes',
headerName: translateCrudLabel('Notes'),
flex: 1,
minWidth: 120,
filterable: false,
@ -183,7 +184,7 @@ export const loadColumns = async (
{
field: 'recorded_by',
headerName: 'RecordedBy',
headerName: translateCrudLabel('RecordedBy'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -20,11 +21,13 @@ import {dataGridStyles} from "../../styles";
import KanbanBoard from '../KanbanBoard/KanbanBoard';
import axios from 'axios';
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleHealth_events = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -211,7 +214,7 @@ const TableSampleHealth_events = ({ filterItems, setFilterItems, filters, showGr
`health_events`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -308,7 +311,7 @@ const TableSampleHealth_events = ({ filterItems, setFilterItems, filters, showGr
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -322,7 +325,7 @@ const TableSampleHealth_events = ({ filterItems, setFilterItems, filters, showGr
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -332,7 +335,7 @@ const TableSampleHealth_events = ({ filterItems, setFilterItems, filters, showGr
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -342,12 +345,12 @@ const TableSampleHealth_events = ({ filterItems, setFilterItems, filters, showGr
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -357,22 +360,22 @@ const TableSampleHealth_events = ({ filterItems, setFilterItems, filters, showGr
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -387,12 +390,12 @@ const TableSampleHealth_events = ({ filterItems, setFilterItems, filters, showGr
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -400,11 +403,11 @@ const TableSampleHealth_events = ({ filterItems, setFilterItems, filters, showGr
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -414,11 +417,11 @@ const TableSampleHealth_events = ({ filterItems, setFilterItems, filters, showGr
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -426,7 +429,7 @@ const TableSampleHealth_events = ({ filterItems, setFilterItems, filters, showGr
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -467,7 +470,7 @@ const TableSampleHealth_events = ({ filterItems, setFilterItems, filters, showGr
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'batch',
headerName: 'Batch',
headerName: translateCrudLabel('Batch'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'observed_at',
headerName: 'ObservedAt',
headerName: translateCrudLabel('ObservedAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -105,7 +106,7 @@ export const loadColumns = async (
{
field: 'event_type',
headerName: 'EventType',
headerName: translateCrudLabel('EventType'),
flex: 1,
minWidth: 120,
filterable: false,
@ -120,7 +121,7 @@ export const loadColumns = async (
{
field: 'severity',
headerName: 'Severity',
headerName: translateCrudLabel('Severity'),
flex: 1,
minWidth: 120,
filterable: false,
@ -135,7 +136,7 @@ export const loadColumns = async (
{
field: 'mortality_count',
headerName: 'MortalityCount',
headerName: translateCrudLabel('MortalityCount'),
flex: 1,
minWidth: 120,
filterable: false,
@ -151,7 +152,7 @@ export const loadColumns = async (
{
field: 'symptoms',
headerName: 'Symptoms',
headerName: translateCrudLabel('Symptoms'),
flex: 1,
minWidth: 120,
filterable: false,
@ -166,7 +167,7 @@ export const loadColumns = async (
{
field: 'treatment',
headerName: 'Treatment',
headerName: translateCrudLabel('Treatment'),
flex: 1,
minWidth: 120,
filterable: false,
@ -181,7 +182,7 @@ export const loadColumns = async (
{
field: 'attachments',
headerName: 'Attachments',
headerName: translateCrudLabel('Attachments'),
flex: 1,
minWidth: 120,
filterable: false,
@ -207,7 +208,7 @@ export const loadColumns = async (
{
field: 'reported_by',
headerName: 'ReportedBy',
headerName: translateCrudLabel('ReportedBy'),
flex: 1,
minWidth: 120,
filterable: false,
@ -229,7 +230,7 @@ export const loadColumns = async (
{
field: 'resolution_status',
headerName: 'ResolutionStatus',
headerName: translateCrudLabel('ResolutionStatus'),
flex: 1,
minWidth: 120,
filterable: false,
@ -244,7 +245,7 @@ export const loadColumns = async (
{
field: 'resolved_at',
headerName: 'ResolvedAt',
headerName: translateCrudLabel('ResolvedAt'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureInventory_itemsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleInventory_items = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleInventory_items = ({ filterItems, setFilterItems, filters, show
`inventory_items`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleInventory_items = ({ filterItems, setFilterItems, filters, show
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleInventory_items = ({ filterItems, setFilterItems, filters, show
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleInventory_items = ({ filterItems, setFilterItems, filters, show
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleInventory_items = ({ filterItems, setFilterItems, filters, show
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleInventory_items = ({ filterItems, setFilterItems, filters, show
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleInventory_items = ({ filterItems, setFilterItems, filters, show
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleInventory_items = ({ filterItems, setFilterItems, filters, show
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleInventory_items = ({ filterItems, setFilterItems, filters, show
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleInventory_items = ({ filterItems, setFilterItems, filters, show
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleInventory_items = ({ filterItems, setFilterItems, filters, show
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'location',
headerName: 'Location',
headerName: translateCrudLabel('Location'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'item_category',
headerName: 'ItemCategory',
headerName: translateCrudLabel('ItemCategory'),
flex: 1,
minWidth: 120,
filterable: false,
@ -102,7 +103,7 @@ export const loadColumns = async (
{
field: 'item_name',
headerName: 'ItemName',
headerName: translateCrudLabel('ItemName'),
flex: 1,
minWidth: 120,
filterable: false,
@ -117,7 +118,7 @@ export const loadColumns = async (
{
field: 'sku',
headerName: 'SKU',
headerName: translateCrudLabel('SKU'),
flex: 1,
minWidth: 120,
filterable: false,
@ -132,7 +133,7 @@ export const loadColumns = async (
{
field: 'unit',
headerName: 'Unit',
headerName: translateCrudLabel('Unit'),
flex: 1,
minWidth: 120,
filterable: false,
@ -147,7 +148,7 @@ export const loadColumns = async (
{
field: 'quantity_on_hand',
headerName: 'QuantityOnHand',
headerName: translateCrudLabel('QuantityOnHand'),
flex: 1,
minWidth: 120,
filterable: false,
@ -163,7 +164,7 @@ export const loadColumns = async (
{
field: 'reorder_level',
headerName: 'ReorderLevel',
headerName: translateCrudLabel('ReorderLevel'),
flex: 1,
minWidth: 120,
filterable: false,
@ -179,7 +180,7 @@ export const loadColumns = async (
{
field: 'unit_cost',
headerName: 'UnitCost',
headerName: translateCrudLabel('UnitCost'),
flex: 1,
minWidth: 120,
filterable: false,
@ -195,7 +196,7 @@ export const loadColumns = async (
{
field: 'feed_product',
headerName: 'FeedProduct',
headerName: translateCrudLabel('FeedProduct'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureInventory_movementsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleInventory_movements = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleInventory_movements = ({ filterItems, setFilterItems, filters,
`inventory_movements`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleInventory_movements = ({ filterItems, setFilterItems, filters,
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleInventory_movements = ({ filterItems, setFilterItems, filters,
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleInventory_movements = ({ filterItems, setFilterItems, filters,
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleInventory_movements = ({ filterItems, setFilterItems, filters,
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleInventory_movements = ({ filterItems, setFilterItems, filters,
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleInventory_movements = ({ filterItems, setFilterItems, filters,
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleInventory_movements = ({ filterItems, setFilterItems, filters,
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleInventory_movements = ({ filterItems, setFilterItems, filters,
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleInventory_movements = ({ filterItems, setFilterItems, filters,
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleInventory_movements = ({ filterItems, setFilterItems, filters,
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'inventory_item',
headerName: 'InventoryItem',
headerName: translateCrudLabel('InventoryItem'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'movement_type',
headerName: 'MovementType',
headerName: translateCrudLabel('MovementType'),
flex: 1,
minWidth: 120,
filterable: false,
@ -102,7 +103,7 @@ export const loadColumns = async (
{
field: 'quantity',
headerName: 'Quantity',
headerName: translateCrudLabel('Quantity'),
flex: 1,
minWidth: 120,
filterable: false,
@ -118,7 +119,7 @@ export const loadColumns = async (
{
field: 'moved_at',
headerName: 'MovedAt',
headerName: translateCrudLabel('MovedAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -136,7 +137,7 @@ export const loadColumns = async (
{
field: 'batch',
headerName: 'Batch',
headerName: translateCrudLabel('Batch'),
flex: 1,
minWidth: 120,
filterable: false,
@ -158,7 +159,7 @@ export const loadColumns = async (
{
field: 'reference',
headerName: 'Reference',
headerName: translateCrudLabel('Reference'),
flex: 1,
minWidth: 120,
filterable: false,
@ -173,7 +174,7 @@ export const loadColumns = async (
{
field: 'notes',
headerName: 'Notes',
headerName: translateCrudLabel('Notes'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -20,11 +21,13 @@ import {dataGridStyles} from "../../styles";
import KanbanBoard from '../KanbanBoard/KanbanBoard';
import axios from 'axios';
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleInvestments = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -211,7 +214,7 @@ const TableSampleInvestments = ({ filterItems, setFilterItems, filters, showGrid
`investments`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -308,7 +311,7 @@ const TableSampleInvestments = ({ filterItems, setFilterItems, filters, showGrid
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -322,7 +325,7 @@ const TableSampleInvestments = ({ filterItems, setFilterItems, filters, showGrid
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -332,7 +335,7 @@ const TableSampleInvestments = ({ filterItems, setFilterItems, filters, showGrid
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -342,12 +345,12 @@ const TableSampleInvestments = ({ filterItems, setFilterItems, filters, showGrid
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -357,22 +360,22 @@ const TableSampleInvestments = ({ filterItems, setFilterItems, filters, showGrid
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -387,12 +390,12 @@ const TableSampleInvestments = ({ filterItems, setFilterItems, filters, showGrid
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -400,11 +403,11 @@ const TableSampleInvestments = ({ filterItems, setFilterItems, filters, showGrid
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -414,11 +417,11 @@ const TableSampleInvestments = ({ filterItems, setFilterItems, filters, showGrid
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -426,7 +429,7 @@ const TableSampleInvestments = ({ filterItems, setFilterItems, filters, showGrid
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -467,7 +470,7 @@ const TableSampleInvestments = ({ filterItems, setFilterItems, filters, showGrid
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'investor_tenant',
headerName: 'InvestorTenant',
headerName: translateCrudLabel('InvestorTenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'farm_tenant',
headerName: 'FarmTenant',
headerName: translateCrudLabel('FarmTenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'investment_name',
headerName: 'InvestmentName',
headerName: translateCrudLabel('InvestmentName'),
flex: 1,
minWidth: 120,
filterable: false,
@ -102,7 +103,7 @@ export const loadColumns = async (
{
field: 'instrument_type',
headerName: 'InstrumentType',
headerName: translateCrudLabel('InstrumentType'),
flex: 1,
minWidth: 120,
filterable: false,
@ -117,7 +118,7 @@ export const loadColumns = async (
{
field: 'amount_committed',
headerName: 'AmountCommitted',
headerName: translateCrudLabel('AmountCommitted'),
flex: 1,
minWidth: 120,
filterable: false,
@ -133,7 +134,7 @@ export const loadColumns = async (
{
field: 'amount_funded',
headerName: 'AmountFunded',
headerName: translateCrudLabel('AmountFunded'),
flex: 1,
minWidth: 120,
filterable: false,
@ -149,7 +150,7 @@ export const loadColumns = async (
{
field: 'currency',
headerName: 'Currency',
headerName: translateCrudLabel('Currency'),
flex: 1,
minWidth: 120,
filterable: false,
@ -164,7 +165,7 @@ export const loadColumns = async (
{
field: 'committed_at',
headerName: 'CommittedAt',
headerName: translateCrudLabel('CommittedAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -182,7 +183,7 @@ export const loadColumns = async (
{
field: 'funded_at',
headerName: 'FundedAt',
headerName: translateCrudLabel('FundedAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -200,7 +201,7 @@ export const loadColumns = async (
{
field: 'investment_status',
headerName: 'InvestmentStatus',
headerName: translateCrudLabel('InvestmentStatus'),
flex: 1,
minWidth: 120,
filterable: false,
@ -215,7 +216,7 @@ export const loadColumns = async (
{
field: 'notes',
headerName: 'Notes',
headerName: translateCrudLabel('Notes'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -6,6 +6,8 @@ import CardBoxModal from '../CardBoxModal';
import { AsyncThunk } from '@reduxjs/toolkit';
import { useDrop } from 'react-dnd';
import KanbanCard from './KanbanCard';
import { useTranslation } from 'react-i18next';
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Props = {
column: { id: string; label: string };
@ -33,6 +35,7 @@ const KanbanColumn = ({
deleteThunk,
updateThunk,
}: Props) => {
const { t, i18n } = useTranslation('common');
const [currentPage, setCurrentPage] = useState(0);
const [count, setCount] = useState(0);
const [data, setData] = useState(null);
@ -106,7 +109,7 @@ const KanbanColumn = ({
setLoading(false);
});
},
[currentUser, column],
[currentUser, column, i18n.language],
);
useEffect(() => {
@ -165,7 +168,7 @@ const KanbanColumn = ({
}
>
<div className={'flex items-center justify-between p-3'}>
<p className={'uppercase'}>{column.label}</p>
<p className={'uppercase'}>{translateCrudLabel(column.label, t)}</p>
<p>{count}</p>
</div>
<div
@ -188,7 +191,7 @@ const KanbanColumn = ({
</div>
))}
{!data?.length && (
<p className={'text-center py-8 bg-gray-50 dark:bg-dark-800'}>No data</p>
<p className={'text-center py-8 bg-gray-50 dark:bg-dark-800'}>{translateCrudLabel('No data', t)}</p>
)}
</div>
</CardBox>
@ -200,7 +203,7 @@ const KanbanColumn = ({
onConfirm={onDeleteConfirm}
onCancel={() => setItemIdToDelete('')}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>
</>
);

View File

@ -1,15 +1,17 @@
import React, { useEffect, useState } from 'react';
import Select, { components, SingleValueProps, OptionProps } from 'react-select';
import { useTranslation } from 'react-i18next';
type LanguageOption = { label: string; value: string };
const LANGS: LanguageOption[] = [
{ value: 'en', label: '🇬🇧 EN' },
{ value: 'fr', label: '🇫🇷 FR' },
{ value: 'es', label: '🇪🇸 ES' },
{ value: 'de', label: '🇩🇪 DE' },
{ value: 'id', label: '🇮🇩 ID' },
{ value: 'en-GB', label: '🇬🇧 EN-UK' },
];
const getLanguageOption = (language?: string) =>
LANGS.find((option) => option.value === language) || LANGS[0];
const Option = (props: OptionProps<LanguageOption, false>) => (
<components.Option {...props}>
<span className='flex items-center gap-1'>{props.data.label}</span>
@ -23,22 +25,42 @@ const SingleVal = (props: SingleValueProps<LanguageOption, false>) => (
);
const LanguageSwitcher: React.FC = () => {
const { i18n } = useTranslation('common');
const [mounted, setMounted] = useState(false);
const [selected, setSelected] = useState<LanguageOption>(LANGS[0]);
useEffect(() => {
setMounted(true);
}, []);
const handleChange = (opt: LanguageOption | null) => {
const savedLanguage = typeof window !== 'undefined' ? window.localStorage.getItem('app_lang_') : null;
const selectedLanguage = getLanguageOption(savedLanguage || i18n.resolvedLanguage || i18n.language);
setSelected(selectedLanguage);
if (selectedLanguage.value !== i18n.language) {
i18n.changeLanguage(selectedLanguage.value);
}
const handleLanguageChanged = (language: string) => {
setSelected(getLanguageOption(language));
};
i18n.on('languageChanged', handleLanguageChanged);
return () => {
i18n.off('languageChanged', handleLanguageChanged);
};
}, [i18n]);
const handleChange = async (opt: LanguageOption | null) => {
if (!opt) return;
setSelected(opt);
window.localStorage.setItem('app_lang_', opt.value);
await i18n.changeLanguage(opt.value);
};
if (!mounted) return null;
return (
<div style={{ width: 88 }}>
<div style={{ width: 118 }}>
<Select
value={selected}
options={LANGS}
@ -78,7 +100,7 @@ const LanguageSwitcher: React.FC = () => {
...base,
paddingTop: 4,
paddingBottom: 4,
height: 26,
height: 28,
fontSize: '0.875rem',
backgroundColor: state.isFocused ? '#f3f4f6' : 'white',
color: '#111827',

View File

@ -10,6 +10,8 @@ import {
} from '@mdi/js';
import Popover from '@mui/material/Popover';
import { IconButton } from '@mui/material';
import { useTranslation } from 'react-i18next';
import { translateCrudLabel } from '../helpers/translateCrudLabel';
type Props = {
@ -31,6 +33,7 @@ const ListActionsPopover = ({
pathEdit,
pathView,
}: Props) => {
const { t } = useTranslation('common');
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
@ -81,7 +84,7 @@ const ListActionsPopover = ({
href={linkView}
sx={{ justifyContent: "start" }}
>
View
{translateCrudLabel('View', t)}
</Button>
{hasUpdatePermission && (
<Button
@ -90,7 +93,7 @@ const ListActionsPopover = ({
href={linkEdit}
sx={{ justifyContent: "start" }}
>
Edit
{translateCrudLabel('Edit', t)}
</Button>
)}
{hasUpdatePermission && (
@ -103,7 +106,7 @@ const ListActionsPopover = ({
}}
sx={{ justifyContent: "start" }}
>
Delete
{translateCrudLabel('Delete', t)}
</Button>
)}
</div>

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -20,11 +21,13 @@ import {dataGridStyles} from "../../styles";
import KanbanBoard from '../KanbanBoard/KanbanBoard';
import axios from 'axios';
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleMarketplace_listings = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -215,7 +218,7 @@ const TableSampleMarketplace_listings = ({ filterItems, setFilterItems, filters,
`marketplace_listings`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -312,7 +315,7 @@ const TableSampleMarketplace_listings = ({ filterItems, setFilterItems, filters,
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -326,7 +329,7 @@ const TableSampleMarketplace_listings = ({ filterItems, setFilterItems, filters,
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -336,7 +339,7 @@ const TableSampleMarketplace_listings = ({ filterItems, setFilterItems, filters,
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -346,12 +349,12 @@ const TableSampleMarketplace_listings = ({ filterItems, setFilterItems, filters,
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -361,22 +364,22 @@ const TableSampleMarketplace_listings = ({ filterItems, setFilterItems, filters,
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -391,12 +394,12 @@ const TableSampleMarketplace_listings = ({ filterItems, setFilterItems, filters,
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -404,11 +407,11 @@ const TableSampleMarketplace_listings = ({ filterItems, setFilterItems, filters,
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -418,11 +421,11 @@ const TableSampleMarketplace_listings = ({ filterItems, setFilterItems, filters,
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -430,7 +433,7 @@ const TableSampleMarketplace_listings = ({ filterItems, setFilterItems, filters,
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -471,7 +474,7 @@ const TableSampleMarketplace_listings = ({ filterItems, setFilterItems, filters,
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'seller_tenant',
headerName: 'SellerTenant',
headerName: translateCrudLabel('SellerTenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'harvest',
headerName: 'Harvest',
headerName: translateCrudLabel('Harvest'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'species',
headerName: 'Species',
headerName: translateCrudLabel('Species'),
flex: 1,
minWidth: 120,
filterable: false,
@ -109,7 +110,7 @@ export const loadColumns = async (
{
field: 'listing_title',
headerName: 'ListingTitle',
headerName: translateCrudLabel('ListingTitle'),
flex: 1,
minWidth: 120,
filterable: false,
@ -124,7 +125,7 @@ export const loadColumns = async (
{
field: 'description',
headerName: 'Description',
headerName: translateCrudLabel('Description'),
flex: 1,
minWidth: 120,
filterable: false,
@ -139,7 +140,7 @@ export const loadColumns = async (
{
field: 'product_form',
headerName: 'ProductForm',
headerName: translateCrudLabel('ProductForm'),
flex: 1,
minWidth: 120,
filterable: false,
@ -154,7 +155,7 @@ export const loadColumns = async (
{
field: 'available_quantity_kg',
headerName: 'AvailableQuantityKg',
headerName: translateCrudLabel('AvailableQuantityKg'),
flex: 1,
minWidth: 120,
filterable: false,
@ -170,7 +171,7 @@ export const loadColumns = async (
{
field: 'price_per_kg',
headerName: 'PricePerKg',
headerName: translateCrudLabel('PricePerKg'),
flex: 1,
minWidth: 120,
filterable: false,
@ -186,7 +187,7 @@ export const loadColumns = async (
{
field: 'currency',
headerName: 'Currency',
headerName: translateCrudLabel('Currency'),
flex: 1,
minWidth: 120,
filterable: false,
@ -201,7 +202,7 @@ export const loadColumns = async (
{
field: 'available_from',
headerName: 'AvailableFrom',
headerName: translateCrudLabel('AvailableFrom'),
flex: 1,
minWidth: 120,
filterable: false,
@ -219,7 +220,7 @@ export const loadColumns = async (
{
field: 'expires_at',
headerName: 'ExpiresAt',
headerName: translateCrudLabel('ExpiresAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -237,7 +238,7 @@ export const loadColumns = async (
{
field: 'listing_status',
headerName: 'ListingStatus',
headerName: translateCrudLabel('ListingStatus'),
flex: 1,
minWidth: 120,
filterable: false,
@ -252,7 +253,7 @@ export const loadColumns = async (
{
field: 'photos',
headerName: 'Photos',
headerName: translateCrudLabel('Photos'),
flex: 1,
minWidth: 120,
filterable: false,
@ -273,7 +274,7 @@ export const loadColumns = async (
{
field: 'fulfillment_location',
headerName: 'FulfillmentLocation',
headerName: translateCrudLabel('FulfillmentLocation'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureOrder_itemsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleOrder_items = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleOrder_items = ({ filterItems, setFilterItems, filters, showGrid
`order_items`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleOrder_items = ({ filterItems, setFilterItems, filters, showGrid
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleOrder_items = ({ filterItems, setFilterItems, filters, showGrid
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleOrder_items = ({ filterItems, setFilterItems, filters, showGrid
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleOrder_items = ({ filterItems, setFilterItems, filters, showGrid
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleOrder_items = ({ filterItems, setFilterItems, filters, showGrid
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleOrder_items = ({ filterItems, setFilterItems, filters, showGrid
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleOrder_items = ({ filterItems, setFilterItems, filters, showGrid
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleOrder_items = ({ filterItems, setFilterItems, filters, showGrid
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleOrder_items = ({ filterItems, setFilterItems, filters, showGrid
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleOrder_items = ({ filterItems, setFilterItems, filters, showGrid
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'order',
headerName: 'Order',
headerName: translateCrudLabel('Order'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'listing',
headerName: 'Listing',
headerName: translateCrudLabel('Listing'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'quantity_kg',
headerName: 'QuantityKg',
headerName: translateCrudLabel('QuantityKg'),
flex: 1,
minWidth: 120,
filterable: false,
@ -103,7 +104,7 @@ export const loadColumns = async (
{
field: 'unit_price',
headerName: 'UnitPrice',
headerName: translateCrudLabel('UnitPrice'),
flex: 1,
minWidth: 120,
filterable: false,
@ -119,7 +120,7 @@ export const loadColumns = async (
{
field: 'line_total',
headerName: 'LineTotal',
headerName: translateCrudLabel('LineTotal'),
flex: 1,
minWidth: 120,
filterable: false,
@ -135,7 +136,7 @@ export const loadColumns = async (
{
field: 'notes',
headerName: 'Notes',
headerName: translateCrudLabel('Notes'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -20,11 +21,13 @@ import {dataGridStyles} from "../../styles";
import KanbanBoard from '../KanbanBoard/KanbanBoard';
import axios from 'axios';
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleOrders = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -217,7 +220,7 @@ const TableSampleOrders = ({ filterItems, setFilterItems, filters, showGrid }) =
`orders`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -314,7 +317,7 @@ const TableSampleOrders = ({ filterItems, setFilterItems, filters, showGrid }) =
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -328,7 +331,7 @@ const TableSampleOrders = ({ filterItems, setFilterItems, filters, showGrid }) =
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -338,7 +341,7 @@ const TableSampleOrders = ({ filterItems, setFilterItems, filters, showGrid }) =
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -348,12 +351,12 @@ const TableSampleOrders = ({ filterItems, setFilterItems, filters, showGrid }) =
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -363,22 +366,22 @@ const TableSampleOrders = ({ filterItems, setFilterItems, filters, showGrid }) =
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -393,12 +396,12 @@ const TableSampleOrders = ({ filterItems, setFilterItems, filters, showGrid }) =
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -406,11 +409,11 @@ const TableSampleOrders = ({ filterItems, setFilterItems, filters, showGrid }) =
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -420,11 +423,11 @@ const TableSampleOrders = ({ filterItems, setFilterItems, filters, showGrid }) =
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -432,7 +435,7 @@ const TableSampleOrders = ({ filterItems, setFilterItems, filters, showGrid }) =
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -473,7 +476,7 @@ const TableSampleOrders = ({ filterItems, setFilterItems, filters, showGrid }) =
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'order_number',
headerName: 'OrderNumber',
headerName: translateCrudLabel('OrderNumber'),
flex: 1,
minWidth: 120,
filterable: false,
@ -58,7 +59,7 @@ export const loadColumns = async (
{
field: 'buyer_tenant',
headerName: 'BuyerTenant',
headerName: translateCrudLabel('BuyerTenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -80,7 +81,7 @@ export const loadColumns = async (
{
field: 'seller_tenant',
headerName: 'SellerTenant',
headerName: translateCrudLabel('SellerTenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -102,7 +103,7 @@ export const loadColumns = async (
{
field: 'ordered_at',
headerName: 'OrderedAt',
headerName: translateCrudLabel('OrderedAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -120,7 +121,7 @@ export const loadColumns = async (
{
field: 'order_status',
headerName: 'OrderStatus',
headerName: translateCrudLabel('OrderStatus'),
flex: 1,
minWidth: 120,
filterable: false,
@ -135,7 +136,7 @@ export const loadColumns = async (
{
field: 'subtotal_amount',
headerName: 'SubtotalAmount',
headerName: translateCrudLabel('SubtotalAmount'),
flex: 1,
minWidth: 120,
filterable: false,
@ -151,7 +152,7 @@ export const loadColumns = async (
{
field: 'tax_amount',
headerName: 'TaxAmount',
headerName: translateCrudLabel('TaxAmount'),
flex: 1,
minWidth: 120,
filterable: false,
@ -167,7 +168,7 @@ export const loadColumns = async (
{
field: 'shipping_amount',
headerName: 'ShippingAmount',
headerName: translateCrudLabel('ShippingAmount'),
flex: 1,
minWidth: 120,
filterable: false,
@ -183,7 +184,7 @@ export const loadColumns = async (
{
field: 'total_amount',
headerName: 'TotalAmount',
headerName: translateCrudLabel('TotalAmount'),
flex: 1,
minWidth: 120,
filterable: false,
@ -199,7 +200,7 @@ export const loadColumns = async (
{
field: 'currency',
headerName: 'Currency',
headerName: translateCrudLabel('Currency'),
flex: 1,
minWidth: 120,
filterable: false,
@ -214,7 +215,7 @@ export const loadColumns = async (
{
field: 'delivery_address',
headerName: 'DeliveryAddress',
headerName: translateCrudLabel('DeliveryAddress'),
flex: 1,
minWidth: 120,
filterable: false,
@ -229,7 +230,7 @@ export const loadColumns = async (
{
field: 'buyer_notes',
headerName: 'BuyerNotes',
headerName: translateCrudLabel('BuyerNotes'),
flex: 1,
minWidth: 120,
filterable: false,
@ -244,7 +245,7 @@ export const loadColumns = async (
{
field: 'expected_delivery_at',
headerName: 'ExpectedDeliveryAt',
headerName: translateCrudLabel('ExpectedDeliveryAt'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureOrganizationsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
`organizations`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleOrganizations = ({ filterItems, setFilterItems, filters, showGr
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'name',
headerName: 'Name',
headerName: translateCrudLabel('Name'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configurePayment_transactionsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSamplePayment_transactions = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSamplePayment_transactions = ({ filterItems, setFilterItems, filters,
`payment_transactions`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSamplePayment_transactions = ({ filterItems, setFilterItems, filters,
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSamplePayment_transactions = ({ filterItems, setFilterItems, filters,
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSamplePayment_transactions = ({ filterItems, setFilterItems, filters,
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSamplePayment_transactions = ({ filterItems, setFilterItems, filters,
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSamplePayment_transactions = ({ filterItems, setFilterItems, filters,
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSamplePayment_transactions = ({ filterItems, setFilterItems, filters,
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSamplePayment_transactions = ({ filterItems, setFilterItems, filters,
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSamplePayment_transactions = ({ filterItems, setFilterItems, filters,
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSamplePayment_transactions = ({ filterItems, setFilterItems, filters,
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSamplePayment_transactions = ({ filterItems, setFilterItems, filters,
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'order',
headerName: 'Order',
headerName: translateCrudLabel('Order'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'buyer_tenant',
headerName: 'BuyerTenant',
headerName: translateCrudLabel('BuyerTenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'seller_tenant',
headerName: 'SellerTenant',
headerName: translateCrudLabel('SellerTenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -109,7 +110,7 @@ export const loadColumns = async (
{
field: 'transaction_type',
headerName: 'TransactionType',
headerName: translateCrudLabel('TransactionType'),
flex: 1,
minWidth: 120,
filterable: false,
@ -124,7 +125,7 @@ export const loadColumns = async (
{
field: 'transaction_status',
headerName: 'TransactionStatus',
headerName: translateCrudLabel('TransactionStatus'),
flex: 1,
minWidth: 120,
filterable: false,
@ -139,7 +140,7 @@ export const loadColumns = async (
{
field: 'amount',
headerName: 'Amount',
headerName: translateCrudLabel('Amount'),
flex: 1,
minWidth: 120,
filterable: false,
@ -155,7 +156,7 @@ export const loadColumns = async (
{
field: 'currency',
headerName: 'Currency',
headerName: translateCrudLabel('Currency'),
flex: 1,
minWidth: 120,
filterable: false,
@ -170,7 +171,7 @@ export const loadColumns = async (
{
field: 'provider',
headerName: 'Provider',
headerName: translateCrudLabel('Provider'),
flex: 1,
minWidth: 120,
filterable: false,
@ -185,7 +186,7 @@ export const loadColumns = async (
{
field: 'provider_reference',
headerName: 'ProviderReference',
headerName: translateCrudLabel('ProviderReference'),
flex: 1,
minWidth: 120,
filterable: false,
@ -200,7 +201,7 @@ export const loadColumns = async (
{
field: 'processed_at',
headerName: 'ProcessedAt',
headerName: translateCrudLabel('ProcessedAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -218,7 +219,7 @@ export const loadColumns = async (
{
field: 'failure_reason',
headerName: 'FailureReason',
headerName: translateCrudLabel('FailureReason'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configurePermissionsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
`permissions`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSamplePermissions = ({ filterItems, setFilterItems, filters, showGrid
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'name',
headerName: 'Name',
headerName: translateCrudLabel('Name'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -20,11 +21,13 @@ import {dataGridStyles} from "../../styles";
import KanbanBoard from '../KanbanBoard/KanbanBoard';
import axios from 'axios';
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSamplePonds = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -209,7 +212,7 @@ const TableSamplePonds = ({ filterItems, setFilterItems, filters, showGrid }) =>
`ponds`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -306,7 +309,7 @@ const TableSamplePonds = ({ filterItems, setFilterItems, filters, showGrid }) =>
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -320,7 +323,7 @@ const TableSamplePonds = ({ filterItems, setFilterItems, filters, showGrid }) =>
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -330,7 +333,7 @@ const TableSamplePonds = ({ filterItems, setFilterItems, filters, showGrid }) =>
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -340,12 +343,12 @@ const TableSamplePonds = ({ filterItems, setFilterItems, filters, showGrid }) =>
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -355,22 +358,22 @@ const TableSamplePonds = ({ filterItems, setFilterItems, filters, showGrid }) =>
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -385,12 +388,12 @@ const TableSamplePonds = ({ filterItems, setFilterItems, filters, showGrid }) =>
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -398,11 +401,11 @@ const TableSamplePonds = ({ filterItems, setFilterItems, filters, showGrid }) =>
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -412,11 +415,11 @@ const TableSamplePonds = ({ filterItems, setFilterItems, filters, showGrid }) =>
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -424,7 +427,7 @@ const TableSamplePonds = ({ filterItems, setFilterItems, filters, showGrid }) =>
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -465,7 +468,7 @@ const TableSamplePonds = ({ filterItems, setFilterItems, filters, showGrid }) =>
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'location',
headerName: 'Location',
headerName: translateCrudLabel('Location'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'pond_name',
headerName: 'PondName',
headerName: translateCrudLabel('PondName'),
flex: 1,
minWidth: 120,
filterable: false,
@ -102,7 +103,7 @@ export const loadColumns = async (
{
field: 'pond_type',
headerName: 'PondType',
headerName: translateCrudLabel('PondType'),
flex: 1,
minWidth: 120,
filterable: false,
@ -117,7 +118,7 @@ export const loadColumns = async (
{
field: 'area_sq_m',
headerName: 'AreaSqM',
headerName: translateCrudLabel('AreaSqM'),
flex: 1,
minWidth: 120,
filterable: false,
@ -133,7 +134,7 @@ export const loadColumns = async (
{
field: 'avg_depth_m',
headerName: 'AverageDepthM',
headerName: translateCrudLabel('AverageDepthM'),
flex: 1,
minWidth: 120,
filterable: false,
@ -149,7 +150,7 @@ export const loadColumns = async (
{
field: 'notes',
headerName: 'Notes',
headerName: translateCrudLabel('Notes'),
flex: 1,
minWidth: 120,
filterable: false,
@ -164,7 +165,7 @@ export const loadColumns = async (
{
field: 'status',
headerName: 'Status',
headerName: translateCrudLabel('Status'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureRolesCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
`roles`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleRoles = ({ filterItems, setFilterItems, filters, showGrid }) =>
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'name',
headerName: 'Name',
headerName: translateCrudLabel('Name'),
flex: 1,
minWidth: 120,
filterable: false,
@ -58,7 +59,7 @@ export const loadColumns = async (
{
field: 'permissions',
headerName: 'Permissions',
headerName: translateCrudLabel('Permissions'),
flex: 1,
minWidth: 120,
filterable: false,
@ -78,7 +79,7 @@ export const loadColumns = async (
{
field: 'globalAccess',
headerName: 'Global Access',
headerName: translateCrudLabel('Global Access'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,17 +1,19 @@
import React from 'react';
import CardBox from './CardBox';
import { useRouter } from 'next/router';
import { humanize } from '../helpers/humanize';
import { useTranslation } from 'react-i18next';
import { translateCrudLabel } from '../helpers/translateCrudLabel';
const SearchResults = ({ searchResults, searchQuery }) => {
const router = useRouter();
const { t } = useTranslation('common');
return (
<>
<p className={'block font-bold mb-2'}>Matches with: {searchQuery}</p>
<p className={'block font-bold mb-2'}>{t('labels.matches_with', { query: searchQuery })}</p>
{Object.keys(searchResults).map((tableName) => (
<>
<p className={'block font-bold mb-2'}>{humanize(tableName)}</p>
<p className={'block font-bold mb-2'}>{translateCrudLabel(tableName, t)}</p>
<CardBox
className='mb-6 border border-gray-300 rounded overflow-hidden'
hasTable
@ -30,7 +32,7 @@ const SearchResults = ({ searchResults, searchQuery }) => {
) {
return (
<th data-label={key} key={key}>
{humanize(key)}
{translateCrudLabel(key, t)}
</th>
);
}
@ -68,13 +70,13 @@ const SearchResults = ({ searchResults, searchQuery }) => {
</table>
</div>
{!Object.keys(searchResults).length && (
<div className={'text-center py-4'}>No data</div>
<div className={'text-center py-4'}>{translateCrudLabel('No data', t)}</div>
)}
</CardBox>
</>
))}
{!Object.keys(searchResults).length && (
<div className={'py-4'}>No matches</div>
<div className={'py-4'}>{translateCrudLabel('No matches', t)}</div>
)}
</>
);

View File

@ -3,7 +3,8 @@ import React, { Children, ReactNode } from 'react'
import BaseButton from './BaseButton'
import BaseIcon from './BaseIcon'
import IconRounded from './IconRounded'
import { humanize } from '../helpers/humanize';
import { useTranslation } from 'react-i18next';
import { translateCrudLabel } from '../helpers/translateCrudLabel';
type Props = {
icon: string
@ -13,14 +14,16 @@ type Props = {
}
export default function SectionTitleLineWithButton({ icon, title, main = false, children }: Props) {
const { t } = useTranslation('common')
const hasChildren = !!Children.count(children)
const translatedTitle = translateCrudLabel(title, t)
return (
<section className={`${main ? '' : 'pt-6'} mb-6 flex items-center justify-between`}>
<div className="flex items-center justify-start">
{icon && main && <IconRounded icon={icon} color="light" className="mr-3" bg />}
{icon && !main && <BaseIcon path={icon} className="mr-2" size="20" />}
<h1 className={`leading-tight ${main ? 'text-3xl' : 'text-2xl'}`}>{humanize(title)}</h1>
<h1 className={`leading-tight ${main ? 'text-3xl' : 'text-2xl'}`}>{translatedTitle}</h1>
</div>
{children}
{!hasChildren && <BaseButton icon={mdiCog} color="whiteDark" />}

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureShipment_updatesCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleShipment_updates = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleShipment_updates = ({ filterItems, setFilterItems, filters, sho
`shipment_updates`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleShipment_updates = ({ filterItems, setFilterItems, filters, sho
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleShipment_updates = ({ filterItems, setFilterItems, filters, sho
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleShipment_updates = ({ filterItems, setFilterItems, filters, sho
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleShipment_updates = ({ filterItems, setFilterItems, filters, sho
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleShipment_updates = ({ filterItems, setFilterItems, filters, sho
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleShipment_updates = ({ filterItems, setFilterItems, filters, sho
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleShipment_updates = ({ filterItems, setFilterItems, filters, sho
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleShipment_updates = ({ filterItems, setFilterItems, filters, sho
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleShipment_updates = ({ filterItems, setFilterItems, filters, sho
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleShipment_updates = ({ filterItems, setFilterItems, filters, sho
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'order',
headerName: 'Order',
headerName: translateCrudLabel('Order'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'shipment_status',
headerName: 'ShipmentStatus',
headerName: translateCrudLabel('ShipmentStatus'),
flex: 1,
minWidth: 120,
filterable: false,
@ -80,7 +81,7 @@ export const loadColumns = async (
{
field: 'carrier',
headerName: 'Carrier',
headerName: translateCrudLabel('Carrier'),
flex: 1,
minWidth: 120,
filterable: false,
@ -95,7 +96,7 @@ export const loadColumns = async (
{
field: 'tracking_number',
headerName: 'TrackingNumber',
headerName: translateCrudLabel('TrackingNumber'),
flex: 1,
minWidth: 120,
filterable: false,
@ -110,7 +111,7 @@ export const loadColumns = async (
{
field: 'status_at',
headerName: 'StatusAt',
headerName: translateCrudLabel('StatusAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -128,7 +129,7 @@ export const loadColumns = async (
{
field: 'status_details',
headerName: 'StatusDetails',
headerName: translateCrudLabel('StatusDetails'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureSpeciesCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleSpecies = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleSpecies = ({ filterItems, setFilterItems, filters, showGrid })
`species`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleSpecies = ({ filterItems, setFilterItems, filters, showGrid })
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleSpecies = ({ filterItems, setFilterItems, filters, showGrid })
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleSpecies = ({ filterItems, setFilterItems, filters, showGrid })
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleSpecies = ({ filterItems, setFilterItems, filters, showGrid })
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleSpecies = ({ filterItems, setFilterItems, filters, showGrid })
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleSpecies = ({ filterItems, setFilterItems, filters, showGrid })
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleSpecies = ({ filterItems, setFilterItems, filters, showGrid })
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleSpecies = ({ filterItems, setFilterItems, filters, showGrid })
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleSpecies = ({ filterItems, setFilterItems, filters, showGrid })
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleSpecies = ({ filterItems, setFilterItems, filters, showGrid })
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'species_name',
headerName: 'SpeciesName',
headerName: translateCrudLabel('SpeciesName'),
flex: 1,
minWidth: 120,
filterable: false,
@ -58,7 +59,7 @@ export const loadColumns = async (
{
field: 'scientific_name',
headerName: 'ScientificName',
headerName: translateCrudLabel('ScientificName'),
flex: 1,
minWidth: 120,
filterable: false,
@ -73,7 +74,7 @@ export const loadColumns = async (
{
field: 'typical_harvest_size',
headerName: 'TypicalHarvestSize',
headerName: translateCrudLabel('TypicalHarvestSize'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,6 +17,7 @@ import {loadColumns} from "./configureTenant_locationsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
import CardTenant_locations from './CardTenant_locations';
@ -24,6 +26,7 @@ import CardTenant_locations from './CardTenant_locations';
const perPage = 10
const TableSampleTenant_locations = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -182,7 +185,7 @@ const TableSampleTenant_locations = ({ filterItems, setFilterItems, filters, sho
`tenant_locations`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -279,7 +282,7 @@ const TableSampleTenant_locations = ({ filterItems, setFilterItems, filters, sho
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -293,7 +296,7 @@ const TableSampleTenant_locations = ({ filterItems, setFilterItems, filters, sho
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -303,7 +306,7 @@ const TableSampleTenant_locations = ({ filterItems, setFilterItems, filters, sho
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -313,12 +316,12 @@ const TableSampleTenant_locations = ({ filterItems, setFilterItems, filters, sho
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -328,22 +331,22 @@ const TableSampleTenant_locations = ({ filterItems, setFilterItems, filters, sho
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -358,12 +361,12 @@ const TableSampleTenant_locations = ({ filterItems, setFilterItems, filters, sho
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -371,11 +374,11 @@ const TableSampleTenant_locations = ({ filterItems, setFilterItems, filters, sho
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -385,11 +388,11 @@ const TableSampleTenant_locations = ({ filterItems, setFilterItems, filters, sho
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -397,7 +400,7 @@ const TableSampleTenant_locations = ({ filterItems, setFilterItems, filters, sho
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -438,7 +441,7 @@ const TableSampleTenant_locations = ({ filterItems, setFilterItems, filters, sho
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'location_name',
headerName: 'LocationName',
headerName: translateCrudLabel('LocationName'),
flex: 1,
minWidth: 120,
filterable: false,
@ -80,7 +81,7 @@ export const loadColumns = async (
{
field: 'address',
headerName: 'Address',
headerName: translateCrudLabel('Address'),
flex: 1,
minWidth: 120,
filterable: false,
@ -95,7 +96,7 @@ export const loadColumns = async (
{
field: 'latitude',
headerName: 'Latitude',
headerName: translateCrudLabel('Latitude'),
flex: 1,
minWidth: 120,
filterable: false,
@ -111,7 +112,7 @@ export const loadColumns = async (
{
field: 'longitude',
headerName: 'Longitude',
headerName: translateCrudLabel('Longitude'),
flex: 1,
minWidth: 120,
filterable: false,
@ -127,7 +128,7 @@ export const loadColumns = async (
{
field: 'timezone',
headerName: 'Timezone',
headerName: translateCrudLabel('Timezone'),
flex: 1,
minWidth: 120,
filterable: false,
@ -142,7 +143,7 @@ export const loadColumns = async (
{
field: 'is_primary',
headerName: 'IsPrimary',
headerName: translateCrudLabel('IsPrimary'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureTenantsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleTenants = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleTenants = ({ filterItems, setFilterItems, filters, showGrid })
`tenants`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleTenants = ({ filterItems, setFilterItems, filters, showGrid })
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleTenants = ({ filterItems, setFilterItems, filters, showGrid })
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleTenants = ({ filterItems, setFilterItems, filters, showGrid })
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleTenants = ({ filterItems, setFilterItems, filters, showGrid })
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleTenants = ({ filterItems, setFilterItems, filters, showGrid })
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleTenants = ({ filterItems, setFilterItems, filters, showGrid })
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleTenants = ({ filterItems, setFilterItems, filters, showGrid })
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleTenants = ({ filterItems, setFilterItems, filters, showGrid })
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleTenants = ({ filterItems, setFilterItems, filters, showGrid })
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleTenants = ({ filterItems, setFilterItems, filters, showGrid })
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant_name',
headerName: 'TenantName',
headerName: translateCrudLabel('TenantName'),
flex: 1,
minWidth: 120,
filterable: false,
@ -58,7 +59,7 @@ export const loadColumns = async (
{
field: 'slug',
headerName: 'Slug',
headerName: translateCrudLabel('Slug'),
flex: 1,
minWidth: 120,
filterable: false,
@ -73,7 +74,7 @@ export const loadColumns = async (
{
field: 'tenant_type',
headerName: 'TenantType',
headerName: translateCrudLabel('TenantType'),
flex: 1,
minWidth: 120,
filterable: false,
@ -88,7 +89,7 @@ export const loadColumns = async (
{
field: 'contact_email',
headerName: 'ContactEmail',
headerName: translateCrudLabel('ContactEmail'),
flex: 1,
minWidth: 120,
filterable: false,
@ -103,7 +104,7 @@ export const loadColumns = async (
{
field: 'contact_phone',
headerName: 'ContactPhone',
headerName: translateCrudLabel('ContactPhone'),
flex: 1,
minWidth: 120,
filterable: false,
@ -118,7 +119,7 @@ export const loadColumns = async (
{
field: 'billing_address',
headerName: 'BillingAddress',
headerName: translateCrudLabel('BillingAddress'),
flex: 1,
minWidth: 120,
filterable: false,
@ -133,7 +134,7 @@ export const loadColumns = async (
{
field: 'subscription_status',
headerName: 'SubscriptionStatus',
headerName: translateCrudLabel('SubscriptionStatus'),
flex: 1,
minWidth: 120,
filterable: false,
@ -148,7 +149,7 @@ export const loadColumns = async (
{
field: 'trial_ends_at',
headerName: 'TrialEndsAt',
headerName: translateCrudLabel('TrialEndsAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -166,7 +167,7 @@ export const loadColumns = async (
{
field: 'is_enabled',
headerName: 'IsEnabled',
headerName: translateCrudLabel('IsEnabled'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureUser_membershipsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleUser_memberships = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleUser_memberships = ({ filterItems, setFilterItems, filters, sho
`user_memberships`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleUser_memberships = ({ filterItems, setFilterItems, filters, sho
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleUser_memberships = ({ filterItems, setFilterItems, filters, sho
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleUser_memberships = ({ filterItems, setFilterItems, filters, sho
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleUser_memberships = ({ filterItems, setFilterItems, filters, sho
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleUser_memberships = ({ filterItems, setFilterItems, filters, sho
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleUser_memberships = ({ filterItems, setFilterItems, filters, sho
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleUser_memberships = ({ filterItems, setFilterItems, filters, sho
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleUser_memberships = ({ filterItems, setFilterItems, filters, sho
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleUser_memberships = ({ filterItems, setFilterItems, filters, sho
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleUser_memberships = ({ filterItems, setFilterItems, filters, sho
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'user',
headerName: 'User',
headerName: translateCrudLabel('User'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'role',
headerName: 'Role',
headerName: translateCrudLabel('Role'),
flex: 1,
minWidth: 120,
filterable: false,
@ -109,7 +110,7 @@ export const loadColumns = async (
{
field: 'membership_status',
headerName: 'MembershipStatus',
headerName: translateCrudLabel('MembershipStatus'),
flex: 1,
minWidth: 120,
filterable: false,
@ -124,7 +125,7 @@ export const loadColumns = async (
{
field: 'joined_at',
headerName: 'JoinedAt',
headerName: translateCrudLabel('JoinedAt'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureUsersCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
`users`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleUsers = ({ filterItems, setFilterItems, filters, showGrid }) =>
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'firstName',
headerName: 'First Name',
headerName: translateCrudLabel('First Name'),
flex: 1,
minWidth: 120,
filterable: false,
@ -58,7 +59,7 @@ export const loadColumns = async (
{
field: 'lastName',
headerName: 'Last Name',
headerName: translateCrudLabel('Last Name'),
flex: 1,
minWidth: 120,
filterable: false,
@ -73,7 +74,7 @@ export const loadColumns = async (
{
field: 'phoneNumber',
headerName: 'Phone Number',
headerName: translateCrudLabel('Phone Number'),
flex: 1,
minWidth: 120,
filterable: false,
@ -88,7 +89,7 @@ export const loadColumns = async (
{
field: 'email',
headerName: 'E-Mail',
headerName: translateCrudLabel('E-Mail'),
flex: 1,
minWidth: 120,
filterable: false,
@ -103,7 +104,7 @@ export const loadColumns = async (
{
field: 'disabled',
headerName: 'Disabled',
headerName: translateCrudLabel('Disabled'),
flex: 1,
minWidth: 120,
filterable: false,
@ -119,7 +120,7 @@ export const loadColumns = async (
{
field: 'avatar',
headerName: 'Avatar',
headerName: translateCrudLabel('Avatar'),
flex: 1,
minWidth: 120,
filterable: false,
@ -140,7 +141,7 @@ export const loadColumns = async (
{
field: 'app_role',
headerName: 'App Role',
headerName: translateCrudLabel('App Role'),
flex: 1,
minWidth: 120,
filterable: false,
@ -162,7 +163,7 @@ export const loadColumns = async (
{
field: 'custom_permissions',
headerName: 'Custom Permissions',
headerName: translateCrudLabel('Custom Permissions'),
flex: 1,
minWidth: 120,
filterable: false,
@ -182,7 +183,7 @@ export const loadColumns = async (
{
field: 'organizations',
headerName: 'Organizations',
headerName: translateCrudLabel('Organizations'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureWater_quality_logsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleWater_quality_logs = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleWater_quality_logs = ({ filterItems, setFilterItems, filters, s
`water_quality_logs`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleWater_quality_logs = ({ filterItems, setFilterItems, filters, s
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleWater_quality_logs = ({ filterItems, setFilterItems, filters, s
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleWater_quality_logs = ({ filterItems, setFilterItems, filters, s
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleWater_quality_logs = ({ filterItems, setFilterItems, filters, s
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleWater_quality_logs = ({ filterItems, setFilterItems, filters, s
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleWater_quality_logs = ({ filterItems, setFilterItems, filters, s
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleWater_quality_logs = ({ filterItems, setFilterItems, filters, s
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleWater_quality_logs = ({ filterItems, setFilterItems, filters, s
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleWater_quality_logs = ({ filterItems, setFilterItems, filters, s
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleWater_quality_logs = ({ filterItems, setFilterItems, filters, s
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'pond',
headerName: 'Pond',
headerName: translateCrudLabel('Pond'),
flex: 1,
minWidth: 120,
filterable: false,
@ -87,7 +88,7 @@ export const loadColumns = async (
{
field: 'sampled_at',
headerName: 'SampledAt',
headerName: translateCrudLabel('SampledAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -105,7 +106,7 @@ export const loadColumns = async (
{
field: 'temperature_c',
headerName: 'TemperatureC',
headerName: translateCrudLabel('TemperatureC'),
flex: 1,
minWidth: 120,
filterable: false,
@ -121,7 +122,7 @@ export const loadColumns = async (
{
field: 'ph',
headerName: 'pH',
headerName: translateCrudLabel('pH'),
flex: 1,
minWidth: 120,
filterable: false,
@ -137,7 +138,7 @@ export const loadColumns = async (
{
field: 'dissolved_oxygen_mg_l',
headerName: 'DissolvedOxygenMgL',
headerName: translateCrudLabel('DissolvedOxygenMgL'),
flex: 1,
minWidth: 120,
filterable: false,
@ -153,7 +154,7 @@ export const loadColumns = async (
{
field: 'salinity_ppt',
headerName: 'SalinityPpt',
headerName: translateCrudLabel('SalinityPpt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -169,7 +170,7 @@ export const loadColumns = async (
{
field: 'ammonia_mg_l',
headerName: 'AmmoniaMgL',
headerName: translateCrudLabel('AmmoniaMgL'),
flex: 1,
minWidth: 120,
filterable: false,
@ -185,7 +186,7 @@ export const loadColumns = async (
{
field: 'nitrite_mg_l',
headerName: 'NitriteMgL',
headerName: translateCrudLabel('NitriteMgL'),
flex: 1,
minWidth: 120,
filterable: false,
@ -201,7 +202,7 @@ export const loadColumns = async (
{
field: 'nitrate_mg_l',
headerName: 'NitrateMgL',
headerName: translateCrudLabel('NitrateMgL'),
flex: 1,
minWidth: 120,
filterable: false,
@ -217,7 +218,7 @@ export const loadColumns = async (
{
field: 'turbidity_ntu',
headerName: 'TurbidityNTU',
headerName: translateCrudLabel('TurbidityNTU'),
flex: 1,
minWidth: 120,
filterable: false,
@ -233,7 +234,7 @@ export const loadColumns = async (
{
field: 'notes',
headerName: 'Notes',
headerName: translateCrudLabel('Notes'),
flex: 1,
minWidth: 120,
filterable: false,
@ -248,7 +249,7 @@ export const loadColumns = async (
{
field: 'recorded_by',
headerName: 'RecordedBy',
headerName: translateCrudLabel('RecordedBy'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureWebhook_deliveriesCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleWebhook_deliveries = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleWebhook_deliveries = ({ filterItems, setFilterItems, filters, s
`webhook_deliveries`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleWebhook_deliveries = ({ filterItems, setFilterItems, filters, s
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleWebhook_deliveries = ({ filterItems, setFilterItems, filters, s
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleWebhook_deliveries = ({ filterItems, setFilterItems, filters, s
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleWebhook_deliveries = ({ filterItems, setFilterItems, filters, s
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleWebhook_deliveries = ({ filterItems, setFilterItems, filters, s
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleWebhook_deliveries = ({ filterItems, setFilterItems, filters, s
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleWebhook_deliveries = ({ filterItems, setFilterItems, filters, s
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleWebhook_deliveries = ({ filterItems, setFilterItems, filters, s
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleWebhook_deliveries = ({ filterItems, setFilterItems, filters, s
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleWebhook_deliveries = ({ filterItems, setFilterItems, filters, s
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'endpoint',
headerName: 'Endpoint',
headerName: translateCrudLabel('Endpoint'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'event_type',
headerName: 'EventType',
headerName: translateCrudLabel('EventType'),
flex: 1,
minWidth: 120,
filterable: false,
@ -80,7 +81,7 @@ export const loadColumns = async (
{
field: 'event_reference',
headerName: 'EventReference',
headerName: translateCrudLabel('EventReference'),
flex: 1,
minWidth: 120,
filterable: false,
@ -95,7 +96,7 @@ export const loadColumns = async (
{
field: 'delivered_at',
headerName: 'DeliveredAt',
headerName: translateCrudLabel('DeliveredAt'),
flex: 1,
minWidth: 120,
filterable: false,
@ -113,7 +114,7 @@ export const loadColumns = async (
{
field: 'delivery_status',
headerName: 'DeliveryStatus',
headerName: translateCrudLabel('DeliveryStatus'),
flex: 1,
minWidth: 120,
filterable: false,
@ -128,7 +129,7 @@ export const loadColumns = async (
{
field: 'http_status',
headerName: 'HTTPStatus',
headerName: translateCrudLabel('HTTPStatus'),
flex: 1,
minWidth: 120,
filterable: false,
@ -144,7 +145,7 @@ export const loadColumns = async (
{
field: 'request_payload',
headerName: 'RequestPayload',
headerName: translateCrudLabel('RequestPayload'),
flex: 1,
minWidth: 120,
filterable: false,
@ -159,7 +160,7 @@ export const loadColumns = async (
{
field: 'response_body',
headerName: 'ResponseBody',
headerName: translateCrudLabel('ResponseBody'),
flex: 1,
minWidth: 120,
filterable: false,
@ -174,7 +175,7 @@ export const loadColumns = async (
{
field: 'attempt_count',
headerName: 'AttemptCount',
headerName: translateCrudLabel('AttemptCount'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -1,4 +1,5 @@
import React, { useEffect, useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
@ -16,12 +17,14 @@ import {loadColumns} from "./configureWebhook_endpointsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
const perPage = 10
const TableSampleWebhook_endpoints = ({ filterItems, setFilterItems, filters, showGrid }) => {
const { t, i18n } = useTranslation('common');
const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});
const dispatch = useAppDispatch();
@ -180,7 +183,7 @@ const TableSampleWebhook_endpoints = ({ filterItems, setFilterItems, filters, sh
`webhook_endpoints`,
currentUser,
).then((newCols) => setColumns(newCols));
}, [currentUser]);
}, [currentUser, i18n.language]);
@ -277,7 +280,7 @@ const TableSampleWebhook_endpoints = ({ filterItems, setFilterItems, filters, sh
return (
<div key={filterItem.id} className="flex mb-4">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Filter</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Filter', t)}</div>
<Field
className={controlClasses}
name='selectedField'
@ -291,7 +294,7 @@ const TableSampleWebhook_endpoints = ({ filterItems, setFilterItems, filters, sh
key={selectOption.title}
value={`${selectOption.title}`}
>
{selectOption.label}
{translateCrudLabel(selectOption.label, t)}
</option>
))}
</Field>
@ -301,7 +304,7 @@ const TableSampleWebhook_endpoints = ({ filterItems, setFilterItems, filters, sh
)?.type === 'enum' ? (
<div className="flex flex-col w-full mr-3">
<div className="text-gray-500 font-bold">
Value
{translateCrudLabel('Value', t)}
</div>
<Field
className={controlClasses}
@ -311,12 +314,12 @@ const TableSampleWebhook_endpoints = ({ filterItems, setFilterItems, filters, sh
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
>
<option value="">Select Value</option>
<option value="">{translateCrudLabel('Select Value', t)}</option>
{filters.find((filter) =>
filter.title === filterItem?.fields?.selectedField
)?.options?.map((option) => (
<option key={option} value={option}>
{option}
{translateCrudLabel(option, t)}
</option>
))}
</Field>
@ -326,22 +329,22 @@ const TableSampleWebhook_endpoints = ({ filterItems, setFilterItems, filters, sh
)?.number ? (
<div className="flex flex-row w-full mr-3">
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">From</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('From', t)}</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
value={filterItem?.fields?.filterValueFrom || ''}
onChange={handleChange(filterItem.id)}
/>
</div>
<div className="flex flex-col w-full">
<div className=" text-gray-500 font-bold">To</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
value={filterItem?.fields?.filterValueTo || ''}
onChange={handleChange(filterItem.id)}
@ -356,12 +359,12 @@ const TableSampleWebhook_endpoints = ({ filterItems, setFilterItems, filters, sh
<div className='flex flex-row w-full mr-3'>
<div className='flex flex-col w-full mr-3'>
<div className=' text-gray-500 font-bold'>
From
{translateCrudLabel('From', t)}
</div>
<Field
className={controlClasses}
name='filterValueFrom'
placeholder='From'
placeholder={translateCrudLabel('From', t)}
id='filterValueFrom'
type='datetime-local'
value={filterItem?.fields?.filterValueFrom || ''}
@ -369,11 +372,11 @@ const TableSampleWebhook_endpoints = ({ filterItems, setFilterItems, filters, sh
/>
</div>
<div className='flex flex-col w-full'>
<div className=' text-gray-500 font-bold'>To</div>
<div className=' text-gray-500 font-bold'>{translateCrudLabel('To', t)}</div>
<Field
className={controlClasses}
name='filterValueTo'
placeholder='to'
placeholder={translateCrudLabel('To', t)}
id='filterValueTo'
type='datetime-local'
value={filterItem?.fields?.filterValueTo || ''}
@ -383,11 +386,11 @@ const TableSampleWebhook_endpoints = ({ filterItems, setFilterItems, filters, sh
</div>
) : (
<div className="flex flex-col w-full mr-3">
<div className=" text-gray-500 font-bold">Contains</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Contains', t)}</div>
<Field
className={controlClasses}
name='filterValue'
placeholder='Contained'
placeholder={translateCrudLabel('Contained', t)}
id='filterValue'
value={filterItem?.fields?.filterValue || ''}
onChange={handleChange(filterItem.id)}
@ -395,7 +398,7 @@ const TableSampleWebhook_endpoints = ({ filterItems, setFilterItems, filters, sh
</div>
)}
<div className="flex flex-col">
<div className=" text-gray-500 font-bold">Action</div>
<div className=" text-gray-500 font-bold">{translateCrudLabel('Action', t)}</div>
<BaseButton
className="my-2"
type='reset'
@ -436,7 +439,7 @@ const TableSampleWebhook_endpoints = ({ filterItems, setFilterItems, filters, sh
onConfirm={handleDeleteAction}
onCancel={handleModalAction}
>
<p>Are you sure you want to delete this item?</p>
<p>{translateCrudLabel('Are you sure you want to delete this item?', t)}</p>
</CardBoxModal>

View File

@ -14,6 +14,7 @@ import DataGridMultiSelect from "../DataGridMultiSelect";
import ListActionsPopover from '../ListActionsPopover';
import {hasPermission} from "../../helpers/userPermissions";
import { translateCrudLabel } from '../../helpers/translateCrudLabel';
type Params = (id: string) => void;
@ -43,7 +44,7 @@ export const loadColumns = async (
{
field: 'tenant',
headerName: 'Tenant',
headerName: translateCrudLabel('Tenant'),
flex: 1,
minWidth: 120,
filterable: false,
@ -65,7 +66,7 @@ export const loadColumns = async (
{
field: 'endpoint_name',
headerName: 'EndpointName',
headerName: translateCrudLabel('EndpointName'),
flex: 1,
minWidth: 120,
filterable: false,
@ -80,7 +81,7 @@ export const loadColumns = async (
{
field: 'url',
headerName: 'URL',
headerName: translateCrudLabel('URL'),
flex: 1,
minWidth: 120,
filterable: false,
@ -95,7 +96,7 @@ export const loadColumns = async (
{
field: 'secret',
headerName: 'Secret',
headerName: translateCrudLabel('Secret'),
flex: 1,
minWidth: 120,
filterable: false,
@ -110,7 +111,7 @@ export const loadColumns = async (
{
field: 'is_enabled',
headerName: 'IsEnabled',
headerName: translateCrudLabel('IsEnabled'),
flex: 1,
minWidth: 120,
filterable: false,
@ -126,7 +127,7 @@ export const loadColumns = async (
{
field: 'event_types',
headerName: 'EventTypes',
headerName: translateCrudLabel('EventTypes'),
flex: 1,
minWidth: 120,
filterable: false,
@ -141,7 +142,7 @@ export const loadColumns = async (
{
field: 'last_delivery_at',
headerName: 'LastDeliveryAt',
headerName: translateCrudLabel('LastDeliveryAt'),
flex: 1,
minWidth: 120,
filterable: false,

View File

@ -0,0 +1,73 @@
import type { TFunction } from 'i18next'
import i18n from '../i18n'
import { humanize } from './humanize'
const splitCamelCase = (value: string) =>
value
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
export const crudLabelKey = (value?: string | null) => {
if (!value) return ''
return splitCamelCase(String(value))
.replace(/&/g, ' and ')
.replace(/[./]/g, ' ')
.replace(/[^A-Za-z0-9_\s-]/g, '')
.replace(/[-\s]+/g, '_')
.replace(/_+/g, '_')
.replace(/^_+|_+$/g, '')
.toLowerCase()
}
const fallbackLabel = (value: string) =>
humanize(splitCamelCase(value).replace(/_/g, ' '))
.replace(/\bApi\b/g, 'API')
.replace(/\bCsv\b/g, 'CSV')
.replace(/\bHttp\b/g, 'HTTP')
.replace(/\bId\b/g, 'ID')
.replace(/\bKg\b/g, 'kg')
.replace(/\bSq\b/g, 'sq')
.replace(/\bMg\b/g, 'mg')
.replace(/\bMm\b/g, 'mm')
.replace(/\bNtu\b/g, 'NTU')
.replace(/\bPh\b/g, 'pH')
export const translateCrudLabel = (value?: string | null, t?: TFunction<'common'>) => {
if (!value) return ''
const rawValue = String(value)
const key = crudLabelKey(rawValue)
const translate = t || i18n.t.bind(i18n)
const deleteRowsMatch = rawValue.match(/^Delete\s+(\d+)\s+(Row|Rows)$/i)
if (deleteRowsMatch) {
return translate('crud.actions.delete_rows', {
count: Number(deleteRowsMatch[1]),
defaultValue: fallbackLabel(rawValue),
})
}
const actionPhraseMatch = fallbackLabel(rawValue).match(/^(View|Edit|New)\s+(.+)$/i)
if (actionPhraseMatch) {
const actionKey = crudLabelKey(actionPhraseMatch[1])
const entityLabel = translateCrudLabel(actionPhraseMatch[2], t)
const actionLabel = translate(`crud.actions.${actionKey}`, {
defaultValue: actionPhraseMatch[1],
})
return `${actionLabel} ${entityLabel}`.trim()
}
const candidates = [
`labels.${key}`,
`crud.actions.${key}`,
`entities.${key}`,
`fields.${key}`,
`enums.${key}`,
]
const match = candidates.find((candidate) => i18n.exists(candidate))
return match ? translate(match) : fallbackLabel(rawValue)
}

View File

@ -1,21 +1,25 @@
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import HttpApi from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
import idCommon from '../public/locales/id/common.json';
import enGBCommon from '../public/locales/en-GB/common.json';
i18n
.use(HttpApi)
.use(LanguageDetector)
.use(initReactI18next)
.init({
fallbackLng: 'en',
detection: {
order: ['localStorage', 'navigator'],
lookupLocalStorage: 'app_lang_',
caches: ['localStorage'],
},
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json',
lng: 'id',
fallbackLng: 'id',
supportedLngs: ['id', 'en-GB'],
resources: {
id: {
common: idCommon,
},
'en-GB': {
common: enGBCommon,
},
},
defaultNS: 'common',
ns: ['common'],
interpolation: { escapeValue: false },
});
});
export default i18n;

View File

@ -12,7 +12,6 @@ import { useRouter } from 'next/router';
import ErrorBoundary from "../components/ErrorBoundary";
import DevModeBadge from '../components/DevModeBadge';
import 'intro.js/introjs.css';
import { appWithTranslation } from 'next-i18next';
import '../i18n';
import IntroGuide from '../components/IntroGuide';
import { appSteps, loginSteps, usersSteps, rolesSteps } from '../stores/introSteps';
@ -198,4 +197,4 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
)
}
export default appWithTranslation(MyApp);
export default MyApp;

View File

@ -19,6 +19,8 @@ import BaseIcon from '../components/BaseIcon'
import { getPageTitle } from '../config'
import { hasPermission } from '../helpers/userPermissions'
import { useAppSelector } from '../stores/hooks'
import { useTranslation } from 'react-i18next'
import { translateCrudLabel } from '../helpers/translateCrudLabel'
type Option = {
id: string
@ -64,10 +66,10 @@ const nowForDateTimeLocal = () => {
return date.toISOString().slice(0, 16)
}
const formatDateTime = (value?: string) => {
if (!value) return 'Not scheduled'
const formatDateTime = (value?: string, locale = 'id', emptyLabel = 'Not scheduled') => {
if (!value) return emptyLabel
return new Intl.DateTimeFormat('en', {
return new Intl.DateTimeFormat(locale, {
month: 'short',
day: 'numeric',
hour: 'numeric',
@ -75,18 +77,18 @@ const formatDateTime = (value?: string) => {
}).format(new Date(value))
}
const formatQuantity = (value?: string | number) => {
const formatQuantity = (value?: string | number, locale = 'id') => {
if (value === undefined || value === null || value === '') return '0 kg'
return `${Number(value).toLocaleString(undefined, { maximumFractionDigits: 2 })} kg`
return `${Number(value).toLocaleString(locale, { maximumFractionDigits: 2 })} kg`
}
const getRecorder = (log?: FeedLog) => {
const getRecorder = (log?: FeedLog, fallback = 'Team member') => {
const firstName = log?.recorded_by?.firstName || ''
const lastName = log?.recorded_by?.lastName || ''
const fullName = `${firstName} ${lastName}`.trim()
return fullName || log?.recorded_by?.email || 'Team member'
return fullName || log?.recorded_by?.email || fallback
}
const statusStyles = {
@ -96,6 +98,9 @@ const statusStyles = {
}
const FarmOpsPage = () => {
const { t, i18n } = useTranslation('common')
const locale = i18n.resolvedLanguage || i18n.language || 'id'
const tr = (value: string) => translateCrudLabel(value, t)
const { currentUser } = useAppSelector((state) => state.auth)
const [logs, setLogs] = useState<FeedLog[]>([])
const [batchOptions, setBatchOptions] = useState<Option[]>([])
@ -123,7 +128,7 @@ const FarmOpsPage = () => {
return ids.size
}, [logs])
const latestAppetite = logs[0]?.appetite || 'normal'
const latestAppetite = tr(logs[0]?.appetite || 'normal')
const fetchWorkspace = async () => {
setLoading(true)
@ -151,7 +156,7 @@ const FarmOpsPage = () => {
}))
} catch (fetchError) {
console.error('Farm ops workspace failed to load', fetchError)
setError('Could not load the farm operations workspace. Please refresh or check your permissions.')
setError(tr('Could not load the farm operations workspace. Please refresh or check your permissions.'))
} finally {
setLoading(false)
}
@ -171,17 +176,17 @@ const FarmOpsPage = () => {
setMessage('')
if (!form.batch) {
setError('Choose a batch before recording feed.')
setError(tr('Choose a batch before recording feed.'))
return
}
if (!form.fed_at) {
setError('Add the feeding time.')
setError(tr('Add the feeding time.'))
return
}
if (!form.quantity_kg || Number(form.quantity_kg) <= 0) {
setError('Feed quantity must be greater than 0 kg.')
setError(tr('Feed quantity must be greater than 0 kg.'))
return
}
@ -201,12 +206,12 @@ const FarmOpsPage = () => {
},
})
setMessage('Feeding record saved. The latest activity list has been refreshed.')
setMessage(tr('Feeding record saved. The latest activity list has been refreshed.'))
setForm({ ...initialForm, fed_at: nowForDateTimeLocal(), batch: form.batch, feed_product: form.feed_product })
await fetchWorkspace()
} catch (saveError) {
console.error('Farm ops feeding log save failed', saveError)
setError('Could not save the feeding record. Please check the values and try again.')
setError(tr('Could not save the feeding record. Please check the values and try again.'))
} finally {
setSaving(false)
}
@ -215,7 +220,7 @@ const FarmOpsPage = () => {
return (
<>
<Head>
<title>{getPageTitle('Farm Ops Command Center')}</title>
<title>{getPageTitle(tr('Farm Ops Command Center'))}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Farm Ops Command Center" main>
@ -227,27 +232,27 @@ const FarmOpsPage = () => {
<div className="grid gap-6 lg:grid-cols-[1.35fr_0.65fr] lg:items-end">
<div>
<p className="mb-3 inline-flex rounded-full bg-white/15 px-3 py-1 text-xs font-semibold uppercase tracking-[0.24em] text-cyan-100 ring-1 ring-white/20">
Multi-tenant aquaculture workflow
{tr('Multi-tenant aquaculture workflow')}
</p>
<h2 className="max-w-3xl text-3xl font-black tracking-tight md:text-5xl">
Record feed, monitor appetite, and keep the farm team aligned.
{tr('Record feed, monitor appetite, and keep the farm team aligned.')}
</h2>
<p className="mt-4 max-w-2xl text-sm leading-6 text-cyan-50 md:text-base">
A focused daily operations slice built on top of your generated CRUD entities: batches, feed products, and feeding logs.
{tr('A focused daily operations slice built on top of your generated CRUD entities: batches, feed products, and feeding logs.')}
</p>
</div>
<div className="grid grid-cols-3 gap-3 text-center">
<div className="rounded-2xl bg-white/15 p-4 ring-1 ring-white/20">
<div className="text-2xl font-black">{formatQuantity(totalFedToday)}</div>
<div className="mt-1 text-xs text-cyan-100">Fed today</div>
<div className="text-2xl font-black">{formatQuantity(totalFedToday, locale)}</div>
<div className="mt-1 text-xs text-cyan-100">{tr('Fed today')}</div>
</div>
<div className="rounded-2xl bg-white/15 p-4 ring-1 ring-white/20">
<div className="text-2xl font-black">{activeBatchCount}</div>
<div className="mt-1 text-xs text-cyan-100">Active batches</div>
<div className="mt-1 text-xs text-cyan-100">{tr('Active batches')}</div>
</div>
<div className="rounded-2xl bg-white/15 p-4 ring-1 ring-white/20">
<div className="text-2xl font-black capitalize">{latestAppetite}</div>
<div className="mt-1 text-xs text-cyan-100">Latest appetite</div>
<div className="mt-1 text-xs text-cyan-100">{tr('Latest appetite')}</div>
</div>
</div>
</div>
@ -268,9 +273,9 @@ const FarmOpsPage = () => {
<CardBox className="border-0 shadow-lg ring-1 ring-slate-200/80 dark:ring-dark-700">
<div className="mb-5 flex items-start justify-between gap-4">
<div>
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-teal-600">Quick input</p>
<h3 className="mt-1 text-2xl font-bold text-slate-900 dark:text-white">Log a feeding</h3>
<p className="mt-1 text-sm text-slate-500">Capture the minimum operational data and confirm it immediately.</p>
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-teal-600">{tr('Quick input')}</p>
<h3 className="mt-1 text-2xl font-bold text-slate-900 dark:text-white">{tr('Log a feeding')}</h3>
<p className="mt-1 text-sm text-slate-500">{tr('Capture the minimum operational data and confirm it immediately.')}</p>
</div>
<span className="rounded-2xl bg-teal-50 p-3 text-teal-700 ring-1 ring-teal-100">
<BaseIcon path={mdiFoodDrumstick} size="24" />
@ -278,17 +283,17 @@ const FarmOpsPage = () => {
</div>
{loading ? (
<div className="rounded-2xl bg-slate-50 p-6 text-sm text-slate-500">Loading batches and feed products</div>
<div className="rounded-2xl bg-slate-50 p-6 text-sm text-slate-500">{tr('Loading batches and feed products')}</div>
) : batchOptions.length === 0 ? (
<div className="rounded-2xl border border-dashed border-slate-300 bg-slate-50 p-6 text-sm text-slate-600">
<p className="font-semibold text-slate-900">No batches available yet.</p>
<p className="mt-2">Create a batch first, then return here to record daily feeding activity.</p>
<p className="font-semibold text-slate-900">{tr('No batches available yet')}</p>
<p className="mt-2">{tr('Create a batch first, then return here to record daily feeding activity')}</p>
<BaseButton href="/batches/batches-new" label="Create batch" color="info" className="mt-4" />
</div>
) : (
<form className="space-y-4" onSubmit={handleSubmit}>
<label className="block">
<span className="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-200">Batch</span>
<span className="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-200">{tr('Batch')}</span>
<select
className="h-11 w-full rounded-xl border border-slate-300 bg-white px-3 text-sm shadow-sm focus:border-teal-500 focus:outline-none focus:ring-2 focus:ring-teal-500/30 dark:border-dark-700 dark:bg-dark-800"
value={form.batch}
@ -305,7 +310,7 @@ const FarmOpsPage = () => {
<div className="grid gap-4 md:grid-cols-2">
<label className="block">
<span className="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-200">Fed at</span>
<span className="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-200">{tr('Fed at')}</span>
<input
className="h-11 w-full rounded-xl border border-slate-300 bg-white px-3 text-sm shadow-sm focus:border-teal-500 focus:outline-none focus:ring-2 focus:ring-teal-500/30 dark:border-dark-700 dark:bg-dark-800"
type="datetime-local"
@ -315,7 +320,7 @@ const FarmOpsPage = () => {
/>
</label>
<label className="block">
<span className="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-200">Quantity (kg)</span>
<span className="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-200">{tr('QuantityKg')}</span>
<input
className="h-11 w-full rounded-xl border border-slate-300 bg-white px-3 text-sm shadow-sm focus:border-teal-500 focus:outline-none focus:ring-2 focus:ring-teal-500/30 dark:border-dark-700 dark:bg-dark-800"
min="0"
@ -330,14 +335,14 @@ const FarmOpsPage = () => {
<div className="grid gap-4 md:grid-cols-3">
<label className="block md:col-span-1">
<span className="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-200">Feed product</span>
<span className="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-200">{tr('Feed product')}</span>
<select
className="h-11 w-full rounded-xl border border-slate-300 bg-white px-3 text-sm shadow-sm focus:border-teal-500 focus:outline-none focus:ring-2 focus:ring-teal-500/30 dark:border-dark-700 dark:bg-dark-800"
value={form.feed_product}
onChange={(event) => handleChange('feed_product', event.target.value)}
disabled={!canCreateFeedLog || saving}
>
<option value="">Not specified</option>
<option value="">{tr('Not specified')}</option>
{feedOptions.map((feed) => (
<option key={feed.id} value={feed.id}>
{feed.label}
@ -346,40 +351,40 @@ const FarmOpsPage = () => {
</select>
</label>
<label className="block md:col-span-1">
<span className="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-200">Method</span>
<span className="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-200">{tr('Method')}</span>
<select
className="h-11 w-full rounded-xl border border-slate-300 bg-white px-3 text-sm shadow-sm focus:border-teal-500 focus:outline-none focus:ring-2 focus:ring-teal-500/30 dark:border-dark-700 dark:bg-dark-800"
value={form.feeding_method}
onChange={(event) => handleChange('feeding_method', event.target.value)}
disabled={!canCreateFeedLog || saving}
>
<option value="manual">Manual</option>
<option value="auto_feeder">Auto feeder</option>
<option value="broadcast">Broadcast</option>
<option value="tray">Tray</option>
<option value="other">Other</option>
<option value="manual">{tr('manual')}</option>
<option value="auto_feeder">{tr('auto_feeder')}</option>
<option value="broadcast">{tr('broadcast')}</option>
<option value="tray">{tr('tray')}</option>
<option value="other">{tr('other')}</option>
</select>
</label>
<label className="block md:col-span-1">
<span className="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-200">Appetite</span>
<span className="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-200">{tr('Appetite')}</span>
<select
className="h-11 w-full rounded-xl border border-slate-300 bg-white px-3 text-sm shadow-sm focus:border-teal-500 focus:outline-none focus:ring-2 focus:ring-teal-500/30 dark:border-dark-700 dark:bg-dark-800"
value={form.appetite}
onChange={(event) => handleChange('appetite', event.target.value)}
disabled={!canCreateFeedLog || saving}
>
<option value="low">Low</option>
<option value="normal">Normal</option>
<option value="high">High</option>
<option value="low">{tr('low')}</option>
<option value="normal">{tr('normal')}</option>
<option value="high">{tr('high')}</option>
</select>
</label>
</div>
<label className="block">
<span className="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-200">Notes</span>
<span className="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-200">{tr('Notes')}</span>
<textarea
className="min-h-[104px] w-full rounded-xl border border-slate-300 bg-white px-3 py-3 text-sm shadow-sm focus:border-teal-500 focus:outline-none focus:ring-2 focus:ring-teal-500/30 dark:border-dark-700 dark:bg-dark-800"
placeholder="Optional observation, e.g. fish surfaced quickly, mild leftovers, weather change…"
placeholder={tr('Optional observation, e.g. fish surfaced quickly, mild leftovers, weather change')}
value={form.notes}
onChange={(event) => handleChange('notes', event.target.value)}
disabled={!canCreateFeedLog || saving}
@ -388,7 +393,7 @@ const FarmOpsPage = () => {
{!canCreateFeedLog && (
<p className="rounded-xl bg-amber-50 px-3 py-2 text-sm text-amber-800 ring-1 ring-amber-200">
Your role can view feeding logs but cannot create new records.
{tr('Your role can view feeding logs but cannot create new records')}
</p>
)}
@ -396,7 +401,7 @@ const FarmOpsPage = () => {
<BaseButton
color="info"
disabled={!canCreateFeedLog || saving}
label={saving ? 'Saving' : 'Save feeding record'}
label={saving ? 'Saving' : 'Save feeding record'}
type="submit"
/>
<BaseButton color="whiteDark" href="/feeding_logs/feeding_logs-new" label="Advanced form" />
@ -409,19 +414,19 @@ const FarmOpsPage = () => {
<CardBox className="border-0 shadow-lg ring-1 ring-slate-200/80 dark:ring-dark-700">
<div className="mb-5 flex items-center justify-between gap-3">
<div>
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-sky-600">Activity stream</p>
<h3 className="mt-1 text-2xl font-bold text-slate-900 dark:text-white">Latest feeding logs</h3>
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-sky-600">{tr('Activity stream')}</p>
<h3 className="mt-1 text-2xl font-bold text-slate-900 dark:text-white">{tr('Latest feeding logs')}</h3>
</div>
<BaseButton color="whiteDark" label="Refresh" onClick={fetchWorkspace} small />
</div>
{loading ? (
<div className="rounded-2xl bg-slate-50 p-6 text-sm text-slate-500">Loading latest records</div>
<div className="rounded-2xl bg-slate-50 p-6 text-sm text-slate-500">{tr('Loading latest records')}</div>
) : logs.length === 0 ? (
<div className="rounded-2xl border border-dashed border-slate-300 bg-slate-50 p-8 text-center">
<BaseIcon path={mdiClipboardTextClock} size="40" className="mx-auto text-slate-400" />
<p className="mt-3 font-semibold text-slate-900">No feeding logs yet</p>
<p className="mt-1 text-sm text-slate-500">Use the quick input form to create the first daily operation record.</p>
<p className="mt-3 font-semibold text-slate-900">{tr('No feeding logs yet')}</p>
<p className="mt-1 text-sm text-slate-500">{tr('Use the quick input form to create the first daily operation record')}</p>
</div>
) : (
<div className="space-y-3">
@ -440,21 +445,21 @@ const FarmOpsPage = () => {
>
<div className="flex items-start justify-between gap-3">
<div>
<p className="font-bold text-slate-900 dark:text-white">{log.batch?.batch_code || 'Unassigned batch'}</p>
<p className="mt-1 text-sm text-slate-500">{formatDateTime(log.fed_at)} {log.feeding_method || 'manual'}</p>
<p className="font-bold text-slate-900 dark:text-white">{log.batch?.batch_code || tr('Unassigned batch')}</p>
<p className="mt-1 text-sm text-slate-500">{formatDateTime(log.fed_at, locale, tr('Not scheduled'))} {tr(log.feeding_method || 'manual')}</p>
</div>
<span className={`rounded-full px-2.5 py-1 text-xs font-semibold capitalize ring-1 ${appetiteClass}`}>
{log.appetite || 'normal'}
{tr(log.appetite || 'normal')}
</span>
</div>
<div className="mt-4 grid grid-cols-2 gap-3 text-sm">
<div className="rounded-xl bg-slate-50 p-3 dark:bg-dark-800">
<span className="block text-xs uppercase tracking-wide text-slate-400">Quantity</span>
<strong>{formatQuantity(log.quantity_kg)}</strong>
<span className="block text-xs uppercase tracking-wide text-slate-400">{tr('Quantity')}</span>
<strong>{formatQuantity(log.quantity_kg, locale)}</strong>
</div>
<div className="rounded-xl bg-slate-50 p-3 dark:bg-dark-800">
<span className="block text-xs uppercase tracking-wide text-slate-400">Feed</span>
<strong>{log.feed_product?.product_name || 'Not specified'}</strong>
<span className="block text-xs uppercase tracking-wide text-slate-400">{tr('Feed')}</span>
<strong>{log.feed_product?.product_name || tr('Not specified')}</strong>
</div>
</div>
</button>
@ -467,8 +472,8 @@ const FarmOpsPage = () => {
<CardBox className="border-0 bg-slate-950 text-white shadow-lg ring-1 ring-slate-800">
<div className="mb-5 flex items-center justify-between gap-3">
<div>
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-cyan-300">Detail</p>
<h3 className="mt-1 text-2xl font-bold">Record snapshot</h3>
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-cyan-300">{tr('Detail')}</p>
<h3 className="mt-1 text-2xl font-bold">{tr('Record snapshot')}</h3>
</div>
<span className="rounded-2xl bg-cyan-400/10 p-3 text-cyan-200 ring-1 ring-cyan-300/20">
<BaseIcon path={mdiWaterPercent} size="24" />
@ -478,26 +483,26 @@ const FarmOpsPage = () => {
{selectedLog ? (
<div className="space-y-4">
<div className="rounded-2xl bg-white/10 p-4 ring-1 ring-white/10">
<p className="text-sm text-slate-300">Batch</p>
<p className="mt-1 text-2xl font-black">{selectedLog.batch?.batch_code || 'Unassigned batch'}</p>
<p className="text-sm text-slate-300">{tr('Batch')}</p>
<p className="mt-1 text-2xl font-black">{selectedLog.batch?.batch_code || tr('Unassigned batch')}</p>
</div>
<div className="grid grid-cols-2 gap-3">
<div className="rounded-2xl bg-white/10 p-4 ring-1 ring-white/10">
<p className="text-xs uppercase tracking-wide text-slate-400">Quantity</p>
<p className="mt-1 text-xl font-bold">{formatQuantity(selectedLog.quantity_kg)}</p>
<p className="text-xs uppercase tracking-wide text-slate-400">{tr('Quantity')}</p>
<p className="mt-1 text-xl font-bold">{formatQuantity(selectedLog.quantity_kg, locale)}</p>
</div>
<div className="rounded-2xl bg-white/10 p-4 ring-1 ring-white/10">
<p className="text-xs uppercase tracking-wide text-slate-400">Appetite</p>
<p className="mt-1 text-xl font-bold capitalize">{selectedLog.appetite || 'normal'}</p>
<p className="text-xs uppercase tracking-wide text-slate-400">{tr('Appetite')}</p>
<p className="mt-1 text-xl font-bold capitalize">{tr(selectedLog.appetite || 'normal')}</p>
</div>
</div>
<div className="rounded-2xl bg-white/10 p-4 ring-1 ring-white/10">
<p className="text-xs uppercase tracking-wide text-slate-400">Recorded</p>
<p className="mt-1 font-semibold">{formatDateTime(selectedLog.fed_at)} by {getRecorder(selectedLog)}</p>
<p className="text-xs uppercase tracking-wide text-slate-400">{tr('Recorded')}</p>
<p className="mt-1 font-semibold">{formatDateTime(selectedLog.fed_at, locale, tr('Not scheduled'))} {tr('by')} {getRecorder(selectedLog, tr('Team member'))}</p>
</div>
<div className="rounded-2xl bg-white/10 p-4 ring-1 ring-white/10">
<p className="text-xs uppercase tracking-wide text-slate-400">Notes</p>
<p className="mt-2 text-sm leading-6 text-slate-200">{selectedLog.notes || 'No notes added for this operation.'}</p>
<p className="text-xs uppercase tracking-wide text-slate-400">{tr('Notes')}</p>
<p className="mt-2 text-sm leading-6 text-slate-200">{selectedLog.notes || tr('No notes added for this operation')}</p>
</div>
<div className="flex flex-wrap gap-3 pt-2">
<BaseButton color="info" href={`/feeding_logs/${selectedLog.id}`} label="Open detail" />
@ -506,7 +511,7 @@ const FarmOpsPage = () => {
</div>
) : (
<div className="rounded-2xl border border-dashed border-white/20 p-8 text-center text-slate-300">
Select a feeding log to inspect its farm-ready details.
{tr('Select a feeding log to inspect its farm-ready details')}
</div>
)}
</CardBox>
@ -521,8 +526,8 @@ const FarmOpsPage = () => {
].map((item) => (
<div key={item.title} className="rounded-2xl bg-white p-5 shadow-sm ring-1 ring-slate-200 dark:bg-dark-900 dark:ring-dark-700">
<BaseIcon path={item.icon} size="28" className="text-teal-600" />
<h4 className="mt-3 font-bold text-slate-900 dark:text-white">{item.title}</h4>
<p className="mt-1 text-sm leading-6 text-slate-500">{item.text}</p>
<h4 className="mt-3 font-bold text-slate-900 dark:text-white">{tr(item.title)}</h4>
<p className="mt-1 text-sm leading-6 text-slate-500">{tr(item.text)}</p>
</div>
))}
</section>

View File

@ -21,8 +21,10 @@ import { useAppDispatch, useAppSelector } from '../stores/hooks';
import Link from 'next/link';
import {toast, ToastContainer} from "react-toastify";
import { getPexelsImage, getPexelsVideo } from '../helpers/pexels'
import { useTranslation } from 'react-i18next'
export default function Login() {
const { t } = useTranslation('common')
const router = useRouter();
const dispatch = useAppDispatch();
const textColor = useAppSelector((state) => state.style.linkColor);
@ -44,7 +46,7 @@ export default function Login() {
password: '60277297',
remember: true })
const title = 'Aquaculture Ops CRUD'
const title = t('app.title')
// Fetch Pexels image/video
useEffect( () => {
@ -109,8 +111,7 @@ export default function Login() {
backgroundRepeat: 'no-repeat',
}}>
<div className="flex justify-center w-full bg-blue-300/20">
<a className="text-[8px]" href={image?.photographer_url} target="_blank" rel="noreferrer">Photo
by {image?.photographer} on Pexels</a>
<a className="text-[8px]" href={image?.photographer_url} target="_blank" rel="noreferrer">{t('pages.login.pexels.photoCredit', { photographer: image?.photographer })}</a>
</div>
</div>
)
@ -126,7 +127,7 @@ export default function Login() {
muted
>
<source src={video.video_files[0]?.link} type='video/mp4'/>
Your browser does not support the video tag.
{t('pages.login.pexels.videoUnsupported')}
</video>
<div className='flex justify-center w-full bg-blue-300/20 z-10'>
<a
@ -135,7 +136,7 @@ export default function Login() {
target='_blank'
rel='noreferrer'
>
Video by {video.user.name} on Pexels
{t('pages.login.pexels.videoCredit', { name: video.user.name })}
</a>
</div>
</div>)
@ -154,7 +155,7 @@ export default function Login() {
backgroundRepeat: 'no-repeat',
} : {}}>
<Head>
<title>{getPageTitle('Login')}</title>
<title>{getPageTitle(t('pages.login.pageTitle'))}</title>
</Head>
<SectionFullScreen bg='violet'>
@ -239,7 +240,7 @@ export default function Login() {
</FormCheckRadio>
<Link className={`${textColor} text-blue-600`} href={'/forgot'}>
Forgot password?
{t('pages.login.form.forgotPassword')}
</Link>
</div>
@ -256,9 +257,9 @@ export default function Login() {
</BaseButtons>
<br />
<p className={'text-center'}>
Dont have an account yet?{' '}
{t('pages.login.form.noAccountYet')}{' '}
<Link className={`${textColor}`} href={'/register'}>
New Account
{t('pages.login.form.newAccount')}
</Link>
</p>
</Form>
@ -268,9 +269,9 @@ export default function Login() {
</div>
</SectionFullScreen>
<div className='bg-black text-white flex flex-col text-center justify-center md:flex-row'>
<p className='py-6 text-sm'>© 2026 <span>{title}</span>. © All rights reserved</p>
<p className='py-6 text-sm'>{t('pages.login.footer.copyright', { year: 2026, title })}</p>
<Link className='py-6 ml-4 text-sm' href='/privacy-policy/'>
Privacy Policy
{t('pages.login.footer.privacy')}
</Link>
</div>
<ToastContainer />