end seller page

This commit is contained in:
karimaldeen 2024-08-19 15:13:54 +03:00
parent 7e8fa6431c
commit 8f993912fc
25 changed files with 3801 additions and 5715 deletions

View File

@ -10,6 +10,7 @@
"Groupbutton",
"handelnavigate",
"Karim",
"latlng",
"queryqlent",
"registraion",
"SENDNOTIFICATION",

View File

@ -18,6 +18,7 @@
"formik": "^2.4.6",
"html-to-image": "^1.11.11",
"i18next": "^23.11.5",
"leaflet": "^1.9.4",
"path-to-regexp": "^6.2.2",
"pdf-lib": "^1.17.1",
"react": "^18.3.1",
@ -26,6 +27,7 @@
"react-dragula": "^1.1.17",
"react-i18next": "^13.5.0",
"react-icons": "^4.12.0",
"react-leaflet": "^4.2.1",
"react-query": "^3.39.3",
"react-router-dom": "^6.23.1",
"react-toastify": "^9.1.3",
@ -66,6 +68,7 @@
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/leaflet": "^1.9.12",
"@types/node": "^20.14.0",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",

File diff suppressed because it is too large Load Diff

View File

@ -49,7 +49,7 @@ const TableHeader = () => {
<Table />
<DeleteModalForm
deleteMutation={deleteMutation}
ModelEnum={ModalEnum?.Package_DELETE}
ModelEnum={ModalEnum?.PACKAGE_DELETE}
/>
</Suspense>
</div>

View File

@ -15,11 +15,11 @@ export const useColumns = () => {
const { setObjectToEdit } = useObjectToEdit((state) => state);
const handelDelete = (record: any) => {
setObjectToEdit(record);
setIsOpen(ModalEnum?.Package_DELETE);
setIsOpen(ModalEnum?.PACKAGE_DELETE);
};
const handleEdit = (record: any) => {
setObjectToEdit(record);
setIsOpen(ModalEnum?.Package_EDIT);
setIsOpen(ModalEnum?.PACKAGE_EDIT);
navigate(`${record?.id}`)
};

View File

@ -50,7 +50,7 @@ const TableHeader = () => {
<Table />
<DeleteModalForm
deleteMutation={deleteMutation}
ModelEnum={ModalEnum?.Package_DELETE}
ModelEnum={ModalEnum?.PACKAGE_DELETE}
/>
</Suspense>
</div>

View File

@ -1,6 +1,6 @@
import { TableColumnsType } from "antd";
import { ModalEnum } from "../../enums/Model";
import { useObjectToEdit } from "../../zustand/ObjectToEditState";
import { useObjectToEdit } from "../../zustand/ObjectToEditState";``
import { useModalState } from "../../zustand/Modal";
import { useTranslation } from "react-i18next";
import { canDeletePackage,canEditPackage, canShowPackage } from "../../utils/hasAbilityFn";
@ -16,18 +16,18 @@ export const useColumns = () => {
const { setObjectToEdit } = useObjectToEdit((state) => state);
const handelDelete = (record: any) => {
setObjectToEdit(record);
setIsOpen(ModalEnum?.Package_DELETE);
setIsOpen(ModalEnum?.PACKAGE_DELETE);
};
const handleEdit = (record: any) => {
setObjectToEdit(record);
navigate(`${record?.id}`)
};
const handleShow = (record: any) => {
setObjectToEdit(record);
navigate(`${record?.id}/${ABILITIES_ENUM?.PACKAGE_ITEM}`)
// const handleShow = (record: any) => {
// setObjectToEdit(record);
// navigate(`${record?.id}/${ABILITIES_ENUM?.PACKAGE_ITEM}`)
};
// };
const columns: TableColumnsType<any> = [
{
@ -58,11 +58,11 @@ export const useColumns = () => {
<ActionButtons
canDelete={canEditPackage}
canEdit={canDeletePackage}
canShow={canShowPackage}
// canShow={canShowPackage}
index={index}
onDelete={() => handelDelete(record)}
onEdit={() => handleEdit(record)}
onShow={() => handleShow(record)}
// onShow={() => handleShow(record)}
/>
);
},

View File

@ -0,0 +1,36 @@
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 ModelForm from "./ModelForm";
import { useAddReSeller } from "../../../api/ReSeller";
const AddModel: React.FC = () => {
const { mutate, status } = useAddReSeller();
const handleSubmit = (values: any) => {
const newValue = JSON.parse(JSON.stringify({...values}))
const location = {lat:newValue?.lat,lng:newValue?.lng}
mutate({
...newValue,
location
});
};
return (
<>
<LayoutModel
status={status as QueryStatusEnum}
ModelEnum={ModalEnum.RE_SELLER_ADD}
modelTitle="ReSeller"
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 { useUpdateReSeller } from "../../../api/ReSeller";
import { handelImageState } from "../../../utils/DataToSendImageState";
const EditModel: React.FC = () => {
const { mutate, status } = useUpdateReSeller();
const { objectToEdit } = useObjectToEdit((state) => state);
const handleSubmit = (values: any) => {
const newValue = JSON.parse(JSON.stringify({...values}))
const location = {lat:newValue?.lat,lng:newValue?.lng}
mutate({
...newValue,
location
});
};
return (
<>
<LayoutModel
status={status as QueryStatusEnum}
ModelEnum={ModalEnum.RE_SELLER_EDIT}
modelTitle="ReSeller"
handleSubmit={handleSubmit}
getInitialValues={getInitialValues(objectToEdit)}
getValidationSchema={getValidationSchemaEdit}
isAddModal={false}
>
<ModelForm isEdit={true} />
</LayoutModel>
</>
);
};
export default EditModel;

View File

@ -0,0 +1,30 @@
import { Col, Row } from "reactstrap";
import ValidationField from "../../../Components/ValidationField/ValidationField";
import MyMap from "./field/MyMap";
const Form = ({isEdit = false}:{isEdit?:boolean}) => {
return (
<Row className="w-100">
<Col>
<ValidationField name="first_name" placeholder="first_name" label="first_name" />
<ValidationField name="last_name" placeholder="last_name" label="last_name" />
<ValidationField name="username" placeholder="username" label="username" />
{!isEdit &&
<ValidationField name="password" placeholder="password" label="password" />
}
</Col>
<Col>
<ValidationField name="contact_number1" placeholder="contact_number1" label="contact_number1" />
<ValidationField name="contact_number2" placeholder="contact_number2" label="contact_number2" />
<ValidationField name="lat" placeholder="lat" label="lat" />
<ValidationField name="lng" placeholder="lng" label="lng" />
<MyMap/>
</Col>
</Row>
);
};
export default Form;

View File

@ -0,0 +1,81 @@
import React, { useState, useEffect } from 'react';
import { MapContainer, TileLayer, Marker, Popup, useMapEvents, useMap } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
import L from 'leaflet';
import { Input, Button } from 'antd';
import { useFormikContext } from 'formik';
import { ReSellerInitialValues } from '../../../../types/ReSeller';
import { useTranslation } from 'react-i18next';
// Fix for marker icon issue
//@ts-ignore
delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({
iconRetinaUrl: 'https://unpkg.com/leaflet/dist/images/marker-icon-2x.png',
iconUrl: 'https://unpkg.com/leaflet/dist/images/marker-icon.png',
shadowUrl: 'https://unpkg.com/leaflet/dist/images/marker-shadow.png',
});
const LocationMarker: React.FC = () => {
const { setFieldValue } = useFormikContext<ReSellerInitialValues>();
useMapEvents({
click(e) {
const { lat, lng } = e.latlng;
setFieldValue('lat', lat); // Update latitude in Formik
setFieldValue('lng', lng); // Update longitude in Formik
},
});
return null;
};
const CenterMapOnPosition: React.FC<{ position: [number, number] }> = ({ position }) => {
const map = useMap();
useEffect(() => {
map.setView(position, map.getZoom());
}, [position, map]);
return null;
};
const MyMap: React.FC = () => {
const [showMap, setShowMap] = useState(false); // State to control map visibility
const [currentPosition] = useState<[number, number] | null>(null); // State to hold current position
const { values } = useFormikContext<ReSellerInitialValues>();
const { lat, lng } = values as any;
const position: [number, number] = [lat, lng];
const [t] = useTranslation()
return (
<div className='mb-4'>
<div className='MapInputs '>
<Button onClick={() => setShowMap(!showMap)} type="primary">
{showMap ? `${t("practical.Hide")} ${t("practical.Map")}` : `${t("practical.Show")} ${t("practical.Map")}`}
</Button>
</div>
{showMap && (
<MapContainer
center={currentPosition || position} // Use currentPosition if available, otherwise fallback to form values
zoom={13}
style={{ height: "200px", width: "100%" }}
>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={currentPosition || position}>
</Marker>
<LocationMarker />
<CenterMapOnPosition position={currentPosition || position} />
</MapContainer>
)}
</div>
);
};
export default MyMap;

View File

@ -0,0 +1,67 @@
import * as Yup from "yup";
import { ReSeller, ReSellerInitialValues } from "../../../types/ReSeller";
export const getInitialValues = (
objectToEdit: Partial<ReSeller>,
): ReSellerInitialValues => {
console.log(objectToEdit,"objectToEdit");
return {
id: objectToEdit?.id,
first_name: objectToEdit?.first_name ?? "",
last_name: objectToEdit?.last_name ?? "",
lat: objectToEdit?.location?.lat ?? 33.5138,
lng: objectToEdit?.location?.lng ?? 36.2765,
contact_number1:objectToEdit?.contact_number1 ?? null,
contact_number2:objectToEdit?.contact_number2 ?? null ,
username: objectToEdit?.user?.username ?? null ,
};
};
export const getValidationSchema = () => {
// validate input
return Yup.object().shape({
first_name: Yup.string().required("validation.required"),
last_name: Yup.string().required("validation.required"),
contact_number1: Yup.string()
.matches(/^([0-9\s\-\+\(\)]*)$/, 'validation.Please enter a valid phone number (e.g., +1 123-456-7890)') // Regex for phone number
.min(10, "validation.must_be_at_least_10_characters_long") // Minimum length
.max(15, "validation.must_not_exceed_15_characters_long") // Maximum length
.required("validation.required"), // Required field
contact_number2: Yup.string()
.matches(/^([0-9\s\-\+\(\)]*)$/, 'validation.Please enter a valid phone number (e.g., +1 123-456-7890)') // Regex for phone number
.min(10, "validation.must_be_at_least_10_characters_long") // Minimum length
.max(15, "validation.must_not_exceed_15_characters_long") // Maximum length
.required("validation.required"), // Required field
password: Yup.string().min(8,"validation.Password_must_be_at_least_8_characters_long").required("validation.required"),
username: Yup.string().required("validation.required"),
lat: Yup.string().required("validation.required"),
lng: Yup.string().required("validation.required"),
});
};
export const getValidationSchemaEdit = () => {
// validate input
return Yup.object().shape({
first_name: Yup.string().required("validation.required"),
last_name: Yup.string().required("validation.required"),
contact_number1: Yup.string()
.matches(/^([0-9\s\-\+\(\)]*)$/, 'validation.Please enter a valid phone number (e.g., +1 123-456-7890)') // Regex for phone number
.min(10, "validation.must_be_at_least_10_characters_long") // Minimum length
.max(15, "validation.must_not_exceed_15_characters_long") // Maximum length
.required("validation.required"), // Required field
contact_number2: Yup.string()
.matches(/^([0-9\s\-\+\(\)]*)$/, 'validation.Please enter a valid phone number (e.g., +1 123-456-7890)') // Regex for phone number
.min(10, "validation.must_be_at_least_10_characters_long") // Minimum length
.max(15, "validation.must_not_exceed_15_characters_long") // Maximum length
.required("validation.required"), // Required field
username: Yup.string().required("validation.required"),
lat: Yup.string().required("validation.required"),
lng: Yup.string().required("validation.required"),
});
};

View File

@ -0,0 +1,44 @@
import { useTranslation } from "react-i18next";
import { lazy, Suspense } from "react";
import { Spin } from "antd";
import useSetPageTitle from "../../Hooks/useSetPageTitle";
import { ModalEnum } from "../../enums/Model";
import { useDeleteReSeller } from "../../api/ReSeller";
import MyMap from "./Model/field/MyMap";
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();
const deleteMutation = useDeleteReSeller();
useSetPageTitle(t(`page_header.ReSeller`));
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<header>
<h6>{t("models.ReSeller")}</h6>
</header>
<Table />
<AddModalForm />
<EditModalForm />
<DeleteModalForm
deleteMutation={deleteMutation}
ModelEnum={ModalEnum?.RE_SELLER_DELETE}
/>
</Suspense>
</div>
);
};
export default TableHeader;

View File

@ -0,0 +1,12 @@
import { useColumns } from "./useTableColumns";
import React from "react";
import DataTable from "../../Layout/Dashboard/Table/DataTable";
import { useGetAllReSeller } from "../../api/ReSeller";
const App: React.FC = () => {
const response = useGetAllReSeller({ pagination: true });
return <DataTable response={response} useColumns={useColumns} />;
};
export default App;

View File

@ -0,0 +1,98 @@
import { TableColumnsType } from "antd";
import { ReSeller } from "../../types/ReSeller";
import { FaPlus } from "react-icons/fa";
import useModalHandler from "../../utils/useModalHandler";
import { ModalEnum } from "../../enums/Model";
import { useObjectToEdit } from "../../zustand/ObjectToEditState";
import { useTranslation } from "react-i18next";
import { ABILITIES_ENUM } from "../../enums/abilities";
import { useNavigate } from "react-router-dom";
import {
canAddReSeller,
canDeleteReSeller,
canEditReSeller,
canShowReSeller,
} from "../../utils/hasAbilityFn";
import ActionButtons from "../../Components/Table/ActionButtons";
import ColumnsImage from "../../Components/Columns/ColumnsImage";
export const useColumns = () => {
const { handel_open_model } = useModalHandler();
const { setObjectToEdit } = useObjectToEdit((state) => state);
const navigate = useNavigate();
const handelDelete = (data: ReSeller) => {
setObjectToEdit(data);
handel_open_model(ModalEnum?.RE_SELLER_DELETE);
};
const handleEdit = (record: ReSeller) => {
setObjectToEdit(record);
handel_open_model(ModalEnum?.RE_SELLER_EDIT);
};
const [t] = useTranslation();
const columns: TableColumnsType<ReSeller> = [
{
title: t("columns.id"),
dataIndex: "id",
key: "id",
align: "center",
render: (_text, record) => record?.id,
},
{
title: `${t("columns.first_name")}`,
dataIndex: "first_name",
key: "first_name",
align: "center",
render: (_text, record) => record?.first_name,
},
{
title: `${t("columns.last_name")}`,
dataIndex: "last_name",
key: "last_name",
align: "center",
render: (_text, record) => record?.last_name,
},
{
title: `${t("columns.username")}`,
dataIndex: "username",
key: "username",
align: "center",
render: (_text, record) => record?.user?.username,
},
{
title: canAddReSeller ? (
<button
onClick={() => handel_open_model(ModalEnum?.RE_SELLER_ADD)}
className="add_button"
>
{t("practical.add")} {t("models.ReSeller")} <FaPlus />
</button>
) : (
""
),
key: "actions",
align: "end",
width: "25vw",
render: (_text, record, index) => {
return (
<ActionButtons
canDelete={canDeleteReSeller}
canEdit={canEditReSeller}
index={index}
onDelete={() => handelDelete(record)}
onEdit={() => handleEdit(record)}
/>
);
},
},
];
return columns;
};

View File

@ -1,5 +1,5 @@
import { TCrudRoute, TMenuItem } from "./types/App";
import { FaHome, FaKey, FaMoneyBill, FaUserGraduate } from "react-icons/fa";
import { FaHome, FaKey, FaMoneyBill, FaSellcast, FaUserGraduate } from "react-icons/fa";
import { LuPackage } from "react-icons/lu";
import React from "react";
const Dummy = React.lazy(() => import("./Pages/Home/Dummy"));
@ -11,6 +11,7 @@ const Grade = React.lazy(() => import("./Pages/Grade/Page"));
const Package = React.lazy(() => import("./Pages/Package/Page"));
const Curriculum = React.lazy(() => import("./Pages/Curriculum/Page"));
const PackageItemPage = React.lazy(() => import("./Pages/Package/PackageItem/Page"));
const ReSeller = React.lazy(() => import("./Pages/ReSeller/Page"));
const Unit = React.lazy(() => import("./Pages/Unit/Page"));
const Lesson = React.lazy(() => import("./Pages/lesson/Page"));
@ -80,6 +81,16 @@ export const menuItems: TMenuItem[] = [
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
prevPath: 0,
},
{
header: "page_header.reSeller",
element: <ReSeller />,
icon: <FaSellcast />,
text: "sidebar.reSeller",
path: `/${ABILITIES_ENUM?.RE_SELLER}`,
abilities: ABILITIES_ENUM?.RE_SELLER,
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
prevPath: 0,
},
];
export const CrudRoute: TCrudRoute[] = [

View File

@ -0,0 +1,9 @@
.MapInputs{
display: flex;
gap: 20px;
margin-bottom: 20px;
}
.leaflet-right{
display: none;
}

View File

@ -10,3 +10,4 @@
@import "./subject.scss";
@import "./Marks.scss";
@import "./exercise.scss";
@import './Map.scss';

21
src/api/ReSeller.ts Normal file
View File

@ -0,0 +1,21 @@
import useAddMutation from "./helper/useAddMutation";
import useDeleteMutation from "./helper/useDeleteMutation";
import useGetQuery from "./helper/useGetQuery";
import useUpdateMutation from "./helper/useUpdateMutation";
const API = {
GET: "/reseller",
ADD: "/reseller",
DELETE: "/reseller",
UPDATE: "/reseller",
};
const KEY = "ReSeller";
export const useGetAllReSeller = (params?: any, options?: any) =>
useGetQuery(KEY, API.GET, params, options);
export const useAddReSeller = () => useAddMutation(KEY, API.ADD);
export const useUpdateReSeller = (params?: any) =>
useUpdateMutation(KEY, API.GET);
export const useDeleteReSeller = (params?: any) =>
useDeleteMutation(KEY, API.DELETE);

View File

@ -155,8 +155,12 @@ export enum ModalEnum {
///package
Package_EDIT = "Package.edit",
Package_ADD = "Package.add",
Package_DELETE = "Package.delete",
PACKAGE_EDIT = "Package.edit",
PACKAGE_ADD = "Package.add",
PACKAGE_DELETE = "Package.delete",
/// ReSeller
RE_SELLER_EDIT = "ReSeller.edit",
RE_SELLER_ADD = "ReSeller.add",
RE_SELLER_DELETE = "ReSeller.delete",
}

View File

@ -44,6 +44,7 @@ export enum ABILITIES_ENUM {
ADMIN = "admin",
CURRICULUM = "curriculum",
PACKAGE_ITEM = "package_item",
RE_SELLER = "ReSeller"
////
}

View File

@ -13,6 +13,7 @@
"Email_is_required": "البريد الإلكتروني مطلوب",
"Password_is_required": "كلمة المرور مطلوبة",
"Password_must_be_at_least_8_characters_long": "يجب أن تكون كلمة المرور مكونة من 8 أحرف على الأقل",
"must_be_at_least_10_characters_long":"يجب أن تكون مكونة من 10 أحرف على الأقل",
"Nationality_is_required": "الجنسية مطلوبة",
"Address_is_required": "العنوان مطلوب",
"Place_of_birth_is_required": "مكان الميلاد مطلوب",
@ -47,7 +48,8 @@
"grade_to_pass_must_be_less_than_max_grade": "يجب أن تكون درجة النجاح أقل من الحد الأقصى للدرجة",
"max_mark_must_be_greater_than_min_mark_to_pass": "يجب ان تكون اكبر من علامة النجاح",
"Sorry, the question must have at least one option": "عذرًا، يجب أن يحتوي السؤال على خيار واحد على الأقل",
"must_have_on_item":"يجب ان يحتوي على عنصر واحد على الاقل"
"must_have_on_item":"يجب ان يحتوي على عنصر واحد على الاقل",
"Please enter a valid phone number (e.g., +1 123-456-7890)":"يرجى إدخال رقم هاتف صالح (مثل: +1 123-456-7890)"
},
"header": {
"register_students": "تسجيل الطلاب",
@ -160,7 +162,8 @@
"question_options_count": "عدد الخيارات",
"canAnswersBeShuffled":"يمكن خلط الإجابات",
"price":"السعر",
"grade_id":"رقم تعريف الدرجة"
"grade_id":"رقم تعريف الدرجة",
"first_name":"الاسم الأول"
},
"practical": {
"to_confirm_deletion_please_re_enter": "لتأكيد الحذف، يرجى إعادة الإدخال",
@ -207,7 +210,10 @@
"delete_last":"حذف عنصر",
"key":"الاسم",
"value":"القيمة",
"delete_this_item":"حذف هذا العنصر"
"delete_this_item":"حذف هذا العنصر",
"Hide":"اخفاء",
"Show":"عرض",
"Map":"خريطة"
},
"Table": {
"header": "",
@ -272,7 +278,8 @@
"curriculum": "مقرر",
"package":"حزمة",
"package_details":"تفاصيل الحزمة",
"add_package":"اضافة حزمة"
"add_package":"اضافة حزمة",
"ReSeller":"بائع"
},
"education_class_actions": {
"Student_Records": "سجلات الطلاب",
@ -378,7 +385,12 @@
"subject":"المادة",
"curriculum":"مقرر",
"lesson":"الدرس",
"unit":"الوحدة"
"unit":"الوحدة",
"contact_number1":"رقم التواصل 1",
"contact_number2":"رقم التواصل 2",
"lat":"خط العرض",
"lng":" خط الطول "
},
"select": {
@ -681,7 +693,8 @@
"tags": "كلمات مفتاحية",
"grade": "الدرجات",
"curriculum": "مقرر",
"package":"حزمة"
"package":"حزمة",
"reSeller":"البائع"
},
"message": {
"some_thing_went_wrong": "حدث خطأ ما",
@ -738,6 +751,7 @@
"edit_Question": "لوحة القيادة /تعديل اسئلة ",
"grade": "لوحة القيادة /الدرجات ",
"curriculum": "لوحة القيادة / تعديل مقرر ",
"package":"لوحة القيادة / الحزم "
"package":"لوحة القيادة / الحزم ",
"ReSeller":"لوحة القيادة / البائع "
}
}

50
src/types/ReSeller.ts Normal file
View File

@ -0,0 +1,50 @@
import { Nullable } from "./App";
// Define the Teacher interface
interface ReSellerUser {
id: number;
username: string;
phone_number: string | null;
type: 'reseller' | 'other'; // Specify other types if needed
}
interface ReSellerLocation {
lat: string;
lng: string;
}
interface ContactInfo {
contact_number1: string;
contact_number2: string;
card_number: string | null;
}
export interface ReSeller {
id: number;
user: ReSellerUser;
first_name: string;
last_name: string;
location: ReSellerLocation;
contact_info: ContactInfo;
contact_number1 : string | number
contact_number2 : string | number
}
export interface InitialValues {
id: number;
user: ReSellerUser;
first_name: string;
last_name: string;
location: ReSellerLocation;
lat: string | Number;
lng: string | Number;
contact_info: ContactInfo;
contact_number1 : string | number
contact_number2 : string | number
username : string
}
export type ReSellerInitialValues = Partial<Nullable<InitialValues>>;

View File

@ -583,3 +583,24 @@ export const canShowPackage = hasAbility(
ABILITIES_ENUM.Package,
ABILITIES_VALUES_ENUM.SHOW,
);
/// ReSeller
export const canAddReSeller = hasAbility(
ABILITIES_ENUM.RE_SELLER,
ABILITIES_VALUES_ENUM.STORE,
);
export const canEditReSeller = hasAbility(
ABILITIES_ENUM.RE_SELLER,
ABILITIES_VALUES_ENUM.UPDATE,
);
export const canDeleteReSeller = hasAbility(
ABILITIES_ENUM.RE_SELLER,
ABILITIES_VALUES_ENUM.DELETE,
);
export const canShowReSeller = hasAbility(
ABILITIES_ENUM.RE_SELLER,
ABILITIES_VALUES_ENUM.SHOW,
);

View File

@ -14,7 +14,10 @@
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
"jsx": "react-jsx",
"types": ["node"]
},
"include": ["src"]
"include": ["src"],
}