updates to UI and add archiving option

This commit is contained in:
Simon Pocrnjič
2025-10-05 19:45:49 +02:00
parent fe91c7e4bc
commit bab9d6561f
50 changed files with 3337 additions and 416 deletions
@@ -73,11 +73,22 @@ const store = async () => {
amount: form.amount,
note: form.note,
});
// Helper to safely format a selected date (Date instance or parsable value) to YYYY-MM-DD
const formatDateForSubmit = (value) => {
if (!value) return null; // leave empty as null
const d = value instanceof Date ? value : new Date(value);
if (isNaN(d.getTime())) return null; // invalid date -> null
// Avoid timezone shifting by constructing in local time
const y = d.getFullYear();
const m = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
return `${y}-${m}-${day}`; // matches en-CA style YYYY-MM-DD
};
form
.transform((data) => ({
...data,
due_date: new Date(data.due_date).toLocaleDateString("en-CA"),
due_date: formatDateForSubmit(data.due_date),
}))
.post(route("clientCase.activity.store", props.client_case), {
onSuccess: () => {
@@ -179,17 +179,17 @@ const confirmDeleteAction = () => {
>
</div>
</td>
<td class="py-2 pl-2 pr-2 align-top text-right">
<Dropdown align="right" width="30" :content-classes="['py-1', 'bg-white']">
<td class="py-2 pl-2 pr-2 align-middle text-right">
<Dropdown align="right" width="30">
<template #trigger>
<button
type="button"
class="inline-flex items-center justify-center w-8 h-8 rounded hover:bg-gray-100"
aria-haspopup="menu"
class="inline-flex items-center justify-center h-8 w-8 rounded-full hover:bg-gray-100 focus:outline-none"
:title="'Actions'"
>
<FontAwesomeIcon
:icon="['fas', 'ellipsis-vertical']"
class="text-gray-600 text-[20px]"
:icon="faEllipsisVertical"
class="h-4 w-4 text-gray-700"
/>
</button>
</template>
@@ -21,6 +21,7 @@ import {
faTrash,
faListCheck,
faPlus,
faBoxArchive,
} from "@fortawesome/free-solid-svg-icons";
const props = defineProps({
@@ -119,6 +120,10 @@ const confirmChange = ref({
fromAll: false,
});
const askChangeSegment = (c, segmentId, fromAll = false) => {
// Prevent segment change for archived contracts
if (!c?.active) {
return;
}
confirmChange.value = { show: true, contract: c, segmentId, fromAll };
};
const closeConfirm = () => {
@@ -262,13 +267,16 @@ const closePaymentsDialog = () => {
class="inline-flex items-center justify-center h-7 w-7 rounded-full hover:bg-gray-100"
:class="{
'opacity-50 cursor-not-allowed':
!segments || segments.length === 0,
!segments || segments.length === 0 || !c.active,
}"
:title="
segments && segments.length
!c.active
? 'Segmenta ni mogoče spremeniti za arhivirano pogodbo'
: segments && segments.length
? 'Spremeni segment'
: 'Ni segmentov na voljo za ta primer'
"
:disabled="!c.active || !segments || !segments.length"
>
<FontAwesomeIcon
:icon="faPenToSquare"
@@ -313,6 +321,11 @@ const closePaymentsDialog = () => {
</div>
</template>
</Dropdown>
<span
v-if="!c.active"
class="inline-flex items-center px-2 py-0.5 rounded text-[10px] font-semibold bg-gray-200 text-gray-700 uppercase tracking-wide"
>Arhivirano</span
>
</div>
</FwbTableCell>
<FwbTableCell class="text-right">{{
@@ -433,6 +446,7 @@ const closePaymentsDialog = () => {
<button
type="button"
class="w-full px-3 py-2 text-left text-sm text-gray-700 hover:bg-gray-50 flex items-center gap-2"
v-if="c.active"
@click="onEdit(c)"
>
<FontAwesomeIcon
@@ -444,6 +458,7 @@ const closePaymentsDialog = () => {
<button
type="button"
class="w-full px-3 py-2 text-left text-sm text-gray-700 hover:bg-gray-50 flex items-center gap-2"
v-if="c.active"
@click="onAddActivity(c)"
>
<FontAwesomeIcon :icon="faListCheck" class="h-4 w-4 text-gray-600" />
@@ -468,6 +483,7 @@ const closePaymentsDialog = () => {
<button
type="button"
class="w-full px-3 py-2 text-left text-sm text-gray-700 hover:bg-gray-50 flex items-center gap-2"
v-if="c.active"
@click="openObjectDialog(c)"
>
<FontAwesomeIcon :icon="faPlus" class="h-4 w-4 text-gray-600" />
@@ -492,12 +508,62 @@ const closePaymentsDialog = () => {
<button
type="button"
class="w-full px-3 py-2 text-left text-sm text-gray-700 hover:bg-gray-50 flex items-center gap-2"
v-if="c.active && c?.account"
@click="openPaymentDialog(c)"
>
<FontAwesomeIcon :icon="faPlus" class="h-4 w-4 text-gray-600" />
<span>Dodaj plačilo</span>
</button>
<div class="my-1 border-t border-gray-100" />
<!-- Arhiviranje / Ponovna aktivacija -->
<div
class="px-3 pt-2 pb-1 text-[11px] uppercase tracking-wide text-gray-400"
>
{{ c.active ? "Arhiviranje" : "Ponovna aktivacija" }}
</div>
<button
v-if="c.active"
type="button"
class="w-full px-3 py-2 text-left text-sm text-gray-700 hover:bg-gray-50 flex items-center gap-2"
@click="
router.post(
route('clientCase.contract.archive', {
client_case: client_case.uuid,
uuid: c.uuid,
}),
{},
{
preserveScroll: true,
only: ['contracts', 'activities', 'documents'],
}
)
"
>
<FontAwesomeIcon :icon="faBoxArchive" class="h-4 w-4 text-gray-600" />
<span>Arhiviraj</span>
</button>
<button
v-else
type="button"
class="w-full px-3 py-2 text-left text-sm text-gray-700 hover:bg-gray-50 flex items-center gap-2"
@click="
router.post(
route('clientCase.contract.archive', {
client_case: client_case.uuid,
uuid: c.uuid,
}),
{ reactivate: true },
{
preserveScroll: true,
only: ['contracts', 'activities', 'documents'],
}
)
"
>
<FontAwesomeIcon :icon="faBoxArchive" class="h-4 w-4 text-gray-600" />
<span>Ponovno aktiviraj</span>
</button>
<div class="my-1 border-t border-gray-100" />
<!-- Destruktivno -->
<button