CRUD Final 4 : Vue, Inertia & Laravel
Thème :
Intermédiaire
2 vues ·4/7 leçons

Edit.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.