Files
Teren-app/resources/js/Pages/Phone/Partials/JobCard.vue
T
Simon Pocrnjič ea9376c713 Phone view update
2026-06-20 23:42:43 +02:00

99 lines
3.3 KiB
Vue

<script setup>
import { computed } from "vue";
import { CalendarDays, ChevronRight, MapPin, Phone, Wallet } from "lucide-vue-next";
import { fmtDateDMY } from "@/Utilities/functions";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/Components/ui/card";
import { Badge } from "@/Components/ui/badge";
import { Separator } from "@/Components/ui/separator";
import { cn } from "@/lib/utils";
const props = defineProps({
job: { type: Object, required: true },
href: { type: String, default: null },
accentClass: { type: String, default: "border-blue-500" },
showLastActivity: { type: Boolean, default: false },
});
const person = computed(() => props.job.contract?.client_case?.person);
const clientName = computed(
() => props.job.contract?.client_case?.client?.person?.full_name
);
const address = computed(() => person.value?.address?.address);
const phone = computed(() => person.value?.phones?.[0]?.nu);
const balance = computed(() => props.job.contract?.account?.balance_amount);
function formatAmount(val) {
if (val === null || val === undefined) return "0,00";
const num = typeof val === "number" ? val : parseFloat(val);
if (Number.isNaN(num)) return String(val);
return num.toLocaleString("sl-SI", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
}
const dateLabel = computed(() =>
props.showLastActivity && props.job.last_activity
? fmtDateDMY(props.job.last_activity)
: fmtDateDMY(props.job.assigned_at)
);
</script>
<template>
<component
:is="href ? 'a' : 'div'"
:href="href ?? undefined"
:class="
href ? 'block active:scale-[0.99] transition-transform duration-100' : 'opacity-60'
"
>
<Card class="py-0! overflow-hidden gap-2">
<CardHeader :class="cn('p-3 py-2! border-b-2', accentClass)">
<CardTitle class="flex justify-between items-center">
<span class="font-bold">{{ person?.full_name || "—" }}</span>
<Badge
v-if="balance != null"
class="bg-error-100 text-error-500 text-sm font-bold flex gap-1 items-center"
>
<Wallet :size="14" />
<span>{{ formatAmount(balance) }} </span>
</Badge>
</CardTitle>
<CardDescription class="flex gap-1 py-2">
<Badge class="font-bold" variant="secondary">{{
job.contract?.reference || job.contract?.uuid || "—"
}}</Badge>
<Badge v-if="clientName">{{ clientName }}</Badge>
</CardDescription>
</CardHeader>
<CardContent class="p-3 flex flex-row items-center justify-between gap-2">
<div class="flex flex-auto items-center-safe gap-2">
<p v-if="address" class="flex items-center gap-1 text-sm border p-1 rounded-md">
<MapPin :size="14" class="text-gray-500" />
{{ address }}
</p>
<p v-if="phone" class="flex items-center gap-2 text-sm border p-1 rounded-md">
<Phone :size="14" class="text-gray-500" />
{{ phone }}
</p>
</div>
<ChevronRight />
</CardContent>
<CardFooter class="bg-gray-50/60 border-t p-3 pt-3!">
<div class="flex items-center gap-1 text-sm text-gray-500">
<CalendarDays :size="12" />
<span>{{ dateLabel }}</span>
</div>
</CardFooter>
</Card>
</component>
</template>