From d424fc23601f52800a0a2d52661f7b4567056e3e Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 8 Mar 2026 10:11:07 +0000 Subject: [PATCH] updating landing page --- admin_cities.php | 8 +- admin_company_profile.php | 10 +- admin_countries.php | 8 +- admin_dashboard.php | 10 +- admin_faqs.php | 8 +- admin_integrations.php | 14 +- admin_landing_pages.php | 57 ++- admin_notification_templates.php | 201 ++++++++ admin_shipment_edit.php | 8 +- admin_shipments.php | 8 +- admin_shipper_edit.php | 8 +- admin_shippers.php | 8 +- admin_truck_owner_edit.php | 8 +- admin_truck_owners.php | 8 +- assets/css/custom.css | 8 +- db/migrations/add_arabic_landing_fields.php | 24 + db/migrations/add_notification_templates.php | 70 +++ db/migrations/add_user_ids_to_shipments.php | 15 + includes/NotificationService.php | 73 +++ includes/app.php | 510 ++++++++++++++----- includes/layout.php | 27 +- index.php | 59 ++- patch_app_translations.php | 12 + profile.php | 52 +- shipment_detail.php | 81 ++- shipper_dashboard.php | 23 +- uploads/pages/img_69ad2b68c8965.jfif | Bin 0 -> 8380 bytes uploads/pages/img_69ad2b9960534.jfif | Bin 0 -> 7791 bytes uploads/pages/img_69ad2bff407d4.jpg | Bin 0 -> 118066 bytes uploads/profiles/profile_7_1772962468.png | Bin 0 -> 542 bytes 30 files changed, 1055 insertions(+), 263 deletions(-) create mode 100644 admin_notification_templates.php create mode 100644 db/migrations/add_arabic_landing_fields.php create mode 100644 db/migrations/add_notification_templates.php create mode 100644 db/migrations/add_user_ids_to_shipments.php create mode 100644 includes/NotificationService.php create mode 100644 uploads/pages/img_69ad2b68c8965.jfif create mode 100644 uploads/pages/img_69ad2b9960534.jfif create mode 100644 uploads/pages/img_69ad2bff407d4.jpg create mode 100644 uploads/profiles/profile_7_1772962468.png diff --git a/admin_cities.php b/admin_cities.php index 017b2a7..dfe568c 100644 --- a/admin_cities.php +++ b/admin_cities.php @@ -107,14 +107,14 @@ if ($editCityId > 0) { } } -render_header('Manage Cities', 'admin'); +render_header('Manage Cities', 'admin', true); ?> -
-
+
+
-
+

Cities

Manage cities and map each city to its country.

diff --git a/admin_company_profile.php b/admin_company_profile.php index c83cc2f..b1a474c 100644 --- a/admin_company_profile.php +++ b/admin_company_profile.php @@ -87,14 +87,14 @@ $currentTermsAr = $settings['terms_ar'] ?? ''; $currentPrivacyEn = $settings['privacy_en'] ?? ''; $currentPrivacyAr = $settings['privacy_ar'] ?? ''; -render_header('Company Profile', 'admin'); +render_header('Company Profile', 'admin', true); ?> -
-
+
+
-
+

Company Profile

Update your app name, logo, favicon, contact details, platform charge, and legal policies.

@@ -109,7 +109,7 @@ render_header('Company Profile', 'admin');
-
+
diff --git a/admin_countries.php b/admin_countries.php index 1597c7e..b33ac91 100644 --- a/admin_countries.php +++ b/admin_countries.php @@ -85,14 +85,14 @@ if ($editCountryId > 0) { } } -render_header('Manage Countries', 'admin'); +render_header('Manage Countries', 'admin', true); ?> -
-
+
+
-
+

Countries

Manage the list of allowed countries for shipment routes.

diff --git a/admin_dashboard.php b/admin_dashboard.php index 804c894..ffb7b2a 100644 --- a/admin_dashboard.php +++ b/admin_dashboard.php @@ -33,14 +33,14 @@ try { $flash = get_flash(); -render_header(t('admin_dashboard'), 'admin'); +render_header(t('admin_dashboard'), 'admin', true); ?> -
-
+
+
-
+

Overview of your platform's performance and recent activity.

@@ -82,7 +82,7 @@ render_header(t('admin_dashboard'), 'admin');
-
+
diff --git a/admin_faqs.php b/admin_faqs.php index 76a519c..95f3f3d 100644 --- a/admin_faqs.php +++ b/admin_faqs.php @@ -101,14 +101,14 @@ if ($editFaqId > 0) { } } -render_header('Manage FAQs', 'admin'); +render_header('Manage FAQs', 'admin', true); ?> -
-
+
+
-
+

Frequently Asked Questions

Manage the Q&A list displayed on the public FAQ page.

diff --git a/admin_integrations.php b/admin_integrations.php index f20a0a6..ae52cf6 100644 --- a/admin_integrations.php +++ b/admin_integrations.php @@ -50,14 +50,14 @@ $smtpPass = $settings['smtp_pass'] ?? ''; $mailFrom = $settings['mail_from'] ?? ''; $mailFromName = $settings['mail_from_name'] ?? ''; -render_header('Integrations', 'admin'); +render_header('Integrations', 'admin', true); ?> -
-
+
+
-
+

Integrations

Manage your payment gateway and communication APIs.

@@ -82,7 +82,7 @@ render_header('Integrations', 'admin');

Configure your Oman-based Thawani Pay integration to process shipment payments.

-
+
@@ -144,7 +144,7 @@ render_header('Integrations', 'admin');

Configure your SMTP server to send emails and system notifications.

-
+
diff --git a/admin_landing_pages.php b/admin_landing_pages.php index e05fddf..4ddc328 100644 --- a/admin_landing_pages.php +++ b/admin_landing_pages.php @@ -18,10 +18,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($action === 'create' || $action === 'edit') { $id = $_POST['id'] ?? null; $title = $_POST['title'] ?? ''; + $title_ar = $_POST['title_ar'] ?? ''; $subtitle = $_POST['subtitle'] ?? ''; + $subtitle_ar = $_POST['subtitle_ar'] ?? ''; $content = $_POST['content'] ?? ''; + $content_ar = $_POST['content_ar'] ?? ''; $layout = $_POST['layout'] ?? 'text_left'; $button_text = $_POST['button_text'] ?? ''; + $button_text_ar = $_POST['button_text_ar'] ?? ''; $button_link = $_POST['button_link'] ?? ''; $section_order = (int)($_POST['section_order'] ?? 0); $is_active = isset($_POST['is_active']) ? 1 : 0; @@ -42,12 +46,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { } if ($action === 'create') { - $stmt = $pdo->prepare("INSERT INTO landing_sections (title, subtitle, content, image_path, layout, button_text, button_link, section_order, is_active, section_type) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'custom')"); - $stmt->execute([$title, $subtitle, $content, $image_path, $layout, $button_text, $button_link, $section_order, $is_active]); + $stmt = $pdo->prepare("INSERT INTO landing_sections (title, title_ar, subtitle, subtitle_ar, content, content_ar, image_path, layout, button_text, button_text_ar, button_link, section_order, is_active, section_type) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'custom')"); + $stmt->execute([$title, $title_ar, $subtitle, $subtitle_ar, $content, $content_ar, $image_path, $layout, $button_text, $button_text_ar, $button_link, $section_order, $is_active]); set_flash('success', 'Section created successfully.'); } else { - $stmt = $pdo->prepare("UPDATE landing_sections SET title=?, subtitle=?, content=?, image_path=?, layout=?, button_text=?, button_link=?, section_order=?, is_active=? WHERE id=?"); - $stmt->execute([$title, $subtitle, $content, $image_path, $layout, $button_text, $button_link, $section_order, $is_active, $id]); + $stmt = $pdo->prepare("UPDATE landing_sections SET title=?, title_ar=?, subtitle=?, subtitle_ar=?, content=?, content_ar=?, image_path=?, layout=?, button_text=?, button_text_ar=?, button_link=?, section_order=?, is_active=? WHERE id=?"); + $stmt->execute([$title, $title_ar, $subtitle, $subtitle_ar, $content, $content_ar, $image_path, $layout, $button_text, $button_text_ar, $button_link, $section_order, $is_active, $id]); set_flash('success', 'Section updated successfully.'); } header('Location: ' . url_with_lang('admin_landing_pages.php')); @@ -82,14 +86,14 @@ if ($editId) { $editSection = $stmt->fetch(); } -render_header(t('app_name') . ' - Landing Pages', 'admin'); +render_header(t('app_name') . ' - Landing Pages', 'admin', true); ?> -
-
+
+
-
+

Landing Page Customization

@@ -103,7 +107,7 @@ render_header(t('app_name') . ' - Landing Pages', 'admin');
-
+

@@ -115,21 +119,36 @@ render_header(t('app_name') . ' - Landing Pages', 'admin');
- +
+ +
+ + +
- +
- + + +
+ +
+ Not applicable for most built-in sections.
+
+ + +
+
@@ -147,14 +166,19 @@ render_header(t('app_name') . ' - Landing Pages', 'admin');
- +
- - + +
+ +
+ + +
@@ -193,6 +217,9 @@ render_header(t('app_name') . ' - Landing Pages', 'admin');
Order: | Type: + +
AR:
+
Edit diff --git a/admin_notification_templates.php b/admin_notification_templates.php new file mode 100644 index 0000000..0c4cb85 --- /dev/null +++ b/admin_notification_templates.php @@ -0,0 +1,201 @@ +exec(" + CREATE TABLE IF NOT EXISTS notification_templates ( + id INT AUTO_INCREMENT PRIMARY KEY, + event_name VARCHAR(50) NOT NULL UNIQUE, + email_subject_en VARCHAR(255), + email_body_en TEXT, + email_subject_ar VARCHAR(255), + email_body_ar TEXT, + whatsapp_body_en TEXT, + whatsapp_body_ar TEXT, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP + ); + "); +} catch (Throwable $e) { + // Ignore if table exists or permission issue, subsequent queries will fail if critical +} + +$action = $_GET['action'] ?? 'list'; +$id = (int)($_GET['id'] ?? 0); +$errors = []; +$flash = get_flash(); + +if ($action === 'edit' && $id > 0) { + // Handle Edit + $stmt = db()->prepare("SELECT * FROM notification_templates WHERE id = ?"); + $stmt->execute([$id]); + $template = $stmt->fetch(); + + if (!$template) { + set_flash('error', 'Template not found.'); + header('Location: ' . url_with_lang('admin_notification_templates.php')); + exit; + } + + if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $email_subject_en = trim($_POST['email_subject_en'] ?? ''); + $email_body_en = trim($_POST['email_body_en'] ?? ''); + $email_subject_ar = trim($_POST['email_subject_ar'] ?? ''); + $email_body_ar = trim($_POST['email_body_ar'] ?? ''); + $whatsapp_body_en = trim($_POST['whatsapp_body_en'] ?? ''); + $whatsapp_body_ar = trim($_POST['whatsapp_body_ar'] ?? ''); + + if ($email_subject_en === '' || $email_body_en === '') { + $errors[] = 'English subject and body are required.'; + } + + if (!$errors) { + $stmt = db()->prepare(" + UPDATE notification_templates SET + email_subject_en = ?, email_body_en = ?, + email_subject_ar = ?, email_body_ar = ?, + whatsapp_body_en = ?, whatsapp_body_ar = ? + WHERE id = ? + "); + $stmt->execute([ + $email_subject_en, $email_body_en, + $email_subject_ar, $email_body_ar, + $whatsapp_body_en, $whatsapp_body_ar, + $id + ]); + set_flash('success', 'Template updated successfully.'); + header('Location: ' . url_with_lang('admin_notification_templates.php')); + exit; + } + } + + render_header('Edit Notification Template', 'admin', true); + ?> +
+
+ +
+
+
+
+

Edit Template:

+ Back to List +
+ + +
', $errors)) ?>
+ + +
+
+ +
+
+
English
+
+ + +
+
+ + +
Use placeholders like {shipment_id}, {user_name}, {offer_price}.
+
+
+ + +
+
+
+
Arabic
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+ +
+ +
+
+
+
+
+ query("SELECT * FROM notification_templates ORDER BY event_name ASC"); +$templates = $stmt->fetchAll(); + +render_header('Notification Templates', 'admin', true); +?> +
+
+ +
+
+
+
+

Notification Templates

+
+ + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + +
Event NameSubject (EN)Subject (AR)Actions
+ + Edit + +
+
+
+
+
+
+ \ No newline at end of file diff --git a/admin_shipment_edit.php b/admin_shipment_edit.php index b18d7f0..492e076 100644 --- a/admin_shipment_edit.php +++ b/admin_shipment_edit.php @@ -109,14 +109,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { } } -render_header('Edit Shipment', 'admin'); +render_header('Edit Shipment', 'admin', true); ?> -
-
+
+
-
+
diff --git a/admin_shipments.php b/admin_shipments.php index 71de516..b492c15 100644 --- a/admin_shipments.php +++ b/admin_shipments.php @@ -66,14 +66,14 @@ $stmt = db()->prepare($sql); $stmt->execute($params); $shipments = $stmt->fetchAll(); -render_header('Manage Shipments', 'admin'); +render_header('Manage Shipments', 'admin', true); ?> -
-
+
+
-
+

Shipments

diff --git a/admin_shipper_edit.php b/admin_shipper_edit.php index d3741ee..1510c8a 100644 --- a/admin_shipper_edit.php +++ b/admin_shipper_edit.php @@ -101,14 +101,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { } } -render_header('Edit Shipper', 'admin'); +render_header('Edit Shipper', 'admin', true); ?> -
-
+
+
-
+
← Back to Shippers diff --git a/admin_shippers.php b/admin_shippers.php index a70632a..064cb66 100644 --- a/admin_shippers.php +++ b/admin_shippers.php @@ -75,14 +75,14 @@ $stmt = db()->prepare($sql); $stmt->execute($params); $shippers = $stmt->fetchAll(); -render_header('Manage Shippers', 'admin'); +render_header('Manage Shippers', 'admin', true); ?> -
-
+
+
-
+

Shippers

diff --git a/admin_truck_owner_edit.php b/admin_truck_owner_edit.php index 9533884..1663483 100644 --- a/admin_truck_owner_edit.php +++ b/admin_truck_owner_edit.php @@ -126,14 +126,14 @@ $idCards = json_decode($owner['id_card_path'] ?? '[]', true) ?: []; $regs = json_decode($owner['registration_path'] ?? '[]', true) ?: []; $pic = $owner['truck_pic_path']; -render_header('Edit Truck Owner', 'admin'); +render_header('Edit Truck Owner', 'admin', true); ?> -
-
+
+
-
+
← Back to Truck Owners diff --git a/admin_truck_owners.php b/admin_truck_owners.php index d1043f4..8e0ac9e 100644 --- a/admin_truck_owners.php +++ b/admin_truck_owners.php @@ -75,14 +75,14 @@ $stmt = db()->prepare($sql); $stmt->execute($params); $owners = $stmt->fetchAll(); -render_header('Manage Truck Owners', 'admin'); +render_header('Manage Truck Owners', 'admin', true); ?> -
-
+
+
-
+

Truck Owners

diff --git a/assets/css/custom.css b/assets/css/custom.css index 0fa6bd7..2426c8d 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -238,8 +238,10 @@ body.app-body { .admin-sidebar { position: sticky; - top: 88px; - border-radius: 16px; + top: 76px; + height: calc(100vh - 76px); + overflow-y: auto; + border-radius: 0; } .admin-nav-link { @@ -289,5 +291,7 @@ body.app-body { .admin-sidebar { position: static; + height: auto; + overflow-y: visible; } } \ No newline at end of file diff --git a/db/migrations/add_arabic_landing_fields.php b/db/migrations/add_arabic_landing_fields.php new file mode 100644 index 0000000..74e6ce0 --- /dev/null +++ b/db/migrations/add_arabic_landing_fields.php @@ -0,0 +1,24 @@ +exec("ALTER TABLE landing_sections ADD COLUMN title_ar VARCHAR(255) NULL AFTER title"); + echo "Added title_ar.\n"; +} catch (PDOException $e) { echo "title_ar likely exists.\n"; } + +try { + $pdo->exec("ALTER TABLE landing_sections ADD COLUMN subtitle_ar TEXT NULL AFTER subtitle"); + echo "Added subtitle_ar.\n"; +} catch (PDOException $e) { echo "subtitle_ar likely exists.\n"; } + +try { + $pdo->exec("ALTER TABLE landing_sections ADD COLUMN content_ar TEXT NULL AFTER content"); + echo "Added content_ar.\n"; +} catch (PDOException $e) { echo "content_ar likely exists.\n"; } + +try { + $pdo->exec("ALTER TABLE landing_sections ADD COLUMN button_text_ar VARCHAR(100) NULL AFTER button_text"); + echo "Added button_text_ar.\n"; +} catch (PDOException $e) { echo "button_text_ar likely exists.\n"; } + diff --git a/db/migrations/add_notification_templates.php b/db/migrations/add_notification_templates.php new file mode 100644 index 0000000..114605b --- /dev/null +++ b/db/migrations/add_notification_templates.php @@ -0,0 +1,70 @@ +exec(" + CREATE TABLE IF NOT EXISTS notification_templates ( + id INT AUTO_INCREMENT PRIMARY KEY, + event_name VARCHAR(50) NOT NULL UNIQUE, + email_subject_en VARCHAR(255), + email_body_en TEXT, + email_subject_ar VARCHAR(255), + email_body_ar TEXT, + whatsapp_body_en TEXT, + whatsapp_body_ar TEXT, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP + ); + "); + + // Insert default templates + $defaults = [ + [ + 'event_name' => 'shipment_created', + 'email_subject_en' => 'Shipment Created: #{shipment_id}', + 'email_body_en' => "Dear {user_name},\n\nYour shipment from {origin} to {destination} has been successfully created.\n\nShipment ID: {shipment_id}\n\nWe will notify you when a truck owner submits an offer.", + 'email_subject_ar' => 'تم إنشاء الشحنة: #{shipment_id}', + 'email_body_ar' => "عزيزي {user_name}،\n\nتم إنشاء شحنتك من {origin} إلى {destination} بنجاح.\n\nرقم الشحنة: {shipment_id}\n\nسنقوم بإعلامك عند تقديم عرض من قبل صاحب شاحنة.", + 'whatsapp_body_en' => "Shipment #{shipment_id} created successfully from {origin} to {destination}.", + 'whatsapp_body_ar' => "تم إنشاء الشحنة #{shipment_id} بنجاح من {origin} إلى {destination}." + ], + [ + 'event_name' => 'shipment_offered', + 'email_subject_en' => 'New Offer for Shipment #{shipment_id}', + 'email_body_en' => "Dear {user_name},\n\nA truck owner has submitted an offer for your shipment #{shipment_id}.\n\nOffer Price: {offer_price}\nTruck Owner: {offer_owner}\n\nPlease login to your dashboard to accept or reject this offer.", + 'email_subject_ar' => 'عرض جديد للشحنة #{shipment_id}', + 'email_body_ar' => "عزيزي {user_name}،\n\nلقد قدم صاحب شاحنة عرضًا لشحنتك #{shipment_id}.\n\nسعر العرض: {offer_price}\nصاحب الشاحنة: {offer_owner}\n\nيرجى تسجيل الدخول إلى لوحة التحكم لقبول أو رفض العرض.", + 'whatsapp_body_en' => "New offer for shipment #{shipment_id}: {offer_price}. Check your dashboard.", + 'whatsapp_body_ar' => "عرض جديد للشحنة #{shipment_id}: {offer_price}. تحقق من لوحة التحكم." + ], + [ + 'event_name' => 'shipment_accepted', + 'email_subject_en' => 'Offer Accepted: Shipment #{shipment_id}', + 'email_body_en' => "Dear {user_name},\n\nYour offer for shipment #{shipment_id} has been accepted and paid for by the shipper.\n\nPlease proceed with the shipment.", + 'email_subject_ar' => 'تم قبول العرض: الشحنة #{shipment_id}', + 'email_body_ar' => "عزيزي {user_name}،\n\nتم قبول عرضك للشحنة #{shipment_id} ودفع ثمنه من قبل الشاحن.\n\nيرجى المتابعة في إجراءات الشحن.", + 'whatsapp_body_en' => "Your offer for shipment #{shipment_id} was accepted. Please proceed.", + 'whatsapp_body_ar' => "تم قبول عرضك للشحنة #{shipment_id}. يرجى المتابعة." + ], + [ + 'event_name' => 'shipment_rejected', + 'email_subject_en' => 'Offer Rejected: Shipment #{shipment_id}', + 'email_body_en' => "Dear {user_name},\n\nYour offer for shipment #{shipment_id} was not accepted by the shipper.\n\nThe shipment is now back to 'Posted' status.", + 'email_subject_ar' => 'تم رفض العرض: الشحنة #{shipment_id}', + 'email_body_ar' => "عزيزي {user_name}،\n\nلم يتم قبول عرضك للشحنة #{shipment_id} من قبل الشاحن.\n\nعادت الشحنة الآن إلى حالة 'منشورة'.", + 'whatsapp_body_en' => "Your offer for shipment #{shipment_id} was rejected.", + 'whatsapp_body_ar' => "تم رفض عرضك للشحنة #{shipment_id}." + ] + ]; + + $stmt = $pdo->prepare("INSERT IGNORE INTO notification_templates (event_name, email_subject_en, email_body_en, email_subject_ar, email_body_ar, whatsapp_body_en, whatsapp_body_ar) VALUES (:event_name, :email_subject_en, :email_body_en, :email_subject_ar, :email_body_ar, :whatsapp_body_en, :whatsapp_body_ar)"); + + foreach ($defaults as $d) { + $stmt->execute($d); + } + + echo "Notification templates table created and defaults inserted."; +} catch (PDOException $e) { + echo "Error: " . $e->getMessage(); +} diff --git a/db/migrations/add_user_ids_to_shipments.php b/db/migrations/add_user_ids_to_shipments.php new file mode 100644 index 0000000..21ed1f4 --- /dev/null +++ b/db/migrations/add_user_ids_to_shipments.php @@ -0,0 +1,15 @@ +exec("ALTER TABLE shipments ADD COLUMN shipper_id INT NULL AFTER id"); + $pdo->exec("ALTER TABLE shipments ADD COLUMN truck_owner_id INT NULL AFTER offer_price"); + + // Add FK constraints (optional but good practice, keeping it simple for now to avoid issues with existing data) + // We won't enforce FK strictly on existing data as it might be NULL + + echo "Added shipper_id and truck_owner_id to shipments table."; +} catch (PDOException $e) { + echo "Error (might already exist): " . $e->getMessage(); +} diff --git a/includes/NotificationService.php b/includes/NotificationService.php new file mode 100644 index 0000000..0bbe892 --- /dev/null +++ b/includes/NotificationService.php @@ -0,0 +1,73 @@ + 123]) + * @param string|null $lang 'en' or 'ar'. If null, sends both combined. + */ + public static function send(string $eventName, array $user, array $data = [], ?string $lang = null) + { + $pdo = db(); + $stmt = $pdo->prepare("SELECT * FROM notification_templates WHERE event_name = ?"); + $stmt->execute([$eventName]); + $template = $stmt->fetch(); + + if (!$template) { + error_log("Notification template not found: $eventName"); + return; + } + + // Prepare data for replacement + $placeholders = []; + $values = []; + $data['user_name'] = $user['full_name'] ?? 'User'; + + foreach ($data as $key => $val) { + $placeholders[] = '{' . $key . '}'; + $values[] = $val; + } + + // Determine Subject and Body based on Lang + $subject = ''; + $body = ''; + $whatsapp = ''; + + if ($lang === 'en') { + $subject = $template['email_subject_en']; + $body = $template['email_body_en']; + $whatsapp = $template['whatsapp_body_en']; + } elseif ($lang === 'ar') { + $subject = $template['email_subject_ar']; + $body = $template['email_body_ar']; + $whatsapp = $template['whatsapp_body_ar']; + } else { + // Combined + $subject = $template['email_subject_en'] . ' / ' . $template['email_subject_ar']; + $body = $template['email_body_en'] . "\n\n---\n\n" . $template['email_body_ar']; + $whatsapp = $template['whatsapp_body_en'] . "\n\n" . $template['whatsapp_body_ar']; + } + + // Replace + $subject = str_replace($placeholders, $values, $subject); + $body = str_replace($placeholders, $values, $body); + $whatsapp = str_replace($placeholders, $values, $whatsapp); + + // Send Email + if (!empty($user['email'])) { + // Convert newlines to BR for HTML + $htmlBody = nl2br(htmlspecialchars($body)); + MailService::sendMail($user['email'], $subject, $htmlBody, $body); + } + + // Log WhatsApp (Mock) + // In a real app, this would call Twilio/Meta API + error_log("WHATSAPP Notification to {$user['email']} (Phone N/A): $whatsapp"); + } +} diff --git a/includes/app.php b/includes/app.php index 3fddf14..eadc88d 100644 --- a/includes/app.php +++ b/includes/app.php @@ -13,142 +13,366 @@ $_SESSION['lang'] = $lang; $dir = $lang === 'ar' ? 'rtl' : 'ltr'; $translations = [ - 'en' => [ - 'app_name' => 'CargoLink', - 'nav_home' => 'Overview', - 'nav_shipper' => 'Shipper Desk', - 'nav_owner' => 'Truck Owner Desk', - 'nav_admin' => 'Admin Panel', - 'hero_title' => 'Move cargo faster with verified trucks.', - 'hero_subtitle' => 'Post shipments, collect offers, and pay via Thawani or bank transfer. Built for local and nearby cross-border moves.', - 'hero_tagline' => 'Multilingual Logistics Marketplace', - 'register_shipper' => 'Register as Shipper', - 'register_owner' => 'Register as Truck Owner', - 'cta_shipper' => 'Post a shipment', - 'cta_owner' => 'Find loads', - 'cta_admin' => 'Open admin', - 'stats_shipments' => 'Shipments posted', - 'stats_offers' => 'Active offers', - 'stats_confirmed' => 'Confirmed trips', - 'section_workflow' => 'How it works', - 'recent_shipments' => 'Recent shipments', - 'step_post' => 'Shipper posts cargo details and preferred payment.', - 'step_offer' => 'Truck owners respond with their best rate.', - 'step_confirm' => 'Admin confirms booking and status.', - 'shipper_dashboard' => 'Shipper Dashboard', - 'new_shipment' => 'Create shipment', - 'shipper_name' => 'Shipper name', - 'shipper_company' => 'Company', - 'origin' => 'Origin city', - 'destination' => 'Destination city', - 'cargo' => 'Cargo description', - 'weight' => 'Weight (tons)', - 'pickup_date' => 'Pickup date', - 'delivery_date' => 'Delivery date', - 'payment_method' => 'Payment method', - 'payment_thawani' => 'Thawani online payment', - 'payment_bank' => 'Bank transfer', - 'submit_shipment' => 'Submit shipment', - 'shipments_list' => 'Your latest shipments', - 'status' => 'Status', - 'offer' => 'Best offer', - 'actions' => 'Actions', - 'view' => 'View', - 'owner_dashboard' => 'Truck Owner Dashboard', - 'available_shipments' => 'Available shipments', - 'offer_price' => 'Offer price', - 'offer_owner' => 'Truck owner name', - 'submit_offer' => 'Send offer', - 'admin_dashboard' => 'Admin Dashboard', - 'update_status' => 'Update status', - 'save' => 'Save', - 'shipment_detail' => 'Shipment detail', - 'created_at' => 'Created', - 'best_offer' => 'Best offer', - 'assign_owner' => 'Assigned owner', - 'no_shipments' => 'No shipments yet. Create the first one to get started.', - 'no_offers' => 'No offers yet.', - 'success_shipment' => 'Shipment posted successfully.', - 'success_offer' => 'Offer submitted to the shipper.', - 'success_status' => 'Status updated.', - 'error_required' => 'Please fill in all required fields.', - 'error_invalid' => 'Please enter valid values.', - 'status_posted' => 'Posted', - 'status_offered' => 'Offered', - 'status_confirmed' => 'Confirmed', - 'status_in_transit' => 'In transit', - 'status_delivered' => 'Delivered', - 'footer_note' => 'This is the initial MVP slice. Payments are not yet connected.', -'marketing_title_1' => 'For Shippers', 'marketing_desc_1' => 'Find the right truck for your cargo quickly and securely. Post your load and get offers instantly.', 'marketing_title_2' => 'For Truck Owners', 'marketing_desc_2' => 'Maximize your earnings and eliminate empty miles. Browse available shipments and offer your rate.', 'motivation_phrase' => 'Empowering the logistics of tomorrow.', 'why_choose_us' => 'لماذا تختار كارجو لينك؟', 'feature_1_title' => 'Fast Matching', 'feature_1_desc' => 'Connect with available trucks or shipments in minutes.', 'feature_2_title' => 'Secure Payments', 'feature_2_desc' => 'Your transactions are protected with security.', 'feature_3_title' => 'Verified Users', 'feature_3_desc' => 'We verify all truck owners to ensure peace of mind.', - ], - 'ar' => [ - 'app_name' => 'CargoLink', - 'nav_home' => 'نظرة عامة', - 'nav_shipper' => 'لوحة الشاحن', - 'nav_owner' => 'لوحة مالك الشاحنة', - 'nav_admin' => 'لوحة الإدارة', - 'hero_title' => 'انقل شحنتك بسرعة مع شاحنات موثوقة.', - 'hero_subtitle' => 'أنشئ شحنة، استلم عروضاً، وادفع عبر ثواني أو التحويل البنكي.', - 'hero_tagline' => 'منصة لوجستية متعددة اللغات', - 'register_shipper' => 'التسجيل كشاحن', - 'register_owner' => 'التسجيل كمالك شاحنة', - 'cta_shipper' => 'إنشاء شحنة', - 'cta_owner' => 'البحث عن الشحنات', - 'cta_admin' => 'الدخول للإدارة', - 'stats_shipments' => 'الشحنات المنشورة', - 'stats_offers' => 'العروض الحالية', - 'stats_confirmed' => 'الرحلات المؤكدة', - 'section_workflow' => 'طريقة العمل', - 'recent_shipments' => 'أحدث الشحنات', - 'step_post' => 'يقوم الشاحن بإدخال تفاصيل الشحنة وطريقة الدفع.', - 'step_offer' => 'يرسل أصحاب الشاحنات أفضل عروضهم.', - 'step_confirm' => 'تؤكد الإدارة الحجز وتحدث الحالة.', - 'shipper_dashboard' => 'لوحة الشاحن', - 'new_shipment' => 'إنشاء شحنة', - 'shipper_name' => 'اسم الشاحن', - 'shipper_company' => 'الشركة', - 'origin' => 'مدينة الانطلاق', - 'destination' => 'مدينة الوصول', - 'cargo' => 'وصف الحمولة', - 'weight' => 'الوزن (طن)', - 'pickup_date' => 'تاريخ الاستلام', - 'delivery_date' => 'تاريخ التسليم', - 'payment_method' => 'طريقة الدفع', - 'payment_thawani' => 'الدفع الإلكتروني عبر ثواني', - 'payment_bank' => 'تحويل بنكي', - 'submit_shipment' => 'إرسال الشحنة', - 'shipments_list' => 'أحدث الشحنات', - 'status' => 'الحالة', - 'offer' => 'أفضل عرض', - 'actions' => 'إجراءات', - 'view' => 'عرض', - 'owner_dashboard' => 'لوحة مالك الشاحنة', - 'available_shipments' => 'الشحنات المتاحة', - 'offer_price' => 'سعر العرض', - 'offer_owner' => 'اسم مالك الشاحنة', - 'submit_offer' => 'إرسال العرض', - 'admin_dashboard' => 'لوحة الإدارة', - 'update_status' => 'تحديث الحالة', - 'save' => 'حفظ', - 'shipment_detail' => 'تفاصيل الشحنة', - 'created_at' => 'تم الإنشاء', - 'best_offer' => 'أفضل عرض', - 'assign_owner' => 'المالك المعتمد', - 'no_shipments' => 'لا توجد شحنات بعد. ابدأ بإنشاء أول شحنة.', - 'no_offers' => 'لا توجد عروض بعد.', - 'success_shipment' => 'تم نشر الشحنة بنجاح.', - 'success_offer' => 'تم إرسال العرض إلى الشاحن.', - 'success_status' => 'تم تحديث الحالة.', - 'error_required' => 'يرجى تعبئة جميع الحقول المطلوبة.', - 'error_invalid' => 'يرجى إدخال قيم صحيحة.', - 'status_posted' => 'منشورة', - 'status_offered' => 'بعرض', - 'status_confirmed' => 'مؤكدة', - 'status_in_transit' => 'قيد النقل', - 'status_delivered' => 'تم التسليم', - 'footer_note' => 'هذه هي النسخة الأولية. الدفع غير متصل بعد.', -'marketing_title_1' => 'للشاحنين', 'marketing_desc_1' => 'ابحث عن الشاحنة المناسبة لحمولتك بسرعة وأمان.', 'marketing_title_2' => 'لأصحاب الشاحنات', 'marketing_desc_2' => 'عظّم أرباحك وتجنب العودة فارغاً.', 'motivation_phrase' => 'تمكين الخدمات اللوجستية للمستقبل.', 'why_choose_us' => 'لماذا تختار كارجو لينك؟', 'feature_1_title' => 'مطابقة سريعة', 'feature_1_desc' => 'تواصل مع الشاحنات المتاحة في دقائق.', 'feature_2_title' => 'مدفوعات آمنة', 'feature_2_desc' => 'معاملاتك محمية بأعلى معايير الأمان.', 'feature_3_title' => 'مستخدمون موثوقون', 'feature_3_desc' => 'نقوم بالتحقق من جميع أصحاب الشاحنات لضمان راحتك.', - ], + "en" => array ( + 'app_name' => 'CargoLink', + 'nav_home' => 'Overview', + 'nav_shipper' => 'Shipper Desk', + 'nav_owner' => 'Truck Owner Desk', + 'nav_admin' => 'Admin Panel', + 'hero_title' => 'Move cargo faster with verified trucks.', + 'hero_subtitle' => 'Post shipments, collect offers, and pay via Thawani or bank transfer. Built for local and nearby cross-border moves.', + 'hero_tagline' => 'Multilingual Logistics Marketplace', + 'register_shipper' => 'Register as Shipper', + 'register_owner' => 'Register as Truck Owner', + 'cta_shipper' => 'Post a shipment', + 'cta_owner' => 'Find loads', + 'cta_admin' => 'Open admin', + 'stats_shipments' => 'Shipments posted', + 'stats_offers' => 'Active offers', + 'stats_confirmed' => 'Confirmed trips', + 'section_workflow' => 'How it works', + 'recent_shipments' => 'Recent shipments', + 'step_post' => 'Shipper posts cargo details and preferred payment.', + 'step_offer' => 'Truck owners respond with their best rate.', + 'step_confirm' => 'Admin confirms booking and status.', + 'step_confirm_desc' => 'Secure booking and track the delivery until completion.', + 'shipper_dashboard' => 'Shipper Dashboard', + 'new_shipment' => 'Create shipment', + 'shipper_name' => 'Shipper name', + 'shipper_company' => 'Company', + 'origin' => 'Origin city', + 'destination' => 'Destination city', + 'cargo' => 'Cargo description', + 'cargo_placeholder' => 'e.g. 20 Pallets of Electronics', + 'weight' => 'Weight (tons)', + 'pickup_date' => 'Pickup date', + 'delivery_date' => 'Delivery date', + 'payment_method' => 'Payment method', + 'payment_thawani' => 'Thawani online payment', + 'payment_bank' => 'Bank transfer', + 'submit_shipment' => 'Submit shipment', + 'shipments_list' => 'Your latest shipments', + 'status' => 'Status', + 'offer' => 'Best offer', + 'actions' => 'Actions', + 'view' => 'View', + 'owner_dashboard' => 'Truck Owner Dashboard', + 'available_shipments' => 'Available shipments', + 'offer_price' => 'Offer price', + 'offer_owner' => 'Truck owner name', + 'submit_offer' => 'Send offer', + 'admin_dashboard' => 'Admin Dashboard', + 'update_status' => 'Update status', + 'save' => 'Save', + 'shipment_detail' => 'Shipment detail', + 'created_at' => 'Created', + 'best_offer' => 'Best offer', + 'assign_owner' => 'Assigned owner', + 'no_shipments' => 'No shipments yet. Create the first one to get started.', + 'no_offers' => 'No offers yet.', + 'success_shipment' => 'Shipment posted successfully.', + 'success_offer' => 'Offer submitted to the shipper.', + 'success_status' => 'Status updated.', + 'error_required' => 'Please fill in all required fields.', + 'error_invalid' => 'Please enter valid values.', + 'status_posted' => 'Posted', + 'status_offered' => 'Offered', + 'status_confirmed' => 'Confirmed', + 'status_in_transit' => 'In transit', + 'status_delivered' => 'Delivered', + 'footer_note' => 'This is the initial MVP slice. Payments are not yet connected.', + 'marketing_title_1' => 'For Shippers', + 'marketing_desc_1' => 'Find the right truck for your cargo quickly and securely. Post your load and get offers instantly.', + 'marketing_title_2' => 'For Truck Owners', + 'marketing_desc_2' => 'Maximize your earnings and eliminate empty miles. Browse available shipments and offer your rate.', + 'motivation_phrase' => 'Empowering the logistics of tomorrow.', + 'why_choose_us' => 'Why Choose CargoLink?', + 'feature_1_title' => 'Fast Matching', + 'feature_1_desc' => 'Connect with available trucks or shipments in minutes.', + 'feature_2_title' => 'Secure Payments', + 'feature_2_desc' => 'Your transactions are protected with security.', + 'feature_3_title' => 'Verified Users', + 'feature_3_desc' => 'We verify all truck owners to ensure peace of mind.', + 'view_faq' => 'View FAQ', + 'faq_title' => 'Have Questions?', + 'faq_subtitle' => 'Check out our Frequently Asked Questions to learn more about how our platform works.', + 'motivation_title' => 'Ready to transform your logistics?', + 'motivation_subtitle' => 'Join our platform today to find reliable trucks or secure the best shipments in the market.', + 'company' => 'Company', + 'about_us' => 'About Us', + 'careers' => 'Careers', + 'contact' => 'Contact', + 'resources' => 'Resources', + 'help_center' => 'Help Center / FAQ', + 'terms_of_service' => 'Terms of Service', + 'privacy_policy' => 'Privacy Policy', + 'language' => 'Language', + 'all_rights_reserved' => 'All rights reserved.', + 'dashboard' => 'Dashboard', + 'settings' => 'Settings', + 'company_setting' => 'Company Setting', + 'integrations' => 'Integrations', + 'locations' => 'Locations', + 'countries' => 'Countries', + 'cities' => 'Cities', + 'users' => 'Users', + 'shippers' => 'Shippers', + 'truck_owners' => 'Truck Owners', + 'user_registration' => 'User Registration', + 'pages' => 'Pages', + 'faqs' => 'FAQs', + 'landing_pages' => 'Landing Pages', + 'login_title' => 'Welcome Back', + 'login_subtitle' => 'Sign in to your account to continue', + 'email_address' => 'Email address', + 'email_placeholder' => 'name@example.com', + 'password' => 'Password', + 'forgot_password' => 'Forgot password?', + 'password_placeholder' => 'Enter your password', + 'change_password' => 'Change Password', + 'new_password' => 'New Password', + 'confirm_password' => 'Confirm Password', + 'passwords_do_not_match' => 'Passwords do not match.', + 'password_too_short' => 'Password must be at least 6 characters.', + 'password_updated' => 'Password updated successfully.', + 'sign_in' => 'Sign In', + 'dont_have_account' => 'Don\'t have an account?', + 'register_now' => 'Register now', + 'reset_password_title' => 'Reset Password', + 'reset_password_subtitle' => 'Enter your email and we\'ll send you a link to reset your password', + 'send_reset_link' => 'Send Reset Link', + 'back_to_login' => 'Back to login', + 'invalid_image' => 'Invalid image format. Please upload JPG, PNG, GIF, or WEBP.', + 'upload_failed' => 'Failed to save uploaded file.', + 'profile_updated' => 'Profile updated successfully.', + 'my_profile' => 'My Profile', + 'profile_picture' => 'Profile Picture', + 'change_picture' => 'Change Picture', + 'picture_hint' => 'JPG, PNG, or GIF up to 5MB', + 'full_name' => 'Full Name', + 'email_hint' => 'Email address cannot be changed.', + 'account_role' => 'Account Role', + 'save_changes' => 'Save Changes', + 'reg_title' => 'Create your logistics account', + 'reg_subtitle' => 'Shippers and truck owners can self-register with full profile details.', + 'reg_success_pending' => 'Registration completed successfully. Your account is pending admin approval.', + 'reg_success' => 'Registration completed successfully.', + 'role' => 'Role', + 'shipper' => 'Shipper', + 'truck_owner' => 'Truck Owner', + 'email' => 'Email', + '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 owner details', + 'truck_type' => 'Truck type', + 'load_capacity' => 'Load capacity (tons)', + 'plate_no' => 'Plate number', + 'bank_account' => 'Bank Account / IBAN', + 'bank_name' => 'Bank Name', + 'bank_branch' => 'Bank Branch', + 'id_card_front' => 'ID card (Front Face)', + 'id_card_back' => 'ID card (Back Face)', + 'truck_reg_front' => 'Truck Registration (Front Face)', + 'truck_reg_back' => 'Truck Registration (Back Face)', + 'truck_picture' => 'Clear Truck Photo (showing plate number)', + 'create_account' => 'Create account', + 'back_to_admin' => 'Back to admin', + 'welcome_back' => 'Welcome to your dashboard. Manage your cargo shipments here.', + 'total_shipments_posted' => 'Total Shipments', + 'active_shipments' => 'Active Shipments', + 'delivered_shipments' => 'Delivered Shipments', + 'route_label' => 'Route', + 'total_label' => 'total', + 'welcome_back_owner' => 'Find loads and submit your best rate.', + 'total_offers' => 'Total Offers', + 'won_shipments' => 'Won Shipments', +), + "ar" => array ( + 'app_name' => 'CargoLink', + 'nav_home' => 'نظرة عامة', + 'nav_shipper' => 'لوحة الشاحن', + 'nav_owner' => 'لوحة مالك الشاحنة', + 'nav_admin' => 'لوحة الإدارة', + 'hero_title' => 'انقل شحنتك بسرعة مع شاحنات موثوقة.', + 'hero_subtitle' => 'أنشئ شحنة، استلم عروضاً، وادفع عبر ثواني أو التحويل البنكي.', + 'hero_tagline' => 'منصة لوجستية متعددة اللغات', + 'register_shipper' => 'التسجيل كشاحن', + 'register_owner' => 'التسجيل كمالك شاحنة', + 'cta_shipper' => 'إنشاء شحنة', + 'cta_owner' => 'البحث عن الشحنات', + 'cta_admin' => 'الدخول للإدارة', + 'stats_shipments' => 'الشحنات المنشورة', + 'stats_offers' => 'العروض الحالية', + 'stats_confirmed' => 'الرحلات المؤكدة', + 'section_workflow' => 'طريقة العمل', + 'recent_shipments' => 'أحدث الشحنات', + 'step_post' => 'يقوم الشاحن بإدخال تفاصيل الشحنة وطريقة الدفع.', + 'step_offer' => 'يرسل أصحاب الشاحنات أفضل عروضهم.', + 'step_confirm' => 'تؤكد الإدارة الحجز وتحدث الحالة.', + 'step_confirm_desc' => 'حجز آمن وتتبع التسليم حتى الانتهاء.', + 'shipper_dashboard' => 'لوحة الشاحن', + 'new_shipment' => 'إنشاء شحنة', + 'shipper_name' => 'اسم الشاحن', + 'shipper_company' => 'الشركة', + 'origin' => 'مدينة الانطلاق', + 'destination' => 'مدينة الوصول', + 'cargo' => 'وصف الحمولة', + 'cargo_placeholder' => 'مثال: 20 منصة إلكترونيات', + 'weight' => 'الوزن (طن)', + 'pickup_date' => 'تاريخ الاستلام', + 'delivery_date' => 'تاريخ التسليم', + 'payment_method' => 'طريقة الدفع', + 'payment_thawani' => 'الدفع الإلكتروني عبر ثواني', + 'payment_bank' => 'تحويل بنكي', + 'submit_shipment' => 'إرسال الشحنة', + 'shipments_list' => 'أحدث الشحنات', + 'status' => 'الحالة', + 'offer' => 'أفضل عرض', + 'actions' => 'إجراءات', + 'view' => 'عرض', + 'owner_dashboard' => 'لوحة مالك الشاحنة', + 'available_shipments' => 'الشحنات المتاحة', + 'offer_price' => 'سعر العرض', + 'offer_owner' => 'اسم مالك الشاحنة', + 'submit_offer' => 'إرسال العرض', + 'admin_dashboard' => 'لوحة الإدارة', + 'update_status' => 'تحديث الحالة', + 'save' => 'حفظ', + 'shipment_detail' => 'تفاصيل الشحنة', + 'created_at' => 'تم الإنشاء', + 'best_offer' => 'أفضل عرض', + 'assign_owner' => 'المالك المعتمد', + 'no_shipments' => 'لا توجد شحنات بعد. ابدأ بإنشاء أول شحنة.', + 'no_offers' => 'لا توجد عروض بعد.', + 'success_shipment' => 'تم نشر الشحنة بنجاح.', + 'success_offer' => 'تم إرسال العرض إلى الشاحن.', + 'success_status' => 'تم تحديث الحالة.', + 'error_required' => 'يرجى تعبئة جميع الحقول المطلوبة.', + 'error_invalid' => 'يرجى إدخال قيم صحيحة.', + 'status_posted' => 'منشورة', + 'status_offered' => 'بعرض', + 'status_confirmed' => 'مؤكدة', + 'status_in_transit' => 'قيد النقل', + 'status_delivered' => 'تم التسليم', + 'footer_note' => 'هذه هي النسخة الأولية. الدفع غير متصل بعد.', + 'marketing_title_1' => 'للشاحنين', + 'marketing_desc_1' => 'ابحث عن الشاحنة المناسبة لحمولتك بسرعة وأمان.', + 'marketing_title_2' => 'لأصحاب الشاحنات', + 'marketing_desc_2' => 'عظّم أرباحك وتجنب العودة فارغاً.', + 'motivation_phrase' => 'تمكين الخدمات اللوجستية للمستقبل.', + 'why_choose_us' => 'لماذا تختار كارجو لينك؟', + 'feature_1_title' => 'مطابقة سريعة', + 'feature_1_desc' => 'تواصل مع الشاحنات المتاحة في دقائق.', + 'feature_2_title' => 'مدفوعات آمنة', + 'feature_2_desc' => 'معاملاتك محمية بأعلى معايير الأمان.', + 'feature_3_title' => 'مستخدمون موثوقون', + 'feature_3_desc' => 'نقوم بالتحقق من جميع أصحاب الشاحنات لضمان راحتك.', + 'view_faq' => 'عرض الأسئلة الشائعة', + 'faq_title' => 'لديك أسئلة؟', + 'faq_subtitle' => 'اطلع على الأسئلة الشائعة لمعرفة المزيد حول كيفية عمل منصتنا.', + 'motivation_title' => 'هل أنت مستعد لتحويل خدماتك اللوجستية؟', + 'motivation_subtitle' => 'انضم إلى منصتنا اليوم للعثور على شاحنات موثوقة أو تأمين أفضل الشحنات في السوق.', + 'company' => 'الشركة', + 'about_us' => 'معلومات عنا', + 'careers' => 'الوظائف', + 'contact' => 'اتصل بنا', + 'resources' => 'الموارد', + 'help_center' => 'مركز المساعدة / الأسئلة الشائعة', + 'terms_of_service' => 'شروط الخدمة', + 'privacy_policy' => 'سياسة الخصوصية', + 'language' => 'اللغة', + 'all_rights_reserved' => 'جميع الحقوق محفوظة.', + 'dashboard' => 'لوحة القيادة', + 'settings' => 'الإعدادات', + 'company_setting' => 'إعدادات الشركة', + 'integrations' => 'التكاملات', + 'locations' => 'المواقع', + 'countries' => 'البلدان', + 'cities' => 'المدن', + 'users' => 'المستخدمون', + 'shippers' => 'الشاحنون', + 'truck_owners' => 'أصحاب الشاحنات', + 'user_registration' => 'تسجيل المستخدم', + 'pages' => 'الصفحات', + 'faqs' => 'الأسئلة الشائعة', + 'landing_pages' => 'صفحات الهبوط', + 'login_title' => 'مرحبًا بعودتك', + 'login_subtitle' => 'قم بتسجيل الدخول إلى حسابك للمتابعة', + 'email_address' => 'البريد الإلكتروني', + 'email_placeholder' => 'name@example.com', + 'password' => 'كلمة المرور', + 'forgot_password' => 'هل نسيت كلمة المرور؟', + 'password_placeholder' => 'أدخل كلمة المرور', + 'change_password' => 'تغيير كلمة المرور', + 'new_password' => 'كلمة المرور الجديدة', + 'confirm_password' => 'تأكيد كلمة المرور', + 'passwords_do_not_match' => 'كلمات المرور غير متطابقة.', + 'password_too_short' => 'يجب أن تتكون كلمة المرور من 6 أحرف على الأقل.', + 'password_updated' => 'تم تحديث كلمة المرور بنجاح.', + 'sign_in' => 'تسجيل الدخول', + 'dont_have_account' => 'ليس لديك حساب؟', + 'register_now' => 'سجل الآن', + 'reset_password_title' => 'إعادة تعيين كلمة المرور', + 'reset_password_subtitle' => 'أدخل بريدك الإلكتروني وسنرسل لك رابطًا لإعادة تعيين كلمة المرور', + 'send_reset_link' => 'إرسال رابط إعادة التعيين', + 'back_to_login' => 'العودة لتسجيل الدخول', + 'invalid_image' => 'صيغة صورة غير صالحة. يرجى تحميل JPG أو PNG أو GIF أو WEBP.', + 'upload_failed' => 'فشل في حفظ الملف المحمل.', + 'profile_updated' => 'تم تحديث الملف الشخصي بنجاح.', + 'my_profile' => 'ملفي الشخصي', + 'profile_picture' => 'صورة الملف الشخصي', + 'change_picture' => 'تغيير الصورة', + 'picture_hint' => 'JPG، PNG، أو GIF حتى 5 ميغابايت', + 'full_name' => 'الاسم الكامل', + 'email_hint' => 'لا يمكن تغيير عنوان البريد الإلكتروني.', + 'account_role' => 'دور الحساب', + 'save_changes' => 'حفظ التغييرات', + 'reg_title' => 'أنشئ حسابك اللوجستي', + 'reg_subtitle' => 'يمكن للشاحنين وأصحاب الشاحنات التسجيل الذاتي ببيانات الملف الشخصي الكاملة.', + 'reg_success_pending' => 'اكتمل التسجيل بنجاح. حسابك في انتظار موافقة الإدارة.', + 'reg_success' => 'اكتمل التسجيل بنجاح.', + 'role' => 'الدور', + 'shipper' => 'شاحن', + 'truck_owner' => 'مالك شاحنة', + 'email' => 'البريد الإلكتروني', + 'phone' => 'الهاتف', + 'country' => 'البلد', + 'select_country' => 'اختر البلد', + 'city' => 'المدينة', + 'select_city' => 'اختر المدينة', + 'address' => 'العنوان', + 'shipper_details' => 'تفاصيل الشاحن', + 'company_name' => 'اسم الشركة', + 'truck_details' => 'تفاصيل مالك الشاحنة', + 'truck_type' => 'نوع الشاحنة', + 'load_capacity' => 'سعة الحمولة (طن)', + 'plate_no' => 'رقم اللوحة', + 'bank_account' => 'الحساب البنكي / الآيبان', + 'bank_name' => 'اسم البنك', + 'bank_branch' => 'فرع البنك', + 'id_card_front' => 'البطاقة الشخصية (الوجه الأمامي)', + 'id_card_back' => 'البطاقة الشخصية (الوجه الخلفي)', + 'truck_reg_front' => 'تسجيل الشاحنة (الوجه الأمامي)', + 'truck_reg_back' => 'تسجيل الشاحنة (الوجه الخلفي)', + 'truck_picture' => 'صورة واضحة للشاحنة (تظهر رقم اللوحة)', + 'create_account' => 'إنشاء حساب', + 'back_to_admin' => 'العودة للإدارة', + 'welcome_back' => 'مرحبًا بك في لوحة القيادة الخاصة بك. قم بإدارة شحناتك هنا.', + 'total_shipments_posted' => 'إجمالي الشحنات', + 'active_shipments' => 'الشحنات النشطة', + 'delivered_shipments' => 'الشحنات المسلمة', + 'route_label' => 'المسار', + 'total_label' => 'المجموع', + 'welcome_back_owner' => 'ابحث عن الأحمال وقدم أفضل سعر لديك.', + 'total_offers' => 'إجمالي العروض', + 'won_shipments' => 'الشحنات الفائزة', +) ]; function t(string $key): string @@ -164,8 +388,7 @@ function e($value): string function ensure_schema(): void { - db()->exec(" - CREATE TABLE IF NOT EXISTS landing_sections ( + db()->exec("\n CREATE TABLE IF NOT EXISTS landing_sections ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255) NOT NULL, subtitle TEXT NULL, @@ -179,6 +402,11 @@ function ensure_schema(): void 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 = <<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) {} + 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) {} @@ -320,4 +548,4 @@ function get_setting(string $key, $default = ''): string { $settings = get_settings(); return $settings[$key] ?? $default; -} \ No newline at end of file +} diff --git a/includes/layout.php b/includes/layout.php index 9f4b362..267e0bd 100644 --- a/includes/layout.php +++ b/includes/layout.php @@ -1,7 +1,7 @@ "> - -
+
-