diff --git a/src/components/ServiceItem.tsx b/src/components/ServiceItem.tsx index 325fe05..cb38f66 100644 --- a/src/components/ServiceItem.tsx +++ b/src/components/ServiceItem.tsx @@ -7,7 +7,8 @@ import { useTranslation } from 'react-i18next' import { ItemServiceType } from '../pages/service/types/ServiecTypes' type Props = { - item: ItemServiceType + item: ItemServiceType, + className?: string, } const ServiceItem: FC = (props: Props) => { @@ -16,7 +17,7 @@ const ServiceItem: FC = (props: Props) => { const { item } = props return ( -
+
{item.name} diff --git a/src/langs/fa.json b/src/langs/fa.json index 940803b..ecc6d23 100644 --- a/src/langs/fa.json +++ b/src/langs/fa.json @@ -419,5 +419,18 @@ "amount": "مبلغ پرداختی", "date": "تاریخ", "back": "بازگشت" + }, + "discount": { + "number": "شماره", + "type": "نوع تحفیف", + "code": "کد تخفیف", + "CODE": "کد", + "start_date": "تاریخ شروع", + "end_date": "تاریخ پایان", + "percent_ammount": "درصد / مبلغ تخفیف", + "service": "سرویس", + "status": "وضعیت", + "active": "فعال", + "deactive": "غیرفعال" } } diff --git a/src/pages/discounts/List.tsx b/src/pages/discounts/List.tsx new file mode 100644 index 0000000..af37455 --- /dev/null +++ b/src/pages/discounts/List.tsx @@ -0,0 +1,61 @@ +import { FC } from 'react' +import { useGetMyDiscount } from './hooks/useDiscountData' +import PageLoading from '../../components/PageLoading' +import Td from '../../components/Td' +import { useTranslation } from 'react-i18next' +import { DiscountItemType } from './types/DiscountTypes' +import moment from 'moment-jalaali' + +const MyDiscountList: FC = () => { + + const { t } = useTranslation('global') + const getDiscounts = useGetMyDiscount() + + return ( +
+ { + getDiscounts.isPending ? + + : +
+ + + + + + + { + getDiscounts.data?.data?.discounts?.map((item: DiscountItemType, index: number) => { + return ( + + + + ) + }) + } + +
+ + + + + + + +
+ + + + + + + + {item.isActive ? {t('discount.active')} : {t('discount.inactive')}} +
+
+ } +
+ ) +} + +export default MyDiscountList \ No newline at end of file diff --git a/src/pages/discounts/hooks/useDiscountData.ts b/src/pages/discounts/hooks/useDiscountData.ts new file mode 100644 index 0000000..cf3f71e --- /dev/null +++ b/src/pages/discounts/hooks/useDiscountData.ts @@ -0,0 +1,9 @@ +import { useQuery } from "@tanstack/react-query"; +import * as api from "../service/DiscountService"; + +export const useGetMyDiscount = () => { + return useQuery({ + queryKey: ["my-discount"], + queryFn: () => api.getMyDiscounts(), + }); +}; diff --git a/src/pages/discounts/service/DiscountService.ts b/src/pages/discounts/service/DiscountService.ts new file mode 100644 index 0000000..91219d0 --- /dev/null +++ b/src/pages/discounts/service/DiscountService.ts @@ -0,0 +1,6 @@ +import axios from "../../../config/axios"; + +export const getMyDiscounts = async () => { + const { data } = await axios.get(`/discounts/user-discounts`); + return data; +}; diff --git a/src/pages/discounts/types/DiscountTypes.ts b/src/pages/discounts/types/DiscountTypes.ts new file mode 100644 index 0000000..ab41620 --- /dev/null +++ b/src/pages/discounts/types/DiscountTypes.ts @@ -0,0 +1,30 @@ +export type DiscountItemType = { + id: string; + createdAt: string; + updatedAt: string; + title: string; + type: string; + calculationType: string; + amount: number; + isActive: boolean; + code: string; + startDate: string; + endDate: string; + subscriptionPlans: { + id: string; + createdAt: string; + updatedAt: string; + name: string; + duration: number; + price: number; + isActive: boolean; + service: { + id: string; + name: string; + title: string; + description: string; + link: string; + icon: string; + }; + }[]; +}; diff --git a/src/pages/home/Home.tsx b/src/pages/home/Home.tsx index 01a0439..260d17f 100644 --- a/src/pages/home/Home.tsx +++ b/src/pages/home/Home.tsx @@ -1,4 +1,4 @@ -import { FC } from 'react' +import { FC, Fragment } from 'react' import { useTranslation } from 'react-i18next' import { ArrowLeft, Element3, Messages3, NotificationStatus, Receipt21 } from 'iconsax-react' import ItemDashboard from './components/ItemDashboard' @@ -10,110 +10,141 @@ import { Carousel } from "@material-tailwind/react"; import { useGetAds } from '../ads/hooks/useAdsData' import { AdsDisplayLocation, AdsItemType } from '../ads/types/AdsTypes' import { Pages } from '../../config/Pages' +import { useGetQuikAccess } from './hooks/useHomeData' +import { QuikAccessItemType } from './types/HomeTypes' +import ServiceItem from '../../components/ServiceItem' +import PageLoading from '../../components/PageLoading' const Home: FC = () => { const { t } = useTranslation('global') const getAds = useGetAds(AdsDisplayLocation.HOMEPAGE_TOP) + const getQuikAccess = useGetQuikAccess() return ( -
-
- { }} onPointerLeaveCapture={() => { }} > - { - getAds.data?.data?.ads?.map((item: AdsItemType) => { - return ( -
- - + ) + }) + } + + +
+ } + color='#00D16C' + count={4} + description={t('home.active_service')} + link={Pages.services.mine} + /> + + } + color='#FF7B00' + count={4} + description={t('home.unread_messages')} + link={Pages.ticket.list} + /> + + } + color='#0047FF' + count={4} + description={t('home.receip')} + link={Pages.receipts.index} + /> + + } + color='#FF0000' + count={4} + description={t('home.unread_announcement')} + link={Pages.announcement.list} + /> + +
+ +
+ +
+ +
+ { + getQuikAccess?.data?.data?.quickAccesses?.length === 0 && +
+ +
+ {t('home.add_access')}
-
- ) - }) - } - + } + { + getQuikAccess.data?.data?.quickAccesses?.map((item: QuikAccessItemType) => { + return ( + + ) + }) + } + {Array.from({ length: 4 - (getQuikAccess.data?.data?.quickAccesses?.length || 1) }).map((_, index) => ( + + ))} -
- } - color='#00D16C' - count={4} - description={t('home.active_service')} - link={Pages.services.mine} - /> - - } - color='#FF7B00' - count={4} - description={t('home.unread_messages')} - link={Pages.ticket.list} - /> - - } - color='#0047FF' - count={4} - description={t('home.receip')} - link={Pages.receipts.index} - /> - - } - color='#FF0000' - count={4} - description={t('home.unread_announcement')} - link={Pages.announcement.list} - /> - -
- -
- -
- -
-
- -
- {t('home.add_access')} +
+
+
+
- - - -
-
- -
+ } + ) } diff --git a/src/pages/home/components/BoxNewAccessbility.tsx b/src/pages/home/components/BoxNewAccessbility.tsx index 24290c5..b63b2ad 100644 --- a/src/pages/home/components/BoxNewAccessbility.tsx +++ b/src/pages/home/components/BoxNewAccessbility.tsx @@ -3,10 +3,11 @@ import { FC, useState } from 'react' import DefaulModal from '../../../components/DefaulModal' import { useTranslation } from 'react-i18next' import Input from '../../../components/Input' -import SwitchComponent from '../../../components/Switch' import { useGetMyServices } from '../../service/hooks/useServiceData' import { MyServicesItem } from '../../service/types/ServiecTypes' import PageLoading from '../../../components/PageLoading' +import { useGetQuikAccess, useQuikAccess, useRemoveQuikAccess } from '../hooks/useHomeData' +import ChangeQuikAccess from './ChangeQuikAccess' const BoxNewAccessbility: FC = () => { @@ -14,12 +15,31 @@ const BoxNewAccessbility: FC = () => { const [open, setOpen] = useState(false) const { t } = useTranslation('global') const getMyservices = useGetMyServices(search) + const getQuikAccess = useGetQuikAccess() + const quikAccess = useQuikAccess() + const removeQuikAceess = useRemoveQuikAccess() + + const handleQuikAccess = (value: boolean, id: string) => { + if (value) { + quikAccess.mutate(id, { + onSuccess: () => { + getQuikAccess.refetch() + } + }) + } else { + removeQuikAceess.mutate(id, { + onSuccess: () => { + getQuikAccess.refetch() + } + }) + } + } return ( <>
setOpen(true)} - className="flex-1 min-w-[40%] xl:min-w-[20%] flex justify-center items-center h-[160px]" + className="flex-1 min-w-[40%] xl:p-6 p-4 xl:min-w-[20%] flex justify-center items-center min-h-[152px]" style={{ position: 'relative', }} @@ -91,6 +111,7 @@ const BoxNewAccessbility: FC = () => {
: getMyservices.data?.data?.subscriptions?.map((item: MyServicesItem) => { + const active = getQuikAccess.data?.data?.quickAccesses?.find((o: any) => o.service?.id === item.plan?.service?.id) ? true : false return (
@@ -107,9 +128,10 @@ const BoxNewAccessbility: FC = () => {
- { }} +
diff --git a/src/pages/home/components/ChangeQuikAccess.tsx b/src/pages/home/components/ChangeQuikAccess.tsx new file mode 100644 index 0000000..7166671 --- /dev/null +++ b/src/pages/home/components/ChangeQuikAccess.tsx @@ -0,0 +1,26 @@ +import { FC, useState } from 'react' +import SwitchComponent from '../../../components/Switch' + +type Props = { + id: string, + value: boolean, + onChange: (value: boolean, id: string) => void +} + + +const ChangeQuikAccess: FC = (props: Props) => { + + const [active, setActive] = useState(props.value) + + return ( + { + props.onChange(value, props.id) + setActive(value) + }} + /> + ) +} + +export default ChangeQuikAccess \ No newline at end of file diff --git a/src/pages/home/hooks/useHomeData.ts b/src/pages/home/hooks/useHomeData.ts new file mode 100644 index 0000000..dc6acec --- /dev/null +++ b/src/pages/home/hooks/useHomeData.ts @@ -0,0 +1,21 @@ +import * as api from "../service/HomeService"; +import { useMutation, useQuery } from "@tanstack/react-query"; + +export const useQuikAccess = () => { + return useMutation({ + mutationFn: (variables: string) => api.quikAccess(variables), + }); +}; + +export const useGetQuikAccess = () => { + return useQuery({ + queryKey: ["quik-access"], + queryFn: () => api.getQuikAccess(), + }); +}; + +export const useRemoveQuikAccess = () => { + return useMutation({ + mutationFn: (variables: string) => api.removeQuikAccess(variables), + }); +}; diff --git a/src/pages/home/service/HomeService.ts b/src/pages/home/service/HomeService.ts new file mode 100644 index 0000000..16cc9c8 --- /dev/null +++ b/src/pages/home/service/HomeService.ts @@ -0,0 +1,20 @@ +import axios from "../../../config/axios"; + +export const quikAccess = async (serviceId: string) => { + const { data } = await axios.post( + `/subscriptions/${serviceId}/add-quick-access` + ); + return data; +}; + +export const getQuikAccess = async () => { + const { data } = await axios.get(`/subscriptions/quick-access`); + return data; +}; + +export const removeQuikAccess = async (serviceId: string) => { + const { data } = await axios.delete( + `/subscriptions/${serviceId}/remove-quick-access` + ); + return data; +}; diff --git a/src/pages/home/types/HomeTypes.ts b/src/pages/home/types/HomeTypes.ts new file mode 100644 index 0000000..0165b79 --- /dev/null +++ b/src/pages/home/types/HomeTypes.ts @@ -0,0 +1,11 @@ +import { ItemServiceType } from "../../service/types/ServiecTypes"; + +export type QuikAccessItemType = { + id: string; + createdAt: string; + isActive: boolean; + service: ItemServiceType; + author: string; + createDate: string; + updatedAt: string; +}; diff --git a/src/pages/ticket/Detail.tsx b/src/pages/ticket/Detail.tsx index d0f27d6..dd7ff53 100644 --- a/src/pages/ticket/Detail.tsx +++ b/src/pages/ticket/Detail.tsx @@ -95,10 +95,15 @@ const TicketDetail: FC = () => { :
-
+ +
{ />
-
- {getMessages.data?.data?.ticket?.subject} -
- { getMessages.data?.data?.messages.map((item: any) => { if (item?.author?.roles[0]?.name === 'user') { diff --git a/src/router/Main.tsx b/src/router/Main.tsx index 5f601d0..406171b 100644 --- a/src/router/Main.tsx +++ b/src/router/Main.tsx @@ -26,6 +26,7 @@ import CreateTicket from '../pages/ticket/CreateTicket' import TicketDetail from '../pages/ticket/Detail' import Financial from '../pages/financial/Financial' import CallBack from '../pages/wallet/CallBack' +import MyDiscountList from '../pages/discounts/List' const MainRouter: FC = () => { return ( @@ -55,6 +56,7 @@ const MainRouter: FC = () => { } /> } /> } /> + } />