311cfc8c60
- Kakeibo'nun 4 sorusu, nasıl hesaplandığıyla birlikte - Grup bazında planlanan/gerçekleşen, en çok harcanan kategoriler, haftalık dağılım - "Nasıl daha iyi yapabilirim?" (Markdown) ve yalnızca başlıkları listelenen notlar Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
68 lines
1.9 KiB
TypeScript
68 lines
1.9 KiB
TypeScript
import { useId, useState, type ReactNode } from 'react'
|
||
import { Markdown } from '@/components/markdown'
|
||
import { t } from '@/lib/strings'
|
||
import { cn } from '@/lib/utils'
|
||
|
||
/**
|
||
* Markdown alanı için "Yaz / Önizle" sekmeleri. `children` = yazma paneli (genelde `Textarea`).
|
||
* Kimlikler `useId` ile üretilir → aynı sayfada birden çok editör olabilir.
|
||
*/
|
||
export function MarkdownTabs({
|
||
label,
|
||
value,
|
||
children,
|
||
}: {
|
||
/** Sekme listesinin erişilebilir adı */
|
||
label: string
|
||
/** Önizlenecek metin */
|
||
value: string
|
||
children: ReactNode
|
||
}) {
|
||
const id = useId()
|
||
const [tab, setTab] = useState<'write' | 'preview'>('write')
|
||
|
||
const tabButton = (v: typeof tab, text: string) => (
|
||
<button
|
||
type="button"
|
||
role="tab"
|
||
id={`${id}-tab-${v}`}
|
||
aria-selected={tab === v}
|
||
aria-controls={`${id}-panel-${v}`}
|
||
onClick={() => setTab(v)}
|
||
className={cn(
|
||
'h-11 rounded-md px-4 text-sm font-medium transition-colors',
|
||
tab === v ? 'bg-background shadow-sm' : 'text-muted-foreground hover:text-foreground',
|
||
)}
|
||
>
|
||
{text}
|
||
</button>
|
||
)
|
||
|
||
return (
|
||
<div className="space-y-2">
|
||
<div role="tablist" aria-label={label} className="inline-flex rounded-lg bg-muted p-1">
|
||
{tabButton('write', t.notes.write)}
|
||
{tabButton('preview', t.notes.preview)}
|
||
</div>
|
||
{tab === 'write' ? (
|
||
<div id={`${id}-panel-write`} role="tabpanel" aria-labelledby={`${id}-tab-write`}>
|
||
{children}
|
||
</div>
|
||
) : (
|
||
<div
|
||
id={`${id}-panel-preview`}
|
||
role="tabpanel"
|
||
aria-labelledby={`${id}-tab-preview`}
|
||
className="min-h-40 rounded-lg border p-3"
|
||
>
|
||
{value.trim() ? (
|
||
<Markdown>{value}</Markdown>
|
||
) : (
|
||
<p className="text-sm text-muted-foreground">{t.notes.previewEmpty}</p>
|
||
)}
|
||
</div>
|
||
)}
|
||
</div>
|
||
)
|
||
}
|