Pređi na sadržaj

Validacija Shema (Zod) i Upravljanje Stanjima

Svaki interaktivni widget zahtijeva dva ključna elementa:

  1. Reaktivno stanje (State): Pamćenje onoga što korisnik unosi ili mijenja u realnom vremenu (npr. pomjeranje slidera ili unos iznosa).
  2. Validacijsku shemu (Zod Schema): Osiguravanje da su unosi ispravnog tipa i unutar dozvoljenih granica prije nego što se podaci pošalju u chat ili bazu.

1. Upravljanje reaktivnim stanjem

Pitaj.io widgeti koriste jednostavan mehanizam stanja sličan React useState kuki:

// Početno stanje widgeta (Initial State)
const initialState = {
monthlyBill: 120,
roofType: "kos krov",
includeBattery: false
};
// Ažuriranje stanja na interakciju
onChange={(val) => setState({ ...state, monthlyBill: val })}

Kad god se pozove setState, widget se trenutno ponovo renderuje sa novim proračunatim vrijednostima bez ponovnog učitavanja chat prozora.


2. Validacija unosa pomoću Zod biblioteke

Kako bi se spriječili pogrešni unosi (npr. negativni iznosi novca ili neispravne email adrese), svaki widget ima pridruženu Zod shemu:

import { z } from "zod";
export const widgetSchema = z.object({
loanAmount: z
.number({ invalid_type_error: "Iznos mora biti broj" })
.min(5000, "Minimalni iznos kredita je 5.000 KM")
.max(300000, "Maksimalni iznos kredita je 300.000 KM"),
repaymentYears: z
.number()
.min(1, "Minimalni rok je 1 godina")
.max(30, "Maksimalni rok je 30 godina"),
contactEmail: z
.string()
.email("Unesite ispravnu email adresu"),
agreeToTerms: z
.boolean()
.refine((val) => val === true, "Morate prihvatiti uslove korištenja")
});

Ako korisnik unese neispravnu vrijednost, input polje automatski dobija crveni obrub i prikazuje poruku o grešci definisanu u Zod shemi.


3. Emitovanje događaja u chat (emit)

Kada korisnik završi unos i klikne na završno dugme unutar widgeta, koristi se funkcija emit za slanje strukturisanih podataka nazad agentu:

// Slanje rezultata u chat konverzaciju
onClick={() => {
const validation = widgetSchema.safeParse(state);
if (!validation.success) {
setErrors(validation.error.flatten().fieldErrors);
return;
}
// Emitovanje čistih, validiranih podataka agentu
emit("loan_calculated", {
amount: state.loanAmount,
years: state.repaymentYears,
calculatedMonthlyRate: calculateRate(state),
email: state.contactEmail
});
}}

Šta se dešava nakon emitovanja?

  1. Widget se vizuelno zaključava i označava kao završen.
  2. AI asistent prima emitovani payload i nastavlja konverzaciju:
    “Hvala vam! Na osnovu vašeg izračuna za kredit od 50.000 KM na 10 godina, vaša mjesečna rata iznosi 482.50 KM. Poslali smo detaljnu ponudu na vaš email: marko@firma.ba.”