my coupon

This commit is contained in:
hamid zarghami
2025-12-08 10:28:53 +03:30
parent 4dc31677c8
commit 6653cba5a0
5 changed files with 105 additions and 26 deletions
@@ -1,7 +1,31 @@
'use client';
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() {
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 (
<section className='pt-6'>
<h1 className='font-medium'>کدهای تخفیف</h1>
@@ -59,30 +83,42 @@ function TransactionsIndex() {
</div>
</section>
<section className="mt-6 space-y-6" aria-label="لیست کدهای تخفیف">
{[1, 2, 3].map((_, i) => (
<article
key={i}
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'>
<h3 className='font-bold text-sm2'>مبلغ تخفیف: 50,000 تومان</h3>
<p className='text-xs mt-[7px]'>قابل استفاده برای همهی منوها و محصولات</p>
<Button
className='w-fit px-10 py-1.5 mt-4 text-xs rounded-lg font-light'
aria-label="کپی کد تخفیف"
>
کپی کد
</Button>
</div>
<div>
<p className='text-sm2 transform -rotate-90 text-[#B2B2B2] font-medium' aria-label="کد تخفیف">
F12BB587
</p>
</div>
</article>
))}
</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="لیست کدهای تخفیف">
{coupons.map((coupon) => (
<article
key={coupon.id}
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'>
<h3 className='font-bold text-sm2'>مبلغ تخفیف: {formatDiscount(coupon)}</h3>
<p className='text-xs mt-[7px]'>{coupon.description || 'قابل استفاده برای همه‌ی منوها و محصولات'}</p>
<Button
className='w-fit text-white font-bold px-10 py-1.5 mt-4 text-xs rounded-lg '
aria-label="کپی کد تخفیف"
onClick={() => handleCopyCode(coupon.code)}
>
کپی کد
</Button>
</div>
<div className='w-14'>
<p className='text-sm2 transform -rotate-90 text-[#B2B2B2] font-medium' aria-label="کد تخفیف">
{coupon.code}
</p>
</div>
</article>
))}
</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,
});
};
+1 -1
View File
@@ -9,7 +9,7 @@ import {
} from 'iconsax-react'
import React from 'react'
function TransactionsReviewIndex () {
function TransactionsReviewIndex() {
return (
<section className='flex flex-col h-full pb-10 pt-6 gap-4'>
<h1 className='font-medium text-base'>لیست تراکنش ها</h1>
@@ -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[]>;