admin/components/events/create/AudienceRestrictionSelector.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

99 lines
3.0 KiB
TypeScript

'use client'
import { Button } from '@heroui/react'
import type { EventAgeRestriction, EventGenderRestriction } from '@/lib/eventAudience'
import { AGE_RESTRICTION_OPTIONS, GENDER_RESTRICTION_OPTIONS } from '@/lib/eventAudience'
import { cn } from '@/lib/cn'
import { texts } from '@/texts'
interface AudienceRestrictionSelectorProps {
ageRestriction: EventAgeRestriction
genderRestriction: EventGenderRestriction
disabled?: boolean
onAgeRestrictionChange: (value: EventAgeRestriction) => void
onGenderRestrictionChange: (value: EventGenderRestriction) => void
}
/** Content-width button groups for age and gender limits shown to event guests. */
export default function AudienceRestrictionSelector({
ageRestriction,
genderRestriction,
disabled = false,
onAgeRestrictionChange,
onGenderRestrictionChange,
}: AudienceRestrictionSelectorProps) {
return (
<div className={cn('grid gap-4', disabled && 'pointer-events-none opacity-70')}>
<RestrictionGroup
ariaLabel={texts.events.genderRestrictionLabel}
disabled={disabled}
options={GENDER_RESTRICTION_OPTIONS}
value={genderRestriction}
onChange={(value) => {
onGenderRestrictionChange(value as EventGenderRestriction)
}}
/>
<RestrictionGroup
ariaLabel={texts.events.ageRestrictionLabel}
disabled={disabled}
options={AGE_RESTRICTION_OPTIONS}
value={ageRestriction}
onChange={(value) => {
onAgeRestrictionChange(value as EventAgeRestriction)
}}
/>
</div>
)
}
function RestrictionGroup({
ariaLabel,
disabled = false,
options,
value,
onChange,
}: {
ariaLabel: string
disabled?: boolean
options: readonly { name: string; selectKey: string }[]
value: string
onChange: (value: string) => void
}) {
return (
<div>
<div
aria-label={ariaLabel}
className="flex w-full gap-1 rounded-xl bg-secondary-50 p-1"
role="group"
>
{options.map((option) => {
const active = option.selectKey === value
return (
<Button
key={option.selectKey}
aria-pressed={active}
className={cn(
'flex-1 min-h-10 px-3 text-xs font-medium rounded-xl',
active
? '[--button-bg:var(--color-secondary-30)] [--button-bg-hover:var(--color-secondary-30)] [--button-bg-pressed:var(--color-secondary-30)] [--button-fg:#ffffff]'
: '[--button-bg:var(--color-secondary-40)] [--button-bg-hover:var(--color-secondary-40)] [--button-bg-pressed:var(--color-secondary-40)] [--button-fg:var(--color-secondary-10)]'
)}
isDisabled={disabled}
size="sm"
variant="secondary"
onPress={() => {
if (disabled) return
onChange(option.selectKey)
}}
>
{option.name}
</Button>
)
})}
</div>
</div>
)
}