39038-vm/includes/app.php
2026-03-14 15:16:48 +00:00

1359 lines
58 KiB
PHP

<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
require_once __DIR__ . '/../db/config.php';
// Basic localization setup
$lang = $_GET['lang'] ?? $_SESSION['lang'] ?? 'en';
if (!in_array($lang, ['en', 'ar'])) $lang = 'en';
$_SESSION['lang'] = $lang;
$translations = [
'en' => [
'nav_home' => 'Home',
'nav_dashboard' => 'Dashboard',
'nav_login' => 'Login',
'nav_logout' => 'Logout',
'nav_register' => 'Register',
'welcome' => 'Welcome to Logistics Platform',
'hero_title' => 'Fast & Reliable Logistics',
'hero_subtitle' => 'Connecting shippers and truck owners seamlessly.',
'track_shipment' => 'Track Shipment',
'enter_tracking' => 'Enter Tracking ID',
'footer_rights' => 'All rights reserved.',
'login_title' => 'Login',
'email_label' => 'Email Address',
'password_label' => 'Password',
'login_btn' => 'Sign In',
'register_link' => "Don't have an account? Register here.",
'dashboard_title' => 'Dashboard',
'post_shipment' => 'Post New Shipment',
'recent_shipments' => 'Recent Shipments',
'status' => 'Status',
'actions' => 'Actions',
'view_details' => 'View Details',
'edit' => 'Edit',
'delete' => 'Delete',
'profile' => 'Profile',
'settings' => 'Settings',
'my_shipments' => 'My Shipments',
'find_trucks' => 'Find Trucks',
'contact_us' => 'Contact Us',
'about_us' => 'About Us',
'privacy_policy' => 'Privacy Policy',
'terms_conditions' => 'Terms & Conditions',
'admin_panel' => 'Admin Panel',
'users' => 'Users',
'reports' => 'Reports',
'logout_confirm' => 'Are you sure you want to logout?',
'yes' => 'Yes',
'no' => 'No',
'cancel' => 'Cancel',
'save' => 'Save',
'update' => 'Update',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
'id' => 'ID',
'name' => 'Name',
'role' => 'Role',
'approved' => 'Approved',
'pending' => 'Pending',
'rejected' => 'Rejected',
'active' => 'Active',
'inactive' => 'Inactive',
'success_message' => 'Operation successful.',
'error_message' => 'An error occurred. Please try again.',
'manage_shipments' => 'Manage Shipments',
'manage_users' => 'Manage Users',
'manage_trucks' => 'Manage Trucks',
'truck_owner' => 'Truck Owner',
'shipper' => 'Shipper',
'admin' => 'Admin',
'notifications' => 'Notifications',
'mark_read' => 'Mark as Read',
'view_all' => 'View All',
'new_shipment_alert' => 'New shipment posted!',
'shipment_update_alert' => 'Shipment status updated.',
'offer_received' => 'New offer received.',
'offer_accepted' => 'Offer accepted.',
'offer_rejected' => 'Offer rejected.',
'payment_received' => 'Payment received.',
'payment_pending' => 'Payment pending.',
'payment_failed' => 'Payment failed.',
'search' => 'Search...',
'filter' => 'Filter',
'sort_by' => 'Sort By',
'date' => 'Date',
'price' => 'Price',
'loading' => 'Loading...',
'no_data' => 'No data available.',
'unauthorized' => 'Unauthorized access.',
'page_not_found' => 'Page not found.',
'server_error' => 'Internal Server Error.',
'go_back' => 'Go Back',
'home_btn' => 'Go Home',
'reset_password' => 'Reset Password',
'forgot_password' => 'Forgot Password?',
'send_link' => 'Send Reset Link',
'password_reset_sent' => 'Password reset link sent to your email.',
'password_changed' => 'Password changed successfully.',
'confirm_password' => 'Confirm Password',
'current_password' => 'Current Password',
'new_password' => 'New Password',
'change_password' => 'Change Password',
'personal_info' => 'Personal Information',
'company_info' => 'Company Information',
'truck_info' => 'Truck Information',
'documents' => 'Documents',
'upload_doc' => 'Upload Document',
'download' => 'Download',
'file_too_large' => 'File is too large.',
'invalid_file_type' => 'Invalid file type.',
'upload_success' => 'File uploaded successfully.',
'delete_confirm' => 'Are you sure you want to delete this?',
'deleted_success' => 'Deleted successfully.',
'feature_not_available' => 'Feature not available yet.',
'coming_soon' => 'Coming Soon',
'contact_support' => 'Contact Support',
'faq' => 'FAQ',
'language' => 'Language',
'english' => 'English',
'arabic' => 'Arabic',
'switch_lang' => 'Switch Language',
'dark_mode' => 'Dark Mode',
'light_mode' => 'Light Mode',
'notifications_settings' => 'Notification Settings',
'email_notif' => 'Email Notifications',
'sms_notif' => 'SMS Notifications',
'push_notif' => 'Push Notifications',
'enable' => 'Enable',
'disable' => 'Disable',
'account_settings' => 'Account Settings',
'delete_account' => 'Delete Account',
'delete_account_warning' => 'This action is irreversible.',
'feedback' => 'Feedback',
'rate_us' => 'Rate Us',
'copyright' => 'Copyright © ' . date('Y'),
'powered_by' => 'Powered by Logistics Platform',
'terms_of_service' => 'Terms of Service',
'cookie_policy' => 'Cookie Policy',
'careers' => 'Careers',
'blog' => 'Blog',
'partners' => 'Partners',
'help_center' => 'Help Center',
'how_it_works' => 'How It Works',
'pricing' => 'Pricing',
'get_started' => 'Get Started',
'learn_more' => 'Learn More',
'demo' => 'Request Demo',
'subscribe' => 'Subscribe',
'newsletter' => 'Newsletter',
'enter_email' => 'Enter your email',
'invalid_email' => 'Invalid email address.',
'message_sent' => 'Message sent successfully.',
'thank_you' => 'Thank you!',
'404_msg' => 'The page you are looking for does not exist.',
'500_msg' => 'Something went wrong on our end.',
'maintenance_msg' => 'System is under maintenance. Please try again later.',
'session_expired' => 'Session expired. Please login again.',
'login_required' => 'Login required to access this page.',
'access_denied' => 'Access denied.',
'csrf_error' => 'Invalid security token. Please refresh and try again.',
'validation_error' => 'Please correct the errors below.',
'required_field' => 'This field is required.',
'min_length' => 'Minimum length is %s characters.',
'max_length' => 'Maximum length is %s characters.',
'numeric_only' => 'Only numbers are allowed.',
'alpha_only' => 'Only letters are allowed.',
'alphanumeric_only' => 'Only letters and numbers are allowed.',
'email_exists' => 'Email already exists.',
'username_exists' => 'Username already exists.',
'password_mismatch' => 'Passwords do not match.',
'invalid_credentials' => 'Invalid email or password.',
'account_locked' => 'Account is locked. Please contact support.',
'too_many_attempts' => 'Too many login attempts. Please try again later.',
'verify_email' => 'Please verify your email address.',
'email_verified' => 'Email verified successfully.',
'verification_link_sent' => 'Verification link sent.',
'invalid_token' => 'Invalid or expired token.',
'token_expired' => 'Token has expired.',
'resend_verification' => 'Resend Verification Email',
'dashboard_overview' => 'Overview',
'total_shipments' => 'Total Shipments',
'active_trucks' => 'Active Trucks',
'pending_approvals' => 'Pending Approvals',
'revenue' => 'Revenue',
'recent_activity' => 'Recent Activity',
'view_all_shipments' => 'View All Shipments',
'view_all_users' => 'View All Users',
'add_new' => 'Add New',
'export' => 'Export',
'import' => 'Import',
'print' => 'Print',
'copy' => 'Copy',
'csv' => 'CSV',
'excel' => 'Excel',
'pdf' => 'PDF',
'search_results' => 'Search Results',
'no_results' => 'No results found.',
'showing_entries' => 'Showing %s to %s of %s entries',
'next_page' => 'Next',
'prev_page' => 'Previous',
'first_page' => 'First',
'last_page' => 'Last',
'apply' => 'Apply',
'clear' => 'Clear',
'filter_by' => 'Filter by',
'status_all' => 'All Statuses',
'role_all' => 'All Roles',
'date_range' => 'Date Range',
'today' => 'Today',
'yesterday' => 'Yesterday',
'last_7_days' => 'Last 7 Days',
'last_30_days' => 'Last 30 Days',
'this_month' => 'This Month',
'last_month' => 'Last Month',
'custom_range' => 'Custom Range',
'start_date' => 'Start Date',
'end_date' => 'End Date',
'to' => 'to',
'from' => 'From',
'subject' => 'Subject',
'message' => 'Message',
'send_message' => 'Send Message',
'reply' => 'Reply',
'forward' => 'Forward',
'mark_unread' => 'Mark as Unread',
'delete_selected' => 'Delete Selected',
'archive' => 'Archive',
'spam' => 'Spam',
'trash' => 'Trash',
'compose' => 'Compose',
'inbox' => 'Inbox',
'sent' => 'Sent',
'drafts' => 'Drafts',
'important' => 'Important',
'starred' => 'Starred',
'labels' => 'Labels',
'add_label' => 'Add Label',
'remove_label' => 'Remove Label',
'color' => 'Color',
'description' => 'Description',
'edit_profile' => 'Edit Profile',
'change_avatar' => 'Change Avatar',
'bio' => 'Bio',
'location' => 'Location',
'website' => 'Website',
'social_links' => 'Social Links',
'facebook' => 'Facebook',
'twitter' => 'Twitter',
'linkedin' => 'LinkedIn',
'instagram' => 'Instagram',
'youtube' => 'YouTube',
'github' => 'GitHub',
'save_changes' => 'Save Changes',
'discard_changes' => 'Discard Changes',
'unsaved_changes' => 'You have unsaved changes.',
'stay_on_page' => 'Stay on Page',
'leave_page' => 'Leave Page',
'confirm_action' => 'Confirm Action',
'action_cannot_undone' => 'This action cannot be undone.',
'type_confirm' => 'Type "CONFIRM" to proceed.',
'notifications_permission' => 'Allow notifications?',
'allow' => 'Allow',
'deny' => 'Deny',
'location_permission' => 'Allow location access?',
'camera_permission' => 'Allow camera access?',
'mic_permission' => 'Allow microphone access?',
'cookie_consent' => 'We use cookies to improve your experience.',
'accept_all' => 'Accept All',
'reject_all' => 'Reject All',
'customize' => 'Customize',
'preferences' => 'Preferences',
'general' => 'General',
'security' => 'Security',
'billing' => 'Billing',
'integrations' => 'Integrations',
'api_keys' => 'API Keys',
'generate_key' => 'Generate Key',
'revoke_key' => 'Revoke Key',
'webhook_url' => 'Webhook URL',
'secret_key' => 'Secret Key',
'documentation' => 'Documentation',
'support_ticket' => 'Support Ticket',
'open_ticket' => 'Open Ticket',
'ticket_id' => 'Ticket ID',
'priority' => 'Priority',
'low' => 'Low',
'medium' => 'Medium',
'high' => 'High',
'critical' => 'Critical',
'status_open' => 'Open',
'status_closed' => 'Closed',
'status_pending' => 'Pending',
'last_reply' => 'Last Reply',
'assigned_to' => 'Assigned To',
'created_by' => 'Created By',
'resolved_at' => 'Resolved At',
'closed_at' => 'Closed At',
'reopen' => 'Reopen',
'close' => 'Close',
'add_comment' => 'Add Comment',
'attach_file' => 'Attach File',
'max_size' => 'Max size: %s',
'allowed_types' => 'Allowed types: %s',
'drag_drop' => 'Drag and drop files here',
'browse' => 'Browse',
'uploading' => 'Uploading...',
'completed' => 'Completed',
'failed' => 'Failed',
'retry' => 'Retry',
'cancel_upload' => 'Cancel Upload',
'remove' => 'Remove',
'preview' => 'Preview',
'zoom_in' => 'Zoom In',
'zoom_out' => 'Zoom Out',
'rotate' => 'Rotate',
'fullscreen' => 'Fullscreen',
'print_preview' => 'Print Preview',
'download_pdf' => 'Download PDF',
'share' => 'Share',
'copy_link' => 'Copy Link',
'email_link' => 'Email Link',
'embed' => 'Embed',
'qrcode' => 'QR Code',
'scan_qrcode' => 'Scan QR Code',
'auth_code' => 'Authentication Code',
'2fa' => 'Two-Factor Authentication',
'setup_2fa' => 'Setup 2FA',
'disable_2fa' => 'Disable 2FA',
'enter_code' => 'Enter Code',
'backup_codes' => 'Backup Codes',
'generate_codes' => 'Generate Codes',
'print_codes' => 'Print Codes',
'recovery_email' => 'Recovery Email',
'verify_phone' => 'Verify Phone Number',
'sms_code' => 'SMS Code',
'resend_code' => 'Resend Code',
'code_sent' => 'Code sent.',
'phone_verified' => 'Phone verified.',
'country_code' => 'Country Code',
'phone_number' => 'Phone Number',
'address_line1' => 'Address Line 1',
'address_line2' => 'Address Line 2',
'city_state' => 'City/State',
'postal_code' => 'Postal Code',
'country_region' => 'Country/Region',
'billing_address' => 'Billing Address',
'shipping_address' => 'Shipping Address',
'same_as_billing' => 'Same as billing address',
'add_address' => 'Add Address',
'edit_address' => 'Edit Address',
'delete_address' => 'Delete Address',
'default_address' => 'Default Address',
'set_default' => 'Set as Default',
'payment_method' => 'Payment Method',
'credit_card' => 'Credit Card',
'paypal' => 'PayPal',
'bank_transfer' => 'Bank Transfer',
'cash_on_delivery' => 'Cash on Delivery',
'card_number' => 'Card Number',
'expiry_date' => 'Expiry Date',
'cvv' => 'CVV',
'card_holder' => 'Card Holder Name',
'save_card' => 'Save card for future use',
'transaction_history' => 'Transaction History',
'invoice' => 'Invoice',
'receipt' => 'Receipt',
'amount' => 'Amount',
'currency' => 'Currency',
'tax' => 'Tax',
'discount' => 'Discount',
'subtotal' => 'Subtotal',
'total' => 'Total',
'promo_code' => 'Promo Code',
'apply_code' => 'Apply Code',
'invalid_code' => 'Invalid promo code.',
'checkout' => 'Checkout',
'place_order' => 'Place Order',
'order_summary' => 'Order Summary',
'cart' => 'Cart',
'empty_cart' => 'Your cart is empty.',
'continue_shopping' => 'Continue Shopping',
'add_to_cart' => 'Add to Cart',
'remove_from_cart' => 'Remove from Cart',
'update_cart' => 'Update Cart',
'quantity' => 'Quantity',
'unit_price' => 'Unit Price',
'total_price' => 'Total Price',
'product_details' => 'Product Details',
'specifications' => 'Specifications',
'reviews' => 'Reviews',
'write_review' => 'Write a Review',
'rating' => 'Rating',
'stars' => 'Stars',
'related_products' => 'Related Products',
'wishlist' => 'Wishlist',
'add_to_wishlist' => 'Add to Wishlist',
'remove_from_wishlist' => 'Remove from Wishlist',
'compare' => 'Compare',
'add_to_compare' => 'Add to Compare',
'clear_compare' => 'Clear Compare',
'compare_products' => 'Compare Products',
'category' => 'Category',
'brand' => 'Brand',
'model' => 'Model',
'sku' => 'SKU',
'availability' => 'Availability',
'in_stock' => 'In Stock',
'out_of_stock' => 'Out of Stock',
'pre_order' => 'Pre-Order',
'limited_stock' => 'Limited Stock',
'new_arrival' => 'New Arrival',
'best_seller' => 'Best Seller',
'featured' => 'Featured',
'sale' => 'Sale',
'hot' => 'Hot',
'deal_of_day' => 'Deal of the Day',
'timer_end' => 'Offer ends in',
'days' => 'Days',
'hours' => 'Hours',
'minutes' => 'Minutes',
'seconds' => 'Seconds',
'subscribe_text' => 'Subscribe to our newsletter for latest updates.',
'follow_us' => 'Follow Us',
'app_download' => 'Download App',
'app_store' => 'App Store',
'google_play' => 'Google Play',
'secure_payment' => 'Secure Payment',
'fast_delivery' => 'Fast Delivery',
'24_7_support' => '24/7 Support',
'money_back' => 'Money Back Guarantee',
'easy_returns' => 'Easy Returns',
'gift_cards' => 'Gift Cards',
'track_order' => 'Track Order',
'order_id' => 'Order ID',
'shipping_info' => 'Shipping Info',
'billing_info' => 'Billing Info',
'order_status' => 'Order Status',
'processing' => 'Processing',
'shipped' => 'Shipped',
'delivered' => 'Delivered',
'cancelled' => 'Cancelled',
'returned' => 'Returned',
'refunded' => 'Refunded',
'return_policy' => 'Return Policy',
'shipping_policy' => 'Shipping Policy',
'sitemap' => 'Sitemap',
'accessibility' => 'Accessibility',
'accessibility_statement' => 'Accessibility Statement',
'skip_to_content' => 'Skip to Content',
'high_contrast' => 'High Contrast',
'text_size' => 'Text Size',
'increase' => 'Increase',
'decrease' => 'Decrease',
'reset' => 'Reset',
'print_page' => 'Print Page',
'read_aloud' => 'Read Aloud',
'stop' => 'Stop',
'pause' => 'Pause',
'resume' => 'Resume',
'mute' => 'Mute',
'unmute' => 'Unmute',
'volume' => 'Volume',
'speed' => 'Speed',
'normal' => 'Normal',
'fast' => 'Fast',
'slow' => 'Slow',
'captions' => 'Captions',
'subtitles' => 'Subtitles',
'audio_desc' => 'Audio Description',
'keyboard_shortcuts' => 'Keyboard Shortcuts',
'help' => 'Help',
'close_menu' => 'Close Menu',
'open_menu' => 'Open Menu',
'menu' => 'Menu',
'navigation' => 'Navigation',
'breadcrumbs' => 'Breadcrumbs',
'pagination' => 'Pagination',
'modal' => 'Modal',
'dialog' => 'Dialog',
'tooltip' => 'Tooltip',
'popover' => 'Popover',
'alert' => 'Alert',
'notification' => 'Notification',
'toast' => 'Toast',
'banner' => 'Banner',
'sidebar' => 'Sidebar',
'footer' => 'Footer',
'header' => 'Header',
'main_content' => 'Main Content',
'admin_dashboard_title' => 'Admin Dashboard',
'wablas_server_url' => 'Wablas Server URL',
'wablas_api_token' => 'Wablas API Token',
'reg_title' => 'Create Account',
'reg_subtitle' => 'Sign up to get started',
'reg_success_pending' => 'Registration successful. Your account is pending approval.',
'reg_success' => 'Registration successful. You can now login.',
'role' => 'Role',
'shipper' => 'Shipper',
'truck_owner' => 'Truck Owner',
'email' => 'Email',
'password' => 'Password',
'phone' => 'Phone',
'country' => 'Country',
'select_country' => 'Select Country',
'city' => 'City',
'select_city' => 'Select City',
'address' => 'Address',
'shipper_details' => 'Shipper Details',
'company_name' => 'Company Name',
'truck_details' => 'Truck Details',
'truck_type' => 'Truck Type',
'load_capacity' => 'Load Capacity (Tons)',
'plate_no' => 'Plate Number',
'bank_account' => 'Bank Account',
'bank_name' => 'Bank Name',
'bank_branch' => 'Branch Name',
'id_card_front' => 'ID Card (Front)',
'id_card_back' => 'ID Card (Back)',
'truck_reg_front' => 'Truck Registration (Front)',
'truck_reg_back' => 'Truck Registration (Back)',
'truck_picture' => 'Truck Picture',
'create_account' => 'Create Account',
'back_to_admin' => 'Back to Admin',
'back_to_home' => 'Back to Home',
'total_revenue' => 'Total Revenue',
'shipments_analytics' => 'Shipments Analytics',
'export_csv' => 'Export CSV',
'status_posted' => 'Posted',
'status_offered' => 'Offered',
'status_confirmed' => 'Confirmed',
'status_in_transit' => 'In Transit',
'status_delivered' => 'Delivered',
'status_pending' => 'Pending',
'status_active' => 'Active',
'status_rejected' => 'Rejected',
'status_unpaid' => 'Unpaid',
'status_paid' => 'Paid',
'payment_thawani' => 'Thawani',
'payment_bank' => 'Bank Transfer',
'currency_symbol' => 'OMR',
'total_shippers' => 'Total Shippers',
'active_shipments' => 'Active Shipments',
'total_truck_owners' => 'Total Truck Owners',
'admin_dashboard' => 'Admin Dashboard',
'overview_performance' => 'Overview & Performance',
'no_shipments' => 'No shipments found.',
'shipment' => 'Shipment',
'route' => 'Route',
'action' => 'Action',
'manage_countries' => 'Manage Countries',
'add_remove_countries' => 'Add/Remove Countries',
'manage_cities' => 'Manage Cities',
'configure_cities' => 'Configure Cities',
'register_user' => 'Register User',
'manually_onboard' => 'Manually Onboard User',
'company_profile' => 'Company Profile',
'update_branding' => 'Update Branding',
'summary_report' => 'Summary Report',
'view_analytics' => 'View Analytics'
],
'ar' => [
'nav_home' => 'الرئيسية',
'nav_dashboard' => 'لوحة التحكم',
'nav_login' => 'تسجيل الدخول',
'nav_logout' => 'تسجيل الخروج',
'nav_register' => 'تسجيل جديد',
'welcome' => 'مرحباً بك في منصة الخدمات اللوجستية',
'hero_title' => 'خدمات لوجستية سريعة وموثوقة',
'hero_subtitle' => 'نربط الشاحنين وأصحاب الشاحنات بسلاسة.',
'track_shipment' => 'تتبع الشحنة',
'enter_tracking' => 'أدخل رقم التتبع',
'footer_rights' => 'جميع الحقوق محفوظة.',
'login_title' => 'تسجيل الدخول',
'email_label' => 'البريد الإلكتروني',
'password_label' => 'كلمة المرور',
'login_btn' => 'دخول',
'register_link' => 'ليس لديك حساب؟ سجل هنا.',
'dashboard_title' => 'لوحة التحكم',
'post_shipment' => 'نشر شحنة جديدة',
'recent_shipments' => 'الشحنات الأخيرة',
'status' => 'الحالة',
'actions' => 'الإجراءات',
'view_details' => 'عرض التفاصيل',
'edit' => 'تعديل',
'delete' => 'حذف',
'profile' => 'الملف الشخصي',
'settings' => 'الإعدادات',
'my_shipments' => 'شحناتي',
'find_trucks' => 'البحث عن شاحنات',
'contact_us' => 'اتصل بنا',
'about_us' => 'من نحن',
'privacy_policy' => 'سياسة الخصوصية',
'terms_conditions' => 'الشروط والأحكام',
'admin_panel' => 'لوحة الإدارة',
'users' => 'المستخدمين',
'reports' => 'التقارير',
'logout_confirm' => 'هل أنت متأكد من تسجيل الخروج؟',
'yes' => 'نعم',
'no' => 'لا',
'cancel' => 'إلغاء',
'save' => 'حفظ',
'update' => 'تحديث',
'created_at' => 'تاريخ الإنشاء',
'updated_at' => 'تاريخ التحديث',
'id' => 'المعرف',
'name' => 'الاسم',
'role' => 'الدور',
'approved' => 'مقبول',
'pending' => 'قيد الانتظار',
'rejected' => 'مرفوض',
'active' => 'نشط',
'inactive' => 'غير نشط',
'success_message' => 'تمت العملية بنجاح.',
'error_message' => 'حدث خطأ. يرجى المحاولة مرة أخرى.',
'manage_shipments' => 'إدارة الشحنات',
'manage_users' => 'إدارة المستخدمين',
'manage_trucks' => 'إدارة الشاحنات',
'truck_owner' => 'مالك شاحنة',
'shipper' => 'شاحن',
'admin' => 'مسؤول',
'notifications' => 'الإشعارات',
'mark_read' => 'تحديد كمقروء',
'view_all' => 'عرض الكل',
'new_shipment_alert' => 'تم نشر شحنة جديدة!',
'shipment_update_alert' => 'تم تحديث حالة الشحنة.',
'offer_received' => 'تم استلام عرض جديد.',
'offer_accepted' => 'تم قبول العرض.',
'offer_rejected' => 'تم رفض العرض.',
'payment_received' => 'تم استلام الدفعة.',
'payment_pending' => 'الدفعة معلقة.',
'payment_failed' => 'فشلت عملية الدفع.',
'search' => 'بحث...',
'filter' => 'تصفية',
'sort_by' => 'فرز حسب',
'date' => 'التاريخ',
'price' => 'السعر',
'loading' => 'جار التحميل...',
'no_data' => 'لا توجد بيانات متاحة.',
'unauthorized' => 'وصول غير مصرح به.',
'page_not_found' => 'الصفحة غير موجودة.',
'server_error' => 'خطأ في الخادم.',
'go_back' => 'رجوع',
'home_btn' => 'الصفحة الرئيسية',
'reset_password' => 'إعادة تعيين كلمة المرور',
'forgot_password' => 'نسيت كلمة المرور؟',
'send_link' => 'إرسال رابط التعيين',
'password_reset_sent' => 'تم إرسال رابط إعادة التعيين إلى بريدك الإلكتروني.',
'password_changed' => 'تم تغيير كلمة المرور بنجاح.',
'confirm_password' => 'تأكيد كلمة المرور',
'current_password' => 'كلمة المرور الحالية',
'new_password' => 'كلمة المرور الجديدة',
'change_password' => 'تغيير كلمة المرور',
'personal_info' => 'المعلومات الشخصية',
'company_info' => 'معلومات الشركة',
'truck_info' => 'معلومات الشاحنة',
'documents' => 'المستندات',
'upload_doc' => 'رفع مستند',
'download' => 'تحميل',
'file_too_large' => 'حجم الملف كبير جداً.',
'invalid_file_type' => 'نوع الملف غير صالح.',
'upload_success' => 'تم رفع الملف بنجاح.',
'delete_confirm' => 'هل أنت متأكد من الحذف؟',
'deleted_success' => 'تم الحذف بنجاح.',
'feature_not_available' => 'الخدمة غير متوفرة حالياً.',
'coming_soon' => 'قريباً',
'contact_support' => 'اتصل بالدعم',
'faq' => 'الأسئلة الشائعة',
'language' => 'اللغة',
'english' => 'إنجليزي',
'arabic' => 'عربي',
'switch_lang' => 'تغيير اللغة',
'dark_mode' => 'الوضع الليلي',
'light_mode' => 'الوضع النهاري',
'notifications_settings' => 'إعدادات الإشعارات',
'email_notif' => 'إشعارات البريد الإلكتروني',
'sms_notif' => 'إشعارات الرسائل القصيرة',
'push_notif' => 'إشعارات الدفع',
'enable' => 'تفعيل',
'disable' => 'تعطيل',
'account_settings' => 'إعدادات الحساب',
'delete_account' => 'حذف الحساب',
'delete_account_warning' => 'هذا الإجراء لا يمكن التراجع عنه.',
'feedback' => 'رأيك يهمنا',
'rate_us' => 'قيمنا',
'copyright' => 'حقوق النشر © ' . date('Y'),
'powered_by' => 'مشغل بواسطة منصة اللوجستيات',
'terms_of_service' => 'شروط الخدمة',
'cookie_policy' => 'سياسة ملفات الارتباط',
'careers' => 'وظائف',
'blog' => 'المدونة',
'partners' => 'الشركاء',
'help_center' => 'مركز المساعدة',
'how_it_works' => 'كيف نعمل',
'pricing' => 'الأسعار',
'get_started' => 'ابدأ الآن',
'learn_more' => 'اعرف المزيد',
'demo' => 'طلب عرض توضيحي',
'subscribe' => 'اشترك',
'newsletter' => 'النشرة البريدية',
'enter_email' => 'أدخل بريدك الإلكتروني',
'invalid_email' => 'بريد إلكتروني غير صالح.',
'message_sent' => 'تم إرسال الرسالة بنجاح.',
'thank_you' => 'شكراً لك!',
'404_msg' => 'الصفحة التي تبحث عنها غير موجودة.',
'500_msg' => 'حدث خطأ من جانبنا.',
'maintenance_msg' => 'النظام تحت الصيانة. يرجى المحاولة لاحقاً.',
'session_expired' => 'انتهت الجلسة. يرجى تسجيل الدخول مرة أخرى.',
'login_required' => 'يجب تسجيل الدخول للوصول لهذه الصفحة.',
'access_denied' => 'تم رفض الوصول.',
'csrf_error' => 'رمز الحماية غير صالح. يرجى التحديث والمحاولة مرة أخرى.',
'validation_error' => 'يرجى تصحيح الأخطاء أدناه.',
'required_field' => 'هذا الحقل مطلوب.',
'min_length' => 'الحد الأدنى للطول هو %s حرف.',
'max_length' => 'الحد الأقصى للطول هو %s حرف.',
'numeric_only' => 'الأرقام فقط مسموحة.',
'alpha_only' => 'الحروف فقط مسموحة.',
'alphanumeric_only' => 'الحروف والأرقام فقط مسموحة.',
'email_exists' => 'البريد الإلكتروني موجود بالفعل.',
'username_exists' => 'اسم المستخدم موجود بالفعل.',
'password_mismatch' => 'كلمات المرور غير متطابقة.',
'invalid_credentials' => 'البريد الإلكتروني أو كلمة المرور غير صحيحة.',
'account_locked' => 'الحساب مقفل. يرجى الاتصال بالدعم.',
'too_many_attempts' => 'محاولات دخول كثيرة جداً. يرجى المحاولة لاحقاً.',
'verify_email' => 'يرجى تأكيد بريدك الإلكتروني.',
'email_verified' => 'تم تأكيد البريد الإلكتروني بنجاح.',
'verification_link_sent' => 'تم إرسال رابط التأكيد.',
'invalid_token' => 'الرمز غير صالح أو منتهي.',
'token_expired' => 'انتهت صلاحية الرمز.',
'resend_verification' => 'إعادة إرسال بريد التأكيد',
'dashboard_overview' => 'نظرة عامة',
'total_shipments' => 'إجمالي الشحنات',
'active_trucks' => 'الشاحنات النشطة',
'pending_approvals' => 'بانتظار الموافقة',
'revenue' => 'الإيرادات',
'recent_activity' => 'النشاط الأخير',
'view_all_shipments' => 'عرض كل الشحنات',
'view_all_users' => 'عرض كل المستخدمين',
'add_new' => 'إضافة جديد',
'export' => 'تصدير',
'import' => 'استيراد',
'print' => 'طباعة',
'copy' => 'نسخ',
'csv' => 'CSV',
'excel' => 'Excel',
'pdf' => 'PDF',
'search_results' => 'نتائج البحث',
'no_results' => 'لا توجد نتائج.',
'showing_entries' => 'عرض %s إلى %s من %s سجل',
'next_page' => 'التالي',
'prev_page' => 'السابق',
'first_page' => 'الأول',
'last_page' => 'الأخير',
'apply' => 'تطبيق',
'clear' => 'مسح',
'filter_by' => 'تصفية حسب',
'status_all' => 'كل الحالات',
'role_all' => 'كل الأدوار',
'date_range' => 'نطاق التاريخ',
'today' => 'اليوم',
'yesterday' => 'أمس',
'last_7_days' => 'آخر 7 أيام',
'last_30_days' => 'آخر 30 يوم',
'this_month' => 'هذا الشهر',
'last_month' => 'الشهر الماضي',
'custom_range' => 'نطاق مخصص',
'start_date' => 'تاريخ البدء',
'end_date' => 'تاريخ الانتهاء',
'to' => 'إلى',
'from' => 'من',
'subject' => 'الموضوع',
'message' => 'الرسالة',
'send_message' => 'إرسال الرسالة',
'reply' => 'رد',
'forward' => 'توجيه',
'mark_unread' => 'تحديد كغير مقروء',
'delete_selected' => 'حذف المحدد',
'archive' => 'أرشفة',
'spam' => 'بريد مزعج',
'trash' => 'سلة المهملات',
'compose' => 'إنشاء',
'inbox' => 'الوارد',
'sent' => 'المرسل',
'drafts' => 'المسودات',
'important' => 'مهم',
'starred' => 'مميز بنجمة',
'labels' => 'تسميات',
'add_label' => 'إضافة تسمية',
'remove_label' => 'إزالة تسمية',
'color' => 'اللون',
'description' => 'الوصف',
'edit_profile' => 'تعديل الملف الشخصي',
'change_avatar' => 'تغيير الصورة الرمزية',
'bio' => 'نبذة',
'location' => 'الموقع',
'website' => 'الموقع الإلكتروني',
'social_links' => 'روابط التواصل الاجتماعي',
'facebook' => 'فيسبوك',
'twitter' => 'تويتر',
'linkedin' => 'لينكد إن',
'instagram' => 'انستغرام',
'youtube' => 'يوتيوب',
'github' => 'جيت هب',
'save_changes' => 'حفظ التغييرات',
'discard_changes' => 'تجاهل التغييرات',
'unsaved_changes' => 'لديك تغييرات غير محفوظة.',
'stay_on_page' => 'البقاء في الصفحة',
'leave_page' => 'مغادرة الصفحة',
'confirm_action' => 'تأكيد الإجراء',
'action_cannot_undone' => 'لا يمكن التراجع عن هذا الإجراء.',
'type_confirm' => 'اكتب "CONFIRM" للمتابعة.',
'notifications_permission' => 'هل تسمح بالإشعارات؟',
'allow' => 'سماح',
'deny' => 'رفض',
'location_permission' => 'هل تسمح بالوصول للموقع؟',
'camera_permission' => 'هل تسمح بالوصول للكاميرا؟',
'mic_permission' => 'هل تسمح بالوصول للميكروفون؟',
'cookie_consent' => 'نستخدم ملفات تعريف الارتباط لتحسين تجربتك.',
'accept_all' => 'قبول الكل',
'reject_all' => 'رفض الكل',
'customize' => 'تخصيص',
'preferences' => 'التفضيلات',
'general' => 'عام',
'security' => 'الأمان',
'billing' => 'الفوترة',
'integrations' => 'التكاملات',
'api_keys' => 'مفاتيح API',
'generate_key' => 'توليد مفتاح',
'revoke_key' => 'إبطال مفتاح',
'webhook_url' => 'رابط Webhook',
'secret_key' => 'المفتاح السري',
'documentation' => 'التوثيق',
'support_ticket' => 'تذكرة دعم',
'open_ticket' => 'فتح تذكرة',
'ticket_id' => 'رقم التذكرة',
'priority' => 'الأولوية',
'low' => 'منخفض',
'medium' => 'متوسط',
'high' => 'عالي',
'critical' => 'حرج',
'status_open' => 'مفتوح',
'status_closed' => 'مغلق',
'status_pending' => 'قيد الانتظار',
'last_reply' => 'آخر رد',
'assigned_to' => 'مسند إلى',
'created_by' => 'أنشئ بواسطة',
'resolved_at' => 'تم الحل في',
'closed_at' => 'تاريخ الإغلاق',
'reopen' => 'إعادة فتح',
'close' => 'إغلاق',
'add_comment' => 'إضافة تعليق',
'attach_file' => 'إرفاق ملف',
'max_size' => 'الحجم الأقصى: %s',
'allowed_types' => 'الأنواع المسموحة: %s',
'drag_drop' => 'اسحب وأفلت الملفات هنا',
'browse' => 'تصفح',
'uploading' => 'جار الرفع...',
'completed' => 'مكتمل',
'failed' => 'فشل',
'retry' => 'إعادة المحاولة',
'cancel_upload' => 'إلغاء الرفع',
'remove' => 'إزالة',
'preview' => 'معاينة',
'zoom_in' => 'تكبير',
'zoom_out' => 'تصغير',
'rotate' => 'تدوير',
'fullscreen' => 'ملء الشاشة',
'print_preview' => 'معاينة الطباعة',
'download_pdf' => 'تحميل PDF',
'share' => 'مشاركة',
'copy_link' => 'نسخ الرابط',
'email_link' => 'إرسال الرابط بالبريد',
'embed' => 'تضمين',
'qrcode' => 'رمز QR',
'scan_qrcode' => 'مسح رمز QR',
'auth_code' => 'رمز المصادقة',
'2fa' => 'المصادقة الثنائية',
'setup_2fa' => 'إعداد المصادقة الثنائية',
'disable_2fa' => 'تعطيل المصادقة الثنائية',
'enter_code' => 'أدخل الرمز',
'backup_codes' => 'رموز احتياطية',
'generate_codes' => 'توليد رموز',
'print_codes' => 'طباعة الرموز',
'recovery_email' => 'بريد الاسترداد',
'verify_phone' => 'تأكيد رقم الهاتف',
'sms_code' => 'رمز SMS',
'resend_code' => 'إعادة إرسال الرمز',
'code_sent' => 'تم إرسال الرمز.',
'phone_verified' => 'تم تأكيد رقم الهاتف.',
'country_code' => 'رمز الدولة',
'phone_number' => 'رقم الهاتف',
'address_line1' => 'العنوان 1',
'address_line2' => 'العنوان 2',
'city_state' => 'المدينة/المنطقة',
'postal_code' => 'الرمز البريدي',
'country_region' => 'الدولة/المنطقة',
'billing_address' => 'عنوان الفوترة',
'shipping_address' => 'عنوان الشحن',
'same_as_billing' => 'نفس عنوان الفوترة',
'add_address' => 'إضافة عنوان',
'edit_address' => 'تعديل عنوان',
'delete_address' => 'حذف عنوان',
'default_address' => 'العنوان الافتراضي',
'set_default' => 'تعيين كافتراضي',
'payment_method' => 'طريقة الدفع',
'credit_card' => 'بطاقة ائتمان',
'paypal' => 'باي بال',
'bank_transfer' => 'تحويل بنكي',
'cash_on_delivery' => 'الدفع عند الاستلام',
'card_number' => 'رقم البطاقة',
'expiry_date' => 'تاريخ الانتهاء',
'cvv' => 'رمز CVV',
'card_holder' => 'اسم حامل البطاقة',
'save_card' => 'حفظ البطاقة للاستخدام المستقبلي',
'transaction_history' => 'سجل المعاملات',
'invoice' => 'فاتورة',
'receipt' => 'إيصال',
'amount' => 'المبلغ',
'currency' => 'العملة',
'tax' => 'الضريبة',
'discount' => 'الخصم',
'subtotal' => 'المجموع الفرعي',
'total' => 'المجموع الكلي',
'promo_code' => 'الرمز الترويجي',
'apply_code' => 'تطبيق الرمز',
'invalid_code' => 'الرمز غير صالح.',
'checkout' => 'الدفع',
'place_order' => 'تأكيد الطلب',
'order_summary' => 'ملخص الطلب',
'cart' => 'سلة التسوق',
'empty_cart' => 'السلة فارغة.',
'continue_shopping' => 'متابعة التسوق',
'add_to_cart' => 'أضف إلى السلة',
'remove_from_cart' => 'إزالة من السلة',
'update_cart' => 'تحديث السلة',
'quantity' => 'الكمية',
'unit_price' => 'سعر الوحدة',
'total_price' => 'السعر الإجمالي',
'product_details' => 'تفاصيل المنتج',
'specifications' => 'المواصفات',
'reviews' => 'المراجعات',
'write_review' => 'اكتب مراجعة',
'rating' => 'التقييم',
'stars' => 'نجوم',
'related_products' => 'منتجات ذات صلة',
'wishlist' => 'قائمة الرغبات',
'add_to_wishlist' => 'أضف لقائمة الرغبات',
'remove_from_wishlist' => 'إزالة من قائمة الرغبات',
'compare' => 'مقارنة',
'add_to_compare' => 'أضف للمقارنة',
'clear_compare' => 'مسح المقارنة',
'compare_products' => 'مقارنة المنتجات',
'category' => 'الفئة',
'brand' => 'العلامة التجارية',
'model' => 'الموديل',
'sku' => 'SKU',
'availability' => 'التوفر',
'in_stock' => 'متوفر',
'out_of_stock' => 'غير متوفر',
'pre_order' => 'طلب مسبق',
'limited_stock' => 'كمية محدودة',
'new_arrival' => 'وصل حديثاً',
'best_seller' => 'الأكثر مبيعاً',
'featured' => 'متميز',
'sale' => 'تخفيضات',
'hot' => 'رائج',
'deal_of_day' => 'صفقة اليوم',
'timer_end' => 'العرض ينتهي في',
'days' => 'أيام',
'hours' => 'ساعات',
'minutes' => 'دقائق',
'seconds' => 'ثواني',
'subscribe_text' => 'Subscribe to our newsletter for latest updates.',
'follow_us' => 'Follow Us',
'app_download' => 'Download App',
'app_store' => 'App Store',
'google_play' => 'Google Play',
'secure_payment' => 'Secure Payment',
'fast_delivery' => 'Fast Delivery',
'24_7_support' => '24/7 Support',
'money_back' => 'Money Back Guarantee',
'easy_returns' => 'Easy Returns',
'gift_cards' => 'Gift Cards',
'track_order' => 'Track Order',
'order_id' => 'Order ID',
'shipping_info' => 'Shipping Info',
'billing_info' => 'Billing Info',
'order_status' => 'Order Status',
'processing' => 'Processing',
'shipped' => 'Shipped',
'delivered' => 'Delivered',
'cancelled' => 'Cancelled',
'returned' => 'Returned',
'refunded' => 'Refunded',
'return_policy' => 'Return Policy',
'shipping_policy' => 'Shipping Policy',
'sitemap' => 'Sitemap',
'accessibility' => 'Accessibility',
'accessibility_statement' => 'Accessibility Statement',
'skip_to_content' => 'Skip to Content',
'high_contrast' => 'High Contrast',
'text_size' => 'Text Size',
'increase' => 'Increase',
'decrease' => 'Decrease',
'reset' => 'Reset',
'print_page' => 'Print Page',
'read_aloud' => 'Read Aloud',
'stop' => 'Stop',
'pause' => 'Pause',
'resume' => 'Resume',
'mute' => 'Mute',
'unmute' => 'Unmute',
'volume' => 'Volume',
'speed' => 'Speed',
'normal' => 'Normal',
'fast' => 'Fast',
'slow' => 'Slow',
'captions' => 'Captions',
'subtitles' => 'Subtitles',
'audio_desc' => 'Audio Description',
'keyboard_shortcuts' => 'Keyboard Shortcuts',
'help' => 'Help',
'close_menu' => 'Close Menu',
'open_menu' => 'Open Menu',
'menu' => 'Menu',
'navigation' => 'Navigation',
'breadcrumbs' => 'Breadcrumbs',
'pagination' => 'Pagination',
'modal' => 'Modal',
'dialog' => 'Dialog',
'tooltip' => 'Tooltip',
'popover' => 'Popover',
'alert' => 'Alert',
'notification' => 'Notification',
'toast' => 'Toast',
'banner' => 'Banner',
'sidebar' => 'Sidebar',
'footer' => 'Footer',
'header' => 'Header',
'main_content' => 'Main Content',
'admin_dashboard_title' => 'Admin Dashboard',
'wablas_server_url' => 'Wablas Server URL',
'wablas_api_token' => 'Wablas API Token',
'reg_title' => 'Create Account',
'reg_subtitle' => 'Sign up to get started',
'reg_success_pending' => 'Registration successful. Your account is pending approval.',
'reg_success' => 'Registration successful. You can now login.',
'role' => 'Role',
'shipper' => 'Shipper',
'truck_owner' => 'Truck Owner',
'email' => 'Email',
'password' => 'Password',
'phone' => 'Phone',
'country' => 'Country',
'select_country' => 'Select Country',
'city' => 'City',
'select_city' => 'Select City',
'address' => 'Address',
'shipper_details' => 'Shipper Details',
'company_name' => 'Company Name',
'truck_details' => 'Truck Details',
'truck_type' => 'Truck Type',
'load_capacity' => 'Load Capacity (Tons)',
'plate_no' => 'Plate Number',
'bank_account' => 'Bank Account',
'bank_name' => 'Bank Name',
'bank_branch' => 'Branch Name',
'id_card_front' => 'ID Card (Front)',
'id_card_back' => 'ID Card (Back)',
'truck_reg_front' => 'Truck Registration (Front)',
'truck_reg_back' => 'Truck Registration (Back)',
'truck_picture' => 'Truck Picture',
'create_account' => 'Create Account',
'back_to_admin' => 'Back to Admin',
'back_to_home' => 'Back to Home',
'total_revenue' => 'Total Revenue',
'shipments_analytics' => 'Shipments Analytics',
'export_csv' => 'Export CSV',
'status_posted' => 'تم النشر',
'status_offered' => 'تم تقديم عرض',
'status_confirmed' => 'مؤكدة',
'status_in_transit' => 'قيد النقل',
'status_delivered' => 'تم التوصيل',
'status_pending' => 'قيد الانتظار',
'status_active' => 'نشط',
'status_rejected' => 'مرفوض',
'status_unpaid' => 'غير مدفوع',
'status_paid' => 'مدفوع',
'payment_thawani' => 'ثواني',
'payment_bank' => 'تحويل بنكي',
'currency_symbol' => 'ر.ع.',
'total_shippers' => 'إجمالي الشاحنين',
'active_shipments' => 'الشحنات النشطة',
'total_truck_owners' => 'إجمالي أصحاب الشاحنات',
'admin_dashboard' => 'لوحة تحكم المسؤول',
'overview_performance' => 'النظرة العامة والأداء',
'no_shipments' => 'لم يتم العثور على شحنات.',
'shipment' => 'الشحنة',
'route' => 'المسار',
'action' => 'الإجراء',
'manage_countries' => 'إدارة الدول',
'add_remove_countries' => 'إضافة/إزالة الدول',
'manage_cities' => 'إدارة المدن',
'configure_cities' => 'إعداد المدن',
'register_user' => 'تسجيل مستخدم',
'manually_onboard' => 'إضافة مستخدم يدوياً',
'company_profile' => 'ملف الشركة',
'update_branding' => 'تحديث الهوية',
'summary_report' => 'تقرير ملخص',
'view_analytics' => 'عرض التحليلات'
]
];
function t(string $key): string
{
global $translations, $lang;
return $translations[$lang][$key] ?? $key;
}
function e($value): string
{
return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
}
function ensure_schema(): void
{
// Make sure we have a connection
if (!db()) return;
try { db()->exec("ALTER TABLE shipments ADD COLUMN pod_path VARCHAR(255) NULL AFTER offer_owner"); } catch (Exception $e) {}
db()->exec(" CREATE TABLE IF NOT EXISTS landing_sections (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
subtitle TEXT NULL,
content TEXT NULL,
image_path VARCHAR(255) NULL,
layout ENUM('text_left', 'text_right', 'center') NOT NULL DEFAULT 'text_left',
button_text VARCHAR(100) NULL,
button_link VARCHAR(255) NULL,
section_order INT NOT NULL DEFAULT 0,
is_active TINYINT(1) NOT NULL DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
try { db()->exec("ALTER TABLE landing_sections ADD COLUMN title_ar VARCHAR(255) NULL AFTER title"); } catch (Exception $e) {}
try { db()->exec("ALTER TABLE landing_sections ADD COLUMN subtitle_ar TEXT NULL AFTER subtitle"); } catch (Exception $e) {}
try { db()->exec("ALTER TABLE landing_sections ADD COLUMN content_ar TEXT NULL AFTER content"); } catch (Exception $e) {}
try { db()->exec("ALTER TABLE landing_sections ADD COLUMN button_text_ar VARCHAR(100) NULL AFTER button_text"); } catch (Exception $e) {}
$sql = <<<SQL
CREATE TABLE IF NOT EXISTS shipments (
id INT AUTO_INCREMENT PRIMARY KEY,
shipper_name VARCHAR(120) NOT NULL,
shipper_company VARCHAR(120) NOT NULL,
origin_city VARCHAR(120) NOT NULL,
destination_city VARCHAR(120) NOT NULL,
cargo_description VARCHAR(255) NOT NULL,
weight_tons DECIMAL(10,2) NOT NULL,
pickup_date DATE NOT NULL,
delivery_date DATE NOT NULL,
payment_method ENUM('thawani','bank_transfer') NOT NULL DEFAULT 'thawani',
status ENUM('posted','offered','confirmed','in_transit','delivered') NOT NULL DEFAULT 'posted',
offer_price DECIMAL(10,2) DEFAULT NULL,
offer_owner VARCHAR(120) DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
SQL;
db()->exec($sql);
try { db()->exec("ALTER TABLE users ADD COLUMN status ENUM('pending','active','rejected') NOT NULL DEFAULT 'active'"); } catch (Exception $e) {}
try { db()->exec("ALTER TABLE users ADD COLUMN profile_picture VARCHAR(255) NULL AFTER full_name"); } catch (Exception $e) {}
// Payment fields for shipments
try { db()->exec("ALTER TABLE shipments ADD COLUMN platform_fee DECIMAL(10,2) DEFAULT 0.00 AFTER offer_price"); } catch (Exception $e) {}
try { db()->exec("ALTER TABLE shipments ADD COLUMN total_price DECIMAL(10,2) DEFAULT 0.00 AFTER platform_fee"); } catch (Exception $e) {}
try { db()->exec("ALTER TABLE shipments ADD COLUMN payment_status ENUM('unpaid', 'paid') DEFAULT 'unpaid' AFTER status"); } catch (Exception $e) {}
// Truck owner documents
try { db()->exec("ALTER TABLE users ADD COLUMN id_card_front VARCHAR(255) NULL"); } catch (Exception $e) {}
try { db()->exec("ALTER TABLE users ADD COLUMN id_card_back VARCHAR(255) NULL"); } catch (Exception $e) {}
try { db()->exec("ALTER TABLE users ADD COLUMN truck_reg_front VARCHAR(255) NULL"); } catch (Exception $e) {}
try { db()->exec("ALTER TABLE users ADD COLUMN truck_reg_back VARCHAR(255) NULL"); } catch (Exception $e) {}
try { db()->exec("ALTER TABLE users ADD COLUMN truck_picture VARCHAR(255) NULL"); } catch (Exception $e) {}
try {
db()->exec("CREATE TABLE IF NOT EXISTS notifications (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(255) NOT NULL,
message TEXT NOT NULL,
is_read TINYINT(1) DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)");
} catch (Exception $e) {}
// Add bank fields to users table if they don't exist
try { db()->exec("ALTER TABLE users ADD COLUMN bank_name VARCHAR(100) NULL AFTER truck_picture"); } catch (Exception $e) {}
try { db()->exec("ALTER TABLE users ADD COLUMN bank_branch VARCHAR(100) NULL AFTER bank_name"); } catch (Exception $e) {}
try { db()->exec("ALTER TABLE users ADD COLUMN bank_account VARCHAR(100) NULL AFTER bank_branch"); } catch (Exception $e) {}
// Create notification_templates table
try {
db()->exec("CREATE TABLE IF NOT EXISTS notification_templates (
id INT AUTO_INCREMENT PRIMARY KEY,
code VARCHAR(50) NOT NULL UNIQUE,
name VARCHAR(100) NOT NULL,
subject VARCHAR(255) NOT NULL,
body TEXT NOT NULL,
sms_body TEXT NULL,
variables TEXT NULL COMMENT 'Comma separated list of available variables',
is_active TINYINT(1) DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)");
} catch (Exception $e) {}
// Settings table
try {
db()->exec("CREATE TABLE IF NOT EXISTS settings (
id INT AUTO_INCREMENT PRIMARY KEY,
setting_key VARCHAR(50) NOT NULL UNIQUE,
setting_value TEXT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)");
} catch (Exception $e) {}
// Permissions tables
try {
db()->exec("CREATE TABLE IF NOT EXISTS permissions (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE,
description VARCHAR(255) NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)");
db()->exec("CREATE TABLE IF NOT EXISTS user_permissions (
user_id INT NOT NULL,
permission_id INT NOT NULL,
PRIMARY KEY (user_id, permission_id),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE
)");
} catch (Exception $e) {}
// Add user_id to shipments
try { db()->exec("ALTER TABLE shipments ADD COLUMN user_id INT NULL AFTER id"); } catch (Exception $e) {}
try { db()->exec("ALTER TABLE shipments ADD INDEX (user_id)"); } catch (Exception $e) {}
// Add pod_file to shipments
try { db()->exec("ALTER TABLE shipments ADD COLUMN pod_file VARCHAR(255) NULL AFTER status"); } catch (Exception $e) {}
}
function get_setting(string $key, $default = null)
{
// Try to get from database first
try {
$stmt = db()->prepare("SELECT setting_value FROM settings WHERE setting_key = ?");
$stmt->execute([$key]);
$val = $stmt->fetchColumn();
if ($val !== false) {
return $val;
}
} catch (Throwable $e) {}
return $default;
}
function require_role(string $role): void
{
if (!isset($_SESSION['user_id']) || !isset($_SESSION['user_role'])) {
header('Location: login.php');
exit;
}
if ($_SESSION['user_role'] !== $role && $_SESSION['user_role'] !== 'admin') {
// Admin can access everything
http_response_code(403);
die('Access Denied');
}
}
function get_flash(): ?array
{
if (isset($_SESSION['flash'])) {
$flash = $_SESSION['flash'];
unset($_SESSION['flash']);
return $flash;
}
return null;
}
function set_flash(string $type, string $message): void
{
$_SESSION['flash'] = ['type' => $type, 'message' => $message];
}
function url_with_lang(string $url, array $params = []): string
{
global $lang;
$params['lang'] = $lang;
$query = http_build_query($params);
if (strpos($url, '?') !== false) {
return $url . '&' . $query;
}
return $url . '?' . $query;
}
function current_url_with_lang(string $targetLang): string
{
$params = $_GET;
$params['lang'] = $targetLang;
$query = http_build_query($params);
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
return $path . '?' . $query;
}
function status_label(string $status): string
{
$key = 'status_' . $status;
return t($key);
}
function format_currency(float $amount): string
{
return number_format($amount, 2) . ' ' . t('currency_symbol');
}
function csrf_token(): string
{
if (empty($_SESSION['csrf_token'])) {
try {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
} catch (Exception $e) {
$_SESSION['csrf_token'] = bin2hex(openssl_random_pseudo_bytes(32));
}
}
return $_SESSION['csrf_token'];
}
function csrf_field(): string
{
return '<input type="hidden" name="csrf_token" value="' . e(csrf_token()) . '">';
}
function validate_csrf_token(): void
{
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!isset($_POST['csrf_token']) || !hash_equals(csrf_token(), $_POST['csrf_token'])) {
http_response_code(403);
die(t('csrf_error'));
}
}
}