-
Analyzing your requirements and generating your website…
-
- Loading…
-
-
= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.
-
This page will update automatically as the plan is implemented.
-
Runtime: PHP = htmlspecialchars($phpVersion) ?> — UTC = htmlspecialchars($now) ?>
+
+
+
+
+
= e(t('hero_tagline')) ?>
+
= e(t('hero_title')) ?>
+
= e(t('hero_subtitle')) ?>
+
+
+
+
+
+
+
= e(t('stats_shipments')) ?>
+
= e($stats['shipments']) ?>
+
+
+
+
+
= e(t('stats_offers')) ?>
+
= e($stats['offers']) ?>
+
+
+
+
+
= e(t('stats_confirmed')) ?>
+
= e($stats['confirmed']) ?>
+
+
+
+
-
-
-
-
+
+
+
+ = e(t('section_workflow')) ?>
+
+
+
+
1
+
= e(t('step_post')) ?>
+
+
+
+
+
2
+
= e(t('step_offer')) ?>
+
+
+
+
+
3
+
= e(t('step_confirm')) ?>
+
+
+
+
+
+
+
+
= e(t('recent_shipments')) ?>
+
= e(t('cta_shipper')) ?>
+
+
+ = e(t('no_shipments')) ?>
+
+
+
+
+
+ | = e(t('shipper_company')) ?> |
+ = e(t('origin')) ?> |
+ = e(t('destination')) ?> |
+ = e(t('status')) ?> |
+ = e(t('actions')) ?> |
+
+
+
+
+
+ | = e($row['shipper_company']) ?> |
+ = e($row['origin_city']) ?> |
+ = e($row['destination_city']) ?> |
+ = e(status_label($row['status'])) ?> |
+
+
+ = e(t('view')) ?>
+
+ |
+
+
+
+
+
+
+
+
+
diff --git a/register.php b/register.php
new file mode 100644
index 0000000..d9b086a
--- /dev/null
+++ b/register.php
@@ -0,0 +1,200 @@
+prepare("INSERT INTO users (email, password, role) VALUES (?, ?, ?)");
+ $stmt->execute([$email, $password, $role]);
+ $userId = (int)db()->lastInsertId();
+
+ if ($role === 'truck_owner') {
+ $truckType = trim($_POST['truck_type'] ?? '');
+ $loadCapacity = trim($_POST['load_capacity'] ?? '');
+ $plateNo = trim($_POST['plate_no'] ?? '');
+
+ if ($truckType === '' || $loadCapacity === '' || $plateNo === '') {
+ $errors[] = 'Please complete truck details.';
+ } elseif (!is_numeric($loadCapacity)) {
+ $errors[] = 'Load capacity must be numeric.';
+ }
+
+ if (!$errors) {
+ $uploadDir = __DIR__ . '/uploads/profiles/' . $userId . '/';
+ if (!is_dir($uploadDir)) {
+ mkdir($uploadDir, 0775, true);
+ }
+
+ $allowed = ['image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp'];
+ $saveImage = static function (string $tmpName, string $prefix) use ($uploadDir, $allowed): ?string {
+ $mime = mime_content_type($tmpName) ?: '';
+ if (!isset($allowed[$mime])) {
+ return null;
+ }
+ $filename = uniqid($prefix, true) . '.' . $allowed[$mime];
+ $target = $uploadDir . $filename;
+ if (!move_uploaded_file($tmpName, $target)) {
+ return null;
+ }
+ return 'uploads/profiles/' . basename($uploadDir) . '/' . $filename;
+ };
+
+ $idCardPaths = [];
+ foreach (array_slice($_FILES['id_card']['tmp_name'] ?? [], 0, 2) as $tmp) {
+ if (!is_uploaded_file($tmp)) {
+ continue;
+ }
+ $path = $saveImage($tmp, 'id_');
+ if ($path) {
+ $idCardPaths[] = $path;
+ }
+ }
+
+ $regPaths = [];
+ foreach (array_slice($_FILES['registration']['tmp_name'] ?? [], 0, 2) as $tmp) {
+ if (!is_uploaded_file($tmp)) {
+ continue;
+ }
+ $path = $saveImage($tmp, 'reg_');
+ if ($path) {
+ $regPaths[] = $path;
+ }
+ }
+
+ $truckPic = null;
+ $truckTmp = $_FILES['truck_picture']['tmp_name'] ?? '';
+ if (is_uploaded_file($truckTmp)) {
+ $truckPic = $saveImage($truckTmp, 'truck_');
+ }
+
+ if (count($idCardPaths) < 2 || count($regPaths) < 2 || !$truckPic) {
+ $errors[] = 'Please upload all required truck-owner images (ID front/back, registration front/back, truck photo).';
+ } else {
+ $profileStmt = db()->prepare(
+ "INSERT INTO truck_owner_profiles (user_id, truck_type, load_capacity, plate_no, id_card_path, truck_pic_path, registration_path)
+ VALUES (?, ?, ?, ?, ?, ?, ?)"
+ );
+ $profileStmt->execute([
+ $userId,
+ $truckType,
+ $loadCapacity,
+ $plateNo,
+ json_encode($idCardPaths, JSON_UNESCAPED_SLASHES),
+ $truckPic,
+ json_encode($regPaths, JSON_UNESCAPED_SLASHES),
+ ]);
+ }
+ }
+ }
+
+ if (!$errors) {
+ $saved = true;
+ }
+ }
+}
+
+render_header('Register Account');
+?>
+
+
+
Create account
+
Register as a shipper or truck owner using a clean onboarding form.
+
+
+
+
+
Registration completed successfully.
+
+
+
= e(implode(' ', $errors)) ?>
+
+
+
+
+
+
+
+
diff --git a/shipment_detail.php b/shipment_detail.php
new file mode 100644
index 0000000..46dd63a
--- /dev/null
+++ b/shipment_detail.php
@@ -0,0 +1,134 @@
+ 0) {
+ $stmt = db()->prepare("SELECT * FROM shipments WHERE id = :id");
+ $stmt->execute([':id' => $shipmentId]);
+ $shipment = $stmt->fetch();
+}
+
+$errors = [];
+if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'submit_offer') {
+ $offerOwner = trim($_POST['offer_owner'] ?? '');
+ $offerPrice = trim($_POST['offer_price'] ?? '');
+ if ($offerOwner === '' || $offerPrice === '') {
+ $errors[] = t('error_required');
+ } elseif (!is_numeric($offerPrice)) {
+ $errors[] = t('error_invalid');
+ } else {
+ $stmt = db()->prepare(
+ "UPDATE shipments SET offer_owner = :offer_owner, offer_price = :offer_price, status = 'offered'
+ WHERE id = :id"
+ );
+ $stmt->execute([
+ ':offer_owner' => $offerOwner,
+ ':offer_price' => $offerPrice,
+ ':id' => $shipmentId,
+ ]);
+ set_flash('success', t('success_offer'));
+ header('Location: ' . url_with_lang('shipment_detail.php', ['id' => $shipmentId]));
+ exit;
+ }
+}
+
+$flash = get_flash();
+
+render_header(t('shipment_detail'));
+?>
+
+
+
+
= e(t('no_shipments')) ?>
+
+
+
+
+
+
+
+
= e(t('shipment_detail')) ?> #= e($shipment['id']) ?>
+
= e(t('created_at')) ?>: = e($shipment['created_at']) ?>
+
+
= e(status_label($shipment['status'])) ?>
+
+
+
+
= e(t('shipper_company')) ?>
+
= e($shipment['shipper_company']) ?>
+
+
+
= e(t('shipper_name')) ?>
+
= e($shipment['shipper_name']) ?>
+
+
+
= e(t('origin')) ?>
+
= e($shipment['origin_city']) ?>
+
+
+
= e(t('destination')) ?>
+
= e($shipment['destination_city']) ?>
+
+
+
= e(t('cargo')) ?>
+
= e($shipment['cargo_description']) ?>
+
+
+
= e(t('weight')) ?>
+
= e($shipment['weight_tons']) ?>
+
+
+
= e(t('pickup_date')) ?>
+
= e($shipment['pickup_date']) ?>
+
+
+
= e(t('delivery_date')) ?>
+
= e($shipment['delivery_date']) ?>
+
+
+
= e(t('payment_method')) ?>
+
= e($shipment['payment_method'] === 'bank_transfer' ? t('payment_bank') : t('payment_thawani')) ?>
+
+
+
= e(t('best_offer')) ?>
+
= $shipment['offer_price'] ? e($shipment['offer_price'] . ' / ' . ($shipment['offer_owner'] ?? '')) : e(t('no_offers')) ?>
+
+
+
+
+
+
+
+
= e(t('submit_offer')) ?>
+
+
= e($flash['message']) ?>
+
+
+
= e(implode(' ', $errors)) ?>
+
+
+
+
+
+
+
+
diff --git a/shipper_dashboard.php b/shipper_dashboard.php
new file mode 100644
index 0000000..34fe5de
--- /dev/null
+++ b/shipper_dashboard.php
@@ -0,0 +1,164 @@
+prepare(
+ "INSERT INTO shipments (shipper_name, shipper_company, origin_city, destination_city, cargo_description, weight_tons, pickup_date, delivery_date, payment_method)
+ VALUES (:shipper_name, :shipper_company, :origin_city, :destination_city, :cargo_description, :weight_tons, :pickup_date, :delivery_date, :payment_method)"
+ );
+ $stmt->execute([
+ ':shipper_name' => $shipperName,
+ ':shipper_company' => $shipperCompany,
+ ':origin_city' => $origin,
+ ':destination_city' => $destination,
+ ':cargo_description' => $cargo,
+ ':weight_tons' => $weight,
+ ':pickup_date' => $pickupDate,
+ ':delivery_date' => $deliveryDate,
+ ':payment_method' => $payment,
+ ]);
+ $_SESSION['shipper_name'] = $shipperName;
+ set_flash('success', t('success_shipment'));
+ header('Location: ' . url_with_lang('shipper_dashboard.php'));
+ exit;
+ }
+}
+
+$shipments = [];
+try {
+ $stmt = db()->query("SELECT * FROM shipments ORDER BY created_at DESC LIMIT 20");
+ $shipments = $stmt->fetchAll();
+} catch (Throwable $e) {
+ $shipments = [];
+}
+
+render_header(t('shipper_dashboard'), 'shipper');
+
+$flash = get_flash();
+?>
+
+
+
+
+
= e(t('new_shipment')) ?>
+
+
= e($flash['message']) ?>
+
+
+
= e(implode(' ', $errors)) ?>
+
+
+
+
+
+
+
+
= e(t('shipments_list')) ?>
+ = e(count($shipments)) ?> total
+
+
+
= e(t('no_shipments')) ?>
+
+
+
+
+
+ | = e(t('origin')) ?> |
+ = e(t('destination')) ?> |
+ = e(t('status')) ?> |
+ = e(t('offer')) ?> |
+ = e(t('actions')) ?> |
+
+
+
+
+
+ | = e($row['origin_city']) ?> |
+ = e($row['destination_city']) ?> |
+ = e(status_label($row['status'])) ?> |
+ = $row['offer_price'] ? e($row['offer_price'] . ' / ' . ($row['offer_owner'] ?? '')) : e(t('no_offers')) ?> |
+
+
+ = e(t('view')) ?>
+
+ |
+
+
+
+
+
+
+
+
+
+
+
diff --git a/truck_owner_dashboard.php b/truck_owner_dashboard.php
new file mode 100644
index 0000000..960c175
--- /dev/null
+++ b/truck_owner_dashboard.php
@@ -0,0 +1,110 @@
+prepare(
+ "UPDATE shipments SET offer_owner = :offer_owner, offer_price = :offer_price, status = 'offered'
+ WHERE id = :id AND status IN ('posted','offered')"
+ );
+ $stmt->execute([
+ ':offer_owner' => $offerOwner,
+ ':offer_price' => $offerPrice,
+ ':id' => $shipmentId,
+ ]);
+ if ($stmt->rowCount() > 0) {
+ set_flash('success', t('success_offer'));
+ header('Location: ' . url_with_lang('truck_owner_dashboard.php'));
+ exit;
+ } else {
+ $errors[] = t('error_invalid');
+ }
+ }
+}
+
+$shipments = [];
+try {
+ $stmt = db()->query("SELECT * FROM shipments WHERE status IN ('posted','offered') ORDER BY created_at DESC LIMIT 20");
+ $shipments = $stmt->fetchAll();
+} catch (Throwable $e) {
+ $shipments = [];
+}
+
+render_header(t('owner_dashboard'), 'owner');
+
+$flash = get_flash();
+?>
+
+
+
+
= e(t('available_shipments')) ?>
+ = e(count($shipments)) ?> total
+
+
+
= e($flash['message']) ?>
+
+
+
= e(implode(' ', $errors)) ?>
+
+
+
= e(t('no_shipments')) ?>
+
+
+
+
+
+ | = e(t('shipper_company')) ?> |
+ = e(t('origin')) ?> |
+ = e(t('destination')) ?> |
+ = e(t('weight')) ?> |
+ = e(t('offer')) ?> |
+ = e(t('actions')) ?> |
+
+
+
+
+
+ | = e($row['shipper_company']) ?> |
+ = e($row['origin_city']) ?> |
+ = e($row['destination_city']) ?> |
+ = e($row['weight_tons']) ?> |
+ = $row['offer_price'] ? e($row['offer_price'] . ' / ' . ($row['offer_owner'] ?? '')) : e(t('no_offers')) ?> |
+
+
+ |
+
+
+
+
+
+
+
+
+