Update Person grid view vue and reverted import v2 back to v1 (v2 not production ready)
This commit is contained in:
@@ -384,6 +384,7 @@ const switchToTab = (tab) => {
|
||||
</TabsList>
|
||||
<TabsContent value="person" class="py-2">
|
||||
<PersonInfoPersonTab
|
||||
:is-client-case="clientCaseUuid ? true : false"
|
||||
:person="person"
|
||||
:edit="edit"
|
||||
:person-edit="personEdit"
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
<script setup>
|
||||
import { UserEditIcon } from "@/Utilities/Icons";
|
||||
import { Button } from "../ui/button";
|
||||
import { fmtDateDMY } from "@/Utilities/functions";
|
||||
|
||||
const props = defineProps({
|
||||
person: Object,
|
||||
isClientCase: { type: Boolean, default: false },
|
||||
edit: { type: Boolean, default: true },
|
||||
personEdit: { type: Boolean, default: true },
|
||||
});
|
||||
|
||||
const emit = defineEmits(['edit']);
|
||||
const emit = defineEmits(["edit"]);
|
||||
|
||||
const getMainAddress = (adresses) => {
|
||||
const addr = adresses.filter((a) => a.type.id === 1)[0] ?? "";
|
||||
@@ -30,7 +32,7 @@ const getMainPhone = (phones) => {
|
||||
};
|
||||
|
||||
const handleEdit = () => {
|
||||
emit('edit');
|
||||
emit("edit");
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -44,51 +46,126 @@ const handleEdit = () => {
|
||||
>
|
||||
<UserEditIcon size="md" />
|
||||
<span>Uredi</span>
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
<div class="grid grid-rows-* grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3">
|
||||
<div class="rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow">
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">Nu.</p>
|
||||
<div
|
||||
class="rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow"
|
||||
>
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">
|
||||
Primer ref.
|
||||
</p>
|
||||
<p class="text-sm font-semibold text-gray-900">{{ person.nu }}</p>
|
||||
</div>
|
||||
<div class="rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow">
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">Name.</p>
|
||||
<div
|
||||
class="rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow"
|
||||
>
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">Naziv</p>
|
||||
<p class="text-sm font-semibold text-gray-900">
|
||||
{{ person.full_name }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow">
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">Tax NU.</p>
|
||||
<div
|
||||
class="rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow"
|
||||
>
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">
|
||||
Davčna
|
||||
</p>
|
||||
<p class="text-sm font-semibold text-gray-900">
|
||||
{{ person.tax_number }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow">
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">Social security NU.</p>
|
||||
<div
|
||||
class="rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow"
|
||||
>
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">Emšo</p>
|
||||
<p class="text-sm font-semibold text-gray-900">
|
||||
{{ person.social_security_number }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-rows-* grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3 mt-3">
|
||||
<div class="rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow">
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">Address</p>
|
||||
<div
|
||||
v-if="isClientCase"
|
||||
class="grid grid-rows-* grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3 mt-3"
|
||||
>
|
||||
<div
|
||||
class="md:col-span-full lg:col-span-1 rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow"
|
||||
>
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">
|
||||
Naslov
|
||||
</p>
|
||||
<p class="text-sm font-medium text-gray-900">
|
||||
{{ getMainAddress(person.addresses) }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow">
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">Phone</p>
|
||||
<div
|
||||
class="rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow"
|
||||
>
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">
|
||||
Telefon
|
||||
</p>
|
||||
<p class="text-sm font-medium text-gray-900">
|
||||
{{ getMainPhone(person.phones) }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="md:col-span-full lg:col-span-1 rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow">
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">Description</p>
|
||||
<div
|
||||
class="rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow"
|
||||
>
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">
|
||||
Dat. rojstva
|
||||
</p>
|
||||
<p class="text-sm font-medium text-gray-900">
|
||||
{{ fmtDateDMY(person.birthday) }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="grid grid-rows-* grid-cols-1 md:grid-cols-2 gap-3 mt-3">
|
||||
<div
|
||||
class="rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow"
|
||||
>
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">
|
||||
Naslov
|
||||
</p>
|
||||
<p class="text-sm font-medium text-gray-900">
|
||||
{{ getMainAddress(person.addresses) }}
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow"
|
||||
>
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">
|
||||
Telefon
|
||||
</p>
|
||||
<p class="text-sm font-medium text-gray-900">
|
||||
{{ getMainPhone(person.phones) }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="grid grid-rows-* grid-cols-1 md:grid-cols-2 gap-3 mt-3"
|
||||
:class="[isClientCase ? 'md:grid-cols-2' : '']"
|
||||
>
|
||||
<div
|
||||
v-if="isClientCase"
|
||||
class="md:col-span-full lg:col-span-1 rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow"
|
||||
>
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">
|
||||
Delodajalec
|
||||
</p>
|
||||
<p class="text-sm font-medium text-gray-900">
|
||||
{{ person.employer }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="md:col-span-full rounded-lg p-3 bg-white border border-gray-200 shadow-sm hover:shadow-md transition-shadow"
|
||||
:class="[isClientCase ? 'lg:col-span-1' : '']"
|
||||
>
|
||||
<p class="text-xs font-medium uppercase tracking-wider text-gray-500 mb-1">Opis</p>
|
||||
<p class="text-sm font-medium text-gray-900">
|
||||
{{ person.description }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,182 +1,205 @@
|
||||
<script setup>
|
||||
import UpdateDialog from '@/Components/Dialogs/UpdateDialog.vue';
|
||||
import SectionTitle from '@/Components/SectionTitle.vue';
|
||||
import UpdateDialog from "@/Components/Dialogs/UpdateDialog.vue";
|
||||
import SectionTitle from "@/Components/SectionTitle.vue";
|
||||
import { useForm, Field as FormField } from "vee-validate";
|
||||
import { toTypedSchema } from "@vee-validate/zod";
|
||||
import * as z from "zod";
|
||||
import { router } from '@inertiajs/vue3';
|
||||
import { ref } from 'vue';
|
||||
import {
|
||||
FormControl,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/Components/ui/form";
|
||||
import { router } from "@inertiajs/vue3";
|
||||
import { ref } from "vue";
|
||||
import { FormControl, FormItem, FormLabel, FormMessage } from "@/Components/ui/form";
|
||||
import { Input } from "@/Components/ui/input";
|
||||
import { Textarea } from "@/Components/ui/textarea";
|
||||
import DatePicker from "../DatePicker.vue";
|
||||
|
||||
const props = defineProps({
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
person: Object
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
person: Object,
|
||||
});
|
||||
|
||||
const processingUpdate = ref(false);
|
||||
|
||||
const emit = defineEmits(['close']);
|
||||
const emit = defineEmits(["close"]);
|
||||
|
||||
const formSchema = toTypedSchema(
|
||||
z.object({
|
||||
full_name: z.string().min(1, "Naziv je obvezen."),
|
||||
tax_number: z.string().optional(),
|
||||
social_security_number: z.string().optional(),
|
||||
birthday: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
employer: z.string().optional(),
|
||||
})
|
||||
);
|
||||
|
||||
const form = useForm({
|
||||
validationSchema: formSchema,
|
||||
initialValues: {
|
||||
full_name: props.person?.full_name || '',
|
||||
tax_number: props.person?.tax_number || '',
|
||||
social_security_number: props.person?.social_security_number || '',
|
||||
description: props.person?.description || ''
|
||||
full_name: props.person?.full_name || "",
|
||||
tax_number: props.person?.tax_number || "",
|
||||
social_security_number: props.person?.social_security_number || "",
|
||||
birthday: props.person?.birthday || "",
|
||||
description: props.person?.description || "",
|
||||
employer: props.person?.employer || "",
|
||||
},
|
||||
});
|
||||
|
||||
const close = () => {
|
||||
emit('close');
|
||||
setTimeout(() => {
|
||||
form.resetForm({
|
||||
values: {
|
||||
full_name: props.person?.full_name || '',
|
||||
tax_number: props.person?.tax_number || '',
|
||||
social_security_number: props.person?.social_security_number || '',
|
||||
description: props.person?.description || ''
|
||||
}
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
emit("close");
|
||||
setTimeout(() => {
|
||||
form.resetForm({
|
||||
values: {
|
||||
full_name: props.person?.full_name || "",
|
||||
tax_number: props.person?.tax_number || "",
|
||||
social_security_number: props.person?.social_security_number || "",
|
||||
birthday: props.person?.birthday || "",
|
||||
description: props.person?.description || "",
|
||||
employer: props.person?.employer || "",
|
||||
},
|
||||
});
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const updatePerson = async () => {
|
||||
processingUpdate.value = true;
|
||||
const { values } = form;
|
||||
processingUpdate.value = true;
|
||||
const { values } = form;
|
||||
|
||||
router.put(
|
||||
route('person.update', props.person),
|
||||
values,
|
||||
{
|
||||
preserveScroll: true,
|
||||
onSuccess: () => {
|
||||
processingUpdate.value = false;
|
||||
close();
|
||||
},
|
||||
onError: (errors) => {
|
||||
// Map Inertia errors to VeeValidate field errors
|
||||
Object.keys(errors).forEach((field) => {
|
||||
const errorMessages = Array.isArray(errors[field])
|
||||
? errors[field]
|
||||
: [errors[field]];
|
||||
form.setFieldError(field, errorMessages[0]);
|
||||
});
|
||||
processingUpdate.value = false;
|
||||
},
|
||||
onFinish: () => {
|
||||
processingUpdate.value = false;
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
router.put(route("person.update", props.person), values, {
|
||||
preserveScroll: true,
|
||||
onSuccess: () => {
|
||||
processingUpdate.value = false;
|
||||
close();
|
||||
},
|
||||
onError: (errors) => {
|
||||
// Map Inertia errors to VeeValidate field errors
|
||||
Object.keys(errors).forEach((field) => {
|
||||
const errorMessages = Array.isArray(errors[field])
|
||||
? errors[field]
|
||||
: [errors[field]];
|
||||
form.setFieldError(field, errorMessages[0]);
|
||||
});
|
||||
processingUpdate.value = false;
|
||||
},
|
||||
onFinish: () => {
|
||||
processingUpdate.value = false;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const onSubmit = form.handleSubmit(() => {
|
||||
updatePerson();
|
||||
});
|
||||
|
||||
const onConfirm = () => {
|
||||
onSubmit();
|
||||
}
|
||||
onSubmit();
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<UpdateDialog
|
||||
:show="show"
|
||||
:title="`Posodobi ${person.full_name}`"
|
||||
confirm-text="Shrani"
|
||||
:processing="processingUpdate"
|
||||
@close="close"
|
||||
@confirm="onConfirm"
|
||||
>
|
||||
<form @submit.prevent="onSubmit">
|
||||
<SectionTitle class="border-b mb-4">
|
||||
<template #title>
|
||||
Oseba
|
||||
</template>
|
||||
</SectionTitle>
|
||||
<UpdateDialog
|
||||
:show="show"
|
||||
:title="`Posodobi ${person.full_name}`"
|
||||
confirm-text="Shrani"
|
||||
:processing="processingUpdate"
|
||||
@close="close"
|
||||
@confirm="onConfirm"
|
||||
>
|
||||
<form @submit.prevent="onSubmit">
|
||||
<SectionTitle class="border-b mb-4">
|
||||
<template #title> Oseba </template>
|
||||
</SectionTitle>
|
||||
|
||||
<div class="space-y-4">
|
||||
<FormField v-slot="{ componentField }" name="full_name">
|
||||
<FormItem>
|
||||
<FormLabel>Naziv</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
id="cfullname"
|
||||
type="text"
|
||||
placeholder="Naziv"
|
||||
autocomplete="full-name"
|
||||
v-bind="componentField"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<div class="space-y-4">
|
||||
<FormField v-slot="{ componentField }" name="full_name">
|
||||
<FormItem>
|
||||
<FormLabel>Naziv</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
id="cfullname"
|
||||
type="text"
|
||||
placeholder="Naziv"
|
||||
autocomplete="full-name"
|
||||
v-bind="componentField"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<FormField v-slot="{ componentField }" name="tax_number">
|
||||
<FormItem>
|
||||
<FormLabel>Davčna</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
id="ctaxnumber"
|
||||
type="text"
|
||||
placeholder="Davčna številka"
|
||||
autocomplete="tax-number"
|
||||
v-bind="componentField"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<FormField v-slot="{ componentField }" name="tax_number">
|
||||
<FormItem>
|
||||
<FormLabel>Davčna</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
id="ctaxnumber"
|
||||
type="text"
|
||||
placeholder="Davčna številka"
|
||||
autocomplete="tax-number"
|
||||
v-bind="componentField"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<FormField v-slot="{ componentField }" name="social_security_number">
|
||||
<FormItem>
|
||||
<FormLabel>Matična / Emšo</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
id="csocialSecurityNumber"
|
||||
type="text"
|
||||
placeholder="Matična / Emšo"
|
||||
autocomplete="social-security-number"
|
||||
v-bind="componentField"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<FormField v-slot="{ componentField }" name="description">
|
||||
<FormItem>
|
||||
<FormLabel>Opis</FormLabel>
|
||||
<FormControl>
|
||||
<Textarea
|
||||
id="cdescription"
|
||||
placeholder="Opis"
|
||||
v-bind="componentField"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</div>
|
||||
</form>
|
||||
</UpdateDialog>
|
||||
<FormField v-slot="{ componentField }" name="social_security_number">
|
||||
<FormItem>
|
||||
<FormLabel>Matična / Emšo</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
id="csocialSecurityNumber"
|
||||
type="text"
|
||||
placeholder="Matična / Emšo"
|
||||
autocomplete="social-security-number"
|
||||
v-bind="componentField"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<FormField v-slot="{ componentField }" name="employer">
|
||||
<FormItem>
|
||||
<FormLabel>Delodajalec</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
id="cemployer"
|
||||
type="text"
|
||||
placeholder="Delodajalec"
|
||||
autocomplete="employer"
|
||||
v-bind="componentField"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<FormField v-slot="{ value, handleChange }" name="birthday">
|
||||
<FormItem>
|
||||
<FormLabel>Datum rojstva</FormLabel>
|
||||
<FormControl>
|
||||
<DatePicker
|
||||
id="cbirthday"
|
||||
:model-value="value"
|
||||
@update:model-value="handleChange"
|
||||
format="dd.MM.yyyy"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<FormField v-slot="{ componentField }" name="description">
|
||||
<FormItem>
|
||||
<FormLabel>Opis</FormLabel>
|
||||
<FormControl>
|
||||
<Textarea id="cdescription" placeholder="Opis" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</div>
|
||||
</form>
|
||||
</UpdateDialog>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user