You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
3.5 KiB
105 lines
3.5 KiB
import React, { useState } from 'react'
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
} from '@/components/ui/dialog'
|
|
import { Button } from '@/components/ui/button'
|
|
import { Textarea } from '@/components/ui/textarea'
|
|
import { Ic } from '@/icons'
|
|
import type { FactorItem } from '../types'
|
|
|
|
interface Props {
|
|
factor: FactorItem | null
|
|
open: boolean
|
|
onClose: () => void
|
|
onConfirm: (factorId: number, reason: string) => Promise<void>
|
|
isSubmitting?: boolean
|
|
}
|
|
|
|
export function RejectFactorDialog({
|
|
factor,
|
|
open,
|
|
onClose,
|
|
onConfirm,
|
|
isSubmitting,
|
|
}: Props) {
|
|
const [reason, setReason] = useState<string>('')
|
|
const [error, setError] = useState<string | null>(null)
|
|
|
|
if (!factor) return null
|
|
|
|
const handleConfirm = async () => {
|
|
if (!reason.trim()) {
|
|
setError('لطفاً دلیل رد فاکتور را وارد فرمایید تا به مشتری اطلاع داده شود.')
|
|
return
|
|
}
|
|
setError(null)
|
|
await onConfirm(factor.id, reason.trim())
|
|
setReason('')
|
|
onClose()
|
|
}
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={(val) => !val && onClose()}>
|
|
<DialogContent className="max-w-md border border-border/60 bg-background/95 backdrop-blur-md">
|
|
<DialogHeader>
|
|
<DialogTitle className="text-base font-bold flex items-center gap-2 text-rose-600 dark:text-rose-400">
|
|
<Ic name="xCircle" className="size-5" />
|
|
<span>رد صورتحساب #{factor.id}</span>
|
|
</DialogTitle>
|
|
<DialogDescription className="text-xs text-muted-foreground">
|
|
مشتری: {factor.user_info?.fullname || factor.user_info?.email || 'نامشخص'} • مبلغ:{' '}
|
|
{Number(factor.amount).toLocaleString()} $
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<div className="space-y-3 py-2">
|
|
<label className="text-xs font-semibold text-foreground">
|
|
دلیل رد صورتحساب / فیش پرداختی:
|
|
</label>
|
|
<Textarea
|
|
rows={4}
|
|
value={reason}
|
|
onChange={(e) => {
|
|
setReason(e.target.value)
|
|
if (error) setError(null)
|
|
}}
|
|
placeholder="مثال: فیش ناخوانا است، مبلغ واریزی مغایرت دارد، شماره رهگیری نامعتبر است..."
|
|
className="text-xs resize-none"
|
|
autoFocus
|
|
/>
|
|
{error && <p className="text-xs text-destructive font-medium">{error}</p>}
|
|
<p className="text-[11px] text-muted-foreground">
|
|
این توضیحات در اپلیکیشن مسافر / کلاینت در بخش جزئیات صورتحساب نمایش داده میشود.
|
|
</p>
|
|
</div>
|
|
|
|
<DialogFooter className="gap-2 sm:gap-0">
|
|
<Button variant="outline" size="sm" onClick={onClose} disabled={isSubmitting}>
|
|
انصراف
|
|
</Button>
|
|
<Button
|
|
variant="destructive"
|
|
size="sm"
|
|
onClick={handleConfirm}
|
|
disabled={isSubmitting}
|
|
className="gap-1.5"
|
|
>
|
|
{isSubmitting ? (
|
|
<span>در حال ثبت...</span>
|
|
) : (
|
|
<>
|
|
<Ic name="xCircle" className="size-4" />
|
|
<span>ثبت و رد فاکتور</span>
|
|
</>
|
|
)}
|
|
</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|