CRUD Final 4 : Vue, Inertia & Laravel
Thème :
Intermédiaire
2 vues ·4/7 leçonsEdit.vue
<script setup lang="ts">
import { Form, Head, Link } from '@inertiajs/vue3';
import StudentController from '@/actions/App/Http/Controllers/StudentController';
import type { Student } from '@/types/student';
import * as studentsRoute from '@/routes/students';
interface Props {
student: Student;
}
const props = defineProps<Props>();
</script>
<template>
<Head title="Modifier un étudiant" />
<div class="container">
<Form v-bind="StudentController.update.form(props.student.id)" enctype="multipart/form-data" class="form" v-slot="{ errors, processing }">
<div class="form-card">
<!-- Nom -->
<div class="form-group">
<label for="name">Nom complet</label>
<input id="name" name="name" type="text" :value="props.student.name" placeholder="ex: Jean Dupont" />
<span class="text-red-500">{{ errors.name }}</span>
</div>
<!-- Email -->
<div class="form-group">
<label for="email">Email</label>
<input id="email" name="email" type="email" :value="props.student.email" placeholder="ex: jean.dupont@example.com" />
<span class="text-red-500">{{ errors.email }}</span>
</div>
<!-- Sexe -->
<div class="form-group">
<label>Sexe</label>
<div class="flex gap-4">
<label> <input type="radio" name="sexe" value="male" :checked="props.student.sexe === 'male'" /> Masculin </label>
<label> <input type="radio" name="sexe" value="female" :checked="props.student.sexe === 'female'" /> Féminin </label>
<label> <input type="radio" name="sexe" value="other" :checked="props.student.sexe === 'other'" /> Autre </label>
</div>
<span class="text-red-500">{{ errors.sexe }}</span>
</div>
<!-- Programmes -->
<div class="form-group">
<label>Programmes</label>
<div class="checkbox-group">
<label>
<input type="checkbox" name="programs[]" value="php" :checked="props.student.programs.includes('php')" />
PHP
</label>
<label>
<input type="checkbox" name="programs[]" value="js" :checked="props.student.programs.includes('js')" />
JavaScript
</label>
<label>
<input type="checkbox" name="programs[]" value="html" :checked="props.student.programs.includes('html')" />
HTML
</label>
<label>
<input type="checkbox" name="programs[]" value="typescript" :checked="props.student.programs.includes('typescript')" />
TypeScript
</label>
<label>
<input type="checkbox" name="programs[]" value="vuejs" :checked="props.student.programs.includes('vuejs')" />
Vue.js
</label>
<label>
<input type="checkbox" name="programs[]" value="nuxtjs" :checked="props.student.programs.includes('nuxtjs')" />
Nuxt.js
</label>
</div>
<span class="text-red-500">{{ errors.programs }}</span>
</div>
<!-- Profil (Image) -->
<div class="form-group">
<label for="profile">Photo de profil</label>
<input id="profile" name="profile" type="file" />
<span class="text-red-500">{{ errors.profile }}</span>
</div>
<!-- Pays -->
<div class="form-group">
<label for="country">Pays</label>
<select id="country" name="country" :value="props.student.country">
<option value="France">France</option>
<option value="Canada">Canada</option>
<option value="Belgique">Belgique</option>
<option value="Suisse">Suisse</option>
</select>
<span class="text-red-500">{{ errors.country }}</span>
</div>
<!-- Langue -->
<div class="form-group">
<label>Langue</label>
<div class="flex gap-4">
<label> <input type="radio" name="language" value="fr" :checked="props.student.language === 'fr'" /> Français </label>
<label> <input type="radio" name="language" value="en" :checked="props.student.language === 'en'" /> Anglais </label>
</div>
<span class="text-red-500">{{ errors.language }}</span>
</div>
<!-- Bio -->
<div class="form-group">
<label for="bio">Biographie</label>
<textarea id="bio" name="bio" :value="props.student.bio" placeholder="Décrivez-vous en quelques mots..."></textarea>
<span class="text-red-500">{{ errors.bio }}</span>
</div>
<!-- Boutons d'action -->
<div class="form-actions">
<button type="reset" :disabled="processing" class="btn-secondary">Annuler</button>
<Link :href="studentsRoute.index().url" class="btn-secondary">Retour aux étudiants</Link>
<button type="submit" :disabled="processing" class="btn-primary">
<span v-if="processing">Enregistrement...</span>
<span v-else>Mettre à jour</span>
</button>
</div>
</div>
</Form>
</div>
</template>
<style scoped>
.container {
padding: 2rem;
max-width: 800px;
margin: 0 auto;
}
.form-card {
background: white;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 极速11选5开奖结果安装1);
}
.form-group {
margin-bottom: 1rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
}
.checkbox-group {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.checkbox-group label {
display: flex;
align-items: center;
gap: 0.5rem;
font-weight: normal;
}
.checkbox-group input[type='checkbox'] {
width: auto;
}
.form-actions {
display: flex;
justify-content: flex-end;
gap: 1rem;
padding-top: 1rem;
border-top: 1px solid #eee;
}
.btn-primary {
background: green;
color: white;
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
cursor: pointer;
}
.btn-primary:hover {
background: darkgreen;
}
.btn-secondary {
background: white;
color: #333;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
cursor: pointer;
}
.btn-secondary:hover {
background: #f5f5f5;
}
</style>
Prêt à passer à la suite ?
Vous avez terminé cette leçon sur Edit.vue. Continuez votre apprentissage avec la prochaine leçon ou explorez d'autres formations.