Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
97 lines
2.8 KiB
TypeScript
97 lines
2.8 KiB
TypeScript
'use client'
|
|
|
|
import type { PropsWithChildren, ReactNode } from 'react'
|
|
|
|
import { texts } from '@/texts'
|
|
import { cn } from '@/lib/cn'
|
|
import Button from '@/components/formElements/Button'
|
|
|
|
export function WizardFormGrid({
|
|
children,
|
|
className,
|
|
singleColumn = false,
|
|
}: PropsWithChildren<{ className?: string; singleColumn?: boolean }>) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
'grid grid-cols-1 gap-x-5 gap-y-6',
|
|
!singleColumn && 'md:grid-cols-2',
|
|
singleColumn && '[&>*]:md:col-span-1',
|
|
className
|
|
)}
|
|
>
|
|
{children}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export function WizardFormFullWidth({ children, className }: PropsWithChildren<{ className?: string }>) {
|
|
return <div className={cn('col-span-1 md:col-span-2', className)}>{children}</div>
|
|
}
|
|
|
|
export function WizardSectionTitle({ children, description }: { children: ReactNode; description?: string }) {
|
|
return (
|
|
<div className="col-span-1 mb-1 rounded-2xl bg-consumer-surface-muted px-4 py-3 md:col-span-2">
|
|
<h3 className="text-sm font-bold text-text-dark">{children}</h3>
|
|
{description ? <p className="mt-1 text-xs leading-5 text-text-muted">{description}</p> : null}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
interface WizardStepFooterProps {
|
|
onBack?: () => void
|
|
backLabel?: string
|
|
primaryLabel: string
|
|
onPrimary: () => void
|
|
primaryType?: 'button' | 'submit'
|
|
isLoading?: boolean
|
|
extraStart?: ReactNode
|
|
variant?: 'default' | 'consumer'
|
|
}
|
|
|
|
export function WizardStepFooter({
|
|
onBack,
|
|
backLabel = texts.events.prevStep,
|
|
primaryLabel,
|
|
onPrimary,
|
|
primaryType = 'submit',
|
|
isLoading,
|
|
extraStart,
|
|
variant = 'default',
|
|
}: WizardStepFooterProps) {
|
|
const isConsumer = variant === 'consumer'
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
'wizard-step-footer col-span-1 mt-2 flex flex-col-reverse gap-3 sm:flex-row sm:items-center sm:justify-between md:col-span-2',
|
|
isConsumer ? 'consumer-sticky-action' : '-mx-4 border-t border-default-100 bg-white/95 px-4 pb-1 pt-4 backdrop-blur sm:mx-0'
|
|
)}
|
|
>
|
|
<div className="flex flex-wrap gap-2">
|
|
{onBack ? (
|
|
<Button
|
|
className={isConsumer ? 'min-h-12 rounded-full px-5 text-sm font-medium' : undefined}
|
|
color={isConsumer ? 'secondary-dark' : 'default'}
|
|
type="button"
|
|
variant="bordered"
|
|
onClick={onBack}
|
|
>
|
|
{backLabel}
|
|
</Button>
|
|
) : null}
|
|
{extraStart}
|
|
</div>
|
|
<Button
|
|
className={isConsumer ? 'button--xl w-full rounded-full sm:w-auto' : 'w-full sm:w-auto'}
|
|
color={isConsumer ? 'secondary-dark' : 'primary'}
|
|
isLoading={isLoading}
|
|
type={primaryType}
|
|
onClick={primaryType === 'button' ? onPrimary : undefined}
|
|
>
|
|
{primaryLabel}
|
|
</Button>
|
|
</div>
|
|
)
|
|
}
|