trkit
Menü

Rehberler

Türkçe formlar

Türkçe hata mesajları, TCKN/IBAN/telefon doğrulama ve il/ilçe seçimiyle form yazma.

.mdChatGPT'de açClaude'da aç

create-trkit-app projelerindeki src/app/iletisim/ dizini çalışan bir örnektir. Bu sayfa o örneği adım adım açıklar.

1. Şema

src/app/iletisim/schema.ts
import { cepTelefonu } from "@trkit-app-pack/validate";
import { isValidDistrict } from "@trkit-app-pack/address";
import { basHarfleriBuyut } from "@trkit-app-pack/format";
import { z } from "@/lib/zod"; // Türkçe hata mesajları

export const iletisimSchema = z
  .object({
    adSoyad: z.string().trim().min(3).max(80).transform(basHarfleriBuyut),
    eposta: z.email(),
    telefon: cepTelefonu,                       // "0532 123 45 67" → "+905321234567"
    il: z.coerce.number().int().min(1, "İl seçiniz").max(81),
    ilce: z.string({ message: "İlçe seçiniz" }).min(1, "İlçe seçiniz"),
    mesaj: z.string().trim().min(10).max(2000),
    ticariIleti: z.boolean().default(false),
  })
  .refine((v) => isValidDistrict(v.il, v.ilce), { path: ["ilce"], message: "Seçilen ilçe bu ile ait değil" });

Hazır mesajlar: "En az 3 karakter olmalıdır", "Geçerli bir e-posta adresi giriniz", "Bu alan zorunludur", "Geçerli bir cep telefonu giriniz (5XX XXX XX XX)".

2. Server action

src/app/iletisim/actions.ts
"use server";
import { iletisimSchema } from "./schema";

export async function iletisimGonder(_prev: FormState, formData: FormData): Promise<FormState> {
  const values = Object.fromEntries(formData) as Record<string, string>;
  const parsed = iletisimSchema.safeParse({ ...values, ticariIleti: values.ticariIleti === "on" });
  if (!parsed.success) {
    const errors: Record<string, string> = {};
    for (const i of parsed.error.issues) errors[String(i.path[0])] ??= i.message;
    return { status: "error", errors, values };
  }
  // parsed.data.telefon E.164 biçiminde, adSoyad düzgün büyük harfli
  return { status: "success", adSoyad: parsed.data.adSoyad };
}

3. Form

const [state, action, pending] = useActionState(iletisimGonder, { status: "idle" });
const [konum, setKonum] = useState<IlIlceDegeri>({ il: null, ilce: null });

<form action={action}>
  <input name="telefon" type="tel" inputMode="tel" autoComplete="tel-national" placeholder="05XX XXX XX XX" />
  <IlIlceSecici value={konum} onChange={setKonum} name={{ il: "il", ilce: "ilce" }} error={{ il: err.il, ilce: err.ilce }} />
</form>

Hazır şemalar

ŞemaKabul ederDönüştürür
tckn11 hane, algoritma kontrolüboşlukları temizler
vkn10 hane, algoritma kontrolü
vergiNoTCKN veya VKN (fatura formları)
ibanTR IBAN, mod-97TR33 0006 … → TR330006…
telefonmobil, sabit, 850E.164 +90…
cepTelefonuyalnızca 5XXE.164
plaka34 ABC 123 vb.34ABC123
postaKodu5 hane, il kodu 01–81
mersis16 hane

Özel mesaj için şema fabrikalarını kullanın: tcknSchema({ message: "TC kimlik numaranızı kontrol edin" }), phoneSchema({ mobileOnly: true }).

İpuçları

  • Telefon alanında inputMode="tel" mobilde rakam klavyesini açar.
  • TCKN algoritma kontrolü numaranın gerçek bir kişiye ait olduğunu göstermez. Kimlik doğrulaması gerekiyorsa NVİ KPS servisi gerekir.
  • Loglarda maskTckn() ve maskPhone() kullanın.