You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
1.9 KiB
TypeScript
83 lines
1.9 KiB
TypeScript
import { Component, Show } from "solid-js";
|
|
import z, { Infer } from "myzod";
|
|
|
|
const addressSchema_ = () => ({
|
|
type: z.literals("S", "K").optional(),
|
|
name: z.string(),
|
|
line1: z.string().optional(),
|
|
line2: z.string().optional(),
|
|
city: z.string().optional(),
|
|
zip: z.number().optional(),
|
|
country: z.string(),
|
|
});
|
|
|
|
export const addressSchema = z.object(addressSchema_());
|
|
|
|
export const postalAddressSchema = z.object({
|
|
...addressSchema_(),
|
|
name2: z.string().optional(),
|
|
});
|
|
|
|
export type AddressData = Infer<typeof addressSchema>;
|
|
|
|
export type PostalAddressData = Infer<typeof postalAddressSchema>;
|
|
|
|
export const createAddress = <T extends AddressData = AddressData>(
|
|
data: Partial<T> = {}
|
|
): T => {
|
|
return {
|
|
name: "",
|
|
line1: "",
|
|
line2: "",
|
|
city: "",
|
|
zip: undefined,
|
|
country: "CH",
|
|
...data,
|
|
} as any;
|
|
};
|
|
|
|
export const isStructuredAddress = (address: AddressData) => {
|
|
if (address.type) {
|
|
return address.type === "S";
|
|
}
|
|
|
|
return address.city || address.zip != null;
|
|
};
|
|
|
|
export const getLine1 = (address: AddressData) => {
|
|
if (isStructuredAddress(address)) {
|
|
return `${address.line1 || ""} ${address.line2 || ""}`;
|
|
}
|
|
|
|
return address.line1;
|
|
};
|
|
|
|
export const getLine2 = (address: AddressData) => {
|
|
if (isStructuredAddress(address)) {
|
|
return `${address.zip || ""} ${address.city || ""}`;
|
|
}
|
|
|
|
return address.line2;
|
|
};
|
|
|
|
const Address: Component<{ address: PostalAddressData }> = (props) => (
|
|
<>
|
|
<div>{props.address.name}</div>
|
|
<Show when={props.address.name2}>
|
|
<div>{props.address.name2}</div>
|
|
</Show>
|
|
<div>{getLine1(props.address)}</div>
|
|
<div>{getLine2(props.address)}</div>
|
|
</>
|
|
);
|
|
|
|
export const applyAddress = (target: AddressData, values: AddressData) => {
|
|
target.name = values.name;
|
|
target.line1 = values.line1;
|
|
target.line2 = values.line2;
|
|
target.zip = values.zip;
|
|
target.city = values.city;
|
|
};
|
|
|
|
export default Address;
|