ba462a091b
Fiches Client / Prospect / Prestataire (onglet Rapport mis à part) : - Champs email/téléphone : composants MalioInputEmail / MalioInputPhone - Grilles en 4 colonnes (Info + blocs Contact/Adresse) - Boutons « Nouveau contact/adresse » en secondary ; « Enregistrer » en taille Malio standard ; marge form↔bouton homogène entre onglets - Bouton retour ghost (mdi:arrow-left-bold) comme Starseed - Adresse : flux CP → ville → rue (rue conditionnée au CP+ville, cascade de reset), titre du bloc = libellé saisi - Suppression d'un bloc Contact/Adresse : modal de confirmation (logique centralisée dans useDirectoryDetail) Onglet Rapport : - Bouton d'ajout en taille Malio standard, label « Ajouter » - Suppression compte-rendu : passe à la ConfirmModal partagée (remplace l'ancienne ConfirmDeleteReportModal, supprimée) - Suppression d'un document joint : ajout d'une modal de confirmation - Upload via MalioInputUpload ; bouton supprimer document aligné (mdi:delete-outline ghost) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
96 lines
3.6 KiB
Vue
96 lines
3.6 KiB
Vue
<template>
|
|
<!-- Bloc à plat (sans box-shadow) : un filet noir 1px le sépare du suivant
|
|
(pas de bordure sous le dernier bloc), comme sur Starseed. -->
|
|
<div class="pb-5" :class="{ 'border-b border-black': !last }">
|
|
<div class="flex items-center justify-between">
|
|
<h3 class="text-[20px] font-semibold text-black">{{ title }}</h3>
|
|
<MalioButtonIcon
|
|
v-if="removable && !readonly"
|
|
icon="mdi:delete-outline"
|
|
variant="ghost"
|
|
button-class="p-0"
|
|
:aria-label="$t('common.delete')"
|
|
@click="$emit('remove')"
|
|
/>
|
|
</div>
|
|
|
|
<div class="mt-6 grid grid-cols-4 gap-x-[44px] gap-y-4">
|
|
<MalioInputText
|
|
:label="$t('directory.contacts.fields.lastName')"
|
|
:model-value="modelValue.lastName ?? ''"
|
|
:readonly="readonly"
|
|
@update:model-value="update('lastName', $event)"
|
|
/>
|
|
<MalioInputText
|
|
:label="$t('directory.contacts.fields.firstName')"
|
|
:model-value="modelValue.firstName ?? ''"
|
|
:readonly="readonly"
|
|
@update:model-value="update('firstName', $event)"
|
|
/>
|
|
<MalioInputText
|
|
class="col-span-2"
|
|
:label="$t('directory.contacts.fields.jobTitle')"
|
|
:model-value="modelValue.jobTitle ?? ''"
|
|
:readonly="readonly"
|
|
@update:model-value="update('jobTitle', $event)"
|
|
/>
|
|
<MalioInputEmail
|
|
:label="$t('directory.contacts.fields.email')"
|
|
:model-value="modelValue.email ?? ''"
|
|
:readonly="readonly"
|
|
:error="emailError"
|
|
@update:model-value="update('email', $event)"
|
|
/>
|
|
<MalioInputPhone
|
|
:label="$t('directory.contacts.fields.phonePrimary')"
|
|
:model-value="modelValue.phonePrimary ?? ''"
|
|
:readonly="readonly"
|
|
:error="phonePrimaryError"
|
|
@update:model-value="update('phonePrimary', $event)"
|
|
/>
|
|
<MalioInputPhone
|
|
:label="$t('directory.contacts.fields.phoneSecondary')"
|
|
:model-value="modelValue.phoneSecondary ?? ''"
|
|
:readonly="readonly"
|
|
:error="phoneSecondaryError"
|
|
@update:model-value="update('phoneSecondary', $event)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { Contact } from '~/modules/directory/services/dto/contact'
|
|
import { isValidEmail, isValidFrPhone } from '~/modules/directory/utils/validation'
|
|
|
|
const props = defineProps<{
|
|
modelValue: Contact
|
|
title: string
|
|
removable?: boolean
|
|
readonly?: boolean
|
|
/** Dernier bloc de la liste : supprime le filet de séparation bas. */
|
|
last?: boolean
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
'update:modelValue': [value: Contact]
|
|
'remove': []
|
|
}>()
|
|
|
|
const { t } = useI18n()
|
|
|
|
const emailError = computed(() =>
|
|
isValidEmail(props.modelValue.email) ? '' : t('directory.validation.emailInvalid'),
|
|
)
|
|
const phonePrimaryError = computed(() =>
|
|
isValidFrPhone(props.modelValue.phonePrimary) ? '' : t('directory.validation.phoneInvalid'),
|
|
)
|
|
const phoneSecondaryError = computed(() =>
|
|
isValidFrPhone(props.modelValue.phoneSecondary) ? '' : t('directory.validation.phoneInvalid'),
|
|
)
|
|
|
|
function update(field: keyof Contact, value: string): void {
|
|
emit('update:modelValue', { ...props.modelValue, [field]: value === '' ? null : value })
|
|
}
|
|
</script>
|