From c8029c9eb0982ecc353a53eb8b9c9854520424cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Pocrnji=C4=8D?= Date: Thu, 9 Oct 2025 01:05:17 +0200 Subject: [PATCH] Teren dodeljen danes statistika --- app/Http/Controllers/DashboardController.php | 32 +++++++++- app/Models/FieldJob.php | 6 +- resources/js/Pages/Dashboard.vue | 66 +++++++++++++++----- 3 files changed, 86 insertions(+), 18 deletions(-) diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index e3151d1..15aa7b1 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -129,9 +129,39 @@ public function __invoke(): Response $fieldJobsAssignedToday = FieldJob::query() ->whereDate(DB::raw('COALESCE(assigned_at, created_at)'), $today) ->select(['id', 'assigned_user_id', 'priority', 'assigned_at', 'created_at', 'contract_id']) + ->with(['contract' => function ($q) { + $q->select('id', 'uuid', 'reference', 'client_case_id') + ->with(['clientCase:id,uuid,person_id', 'clientCase.person:id,full_name', 'segments:id,name']); + }]) ->latest(DB::raw('COALESCE(assigned_at, created_at)')) ->limit(15) - ->get(); + ->get() + ->map(function ($fj) { + $contract = $fj->contract; + $segmentId = null; + if ($contract && method_exists($contract, 'segments')) { + // Determine active segment via pivot active flag if present + $activeSeg = $contract->segments->first(); + if ($activeSeg && isset($activeSeg->pivot) && ($activeSeg->pivot->active ?? true)) { + $segmentId = $activeSeg->id; + } + } + + return [ + 'id' => $fj->id, + 'priority' => $fj->priority, + // Normalize to ISO8601 strings so FE retains timezone & time component + 'assigned_at' => $fj->assigned_at?->toIso8601String(), + 'created_at' => $fj->created_at?->toIso8601String(), + 'contract' => $contract ? [ + 'uuid' => $contract->uuid, + 'reference' => $contract->reference, + 'client_case_uuid' => optional($contract->clientCase)->uuid, + 'person_full_name' => optional(optional($contract->clientCase)->person)->full_name, + 'segment_id' => $segmentId, + ] : null, + ]; + }); // Imports in progress (queued / processing) $importsInProgress = Import::query() diff --git a/app/Models/FieldJob.php b/app/Models/FieldJob.php index f2cfeaa..179d44a 100644 --- a/app/Models/FieldJob.php +++ b/app/Models/FieldJob.php @@ -27,9 +27,9 @@ class FieldJob extends Model ]; protected $casts = [ - 'assigned_at' => 'date', - 'completed_at' => 'date', - 'cancelled_at' => 'date', + 'assigned_at' => 'datetime', + 'completed_at' => 'datetime', + 'cancelled_at' => 'datetime', 'priority' => 'boolean', 'address_snapshot ' => 'array', ]; diff --git a/resources/js/Pages/Dashboard.vue b/resources/js/Pages/Dashboard.vue index 742aac2..e415455 100644 --- a/resources/js/Pages/Dashboard.vue +++ b/resources/js/Pages/Dashboard.vue @@ -115,6 +115,23 @@ function formatStaleDaysLabel(value) { const whole = Math.floor(num); return whole === 1 ? "1 dan" : whole + " dni"; } + +// Robust time formatter to avoid fixed 02:00:00 (timezone / fallback issues) +function formatJobTime(ts) { + if (!ts) return ""; + try { + const d = new Date(ts); + if (isNaN(d.getTime())) return ""; + // Show HH:MM (24h) and seconds only if non-zero seconds + const pad = (n) => n.toString().padStart(2, "0"); + const h = pad(d.getHours()); + const m = pad(d.getMinutes()); + const s = d.getSeconds(); + return s ? `${h}:${m}:${pad(s)}` : `${h}:${m}`; + } catch (e) { + return ""; + } +}