reseller : sales page and collection page

admin: collection and some fixes
This commit is contained in:
Moaz Dawalibi 2024-09-26 09:40:58 +03:00
parent 3bdfdf799e
commit 81eb55e2e0
49 changed files with 784 additions and 193 deletions

View File

@ -38,7 +38,7 @@ const NavBarRightSide = () => {
icon={<CiCirclePlus size={25} />} icon={<CiCirclePlus size={25} />}
/> />
<TooltipComp <TooltipComp
onClick={()=>(Navigate('/notifications'))} // onClick={()=>(Navigate('/notifications'))}
className="NotificationsIcon" className="NotificationsIcon"
note="notification" note="notification"
color="#E0E0E0" color="#E0E0E0"
@ -55,7 +55,9 @@ const NavBarRightSide = () => {
<h6>{userData?.username}</h6> <h6>{userData?.username}</h6>
<p>{userData?.type}</p> <p>{userData?.type}</p>
</span> */} </span> */}
<Image onClick={()=>(Navigate('/profile'))} src="/Image/faker_user.png" alt="Profile" /> <Image
// onClick={()=>(Navigate('/profile'))}
src="/Image/faker_user.png" alt="Profile" />
</div> </div>
</article> </article>
); );

View File

@ -158,14 +158,14 @@ const useFilter = () => {
return ( return (
<div className="filter-submit-buttons buttons"> <div className="filter-submit-buttons buttons">
<Button <Button
className="back_button filter_modal_add_button" className="back_button filter_modal_cancel_button"
type="default" type="default"
htmlType="reset" htmlType="reset"
> >
{t("practical.reset")} {t("practical.reset")}
</Button> </Button>
<Button <Button
className="add_button pointer filter_modal_add_button" className="pointer filter_modal_add_button"
type="primary" type="primary"
{...buttonProps} {...buttonProps}
htmlType="submit" htmlType="submit"

View File

@ -25,6 +25,7 @@ const Date = ({
const onCalendarChange = (value: any) => { const onCalendarChange = (value: any) => {
formik.setFieldValue(name, value); formik.setFieldValue(name, value);
}; };
console.log(FormikValue);
const Formatter = [DateEnum?.FORMATE]; const Formatter = [DateEnum?.FORMATE];
return ( return (

View File

@ -1,5 +1,5 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { Divider, Modal, Spin } from "antd"; import { Button, Divider, Modal, Spin } from "antd";
import { useModalState } from "../../zustand/Modal"; import { useModalState } from "../../zustand/Modal";
import FormikForm from "./FormikFormModel"; import FormikForm from "./FormikFormModel";
import { useObjectToEdit } from "../../zustand/ObjectToEditState"; import { useObjectToEdit } from "../../zustand/ObjectToEditState";
@ -76,7 +76,6 @@ const LayoutModel = ({
initialValues={getInitialValues} initialValues={getInitialValues}
validationSchema={getValidationSchema} validationSchema={getValidationSchema}
onSubmit={handleSubmit} onSubmit={handleSubmit}
> >
{(formik) => { {(formik) => {
useEffect(() => { useEffect(() => {
@ -101,13 +100,13 @@ const LayoutModel = ({
<Divider /> <Divider />
<div className="buttons"> <div className="buttons">
<div className="back_button pointer" onClick={handleCancel}> <Button className="back_button pointer" onClick={handleCancel}>
{t("practical.cancel")} {t("practical.cancel")}
</div> </Button>
<button <Button
className="add_button" className="add_button"
disabled={status === QueryStatusEnum.LOADING || !formik.dirty} disabled={status === QueryStatusEnum.LOADING || !formik.dirty}
type="submit" htmlType="submit"
> >
{ {
initialButtonName ? t(`practical.${isAddModal ? "add" : "edit"}`) initialButtonName ? t(`practical.${isAddModal ? "add" : "edit"}`)
@ -118,7 +117,7 @@ const LayoutModel = ({
<Spin /> <Spin />
</span> </span>
)} )}
</button> </Button>
</div> </div>
</main> </main>

View File

@ -66,7 +66,9 @@ const SideBar = ({
</div> </div>
<div className="side_bar_setting"> <div className="side_bar_setting">
<p>{t("sidebar.setting")}</p> <p>{t("sidebar.setting")}</p>
<div onClick={() => {navigate("/setting")}}> <div
// onClick={() => {navigate("/setting")}}
>
<CiSettings /> <CiSettings />
<span>{t("sidebar.setting")}</span> <span>{t("sidebar.setting")}</span>
</div> </div>

View File

@ -0,0 +1,39 @@
import React from "react";
import { getInitialValues, getValidationSchema } from "./formUtil";
import { ModalEnum } from "../../../../enums/Model";
import LayoutModel from "../../../../Layout/Dashboard/LayoutModel";
import { QueryStatusEnum } from "../../../../enums/QueryStatus";
import { useAddTag } from "../../../../api/tags";
import ModelForm from "./ModelForm";
import { useAddFinancialCollection } from "../../../../api/financial_collection";
import { formatDate } from "../../../../utils/formatDate";
import dayjs from "dayjs";
const AddModel: React.FC = () => {
const { mutate, status } = useAddFinancialCollection();
const handleSubmit = (values: any) => {
console.log(values);
mutate({
...values,
date: dayjs(values?.date).format('YYYY-MM-DD'),
});
};
return (
<>
<LayoutModel
status={status as QueryStatusEnum}
ModelEnum={ModalEnum.Financial_Collection_ADD}
modelTitle="financial_collection"
handleSubmit={handleSubmit}
getInitialValues={getInitialValues({})}
getValidationSchema={getValidationSchema}
>
<ModelForm />
</LayoutModel>
</>
);
};
export default AddModel;

View File

@ -0,0 +1,40 @@
import React from "react";
import { getInitialValues, getValidationSchema, getValidationSchemaEdit } from "./formUtil";
import { ModalEnum } from "../../../../enums/Model";
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 { useUpdateFinancialCollection } from "../../../../api/financial_collection";
import dayjs from "dayjs";
const EditModel: React.FC = () => {
const { mutate, status } = useUpdateFinancialCollection();
const { objectToEdit } = useObjectToEdit((state) => state);
console.log(objectToEdit);
const handleSubmit = (values: any) => {
mutate({
...values,
date: dayjs(values?.date).format('YYYY-MM-DD'),
});
};
return (
<>
<LayoutModel
status={status as QueryStatusEnum}
ModelEnum={ModalEnum.Financial_Collection_EDIT}
modelTitle="financial_collection_details"
handleSubmit={handleSubmit}
getInitialValues={getInitialValues(objectToEdit)}
getValidationSchema={getValidationSchemaEdit}
isAddModal={false}
>
<ModelForm isEdit={true}/>
</LayoutModel>
</>
);
};
export default EditModel;

View File

@ -0,0 +1,35 @@
import React from "react";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap";
import { useGetAllReseller } from "../../../../api/reseller";
const FilterForm = () => {
const {data} = useGetAllReseller()
return (
<div>
<Row>
<Col>
<ValidationField placeholder="description" label="description" name="description" />
<ValidationField placeholder="amount" label="amount" name="amount" />
<ValidationField
placeholder="reseller"
label="reseller"
name="reseller_id"
type="Select"
option={data?.data?.map((e: any) => ({
...e,
fullName: `${e.first_name} ${e.last_name}`
}))}
fieldNames={{
label: "fullName",
value: "id"
}}
/>
</Col>
</Row>
</div>
);
};
export default FilterForm;

View File

@ -0,0 +1,38 @@
import { Col, Row } from "reactstrap";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { useGetAllReseller } from "../../../../api/reseller";
const Form = ({isEdit= false}:{isEdit?:boolean}) => {
const {data} = useGetAllReseller()
return (
<Row className="w-100">
<Col>
<ValidationField placeholder="description" label="description" name="description" />
<ValidationField placeholder="amount" label="amount" name="amount" />
</Col>
<Col>
<ValidationField placeholder="date" label="date" name="date" type="Date"/>
{isEdit ? " " :
<ValidationField
placeholder="reseller"
label="reseller"
name="reseller_id"
type="Select"
option={data?.data?.map((e: any) => ({
...e,
fullName: `${e.first_name} ${e.last_name}`
}))}
fieldNames={{
label: "fullName",
value: "id"
}}
/>
}
</Col>
</Row>
);
};
export default Form;

View File

@ -0,0 +1,30 @@
import * as Yup from "yup";
import dayjs from "dayjs";
export const getInitialValues = (objectToEdit: any): any => {
console.log(objectToEdit);
return {
id: objectToEdit?.id ?? null,
description: objectToEdit?.description ?? null,
amount: objectToEdit?.amount ?? null,
date: objectToEdit?.date ? dayjs(objectToEdit?.date) : null,
reseller_id: objectToEdit?.reseller_id ?? null,
};
};
export const getValidationSchema = () => {
return Yup.object().shape({
description: Yup.string().required("validation.required"),
amount: Yup.mixed().required("validation.required"),
date: Yup.mixed().required("validation.required"),
reseller_id: Yup.mixed().required("validation.required"),
});
};
export const getValidationSchemaEdit = () => {
return Yup.object().shape({
description: Yup.string().required("validation.required"),
amount: Yup.mixed().required("validation.required"),
date: Yup.mixed().required("validation.required"),
});
};

View File

@ -0,0 +1,54 @@
import { FaPlus } from "react-icons/fa";
import useModalHandler from "../../../utils/useModalHandler";
import { ModalEnum } from "../../../enums/Model";
import { useTranslation } from "react-i18next";
import { lazy, Suspense } from "react";
import { Spin } from "antd";
import { canAddFinancial_Collection, canAddTags } from "../../../utils/hasAbilityFn";
import useSetPageTitle from "../../../Hooks/useSetPageTitle";
import { useDeleteTag } from "../../../api/tags";
import PageHeader from "../../../Layout/Dashboard/PageHeader";
import FilterLayout from "../../../Layout/Dashboard/FilterLayout";
import FilterForm from "./Model/FilterForm";
import { useDeleteFinancialCollection } from "../../../api/financial_collection";
const Table = lazy(() => import("./Table"));
const AddModalForm = lazy(() => import("./Model/AddModel"));
const EditModalForm = lazy(() => import("./Model/EditModel"));
const DeleteModalForm = lazy(
() => import("../../../Layout/Dashboard/DeleteModels"),
);
const TableHeader = () => {
const [t] = useTranslation();
useSetPageTitle([
{name:`${t(`page_header.home`)}`, path:"/"},
{name:`${t(`page_header.financial_collection`)}`, path:"financial_collection"}
]);
const deleteMutation = useDeleteFinancialCollection();
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<PageHeader
pageTitle="financial_collection"
ModelAbility={ModalEnum?.Financial_Collection_ADD}
canAdd={canAddFinancial_Collection}
/>
<FilterLayout
sub_children={<FilterForm />}
filterTitle="sidebar.financial_collection"
/>
<Table />
<DeleteModalForm
deleteMutation={deleteMutation}
ModelEnum={ModalEnum?.Financial_Collection_DELETE}
/>
<AddModalForm />
<EditModalForm />
</Suspense>
</div>
);
};
export default TableHeader;

View File

@ -0,0 +1,24 @@
import React from "react";
import DataTable from "../../../Layout/Dashboard/Table/DataTable";
import { useColumns } from "./useTableColumns";
import { useFilterState } from "../../../Components/Utils/Filter/FilterState";
import { useFilterStateState } from "../../../zustand/Filter";
import { useGetAllFinancialCollection } from "../../../api/financial_collection";
const App: React.FC = () => {
const { filterState } = useFilterState();
const { Filter } = useFilterStateState();
const name = Filter?.name ;
const sort_by = Filter?.sort_by ;
const response = useGetAllFinancialCollection({
pagination: true,
name,
sort_by,
...filterState,
});
return <DataTable response={response} useColumns={useColumns} />;
};
export default App;

View File

@ -0,0 +1,17 @@
import { useColumns } from "./useTableColumns";
import Table from "./Table";
import { FaPlus } from "react-icons/fa";
import AddModalForm from "./Model/AddModel";
import EditModalForm from "./Model/EditModel";
// import DeleteModalForm from "../../";
export {
Table,
useColumns,
AddModalForm,
EditModalForm,
// DeleteModalForm,
FaPlus,
};

View File

@ -0,0 +1,73 @@
import { TableColumnsType } from "antd";
import { tags } from "../../../types/Item";
import { ModalEnum } from "../../../enums/Model";
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
import { useModalState } from "../../../zustand/Modal";
import { useTranslation } from "react-i18next";
import { canDeleteFinancial_Collection, canDeleteTags, canEditFinancial_Collection, canEditTags } from "../../../utils/hasAbilityFn";
import ActionButtons from "../../../Components/Table/ActionButtons";
export const useColumns = () => {
const [t] = useTranslation();
const { setIsOpen } = useModalState((state) => state);
const { setObjectToEdit } = useObjectToEdit((state) => state);
const handelDelete = (record: any) => {
setObjectToEdit(record);
setIsOpen(ModalEnum?.Financial_Collection_DELETE);
};
const handleEdit = (record: any) => {
setObjectToEdit(record);
setIsOpen(ModalEnum?.Financial_Collection_EDIT);
};
const columns: TableColumnsType<any> = [
{
title: t("columns.id"),
dataIndex: "id",
key: "id",
align: "center",
},
{
title: t("columns.amount"),
dataIndex: "amount",
key: "amount",
align: "center",
ellipsis:true
},
{
title: t("columns.date"),
dataIndex: "date",
key: "date",
align: "center",
ellipsis:true
},
{
title: t("columns.description"),
dataIndex: "description",
key: "description",
align: "center",
ellipsis:true
},
{
title: t("columns.procedure"),
key: "actions",
align: "center",
width: "25vw",
render: (_text, record, index) => {
return (
<ActionButtons
canDelete={canEditFinancial_Collection}
canEdit={canDeleteFinancial_Collection}
index={index}
onDelete={() => handelDelete(record)}
onEdit={() => handleEdit(record)}
/>
);
},
},
];
return columns;
};

View File

@ -16,6 +16,7 @@ const App: React.FC = () => {
name, name,
sort_by sort_by
}); });
// console.log(response);
return <DataTable response={response} useColumns={useColumns} />; return <DataTable response={response} useColumns={useColumns} />;
}; };

View File

@ -1,12 +1,13 @@
import { Spin } from "antd";
import { useTranslation } from "react-i18next" import { useTranslation } from "react-i18next"
const CollectionInfoCard = ({label,value}:{label:string,value:string}) => { const CollectionInfoCard = ({label,value,isLoading}:{label:string,value:string,isLoading?:boolean}) => {
const {t} = useTranslation(); const {t} = useTranslation();
return ( return (
<div className='collection_info_card'> <div className='collection_info_card'>
<h5>{t(`card.${label}`)}</h5> <h5>{t(`card.${label}`)}</h5>
<p>{t(value)}</p> <p> {isLoading ?<Spin/>: t(value)}</p>
</div> </div>
) )
} }

View File

@ -1,30 +1,39 @@
import React from 'react' import React from 'react'
import CollectionInfoCard from './CollectionInfoCard' import CollectionInfoCard from './CollectionInfoCard'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useGetSummery } from '../../../../api/sales';
import { Spin } from 'antd';
const CollectionsCards = ({data}:{data?:any}) => { const CollectionsCards = () => {
const {t} = useTranslation(); const {t} = useTranslation();
const { data ,isLoading} = useGetSummery();
return ( return (
<> <>
<CollectionInfoCard <CollectionInfoCard
label={t('total_sells')} label={t('total_sells')}
value={"210"} isLoading={isLoading}
value={data?.data?.total_sells}
/> />
<CollectionInfoCard <CollectionInfoCard
label={t('reseller_profit')} label={t('reseller_profit')}
value={"210"} isLoading={isLoading}
value={data?.data?.reseller_profit}
/> />
<CollectionInfoCard <CollectionInfoCard
label={t('company_profit')} label={t('company_profit')}
value={"210"} isLoading={isLoading}
value={data?.data?.dues}
/> />
<CollectionInfoCard <CollectionInfoCard
label={t('collected')} label={t('collected')}
value={"210"} isLoading={isLoading}
value={data?.data?.collected_amount}
/> />
<CollectionInfoCard <CollectionInfoCard
label={t('residual')} label={t('residual')}
value={"210"} isLoading={isLoading}
value={data?.data?.remaining_amount}
/> />
</> </>
) )

View File

@ -1,18 +1,17 @@
import React from "react";
import ValidationField from "../../../../Components/ValidationField/ValidationField"; import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap"; import { Col, Row } from "reactstrap";
import { useGetAllReseller } from "../../../../api/reseller";
const FilterForm = () => { const FilterForm = () => {
const {data} = useGetAllReseller()
console.log(data);
return ( return (
<div> <div>
<Row> <Row>
<Col> <Col>
<ValidationField <ValidationField placeholder="description" label="description" name="description" />
placeholder="activation_date" <ValidationField placeholder="amount" label="amount" name="amount" />
label="activation_date"
name="activation_date"
/>
{/* <ValidationField placeholder="name" label="name" name="name" /> */}
</Col> </Col>
</Row> </Row>
</div> </div>

View File

@ -22,7 +22,7 @@ const TableHeader = () => {
pageTitle="collections" pageTitle="collections"
/> />
<div className="collection_infos"> <div className="collection_infos">
<CollectionsCards/> <CollectionsCards />
</div> </div>
<FilterLayout <FilterLayout
sub_children={<FilterForm />} sub_children={<FilterForm />}

View File

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

View File

@ -0,0 +1,35 @@
import { useTranslation } from "react-i18next";
import { lazy, 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";
const Table = lazy(() => import("./Table"));
const TableHeader = () => {
const [t] = useTranslation();
useSetPageTitle([
{name:`${t(`page_header.home`)}`, path:"/"},
{name:`${t(`page_header.collections`)}`, path:"collections"},
{name:`${t(`page_header.show_collection`)}`, path:"show_collection"},
]);
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<PageHeader
pageTitle="show_collection"
/>
<FilterLayout
sub_children={<FilterForm />}
filterTitle="table.show_collection"
/>
<Table />
</Suspense>
</div>
);
};
export default TableHeader;

View File

@ -0,0 +1,25 @@
import React from "react";
import DataTable from "../../../../Layout/Dashboard/Table/DataTable";
import { useColumns } from "./useTableColumns";
import useSearchQuery from "../../../../api/utils/useSearchQuery";
import { useFilterState } from "../../../../Components/Utils/Filter/FilterState";
import { useGetCollection } from "../../../../api/collections";
import { useParams } from "react-router-dom";
const App: React.FC = () => {
const [searchQuery] = useSearchQuery("name");
const { filterState } = useFilterState();
const {collection_id}= useParams()
console.log(collection_id);
const response = useGetCollection({
name: searchQuery,
pagination: true,
...filterState,
show:collection_id
});
return <DataTable response={response} useColumns={useColumns} dataSource={[]} />;
};
export default App;

View File

@ -0,0 +1,35 @@
import { TableColumnsType } from "antd";
import { Collection } from "../../../../types/Item";
import { useTranslation } from "react-i18next";
export const useColumns = () => {
const [t] = useTranslation();
const columns: TableColumnsType<Collection> = [
{
title: t("columns.ID"),
dataIndex: "id",
key: "id",
align: "center",
},
{
title: t("columns.amount"),
dataIndex: "amount",
key: "amount",
align: "center",
},
{
title: t("columns.date"),
dataIndex: "date",
key: "date",
align: "center",
},
{
title: t("columns.description"),
dataIndex: "description",
key: "description",
align: "center",
},
];
return columns;
};

View File

@ -20,9 +20,9 @@ export const useColumns = () => {
align: "center", align: "center",
}, },
{ {
title: t("columns.date_of_receipt"), title: t("columns.date"),
dataIndex: "date_of_receipt", dataIndex: "date",
key: "date_of_receipt", key: "date",
align: "center", align: "center",
}, },
{ {
@ -31,12 +31,6 @@ export const useColumns = () => {
key: "description", key: "description",
align: "center", align: "center",
}, },
{
title: t("columns.residual"),
dataIndex: "residual",
key: "residual",
align: "center",
},
]; ];
return columns; return columns;

View File

@ -11,7 +11,7 @@ import LayoutModel from "./LayoutModel";
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState"; import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
const AddModel: React.FC = () => { const AddModel: React.FC = () => {
const { mutate, status } = useAddSales(); // const { mutate, status } = useAddSales();
const handleSubmit = (values: any) => { const handleSubmit = (values: any) => {
// mutate({ // mutate({
@ -31,13 +31,13 @@ const AddModel: React.FC = () => {
} }
// const modelTitle = Forms.[modal.Number] ? "sale" : Forms.Package ? "adcs" : "Ascas"; // const modelTitle = Forms.[modal.Number] ? "sale" : Forms.Package ? "adcs" : "Ascas";
const { objectToEdit,setObjectToEdit } = useObjectToEdit(); const { objectToEdit,setObjectToEdit } = useObjectToEdit();
console.log(objectToEdit); console.log(objectToEdit);
return ( return (
<> <>
<LayoutModel <LayoutModel
status={status as QueryStatusEnum} status={objectToEdit?.status as QueryStatusEnum}
ModelEnum={ModalEnum.Sales_ADD} ModelEnum={ModalEnum.Sales_ADD}
modelTitle={"modelTitle"} modelTitle={"modelTitle"}
handleSubmit={handleSubmit} handleSubmit={handleSubmit}

View File

@ -11,8 +11,14 @@ const FilterForm = () => {
placeholder="activation_date" placeholder="activation_date"
label="activation_date" label="activation_date"
name="activation_date" name="activation_date"
type="Date"
/>
<ValidationField
placeholder="expiration_date"
label="expiration_date"
name="expiration_date"
type="Date"
/> />
{/* <ValidationField placeholder="name" label="name" name="name" /> */}
</Col> </Col>
</Row> </Row>
</div> </div>

View File

@ -15,7 +15,7 @@ interface LayoutModalProps {
getInitialValues: any; getInitialValues: any;
getValidationSchema: any; getValidationSchema: any;
children: React.ReactNode; children: React.ReactNode;
status: QueryStatusEnum; status?: QueryStatusEnum;
ModelEnum: any; ModelEnum: any;
ModelClassName?: string; ModelClassName?: string;
width?: string; width?: string;
@ -75,7 +75,6 @@ const LayoutModel = ({
initialValues={getInitialValues} initialValues={getInitialValues}
validationSchema={getValidationSchema} validationSchema={getValidationSchema}
onSubmit={handleSubmit} onSubmit={handleSubmit}
> >
{(formik) => { {(formik) => {
useEffect(() => { useEffect(() => {

View File

@ -6,10 +6,10 @@ import { useModalState } from "../../../../zustand/Modal";
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState"; import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { QueryStatusEnum } from "../../../../enums/QueryStatus"; import { QueryStatusEnum } from "../../../../enums/QueryStatus";
import { Divider, Spin } from "antd"; import { Button, Divider, Spin } from "antd";
import { MdCancel } from "react-icons/md"; import { MdCancel } from "react-icons/md";
const Form = ({status}:{status?:any}) => { const Form = () => {
const {values,setFieldValue} = useFormikContext<any>() const {values,setFieldValue} = useFormikContext<any>()
console.log(values?.currentModalIndex); console.log(values?.currentModalIndex);
@ -32,7 +32,6 @@ console.log(objectToEdit);
name: info.name + " " + `( ${info?.original_price} )` name: info.name + " " + `( ${info?.original_price} )`
})); }));
console.log(PackagesInfo);
return ( return (
values?.currentModalIndex == 1 && values?.currentModalIndex == 1 &&
@ -50,7 +49,7 @@ console.log(PackagesInfo);
<img src="/Image/faker_user.png" alt="" /> <img src="/Image/faker_user.png" alt="" />
<span> <span>
<h5>{student_info?.first_name +" " + student_info?.last_name}</h5> <h5>{student_info?.first_name +" " + student_info?.last_name}</h5>
<h5>الصف: <p> {student_info?.grade_name}</p></h5> <h5>{t("models.course")}: <p> {student_info?.grade_name}</p></h5>
</span> </span>
</div> </div>
<ValidationField <ValidationField
@ -63,10 +62,10 @@ console.log(PackagesInfo);
</div> </div>
{/* {values?.currentModalIndex} */} {/* {values?.currentModalIndex} */}
<div className="buttons"> <div className="buttons">
<div className="back_button pointer" onClick={handleCancel}> <Button className="back_button pointer" onClick={handleCancel}>
{t("practical.cancel")} {t("practical.cancel")}
</div> </Button>
<button <Button
className="add_button" className="add_button"
disabled={status === QueryStatusEnum.LOADING || !formik.dirty || !values?.package_id} disabled={status === QueryStatusEnum.LOADING || !formik.dirty || !values?.package_id}
onClick={handleNext} onClick={handleNext}
@ -77,7 +76,7 @@ console.log(PackagesInfo);
<Spin /> <Spin />
</span> </span>
)} )}
</button> </Button>
</div> </div>
</div> </div>
); );

View File

@ -1,33 +1,23 @@
import { Col, Row } from "reactstrap";
import ValidationField from "../../../../Components/ValidationField/ValidationField"; import ValidationField from "../../../../Components/ValidationField/ValidationField";
import useFormatDataToSelect from "../../../../utils/useFormatDataToSelect";
import { useFormikContext } from "formik"; import { useFormikContext } from "formik";
import { useModalState } from "../../../../zustand/Modal"; import { useModalState } from "../../../../zustand/Modal";
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState"; import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { QueryStatusEnum } from "../../../../enums/QueryStatus"; import { QueryStatusEnum } from "../../../../enums/QueryStatus";
import { Divider, Spin } from "antd"; import { Button, Divider, Spin } from "antd";
import { MdCancel } from "react-icons/md"; import { MdCancel } from "react-icons/md";
import { useAddSales } from "../../../../api/sales";
import { useEffect } from "react";
const Form = ({status}:{status?:any}) => { const Form = () => {
const {values,setFieldValue} = useFormikContext<any>() const {values,setFieldValue} = useFormikContext<any>()
console.log(values?.currentModalIndex);
const { isOpen, setIsOpen } = useModalState((state) => state); const { isOpen, setIsOpen } = useModalState((state) => state);
const { setObjectToEdit,objectToEdit } = useObjectToEdit(); const { setObjectToEdit,objectToEdit } = useObjectToEdit();
const {t} = useTranslation(); const {t} = useTranslation();
const formik = useFormikContext();
const handleNext = ()=>{
setFieldValue( "currentModalIndex" , values?.currentModalIndex - 2 )
setIsOpen("");
}
const handleCancel = () => {
setIsOpen("");
setObjectToEdit({});
};
const {mutate,isSuccess,status} = useAddSales();
const coupon_id_object = objectToEdit?.data?.data?.packages.find((e:any)=>(e.id === values?.package_id))
const student_info = objectToEdit?.data?.data const student_info = objectToEdit?.data?.data
const PackagesInfo = student_info?.packages.map((info:any) => ({ const PackagesInfo = student_info?.packages.map((info:any) => ({
id: info?.id, id: info?.id,
@ -35,6 +25,34 @@ const Form = ({status}:{status?:any}) => {
})); }));
const handleNext = ()=>{
mutate({
package_id:values?.package_id,
student_id:objectToEdit?.data?.data?.student_id,
coupon_id:coupon_id_object?.coupon_id
});
}
const handleCancel = () => {
setObjectToEdit({});
setIsOpen("");
setFieldValue( "currentModalIndex" , values?.currentModalIndex - 2 )
};
useEffect(() => {
if(status === QueryStatusEnum.SUCCESS){
setIsOpen("");
setObjectToEdit({});
setFieldValue( "currentModalIndex" , values?.currentModalIndex - 2 )
}
if(values?.currentModalIndex >= 3){
setIsOpen("")
setObjectToEdit({})
setFieldValue( "currentModalIndex" , values?.currentModalIndex - 2 )
}
}, [isSuccess,values?.currentModalIndex])
return ( return (
values?.currentModalIndex == 2 && values?.currentModalIndex == 2 &&
@ -50,8 +68,8 @@ const Form = ({status}:{status?:any}) => {
<div className="info"> <div className="info">
<img src="/Image/faker_user.png" alt="" /> <img src="/Image/faker_user.png" alt="" />
<span> <span>
<h5>أنس محمد ياسر القلعجي</h5> <h5>{student_info?.first_name +" " + student_info?.last_name}</h5>
<h5>الصف: <p> بكالوريا / علمي</p></h5> <h5>{t("models.course")}: <p> {student_info?.grade_name}</p></h5>
</span> </span>
</div> </div>
<ValidationField <ValidationField
@ -61,15 +79,14 @@ const Form = ({status}:{status?:any}) => {
type="Select" type="Select"
option={PackagesInfo} option={PackagesInfo}
disabled disabled
allowClear={false} allowClear={false}
/> />
</div> </div>
{/* {values?.currentModalIndex} */}
<div className="buttons"> <div className="buttons">
<div className="back_button pointer" onClick={handleCancel}> <Button className="back_button pointer" onClick={handleCancel}>
{t("practical.cancel")} {t("practical.cancel")}
</div> </Button>
<button <Button
className="add_button" className="add_button"
disabled={status === QueryStatusEnum.LOADING} disabled={status === QueryStatusEnum.LOADING}
onClick={handleNext} onClick={handleNext}
@ -80,7 +97,7 @@ const Form = ({status}:{status?:any}) => {
<Spin /> <Spin />
</span> </span>
)} )}
</button> </Button>
</div> </div>
</div> </div>
); );

View File

@ -1,17 +1,17 @@
import { Col, Row } from "reactstrap"; import { Col, Row } from "reactstrap";
import ValidationField from "../../../../Components/ValidationField/ValidationField"; import ValidationField from "../../../../Components/ValidationField/ValidationField";
import useFormatDataToSelect from "../../../../utils/useFormatDataToSelect";
import { useFormikContext } from "formik"; import { useFormikContext } from "formik";
import { useModalState } from "../../../../zustand/Modal"; import { useModalState } from "../../../../zustand/Modal";
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState"; import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { QueryStatusEnum } from "../../../../enums/QueryStatus"; import { QueryStatusEnum } from "../../../../enums/QueryStatus";
import { Divider, Spin } from "antd"; import { Button, Divider, Spin } from "antd";
import { MdCancel } from "react-icons/md"; import { MdCancel } from "react-icons/md";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useGetStudentByPhone } from "../../../../api/sales"; import { useGetStudentByPhone } from "../../../../api/sales";
const Form = () => { const Form = () => {
const {values,setFieldValue} = useFormikContext<any>() const {values,setFieldValue} = useFormikContext<any>()
const [triggerApi, setTriggerApi] = useState(false) const [triggerApi, setTriggerApi] = useState(false)
const phoneNumber : number = values?.phone_number const phoneNumber : number = values?.phone_number
@ -21,7 +21,7 @@ const Form = () => {
const formik = useFormikContext(); const formik = useFormikContext();
const {data,isError,isSuccess,status} = useGetStudentByPhone({ const {data,isError,isSuccess,status} = useGetStudentByPhone({
phone_number:phoneNumber phone_number:phoneNumber,
},{ },{
enabled: triggerApi enabled: triggerApi
}); });
@ -30,30 +30,33 @@ const Form = () => {
if(values?.phone_number && phoneNumber.toString().length === 10){ if(values?.phone_number && phoneNumber.toString().length === 10){
setTriggerApi(true) setTriggerApi(true)
} }
// if(values?.currentModalIndex == 0 && phoneNumber.toString().length === 10){
// toast.error("phone number not found ")
// }
} }
console.log(status); // console.log(status);
console.log(isSuccess); // console.log(isSuccess);
// console.log(isError);
// console.log(data?.data);
// console.log(triggerApi);
const handleCancel = () => { const handleCancel = () => {
setIsOpen(""); setIsOpen("");
setObjectToEdit({}); setObjectToEdit({});
}; };
console.log(data?.data);
useEffect(() => { useEffect(() => {
if(!!data?.data?.phone_number){ if(!!data?.data?.phone_number){
setFieldValue( "currentModalIndex" , values?.currentModalIndex + 1 ) setFieldValue( "currentModalIndex" , values?.currentModalIndex + 1 )
setObjectToEdit({data}) setObjectToEdit({data})
setTriggerApi(false) setTriggerApi(false)
} }
else { else if(!data?.data){
setTriggerApi(false) setTriggerApi(false)
} }
}, [data?.data]) }, [data?.data,triggerApi])
return ( return (
@ -78,21 +81,21 @@ const Form = () => {
<Divider className="margin_auto"/> <Divider className="margin_auto"/>
</Col> </Col>
<div className="buttons"> <div className="buttons">
<div className="back_button pointer" onClick={handleCancel}> <Button className="back_button pointer" onClick={handleCancel}>
{t("practical.cancel")} {t("practical.cancel")}
</div> </Button>
<button <Button
className="add_button" className="add_button"
disabled={status === QueryStatusEnum.LOADING || !formik.dirty} disabled={status === QueryStatusEnum.LOADING || !formik.dirty || !values?.phone_number}
onClick={handleNext} onClick={handleNext}
> >
{t(`practical.search`)} {t(`practical.sale`)}
{status === QueryStatusEnum.LOADING && ( {status === QueryStatusEnum.LOADING && (
<span className="Spinier_Div"> <span className="Spinier_Div">
<Spin /> <Spin />
</span> </span>
)} )}
</button> </Button>
</div> </div>
</Row> </Row>
</div> </div>

View File

@ -1,26 +1,26 @@
import * as Yup from "yup"; import * as Yup from "yup";
import { formatDate } from "../../../../utils/formatDate";
// Function to get the initial values
export const getInitialValues = (objectToEdit: any): any => { export const getInitialValues = (objectToEdit: any): any => {
return { return {
id: objectToEdit?.id ?? null, id: objectToEdit?.id ?? null,
phone_number: objectToEdit?.phone_number ?? null, phone_number: objectToEdit?.phone_number ?? null,
currentModalIndex: 0, currentModalIndex: 0,
package_id:objectToEdit?.package_id ?? null package_id: objectToEdit?.package_id ?? null,
student_id: objectToEdit?.student_id ?? 0,
coupon_id: objectToEdit?.coupon_id ?? 1,
}; };
}; };
// Validation schema with Yup
export const getValidationSchema = () => { export const getValidationSchema = () => {
return Yup.object().shape({ return Yup.object().shape({
phone_number: Yup.string() phone_number: Yup.string()
.required("Phone number is required") .required("Phone number is required")
.length(10, "Phone number must be exactly 10 numbers") .length(10, "Phone number must be exactly 10 digits")
.matches(/^\d{10}$/, "Phone number must be a valid 10-number number"), .matches(/^\d{10}$/, "Phone number must be a valid 10-digit number"),
currentModalIndex: Yup.number().max(2) currentModalIndex: Yup.number().max(2),
});
};
export const getValidationSchemaForSale = () => {
return Yup.object().shape({
package_id: Yup.string().required("package_id is required")
}); });
}; };

View File

@ -4,14 +4,17 @@ import { useColumns } from "./useTableColumns";
import useSearchQuery from "../../../api/utils/useSearchQuery"; import useSearchQuery from "../../../api/utils/useSearchQuery";
import { useFilterState } from "../../../Components/Utils/Filter/FilterState"; import { useFilterState } from "../../../Components/Utils/Filter/FilterState";
import { useGetAllSales } from "../../../api/sales"; import { useGetAllSales } from "../../../api/sales";
import { formatDate } from "../../../utils/formatDate";
const App: React.FC = () => { const App: React.FC = () => {
const [searchQuery] = useSearchQuery("name"); const [searchQuery] = useSearchQuery("name");
const { filterState } = useFilterState(); const { filterState }:any = useFilterState();
const response = useGetAllSales({ const response = useGetAllSales({
name: searchQuery, name: searchQuery,
pagination: true, pagination: true,
...filterState, ...filterState,
activation_date:formatDate(filterState?.activation_date),
expiration_date:formatDate(filterState?.expiration_date),
}); });
return <DataTable response={response} useColumns={useColumns} />; return <DataTable response={response} useColumns={useColumns} />;

View File

@ -15,32 +15,38 @@ export const useColumns = () => {
}, },
{ {
title: t("columns.student_full_name"), title: t("columns.student_full_name"),
key: "student_full_name",
align: "center",
render: (row) => {
return row?.student?.first_name +" "+ row?.student?.last_name;
},
},
{
title: t("columns.grade"),
render: (row) => {
return row?.package?.name;
},
key: "package",
align: "center",
},
{
title: t("columns.paid_price"),
render: (row) => {
return row?.package?.price;
},
key: "price",
align: "center",
},
{
title: t("columns.activation_date"),
dataIndex: "activation_date", dataIndex: "activation_date",
key: "activation_date", key: "activation_date",
align: "center", align: "center",
}, },
{ {
title: t("columns.grade"), title: t("columns.expiration_date"),
dataIndex: "grade", dataIndex: "expiration_date",
key: "grade", key: "expiration_date",
align: "center",
},
{
title: t("columns.package"),
dataIndex: "package",
key: "package",
align: "center",
},
{
title: t("columns.amount_paid"),
dataIndex: "amount_paid",
key: "amount_paid",
align: "center",
},
{
title: t("columns.sale_date"),
dataIndex: "sale_date",
key: "sale_date",
align: "center", align: "center",
}, },
]; ];

View File

@ -65,24 +65,6 @@ export const useColumns = () => {
return row?.student?.sex; return row?.student?.sex;
}, },
}, },
// {
// title: t("columns.procedure"),
// key: "actions",
// align: "center",
// width: "25vw",
// render: (_text, record, index) => {
// return (
// <ActionButtons
// // canDelete={canEditUser}
// canEdit={canDeleteUser}
// index={index}
// onDelete={() => handelDelete(record)}
// onEdit={() => handleEdit(record)}
// />
// );
// },
// },
]; ];
return columns; return columns;

View File

@ -31,6 +31,8 @@ const Manager = React.lazy(() => import("./Pages/Admin/Manager/Page"));
const AddManager = React.lazy(() => import("./Pages/Admin/Manager/Add/Page")); const AddManager = React.lazy(() => import("./Pages/Admin/Manager/Add/Page"));
const EditManager = React.lazy(() => import("./Pages/Admin/Manager/Edit/Page")); const EditManager = React.lazy(() => import("./Pages/Admin/Manager/Edit/Page"));
const FinancialCollection = React.lazy(() => import("./Pages/Admin/FinancialCollection/Page"));
const ReSeller = React.lazy(() => import("./Pages/Admin/Reseller/Page")); const ReSeller = React.lazy(() => import("./Pages/Admin/Reseller/Page"));
const ShowReSeller = React.lazy(() => import("./Pages/Admin/Reseller/show/Page")); const ShowReSeller = React.lazy(() => import("./Pages/Admin/Reseller/show/Page"));
@ -52,6 +54,7 @@ const Param = React.lazy(() => import("./Pages/Admin/Param/Page"));
/// RESELLER /// /// RESELLER ///
const Sales = React.lazy(() => import("./Pages/ReSeller/Sales/Page")); const Sales = React.lazy(() => import("./Pages/ReSeller/Sales/Page"));
const Collections = React.lazy(() => import("./Pages/ReSeller/Collections/Page")); const Collections = React.lazy(() => import("./Pages/ReSeller/Collections/Page"));
const ShowCollection = React.lazy(() => import("./Pages/ReSeller/Collections/Show/Page"));
const NotificationReSeller = React.lazy(() => import("./Pages/ReSeller/Notifications/Page")); const NotificationReSeller = React.lazy(() => import("./Pages/ReSeller/Notifications/Page"));
const ProfileReSeller = React.lazy(() => import("./Pages/ReSeller/Profile/Page")); const ProfileReSeller = React.lazy(() => import("./Pages/ReSeller/Profile/Page"));
@ -192,7 +195,16 @@ export const menuItems: TMenuItem[] = [
abilities_value: ABILITIES_VALUES_ENUM.INDEX, abilities_value: ABILITIES_VALUES_ENUM.INDEX,
prevPath: 0, prevPath: 0,
}, },
{
header: "page_header.financial_collection",
element: <FinancialCollection />,
icon: <FaMoneyBill />,
text: "sidebar.financial_collection",
path: `/${ABILITIES_ENUM?.Financial_Collection}`,
abilities: ABILITIES_ENUM?.Financial_Collection,
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
prevPath: 0,
},
/// RESELLER ///// /// RESELLER /////
{ {
@ -217,17 +229,17 @@ export const menuItems: TMenuItem[] = [
prevPath: 0, prevPath: 0,
type: UserTypeEnum.RE_SELLER, type: UserTypeEnum.RE_SELLER,
}, },
{ // {
header: "page_header.profile", // header: "page_header.profile",
element: <ProfileReSeller />, // element: <ProfileReSeller />,
icon: <CgProfile />, // icon: <CgProfile />,
text: "sidebar.profile", // text: "sidebar.profile",
path: `/${ABILITIES_ENUM?.PROFILE}`, // path: `/${ABILITIES_ENUM?.PROFILE}`,
abilities: ABILITIES_ENUM?.Profile_RE_SELLER, // abilities: ABILITIES_ENUM?.Profile_RE_SELLER,
abilities_value: ABILITIES_VALUES_ENUM.INDEX, // abilities_value: ABILITIES_VALUES_ENUM.INDEX,
prevPath: 0, // prevPath: 0,
type: UserTypeEnum.RE_SELLER, // type: UserTypeEnum.RE_SELLER,
}, // },
]; ];
@ -380,7 +392,16 @@ export const CrudRoute: TCrudRoute[] = [
abilities_value: ABILITIES_VALUES_ENUM.INDEX, abilities_value: ABILITIES_VALUES_ENUM.INDEX,
prevPath: 1, prevPath: 1,
}, },
{
header: "page_header.collection",
element: <ShowCollection />,
path: `/${ABILITIES_ENUM?.Collections}/:${ParamsEnum?.Collection_ID}`,
abilities: ABILITIES_ENUM?.Collections,
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
prevPath: 0,
type:UserTypeEnum.RE_SELLER
},
]; ];
export const AppRoutes: Record<string, string> = Object.fromEntries( export const AppRoutes: Record<string, string> = Object.fromEntries(

View File

@ -43,7 +43,9 @@
font-size: 20px; font-size: 20px;
} }
} }
.main_modal{
}
.add_button { .add_button {
outline: none; outline: none;
border: none; border: none;
@ -64,8 +66,12 @@
} }
transition: .4s ease-in-out; transition: .4s ease-in-out;
&:focus{
// display: none !important;
}
&:hover{ &:hover{
scale: 1.1; scale: 1.04;
background: var(--primary) !important;
color: var(--white) !important;
} }
} }

View File

@ -93,6 +93,10 @@
padding: 20px 10px !important; padding: 20px 10px !important;
} }
.filter_modal_add_button{
padding: 20.8px 10px !important;
}
@media screen and (max-width: 800px) { @media screen and (max-width: 800px) {
.filter_modal_add_button, .filter_modal_add_button,

View File

@ -94,7 +94,6 @@
color: var(--borderColor); color: var(--borderColor);
} }
svg { svg {
// width: 20px;
border-radius: 5px; border-radius: 5px;
padding: 4px; padding: 4px;
color: var(--borderColor); color: var(--borderColor);
@ -121,7 +120,6 @@
justify-content: start; justify-content: start;
background: inherit; background: inherit;
font-size: 20px; font-size: 20px;
// height: 2.5vw;
width: 80%; width: 80%;
font-weight: bold; font-weight: bold;
margin-inline: auto; margin-inline: auto;
@ -152,7 +150,6 @@
} }
} }
.active { .active {
// transform: translateX(-1vw);
color: var(--text) !important; color: var(--text) !important;
background-color: var(--bg); background-color: var(--bg);
font-weight: bold; font-weight: bold;
@ -162,8 +159,6 @@
} }
i { i {
// width: 1.5vw;
// height: 1.5vw;
border-radius: 5px; border-radius: 5px;
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -209,6 +204,11 @@
.side_bar_links { .side_bar_links {
display: flex; display: flex;
align-items: center; align-items: center;
.DropDownLink{
.DropDownIcon{
transform: translate(-1.4vw,10px);
}
}
.active { .active {
background: inherit !important; background: inherit !important;
} }
@ -240,7 +240,7 @@
div { div {
@include Flex; @include Flex;
width: 100%; width: 100%;
margin-block: 12px; margin-block: 0px;
svg { svg {
height: 36px; height: 36px;
padding: 7px; padding: 7px;

View File

@ -4,7 +4,6 @@
gap: 5px; gap: 5px;
.collection_info_card { .collection_info_card {
display: flex; display: flex;
justify-content: center;
flex-direction: column; flex-direction: column;
width: 15vw; width: 15vw;
padding: 1.2vw 1.2vw; padding: 1.2vw 1.2vw;

View File

@ -1,7 +1,7 @@
import useGetQuery from "./helper/useGetQuery"; import useGetQuery from "./helper/useGetQuery";
const API = { const API = {
GET: "/collections", GET: "/resellers/financialCollection",
}; };
const KEY = "collections"; const KEY = "collections";

View File

@ -0,0 +1,20 @@
import useAddMutation from "./helper/useAddMutation";
import useDeleteMutation from "./helper/useDeleteMutation";
import useGetQuery from "./helper/useGetQuery";
import useUpdateMutation from "./helper/useUpdateMutation";
const API = {
GET: "/financialCollection",
ADD: "/financialCollection",
DELETE: "/financialCollection",
UPDATE: "/financialCollection",
};
const KEY = "financialCollection";
export const useGetAllFinancialCollection = (params?: any, options?: any) =>
useGetQuery(KEY, API.GET, params, options);
export const useAddFinancialCollection = () => useAddMutation(KEY, API.ADD);
export const useUpdateFinancialCollection = (params?: any) => useUpdateMutation(KEY, API.GET);
export const useDeleteFinancialCollection = (params?: any) =>
useDeleteMutation(KEY, API.DELETE);

View File

@ -3,15 +3,18 @@ import useGetQuery from "./helper/useGetQuery";
const API = { const API = {
GET: "/resellers/studentPackage", GET: "/resellers/studentPackage",
ADD: "/resellers/studentPackage", ADD: "/resellers/studentPackage/purchase",
GET_BY_PHONE: "/resellers/studentPackage/student", GET_BY_PHONE: "/resellers/studentPackage/student",
GET_SUMMERY: "/resellers/studentPackage/summery", GET_SUMMERY: "/resellers/studentPackage/summery",
}; };
const KEY = "sales"; const KEY = "sales";
const KEY2 = "Sale_Student_Data";
const KEY3 = "collection_summery";
export const useGetAllSales = (params?: any, options?: any) =>useGetQuery(KEY, API.GET, params, options); export const useGetAllSales = (params?: any, options?: any) =>useGetQuery(KEY, API.GET, params, options);
export const useAddSales = () => useAddMutation(KEY, API.ADD); export const useAddSales = () => useAddMutation(KEY, API.ADD);
export const useGetStudentByPhone = (params?: any, options?: any) => useGetQuery(KEY, API.GET_BY_PHONE, params, options); export const useGetStudentByPhone = (params?: any, options?: any) => useGetQuery(KEY2, API.GET_BY_PHONE, params, options);
export const useGetSummery = () => useGetQuery(KEY, API.GET_SUMMERY); export const useGetSummery = () => useGetQuery(KEY3, API.GET_SUMMERY);

View File

@ -237,4 +237,10 @@ export enum ModalEnum {
/// email /// email
Email_EDIT = "Email.edit", Email_EDIT = "Email.edit",
///financial_collection
Financial_Collection_EDIT = "Financial_Collection.edit",
Financial_Collection_ADD = "Financial_Collection.add",
Financial_Collection_DELETE = "Financial_Collection.delete",
} }

View File

@ -59,8 +59,9 @@ export enum ABILITIES_ENUM {
SETTING = "setting", SETTING = "setting",
Email = "email", Email = "email",
Phone = "phone", Phone = "phone",
CITY = "city", CITY = "city",
AREA = "area" AREA = "area",
Financial_Collection = "financial_collection"
//// ////
} }

View File

@ -14,4 +14,5 @@ export enum ParamsEnum {
RE_SELLER_ID = "re_seller_id", RE_SELLER_ID = "re_seller_id",
ROLE_ID = "role_id", ROLE_ID = "role_id",
CITY_ID = "city_id", CITY_ID = "city_id",
Collection_ID = "collection_id"
} }

View File

@ -149,7 +149,8 @@
"past_your_MMl_text":"ضع نص MMl الخاص بك", "past_your_MMl_text":"ضع نص MMl الخاص بك",
"add_MML":"إضافة MML", "add_MML":"إضافة MML",
"show_preview":"عرض المعاينة", "show_preview":"عرض المعاينة",
"show_MMl":" MML عرض" "show_MMl":" MML عرض",
"financial_collection":"التحصيلات"
}, },
"columns": { "columns": {
"id": "الرقم التعريفي", "id": "الرقم التعريفي",
@ -233,7 +234,8 @@
"delete":"حذف", "delete":"حذف",
"read":"قراءة", "read":"قراءة",
"managers":"مدراء", "managers":"مدراء",
"show":"عرض" "show":"عرض",
"paid_price":"المبلغ المدفوع"
}, },
"practical": { "practical": {
"to_confirm_deletion_please_re_enter": "لتأكيد الحذف، يرجى إعادة الإدخال", "to_confirm_deletion_please_re_enter": "لتأكيد الحذف، يرجى إعادة الإدخال",
@ -313,7 +315,9 @@
"Map":"الخريطة", "Map":"الخريطة",
"Show":"عرض", "Show":"عرض",
"Hide":"اخفاء", "Hide":"اخفاء",
"sale":"بيع" "sale":"بيع",
"financial_collection":"التحصيلات",
"show_collection":"حصيلة"
}, },
"Table": { "Table": {
"header": "", "header": "",
@ -404,7 +408,9 @@
"Area":"المنطقة", "Area":"المنطقة",
"City":"مدينة", "City":"مدينة",
"add_sales":"إضافة عملية بيع", "add_sales":"إضافة عملية بيع",
"are_you_sure_about_sale":"هل أنت متأكد من عملية البيع ؟" "are_you_sure_about_sale":"هل أنت متأكد من عملية البيع ؟",
"financial_collection":"التحصيلات",
"show_collection":"حصيلة"
}, },
"education_class_actions": { "education_class_actions": {
"Student_Records": "سجلات الطلاب", "Student_Records": "سجلات الطلاب",
@ -538,7 +544,11 @@
"contact_number2":"رقم الهاتف الإضافي", "contact_number2":"رقم الهاتف الإضافي",
"lat":"الطول", "lat":"الطول",
"lng":"العرض", "lng":"العرض",
"choose":"حدد" "choose":"حدد",
"amount":"مبلغ",
"reseller":"البائعين",
"activation_date":"تاريخ التنشيط",
"expiration_date":"تاريخ الالغاء"
}, },
"select": { "select": {
"enums": { "enums": {
@ -875,7 +885,8 @@
"sales":"المبيعات", "sales":"المبيعات",
"collections": "التحصيلات", "collections": "التحصيلات",
"Area":"المنطقة", "Area":"المنطقة",
"city":"مدينة" "city":"مدينة",
"financial_collection":"التحصيلات"
}, },
"message": { "message": {
"some_thing_went_wrong": "حدث خطأ ما", "some_thing_went_wrong": "حدث خطأ ما",
@ -924,7 +935,9 @@
"City":"مدينة", "City":"مدينة",
"Area":"المنطقة", "Area":"المنطقة",
"setting":"الإعدادات", "setting":"الإعدادات",
"edit_reseller":"تعديل البائع" "edit_reseller":"تعديل البائع",
"financial_collection":"التحصيلات",
"show_collection":"حصيلة"
}, },
"page_header": { "page_header": {
"home": "لوحة القيادة", "home": "لوحة القيادة",
@ -973,7 +986,9 @@
"sales":"المبيعات", "sales":"المبيعات",
"setting":"الإعدادات", "setting":"الإعدادات",
"City":"مدينة", "City":"مدينة",
"Area":"المنطقة" "Area":"المنطقة",
"financial_collection":"التحصيلات",
"show_collection":"حصيلة"
}, },
"table": { "table": {
"student": "قائمة الطلاب", "student": "قائمة الطلاب",
@ -992,7 +1007,9 @@
"City":"مدينة", "City":"مدينة",
"notification":"الاشعارات", "notification":"الاشعارات",
"upload_your_photo_and_personal_data_here":"قم بتحميل صورتك وبياناتك الشخصية هنا", "upload_your_photo_and_personal_data_here":"قم بتحميل صورتك وبياناتك الشخصية هنا",
"get_notified_of_whats_happening_now_you_can_turn_it_off_at_any_time":"احصل على إشعار بما يحدث الآن ، يمكنك إيقاف تشغيله في أي وقت" "get_notified_of_whats_happening_now_you_can_turn_it_off_at_any_time":"احصل على إشعار بما يحدث الآن ، يمكنك إيقاف تشغيله في أي وقت",
"financial_collection":"التحصيلات",
"show_collection":"حصيلة"
}, },
"card" : { "card" : {
"residual":"المتبقي", "residual":"المتبقي",

View File

@ -367,7 +367,7 @@ export type Sales = {
export type Collection = { export type Collection = {
id: number; id: number;
student: student; amount: student;
expiration_date: string; date: string;
activation_date: string; description: string;
}; };

View File

@ -767,7 +767,7 @@ export const canShowQuestionBank = hasAbility(
); );
/// User /// sales
export const canAddSales = hasAbility( export const canAddSales = hasAbility(
ABILITIES_ENUM.Sales, ABILITIES_ENUM.Sales,
@ -797,3 +797,26 @@ export const canEditEmail = hasAbility(
ABILITIES_ENUM.Email, ABILITIES_ENUM.Email,
ABILITIES_VALUES_ENUM.UPDATE, ABILITIES_VALUES_ENUM.UPDATE,
); );
/// financial_collection
export const canAddFinancial_Collection = hasAbility(
ABILITIES_ENUM.Financial_Collection,
ABILITIES_VALUES_ENUM.STORE,
);
export const canEditFinancial_Collection = hasAbility(
ABILITIES_ENUM.Financial_Collection,
ABILITIES_VALUES_ENUM.UPDATE,
);
export const canDeleteFinancial_Collection = hasAbility(
ABILITIES_ENUM.Financial_Collection,
ABILITIES_VALUES_ENUM.DELETE,
);
// collection reseller
export const canShowCollection = hasAbility(
ABILITIES_ENUM.Collections,
ABILITIES_VALUES_ENUM.SHOW,
);