e188922c0f
- REGISTRATION ortam değişkeni: invite_only (varsayılan) | open - invite_only: ilk hane serbest, sonrasında yalnızca davet koduyla katılım - Backend'de zorunlu: 403 registration_closed; GET /api/auth/registration - Kayıt ekranı: kayıt kapalıyken yalnızca davet kodu ve açıklama - Entegrasyon testleri: kayıt politikası (2) - Prettier ayarı eklendi (proje stiliyle uyumlu), kaynaklar biçimlendirildi Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
50 lines
1.6 KiB
TypeScript
50 lines
1.6 KiB
TypeScript
import { Monitor, Moon, Sun } from 'lucide-react'
|
||
import { cn } from '@/lib/utils'
|
||
import { useTheme, type Theme } from '@/lib/theme'
|
||
|
||
const OPTIONS: { value: Theme; label: string; icon: typeof Sun }[] = [
|
||
{ value: 'light', label: 'Aydınlık', icon: Sun },
|
||
{ value: 'dark', label: 'Karanlık', icon: Moon },
|
||
{ value: 'system', label: 'Sistem', icon: Monitor },
|
||
]
|
||
|
||
/**
|
||
* Aydınlık / Karanlık / Sistem seçici (radyo grubu gibi davranır, klavyeyle gezilebilir).
|
||
* `compact`: yalnızca ikonlar (dar alanlar için; etiketler ekran okuyucuda kalır).
|
||
*/
|
||
export function ThemeToggle({
|
||
className,
|
||
compact = false,
|
||
}: {
|
||
className?: string
|
||
compact?: boolean
|
||
}) {
|
||
const { theme, setTheme } = useTheme()
|
||
return (
|
||
<div
|
||
role="radiogroup"
|
||
aria-label="Tema"
|
||
className={cn('inline-flex rounded-lg border bg-muted p-1', className)}
|
||
>
|
||
{OPTIONS.map(({ value, label, icon: Icon }) => (
|
||
<button
|
||
key={value}
|
||
type="button"
|
||
role="radio"
|
||
aria-checked={theme === value}
|
||
title={label}
|
||
onClick={() => setTheme(value)}
|
||
className={cn(
|
||
'inline-flex min-h-11 min-w-11 items-center justify-center gap-2 rounded-md px-3 text-sm font-medium text-muted-foreground transition-colors',
|
||
compact && 'flex-1 px-0',
|
||
theme === value && 'bg-background text-foreground shadow-sm',
|
||
)}
|
||
>
|
||
<Icon className="size-4" aria-hidden />
|
||
<span className={compact ? 'sr-only' : undefined}>{label}</span>
|
||
</button>
|
||
))}
|
||
</div>
|
||
)
|
||
}
|