diff --git a/README.md b/README.md index 62b5dbd..4b405cb 100644 --- a/README.md +++ b/README.md @@ -7,5 +7,5 @@ ```bash git clone https://repos.point-dev.net/Karimaldeen/hijabi-dashboard.git cd hijabi-dashboard - npm install +npm install npm start diff --git a/src/Components/Karimalden/KarimField.scss b/src/Components/Karimalden/KarimField.scss index b9a44c3..864c255 100644 --- a/src/Components/Karimalden/KarimField.scss +++ b/src/Components/Karimalden/KarimField.scss @@ -69,4 +69,10 @@ input:-webkit-autofill:focus { /* Remove autofill background color on hover */ input:-webkit-autofill:hover { -webkit-box-shadow: 0 0 0 1000px white inset !important; /* Change the color to your desired background color */ -} \ No newline at end of file +} + + +.ant-upload-list .ant-upload-list-item{ + height:78px !important; + } + \ No newline at end of file diff --git a/src/Components/Karimalden/View/File.tsx b/src/Components/Karimalden/View/File.tsx index d33b79f..599760c 100644 --- a/src/Components/Karimalden/View/File.tsx +++ b/src/Components/Karimalden/View/File.tsx @@ -41,6 +41,7 @@ const File = ({ name, label, onChange, isDisabled,placholder,className, props }: customRequest={customRequest} className={`${className} w-100`} + > diff --git a/src/Layout/Dashboard/FormPage.tsx b/src/Layout/Dashboard/FormPage.tsx index 5804310..befc606 100644 --- a/src/Layout/Dashboard/FormPage.tsx +++ b/src/Layout/Dashboard/FormPage.tsx @@ -15,7 +15,7 @@ interface FormPageProps { children: ReactNode; } -const FormPage: React.FC = ({ children, handleSubmit, initialValues, validationSchema, title = "Add New Item" }) => { +const FormPage: React.FC = ({ children, handleSubmit, initialValues, validationSchema, title = "Edit Item" }) => { return ( <>

{title}

diff --git a/src/Pages/Categories copy/AddCouponModal.tsx b/src/Pages/Categories copy/AddCouponModal.tsx new file mode 100644 index 0000000..1e8662c --- /dev/null +++ b/src/Pages/Categories copy/AddCouponModal.tsx @@ -0,0 +1,43 @@ + + +import React from 'react' +import LayoutModal from '../../Layout/Dashboard/LayoutModal' +import AddForm from './AddForm' +import { useAddCoupon } from '../../api/Coupon' +import { getDataToSend, getInitialValues, getValidationSchema } from './formUtil' +import { QueryStatusEnum } from '../../config/QueryStatus' +import { useTranslation } from 'react-i18next' + +function AddCouponModal() { + + + const [t] = useTranslation() + const {mutate , status} = useAddCoupon() + const handelSubmit = (values:any )=>{ + values['name'] = { + "en" : values.name_en, + "ar" : values.name_ar, + "de" : values.name_de, + } + console.log(values); + mutate(values) + + } + return ( + + + + + ) +} + +export default AddCouponModal + diff --git a/src/Pages/Categories/FormCoupon.tsx b/src/Pages/Categories copy/AddForm.tsx similarity index 55% rename from src/Pages/Categories/FormCoupon.tsx rename to src/Pages/Categories copy/AddForm.tsx index 166bd28..2d4036d 100644 --- a/src/Pages/Categories/FormCoupon.tsx +++ b/src/Pages/Categories copy/AddForm.tsx @@ -6,19 +6,25 @@ import { FakeSelectData } from '../../Layout/app/Const'; import { useFormikContext } from 'formik'; import { DatePicker } from 'antd'; +import { useGetCoupon } from '../../api/Coupon'; -function FormCoupon() { +function AddForm() { const formik = useFormikContext(); - + const {data } = useGetCoupon() return ( - + + + + - + + + @@ -26,6 +32,6 @@ function FormCoupon() { ) } -export default FormCoupon +export default AddForm diff --git a/src/Pages/Categories copy/CouponPage.tsx b/src/Pages/Categories copy/CouponPage.tsx new file mode 100644 index 0000000..45a0235 --- /dev/null +++ b/src/Pages/Categories copy/CouponPage.tsx @@ -0,0 +1,40 @@ + +import React from 'react' +import DashBody from '../../Layout/Dashboard/DashBody' +import DashHeader from '../../Layout/Dashboard/DashHeader' +import LyTable from '../../Layout/Dashboard/LyTable' +import useTableColumns from './useTableColumns' +import { useGetCoupon} from '../../api/Coupon' + +import { useTranslation } from 'react-i18next' +import AddCouponModal from './AddCouponModal' +import { QueryStatusEnum } from '../../config/QueryStatus' +// import * as XLSX from 'ts-xlsx'; + +function CouponPage() { + + const column =useTableColumns() + const {data ,status } = useGetCoupon() + const {t} = useTranslation(); + + + return ( + + + + + + + + ) +} + +export default CouponPage + diff --git a/src/Pages/Categories copy/EditCoupon/EditForm.tsx b/src/Pages/Categories copy/EditCoupon/EditForm.tsx new file mode 100644 index 0000000..690cbe2 --- /dev/null +++ b/src/Pages/Categories copy/EditCoupon/EditForm.tsx @@ -0,0 +1,23 @@ +import React from 'react' +import { Col, Row } from "reactstrap"; +import KarimField from '../../../Components/Karimalden/KarimField'; + +const CreateForm = () => { + + + return ( + + + + + + + + + + + + ) +} + +export default CreateForm \ No newline at end of file diff --git a/src/Pages/Categories copy/EditCoupon/Page.tsx b/src/Pages/Categories copy/EditCoupon/Page.tsx new file mode 100644 index 0000000..14de388 --- /dev/null +++ b/src/Pages/Categories copy/EditCoupon/Page.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import FormPage from '../../../Layout/Dashboard/FormPage'; +import EditForm from './EditForm'; +import { getInitialValues, getValidationSchema } from '../formUtil'; +import { useParams } from 'react-router-dom'; +import KarimSpinner from '../../../Components/Karimalden/Ui/KarimSpinner'; +import { useAddCoupon, useGetOneCoupon } from '../../../api/Coupon'; + +const EditPage = () => { + + const { id } = useParams() + const { data,isLoading } = useGetOneCoupon({id}) + const {mutate} = useAddCoupon() + const handleSubmit = (values: any) => { + const newdata = {} as any; + + for (const key in data) { + if (values[key] !== data[key]) { + newdata[key] = values[key]; + } + } + + return mutate(newdata); + }; + + return ( + + handleSubmit(values)} + initialValues={getInitialValues(data)} + validationSchema={getValidationSchema} + title='Edit Coupon' + > + + + + + ); +}; + +export default EditPage; diff --git a/src/Pages/Categories copy/formUtil.ts b/src/Pages/Categories copy/formUtil.ts new file mode 100644 index 0000000..7d73b6c --- /dev/null +++ b/src/Pages/Categories copy/formUtil.ts @@ -0,0 +1,65 @@ + +import * as Yup from "yup"; +import { buildFormData } from "../../api/helper/buildFormData"; + +interface formUtilCommon { + number:number, + value:number +} + +interface ObjectToEdit extends formUtilCommon { + + id?:number, + +} + +interface InitialValues extends ObjectToEdit { + +} +interface ValidateSchema extends formUtilCommon{ + +} +export const getInitialValues = (objectToEdit: any | null = null): any => { + return { + id: objectToEdit?.id ?? 0, + name: "", + name_ar: objectToEdit?.name?.ar ?? '', + name_en: objectToEdit?.name?.en ?? '', + name_de: objectToEdit?.name?.de ?? '', + parent_id: objectToEdit?.parent_id ?? 1, + photo: objectToEdit?.photo ?? '', + }; +}; + + +export const getValidationSchema = (editMode: boolean = false): Yup.Schema => { + // Validate input + return Yup.object().shape({ + name : Yup.string().required('Required'), + name_ar: Yup.string().required('Required'), + name_en: Yup.string().required('Required'), + name_de: Yup.string().required('Required'), + parent_id: Yup.string().required('Required'), + photo: Yup.string().required('Required'), + }); +}; + + +export const getDataToSend = (values: any): FormData => { + const data = { ...values }; + + + const formData = new FormData(); + buildFormData(formData, data); + return formData; +}; + +export const ChangeDataToPrint = (data:any)=>{ + + let new_array = data + for(let i =0 ; i { + const [t] = useTranslation(); + const deleteMutation = useDeleteCoupon() + const navigate = useNavigate() + return useMemo( + () => [ + + { + name: t("name"), + sortable: false, + center: "true", + cell: (row:any) => row?.name + }, + { + name: t("image"), + sortable: false, + center: "true", + cell: (row:any) => + }, + { + name: t("parent_id"), + sortable: false, + center: "true", + cell: (row:any) => row?.parent_id + }, + { + name: t("product_count"), + sortable: false, + center: "true", + cell: (row:any) => row?.product_count + }, + { + name: "#", + sortable: false, + center: true, + cell: (row:any) => ( + navigate(`/Coupon/${row.id}`) } + showView={false} + onDelete={() => deleteMutation.mutate({ id: row.id })} + /> + ), + }, + // { + // name: t("status"), + // sortable: false, + // center: "true", + // cell: (row:any) => { + + // return( + //

+ // { + // !row.deleted_at ? t('available') : t('unavailable') + + // } + //

+ // ) + // } + // }, + + ], + [t] + ); +}; + +export default useTableColumns; + diff --git a/src/Pages/Categories/AddCategoriesModal.tsx b/src/Pages/Categories/AddCategoriesModal.tsx index 6b2f5d6..08cdbe1 100644 --- a/src/Pages/Categories/AddCategoriesModal.tsx +++ b/src/Pages/Categories/AddCategoriesModal.tsx @@ -2,7 +2,7 @@ import React from 'react' import LayoutModal from '../../Layout/Dashboard/LayoutModal' -import FormCategories from './FormCoupon' +import AddForm from './AddForm' import { useAddCategories } from '../../api/Categories' import { getDataToSend, getInitialValues, getValidationSchema } from './formUtil' import { QueryStatusEnum } from '../../config/QueryStatus' @@ -14,11 +14,14 @@ function AddCategoriesModal() { const [t] = useTranslation() const {mutate , status} = useAddCategories() const handelSubmit = (values:any )=>{ + values['name'] = { + "en" : values.name_en, + "ar" : values.name_ar, + "de" : values.name_de, + } + console.log(values); + mutate(values) - const dataToSend = getDataToSend(values) - - mutate(dataToSend) - // Submit Value } return ( - + ) } diff --git a/src/Pages/Categories/AddForm.tsx b/src/Pages/Categories/AddForm.tsx new file mode 100644 index 0000000..7dc0f6f --- /dev/null +++ b/src/Pages/Categories/AddForm.tsx @@ -0,0 +1,37 @@ + +import React from 'react' +import { Col, Row } from 'reactstrap'; +import KarimField from '../../Components/Karimalden/KarimField'; +import { FakeSelectData } from '../../Layout/app/Const'; +import { useFormikContext } from 'formik'; + +import { DatePicker } from 'antd'; +import { useGetCategories } from '../../api/Categories'; + +function AddForm() { + const formik = useFormikContext(); + const {data } = useGetCategories() + + + return ( + + + + + + + + + + + + + + + + ) +} + +export default AddForm + + diff --git a/src/Pages/Categories/EditCategories/EditForm.tsx b/src/Pages/Categories/EditCategories/EditForm.tsx index 5657fd6..690cbe2 100644 --- a/src/Pages/Categories/EditCategories/EditForm.tsx +++ b/src/Pages/Categories/EditCategories/EditForm.tsx @@ -9,13 +9,12 @@ const CreateForm = () => { - - - + + - - + + ) diff --git a/src/Pages/Categories/EditCategories/Page.tsx b/src/Pages/Categories/EditCategories/Page.tsx index 699290d..c883658 100644 --- a/src/Pages/Categories/EditCategories/Page.tsx +++ b/src/Pages/Categories/EditCategories/Page.tsx @@ -1,5 +1,4 @@ import React from 'react'; - import FormPage from '../../../Layout/Dashboard/FormPage'; import EditForm from './EditForm'; import { getInitialValues, getValidationSchema } from '../formUtil'; @@ -12,7 +11,6 @@ const EditPage = () => { const { id } = useParams() const { data,isLoading } = useGetOneCategories({id}) const {mutate} = useAddCategories() - const handleSubmit = (values: any) => { const newdata = {} as any; @@ -31,6 +29,7 @@ const EditPage = () => { handleSubmit={(values: any) => handleSubmit(values)} initialValues={getInitialValues(data)} validationSchema={getValidationSchema} + title='Edit Categories' > diff --git a/src/Pages/Categories/formUtil.ts b/src/Pages/Categories/formUtil.ts index b716caf..7d73b6c 100644 --- a/src/Pages/Categories/formUtil.ts +++ b/src/Pages/Categories/formUtil.ts @@ -19,27 +19,32 @@ interface InitialValues extends ObjectToEdit { interface ValidateSchema extends formUtilCommon{ } - -export const getInitialValues = (objectToEdit: ObjectToEdit | null = null): InitialValues => { - - +export const getInitialValues = (objectToEdit: any | null = null): any => { return { - id:objectToEdit?.id?? 0 , - number:objectToEdit?.number ?? 0, - value:objectToEdit?.value?? 0 - } - - + id: objectToEdit?.id ?? 0, + name: "", + name_ar: objectToEdit?.name?.ar ?? '', + name_en: objectToEdit?.name?.en ?? '', + name_de: objectToEdit?.name?.de ?? '', + parent_id: objectToEdit?.parent_id ?? 1, + photo: objectToEdit?.photo ?? '', + }; }; -export const getValidationSchema = (editMode: boolean = false): Yup.Schema => { - // validate input + +export const getValidationSchema = (editMode: boolean = false): Yup.Schema => { + // Validate input return Yup.object().shape({ - number:Yup.number().required('required'), - value:Yup.number().required("required") + name : Yup.string().required('Required'), + name_ar: Yup.string().required('Required'), + name_en: Yup.string().required('Required'), + name_de: Yup.string().required('Required'), + parent_id: Yup.string().required('Required'), + photo: Yup.string().required('Required'), }); }; + export const getDataToSend = (values: any): FormData => { const data = { ...values }; diff --git a/src/Routes.tsx b/src/Routes.tsx index 8c6da2f..6f5a41e 100644 --- a/src/Routes.tsx +++ b/src/Routes.tsx @@ -2,28 +2,17 @@ import { ReactNode, lazy } from "react"; // Icons Import -import { Home } from "react-feather"; -import { AiFillQuestionCircle, AiFillStar} from "react-icons/ai" -import {FaUserFriends , FaUser, FaHome, FaSadCry } from "react-icons/fa" -import { MdPrivacyTip } from "react-icons/md"; -import {DiDatabase} from "react-icons/di" -import { FiMail } from "react-icons/fi"; -import {CgUnavailable} from "react-icons/cg" -import {BsCode, BsInfoCircle} from "react-icons/bs" -import {AiOutlineTransaction ,AiFillSetting ,AiFillGift} from "react-icons/ai" -import { IoIosNotificationsOutline, IoIosPaper, } from "react-icons/io"; -import { BiCategory, BiLockAlt } from "react-icons/bi"; -import { RiCouponFill } from "react-icons/ri"; -import { IoPersonAddSharp } from "react-icons/io5"; -import { MdOutlineManageAccounts } from "react-icons/md"; -import { TbBrandSocketIo } from "react-icons/tb"; -import { BsPersonFillAdd } from "react-icons/bs"; +import { FaUser, FaHome, FaSadCry } from "react-icons/fa" + // Pages Import import HomePage from "./Pages/Home/HomePage"; import CategoriesPage from "./Pages/Categories/CategoriesPage"; -import Page from "./Pages/Categories/EditCategories/Page"; +import Page from "./Pages/Categories/EditCategories/Page"; +import Page from "./Pages/"; + +import CouponPage from "./Pages/Categories copy/CouponPage"; interface RoutesLinksType { @@ -53,6 +42,12 @@ export const RoutesLinks: RoutesLinksType[] = [ href: "/categories", }, + { + name: "Coupon", + element: , + icon: , + href: "/Coupon", + }, /////////////// hidden route @@ -60,5 +55,10 @@ export const RoutesLinks: RoutesLinksType[] = [ href: "/categories/:id", element: , hidden:true + }, + { + href: "/coupon/:id", + element: , + hidden:true } ] \ No newline at end of file diff --git a/src/api/Categories.ts b/src/api/Categories.ts index b75e7e3..1485af0 100644 --- a/src/api/Categories.ts +++ b/src/api/Categories.ts @@ -15,6 +15,7 @@ const API = { }; const KEY = "CATEGORIES" + export const useGetCategories = (params?:any) => useGetQueryPagination(KEY, API.GET_ALL,params); export const useGetOneCategories = (params?:any) => useGetOneQuery(KEY, API.GET_ALL,params); diff --git a/src/api/Coupon.ts b/src/api/Coupon.ts new file mode 100644 index 0000000..1a070ce --- /dev/null +++ b/src/api/Coupon.ts @@ -0,0 +1,25 @@ + +import useGetQueryPagination from "./helper/ueGetPagination"; +import useAddMutation from "./helper/useAddMutation" +import useDeleteMutation from "./helper/useDeleteMutation" +import useGetOneQuery from "./helper/useGetOneQuery"; +import useGetQuery from "./helper/useGetQuery" +import useUpdateMutation from "./helper/useUpdateMutation"; + +const API = { + ADD: `coupon`, + GET_ALL: `coupon`, + DELETE: `coupon`, + UPDATE: `coupon`, + +}; +const KEY = "COUPON" + + +export const useGetCoupon = (params?:any) => useGetQueryPagination(KEY, API.GET_ALL,params); +export const useGetOneCoupon = (params?:any) => useGetOneQuery(KEY, API.GET_ALL,params); + +export const useAddCoupon = () => useAddMutation(KEY, API.ADD); +export const useUpdateCoupon = () => useUpdateMutation(KEY, API.UPDATE); + +export const useDeleteCoupon = () =>useDeleteMutation(KEY, API.DELETE); diff --git a/src/api/helper/useAddMutation.ts b/src/api/helper/useAddMutation.ts index 3e33e5b..aafaa05 100644 --- a/src/api/helper/useAddMutation.ts +++ b/src/api/helper/useAddMutation.ts @@ -16,7 +16,11 @@ function useAddMutation(key: string, url: string): UseMutationResult( async (dataToSend) => { - const { data } = await axios.post(url, dataToSend); + const { data } = await axios.post(url, dataToSend,{ + headers: { + 'Content-Type': 'multipart/form-data' + } + } ); return data; }, { diff --git a/src/api/helper/useGetOneQuery.ts b/src/api/helper/useGetOneQuery.ts index 0b2c335..0d290f5 100644 --- a/src/api/helper/useGetOneQuery.ts +++ b/src/api/helper/useGetOneQuery.ts @@ -5,10 +5,11 @@ import useAuthState from '../../lib/state mangment/AuthState'; function useGetOneQuery(key: string, url: string , params:any={},options:any={}) { const axios = useAxios(); const {logout} = useAuthState() + const language = localStorage.getItem("language") ?? "en" return useQuery( params ? [key, params] : key, async () => { - const response = await axios.get(url+"/"+ params?.id); + const response = await axios.get(url+"/"+ params?.id+`?lang=${language}`); return response.data.data; },