111 lines
3.1 KiB
Vue
111 lines
3.1 KiB
Vue
<script setup>
|
|
import { Link } from "@inertiajs/vue3";
|
|
import { computed } from "vue";
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/Components/ui/card";
|
|
import AppCard from "@/Components/app/ui/card/AppCard.vue";
|
|
import { ChevronRightIcon, MapIcon, UserRound } from "lucide-vue-next";
|
|
import { ScrollArea } from "@/Components/ui/scroll-area";
|
|
import {
|
|
Item,
|
|
ItemActions,
|
|
ItemContent,
|
|
ItemDescription,
|
|
ItemMedia,
|
|
ItemTitle,
|
|
} from "@/Components/ui/item";
|
|
import { Badge } from "@/Components/ui/badge";
|
|
|
|
const props = defineProps({
|
|
fieldJobsAssignedToday: Array,
|
|
});
|
|
|
|
// 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 "";
|
|
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 "";
|
|
}
|
|
}
|
|
|
|
// Safely build a client case href using Ziggy when available, with a plain fallback.
|
|
function safeCaseHref(uuid, segment = null) {
|
|
if (!uuid) {
|
|
return "#";
|
|
}
|
|
try {
|
|
const params = { client_case: uuid };
|
|
if (segment != null) {
|
|
params.segment = segment;
|
|
}
|
|
return String(route("clientCase.show", params));
|
|
} catch (e) {
|
|
return segment != null
|
|
? `/client-cases/${uuid}?segment=${segment}`
|
|
: `/client-cases/${uuid}`;
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<AppCard
|
|
title=""
|
|
padding="none"
|
|
class="p-0! gap-2"
|
|
header-class="py-3! px-4 border-b gap-0 text-muted-foreground"
|
|
body-class="flex flex-col gap-4"
|
|
>
|
|
<template #header>
|
|
<div class="flex items-center gap-2">
|
|
<MapIcon size="18" />
|
|
<CardTitle class="text-muted-foreground uppercase"> Današnji teren </CardTitle>
|
|
</div>
|
|
</template>
|
|
<ScrollArea
|
|
class="h-96 w-full"
|
|
v-if="fieldJobsAssignedToday && fieldJobsAssignedToday.length > 0"
|
|
>
|
|
<div class="flex flex-col gap-1 px-1">
|
|
<Item
|
|
v-for="f in fieldJobsAssignedToday"
|
|
:key="f.id"
|
|
variant="outline"
|
|
size="sm"
|
|
as-child
|
|
>
|
|
<a :href="safeCaseHref(f.contract.client_case_uuid, f.contract.segment_id)">
|
|
<ItemMedia>
|
|
<span class="w-2 h-2 mt-2 rounded-full bg-primary" />
|
|
</ItemMedia>
|
|
<ItemContent>
|
|
<ItemTitle>
|
|
<span>{{ f.contract.person_full_name }}</span>
|
|
</ItemTitle>
|
|
<ItemDescription class="flex gap-1">
|
|
<Badge>{{ f.contract.reference }}</Badge>
|
|
<Badge variant="outline">{{ formatJobTime(f.created_at) }}</Badge>
|
|
</ItemDescription>
|
|
</ItemContent>
|
|
<ItemActions>
|
|
<ChevronRightIcon class="size-4" />
|
|
</ItemActions>
|
|
</a>
|
|
</Item>
|
|
</div>
|
|
</ScrollArea>
|
|
<div
|
|
v-if="!fieldJobsAssignedToday?.length"
|
|
class="py-4 text-xs text-gray-500 text-center"
|
|
>
|
|
Ni zabeleženih primerov.
|
|
</div>
|
|
</AppCard>
|
|
</template>
|