Files
OrderCheck/resources/js/Pages/BesoinsInformatiques/Edit.vue
T
mrKamooandClaude Sonnet 4.6 7312c7640b feat: add Devis and BesoinInformatique modules
- Devis: CRUD complet, génération PDF (dompdf), paramètres (DevisSetting)
- BesoinInformatique: CRUD complet avec gestion matériels/licences
- Migrations pour les 3 nouvelles tables
- Navigation mise à jour dans AuthenticatedLayout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 14:46:16 +02:00

232 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
import { Head, useForm, Link } from '@inertiajs/vue3';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import { onMounted } from 'vue';
const props = defineProps({
besoin: Object,
});
const form = useForm({
collectivite: props.besoin.collectivite || '',
nom_referent: props.besoin.nom_referent || '',
descriptif_projet: props.besoin.descriptif_projet || '',
materiels_support: props.besoin.materiels_support || [{ type: '', agent: '' }],
licences_bureautique: props.besoin.licences_bureautique || [{ licence: '', type: '', destination: '', quantite: 1 }],
equipements_reseaux: props.besoin.equipements_reseaux || '',
cablage_reseau: props.besoin.cablage_reseau || '',
telephonie_ip: props.besoin.telephonie_ip || '',
nouveau_batiment: props.besoin.nouveau_batiment || '',
logiciels_metiers: props.besoin.logiciels_metiers || '',
licences_projets: props.besoin.licences_projets || [{ action: '', nom: '', domaine: '', quantite: 1 }],
});
// Sécurités pour éviter que le formulaire crashe si les arrays sont vides depuis la DB
onMounted(() => {
if (!form.materiels_support || form.materiels_support.length === 0) {
form.materiels_support = [{ type: '', agent: '' }];
}
if (!form.licences_bureautique || form.licences_bureautique.length === 0) {
form.licences_bureautique = [{ licence: '', type: '', destination: '', quantite: 1 }];
}
if (!form.licences_projets || form.licences_projets.length === 0) {
form.licences_projets = [{ action: '', nom: '', domaine: '', quantite: 1 }];
}
});
const submit = () => {
form.put(route('besoins-informatiques.update', props.besoin.id));
};
const addMateriel = () => form.materiels_support.push({ type: '', agent: '' });
const removeMateriel = (index) => form.materiels_support.splice(index, 1);
const addLicenceBureautique = () => form.licences_bureautique.push({ licence: '', type: '', destination: '', quantite: 1 });
const removeLicenceBureautique = (index) => form.licences_bureautique.splice(index, 1);
const addLicenceProjet = () => form.licences_projets.push({ action: '', nom: '', domaine: '', quantite: 1 });
const removeLicenceProjet = (index) => form.licences_projets.splice(index, 1);
</script>
<template>
<Head title="Modifier le Besoin Informatique" />
<AuthenticatedLayout>
<template #header>
<div class="flex items-center justify-between">
<h2 class="text-xl font-bold leading-tight text-slate-800 dark:text-slate-200">
Modifier la fiche de synthèse (Mutualisation)
</h2>
<Link
:href="route('besoins-informatiques.index')"
class="inline-flex items-center px-4 py-2 text-sm font-semibold text-slate-700 bg-white border border-slate-300 rounded-lg hover:bg-slate-50 dark:bg-slate-900 dark:text-slate-300 dark:border-slate-850 dark:hover:bg-slate-800 transition-colors"
>
Retour
</Link>
</div>
</template>
<div class="py-6">
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
<form @submit.prevent="submit" class="space-y-6">
<!-- Entête du budget -->
<div class="bg-[#000066] text-white rounded-xl shadow-sm overflow-hidden p-6 text-center">
<h1 class="text-lg font-bold tracking-wider uppercase">PRÉPARATION BUDGET 2027</h1>
<p class="text-sm font-semibold mt-1">FICHE Synthèse des Besoins Informatiques MUTUALISATION</p>
</div>
<!-- Informations Générales -->
<div class="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-xl shadow-sm overflow-hidden">
<div class="p-6 space-y-6">
<h3 class="text-md font-bold text-slate-800 dark:text-slate-200 border-b border-slate-100 dark:border-slate-850 pb-3">Informations Générales</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label class="block text-sm font-bold text-slate-700 dark:text-slate-300 mb-1">Collectivité :</label>
<input v-model="form.collectivite" type="text" class="w-full text-sm rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200" required>
</div>
<div>
<label class="block text-sm font-bold text-slate-700 dark:text-slate-300 mb-1">Nom du référent :</label>
<input v-model="form.nom_referent" type="text" class="w-full text-sm rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200" required>
</div>
<div class="md:col-span-2">
<label class="block text-sm font-bold text-slate-700 dark:text-slate-300 mb-1">Descriptif / objectif du projet :</label>
<textarea v-model="form.descriptif_projet" rows="3" class="w-full text-sm rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200"></textarea>
</div>
</div>
</div>
</div>
<!-- Service Support -->
<div class="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-xl shadow-sm overflow-hidden flex flex-col md:flex-row">
<div class="bg-[#002060] p-6 md:w-56 flex-shrink-0 flex flex-col justify-center text-white">
<h3 class="text-md font-bold tracking-wide text-center md:text-left">Service Support et Relations Usagers</h3>
<p class="text-xxs opacity-80 mt-2 hidden md:block">Contact : Frédéric FERNANDEZ fredericfernandez@beziers-mediterranee.fr</p>
</div>
<div class="p-6 flex-1 space-y-6">
<!-- Matériel -->
<div>
<div class="flex items-center justify-between mb-3 border-b border-slate-100 dark:border-slate-850 pb-2">
<h4 class="text-sm font-bold text-slate-850 dark:text-slate-250">Type de matériel (PC / Portables / Ecran / Tel...)</h4>
<button type="button" @click="addMateriel" class="text-xs font-semibold text-sky-600 hover:text-sky-700 bg-sky-50 dark:bg-sky-950/40 px-2 py-1 rounded-md border border-sky-100 dark:border-sky-900/60">+ Ajouter</button>
</div>
<div class="space-y-3">
<div v-for="(item, index) in form.materiels_support" :key="index" class="flex items-start gap-2">
<div class="flex-1 grid grid-cols-1 sm:grid-cols-2 gap-2">
<input v-model="item.type" type="text" placeholder="Type de matériel" class="text-xs w-full rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200">
<input v-model="item.agent" type="text" placeholder="Nom de l'agent / Service" class="text-xs w-full rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200">
</div>
<button type="button" @click="removeMateriel(index)" class="p-1.5 text-rose-500 hover:bg-rose-50 dark:hover:bg-rose-950/40 rounded-md border border-transparent hover:border-rose-200 dark:hover:border-rose-900/60">
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
</button>
</div>
</div>
</div>
<!-- Licences -->
<div>
<div class="flex items-center justify-between mb-3 border-b border-slate-100 dark:border-slate-850 pb-2">
<h4 class="text-sm font-bold text-slate-850 dark:text-slate-250">Besoins de Licences Bureautique</h4>
<button type="button" @click="addLicenceBureautique" class="text-xs font-semibold text-sky-600 hover:text-sky-700 bg-sky-50 dark:bg-sky-950/40 px-2 py-1 rounded-md border border-sky-100 dark:border-sky-900/60">+ Ajouter</button>
</div>
<div class="space-y-3">
<div v-for="(item, index) in form.licences_bureautique" :key="index" class="flex items-start gap-2">
<div class="flex-1 grid grid-cols-1 sm:grid-cols-4 gap-2">
<input v-model="item.licence" type="text" placeholder="Licence bureautique" class="text-xs w-full rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200">
<input v-model="item.type" type="text" placeholder="Type de Licence" class="text-xs w-full rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200">
<input v-model="item.destination" type="text" placeholder="PC neuf ou existant" class="text-xs w-full rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200">
<input v-model="item.quantite" type="number" min="1" placeholder="Quantité" class="text-xs w-full rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200">
</div>
<button type="button" @click="removeLicenceBureautique(index)" class="p-1.5 text-rose-500 hover:bg-rose-50 dark:hover:bg-rose-950/40 rounded-md border border-transparent hover:border-rose-200 dark:hover:border-rose-900/60">
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Infrastructures -->
<div class="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-xl shadow-sm overflow-hidden flex flex-col md:flex-row">
<div class="bg-[#2f5597] p-6 md:w-56 flex-shrink-0 flex flex-col justify-center text-white">
<h3 class="text-md font-bold tracking-wide text-center md:text-left">Infrastructures Système et Télécommunications</h3>
<p class="text-xxs opacity-80 mt-2 hidden md:block">Contact : Jérémy BAYSE 04.99.41.33.18. jeremybayse@beziers-mediterranee.fr</p>
</div>
<div class="p-6 flex-1 space-y-4">
<div>
<label class="block text-xs font-bold text-slate-700 dark:text-slate-300 mb-1">Équipements réseaux - serveur :</label>
<input v-model="form.equipements_reseaux" type="text" class="w-full text-xs rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200">
</div>
<div>
<label class="block text-xs font-bold text-slate-700 dark:text-slate-300 mb-1">Travaux de câblage réseau :</label>
<input v-model="form.cablage_reseau" type="text" class="w-full text-xs rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200">
</div>
<div>
<label class="block text-xs font-bold text-slate-700 dark:text-slate-300 mb-1">Projet dans le domaine téléphonie IP :</label>
<input v-model="form.telephonie_ip" type="text" class="w-full text-xs rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200">
</div>
<div>
<label class="block text-xs font-bold text-rose-600 dark:text-rose-450 mb-1">Nouvelle structure ou bâtiment planifié en 2027 et nécessitant un raccordement informatique :</label>
<textarea v-model="form.nouveau_batiment" rows="2" class="w-full text-xs rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200"></textarea>
</div>
</div>
</div>
<!-- Etudes Projets -->
<div class="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-xl shadow-sm overflow-hidden flex flex-col md:flex-row">
<div class="bg-[#8faadc] p-6 md:w-56 flex-shrink-0 flex flex-col justify-center text-slate-900">
<h3 class="text-md font-bold tracking-wide text-center md:text-left">Etudes Projets et Dématérialisation</h3>
<p class="text-xxs opacity-85 mt-2 hidden md:block">Contact projets logiciels : Gaëtan PRULHIERE gaetanprulhiere@beziers-mediterranee.fr</p>
</div>
<div class="p-6 flex-1 space-y-6">
<div>
<label class="block text-xs font-bold text-slate-750 dark:text-slate-300 mb-1">Projet d'acquisition de logiciels métiers ou projet de dématérialisation :</label>
<p class="text-xxs text-slate-500 dark:text-slate-400 italic mb-2">Toute demande devra intégrer un chiffrage à l'appui de la demande</p>
<textarea v-model="form.logiciels_metiers" rows="3" class="w-full text-xs rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200"></textarea>
</div>
<div>
<div class="flex items-center justify-between mb-3 border-b border-slate-100 dark:border-slate-850 pb-2">
<h4 class="text-sm font-bold text-slate-850 dark:text-slate-250">Besoins ou Renouvellement de Licences</h4>
<button type="button" @click="addLicenceProjet" class="text-xs font-semibold text-sky-600 hover:text-sky-700 bg-sky-50 dark:bg-sky-950/40 px-2 py-1 rounded-md border border-sky-100 dark:border-sky-900/60">+ Ajouter</button>
</div>
<div class="space-y-3">
<div v-for="(item, index) in form.licences_projets" :key="index" class="flex items-start gap-2">
<div class="flex-1 grid grid-cols-1 sm:grid-cols-4 gap-2">
<input v-model="item.action" type="text" placeholder="Renouvellement ou achat" class="text-xs w-full rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200">
<input v-model="item.nom" type="text" placeholder="Nom de la Licence (« Adobe », « AutoCAD », GED...)" class="text-xs w-full rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200">
<input v-model="item.domaine" type="text" placeholder="Domaine (Enfance, RH, Police...)" class="text-xs w-full rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200">
<input v-model="item.quantite" type="number" min="1" placeholder="Quantité" class="text-xs w-full rounded-lg border-slate-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:bg-slate-950 dark:border-slate-800 dark:text-slate-200">
</div>
<button type="button" @click="removeLicenceProjet(index)" class="p-1.5 text-rose-500 hover:bg-rose-50 dark:hover:bg-rose-950/40 rounded-md border border-transparent hover:border-rose-200 dark:hover:border-rose-900/60">
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Barre d'actions -->
<div class="flex items-center justify-end gap-3 pt-6 border-t border-slate-200 dark:border-slate-800">
<Link
:href="route('besoins-informatiques.index')"
class="inline-flex items-center px-4 py-2 border border-slate-300 text-sm font-semibold rounded-lg text-slate-700 bg-white hover:bg-slate-50 dark:bg-slate-900 dark:text-slate-300 dark:border-slate-850 dark:hover:bg-slate-800 transition-colors shadow-sm"
>
Annuler
</Link>
<button
type="submit"
:disabled="form.processing"
class="inline-flex items-center px-4 py-2 text-sm font-semibold text-white bg-sky-600 hover:bg-sky-500 dark:bg-sky-500 dark:hover:bg-sky-400 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-sky-500 transition-colors disabled:opacity-50"
>
Mettre à jour
</button>
</div>
</form>
</div>
</div>
</AuthenticatedLayout>
</template>