feat: implement second name field for postal addresses

closes issue #25
master
Katja Lutz 2 years ago
parent d236cd2aa1
commit e0f5a05c3a

@ -1,7 +1,7 @@
import { Component } from "solid-js";
import { Component, Show } from "solid-js";
import z, { Infer } from "myzod";
export const addressSchema = z.object({
const addressSchema_ = () => ({
type: z.literals("S", "K").optional(),
name: z.string(),
line1: z.string().optional(),
@ -11,9 +11,20 @@ export const addressSchema = z.object({
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 const createAddress = (data: Partial<AddressData> = {}): AddressData => {
export type PostalAddressData = Infer<typeof postalAddressSchema>;
export const createAddress = <T extends AddressData = AddressData>(
data: Partial<T> = {}
): T => {
return {
name: "",
line1: "",
@ -22,7 +33,7 @@ export const createAddress = (data: Partial<AddressData> = {}): AddressData => {
zip: undefined,
country: "CH",
...data,
};
} as any;
};
export const isStructuredAddress = (address: AddressData) => {
@ -49,9 +60,12 @@ export const getLine2 = (address: AddressData) => {
return address.line2;
};
const Address: Component<{ address: AddressData }> = (props) => (
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>
</>

@ -10,6 +10,7 @@ import {
createMemo,
onMount,
onCleanup,
mergeProps,
} from "solid-js";
import { createStore, reconcile, unwrap } from "solid-js/store";
import { format, fromUnixTime, getUnixTime } from "date-fns";
@ -51,7 +52,7 @@ import {
storeSchema,
UiStoreContext,
} from "~/stores";
import { AddressData, isStructuredAddress } from "../Address";
import { isStructuredAddress, PostalAddressData } from "../Address";
import PositionsIcon from "~icons/carbon/show-data-cards";
import YouIcon from "~icons/carbon/face-wink";
import DesignIcon from "~icons/carbon/paint-brush";
@ -110,11 +111,13 @@ const SettingsOverlay: Component = () => {
const [CustomerValidationContext, customerDataForm] = createValidation();
const AddressInputs: Component<{
postal?: boolean;
namePrefix?: string;
nameRequired?: boolean;
setter: (name: string, value: any) => void;
address: () => AddressData;
}> = (props) => {
address: () => PostalAddressData;
}> = (p) => {
const props = mergeProps({ postal: false }, p);
const isStructured = createMemo(() => isStructuredAddress(props.address()));
const withPrefix = (name: string) =>
createMemo(
@ -123,7 +126,11 @@ const SettingsOverlay: Component = () => {
return (
<>
<div class="col-span-2">
<div
classList={{
"col-span-2": !props.postal,
}}
>
<TextInput
name={withPrefix("name")}
label="Name"
@ -134,6 +141,15 @@ const SettingsOverlay: Component = () => {
/>
</div>
<Show when={props.nameRequired || props.address().name}>
<Show when={props.postal}>
<TextInput
name={withPrefix("name2")}
label="Name 2"
maxLength={70}
value={props.address().name2}
onInput={(evt) => props.setter("name2", evt.currentTarget.value)}
/>
</Show>
<TextInput
name={withPrefix("line1")}
label={isStructured() ? "Strasse" : "Linie 1"}
@ -581,6 +597,7 @@ const SettingsOverlay: Component = () => {
<AddressInputs
namePrefix="customAddress"
nameRequired={true}
postal
setter={(name, value) => {
setLocalState("customAddress", name as any, value);
}}
@ -705,6 +722,8 @@ const SettingsOverlay: Component = () => {
<Show when={state.useCustomerAlternativeAddress}>
<AccordionItemGrid>
<AddressInputs
nameRequired
postal
setter={createCustomerAddressSetter(true)}
address={() => state.customer.alternativeAddress}
/>

@ -16,7 +16,12 @@ import Page from "~/components/Page";
import LufraiLogoWww from "~icons/custom/lufrai-logo-www";
import AppIcon from "~icons/custom/icon";
import { getLine1, getLine2, isStructuredAddress } from "~/components/Address";
import Address, {
getLine1,
getLine2,
isStructuredAddress,
PostalAddressData,
} from "~/components/Address";
import Positions, {
calculatePositionsPrice,
calculatePositionsTax,
@ -124,7 +129,7 @@ export default function Home() {
);
};
const address = createMemo(() => {
const address = createMemo<PostalAddressData>(() => {
const value =
(localState.useCustomAddress && localState.customAddress
? localState.customAddress
@ -218,15 +223,18 @@ export default function Home() {
>
<div class="text-sm mb-3">
{address().name
? [address().name, getLine1(address()), getLine2(address())]
.filter((x) => x != "")
.join(" · ")
? [
address().name,
address().name2,
getLine1(address()),
getLine2(address()),
]
.filter((x) => x != "" && x != null)
.join(" ∙ ")
: ""}
</div>
<div class="text-lg leading-snug">
<div>{customerAddress().name}</div>
<div>{getLine1(customerAddress())}</div>
<div>{getLine2(customerAddress())}</div>
<Address address={customerAddress()} />
</div>
</div>
<div>

@ -1,6 +1,11 @@
import { createContext } from "solid-js";
import { createStore as createStore_ } from "solid-js/store";
import { addressSchema, createAddress } from "./components/Address";
import {
addressSchema,
createAddress,
PostalAddressData,
postalAddressSchema,
} from "./components/Address";
import { createLocalStore as createLocalStore_ } from "./localStore";
import { getUnixTime } from "date-fns";
import z, { Infer } from "myzod";
@ -84,7 +89,7 @@ export const storeSchema = z.object({
customer: z.object({
customerNumber: z.string(),
vatNumber: z.string(),
alternativeAddress: addressSchema,
alternativeAddress: postalAddressSchema,
debtorAddress: addressSchema,
}),
defaultItemPrice: z.number(),
@ -119,7 +124,9 @@ export const createStore = () =>
customer: {
customerNumber: "",
vatNumber: "",
alternativeAddress: createAddress(),
alternativeAddress: createAddress<PostalAddressData>({
name2: undefined,
}),
debtorAddress: createAddress(),
},
defaultPositionType: POSITION_TYPE_QUANTITY,
@ -143,7 +150,7 @@ export const localStoreSchema = z.object({
creditor: addressSchema,
addressLayout: z.literals(ADDRESS_LAYOUT_LEFT, ADDRESS_LAYOUT_RIGHT),
font: z.string(),
customAddress: addressSchema,
customAddress: postalAddressSchema,
contact: z.object({
name: z.string(),
phone: z.string(),
@ -195,7 +202,7 @@ export const createLocalStore = () =>
creditor: createAddress(),
font: "default",
addressLayout: ADDRESS_LAYOUT_RIGHT,
customAddress: createAddress(),
customAddress: createAddress<PostalAddressData>({ name2: undefined }),
contact: {
name: "",
phone: "",

Loading…
Cancel
Save