- Replaced multiple conditional AlertBanner components with a new CheckoutStatusBanners component to streamline eligibility status display. - Integrated eligibility handling logic into the CheckoutStatusBanners for improved readability and maintainability. - Updated the resolveOrderType method in CheckoutParamsService to normalize order types more effectively, enhancing the checkout process. - Modified the normalizeOrderType function in the schema to handle non-string inputs, improving robustness.
85 lines
2.8 KiB
TypeScript
85 lines
2.8 KiB
TypeScript
/**
|
|
* Checkout Domain - Schemas
|
|
*
|
|
* Zod validation schemas for checkout flow.
|
|
* Supports authenticated checkout.
|
|
*/
|
|
|
|
import { z } from "zod";
|
|
|
|
// ============================================================================
|
|
// Order Type Schema
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Checkout order types - uses PascalCase to match Salesforce/BFF contracts
|
|
* @see packages/domain/orders/contract.ts ORDER_TYPE for canonical values
|
|
*/
|
|
export const checkoutOrderTypeSchema = z.enum(["Internet", "SIM", "VPN"]);
|
|
|
|
/**
|
|
* @deprecated Use checkoutOrderTypeSchema instead. This alias exists for backwards compatibility.
|
|
*/
|
|
export const orderTypeSchema = checkoutOrderTypeSchema;
|
|
|
|
// ============================================================================
|
|
// Order Type Helpers
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Convert legacy uppercase order type to PascalCase
|
|
* Used for migrating old localStorage data
|
|
*/
|
|
export function normalizeOrderType(value: unknown): z.infer<typeof checkoutOrderTypeSchema> | null {
|
|
if (typeof value !== "string") return null;
|
|
|
|
const upper = value.trim().toUpperCase();
|
|
switch (upper) {
|
|
case "INTERNET":
|
|
return "Internet";
|
|
case "SIM":
|
|
return "SIM";
|
|
case "VPN":
|
|
return "VPN";
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Price Breakdown Schema
|
|
// ============================================================================
|
|
|
|
export const priceBreakdownItemSchema = z.object({
|
|
label: z.string(),
|
|
sku: z.string().optional(),
|
|
monthlyPrice: z.number().optional(),
|
|
oneTimePrice: z.number().optional(),
|
|
quantity: z.number().optional().default(1),
|
|
});
|
|
|
|
// ============================================================================
|
|
// Cart Item Schema
|
|
// ============================================================================
|
|
|
|
export const cartItemSchema = z.object({
|
|
orderType: orderTypeSchema,
|
|
planSku: z.string().min(1, "Plan SKU is required"),
|
|
planName: z.string().min(1, "Plan name is required"),
|
|
addonSkus: z.array(z.string()).default([]),
|
|
configuration: z.record(z.string(), z.unknown()).default({}),
|
|
pricing: z.object({
|
|
monthlyTotal: z.number().nonnegative(),
|
|
oneTimeTotal: z.number().nonnegative(),
|
|
breakdown: z.array(priceBreakdownItemSchema).default([]),
|
|
}),
|
|
});
|
|
|
|
// ============================================================================
|
|
// Inferred Types
|
|
// ============================================================================
|
|
|
|
export type OrderType = z.infer<typeof orderTypeSchema>;
|
|
export type PriceBreakdownItem = z.infer<typeof priceBreakdownItemSchema>;
|
|
export type CartItem = z.infer<typeof cartItemSchema>;
|