Classrooom sections

المطلوب

في صفحة الصفوف:

الصف الأول
الصف الثاني
الصف الثالث
JSX

كل صف يحتوي زر:

عرض الأقسام
JSX

🚀 الخطوة 1: إضافة الزر داخل جدول الصفوف

داخل:

classrooms.map(...)
JSX

أضف:

<Link
    to={`/classrooms/${classroom.documentId}/sections`}
    className="btn btn-info btn-sm"
>
    الأقسام
</Link>
JSX

🚀 الخطوة 2: إنشاء Route

داخل App.jsx

<Route
    path="/classrooms/:id/sections"
    element={<ClassroomSections />}
/>
JSX

🚀 الخطوة 3: إنشاء صفحة جديدة

pages/classrooms/ClassroomSections.jsx
JSX

🎯 ما الذي ستفعله الصفحة؟

1- جلب بيانات الصف

الصف الأول
JSX

2- جلب الأقسام التابعة له

A
B
C
JSX

🚀 الخطوة 4: إنشاء fetchSingleClassroom

داخل ClassroomsSlice


AsyncThunk

export const fetchSingleClassroom =
    createAsyncThunk(

        "classrooms/fetchSingleClassroom",

        async (id, thunkAPI) => {

            try {

                const response =
                    await axiosInstance.get(

                        `/classrooms/${id}?populate=grade`

                    );

                return response.data.data;

            } catch (error) {

                return thunkAPI.rejectWithValue(
                    error.response?.data || error.message
                );

            }

        }

    );
JSX

initialState

أضف:

singleClassroom: null,
JSX

addCase

.addCase(
    fetchSingleClassroom.fulfilled,

    (state, action) => {

        state.singleClassroom =
            action.payload;

    }
)
JSX

🚀 الخطوة 5: إنشاء fetchSectionsByClassroom

داخل SectionsSlice


AsyncThunk

export const fetchSectionsByClassroom =
    createAsyncThunk(

        "sections/fetchSectionsByClassroom",

        async (classroomId, thunkAPI) => {

            try {

                const response =
                    await axiosInstance.get(

                        `/sections?filters[classroom][documentId][$eq]=${classroomId}&populate=classroom.grade`

                    );

                return response.data.data;

            } catch (error) {

                return thunkAPI.rejectWithValue(
                    error.response?.data || error.message
                );

            }

        }

    );
JSX

addCase

.addCase(
    fetchSectionsByClassroom.fulfilled,

    (state, action) => {

        state.sections =
            action.payload;

    }
)
JSX

🚀 الخطوة 6: صفحة ClassroomSections


البداية

import { useEffect } from "react";

import { useDispatch, useSelector }
from "react-redux";

import { useParams, Link }
from "react-router-dom";

import {
    fetchSingleClassroom
}
from "../../features/classrooms/ClassroomsSlice";

import {
    fetchSectionsByClassroom
}
from "../../features/sections/SectionsSlice";
JSX

Hooks

const { id } = useParams();

const dispatch = useDispatch();
JSX

Redux

const {
    singleClassroom
} = useSelector(
    (state) => state.classrooms
);

const {
    sections
} = useSelector(
    (state) => state.sections
);
JSX

Fetch

useEffect(() => {

    dispatch(
        fetchSingleClassroom(id)
    );

    dispatch(
        fetchSectionsByClassroom(id)
    );

}, [dispatch, id]);
JSX

🚀 عرض معلومات الصف

<div className="card mb-3">

    <div className="card-body">

        <h3>

            {singleClassroom?.name}

        </h3>

        <p>

            المرحلة:

            {singleClassroom?.grade?.name}

        </p>

    </div>

</div>
JSX

🚀 عرض الأقسام

<table className="table table-bordered">

    <thead>

        <tr>

            <th>#</th>

            <th>اسم القسم</th>

            <th>الإجراءات</th>

        </tr>

    </thead>

    <tbody>

        {
            sections.map(

                (section, index) => (

                    <tr
                        key={
                            section.documentId
                        }
                    >

                        <td>
                            {index + 1}
                        </td>

                        <td>
                            {section.name}
                        </td>

                        <td>

                            <Link
                                to={`/sections/${section.documentId}/students`}
                                className="btn btn-primary btn-sm"
                            >

                                الطلاب

                            </Link>

                        </td>

                    </tr>

                )

            )
        }

    </tbody>

</table>
JSX

🎯 النتيجة النهائية

سيصبح لديك تسلسل احترافي جدًا:

صفوف

صف واحد

الأقسام التابعة

طلاب القسم

تفاصيل الطالب
JSX

💡 اقتراح معماري مهم

بما أنك بدأت تضيف صفحات متسلسلة، أنصحك باعتماد هذا النمط:

/grades/:id/classrooms

/classrooms/:id/sections

/sections/:id/students

/students/:id
JSX

بهذا تصبح الروابط منطقية وقابلة للمشاركة، وحتى عند تحديث الصفحة (F5) يمكن جلب البيانات من الـ API مباشرة لكل مستوى من مستويات النظام. 🚀