- Implemented FormStep component for user input (name, email, address). - Created OtpStep component for OTP verification. - Developed SuccessStep component to display success messages based on account creation. - Introduced eligibility-check.store for managing state throughout the eligibility check process. - Added commitlint configuration for standardized commit messages. - Configured knip for workspace management and project structure.
93 lines
3.0 KiB
TypeScript
93 lines
3.0 KiB
TypeScript
import {
|
|
orderConfigurationsSchema,
|
|
orderSelectionsSchema,
|
|
type OrderConfigurations,
|
|
type CreateOrderRequest,
|
|
type OrderSelections,
|
|
} from "./schema.js";
|
|
import { ORDER_TYPE, type CheckoutCart, type OrderTypeValue } from "./contract.js";
|
|
|
|
export type CheckoutOrderTypeValue = Extract<OrderTypeValue, "Internet" | "SIM" | "VPN">;
|
|
|
|
export function isCheckoutOrderType(value: unknown): value is CheckoutOrderTypeValue {
|
|
return value === ORDER_TYPE.INTERNET || value === ORDER_TYPE.SIM || value === ORDER_TYPE.VPN;
|
|
}
|
|
|
|
export function toCheckoutOrderType(orderType: OrderTypeValue): CheckoutOrderTypeValue | null {
|
|
return isCheckoutOrderType(orderType) ? orderType : null;
|
|
}
|
|
|
|
export function toOrderTypeValueFromCheckout(
|
|
orderType: string | null | undefined
|
|
): OrderTypeValue | null {
|
|
return isCheckoutOrderType(orderType) ? orderType : null;
|
|
}
|
|
|
|
export function buildOrderConfigurations(selections: OrderSelections): OrderConfigurations {
|
|
const normalizedSelections = orderSelectionsSchema.parse(selections);
|
|
|
|
return orderConfigurationsSchema.parse({
|
|
...normalizedSelections,
|
|
address: normalizedSelections.address
|
|
? {
|
|
street: normalizedSelections.address.street ?? null,
|
|
streetLine2: normalizedSelections.address.streetLine2 ?? null,
|
|
city: normalizedSelections.address.city ?? null,
|
|
state: normalizedSelections.address.state ?? null,
|
|
postalCode: normalizedSelections.address.postalCode ?? null,
|
|
country: normalizedSelections.address.country ?? null,
|
|
}
|
|
: undefined,
|
|
});
|
|
}
|
|
|
|
export function createOrderRequest(payload: {
|
|
orderType?: string;
|
|
skus: string[];
|
|
configurations?: OrderSelections | null;
|
|
}): CreateOrderRequest {
|
|
const orderType = (payload.orderType ?? ORDER_TYPE.OTHER) as CreateOrderRequest["orderType"];
|
|
const configurations = payload.configurations
|
|
? buildOrderConfigurations(payload.configurations)
|
|
: undefined;
|
|
return {
|
|
orderType,
|
|
skus: payload.skus,
|
|
...(configurations ? { configurations } : {}),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Transform CheckoutCart into CreateOrderRequest
|
|
* Handles SKU extraction, validation, and payload formatting
|
|
*
|
|
* @throws Error if no products are selected
|
|
*/
|
|
export function prepareOrderFromCart(
|
|
cart: CheckoutCart,
|
|
orderType: OrderTypeValue
|
|
): CreateOrderRequest {
|
|
const uniqueSkus = [
|
|
...new Set(
|
|
cart.items
|
|
.map(item => item.sku)
|
|
.filter((sku): sku is string => typeof sku === "string" && sku.trim().length > 0)
|
|
),
|
|
];
|
|
|
|
if (uniqueSkus.length === 0) {
|
|
throw new Error("No products selected for order. Please go back and select products.");
|
|
}
|
|
|
|
// Note: Zod validation of the final structure should happen at the boundary or via schema.parse
|
|
// This function focuses on the structural transformation logic.
|
|
|
|
const orderData: CreateOrderRequest = {
|
|
orderType,
|
|
skus: uniqueSkus,
|
|
...(Object.keys(cart.configuration).length > 0 ? { configurations: cart.configuration } : {}),
|
|
};
|
|
|
|
return orderData;
|
|
}
|