import React, { useEffect, useMemo } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useForm } from "react-hook-form";
import { fetchGrades } from "../features/grades/GradesSlice";
import { fetchClassRooms } from "../features/classrooms/ClassRoomsSlice";
import { fetchSections } from "../features/sections/SectionsSlice";
import { addStudent } from "../features/students/StudentsSlice";
import toast from "react-hot-toast";
const AddStudent = () => {
const dispatch = useDispatch();
// ================================
// Redux State
// ================================
const { grades } = useSelector((state) => state.grades);
const { classrooms } = useSelector((state) => state.classrooms);
const { sections } = useSelector((state) => state.sections);
// ================================
// React Hook Form
// ================================
const {
register,
handleSubmit,
watch,
reset,
formState: { errors }
} = useForm({
// 🔥 التحقق لحظيًا أثناء الكتابة
mode: "onChange",
// 🔥 قيم افتراضية
defaultValues: {
grade: "",
classroom: "",
section: ""
}
});
// ================================
// جلب البيانات
// ================================
useEffect(() => {
dispatch(fetchGrades());
dispatch(fetchClassRooms());
dispatch(fetchSections());
}, [dispatch]);
// ================================
// مراقبة الحقول
// ================================
// 🔥 المرحلة المختارة
const selectedGrade = watch("grade");
// 🔥 الصف المختار
const selectedClassroom = watch("classroom");
// ================================
// فلترة الصفوف حسب المرحلة
// ================================
const filteredClassrooms = useMemo(() => {
if (!selectedGrade) return [];
return classrooms.filter(
(classroom) =>
classroom.grade?.documentId === selectedGrade
);
}, [selectedGrade, classrooms]);
// ================================
// فلترة الأقسام حسب الصف
// ================================
const filteredSections = useMemo(() => {
if (!selectedClassroom) return [];
return sections.filter(
(section) =>
section.classroom?.documentId === selectedClassroom
);
}, [selectedClassroom, sections]);
// ================================
// إرسال البيانات
// ================================
const onSubmit = (data) => {
// 🔥 لا نرسل المرحلة والصف
// فقط القسم
const studentData = {
st_code: data.st_code,
name: data.name,
age: data.age,
phone: data.phone,
email: data.email,
address: data.address,
blood: data.blood,
father: data.father,
mother: data.mother,
// 🔥 المهم
section: data.section
};
dispatch(addStudent(studentData))
.unwrap()
.then(() => {
toast.success("تم إضافة الطالب بنجاح");
// 🔥 تصفير الفورم
reset();
})
.catch(() => {
toast.error("حدث خطأ أثناء الإضافة");
});
};
return (
<div className="row">
<div className="col-12">
<div className="card">
{/* ============================= */}
{/* Header */}
{/* ============================= */}
<div className="card-header">
<h3 className="card-title">
إضافة طالب جديد
</h3>
</div>
{/* ============================= */}
{/* Body */}
{/* ============================= */}
<div className="card-body">
<form onSubmit={handleSubmit(onSubmit)}>
{/* ===================================== */}
{/* الصف الأول */}
{/* ===================================== */}
<div className="row">
{/* كود الطالب */}
<div className="mb-3 col">
<label className="form-label">
كود الطالب
</label>
<input
type="text"
className="form-control"
{...register("st_code", {
required: "كود الطالب مطلوب"
})}
/>
{errors.st_code && (
<small className="text-danger">
{errors.st_code.message}
</small>
)}
</div>
{/* اسم الطالب */}
<div className="mb-3 col">
<label className="form-label">
اسم الطالب
</label>
<input
type="text"
className="form-control"
{...register("name", {
required: "اسم الطالب مطلوب",
minLength: {
value: 3,
message: "الاسم يجب أن يكون 3 أحرف على الأقل"
}
})}
/>
{errors.name && (
<small className="text-danger">
{errors.name.message}
</small>
)}
</div>
{/* العمر */}
<div className="mb-3 col">
<label className="form-label">
العمر
</label>
<input
type="number"
className="form-control"
{...register("age", {
required: "العمر مطلوب",
min: {
value: 5,
message: "العمر غير صالح"
}
})}
/>
{errors.age && (
<small className="text-danger">
{errors.age.message}
</small>
)}
</div>
</div>
{/* ===================================== */}
{/* الصف الثاني */}
{/* ===================================== */}
<div className="row">
{/* الهاتف */}
<div className="mb-3 col">
<label className="form-label">
الهاتف
</label>
<input
type="text"
className="form-control"
{...register("phone", {
required: "رقم الهاتف مطلوب",
minLength: {
value: 9,
message: "رقم الهاتف غير صالح"
}
})}
/>
{errors.phone && (
<small className="text-danger">
{errors.phone.message}
</small>
)}
</div>
{/* البريد */}
<div className="mb-3 col">
<label className="form-label">
البريد الإلكتروني
</label>
<input
type="email"
className="form-control"
{...register("email", {
required: "البريد الإلكتروني مطلوب",
pattern: {
value: /^\S+@\S+$/i,
message: "البريد الإلكتروني غير صالح"
}
})}
/>
{errors.email && (
<small className="text-danger">
{errors.email.message}
</small>
)}
</div>
</div>
{/* ===================================== */}
{/* الصف الثالث */}
{/* ===================================== */}
<div className="row">
{/* العنوان */}
<div className="mb-3 col">
<label className="form-label">
العنوان
</label>
<input
type="text"
className="form-control"
{...register("address", {
required: "العنوان مطلوب"
})}
/>
{errors.address && (
<small className="text-danger">
{errors.address.message}
</small>
)}
</div>
{/* زمرة الدم */}
<div className="mb-3 col">
<label className="form-label">
زمرة الدم
</label>
<input
type="text"
className="form-control"
{...register("blood")}
/>
</div>
</div>
{/* ===================================== */}
{/* الأب والأم */}
{/* ===================================== */}
<div className="row">
<div className="mb-3 col">
<label className="form-label">
اسم الأب
</label>
<input
type="text"
className="form-control"
{...register("father")}
/>
</div>
<div className="mb-3 col">
<label className="form-label">
اسم الأم
</label>
<input
type="text"
className="form-control"
{...register("mother")}
/>
</div>
</div>
{/* ===================================== */}
{/* المرحلة - الصف - القسم */}
{/* ===================================== */}
<div className="row mt-3">
{/* المرحلة */}
<div className="col">
<label className="form-label">
المرحلة
</label>
<select
className="form-select"
{...register("grade", {
required: "المرحلة مطلوبة"
})}
>
<option value="">
اختر المرحلة
</option>
{grades?.map((grade) => (
<option
key={grade.documentId}
value={grade.documentId}
>
{grade.name}
</option>
))}
</select>
{errors.grade && (
<small className="text-danger">
{errors.grade.message}
</small>
)}
</div>
{/* الصف */}
<div className="col">
<label className="form-label">
الصف
</label>
<select
className="form-select"
{...register("classroom", {
required: "الصف مطلوب"
})}
>
<option value="">
اختر الصف
</option>
{filteredClassrooms.map((classroom) => (
<option
key={classroom.documentId}
value={classroom.documentId}
>
{classroom.name}
</option>
))}
</select>
{errors.classroom && (
<small className="text-danger">
{errors.classroom.message}
</small>
)}
</div>
{/* القسم */}
<div className="col">
<label className="form-label">
القسم
</label>
<select
className="form-select"
{...register("section", {
required: "القسم مطلوب"
})}
>
<option value="">
اختر القسم
</option>
{filteredSections.map((section) => (
<option
key={section.documentId}
value={section.documentId}
>
{section.name}
</option>
))}
</select>
{errors.section && (
<small className="text-danger">
{errors.section.message}
</small>
)}
</div>
</div>
{/* ===================================== */}
{/* زر الحفظ */}
{/* ===================================== */}
<button
type="submit"
className="btn btn-primary mt-5"
>
حفظ البيانات
</button>
</form>
</div>
</div>
</div>
</div>
);
};
export default AddStudent;
Dart