detail form contact data

This commit is contained in:
Julian Krauser 2025-03-06 14:02:21 +01:00
parent c5b62d3221
commit 5f7062e5f1
5 changed files with 191 additions and 5 deletions

View file

@ -0,0 +1,59 @@
<template>
<div class="flex flex-col gap-2">
<div class="flex flex-row gap-2 items-center">
<p>Kontaktdaten</p>
<PlusCircleIcon v-if="enabled" class="w-5 h-5 cursor-pointer" @click="addContact()" />
</div>
<DetailFormContactItem
v-for="[key, contact] in contacts"
:key="key"
:contactId="key"
:contact="contact"
:awareness="awareness"
:enabled="enabled"
@remove="removeContact(key)"
/>
</div>
</template>
<script setup lang="ts">
import { defineComponent, type PropType } from "vue";
import * as Y from "yjs";
import { Awareness } from "@/helpers/awareness";
import DetailFormContactItem from "./DetailFormContactItem.vue";
import { PlusCircleIcon } from "@heroicons/vue/24/outline";
import { v4 as uuidv4 } from "uuid";
</script>
<script lang="ts">
export default defineComponent({
props: {
map: {
type: Object as PropType<Y.Map<Y.Map<number | string>>>,
required: true,
},
awareness: {
type: Object as PropType<Awareness>,
required: true,
},
enabled: {
type: Boolean,
default: true,
},
},
computed: {
contacts() {
return Array.from(this.map.entries());
},
},
methods: {
addContact() {
this.map.set(uuidv4(), new Y.Map<string | number>());
},
removeContact(contactId: string) {
this.map.delete(contactId);
},
},
});
</script>

View file

@ -0,0 +1,128 @@
<template>
<div
class="flex flex-col gap-2 rounded-md shadow-sm relative w-full p-2 border border-gray-300 focus:border-primary placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-0 focus:z-10 sm:text-sm resize-none"
>
<TrashIcon class="w-5 h-5 min-w-5 min-h-5 cursor-pointer self-end" @click="$emit('remove')" />
<div class="flex flex-col md:flex-row gap-2 items-center">
<DetailFormInput
:ident="contactId + 'firstname'"
title="Vorname"
v-model="firstname"
type="text"
:awareness="awareness"
:enabled="enabled"
/>
<DetailFormInput
:ident="contactId + 'lastname'"
title="Nachname"
v-model="lastname"
type="text"
:awareness="awareness"
:enabled="enabled"
/>
</div>
<div class="flex flex-col md:flex-row gap-2 items-center">
<DetailFormInput
:ident="contactId + 'phone'"
title="Telefon"
v-model="phone"
type="text"
:awareness="awareness"
:enabled="enabled"
/>
<DetailFormInput
:ident="contactId + 'address'"
title="Adresse"
v-model="address"
type="text"
:awareness="awareness"
:enabled="enabled"
/>
</div>
<DetailFormInput
:ident="contactId + 'note'"
title="Notiz"
v-model="note"
type="text"
:awareness="awareness"
:enabled="enabled"
/>
</div>
</template>
<script setup lang="ts">
import { defineComponent, type PropType } from "vue";
import { mapState, mapActions } from "pinia";
import * as Y from "yjs";
import { Awareness } from "@/helpers/awareness";
import { useForceStore } from "@/stores/admin/configuration/force";
import DetailFormInput from "./DetailFormInput.vue";
import { TrashIcon } from "@heroicons/vue/24/outline";
</script>
<script lang="ts">
export default defineComponent({
props: {
contactId: {
type: String,
required: true,
},
contact: {
type: Object as PropType<Y.Map<string | number>>,
required: true,
},
awareness: {
type: Object as PropType<Awareness>,
required: true,
},
enabled: {
type: Boolean,
default: true,
},
},
emits: ["remove"],
computed: {
...mapState(useForceStore, ["availableForces"]),
firstname: {
get() {
return this.contact.get("firstname") as string;
},
set(val: string) {
this.contact.set("firstname", val);
},
},
lastname: {
get() {
return this.contact.get("lastname") as string;
},
set(val: string) {
this.contact.set("lastname", val);
},
},
phone: {
get() {
return this.contact.get("phone") as string;
},
set(val: string) {
this.contact.set("phone", val);
},
},
address: {
get() {
return this.contact.get("address") as string;
},
set(val: string) {
this.contact.set("address", val);
},
},
note: {
get() {
return this.contact.get("note") as string;
},
set(val: string) {
this.contact.set("note", val);
},
},
},
});
</script>

View file

@ -1,6 +1,6 @@
<template>
<div
class="flex flex-col md:flex-row gap-2 rounded-md shadow-sm relative w-full px-3 py-2 border border-gray-300 focus:border-primary placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-0 focus:z-10 sm:text-sm resize-none"
class="flex flex-col md:flex-row gap-2 rounded-md shadow-sm relative w-full p-2 border border-gray-300 focus:border-primary placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-0 focus:z-10 sm:text-sm resize-none"
>
<div class="flex flex-row gap-2 items-center">
<TrashIcon class="w-5 h-5 min-w-5 min-h-5 cursor-pointer" @click="$emit('remove')" />

View file

@ -1,6 +1,6 @@
<template>
<div
class="flex flex-col md:flex-row gap-2 rounded-md shadow-sm relative w-full px-3 py-2 border border-gray-300 focus:border-primary placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-0 focus:z-10 sm:text-sm resize-none"
class="flex flex-col md:flex-row gap-2 rounded-md shadow-sm relative w-full p-2 border border-gray-300 focus:border-primary placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-0 focus:z-10 sm:text-sm resize-none"
>
<div class="flex flex-row gap-2 items-center">
<TrashIcon class="w-5 h-5 min-w-5 min-h-5 cursor-pointer" @click="$emit('remove')" />

View file

@ -66,9 +66,7 @@
<DetailFormEditor title="Einsatzbeschreibung" :text="editor" :awareness="awareness" :enabled="enabled" />
<DetailFormVehicle :map="vehicle" :awareness="awareness" :enabled="enabled" />
<DetailFormEquipment :map="equipment" :awareness="awareness" :enabled="enabled" />
<div class="flex flex-col">
<p>Kontaktdaten</p>
</div>
<DetailFormContact :map="contact" :awareness="awareness" :enabled="enabled" />
</div>
</template>
@ -83,6 +81,7 @@ import DetailFormEditor from "./DetailFormEditor.vue";
import DetailFormVehicle from "./DetailFormVehicle.vue";
import ForceSelect from "@/components/admin/ForceSelect.vue";
import DetailFormEquipment from "./DetailFormEquipment.vue";
import DetailFormContact from "./DetailFormContact.vue";
</script>
<script lang="ts">