Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
139 lines
4.7 KiB
TypeScript
139 lines
4.7 KiB
TypeScript
'use client'
|
||
|
||
import { AlertDialog } from '@heroui/react'
|
||
import React, { createContext, useState } from 'react'
|
||
|
||
import type { AlertModalContextType, ShowAlertOptions } from '@/types'
|
||
import ConsumerModal from '@/components/consumer/ConsumerModal'
|
||
import Button from '@/components/formElements/Button'
|
||
import { useMediaQuery } from '@/hooks/useMediaQuery'
|
||
import { cn } from '@/lib/cn'
|
||
|
||
export const AlertModalContext = createContext<AlertModalContextType | undefined>(undefined)
|
||
|
||
interface AlertModalProviderProps {
|
||
children: React.ReactNode
|
||
variant?: 'default' | 'consumer'
|
||
}
|
||
|
||
export const AlertModalProvider = ({ children, variant = 'default' }: AlertModalProviderProps) => {
|
||
const isMobile = useMediaQuery('(max-width: 768px)')
|
||
const [isVisible, setIsVisible] = useState(false)
|
||
const [isConfirming, setIsConfirming] = useState(false)
|
||
const [message, setMessage] = useState('')
|
||
const [onConfirm, setOnConfirm] = useState<((data?: unknown) => unknown) | undefined>(undefined)
|
||
const [confirmData, setConfirmData] = useState<unknown>(undefined)
|
||
const [dangerAccept, setDangerAccept] = useState(false)
|
||
|
||
const showAlert = (msg: string, confirmCallback?: (data?: unknown) => unknown, data?: unknown, options?: ShowAlertOptions) => {
|
||
setMessage(msg)
|
||
setOnConfirm(() => confirmCallback)
|
||
setConfirmData(data)
|
||
setDangerAccept(Boolean(options?.dangerAccept))
|
||
setIsVisible(true)
|
||
}
|
||
|
||
const hideAlert = () => {
|
||
if (isConfirming) return
|
||
|
||
setIsVisible(false)
|
||
setMessage('')
|
||
setOnConfirm(undefined)
|
||
setConfirmData(undefined)
|
||
setDangerAccept(false)
|
||
}
|
||
|
||
const confirmAlert = async () => {
|
||
setIsConfirming(true)
|
||
|
||
try {
|
||
if (onConfirm) await onConfirm(confirmData)
|
||
} finally {
|
||
setIsConfirming(false)
|
||
setIsVisible(false)
|
||
setMessage('')
|
||
setOnConfirm(undefined)
|
||
setConfirmData(undefined)
|
||
setDangerAccept(false)
|
||
}
|
||
}
|
||
|
||
return (
|
||
<AlertModalContext.Provider value={{ showAlert, hideAlert }}>
|
||
{children}
|
||
{variant === 'consumer' ? (
|
||
<ConsumerModal
|
||
cancelLabel="انصراف"
|
||
isDismissable={false}
|
||
isOpen={isVisible}
|
||
isSubmitting={isConfirming}
|
||
stackLevel={1}
|
||
submitLabel="تأیید"
|
||
title="تأیید"
|
||
onCancel={hideAlert}
|
||
onOpenChange={(isOpen) => {
|
||
if (!isOpen) hideAlert()
|
||
}}
|
||
onSubmit={confirmAlert}
|
||
>
|
||
<p className="text-center font-semibold leading-7 text-overlay-foreground">{message}</p>
|
||
</ConsumerModal>
|
||
) : (
|
||
<AlertDialog>
|
||
<AlertDialog.Backdrop
|
||
isKeyboardDismissDisabled
|
||
className="z-[60]"
|
||
isDismissable={false}
|
||
isOpen={isVisible}
|
||
onOpenChange={(isOpen) => {
|
||
if (!isOpen) hideAlert()
|
||
}}
|
||
>
|
||
<AlertDialog.Container
|
||
className={isMobile ? 'p-0' : undefined}
|
||
placement={isMobile ? 'bottom' : 'center'}
|
||
size="xs"
|
||
>
|
||
<AlertDialog.Dialog
|
||
className={cn(
|
||
'border border-border bg-overlay text-right shadow-overlay sm:max-w-[400px]',
|
||
isMobile &&
|
||
'mx-0 mt-auto w-full max-w-none rounded-b-none rounded-t-3xl border-b-0 pb-[max(1rem,env(safe-area-inset-bottom))]'
|
||
)}
|
||
>
|
||
<AlertDialog.Header className="items-center text-center">
|
||
<AlertDialog.Icon status={dangerAccept ? 'danger' : 'warning'} />
|
||
</AlertDialog.Header>
|
||
<AlertDialog.Body className="text-center font-semibold leading-7 text-overlay-foreground">
|
||
<p>{message}</p>
|
||
</AlertDialog.Body>
|
||
<AlertDialog.Footer className="grid grid-cols-2 gap-2">
|
||
<Button
|
||
fullWidth
|
||
color="default"
|
||
disabled={isConfirming}
|
||
variant="light"
|
||
onClick={hideAlert}
|
||
>
|
||
انصراف
|
||
</Button>
|
||
<Button
|
||
fullWidth
|
||
color={dangerAccept ? 'danger' : 'primary'}
|
||
disabled={isConfirming}
|
||
isLoading={isConfirming}
|
||
variant={dangerAccept ? 'flat' : 'solid'}
|
||
onClick={confirmAlert}
|
||
>
|
||
تأیید
|
||
</Button>
|
||
</AlertDialog.Footer>
|
||
</AlertDialog.Dialog>
|
||
</AlertDialog.Container>
|
||
</AlertDialog.Backdrop>
|
||
</AlertDialog>
|
||
)}
|
||
</AlertModalContext.Provider>
|
||
)
|
||
}
|