feat: implement reactive stores and store models

master
Katja Lutz 2 years ago
parent a46be3e8dc
commit 69e624b097

@ -0,0 +1,184 @@
import { createContext } from "solid-js";
import { createStore as createStore_ } from "solid-js/store";
import { addressSchema, createAddress } from "./components/Address";
import { createLocalStore as createLocalStore_ } from "./localStore";
import { getUnixTime } from "date-fns";
import z, { Infer } from "myzod";
export const POSITION_TYPE_QUANTITY = "QUANTITY";
export const POSITION_TYPE_AGILE = "AGILE";
export const positionSchema = z.object({
id: z.number(),
name: z.string(),
enabled: z.boolean(),
type: z.literals(POSITION_TYPE_QUANTITY, POSITION_TYPE_AGILE),
agilePointsMin: z.number().optional(),
agilePointsMax: z.number().optional(),
agileRiskFactor: z.number().optional(),
number: z.string().optional(),
description: z.string().optional(),
quantity: z.number(),
fixedDiscountPrice: z.number().optional(),
itemPrice: z.number().optional(),
});
export type Position = Infer<typeof positionSchema>;
export const PRINT_TYPE_OFFER = "OFFER";
export const PRINT_TYPE_CONFIRMATION = "CONFIRMATION";
export const PRINT_TYPE_INVOICE = "INVOICE";
export const createUiStore = () =>
createStore_({
printType: PRINT_TYPE_INVOICE as
| typeof PRINT_TYPE_OFFER
| typeof PRINT_TYPE_CONFIRMATION
| typeof PRINT_TYPE_INVOICE,
selectedPosition: undefined as undefined | number,
});
export type UiStore = ReturnType<typeof createUiStore>;
export const UiStoreContext = createContext<UiStore>();
export const storeSchema = z.object({
version: z.number(),
project: z.object({
orderNumber: z.string(),
projectNumber: z.string(),
deliveryNumber: z.string(),
deliveryDate: z.number().optional(),
date: z.number(),
preface: z.string().optional(),
conclusion: z.string().optional(),
}),
invoice: z.object({
reference: z.string(),
message: z.string(),
}),
fullWidthInvoice: z.boolean(),
useCustomerAlternativeAddress: z.boolean(),
customer: z.object({
customerNumber: z.string(),
vatNumber: z.string(),
alternativeAddress: addressSchema,
debtorAddress: addressSchema,
}),
defaultItemPrice: z.number(),
agileRiskFactor: z.number(),
agileHoursPerStoryPoint: z.number(),
defaultPositionType: z.literals(POSITION_TYPE_QUANTITY, POSITION_TYPE_AGILE),
positions: z.array(positionSchema),
});
export type StoreObject = Infer<typeof storeSchema>;
export const createStore = () =>
createStore_<StoreObject>({
version: 1,
project: {
orderNumber: "",
projectNumber: "",
deliveryNumber: "",
date: getUnixTime(new Date()),
},
invoice: {
reference: "",
message: "",
},
fullWidthInvoice: true,
useCustomerAlternativeAddress: false,
customer: {
customerNumber: "",
vatNumber: "",
alternativeAddress: createAddress(),
debtorAddress: createAddress(),
},
defaultPositionType: POSITION_TYPE_QUANTITY,
defaultItemPrice: 0,
agileRiskFactor: 0.7,
agileHoursPerStoryPoint: 4,
positions: [
{
id: 0,
name: "Entwicklung",
enabled: true,
quantity: 0,
agilePointsMin: 8,
agilePointsMax: 13,
itemPrice: 80,
type: POSITION_TYPE_AGILE,
},
{
id: 1,
name: "Kaffee Trinken",
enabled: true,
quantity: 2,
itemPrice: 160,
type: POSITION_TYPE_QUANTITY,
},
{
id: 2,
name: "Pizza Essen",
enabled: true,
quantity: 1,
itemPrice: 280,
type: POSITION_TYPE_QUANTITY,
},
] as Position[],
});
export type Store = ReturnType<typeof createStore>;
export const StoreContext = createContext<Store>();
export const localStoreSchema = z.object({
showWelcome: z.boolean(),
version: z.number(),
vatNumber: z.string(),
vatRate: z.number(),
paymentTerms: z.string().optional(),
iban: z.string(),
creditor: addressSchema,
customAddress: addressSchema,
contact: z.object({
name: z.string(),
phone: z.string(),
email: z.string(),
}),
showLufraiWatermark: z.boolean(),
// TODO: Signature Image
logo: z
.object({
type: z.string(),
url: z.string(),
width: z.number(),
height: z.number(),
})
.optional(),
useCustomAddress: z.boolean(),
});
export type LocalStoreObject = Infer<typeof localStoreSchema>;
export const createLocalStore = () =>
createLocalStore_<LocalStoreObject>(
{
version: 1,
showWelcome: true,
vatNumber: "",
vatRate: 0.0,
paymentTerms: undefined,
creditor: createAddress(),
customAddress: createAddress(),
contact: {
name: "",
phone: "",
email: "",
},
logo: undefined,
showLufraiWatermark: false,
useCustomAddress: false,
iban: "",
},
{ prefix: "invoice-app" }
);
export type LocalStore = ReturnType<typeof createLocalStore>;
export const LocalStoreContext = createContext<LocalStore>();
Loading…
Cancel
Save