my coupon
This commit is contained in:
@@ -1,7 +1,31 @@
|
|||||||
|
'use client';
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import React from 'react'
|
import React, { useCallback } from 'react'
|
||||||
|
import { useGetMyCoupons } from '../hooks/useTransactionData';
|
||||||
|
import { toast } from '@/components/Toast';
|
||||||
|
import type { Coupon } from '../types/Types';
|
||||||
|
|
||||||
function TransactionsIndex() {
|
function TransactionsIndex() {
|
||||||
|
const { data: myCoupons, isLoading } = useGetMyCoupons();
|
||||||
|
|
||||||
|
const handleCopyCode = useCallback(async (code: string) => {
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(code);
|
||||||
|
toast('کد تخفیف با موفقیت کپی شد', 'success');
|
||||||
|
} catch {
|
||||||
|
toast('خطا در کپی کردن کد تخفیف', 'error');
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const formatDiscount = useCallback((coupon: Coupon) => {
|
||||||
|
if (coupon.type === 'PERCENTAGE') {
|
||||||
|
return `${coupon.value}%`;
|
||||||
|
}
|
||||||
|
return `${coupon.value.toLocaleString('fa-IR')} تومان`;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const coupons = myCoupons?.data ?? [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className='pt-6'>
|
<section className='pt-6'>
|
||||||
<h1 className='font-medium'>کدهای تخفیف</h1>
|
<h1 className='font-medium'>کدهای تخفیف</h1>
|
||||||
@@ -59,30 +83,42 @@ function TransactionsIndex() {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
{isLoading ? (
|
||||||
|
<div className='flex flex-col items-center justify-center gap-2 py-12 text-sm2 text-muted-foreground mt-6'>
|
||||||
|
<span className='h-4 w-4 animate-spin rounded-full border border-dashed border-foreground border-t-transparent'></span>
|
||||||
|
<p>در حال دریافت کدهای تخفیف...</p>
|
||||||
|
</div>
|
||||||
|
) : coupons.length === 0 ? (
|
||||||
|
<div className='flex flex-col items-center justify-center gap-2 py-12 text-sm2 text-muted-foreground mt-6'>
|
||||||
|
<p>کد تخفیفی موجود نیست</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
<section className="mt-6 space-y-6" aria-label="لیست کدهای تخفیف">
|
<section className="mt-6 space-y-6" aria-label="لیست کدهای تخفیف">
|
||||||
{[1, 2, 3].map((_, i) => (
|
{coupons.map((coupon) => (
|
||||||
<article
|
<article
|
||||||
key={i}
|
key={coupon.id}
|
||||||
className='bg-container rounded-normal flex justify-between items-center'
|
className='bg-container rounded-normal flex justify-between items-center'
|
||||||
>
|
>
|
||||||
<div className='py-4 pe-7 ps-5 border-e-2 w-full border-border border-dashed'>
|
<div className='py-4 pe-7 ps-5 border-e-2 w-full border-border border-dashed'>
|
||||||
<h3 className='font-bold text-sm2'>مبلغ تخفیف: 50,000 تومان</h3>
|
<h3 className='font-bold text-sm2'>مبلغ تخفیف: {formatDiscount(coupon)}</h3>
|
||||||
<p className='text-xs mt-[7px]'>قابل استفاده برای همهی منوها و محصولات</p>
|
<p className='text-xs mt-[7px]'>{coupon.description || 'قابل استفاده برای همهی منوها و محصولات'}</p>
|
||||||
<Button
|
<Button
|
||||||
className='w-fit px-10 py-1.5 mt-4 text-xs rounded-lg font-light'
|
className='w-fit text-white font-bold px-10 py-1.5 mt-4 text-xs rounded-lg '
|
||||||
aria-label="کپی کد تخفیف"
|
aria-label="کپی کد تخفیف"
|
||||||
|
onClick={() => handleCopyCode(coupon.code)}
|
||||||
>
|
>
|
||||||
کپی کد
|
کپی کد
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className='w-14'>
|
||||||
<p className='text-sm2 transform -rotate-90 text-[#B2B2B2] font-medium' aria-label="کد تخفیف">
|
<p className='text-sm2 transform -rotate-90 text-[#B2B2B2] font-medium' aria-label="کد تخفیف">
|
||||||
F12BB587
|
{coupon.code}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
))}
|
))}
|
||||||
</section>
|
</section>
|
||||||
|
)}
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import * as api from "../service/TransactionService";
|
||||||
|
|
||||||
|
export const useGetMyCoupons = () => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ["my-coupons"],
|
||||||
|
queryFn: api.getMyCoupons,
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { api } from "@/config/axios";
|
||||||
|
import { CouponsResponse } from "../types/Types";
|
||||||
|
|
||||||
|
export const getMyCoupons = async (): Promise<CouponsResponse> => {
|
||||||
|
const { data } = await api.get<CouponsResponse>("/public/coupons/me");
|
||||||
|
return data;
|
||||||
|
};
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { BaseResponse } from "@/app/[name]/(Main)/types/Types";
|
||||||
|
|
||||||
|
export interface Coupon {
|
||||||
|
id: string;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
deletedAt: string | null;
|
||||||
|
restaurant: string;
|
||||||
|
code: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
type: "PERCENTAGE" | "FIXED";
|
||||||
|
value: number;
|
||||||
|
maxDiscount: number | null;
|
||||||
|
minOrderAmount: number;
|
||||||
|
maxUses: number;
|
||||||
|
usedCount: number;
|
||||||
|
maxUsesPerUser: number | null;
|
||||||
|
startDate: string | null;
|
||||||
|
endDate: string | null;
|
||||||
|
isActive: boolean;
|
||||||
|
foodCategories: unknown | null;
|
||||||
|
foods: unknown | null;
|
||||||
|
userPhone: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CouponsResponse = BaseResponse<Coupon[]>;
|
||||||
Reference in New Issue
Block a user