Initial commit: Import existing Laravel project

This commit is contained in:
jeremy bayse
2026-06-15 08:12:33 +02:00
parent 7420d1b466
commit 030d76af53
143 changed files with 21885 additions and 1 deletions

View File

@@ -0,0 +1,307 @@
<script setup>
import { useForm, Head, Link } from '@inertiajs/vue3';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import InputError from '@/Components/InputError.vue';
import InputLabel from '@/Components/InputLabel.vue';
import TextInput from '@/Components/TextInput.vue';
import PrimaryButton from '@/Components/PrimaryButton.vue';
const props = defineProps({
hardware: {
type: Object,
default: () => null
},
orders: Array,
isEdit: Boolean,
});
// Initialisation du formulaire Inertia
const form = useForm({
name: props.hardware?.data?.name || '',
type: props.hardware?.data?.type || '',
brand: props.hardware?.data?.brand || '',
model: props.hardware?.data?.model || '',
serial_number: props.hardware?.data?.serial_number || '',
status: props.hardware?.data?.status || 'en_stock',
purchase_date: props.hardware?.data?.purchase_date || '',
commissioning_date: props.hardware?.data?.commissioning_date || '',
warranty_expiration_date: props.hardware?.data?.warranty_expiration_date || '',
location: props.hardware?.data?.location || '',
ip_address: props.hardware?.data?.ip_address || '',
order_id: props.hardware?.data?.order_id || '',
notes: props.hardware?.data?.notes || '',
});
// Raccourci pour définir une garantie standard (+3 ans)
const setStandardWarranty = () => {
if (form.purchase_date) {
const purchase = new Date(form.purchase_date);
purchase.setFullYear(purchase.getFullYear() + 3);
// Formater au format YYYY-MM-DD
const yyyy = purchase.getFullYear();
let mm = purchase.getMonth() + 1;
let dd = purchase.getDate();
if (mm < 10) mm = '0' + mm;
if (dd < 10) dd = '0' + dd;
form.warranty_expiration_date = `${yyyy}-${mm}-${dd}`;
} else {
alert("Veuillez d'abord saisir la date d'achat de l'équipement.");
}
};
const submit = () => {
if (props.isEdit) {
form.put(route('materiels.update', { materiel: props.hardware.data.id }));
} else {
form.post(route('materiels.store'));
}
};
</script>
<template>
<Head :title="isEdit ? 'Modifier équipement' : 'Ajouter un équipement'" />
<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">
{{ isEdit ? `Modifier la fiche : ${hardware.data.name}` : 'Ajouter un équipement à l\'inventaire' }}
</h2>
<Link
:href="isEdit ? route('materiels.show', { materiel: hardware.data.id }) : route('materiels.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"
>
Annuler
</Link>
</div>
</template>
<div class="py-6">
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-xl shadow-sm overflow-hidden p-6">
<form @submit.prevent="submit" class="space-y-6">
<!-- Section : Identification -->
<div>
<h3 class="text-sm font-bold text-sky-600 dark:text-sky-400 uppercase tracking-wider border-b border-slate-100 dark:border-slate-850 pb-2 mb-4">
Identification du matériel
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<InputLabel for="name" value="Nom d'usage de l'équipement" />
<TextInput
id="name"
type="text"
class="mt-1 block w-full"
v-model="form.name"
required
placeholder="ex: Serveur Hyper-V 01"
/>
<InputError class="mt-2" :message="form.errors.name" />
</div>
<div>
<InputLabel for="type" value="Type de matériel" />
<select
id="type"
v-model="form.type"
required
class="mt-1 block w-full border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm"
>
<option value="" disabled>Sélectionner un type</option>
<option value="serveur">Serveur</option>
<option value="switch">Switch</option>
<option value="routeur">Routeur</option>
<option value="onduleur">Onduleur</option>
<option value="stockage">Stockage (NAS/SAN)</option>
<option value="pare-feu">Pare-feu</option>
<option value="poste_travail">Poste de travail</option>
<option value="autre">Autre</option>
</select>
<InputError class="mt-2" :message="form.errors.type" />
</div>
<div>
<InputLabel for="brand" value="Marque / Constructeur" />
<TextInput
id="brand"
type="text"
class="mt-1 block w-full"
v-model="form.brand"
required
placeholder="ex: Dell"
/>
<InputError class="mt-2" :message="form.errors.brand" />
</div>
<div>
<InputLabel for="model" value="Modèle" />
<TextInput
id="model"
type="text"
class="mt-1 block w-full"
v-model="form.model"
required
placeholder="ex: PowerEdge R750"
/>
<InputError class="mt-2" :message="form.errors.model" />
</div>
<div>
<InputLabel for="serial_number" value="Numéro de série physique" />
<TextInput
id="serial_number"
type="text"
class="mt-1 block w-full font-mono uppercase"
v-model="form.serial_number"
required
placeholder="ex: CN-0ABC12-DEF34-..."
/>
<InputError class="mt-2" :message="form.errors.serial_number" />
</div>
<div>
<InputLabel for="status" value="Statut courant" />
<select
id="status"
v-model="form.status"
required
class="mt-1 block w-full border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm"
>
<option value="en_stock">En stock / Rechange</option>
<option value="en_service">En service / Actif</option>
<option value="en_panne">En panne / Maintenance</option>
<option value="au_rebut">Au rebut / Declassé</option>
</select>
<InputError class="mt-2" :message="form.errors.status" />
</div>
</div>
</div>
<!-- Section : Cycle de vie & Dates -->
<div>
<h3 class="text-sm font-bold text-sky-600 dark:text-sky-400 uppercase tracking-wider border-b border-slate-100 dark:border-slate-850 pb-2 mb-4">
Cycle de vie & Garantie
</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<InputLabel for="purchase_date" value="Date d'achat" />
<TextInput
id="purchase_date"
type="date"
class="mt-1 block w-full"
v-model="form.purchase_date"
/>
<InputError class="mt-2" :message="form.errors.purchase_date" />
</div>
<div>
<InputLabel for="commissioning_date" value="Date de mise en service" />
<TextInput
id="commissioning_date"
type="date"
class="mt-1 block w-full"
v-model="form.commissioning_date"
/>
<InputError class="mt-2" :message="form.errors.commissioning_date" />
</div>
<div>
<div class="flex justify-between items-center">
<InputLabel for="warranty_expiration_date" value="Fin de garantie" />
<button
type="button"
@click="setStandardWarranty"
class="text-xxs font-bold text-sky-600 hover:text-sky-500 dark:text-sky-450 underline"
>
+3 ans de garantie
</button>
</div>
<TextInput
id="warranty_expiration_date"
type="date"
class="mt-1 block w-full"
v-model="form.warranty_expiration_date"
/>
<InputError class="mt-2" :message="form.errors.warranty_expiration_date" />
</div>
</div>
</div>
<!-- Section : Technique & Traçabilité -->
<div>
<h3 class="text-sm font-bold text-sky-600 dark:text-sky-400 uppercase tracking-wider border-b border-slate-100 dark:border-slate-850 pb-2 mb-4">
Localisation & Réseau
</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<InputLabel for="location" value="Emplacement physique" />
<TextInput
id="location"
type="text"
class="mt-1 block w-full"
v-model="form.location"
required
placeholder="ex: Baie A, Salle Serveur 1"
/>
<InputError class="mt-2" :message="form.errors.location" />
</div>
<div>
<InputLabel for="ip_address" value="Adresse IP de gestion" />
<TextInput
id="ip_address"
type="text"
class="mt-1 block w-full font-mono"
v-model="form.ip_address"
placeholder="ex: 192.168.10.25"
/>
<InputError class="mt-2" :message="form.errors.ip_address" />
</div>
<div>
<InputLabel for="order_id" value="Commande d'achat d'origine" />
<select
id="order_id"
v-model="form.order_id"
class="mt-1 block w-full border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm"
>
<option value="">Aucune commande liée</option>
<option v-for="order in orders" :key="order.id" :value="order.id">
{{ order.number }} - {{ order.label }}
</option>
</select>
<InputError class="mt-2" :message="form.errors.order_id" />
</div>
</div>
</div>
<!-- Notes libres -->
<div>
<InputLabel for="notes" value="Notes libres & Historique des interventions" />
<textarea
id="notes"
v-model="form.notes"
rows="4"
placeholder="Historique des pannes, changements de pièces, interventions..."
class="mt-1 block w-full border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm"
></textarea>
<InputError class="mt-2" :message="form.errors.notes" />
</div>
<!-- Boutons d'action -->
<div class="flex items-center justify-end gap-3 pt-4 border-t border-slate-100 dark:border-slate-850">
<PrimaryButton :disabled="form.processing">
{{ isEdit ? 'Enregistrer les modifications' : 'Enregistrer le matériel' }}
</PrimaryButton>
</div>
</form>
</div>
</div>
</div>
</AuthenticatedLayout>
</template>