admin/components/events/create/WizardFormLayout.tsx
alisaza e1eaf5eff5 feat: initial ghabilee-admin backoffice app
Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js
app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
2026-09-05 13:12:59 +03:30

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>
)
}