diff --git a/admin_company_profile.php b/admin_company_profile.php new file mode 100644 index 0000000..128f35c --- /dev/null +++ b/admin_company_profile.php @@ -0,0 +1,155 @@ + $companyName, + 'company_email' => $companyEmail, + 'company_phone' => $companyPhone, + 'company_address' => $companyAddress, + ]; + + // Handle file uploads + $uploadDir = __DIR__ . '/uploads/logos/'; + if (!is_dir($uploadDir)) { + mkdir($uploadDir, 0775, true); + } + + if (isset($_FILES['logo_file']) && $_FILES['logo_file']['error'] === UPLOAD_ERR_OK) { + $tmpName = $_FILES['logo_file']['tmp_name']; + $ext = strtolower(pathinfo($_FILES['logo_file']['name'], PATHINFO_EXTENSION)); + $allowedExt = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp']; + if (in_array($ext, $allowedExt, true)) { + $logoName = 'logo_' . time() . '.' . $ext; + $dest = $uploadDir . $logoName; + if (move_uploaded_file($tmpName, $dest)) { + $updates['logo_path'] = '/uploads/logos/' . $logoName; + } + } else { + $errors[] = "Invalid logo format."; + } + } + + if (isset($_FILES['favicon_file']) && $_FILES['favicon_file']['error'] === UPLOAD_ERR_OK) { + $tmpName = $_FILES['favicon_file']['tmp_name']; + $ext = strtolower(pathinfo($_FILES['favicon_file']['name'], PATHINFO_EXTENSION)); + $allowedExt = ['ico', 'png', 'svg', 'gif']; + if (in_array($ext, $allowedExt, true)) { + $faviconName = 'favicon_' . time() . '.' . $ext; + $dest = $uploadDir . $faviconName; + if (move_uploaded_file($tmpName, $dest)) { + $updates['favicon_path'] = '/uploads/logos/' . $faviconName; + } + } else { + $errors[] = "Invalid favicon format."; + } + } + + if (empty($errors)) { + $pdo = db(); + foreach ($updates as $key => $val) { + $stmt = $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (:k, :v) ON DUPLICATE KEY UPDATE setting_value = :v2"); + $stmt->execute([':k' => $key, ':v' => $val, ':v2' => $val]); + } + $success = "Company profile updated successfully."; + } +} + +// Fetch current settings +$settings = get_settings(); +$currentName = $settings['company_name'] ?? t('app_name'); +$currentEmail = $settings['company_email'] ?? ''; +$currentPhone = $settings['company_phone'] ?? ''; +$currentAddress = $settings['company_address'] ?? ''; +$currentLogo = $settings['logo_path'] ?? ''; +$currentFavicon = $settings['favicon_path'] ?? ''; + +render_header('Company Profile', 'admin'); +?> + +
+
+ +
+
+
+

Company Profile

+

Update your app name, logo, favicon, and contact details.

+
+ + +
+ + +
', $errors)) ?>
+ + +
+
+
+
+ + +
+ +
+ + +
Displayed in the footer.
+
+ +
+ + +
Displayed in the footer.
+
+ +
+ + +
Displayed in the footer.
+
+ +
+ + +
+ Logo +
+ + +
Recommended size: 150x40px (PNG, JPG, SVG). Leave empty to keep current.
+
+ +
+ + +
+ Favicon +
+ + +
Recommended size: 32x32px (ICO, PNG, SVG). Leave empty to keep current.
+
+
+ +
+ +
+
+
+
+ + diff --git a/admin_integrations.php b/admin_integrations.php new file mode 100644 index 0000000..dc1a4c2 --- /dev/null +++ b/admin_integrations.php @@ -0,0 +1,130 @@ + trim($_POST['thawani_publishable_key'] ?? ''), + 'thawani_secret_key' => trim($_POST['thawani_secret_key'] ?? ''), + 'thawani_environment' => trim($_POST['thawani_environment'] ?? 'test'), + 'wablas_domain' => trim($_POST['wablas_domain'] ?? ''), + 'wablas_api_token' => trim($_POST['wablas_api_token'] ?? ''), + 'wablas_secret_key' => trim($_POST['wablas_secret_key'] ?? ''), + ]; + + if (empty($errors)) { + $pdo = db(); + foreach ($updates as $key => $val) { + $stmt = $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (:k, :v) ON DUPLICATE KEY UPDATE setting_value = :v2"); + $stmt->execute([':k' => $key, ':v' => $val, ':v2' => $val]); + } + $success = "Integrations settings updated successfully."; + } +} + +$settings = get_settings(); +$thawaniPub = $settings['thawani_publishable_key'] ?? ''; +$thawaniSec = $settings['thawani_secret_key'] ?? ''; +$thawaniEnv = $settings['thawani_environment'] ?? 'test'; +$wablasDomain = $settings['wablas_domain'] ?? ''; +$wablasToken = $settings['wablas_api_token'] ?? ''; +$wablasSecret = $settings['wablas_secret_key'] ?? ''; + +render_header('Integrations', 'admin'); +?> + +
+
+ +
+
+
+

Integrations

+

Manage your payment gateway and communication APIs.

+
+ + +
+ + +
', $errors)) ?>
+ + +
+ +
+

+ + + + + Thawani Payments Gateway +

+

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

+ +
+
+ + +
+
+ +
+ + +
+ +
+ + +
+
+
+ + +
+

+ + + + Wablas WhatsApp Gateway +

+

Connect Wablas to automatically send WhatsApp notifications to Shippers and Truck Owners.

+ +
+
+ + +
Your assigned server node from the Wablas dashboard.
+
+ +
+ + +
+ +
+ + +
Optional. Provide if your Wablas webhooks require signature verification.
+
+
+
+ +
+ +
+
+
+
+ + \ No newline at end of file diff --git a/admin_shippers.php b/admin_shippers.php index e39ccb8..9f9250f 100644 --- a/admin_shippers.php +++ b/admin_shippers.php @@ -140,7 +140,7 @@ render_header('Manage Shippers', 'admin');
- + diff --git a/admin_truck_owner_edit.php b/admin_truck_owner_edit.php index 0fa8b14..dd2929c 100644 --- a/admin_truck_owner_edit.php +++ b/admin_truck_owner_edit.php @@ -16,7 +16,8 @@ $flash = null; $stmt = db()->prepare(" SELECT u.id, u.email, u.full_name, u.status, u.role, p.phone, p.address_line, p.country_id, p.city_id, - p.truck_type, p.load_capacity, p.plate_no + p.truck_type, p.load_capacity, p.plate_no, + p.id_card_path, p.truck_pic_path, p.registration_path FROM users u LEFT JOIN truck_owner_profiles p ON u.id = p.user_id WHERE u.id = ? AND u.role = 'truck_owner' @@ -107,6 +108,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { } } +$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'); ?> @@ -197,6 +202,48 @@ render_header('Edit Truck Owner', 'admin');
+
Uploaded Documents
+
+
+
ID Card
+ +
+ +

No ID card uploaded.

+ +
+
+
Truck Picture
+ + + Truck Picture + + +

No picture uploaded.

+ +
+
+
Registration
+ +
+ + + Registration + + +
+ +

No registration uploaded.

+ +
+
+
Cancel diff --git a/admin_truck_owners.php b/admin_truck_owners.php index 5c6201d..b51555d 100644 --- a/admin_truck_owners.php +++ b/admin_truck_owners.php @@ -148,7 +148,7 @@ render_header('Manage Truck Owners', 'admin');
- + diff --git a/assets/images/hero_trucks.jpg b/assets/images/hero_trucks.jpg new file mode 100644 index 0000000..8615e2a Binary files /dev/null and b/assets/images/hero_trucks.jpg differ diff --git a/assets/images/workflow_trucks.jpg b/assets/images/workflow_trucks.jpg new file mode 100644 index 0000000..76068ad Binary files /dev/null and b/assets/images/workflow_trucks.jpg differ diff --git a/db/migrations/add_settings_table.php b/db/migrations/add_settings_table.php new file mode 100644 index 0000000..3b53e07 --- /dev/null +++ b/db/migrations/add_settings_table.php @@ -0,0 +1,22 @@ +exec(" + CREATE TABLE IF NOT EXISTS settings ( + setting_key VARCHAR(50) PRIMARY KEY, + setting_value TEXT + ); + INSERT IGNORE INTO settings (setting_key, setting_value) VALUES + ('company_name', 'My Transport Company'), + ('company_email', 'info@example.com'), + ('company_phone', '+1234567890'), + ('company_address', '123 Transport St, City, Country'), + ('logo_path', ''), + ('favicon_path', ''); + "); + echo "Settings table created.\n"; +} catch (Exception $e) { + echo "Error: " . $e->getMessage() . "\n"; +} + diff --git a/includes/app.php b/includes/app.php index 21f7776..ad1ec88 100644 --- a/includes/app.php +++ b/includes/app.php @@ -273,3 +273,26 @@ function status_label(string $status): string ]; return $map[$status] ?? $status; } + +function get_settings(): array +{ + static $settings = null; + if ($settings !== null) { + return $settings; + } + $settings = []; + try { + $stmt = db()->query("SELECT setting_key, setting_value FROM settings"); + while ($row = $stmt->fetch()) { + $settings[$row['setting_key']] = $row['setting_value']; + } + } catch (Throwable $e) { + } + return $settings; +} + +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 a83b3a9..983bee1 100644 --- a/includes/layout.php +++ b/includes/layout.php @@ -8,13 +8,20 @@ function render_header(string $title, string $active = ''): void $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? ''; $toggleLang = $lang === 'ar' ? 'en' : 'ar'; $toggleLabel = $lang === 'ar' ? 'EN' : 'AR'; + + $appName = get_setting('company_name', t('app_name')); + $logoPath = get_setting('logo_path'); + $faviconPath = get_setting('favicon_path'); ?> - <?= e($title) ?> + <?= e($title) ?> | <?= e($appName) ?> + + + @@ -25,16 +32,21 @@ function render_header(string $title, string $active = ''): void +
@@ -134,7 +134,7 @@ render_header(t('app_name'), 'home');
- Logistics + Logistics