feat(shopping): mağazalar, zahmet skoru ve ürünler (marka/paket, dönüşüm, görseller)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import { z } from "zod";
|
||||
import { tr } from "../../i18n/tr";
|
||||
import { MEAL_CARD_PROVIDERS } from "../accounts";
|
||||
import { parseMoney } from "../money";
|
||||
import { parseQuantity } from "../quantity";
|
||||
import { STORE_KINDS } from "../stores";
|
||||
|
||||
const v = tr.validation;
|
||||
const s = tr.stores.validation;
|
||||
|
||||
/** Boş → null; dolu → kuruş (≥ 0). */
|
||||
const optionalMoney = z
|
||||
.string()
|
||||
.trim()
|
||||
.transform((x, ctx) => {
|
||||
if (x === "") return null;
|
||||
const minor = parseMoney(x);
|
||||
if (minor === null || minor < 0) {
|
||||
ctx.addIssue({ code: "custom", message: v.money });
|
||||
return z.NEVER;
|
||||
}
|
||||
return minor;
|
||||
});
|
||||
|
||||
/** "2,5" km → 2500 m (3 ondalık = metre). Boş → null. */
|
||||
const distance = z
|
||||
.string()
|
||||
.trim()
|
||||
.transform((x, ctx) => {
|
||||
if (x === "") return null;
|
||||
const m = parseQuantity(x);
|
||||
if (m === null || m > 1_000_000) {
|
||||
ctx.addIssue({ code: "custom", message: s.distance });
|
||||
return z.NEVER;
|
||||
}
|
||||
return m;
|
||||
});
|
||||
|
||||
export const storeFormSchema = z
|
||||
.object({
|
||||
name: z.string().trim().min(1, tr.common.required).max(80, v.nameMax),
|
||||
kind: z.enum(STORE_KINDS),
|
||||
branch: z.string().trim().max(80).default(""),
|
||||
distanceKm: distance,
|
||||
carryDifficulty: z.coerce.number().int().min(1, s.carry).max(5, s.carry),
|
||||
deliveryFee: optionalMoney,
|
||||
freeDeliveryMin: optionalMoney,
|
||||
mealCardAccepted: z.boolean(),
|
||||
mealCardProviders: z.array(z.enum(MEAL_CARD_PROVIDERS)).max(MEAL_CARD_PROVIDERS.length),
|
||||
note: z.string().trim().max(300).default(""),
|
||||
})
|
||||
.superRefine((x, ctx) => {
|
||||
if (x.mealCardAccepted && x.mealCardProviders.length === 0)
|
||||
ctx.addIssue({ code: "custom", path: ["mealCardProviders"], message: s.providers });
|
||||
})
|
||||
.transform((x) => {
|
||||
const online = x.kind === "online";
|
||||
return {
|
||||
name: x.name,
|
||||
kind: x.kind,
|
||||
branch: x.branch,
|
||||
distanceM: online ? null : x.distanceKm,
|
||||
carryDifficulty: x.carryDifficulty,
|
||||
deliveryFeeMinor: online ? x.deliveryFee : null,
|
||||
freeDeliveryMinMinor: online ? x.freeDeliveryMin : null,
|
||||
mealCardAccepted: x.mealCardAccepted,
|
||||
mealCardProviders: x.mealCardAccepted ? [...new Set(x.mealCardProviders)] : [],
|
||||
note: x.note,
|
||||
};
|
||||
});
|
||||
export type StoreFormInput = z.input<typeof storeFormSchema>;
|
||||
export type StoreForm = z.output<typeof storeFormSchema>;
|
||||
Reference in New Issue
Block a user