Compare commits

...

3 Commits

Author SHA1 Message Date
Moaz Dawalibi
36feda0b43 fixes 2024-09-14 14:41:13 +03:00
Moaz Dawalibi
4b3246e6e8 Merge branch 'dev' of into dev 2024-09-14 14:41:07 +03:00
Moaz Dawalibi
0c7603ce94 single student 2024-09-14 14:39:13 +03:00
17 changed files with 400 additions and 65 deletions

View File

@ -0,0 +1,24 @@
import { Divider } from 'antd'
import { useTranslation } from 'react-i18next'
import { RxHome } from "react-icons/rx";
const StudentAddressCard = ({address}:{address:string}) => {
const {t} = useTranslation();
return (
<div className='student_address_card'>
<h5>{t("practical.address")}</h5>
<Divider/>
<div className="student_address_card_body">
<RxHome/>
<span>
<h6>{t("practical.address")}</h6>
<p>{address}</p>
</span>
</div>
</div>
)
}
export default StudentAddressCard

View File

@ -0,0 +1,30 @@
import React from 'react'
import { studentParamInfo } from './StudentParam'
import { Divider } from 'antd'
const StudentInfoCard = ({data,name,status}:any) => {
return (
<div className='student_info_card'>
<div className="student_info_card_header">
<img src="/Image/faker_user.png " alt="" />
<div className="student_name_and_sub">
<span>{status}</span>
<h2>{name}</h2>
</div>
</div>
<Divider/>
<div className="student_info_card_body">
{data?.map((student:any)=>(
<span>
<h4>{student?.key}</h4>
<p>{student?.value}</p>
</span>
))}
</div>
</div>
)
}
export default StudentInfoCard

View File

@ -0,0 +1,8 @@
export const studentParamInfo = [
{key:"الحنس" , value:"male"},
{key:"sex" , value:"male"},
{key:"sex" , value:"male"},
{key:"sex" , value:"male"},
{key:"sex" , value:"male"},
{key:"sex" , value:"male"}
]

View File

@ -17,12 +17,14 @@ const PageHeader = ({
pageTitle, pageTitle,
openModel = true, openModel = true,
locationToNavigate, locationToNavigate,
addModal = true
}: { }: {
canAdd: any; canAdd?: any;
ModelAbility: any; ModelAbility?: any;
pageTitle: string; pageTitle: string;
openModel?: boolean; openModel?: boolean;
locationToNavigate?: string | any; locationToNavigate?: string | any;
addModal?:boolean;
}) => { }) => {
const navigate = useNavigate(); const navigate = useNavigate();
const { handel_open_model } = useModalHandler(); const { handel_open_model } = useModalHandler();
@ -49,7 +51,7 @@ const PageHeader = ({
<MdOutlineArrowForwardIos /> {PageTitle} <MdOutlineArrowForwardIos /> {PageTitle}
</span> </span>
</span> </span>
{canAdd && ( { addModal ? canAdd && (
<div className="Selects"> <div className="Selects">
<button <button
onClick={() => onClick={() =>
@ -63,7 +65,7 @@ const PageHeader = ({
{t(`practical.add`)} {t(`practical.add`)}
</button> </button>
</div> </div>
)} ) :""}
</header> </header>
</div> </div>
); );

View File

@ -0,0 +1,22 @@
import React from "react";
import ValidationField from "../../../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap";
import { userTypeOptions } from "../../../../../config/userTypeOptions";
const FilterForm = () => {
return (
<div>
<Row>
<Col>
<ValidationField placeholder="username" label="username" name="username" />
<ValidationField placeholder="phone_number" label="phone_number" name="phone_number" />
</Col>
<Col>
<ValidationField type="Select" option={userTypeOptions} placeholder="type" label="type" name="type" />
</Col>
</Row>
</div>
);
};
export default FilterForm;

View File

@ -0,0 +1,44 @@
import { useTranslation } from "react-i18next";
import { Suspense } from "react";
import { Spin } from "antd";
import useSetPageTitle from "../../../../Hooks/useSetPageTitle";
import PageHeader from "../../../../Layout/Dashboard/PageHeader";
import FilterLayout from "../../../../Layout/Dashboard/FilterLayout";
import FilterForm from "./Model/FilterForm";
import StudentInfoCard from "../../../../Components/student/StudentInfoCard";
import StudentAddressCard from "../../../../Components/student/AddressCard";
import { studentParamInfo } from "../../../../Components/student/StudentParam";
import StudentTabs from "./StudentTabs";
const TableHeader = () => {
const [t] = useTranslation();
useSetPageTitle(
t(`page_header.users`) +
"/ " +
t(`PageTitle.students`)
+
" / " +
t(`PageTitle.students_details`),
);
return (
<div className="TableWithHeader single_student">
<Suspense fallback={<Spin />}>
<PageHeader
pageTitle="users"
/>
<div className="single_student_body">
<div className="student_info">
<StudentInfoCard data={studentParamInfo} name={"moaz dawalibi"} status={"subs"}/>
<StudentAddressCard address={"adawi tjara dar alshfaa askn akan an aksn akn"} />
</div>
<div className="student_table">
<StudentTabs/>
</div>
</div>
</Suspense>
</div>
);
};
export default TableHeader;

View File

@ -0,0 +1,61 @@
import { useTranslation } from 'react-i18next';
import { Tabs } from 'antd';
import type { TabsProps } from 'antd';
import FilterLayout from '../../../../Layout/Dashboard/FilterLayout';
import FilterForm from './Model/FilterForm';
import { lazy } from 'react';
import { BsQuestionSquare } from "react-icons/bs";
import { IoStatsChartOutline } from "react-icons/io5";
import { useGetAllUser } from '../../../../api/user';
import useSearchQuery from '../../../../api/utils/useSearchQuery';
import { useFilterState } from '../../../../Components/Utils/Filter/FilterState';
const Table = lazy(() => import("./Table"));
const StudentTabs = () => {
const {t} = useTranslation();
const [searchQuery] = useSearchQuery("name");
const { filterState } = useFilterState();
const response = useGetAllUser({
name: searchQuery,
pagination: true,
...filterState,
});
const items: TabsProps['items'] = [
{
key: '1',
label: <span>{t("practical.quiz")} </span>,
icon:<BsQuestionSquare/>,
children:
<>
<FilterLayout
sub_children={<FilterForm />}
filterTitle="sidebar.quiz"
/>
<Table response={response}/>
</>,
},
{
key: '2',
label: <span>{t("practical.hightes_quiz")} </span>,
icon:<IoStatsChartOutline/>,
children:
<>
<FilterLayout
sub_children={<FilterForm />}
filterTitle="practical.hightes_quiz"
/>
<Table response={response}/>
</>,
},
];
return (
<>
<Tabs defaultActiveKey="1" items={items} />
</>
)
}
export default StudentTabs

View File

@ -0,0 +1,8 @@
import DataTable from "../../../../Layout/Dashboard/Table/DataTable";
import { useColumns } from "./useTableColumns";
const App = ({response}:{response:any}) => {
return <DataTable response={response} useColumns={useColumns} />;
};
export default App;

View File

@ -0,0 +1,9 @@
import { useColumns } from "./useTableColumns";
import Table from "./Table";
import { FaPlus } from "react-icons/fa";
export {
Table,
useColumns,
FaPlus,
};

View File

@ -0,0 +1,48 @@
import { TableColumnsType } from "antd";
import { user } from "../../../../types/Item";
import { useTranslation } from "react-i18next";
export const useColumns = () => {
const [t] = useTranslation();
const columns: TableColumnsType<user> = [
{
title: t("columns.quiz_date"),
dataIndex: "id",
key: "id",
align: "center",
},
{
title: t("columns.subject"),
dataIndex: "username",
key: "username",
align: "center",
},
{
title: t("columns.quiz_address"),
dataIndex: "phone_number",
key: "phone_number",
align: "center",
},
{
title: t("columns.created_by"),
dataIndex: "type",
key: "type",
align: "center",
},
{
title: t("columns.creator_name"),
dataIndex: "type",
key: "type",
align: "center",
},
{
title: t("columns.quiz_status"),
dataIndex: "type",
key: "type",
align: "center",
},
];
return columns;
};

View File

@ -1,11 +1,12 @@
import { TableColumnsType } from "antd"; import { TableColumnsType } from "antd";
import { user } from "../../../types/Item"; import { user } from "../../../types/Item";
import { ModalEnum } from "../../../enums/Model"; import { ModalEnum } from "../../../enums/Model";
import { useObjectToEdit } from "../../../zustand/ObjectToEditState"; import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
import { useModalState } from "../../../zustand/Modal"; import { useModalState } from "../../../zustand/Modal";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { canDeleteUser, canEditUser } from "../../../utils/hasAbilityFn"; import { canDeleteUser, canEditUser } from "../../../utils/hasAbilityFn";
import ActionButtons from "../../../Components/Table/ActionButtons"; import ActionButtons from "../../../Components/Table/ActionButtons";
import { useNavigate } from "react-router-dom";
export const useColumns = () => { export const useColumns = () => {
const [t] = useTranslation(); const [t] = useTranslation();
@ -13,6 +14,7 @@ export const useColumns = () => {
const { setIsOpen } = useModalState((state) => state); const { setIsOpen } = useModalState((state) => state);
const { setObjectToEdit } = useObjectToEdit((state) => state); const { setObjectToEdit } = useObjectToEdit((state) => state);
const handelDelete = (record: any) => { const handelDelete = (record: any) => {
setObjectToEdit(record); setObjectToEdit(record);
setIsOpen(ModalEnum?.USER_DELETE); setIsOpen(ModalEnum?.USER_DELETE);

View File

@ -21,6 +21,8 @@ const EditQuestionPage = React.lazy(
const Report = React.lazy(() => import("./Pages/Admin/Report/Page")); const Report = React.lazy(() => import("./Pages/Admin/Report/Page"));
const Student = React.lazy(() => import("./Pages/Admin/Student/Page")); const Student = React.lazy(() => import("./Pages/Admin/Student/Page"));
const ShowStudent = React.lazy(() => import("./Pages/Admin/Student/show/Page"));
const ReSeller = React.lazy(() => import("./Pages/Admin/Reseller/Page")); const ReSeller = React.lazy(() => import("./Pages/Admin/Reseller/Page"));
const AddReSeller = React.lazy(() => import("./Pages/Admin/Reseller/Add/Page")); const AddReSeller = React.lazy(() => import("./Pages/Admin/Reseller/Add/Page"));
const EditReSeller = React.lazy( const EditReSeller = React.lazy(
@ -28,6 +30,7 @@ const EditReSeller = React.lazy(
); );
const User = React.lazy(() => import("./Pages/Admin/User/Page")); const User = React.lazy(() => import("./Pages/Admin/User/Page"));
const Param = React.lazy(() => import("./Pages/Admin/Param/Page")); const Param = React.lazy(() => import("./Pages/Admin/Param/Page"));
/// RESELLER /// /// RESELLER ///
@ -138,57 +141,6 @@ export const menuItems: TMenuItem[] = [
type: UserTypeEnum.RE_SELLER, type: UserTypeEnum.RE_SELLER,
}, },
// {
// header: "page_header.tags",
// element: <Tags />,
// icon: <FaMoneyBill />,
// text: "sidebar.tags",
// path: `/${ABILITIES_ENUM?.TAG}`,
// abilities: ABILITIES_ENUM?.TAG,
// abilities_value: ABILITIES_VALUES_ENUM.INDEX,
// prevPath: 0,
// },
// {
// header: "page_header.subject",
// element: <Subject />,
// icon: <FaMoneyBill />,
// text: "sidebar.subject",
// path: `/${ABILITIES_ENUM?.SUBJECT}`,
// abilities: ABILITIES_ENUM?.SUBJECT,
// abilities_value: ABILITIES_VALUES_ENUM.INDEX,
// prevPath: 0,
// },
// {
// header: "page_header.package",
// element: <Package />,
// icon: <LuPackage />,
// text: "sidebar.package",
// path: `/${ABILITIES_ENUM?.Package}`,
// abilities: ABILITIES_ENUM?.Package,
// abilities_value: ABILITIES_VALUES_ENUM.INDEX,
// prevPath: 0,
// },
// {
// header: "page_header.subject",
// element: <Subject />,
// icon: <FaMoneyBill />,
// text: "sidebar.subject",
// path: `/${ABILITIES_ENUM?.SUBJECT}`,
// abilities: ABILITIES_ENUM?.SUBJECT,
// abilities_value: ABILITIES_VALUES_ENUM.INDEX,
// prevPath: 0,
// },
// {
// header: "page_header.tags",
// element: <Tags />,
// icon: <FaMoneyBill />,
// text: "sidebar.tags",
// path: `/${ABILITIES_ENUM?.TAG}`,
// abilities: ABILITIES_ENUM?.TAG,
// abilities_value: ABILITIES_VALUES_ENUM.INDEX,
// prevPath: 0,
// },
]; ];
export const CrudRoute: TCrudRoute[] = [ export const CrudRoute: TCrudRoute[] = [
@ -259,6 +211,14 @@ export const CrudRoute: TCrudRoute[] = [
abilities_value: ABILITIES_VALUES_ENUM.INDEX, abilities_value: ABILITIES_VALUES_ENUM.INDEX,
prevPath: 0, prevPath: 0,
}, },
{
header: "page_header.student",
element: <ShowStudent />,
path: `/${ABILITIES_ENUM?.STUDENT}/:id`,
abilities: ABILITIES_ENUM?.STUDENT,
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
prevPath: 0,
}
]; ];
export const AppRoutes: Record<string, string> = Object.fromEntries( export const AppRoutes: Record<string, string> = Object.fromEntries(

View File

@ -0,0 +1,101 @@
.single_student{
display: flex;
.single_student_body{
display: flex;
width: 100%;
.student_info{
width: 32%;
}
.student_table{
width: 68%;
}
}
}
.student_info_card{
width: 24vw;
box-shadow: 2px 2px 8px 3px rgba(0, 0, 0, 0.1);
border-radius: 10px;
padding: 20px 15px ;
.student_info_card_header{
display: flex;
gap: 10px;
img{
width: 24%;
}
.student_name_and_sub{
display: flex; flex-direction: column;justify-content: center;
span{
color: greenyellow;
}
h2{
font-size: 22px;
}
}
}
.student_info_card_body{
display: flex; flex-direction: column;
gap: 30px;
span{
display: flex;justify-content: space-between;
h4{
color: #202C4B;
font-size: 20px;
}
p{
color: #6A7287;
}
}
}
}
.student_address_card{
width: 24vw;
box-shadow: 2px 2px 8px 3px rgba(0, 0, 0, 0.1);
border-radius: 10px;
padding: 20px 15px ;
margin-top: 30px;
.student_address_card_body{
display: flex;align-items: center;
gap: 15px;
svg{
@include Flex;
border-radius: 5px;
background: #F2F4F8;
width: 40px;height: 40px;
padding: 7px;
}
p{
color: #6A7287;
}
}
}
@media screen and (max-width:1250px) {
.single_student{
display: flex;
.single_student_body{
display: flex;flex-direction: column !important;
width: 100%;
.student_info{
display: flex;
width: 100%;
gap: 20px;
.student_address_card{
width: 50%;
margin-top: 0 !important;
max-height: 17vw ;
}
.student_info_card{
width: 50%;
}
}
.student_table{
width: 100%;
}
}
}
}

View File

@ -9,4 +9,5 @@
@import "./subject.scss"; @import "./subject.scss";
@import "./Marks.scss"; @import "./Marks.scss";
@import "./exercise.scss"; @import "./exercise.scss";
@import "./reSeller.scss"; @import './reSeller.scss';
@import './StudentInfoCard.scss';

View File

@ -177,7 +177,13 @@
"key": "المفتاح", "key": "المفتاح",
"expiration_date": "تاريخ الالغاء", "expiration_date": "تاريخ الالغاء",
"activation_date": "تاريخ التنشيط", "activation_date": "تاريخ التنشيط",
"first_name": "الاسم الأول" "first_name": "الاسم الأول",
"quiz_date":"تاريخ الاختبار",
"quiz_address":"عنوان الاختبار",
"subject":"المادة",
"quiz_status":"حالة الاختبار",
"creator_name":"اسم المنشئ",
"created_by":"أنشئ بواسطة"
}, },
"practical": { "practical": {
"to_confirm_deletion_please_re_enter": "لتأكيد الحذف، يرجى إعادة الإدخال", "to_confirm_deletion_please_re_enter": "لتأكيد الحذف، يرجى إعادة الإدخال",
@ -224,7 +230,10 @@
"reset": "اعادة تعيين", "reset": "اعادة تعيين",
"next": "التالي", "next": "التالي",
"prev": "السابق", "prev": "السابق",
"Abbreviations": "الاختصارات" "Abbreviations": "الاختصارات",
"address":"العنوان",
"quiz":"الاختبارات",
"hightes_quiz":"اعلى اختبار"
}, },
"Table": { "Table": {
"header": "", "header": "",
@ -739,7 +748,8 @@
"student": "الطلاب", "student": "الطلاب",
"reseller": "البائعين", "reseller": "البائعين",
"param": "معامل", "param": "معامل",
"student_package": "حزمة الطالب" "student_package": "حزمة الطالب",
"quiz":"الاختبارات"
}, },
"message": { "message": {
"some_thing_went_wrong": "حدث خطأ ما", "some_thing_went_wrong": "حدث خطأ ما",
@ -767,6 +777,9 @@
"user": "مستخدم", "user": "مستخدم",
"param": "معامل", "param": "معامل",
"student_package": "حزمة الطالب", "student_package": "حزمة الطالب",
"users":"المستخدمون",
"students":"الطلاب",
"students_details":"تفاصيل الطلاب",
"add_reseller": "إضافة بائع", "add_reseller": "إضافة بائع",
"grade": "الصفوف", "grade": "الصفوف",
"report": "تقرير", "report": "تقرير",
@ -804,7 +817,7 @@
"edit_Question": "لوحة القيادة /تعديل اسئلة ", "edit_Question": "لوحة القيادة /تعديل اسئلة ",
"grade": "لوحة القيادة / الصفوف", "grade": "لوحة القيادة / الصفوف",
"report": "تقرير", "report": "تقرير",
"user": "مستخدم", "users": "لوحة القيادة / المستخدمون",
"reseller": " لوحة القيادة / البائعين", "reseller": " لوحة القيادة / البائعين",
"add_reseller": " لوحة القيادة / البائعين / إضافة بائع ", "add_reseller": " لوحة القيادة / البائعين / إضافة بائع ",
"param": "معامل", "param": "معامل",

View File

@ -350,7 +350,7 @@ export type Student_Package = {
}; };
type student = { type student = {
first_name: string; first_name:string;
last_name: string; last_name:string;
sex: string; sex:string
}; }

View File

@ -675,3 +675,5 @@ export const canDeleteStudent_Package = hasAbility(
ABILITIES_ENUM.Student_Package, ABILITIES_ENUM.Student_Package,
ABILITIES_VALUES_ENUM.DELETE, ABILITIES_VALUES_ENUM.DELETE,
); );