work on question
This commit is contained in:
parent
e8cc73ecc3
commit
aece39ae8f
|
|
@ -4,17 +4,26 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.3.7",
|
||||
"@dnd-kit/core": "^6.1.0",
|
||||
"@dnd-kit/modifiers": "^7.0.0",
|
||||
"@dnd-kit/sortable": "^8.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@types/react-beautiful-dnd": "^13.1.8",
|
||||
"@types/react-dragula": "^1.1.3",
|
||||
"antd": "^5.17.4",
|
||||
"axios": "^1.7.2",
|
||||
"bootstrap": "^5.3.3",
|
||||
"dayjs": "^1.11.11",
|
||||
"dragula": "^3.7.3",
|
||||
"formik": "^2.4.6",
|
||||
"html-to-image": "^1.11.11",
|
||||
"i18next": "^23.11.5",
|
||||
"path-to-regexp": "^6.2.2",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"react": "^18.3.1",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-dragula": "^1.1.17",
|
||||
"react-i18next": "^13.5.0",
|
||||
"react-icons": "^4.12.0",
|
||||
"react-query": "^3.39.3",
|
||||
|
|
|
|||
8759
pnpm-lock.yaml
8759
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
26
src/Components/DrapableTable/DragHandle.tsx
Normal file
26
src/Components/DrapableTable/DragHandle.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { HolderOutlined } from "@ant-design/icons";
|
||||
import { SyntheticListenerMap } from "@dnd-kit/core/dist/hooks/utilities";
|
||||
import { Button } from "antd";
|
||||
import React, { useContext } from "react";
|
||||
|
||||
export const DragHandle: React.FC = () => {
|
||||
|
||||
interface RowContextProps {
|
||||
setActivatorNodeRef?: (element: HTMLElement | null) => void;
|
||||
listeners?: SyntheticListenerMap;
|
||||
}
|
||||
|
||||
const RowContext = React.createContext<RowContextProps>({});
|
||||
const { setActivatorNodeRef, listeners } = useContext(RowContext);
|
||||
return (
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<HolderOutlined />}
|
||||
style={{ cursor: 'move' }}
|
||||
ref={setActivatorNodeRef}
|
||||
{...listeners}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
128
src/Components/DrapableTable/DrapableTable.tsx
Normal file
128
src/Components/DrapableTable/DrapableTable.tsx
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
import React, { useContext, useMemo } from 'react';
|
||||
import { HolderOutlined } from '@ant-design/icons';
|
||||
import type { DragEndEvent } from '@dnd-kit/core';
|
||||
import { DndContext } from '@dnd-kit/core';
|
||||
import type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';
|
||||
import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
|
||||
import {
|
||||
arrayMove,
|
||||
SortableContext,
|
||||
useSortable,
|
||||
verticalListSortingStrategy,
|
||||
} from '@dnd-kit/sortable';
|
||||
import { CSS } from '@dnd-kit/utilities';
|
||||
import { Button, Table } from 'antd';
|
||||
import type { TableColumnsType } from 'antd';
|
||||
|
||||
interface DataType {
|
||||
key: string;
|
||||
order: number;
|
||||
name: string;
|
||||
age: number;
|
||||
address: string;
|
||||
}
|
||||
|
||||
interface RowContextProps {
|
||||
setActivatorNodeRef?: (element: HTMLElement | null) => void;
|
||||
listeners?: SyntheticListenerMap;
|
||||
}
|
||||
|
||||
const RowContext = React.createContext<RowContextProps>({});
|
||||
|
||||
const DragHandle: React.FC = () => {
|
||||
const { setActivatorNodeRef, listeners } = useContext(RowContext);
|
||||
return (
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<HolderOutlined />}
|
||||
style={{ cursor: 'move' }}
|
||||
ref={setActivatorNodeRef}
|
||||
{...listeners}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const columns: TableColumnsType<DataType> = [
|
||||
{ key: 'sort', align: 'center', width: 80, render: () => <DragHandle /> },
|
||||
{ title: 'Name', dataIndex: 'name' },
|
||||
{ title: 'Age', dataIndex: 'age' },
|
||||
{ title: 'Address', dataIndex: 'address' },
|
||||
];
|
||||
|
||||
const initialData: DataType[] = [
|
||||
{ key: '1', order: 1, name: '1', age: 32, address: 'Long text Long' },
|
||||
{ key: '4', order: 4, name: '4', age: 42, address: 'London No. 1 Lake Park' },
|
||||
{ key: '3', order: 3, name: '3', age: 32, address: 'Sidney No. 1 Lake Park' },
|
||||
].sort((a, b) => a.order - b.order);
|
||||
|
||||
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
||||
'data-row-key': string;
|
||||
}
|
||||
|
||||
const Row: React.FC<RowProps> = (props) => {
|
||||
const {
|
||||
attributes,
|
||||
listeners,
|
||||
setNodeRef,
|
||||
setActivatorNodeRef,
|
||||
transform,
|
||||
transition,
|
||||
isDragging,
|
||||
} = useSortable({ id: props['data-row-key'] });
|
||||
|
||||
const style: React.CSSProperties = {
|
||||
...props.style,
|
||||
transform: CSS.Translate.toString(transform),
|
||||
transition,
|
||||
...(isDragging ? { position: 'relative', zIndex: 9999 } : {}),
|
||||
};
|
||||
|
||||
const contextValue = useMemo<RowContextProps>(
|
||||
() => ({ setActivatorNodeRef, listeners }),
|
||||
[setActivatorNodeRef, listeners],
|
||||
);
|
||||
|
||||
return (
|
||||
<RowContext.Provider value={contextValue}>
|
||||
<tr {...props} ref={setNodeRef} style={style} {...attributes} />
|
||||
</RowContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
const DrapableTable: React.FC = () => {
|
||||
const [dataSource, setDataSource] = React.useState<DataType[]>(initialData);
|
||||
|
||||
const onDragEnd = ({ active, over }: DragEndEvent) => {
|
||||
if (active.id !== over?.id) {
|
||||
// Log the old state before reordering
|
||||
console.log("Old Data:", dataSource);
|
||||
|
||||
setDataSource((prevState) => {
|
||||
const activeIndex = prevState.findIndex((record) => record.key === active?.id);
|
||||
const overIndex = prevState.findIndex((record) => record.key === over?.id);
|
||||
const newState = arrayMove(prevState, activeIndex, overIndex);
|
||||
|
||||
// Log the new state after reordering
|
||||
console.log("New Data:", newState);
|
||||
|
||||
return newState;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>
|
||||
<SortableContext items={dataSource.map((i) => i.key)} strategy={verticalListSortingStrategy}>
|
||||
<Table
|
||||
rowKey="key"
|
||||
components={{ body: { row: Row } }}
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
/>
|
||||
</SortableContext>
|
||||
</DndContext>
|
||||
);
|
||||
};
|
||||
|
||||
export default DrapableTable;
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
import React from "react";
|
||||
import useFormField from "../../../Hooks/useFormField";
|
||||
import { Checkbox, Form } from "antd";
|
||||
|
|
@ -13,7 +14,7 @@ const CheckboxField = ({
|
|||
}: any) => {
|
||||
const { t, formik, isError, errorMsg } = useFormField(name, props);
|
||||
const CheckboxhandleChange = (value: any) => {
|
||||
formik.setFieldValue(name, value?.target?.checked);
|
||||
formik.setFieldValue(name, value?.target?.checked ? 1 : 0);
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -26,7 +27,7 @@ const CheckboxField = ({
|
|||
<Checkbox
|
||||
onChange={onChange || CheckboxhandleChange}
|
||||
disabled={isDisabled}
|
||||
checked={formik.values?.[name] ?? false}
|
||||
checked={formik.values?.[name] === 1}
|
||||
className={className}
|
||||
>
|
||||
{t(`input.${label ? label : name}`)}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ const File = ({
|
|||
}: any) => {
|
||||
const { formik, t, isError, errorMsg } = useFormField(name, props);
|
||||
let imageUrl = formik?.values?.[name] ?? null;
|
||||
console.log(imageUrl);
|
||||
console.log(typeof imageUrl === "string");
|
||||
|
||||
const fileList: UploadFile[] = useMemo(() => {
|
||||
if (!imageUrl) return [];
|
||||
|
|
|
|||
128
src/Layout/Dashboard/Table/DataTableWithDrag.tsx
Normal file
128
src/Layout/Dashboard/Table/DataTableWithDrag.tsx
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
import React, { useContext, useMemo } from 'react';
|
||||
import { HolderOutlined } from '@ant-design/icons';
|
||||
import type { DragEndEvent } from '@dnd-kit/core';
|
||||
import { DndContext } from '@dnd-kit/core';
|
||||
import type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';
|
||||
import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
|
||||
import {
|
||||
arrayMove,
|
||||
SortableContext,
|
||||
useSortable,
|
||||
verticalListSortingStrategy,
|
||||
} from '@dnd-kit/sortable';
|
||||
import { CSS } from '@dnd-kit/utilities';
|
||||
import { Button, Table } from 'antd';
|
||||
import type { TableColumnsType } from 'antd';
|
||||
|
||||
interface DataType {
|
||||
key: string;
|
||||
order: number;
|
||||
name: string;
|
||||
age: number;
|
||||
address: string;
|
||||
}
|
||||
|
||||
interface RowContextProps {
|
||||
setActivatorNodeRef?: (element: HTMLElement | null) => void;
|
||||
listeners?: SyntheticListenerMap;
|
||||
}
|
||||
|
||||
const RowContext = React.createContext<RowContextProps>({});
|
||||
|
||||
const DragHandle: React.FC = () => {
|
||||
const { setActivatorNodeRef, listeners } = useContext(RowContext);
|
||||
return (
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<HolderOutlined />}
|
||||
style={{ cursor: 'move' }}
|
||||
ref={setActivatorNodeRef}
|
||||
{...listeners}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const columns: TableColumnsType<DataType> = [
|
||||
{ key: 'sort', align: 'center', width: 80, render: () => <DragHandle /> },
|
||||
{ title: 'Name', dataIndex: 'name' },
|
||||
{ title: 'Age', dataIndex: 'age' },
|
||||
{ title: 'Address', dataIndex: 'address' },
|
||||
];
|
||||
|
||||
const initialData: DataType[] = [
|
||||
{ key: '1', order: 1, name: '1', age: 32, address: 'Long text Long' },
|
||||
{ key: '4', order: 4, name: '4', age: 42, address: 'London No. 1 Lake Park' },
|
||||
{ key: '3', order: 3, name: '3', age: 32, address: 'Sidney No. 1 Lake Park' },
|
||||
].sort((a, b) => a.order - b.order);
|
||||
|
||||
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
||||
'data-row-key': string;
|
||||
}
|
||||
|
||||
const Row: React.FC<RowProps> = (props) => {
|
||||
const {
|
||||
attributes,
|
||||
listeners,
|
||||
setNodeRef,
|
||||
setActivatorNodeRef,
|
||||
transform,
|
||||
transition,
|
||||
isDragging,
|
||||
} = useSortable({ id: props['data-row-key'] });
|
||||
|
||||
const style: React.CSSProperties = {
|
||||
...props.style,
|
||||
transform: CSS.Translate.toString(transform),
|
||||
transition,
|
||||
...(isDragging ? { position: 'relative', zIndex: 9999 } : {}),
|
||||
};
|
||||
|
||||
const contextValue = useMemo<RowContextProps>(
|
||||
() => ({ setActivatorNodeRef, listeners }),
|
||||
[setActivatorNodeRef, listeners],
|
||||
);
|
||||
|
||||
return (
|
||||
<RowContext.Provider value={contextValue}>
|
||||
<tr {...props} ref={setNodeRef} style={style} {...attributes} />
|
||||
</RowContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [dataSource, setDataSource] = React.useState<DataType[]>(initialData);
|
||||
|
||||
const onDragEnd = ({ active, over }: DragEndEvent) => {
|
||||
if (active.id !== over?.id) {
|
||||
// Log the old state before reordering
|
||||
console.log("Old Data:", dataSource);
|
||||
|
||||
setDataSource((prevState) => {
|
||||
const activeIndex = prevState.findIndex((record) => record.key === active?.id);
|
||||
const overIndex = prevState.findIndex((record) => record.key === over?.id);
|
||||
const newState = arrayMove(prevState, activeIndex, overIndex);
|
||||
|
||||
// Log the new state after reordering
|
||||
console.log("New Data:", newState);
|
||||
|
||||
return newState;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>
|
||||
<SortableContext items={dataSource.map((i) => i.key)} strategy={verticalListSortingStrategy}>
|
||||
<Table
|
||||
rowKey="key"
|
||||
components={{ body: { row: Row } }}
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
/>
|
||||
</SortableContext>
|
||||
</DndContext>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
|
@ -7,6 +7,7 @@ import { useGetAllSubject } from "../../api/subject";
|
|||
import useSetPageTitle from "../../Hooks/useSetPageTitle";
|
||||
import { ModalEnum } from "../../enums/Model";
|
||||
import { useDeleteCurriculum } from "../../api/curriculum";
|
||||
import { useGetAllGrade } from "../../api/grade";
|
||||
|
||||
const Table = lazy(() => import('./Table'));
|
||||
const AddModalForm = lazy(() => import('./Model/AddModel'));
|
||||
|
|
@ -17,22 +18,28 @@ const TableHeader = () => {
|
|||
const [t] = useTranslation();
|
||||
const deleteMutation = useDeleteCurriculum();
|
||||
|
||||
const { subject_id} = useParams<ParamsEnum>();
|
||||
const { subject_id,grade_id} = useParams<ParamsEnum>();
|
||||
|
||||
const { data: Subject } = useGetAllSubject({
|
||||
show: subject_id,
|
||||
});
|
||||
const { data: grade } = useGetAllGrade({
|
||||
show: grade_id,
|
||||
});
|
||||
|
||||
const gradeName = grade?.data?.name ?? "";
|
||||
|
||||
const SubjectName = Subject?.data?.name ?? "";
|
||||
|
||||
useSetPageTitle(t(`page_header.curriculum`) + "/" + t(`${SubjectName}`));
|
||||
useSetPageTitle( t(`page_header.grade`)+ "/"+ gradeName +"/"+t(`PageTitle.subject`)+"/"+SubjectName+"/"+t("PageTitle.curriculum"));
|
||||
|
||||
|
||||
return (
|
||||
<div className="TableWithHeader">
|
||||
<Suspense fallback={<Spin />}>
|
||||
<header>
|
||||
<h6>
|
||||
{t("models.curriculum")} {SubjectName}
|
||||
{t("models.curriculum")}
|
||||
</h6>
|
||||
</header>
|
||||
<Table />
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ const TableHeader = () => {
|
|||
const [t] = useTranslation();
|
||||
const deleteMutation = useDeleteGrade();
|
||||
|
||||
|
||||
|
||||
useSetPageTitle(t(`page_header.grade`));
|
||||
|
||||
return (
|
||||
|
|
|
|||
145
src/Pages/Unit/DrapableTable.tsx
Normal file
145
src/Pages/Unit/DrapableTable.tsx
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
import React, { useContext, useEffect, useMemo } from 'react';
|
||||
import { HolderOutlined } from '@ant-design/icons';
|
||||
import type { DragEndEvent } from '@dnd-kit/core';
|
||||
import { DndContext } from '@dnd-kit/core';
|
||||
import type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';
|
||||
import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
|
||||
import {
|
||||
arrayMove,
|
||||
SortableContext,
|
||||
useSortable,
|
||||
verticalListSortingStrategy,
|
||||
} from '@dnd-kit/sortable';
|
||||
import { CSS } from '@dnd-kit/utilities';
|
||||
import { Button, Table } from 'antd';
|
||||
import type { TableColumnsType } from 'antd';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { ParamsEnum } from '../../enums/params';
|
||||
import { useGetAllUnit } from '../../api/unit';
|
||||
|
||||
interface DataType {
|
||||
id: string; // Unique identifier for each row
|
||||
order: number;
|
||||
name: string;
|
||||
age: number;
|
||||
address: string;
|
||||
}
|
||||
|
||||
interface RowContextProps {
|
||||
setActivatorNodeRef?: (element: HTMLElement | null) => void;
|
||||
listeners?: SyntheticListenerMap;
|
||||
}
|
||||
|
||||
const RowContext = React.createContext<RowContextProps>({});
|
||||
|
||||
const DragHandle: React.FC = () => {
|
||||
const { setActivatorNodeRef, listeners } = useContext(RowContext);
|
||||
return (
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<HolderOutlined />}
|
||||
style={{ cursor: 'move' }}
|
||||
ref={setActivatorNodeRef}
|
||||
{...listeners}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const columns: TableColumnsType<DataType> = [
|
||||
{ key: 'sort', align: 'center', width: 80, render: () => <DragHandle /> },
|
||||
{ title: 'Name', dataIndex: 'name' },
|
||||
{ title: 'Age', dataIndex: 'age' },
|
||||
{ title: 'Address', dataIndex: 'address' },
|
||||
];
|
||||
|
||||
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
||||
'data-row-key': string;
|
||||
}
|
||||
|
||||
const Row: React.FC<RowProps> = (props) => {
|
||||
const {
|
||||
attributes,
|
||||
listeners,
|
||||
setNodeRef,
|
||||
setActivatorNodeRef,
|
||||
transform,
|
||||
transition,
|
||||
isDragging,
|
||||
} = useSortable({ id: props['data-row-key'] });
|
||||
|
||||
const style: React.CSSProperties = {
|
||||
...props.style,
|
||||
transform: CSS.Translate.toString(transform),
|
||||
transition,
|
||||
...(isDragging ? { position: 'relative', zIndex: 9999 } : {}),
|
||||
};
|
||||
|
||||
const contextValue = useMemo<RowContextProps>(
|
||||
() => ({ setActivatorNodeRef, listeners }),
|
||||
[setActivatorNodeRef, listeners],
|
||||
);
|
||||
|
||||
return (
|
||||
<RowContext.Provider value={contextValue}>
|
||||
<tr {...props} ref={setNodeRef} style={style} {...attributes} />
|
||||
</RowContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
const DrapableTable: React.FC = () => {
|
||||
const { subject_id } = useParams<ParamsEnum>();
|
||||
const response = useGetAllUnit({ subject_id: subject_id, pagination: false });
|
||||
|
||||
// Assuming the response contains a unique id for each item
|
||||
const data = response?.data?.data?.map((item: any, index: number) => ({
|
||||
id: item.id, // Ensure this is a unique identifier
|
||||
order: index + 1, // Assign order based on index
|
||||
name: item.name,
|
||||
age: item.age,
|
||||
address: item.address,
|
||||
})) ?? [];
|
||||
|
||||
const [dataSource, setDataSource] = React.useState<DataType[]>(data);
|
||||
console.log(dataSource,"dataSource");
|
||||
|
||||
useEffect(() => {
|
||||
// Update dataSource when the fetched data changes
|
||||
const sortedData = data.sort((a:any, b:any) => a.order - b.order);
|
||||
setDataSource(sortedData);
|
||||
}, [response?.data?.data]);
|
||||
|
||||
const onDragEnd = ({ active, over }: DragEndEvent) => {
|
||||
if (active.id !== over?.id) {
|
||||
setDataSource((prevState) => {
|
||||
const activeIndex = prevState.findIndex((record) => record.id === active.id);
|
||||
const overIndex = prevState.findIndex((record) => record.id === over.id);
|
||||
|
||||
// Move the items in the array
|
||||
const newState = arrayMove(prevState, activeIndex, overIndex);
|
||||
|
||||
// Update the order based on the new positions
|
||||
return newState.map((item, index) => ({
|
||||
...item,
|
||||
order: index + 1, // Update the order based on the new index
|
||||
}));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>
|
||||
<SortableContext items={dataSource.map((i) => i.id)} strategy={verticalListSortingStrategy}>
|
||||
<Table
|
||||
rowKey="id"
|
||||
components={{ body: { row: Row } }}
|
||||
columns={columns}
|
||||
dataSource={dataSource.sort((a, b) => a.order - b.order)} // Sort by order for rendering
|
||||
pagination={false}
|
||||
/>
|
||||
</SortableContext>
|
||||
</DndContext>
|
||||
);
|
||||
};
|
||||
|
||||
export default DrapableTable;
|
||||
|
|
@ -6,15 +6,25 @@ import { QueryStatusEnum } from "../../../enums/QueryStatus";
|
|||
import ModelForm from "./ModelForm";
|
||||
import { useAddUnit } from "../../../api/unit";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
||||
|
||||
const AddModel: React.FC = () => {
|
||||
const { mutate, status } = useAddUnit();
|
||||
const { subject_id } = useParams();
|
||||
const { curriculum_id } = useParams();
|
||||
const {OldObjectToEdit} = useObjectToEdit()
|
||||
|
||||
const handleSubmit = (values: any) => {
|
||||
let order = 0 ;
|
||||
if(OldObjectToEdit?.order || OldObjectToEdit?.order === 0){
|
||||
order = Number(OldObjectToEdit.order) + 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
mutate({
|
||||
...values,
|
||||
subject_id: subject_id,
|
||||
curriculum_id: curriculum_id,
|
||||
order:order
|
||||
});
|
||||
};
|
||||
return (
|
||||
|
|
@ -26,7 +36,7 @@ const AddModel: React.FC = () => {
|
|||
handleSubmit={handleSubmit}
|
||||
getInitialValues={getInitialValues({})}
|
||||
getValidationSchema={getValidationSchema}
|
||||
width="40vw"
|
||||
width="60vw"
|
||||
>
|
||||
<ModelForm />
|
||||
</LayoutModel>
|
||||
|
|
|
|||
|
|
@ -5,20 +5,16 @@ import LayoutModel from "../../../Layout/Dashboard/LayoutModel";
|
|||
import ModelForm from "./ModelForm";
|
||||
import { QueryStatusEnum } from "../../../enums/QueryStatus";
|
||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
||||
import { useUpdateTag } from "../../../api/tags";
|
||||
import { useUpdateUnit } from "../../../api/unit";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
const EditModel: React.FC = () => {
|
||||
const { mutate, status } = useUpdateUnit();
|
||||
const { objectToEdit } = useObjectToEdit((state) => state);
|
||||
|
||||
const { subject_id } = useParams();
|
||||
|
||||
const handleSubmit = (values: any) => {
|
||||
mutate({
|
||||
...values,
|
||||
subject_id: subject_id,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -32,7 +28,7 @@ const EditModel: React.FC = () => {
|
|||
getInitialValues={getInitialValues(objectToEdit)}
|
||||
getValidationSchema={getValidationSchema}
|
||||
isAddModal={false}
|
||||
width="40vw"
|
||||
width="60vw"
|
||||
>
|
||||
<ModelForm />
|
||||
</LayoutModel>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,21 @@
|
|||
import { Col, Row } from "reactstrap";
|
||||
import ValidationField from "../../../Components/ValidationField/ValidationField";
|
||||
import { TermEnum } from "../../../enums/Term";
|
||||
import { enumToArray } from "../../../utils/enumToArray";
|
||||
|
||||
const Form = () => {
|
||||
|
||||
const termsArray = enumToArray(TermEnum);
|
||||
console.log(termsArray,"termsArray");
|
||||
|
||||
return (
|
||||
<Row className="w-100">
|
||||
<Col>
|
||||
<ValidationField name="name" placeholder="name" label="name" />
|
||||
</Col>
|
||||
<Col>
|
||||
<ValidationField name="term" type="Select" placeholder="term" label="term" option={termsArray} />
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
import * as Yup from "yup";
|
||||
import { UnitInitialValues,Unit } from "../../../types/Unit";
|
||||
|
||||
export const getInitialValues = (objectToEdit: any): any => {
|
||||
export const getInitialValues = (objectToEdit: Partial<Unit>): UnitInitialValues => {
|
||||
return {
|
||||
id: objectToEdit?.id,
|
||||
name: objectToEdit?.name ?? "",
|
||||
name: objectToEdit?.name ?? null,
|
||||
term: objectToEdit?.term ?? null,
|
||||
order: objectToEdit?.order ?? null,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -11,6 +14,7 @@ export const getValidationSchema = () => {
|
|||
// validate input
|
||||
return Yup.object().shape({
|
||||
name: Yup.string().required("validation.required"),
|
||||
term: Yup.string().required("validation.required"),
|
||||
// subject_id: Yup.string().required('validation.required'),
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ import { useGetAllSubject } from "../../api/subject";
|
|||
import useSetPageTitle from "../../Hooks/useSetPageTitle";
|
||||
import { ModalEnum } from "../../enums/Model";
|
||||
import { useDeleteUnit } from "../../api/unit";
|
||||
import DrapableTable from "./DrapableTable";
|
||||
import { useGetAllGrade } from "../../api/grade";
|
||||
import { useGetAllCurriculum } from "../../api/curriculum";
|
||||
|
||||
const Table = lazy(() => import('./Table'));
|
||||
const AddModalForm = lazy(() => import('./Model/AddModel'));
|
||||
|
|
@ -17,23 +20,34 @@ const TableHeader = () => {
|
|||
const [t] = useTranslation();
|
||||
const deleteMutation = useDeleteUnit();
|
||||
|
||||
const { subject_id} = useParams<ParamsEnum>();
|
||||
const { subject_id,grade_id,curriculum_id} = useParams<ParamsEnum>();
|
||||
|
||||
const { data: Subject } = useGetAllSubject({
|
||||
show: subject_id,
|
||||
});
|
||||
|
||||
const SubjectName = Subject?.data?.name ?? "";
|
||||
const { data: grade } = useGetAllGrade({
|
||||
show: grade_id,
|
||||
});
|
||||
const { data: Curriculum } = useGetAllCurriculum({
|
||||
show: curriculum_id,
|
||||
});
|
||||
const gradeName = grade?.data?.name ?? "";
|
||||
|
||||
const SubjectName = Subject?.data?.name ?? "";
|
||||
const CurriculumName = Curriculum?.data?.name ?? "";
|
||||
useSetPageTitle( t(`page_header.grade`)+ "/"+ gradeName +"/"+t(`PageTitle.subject`)+"/"+SubjectName+"/"+t("PageTitle.curriculum")+"/"+CurriculumName+"/"+t("PageTitle.unit"));
|
||||
|
||||
|
||||
useSetPageTitle(t(`page_header.subject`) + "/" + t(`${SubjectName}`));
|
||||
|
||||
return (
|
||||
<div className="TableWithHeader">
|
||||
<Suspense fallback={<Spin />}>
|
||||
<header>
|
||||
<h6>
|
||||
{t("models.units")} {SubjectName}
|
||||
{t("models.units")}
|
||||
</h6>
|
||||
|
||||
</header>
|
||||
<Table />
|
||||
<AddModalForm />
|
||||
|
|
|
|||
|
|
@ -1,14 +1,25 @@
|
|||
import { useColumns } from "./useTableColumns";
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import DataTable from "../../Layout/Dashboard/Table/DataTable";
|
||||
import { useGetAllUnit } from "../../api/unit";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { ParamsEnum } from "../../enums/params";
|
||||
import { useObjectToEdit } from "../../zustand/ObjectToEditState";
|
||||
|
||||
const App: React.FC = () => {
|
||||
const { subject_id } = useParams<ParamsEnum>();
|
||||
const response = useGetAllUnit({ subject_id: subject_id, pagination: true });
|
||||
const {setOldObjectToEdit} = useObjectToEdit()
|
||||
console.log(response?.data?.data, "response?.data");
|
||||
const data = response?.data?.data;
|
||||
const lastElement = response?.data?.data && response?.data?.data[data?.length - 1]
|
||||
console.log(lastElement);
|
||||
|
||||
useEffect(() => {
|
||||
if(lastElement){
|
||||
setOldObjectToEdit(lastElement)
|
||||
}
|
||||
}, [lastElement])
|
||||
|
||||
return <DataTable response={response} useColumns={useColumns} />;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { Space, TableColumnsType, Tooltip } from "antd";
|
||||
import { Unit } from "../../types/Item";
|
||||
import { FaPlus } from "react-icons/fa";
|
||||
import useModalHandler from "../../utils/useModalHandler";
|
||||
import { ModalEnum } from "../../enums/Model";
|
||||
|
|
@ -17,6 +16,7 @@ import {
|
|||
canShowUnit,
|
||||
} from "../../utils/hasAbilityFn";
|
||||
import ActionButtons from "../../Components/Table/ActionButtons";
|
||||
import { Unit } from "../../types/Unit";
|
||||
|
||||
export const useColumns = () => {
|
||||
const { handel_open_model } = useModalHandler();
|
||||
|
|
@ -24,16 +24,16 @@ export const useColumns = () => {
|
|||
const { setObjectToEdit } = useObjectToEdit((state) => state);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handelShow = (record: any) => {
|
||||
const handelShow = (record: Unit) => {
|
||||
navigate(`${ABILITIES_ENUM?.UNIT}/${record?.id}`);
|
||||
};
|
||||
|
||||
const handelDelete = (data: any) => {
|
||||
const handelDelete = (data: Unit) => {
|
||||
setObjectToEdit(data);
|
||||
handel_open_model(ModalEnum?.UNIT_DELETE);
|
||||
};
|
||||
|
||||
const handleEdit = (record: any) => {
|
||||
const handleEdit = (record: Unit) => {
|
||||
setObjectToEdit(record);
|
||||
handel_open_model(ModalEnum?.UNIT_EDIT);
|
||||
};
|
||||
|
|
@ -56,11 +56,11 @@ export const useColumns = () => {
|
|||
},
|
||||
|
||||
{
|
||||
title: t("columns.lesson_count"),
|
||||
dataIndex: "lesson_count",
|
||||
key: "lesson_count",
|
||||
title: t("columns.term"),
|
||||
dataIndex: "term",
|
||||
key: "term",
|
||||
align: "center",
|
||||
render: (text, record) => record?.lessons_count,
|
||||
render: (text, record) => record?.term,
|
||||
},
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,13 +9,14 @@ import { useAddLesson } from "../../../api/lesson";
|
|||
import { useParams } from "react-router-dom";
|
||||
import { ParamsEnum } from "../../../enums/params";
|
||||
import { useModalState } from "../../../zustand/Modal";
|
||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
||||
|
||||
const AddModel: React.FC = () => {
|
||||
|
||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
||||
const queryClient = useQueryClient();
|
||||
const { mutate, isSuccess, status } = useAddLesson();
|
||||
|
||||
const {OldObjectToEdit} = useObjectToEdit()
|
||||
const { unit_id } = useParams<ParamsEnum>();
|
||||
useEffect(() => {
|
||||
if (isSuccess) {
|
||||
|
|
@ -25,6 +26,13 @@ const AddModel: React.FC = () => {
|
|||
}, [setIsOpen, isSuccess, queryClient]);
|
||||
|
||||
const handleSubmit = (values: any) => {
|
||||
|
||||
let order = 0 ;
|
||||
if(OldObjectToEdit?.order || OldObjectToEdit?.order === 0){
|
||||
order = Number(OldObjectToEdit.order) + 1;
|
||||
|
||||
}
|
||||
|
||||
mutate({ ...values, unit_id: unit_id });
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ import { ParamsEnum } from "../../enums/params";
|
|||
import { useGetAllUnit } from "../../api/unit";
|
||||
import { ModalEnum } from "../../enums/Model";
|
||||
import { useDeleteLesson } from "../../api/lesson";
|
||||
import { useGetAllGrade } from "../../api/grade";
|
||||
import { useGetAllCurriculum } from "../../api/curriculum";
|
||||
import { useGetAllSubject } from "../../api/subject";
|
||||
|
||||
const Table = lazy(() => import('./Table'));
|
||||
const AddModalForm = lazy(() => import('./Model/AddModel'));
|
||||
|
|
@ -17,22 +20,29 @@ const TableHeader = () => {
|
|||
const [t] = useTranslation();
|
||||
const deleteMutation = useDeleteLesson();
|
||||
|
||||
const { unit_id } = useParams<ParamsEnum>();
|
||||
const { unit_id,curriculum_id,grade_id ,subject_id} = useParams<ParamsEnum>();
|
||||
const { data: unit } = useGetAllUnit({ show: unit_id });
|
||||
|
||||
|
||||
const { data: Subject } = useGetAllSubject({
|
||||
show: subject_id,
|
||||
});
|
||||
const { data: grade } = useGetAllGrade({
|
||||
show: grade_id,
|
||||
});
|
||||
const { data: Curriculum } = useGetAllCurriculum({
|
||||
show: curriculum_id,
|
||||
});
|
||||
|
||||
const gradeName = grade?.data?.name ?? "";
|
||||
const SubjectName = Subject?.data?.name ?? "";
|
||||
const CurriculumName = Curriculum?.data?.name ?? "";
|
||||
const unitName = unit?.data?.name ?? "";
|
||||
const SubjectName = unit?.data?.subject?.name ?? "";
|
||||
|
||||
console.log(unit?.data);
|
||||
|
||||
useSetPageTitle(
|
||||
t(`page_header.subject`) +
|
||||
"/" +
|
||||
`${SubjectName}` +
|
||||
"/" +
|
||||
t(`PageTitle.unit`) +
|
||||
"/" +
|
||||
`${unitName}`,
|
||||
);
|
||||
useSetPageTitle( t(`page_header.grade`)+ "/"+ gradeName +"/"+t(`PageTitle.subject`)+"/"+SubjectName+"/"+t("PageTitle.curriculum")+"/"+CurriculumName+"/"+t("PageTitle.unit")+"/"+unitName+"/"+t("PageTitle.lesson"));
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className="TableWithHeader">
|
||||
|
|
|
|||
|
|
@ -1,14 +1,27 @@
|
|||
import { useColumns } from "./useTableColumns";
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import DataTable from "../../Layout/Dashboard/Table/DataTable";
|
||||
import { useGetAllLesson } from "../../api/lesson";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { ParamsEnum } from "../../enums/params";
|
||||
import { useObjectToEdit } from "../../zustand/ObjectToEditState";
|
||||
|
||||
const App: React.FC = () => {
|
||||
const { unit_id } = useParams<ParamsEnum>();
|
||||
const response = useGetAllLesson({ unit_id: unit_id, pagination: true });
|
||||
|
||||
const {setOldObjectToEdit} = useObjectToEdit()
|
||||
console.log(response?.data?.data, "response?.data");
|
||||
const data = response?.data?.data;
|
||||
const lastElement = response?.data?.data && response?.data?.data[data?.length - 1]
|
||||
console.log(lastElement);
|
||||
|
||||
useEffect(() => {
|
||||
if(lastElement){
|
||||
setOldObjectToEdit(lastElement)
|
||||
}
|
||||
}, [lastElement])
|
||||
|
||||
return <DataTable response={response} useColumns={useColumns} />;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ import { toast } from "react-toastify";
|
|||
import useSetPageTitle from "../../Hooks/useSetPageTitle";
|
||||
import { useGetAllUnit } from "../../api/unit";
|
||||
import { useGetAllLesson } from "../../api/lesson";
|
||||
import { useGetAllSubject } from "../../api/subject";
|
||||
import { useGetAllGrade } from "../../api/grade";
|
||||
import { useGetAllCurriculum } from "../../api/curriculum";
|
||||
|
||||
const AddPage: React.FC = () => {
|
||||
const { isSuccess: isSuccessAsync, mutateAsync } = useAddQuestionAsync();
|
||||
|
|
@ -43,41 +46,42 @@ const AddPage: React.FC = () => {
|
|||
SavedQuestionData,
|
||||
} = useObjectToEdit();
|
||||
|
||||
const { subject_id, lesson_id, unit_id } = useParams<ParamsEnum>();
|
||||
const { setIsOpen } = useModalState((state) => state);
|
||||
|
||||
const { data: unit } = useGetAllUnit({ show: unit_id });
|
||||
const { data: lesson } = useGetAllLesson({ show: lesson_id });
|
||||
|
||||
const [t] = useTranslation();
|
||||
const { unit_id,curriculum_id,grade_id ,subject_id,lesson_id} = useParams<ParamsEnum>();
|
||||
const { data: unit } = useGetAllUnit({ show: unit_id });
|
||||
|
||||
|
||||
const { data: Subject } = useGetAllSubject({
|
||||
show: subject_id,
|
||||
});
|
||||
const { data: grade } = useGetAllGrade({
|
||||
show: grade_id,
|
||||
});
|
||||
const { data: Curriculum } = useGetAllCurriculum({
|
||||
show: curriculum_id,
|
||||
});
|
||||
const { data: Lesson } = useGetAllLesson({
|
||||
show: lesson_id,
|
||||
});
|
||||
|
||||
const gradeName = grade?.data?.name ?? "";
|
||||
const SubjectName = Subject?.data?.name ?? "";
|
||||
const CurriculumName = Curriculum?.data?.name ?? "";
|
||||
const unitName = unit?.data?.name ?? "";
|
||||
const SubjectName = unit?.data?.subject?.name ?? "";
|
||||
const lessonName = lesson?.data?.name ?? "";
|
||||
|
||||
useSetPageTitle(
|
||||
t(`page_header.subject`) +
|
||||
"/" +
|
||||
`${SubjectName}` +
|
||||
"/" +
|
||||
t(`PageTitle.unit`) +
|
||||
"/" +
|
||||
`${unitName}` +
|
||||
"/" +
|
||||
t(`PageTitle.lesson`) +
|
||||
"/" +
|
||||
`${lessonName}` +
|
||||
"/" +
|
||||
t(`PageTitle.questions`),
|
||||
);
|
||||
const LessonName = Lesson?.data?.name ?? "";
|
||||
|
||||
useSetPageTitle( t(`page_header.grade`)+ "/"+ gradeName +"/"+t(`PageTitle.subject`)+"/"+SubjectName+"/"+t("PageTitle.curriculum")+"/"+CurriculumName+"/"+t("PageTitle.unit")+"/"+unitName+"/"+t("PageTitle.lesson")+"/"+LessonName+"/"+t("PageTitle.question")+"/"+t("practical.add"));
|
||||
const handleSubmit = (
|
||||
values: any,
|
||||
{ resetForm }: { resetForm: () => void },
|
||||
) => {
|
||||
const DataToSend = structuredClone(values);
|
||||
setTagsSearch(null);
|
||||
console.log(isBseQuestion);
|
||||
|
||||
setTagsSearch(null);
|
||||
const canAnswersBeShuffled = DataToSend?.canAnswersBeShuffled ? 1 : 0 ;
|
||||
if (isBseQuestion || DataToSend?.isBase === 1) {
|
||||
const newBseQuestion = {
|
||||
subject_id: subject_id,
|
||||
|
|
@ -85,6 +89,9 @@ const AddPage: React.FC = () => {
|
|||
image: DataToSend?.image ?? "",
|
||||
isBase: 1,
|
||||
lessons_ids: [lesson_id],
|
||||
canAnswersBeShuffled,
|
||||
hint:DataToSend?.hint
|
||||
|
||||
};
|
||||
|
||||
mutateAsync(newBseQuestion).then((data: any) => {
|
||||
|
|
@ -113,6 +120,7 @@ const AddPage: React.FC = () => {
|
|||
subject_id: subject_id,
|
||||
tags,
|
||||
lessons_ids: [lesson_id],
|
||||
canAnswersBeShuffled
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -162,7 +170,7 @@ const AddPage: React.FC = () => {
|
|||
>
|
||||
<main className="w-100 exercise_add_main">
|
||||
<Header/>
|
||||
<ModelForm/>
|
||||
<BaseForm/>
|
||||
|
||||
<div className="exercise_add_buttons">
|
||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
||||
|
|
|
|||
|
|
@ -28,9 +28,12 @@ import { toast } from "react-toastify";
|
|||
import useSetPageTitle from "../../Hooks/useSetPageTitle";
|
||||
import { useGetAllUnit } from "../../api/unit";
|
||||
import { useGetAllLesson } from "../../api/lesson";
|
||||
import { useGetAllSubject } from "../../api/subject";
|
||||
import { useGetAllGrade } from "../../api/grade";
|
||||
import { useGetAllCurriculum } from "../../api/curriculum";
|
||||
|
||||
const EditPage: React.FC = () => {
|
||||
const { question_id, subject_id, unit_id } = useParams<ParamsEnum>();
|
||||
const { unit_id,curriculum_id,grade_id ,subject_id,lesson_id,question_id } = useParams<ParamsEnum>();
|
||||
const { isBseQuestion, setIsBseQuestion, setTagsSearch, DeletedQuestions } =
|
||||
useObjectToEdit();
|
||||
|
||||
|
|
@ -50,36 +53,38 @@ const EditPage: React.FC = () => {
|
|||
|
||||
const objectToEdit = { ...data?.data, Questions: Questions?.data };
|
||||
|
||||
const { lesson_id } = useParams();
|
||||
useEffect(() => {
|
||||
if (objectToEdit?.isBase && isBseQuestion !== true) {
|
||||
setIsBseQuestion(true);
|
||||
}
|
||||
}, [objectToEdit?.isBase]);
|
||||
|
||||
const { data: unit } = useGetAllUnit({ show: unit_id });
|
||||
const { data: lesson } = useGetAllLesson({ show: lesson_id });
|
||||
|
||||
|
||||
const [t] = useTranslation();
|
||||
const unitName = unit?.data?.name ?? "";
|
||||
const SubjectName = unit?.data?.subject?.name ?? "";
|
||||
const lessonName = lesson?.data?.name ?? "";
|
||||
const { data: unit } = useGetAllUnit({ show: unit_id });
|
||||
|
||||
useSetPageTitle(
|
||||
t(`page_header.subject`) +
|
||||
"/" +
|
||||
`${SubjectName}` +
|
||||
"/" +
|
||||
t(`PageTitle.unit`) +
|
||||
"/" +
|
||||
`${unitName}` +
|
||||
"/" +
|
||||
t(`PageTitle.lesson`) +
|
||||
"/" +
|
||||
`${lessonName}` +
|
||||
"/" +
|
||||
t(`PageTitle.questions`),
|
||||
);
|
||||
|
||||
const { data: Subject } = useGetAllSubject({
|
||||
show: subject_id,
|
||||
});
|
||||
const { data: grade } = useGetAllGrade({
|
||||
show: grade_id,
|
||||
});
|
||||
const { data: Curriculum } = useGetAllCurriculum({
|
||||
show: curriculum_id,
|
||||
});
|
||||
const { data: Lesson } = useGetAllLesson({
|
||||
show: lesson_id,
|
||||
});
|
||||
|
||||
const gradeName = grade?.data?.name ?? "";
|
||||
const SubjectName = Subject?.data?.name ?? "";
|
||||
const CurriculumName = Curriculum?.data?.name ?? "";
|
||||
const unitName = unit?.data?.name ?? "";
|
||||
const LessonName = Lesson?.data?.name ?? "";
|
||||
|
||||
useSetPageTitle( t(`page_header.grade`)+ "/"+ gradeName +"/"+t(`PageTitle.subject`)+"/"+SubjectName+"/"+t("PageTitle.curriculum")+"/"+CurriculumName+"/"+t("PageTitle.unit")+"/"+unitName+"/"+t("PageTitle.lesson")+"/"+LessonName+"/"+t("PageTitle.question")+"/"+t("practical.edit"));
|
||||
|
||||
const handleSubmit = (values: any) => {
|
||||
const DataToSend = structuredClone(values);
|
||||
|
|
@ -91,6 +96,8 @@ const EditPage: React.FC = () => {
|
|||
id: DataToSend?.id,
|
||||
content: DataToSend?.content,
|
||||
image: DataToSend?.image ?? "",
|
||||
|
||||
|
||||
};
|
||||
if (
|
||||
typeof UpdateBseQuestion?.image === "string" &&
|
||||
|
|
@ -150,6 +157,8 @@ const EditPage: React.FC = () => {
|
|||
tags,
|
||||
lessons_ids: [lesson_id],
|
||||
parent_id: values?.id,
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -169,9 +178,6 @@ const EditPage: React.FC = () => {
|
|||
|
||||
updatedObject?.QuestionOptions?.forEach((item: any) => {
|
||||
if (item?.id) {
|
||||
// if(!item?.answer_image){
|
||||
// item["answer_image"] = ""
|
||||
// }
|
||||
console.log(item);
|
||||
|
||||
oldQuestionOptions.push(item);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import TextField from "./TextField";
|
|||
import File from "./File";
|
||||
import { FaCirclePlus, FaDeleteLeft } from "react-icons/fa6";
|
||||
import { FaTrash } from "react-icons/fa";
|
||||
import HintField from "./HintField";
|
||||
|
||||
const ChoiceFields = ({ index, data }: { index: number; data: Choice }) => {
|
||||
const formik = useFormikContext<any>();
|
||||
|
|
@ -25,9 +26,9 @@ const ChoiceFields = ({ index, data }: { index: number; data: Choice }) => {
|
|||
|
||||
formik.setFieldValue("QuestionOptions", updatedQuestionOptions);
|
||||
};
|
||||
console.log(formik.values);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="ChoiceFields">
|
||||
<TextField
|
||||
className="textarea_exercise"
|
||||
|
|
@ -50,10 +51,21 @@ const ChoiceFields = ({ index, data }: { index: number; data: Choice }) => {
|
|||
name={index}
|
||||
type="Checkbox"
|
||||
/>
|
||||
|
||||
<p className="delete_question_options">
|
||||
<FaTrash onClick={handleDeleteChoice} size={17} />
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<HintField
|
||||
placeholder={"hint"}
|
||||
name={index}
|
||||
label="hint"
|
||||
id={`hint`}
|
||||
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
70
src/Pages/question/Model/Field/Choices.tsx
Normal file
70
src/Pages/question/Model/Field/Choices.tsx
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import React from 'react';
|
||||
import { Choice } from '../../../../types/Item';
|
||||
import ChoiceFields from './ChoiceFields';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
|
||||
|
||||
const Choices = () => {
|
||||
const formik = useFormikContext<any>();
|
||||
|
||||
const handleDragEnd = (result: any) => {
|
||||
// Check if the item was dropped outside the list
|
||||
if (!result.destination) return;
|
||||
|
||||
// Create a new array from the current QuestionOptions
|
||||
const items = Array.from(formik?.values?.QuestionOptions);
|
||||
|
||||
// Remove the item from the original position
|
||||
const [reorderedItem] = items.splice(result.source.index, 1);
|
||||
|
||||
// Insert the item at the new position
|
||||
items.splice(result.destination.index, 0, reorderedItem);
|
||||
|
||||
// Update the order keys based on the new indices
|
||||
const updatedItems = items.map((item, index) => ({
|
||||
...item ?? {},
|
||||
order: index + 1, // Update order to be 1-based index
|
||||
}));
|
||||
|
||||
// Update the formik state with the new order
|
||||
console.log(updatedItems,"updatedItems");
|
||||
|
||||
formik.setFieldValue('QuestionOptions', updatedItems);
|
||||
};
|
||||
|
||||
return (
|
||||
<DragDropContext onDragEnd={handleDragEnd}>
|
||||
<Droppable droppableId="choices">
|
||||
{(provided) => (
|
||||
<div
|
||||
{...provided.droppableProps}
|
||||
ref={provided.innerRef}
|
||||
|
||||
>
|
||||
{formik?.values?.QuestionOptions?.map((item: Choice, index: number) => {
|
||||
// Use a unique identifier for draggableId
|
||||
const draggableId = item.name ? item.name.toString() : `item-${index}`;
|
||||
|
||||
return (
|
||||
<Draggable key={draggableId} draggableId={draggableId} index={index}>
|
||||
{(provided) => (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
>
|
||||
<ChoiceFields index={index} data={item} />
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
);
|
||||
})}
|
||||
{provided.placeholder} {/* Placeholder for spacing */}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
</DragDropContext>
|
||||
);
|
||||
};
|
||||
|
||||
export default Choices;
|
||||
|
|
@ -17,7 +17,6 @@ const File = ({
|
|||
const { formik, t, isError, errorMsg } = useFormField(newName, props);
|
||||
let imageUrl = formik?.values?.QuestionOptions[name]?.answer_image ?? null;
|
||||
// console.log(imageUrl);
|
||||
console.log(imageUrl);
|
||||
|
||||
const fileList: UploadFile[] = useMemo(() => {
|
||||
if (!imageUrl) return [];
|
||||
|
|
|
|||
69
src/Pages/question/Model/Field/HintField.tsx
Normal file
69
src/Pages/question/Model/Field/HintField.tsx
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import { Form, Input } from "antd";
|
||||
import React from "react";
|
||||
import useFormField from "../../../../Hooks/useFormField";
|
||||
import { MdOutlineEdit } from "react-icons/md";
|
||||
import { Field } from "formik";
|
||||
const { TextArea } = Input;
|
||||
|
||||
const HintField = ({
|
||||
name,
|
||||
label,
|
||||
label2,
|
||||
placeholder,
|
||||
isDisabled,
|
||||
onChange,
|
||||
props,
|
||||
no_label,
|
||||
label_icon,
|
||||
id,
|
||||
className,
|
||||
}: any) => {
|
||||
const newName = `QuestionOptions[${name}].hint`;
|
||||
const { formik, isError, errorMsg, t } = useFormField(newName, props);
|
||||
const TextFilehandleChange = (
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
) => {
|
||||
// console.log('Change:', e.target.value);
|
||||
formik.setFieldValue(newName, e.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`ValidationField w-100 ${className ?? ""} `}>
|
||||
{no_label ? (
|
||||
<label htmlFor={name} className="text">
|
||||
<span>empty</span>
|
||||
</label>
|
||||
) : label_icon ? (
|
||||
<div className="LabelWithIcon">
|
||||
<label htmlFor={name} className="text">
|
||||
{label2 ? label2 : t(`input.${label ? label : name}`)}
|
||||
</label>
|
||||
<MdOutlineEdit size={22} style={{ color: "#A098AE" }} />
|
||||
</div>
|
||||
) : (
|
||||
<label htmlFor={name} className="text">
|
||||
{label2 ? label2 : t(`input.${label ? label : name}`)}
|
||||
</label>
|
||||
)}
|
||||
|
||||
<Form.Item
|
||||
hasFeedback
|
||||
validateStatus={isError ? "error" : ""}
|
||||
help={isError ? errorMsg : ""}
|
||||
>
|
||||
<Field
|
||||
as={Input}
|
||||
placeholder={t(`input.${placeholder ? placeholder : name}`)}
|
||||
name={newName}
|
||||
disabled={isDisabled}
|
||||
size="large"
|
||||
onChange={onChange || TextFilehandleChange}
|
||||
style={{width:200}}
|
||||
id={id}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(HintField);
|
||||
|
|
@ -10,17 +10,14 @@ import { useTranslation } from "react-i18next";
|
|||
import DynamicTags from "./Tags/DynamicTags";
|
||||
import QuestionFIeld from "./QuestionFIeld/QuestionFIeld";
|
||||
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
|
||||
import Choices from "./ChoiceField/Choices";
|
||||
|
||||
const Form = () => {
|
||||
const formik = useFormikContext<any>();
|
||||
const { isOpen } = useModalState((state) => state);
|
||||
// const {data} = useGetAllQuestion();
|
||||
const { setSuccess, Success, setSavedQuestionData } = useObjectToEdit();
|
||||
|
||||
useEffect(() => {
|
||||
if (Success) {
|
||||
console.log(1);
|
||||
|
||||
formik.setErrors({});
|
||||
formik.resetForm({ values: {} });
|
||||
setSuccess(false);
|
||||
|
|
@ -32,7 +29,6 @@ const Form = () => {
|
|||
}, [formik?.values]);
|
||||
|
||||
// console.log(formik?.errors);
|
||||
console.log(formik?.values?.Questions, "formik?.values?.Questions");
|
||||
|
||||
const handleAddChoice = (parent_index: number) => {
|
||||
console.log(parent_index);
|
||||
|
|
@ -70,7 +66,6 @@ const Form = () => {
|
|||
formik.setFieldValue("max_mark", max_mark);
|
||||
};
|
||||
const [t] = useTranslation();
|
||||
console.log(formik.errors);
|
||||
|
||||
return (
|
||||
<Row className="w-100">
|
||||
|
|
@ -109,19 +104,7 @@ const Form = () => {
|
|||
/>
|
||||
</div>
|
||||
|
||||
{(
|
||||
(formik?.values as any)?.Questions?.[parent_index]
|
||||
?.QuestionOptions || []
|
||||
).map((item: Choice, index: number) => {
|
||||
return (
|
||||
<ChoiceFields
|
||||
key={index}
|
||||
parent_index={parent_index}
|
||||
index={index}
|
||||
data={item}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<Choices parent_index={parent_index} />
|
||||
|
||||
{formik?.values?.Questions?.[parent_index]?.QuestionOptions
|
||||
?.length < 5 && (
|
||||
|
|
|
|||
87
src/Pages/question/Model/Malty/ChoiceField/Choices.tsx
Normal file
87
src/Pages/question/Model/Malty/ChoiceField/Choices.tsx
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import React from 'react'
|
||||
import ChoiceFields from './ChoiceFields';
|
||||
import { Choice } from '../../../../../types/Item';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
|
||||
|
||||
const Choices = ({parent_index}:{parent_index:number}) => {
|
||||
const formik = useFormikContext<any>();
|
||||
|
||||
|
||||
const handleDragEnd = (result: any) => {
|
||||
// Check if the item was dropped outside the list
|
||||
if (!result.destination) return;
|
||||
|
||||
// Create a new array from the current QuestionOptions
|
||||
const items = Array.from(formik?.values?.QuestionOptions);
|
||||
|
||||
// Remove the item from the original position
|
||||
const [reorderedItem] = items.splice(result.source.index, 1);
|
||||
|
||||
// Insert the item at the new position
|
||||
items.splice(result.destination.index, 0, reorderedItem);
|
||||
|
||||
// Update the order keys based on the new indices
|
||||
const updatedItems = items.map((item, index) => ({
|
||||
...item ?? {},
|
||||
order: index + 1, // Update order to be 1-based index
|
||||
}));
|
||||
|
||||
// Update the formik state with the new order
|
||||
console.log(updatedItems,"updatedItems");
|
||||
|
||||
formik.setFieldValue('QuestionOptions', updatedItems);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<DragDropContext onDragEnd={handleDragEnd}>
|
||||
<Droppable droppableId="choices">
|
||||
{(provided) => (
|
||||
<div
|
||||
{...provided.droppableProps}
|
||||
ref={provided.innerRef}
|
||||
|
||||
>
|
||||
{(
|
||||
(formik?.values as any)?.Questions?.[parent_index]
|
||||
?.QuestionOptions || []
|
||||
).map((item: Choice, index: number) => {
|
||||
const draggableId = item.name ? item.name.toString() : `item-${index}`;
|
||||
|
||||
return (
|
||||
<Draggable key={draggableId} draggableId={draggableId} index={index}>
|
||||
{(provided) => (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
>
|
||||
|
||||
<ChoiceFields
|
||||
key={index}
|
||||
parent_index={parent_index}
|
||||
index={index}
|
||||
data={item}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
|
||||
);
|
||||
})}
|
||||
|
||||
{provided.placeholder}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
</DragDropContext>
|
||||
|
||||
|
||||
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Choices
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import React from "react";
|
||||
import { Checkbox, Form } from "antd";
|
||||
import { useFormik, useFormikContext } from "formik";
|
||||
import { useTranslation } from "react-i18next";
|
||||
const CheckboxField = ({
|
||||
name,
|
||||
label,
|
||||
isDisabled,
|
||||
onChange,
|
||||
Group,
|
||||
className,
|
||||
props,
|
||||
}: any) => {
|
||||
const formik = useFormikContext<any>();
|
||||
const [t] = useTranslation();
|
||||
const newName = `Questions[${name}].canAnswersBeShuffled`;
|
||||
console.log(formik.values?.Questions?.[name]);
|
||||
|
||||
const CheckboxhandleChange = (value: any, index: number) => {
|
||||
formik.setFieldValue(newName, value?.target?.checked ? 1 : 0);
|
||||
};
|
||||
return (
|
||||
<div className={Group ? "d-inline mt-5 Checkbox" : ``}>
|
||||
<Checkbox
|
||||
onChange={onChange || CheckboxhandleChange}
|
||||
disabled={isDisabled}
|
||||
checked={formik.values?.Questions?.[name]?.canAnswersBeShuffled === 1}
|
||||
className={className}
|
||||
>
|
||||
{t(`input.${label ? label : name}`)}
|
||||
</Checkbox>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CheckboxField;
|
||||
|
|
@ -9,6 +9,7 @@ import File from "./File";
|
|||
import { FaTrash } from "react-icons/fa";
|
||||
import { useObjectToEdit } from "../../../../../zustand/ObjectToEditState";
|
||||
import { toast } from "react-toastify";
|
||||
import CheckboxField from "./CheckboxField";
|
||||
|
||||
const QuestionFIeld = ({ index, data }: { index: number; data: Choice }) => {
|
||||
const formik = useFormikContext<any>();
|
||||
|
|
@ -46,6 +47,13 @@ const QuestionFIeld = ({ index, data }: { index: number; data: Choice }) => {
|
|||
name={index}
|
||||
type="File"
|
||||
/>
|
||||
<CheckboxField
|
||||
className="canAnswersBeShuffled"
|
||||
label={"canAnswersBeShuffled"}
|
||||
name={index}
|
||||
|
||||
/>
|
||||
|
||||
<p className="delete_question_options">
|
||||
<FaTrash onClick={handleDeleteQuestion} size={17} />
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { useTranslation } from "react-i18next";
|
|||
import DynamicTags from "./Tags/DynamicTags";
|
||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
||||
import { useEffect } from "react";
|
||||
import Choices from "./Field/Choices";
|
||||
|
||||
const Form = () => {
|
||||
const [t] = useTranslation()
|
||||
|
|
@ -42,11 +43,12 @@ const Form = () => {
|
|||
<div className="exercise_form">
|
||||
<ValidationField className="textarea_exercise" name="content" label="details" type="TextArea" />
|
||||
<ValidationField className="file_exercise" name="image" label="attachment" type="File" />
|
||||
<ValidationField name="canAnswersBeShuffled" label="canAnswersBeShuffled" type="Checkbox" />
|
||||
</div>
|
||||
{
|
||||
(((formik?.values as any)?.QuestionOptions as Choice[])||[]) .map((item:Choice,index:number)=>{
|
||||
return <ChoiceFields key={index} index={index} data={item}/>
|
||||
})}
|
||||
<div>
|
||||
<ValidationField className="hint" name="hint" label="hint" type="text" style={{width:200}} />
|
||||
</div>
|
||||
<Choices />
|
||||
{formik?.values?.QuestionOptions?.length < 5 && (
|
||||
<p className="add_new_button" >
|
||||
<FaCirclePlus onClick={handleAddChoice} size={23} /> {t("header.add_new_choice")}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ export const getInitialValues = (objectToEdit: Question): any => {
|
|||
content: objectToEdit?.content ?? "",
|
||||
image: objectToEdit?.image ?? "",
|
||||
subject_id: objectToEdit?.subject_id ?? "",
|
||||
canAnswersBeShuffled: objectToEdit?.canAnswersBeShuffled ?? 0,
|
||||
isBase: 0,
|
||||
parent_id: objectToEdit?.parent_id ?? "",
|
||||
QuestionOptions: objectToEdit?.QuestionOptions ?? [],
|
||||
|
|
@ -38,10 +39,6 @@ export const getValidationSchema = () => {
|
|||
};
|
||||
|
||||
export const getInitialValuesBase = (objectToEdit: Question): any => {
|
||||
const tags = objectToEdit?.tags?.map((item: any, index: number) => {
|
||||
return { ...item, key: index };
|
||||
});
|
||||
console.log(objectToEdit);
|
||||
|
||||
const newQuestions = objectToEdit?.Questions?.map((item: any) => {
|
||||
const tags = item?.tags?.map((tag: any) => ({
|
||||
|
|
@ -52,6 +49,7 @@ export const getInitialValuesBase = (objectToEdit: Question): any => {
|
|||
|
||||
return {
|
||||
...item,
|
||||
canAnswersBeShuffled: item?.canAnswersBeShuffled ?? 0,
|
||||
tags,
|
||||
};
|
||||
});
|
||||
|
|
@ -65,10 +63,13 @@ export const getInitialValuesBase = (objectToEdit: Question): any => {
|
|||
subject_id: objectToEdit?.subject_id ?? "",
|
||||
isBase: 1,
|
||||
parent_id: objectToEdit?.parent_id ?? "",
|
||||
canAnswersBeShuffled: objectToEdit?.canAnswersBeShuffled ?? 0,
|
||||
|
||||
Questions: questions,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
export const getValidationSchemaBase = () => {
|
||||
// validate input
|
||||
return Yup.object().shape({
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ import { useGetAllLesson } from "../../api/lesson";
|
|||
import { useDeleteQuestion } from "../../api/Question";
|
||||
import DeleteModels from "../../Layout/Dashboard/DeleteModels";
|
||||
import { ModalEnum } from "../../enums/Model";
|
||||
import { useGetAllSubject } from "../../api/subject";
|
||||
import { useGetAllGrade } from "../../api/grade";
|
||||
import { useGetAllCurriculum } from "../../api/curriculum";
|
||||
const Table = lazy(() => import("./Table"));
|
||||
|
||||
const TableHeader = () => {
|
||||
|
|
@ -16,35 +19,37 @@ const TableHeader = () => {
|
|||
|
||||
const deleteMutation = useDeleteQuestion();
|
||||
|
||||
const { unit_id,lesson_id } = useParams<ParamsEnum>();
|
||||
const { unit_id,curriculum_id,grade_id ,subject_id,lesson_id} = useParams<ParamsEnum>();
|
||||
const { data: unit } = useGetAllUnit({ show: unit_id });
|
||||
const { data: lesson } = useGetAllLesson({ show: lesson_id });
|
||||
const unitName = unit?.data?.name ?? "";
|
||||
const SubjectName = unit?.data?.subject?.name ?? "";
|
||||
const lessonName = lesson?.data?.name ?? "";
|
||||
|
||||
useSetPageTitle(
|
||||
t(`page_header.subject`) +
|
||||
"/" +
|
||||
`${SubjectName}` +
|
||||
"/" +
|
||||
t(`PageTitle.unit`) +
|
||||
"/" +
|
||||
`${unitName}` +
|
||||
"/" +
|
||||
t(`PageTitle.lesson`) +
|
||||
"/" +
|
||||
`${lessonName}` +
|
||||
"/" +
|
||||
t(`PageTitle.questions`),
|
||||
);
|
||||
|
||||
const { data: Subject } = useGetAllSubject({
|
||||
show: subject_id,
|
||||
});
|
||||
const { data: grade } = useGetAllGrade({
|
||||
show: grade_id,
|
||||
});
|
||||
const { data: Curriculum } = useGetAllCurriculum({
|
||||
show: curriculum_id,
|
||||
});
|
||||
const { data: Lesson } = useGetAllLesson({
|
||||
show: lesson_id,
|
||||
});
|
||||
|
||||
const gradeName = grade?.data?.name ?? "";
|
||||
const SubjectName = Subject?.data?.name ?? "";
|
||||
const CurriculumName = Curriculum?.data?.name ?? "";
|
||||
const unitName = unit?.data?.name ?? "";
|
||||
const LessonName = Lesson?.data?.name ?? "";
|
||||
|
||||
useSetPageTitle( t(`page_header.grade`)+ "/"+ gradeName +"/"+t(`PageTitle.subject`)+"/"+SubjectName+"/"+t("PageTitle.curriculum")+"/"+CurriculumName+"/"+t("PageTitle.unit")+"/"+unitName+"/"+t("PageTitle.lesson")+"/"+LessonName+"/"+t("PageTitle.question"));
|
||||
|
||||
return (
|
||||
<div className="TableWithHeader">
|
||||
<Suspense fallback={<Spin />}>
|
||||
<header>
|
||||
<h6>
|
||||
{t("models.Question")} {SubjectName} {unitName} {lessonName}
|
||||
{t("models.Question")}
|
||||
</h6>
|
||||
</header>
|
||||
<Table />
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@ import useSetPageTitle from "../../../Hooks/useSetPageTitle";
|
|||
import { canAddSubject } from "../../../utils/hasAbilityFn";
|
||||
import { useDeleteSubject } from "../../../api/subject";
|
||||
import { lazy } from "react";
|
||||
import { useGetAllCurriculum } from "../../../api/curriculum";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { ParamsEnum } from "../../../enums/params";
|
||||
import { useGetAllGrade } from "../../../api/grade";
|
||||
const Table = lazy(() => import("./TablePage"));
|
||||
const AddModalForm = lazy(() => import("../Model/AddModel"));
|
||||
const EditModalForm = lazy(() => import("../Model/EditModel"));
|
||||
|
|
@ -16,7 +20,15 @@ const TableWithHeader = () => {
|
|||
const [t] = useTranslation();
|
||||
const deleteMutation = useDeleteSubject();
|
||||
|
||||
useSetPageTitle(t(`page_header.subject`));
|
||||
const { grade_id} = useParams<ParamsEnum>();
|
||||
|
||||
const { data: grade } = useGetAllGrade({
|
||||
show: grade_id,
|
||||
});
|
||||
|
||||
const gradeName = grade?.data?.name ?? "";
|
||||
useSetPageTitle( t(`page_header.grade`)+ "/"+ `${gradeName}` +"/"+t(`PageTitle.subject`));
|
||||
|
||||
|
||||
return (
|
||||
<div className="TableWithHeader">
|
||||
|
|
|
|||
|
|
@ -4,3 +4,8 @@
|
|||
@import "./Model.scss";
|
||||
@import "./Segmented.scss";
|
||||
@import "./Mix.scss";
|
||||
|
||||
|
||||
.draggable-row {
|
||||
cursor: move; /* Change cursor to indicate draggable rows */
|
||||
}
|
||||
|
|
@ -120,3 +120,10 @@
|
|||
position: absolute;
|
||||
left: 100px;
|
||||
}
|
||||
|
||||
|
||||
.hint_canAnswersBeShuffled{
|
||||
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// export const BaseURL = "http://192.168.1.6:8000/api/";
|
||||
export const BaseURL = "http://192.168.1.111:8000/api/";
|
||||
// export const BaseURL = "http://127.0.0.1:8000/api/";
|
||||
|
||||
export const BaseURL = "http://192.168.1.111:8000/api/";
|
||||
// export const BaseURL = "http://192.168.1.120:8000/api/";
|
||||
|
||||
// export const ImageBaseURL = "http://192.168.1.9:8000/";
|
||||
|
||||
|
|
|
|||
5
src/enums/Term.ts
Normal file
5
src/enums/Term.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export enum TermEnum {
|
||||
FIRST_TERM = "first_term",
|
||||
SECOND_TERM = "second_term",
|
||||
}
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ function QueryProvider({ children }: any) {
|
|||
defaultOptions: {
|
||||
queries: {
|
||||
refetchOnWindowFocus: false,
|
||||
cacheTime:0
|
||||
// staleTime:Infinity
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -106,7 +106,9 @@
|
|||
"add_Question": "إضافة اسئلة",
|
||||
"malty_exercise": "تمرين متعدد",
|
||||
"add_new_question": "اضافة سؤال جديد",
|
||||
"exercise": "تمارين"
|
||||
"exercise": "تمارين",
|
||||
"icon" :"الايقونة"
|
||||
|
||||
},
|
||||
"columns": {
|
||||
"id": "الرقم التعريفي",
|
||||
|
|
@ -119,6 +121,7 @@
|
|||
"payment_type": "نوع الدفع",
|
||||
"value": "القيمة",
|
||||
"subject_name": "اسم المادة",
|
||||
"icon" :"الايقونة",
|
||||
"image": "الصورة",
|
||||
"card": "البطاقة",
|
||||
"birthday": "تاريخ الميلاد",
|
||||
|
|
@ -317,6 +320,7 @@
|
|||
"due_date": "تاريخ الاستحقاق",
|
||||
"assigning_date": "تاريخ التعيين",
|
||||
"subject_name": "اسم المادة",
|
||||
"icon" :"الايقونة",
|
||||
"exam_type": "نوع الامتحان",
|
||||
"grade_to_pass": "الدرجة اللازمة للنجاح",
|
||||
"max_grade": "الدرجة القصوى",
|
||||
|
|
@ -354,7 +358,9 @@
|
|||
"isBase": "سؤال رئيسي",
|
||||
"main_question": "النص الأساسي ",
|
||||
"question": "السؤال",
|
||||
"id": "الرقم التعريفي"
|
||||
"id": "الرقم التعريفي",
|
||||
"canAnswersBeShuffled":"يمكن خلط الإجابات",
|
||||
"hint":"لحليح"
|
||||
},
|
||||
|
||||
"select": {
|
||||
|
|
@ -679,7 +685,9 @@
|
|||
"edit": "تعديل",
|
||||
"questions": "اسئلة",
|
||||
"lesson": "الدرس",
|
||||
"curriculum": "مقرر"
|
||||
"curriculum": "مقرر",
|
||||
"subject":"المادة",
|
||||
"question":"السؤال"
|
||||
},
|
||||
"page_header": {
|
||||
"dashboard": "لوحة القيادة / الصفحة الرئيسية",
|
||||
|
|
|
|||
|
|
@ -306,6 +306,7 @@ export interface Question {
|
|||
parent_id: number;
|
||||
isBase: number;
|
||||
content: string;
|
||||
canAnswersBeShuffled:number ;
|
||||
max_mark: number;
|
||||
min_mark_to_pass: number;
|
||||
image: string | null;
|
||||
|
|
|
|||
21
src/types/Unit.ts
Normal file
21
src/types/Unit.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { TermEnum } from "../enums/Term";
|
||||
import { Nullable } from "./App";
|
||||
|
||||
// Define the type for the object
|
||||
export interface Unit {
|
||||
curriculum_id: number;
|
||||
id: number; // Represents the student ID
|
||||
name: string; // Represents the student's name
|
||||
order: number; // Represents the order (could be for sorting)
|
||||
term: TermEnum; // Represents the term using the Term enum
|
||||
}
|
||||
|
||||
export interface InitialValues {
|
||||
curriculum_id: number;
|
||||
id: number; // Represents the student ID
|
||||
name: string; // Represents the student's name
|
||||
order: number; // Represents the order (could be for sorting)
|
||||
term: TermEnum;
|
||||
}
|
||||
|
||||
export type UnitInitialValues = Partial<Nullable<InitialValues>>;
|
||||
6
src/utils/enumToArray.ts
Normal file
6
src/utils/enumToArray.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
export const enumToArray = (enumObj: any) => {
|
||||
return Object.keys(enumObj).map(key => ({
|
||||
value: enumObj[key],
|
||||
label: enumObj[key],
|
||||
}));
|
||||
};
|
||||
|
|
@ -3,6 +3,8 @@ import { create } from "zustand";
|
|||
interface ModelState {
|
||||
objectToEdit: any;
|
||||
setObjectToEdit: (data: any) => void;
|
||||
OldObjectToEdit: any;
|
||||
setOldObjectToEdit: (data: any) => void;
|
||||
paramToSend: any;
|
||||
setParamToSend: (data: any) => void;
|
||||
TagsSearch: any;
|
||||
|
|
@ -27,6 +29,8 @@ interface ModelState {
|
|||
export const useObjectToEdit = create<ModelState>((set) => ({
|
||||
objectToEdit: null,
|
||||
setObjectToEdit: (data) => set(() => ({ objectToEdit: data })),
|
||||
OldObjectToEdit: null,
|
||||
setOldObjectToEdit: (data) => set(() => ({ OldObjectToEdit: data })),
|
||||
paramToSend: {},
|
||||
setParamToSend: (data) => set(() => ({ paramToSend: data })),
|
||||
TagsSearch: null,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user