feat(plan): ilk dönem sihirbazı (dönem, gelir, gider, birikim, bütçe)

- /plan/donem-ac?adim=1..5: her adım hemen kaydedilir, adım adreste
- Panel ve Plan'da açık dönem yoksa "Dönemi başlat" kartı
- MoneyInput (sayısal klavye, Türkçe biçim), moneyText/toKurus, period-dates
- lib/periods.ts: dönem, plan kalemi, özet, bütçe ve öneri kancaları
- SummaryTiles, PageLoading/PageError; 13 yeni vitest

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-12 08:16:32 +03:00
parent 95231cd4d6
commit ca0d3a505c
26 changed files with 1594 additions and 7 deletions
+93
View File
@@ -102,7 +102,100 @@ export const t = {
},
},
noPeriod: {
title: 'Henüz açık bir dönem yok',
description:
'Kakeibo her ay bir planla başlar: gelirini, sabit giderlerini ve birikim hedefini yaz, kalanı 4 gruba dağıt. Birkaç dakika sürer.',
action: 'Dönemi başlat',
},
wizard: {
title: 'Yeni dönem',
description:
'Dönemini birkaç adımda planla. Her adım hemen kaydedilir; istediğin an ara verebilirsin.',
steps: ['Dönem', 'Gelirler', 'Giderler', 'Birikim', 'Bütçe'],
stepOf: (n: number, total: number) => `Adım ${n}/${total}`,
back: 'Geri',
next: 'İleri',
saving: 'Kaydediliyor…',
dates: {
title: 'Dönemin tarihleri',
hint: 'Çoğu kişi takvim ayını seçer. Maaşın ayın ortasında yatıyorsa dönemi o güne göre de başlatabilirsin.',
presetsLabel: 'Hızlı seçim',
start: 'Başlangıç',
last: 'Son gün',
name: 'Dönem adı',
nameHint: 'Boş bırakırsan tarihlere göre otomatik verilir (ör. "Aralık 2026").',
days: (n: number) => `${n} gün · haftalar Pazartesi başlar`,
created: 'Dönem açıldı',
startRequired: 'Başlangıç tarihini seçin',
lastRequired: 'Son günü seçin',
lastBeforeStart: 'Son gün, başlangıçtan önce olamaz',
tooLong: (max: number) => `Dönem en fazla ${max} gün olabilir`,
nameTooLong: 'Dönem adı en fazla 60 karakter olabilir',
},
items: {
income: {
title: 'Sabit gelirler',
hint: 'Bu dönem beklediğin gelirler: maaş, kira geliri, burs… Tarih isteğe bağlı.',
placeholder: 'ör. Maaş',
empty: 'Henüz gelir eklenmedi.',
total: 'Toplam gelir',
},
expense: {
title: 'Sabit giderler',
hint: 'Her ay ödediğin, tutarı belli giderler: kira, aidat, faturalar, abonelikler, kredi taksiti.',
placeholder: 'ör. Kira',
empty: 'Henüz sabit gider eklenmedi.',
total: 'Toplam sabit gider',
},
name: 'Ad',
amount: 'Tutar',
date: 'Tarih (isteğe bağlı)',
add: 'Ekle',
remove: (name: string) => `${name} kalemini sil`,
removed: (name: string) => `${name} silindi`,
copy: 'Önceki dönemden kopyala',
copyHint: 'Önceki dönemin gelir ve giderleri eklenir; aynı adda olanlar atlanır.',
copied: (n: number) => (n > 0 ? `${n} kalem kopyalandı` : 'Kopyalanacak yeni kalem yok'),
nameRequired: 'Adını yazın',
nameTooLong: 'Ad en fazla 60 karakter olabilir',
dateOutside: 'Tarih dönemin içinde olmalı',
},
savings: {
title: 'Birikim hedefi',
hint: 'Kakeibo’da birikim, harcamadan önce ayrılır. Bu dönem kenara koymak istediğin tutarı yaz.',
available: 'Gelir − sabit giderler',
goal: 'Birikim hedefi',
after: 'Harcanabilir kalan',
negative: 'Birikim hedefi bu dönemin gelirini aşıyor. Tutarı azaltmayı düşünebilirsin.',
},
budget: {
title: 'Bütçe dağıtımı',
hint: 'Harcanabilir tutarı 4 gruba böl. Haftalık bütçeler, haftaların gün sayısına göre otomatik hesaplanır.',
method: 'Öneri',
methods: { default: 'Varsayılan %', previous: 'Önceki dönem', avg3: 'Son 3 dönem' },
apply: 'Öneriyi uygula',
distributed: 'Dağıtılan',
unallocated: (amount: string) => `${amount} dağıtılmadı`,
over: (amount: string) => `Harcanabilir tutar ${amount} aşıldı`,
balanced: 'Tamamı dağıtıldı 👌',
finish: 'Planı tamamla',
done: 'Dönemin hazır! Harcamalarını Defter’e yazmaya başlayabilirsin 📒',
},
},
summary: {
income: 'Gelir',
fixed: 'Sabit giderler',
savings: 'Birikim',
debt: 'Devreden borç',
surplus: 'Devreden artı',
spendable: 'Harcanabilir',
},
common: {
loading: 'Yükleniyor…',
retry: 'Tekrar dene',
},
} as const