import { batch, Component, FlowComponent, For, Show, useContext, JSX, startTransition, createMemo, onMount, onCleanup, } from "solid-js"; import { createStore, reconcile, unwrap } from "solid-js/store"; import { format, fromUnixTime, getUnixTime } from "date-fns"; import z from "myzod"; import Big from "big.js"; import { generate } from "node-iso11649"; import { customAlphabet } from "nanoid"; import createAccordion from "../Accordion"; import { Checkbox, NumberInput, Select, TextArea, TextInput, UnixDateInput, } from "../Form"; import { autoAnimate } from "~/directives/autoAnimate"; import { ADDRESS_LAYOUT_LEFT, ADDRESS_LAYOUT_RIGHT, CURRENT_VERSION, LocalStoreContext, localStoreSchema, migrateInfoLog, migrateLocalState, migrateState, POSITION_TYPE_AGILE, POSITION_TYPE_QUANTITY, PrintType, printTypeTitles, PRINT_TYPE_CONFIRMATION, PRINT_TYPE_INVOICE, PRINT_TYPE_OFFER, StoreContext, storeSchema, UiStoreContext, } from "~/stores"; import { AddressData, isStructuredAddress } from "../Address"; import PositionsIcon from "~icons/carbon/show-data-cards"; import YouIcon from "~icons/carbon/face-wink"; import DesignIcon from "~icons/carbon/paint-brush"; import PrinterIcon from "~icons/carbon/printer"; import ProjectIcon from "~icons/carbon/product"; import DownloadIcon from "~icons/carbon/download"; import LoadIcon from "~icons/carbon/folder"; import LoadingSpinnerIcon from "~icons/icomoon-free/spinner9"; import ErrorIcon from "~icons/carbon/error"; import SuccessIcon from "~icons/carbon/checkmark-filled"; import CustomerIcon from "~icons/carbon/friendship"; import WarningIcon from "~icons/carbon/warning-alt-filled"; import GenerateIcon from "~icons/carbon/chemistry"; import DeleteIcon from "~icons/carbon/trash-can"; import { saveFile, selectLocalFiles, uploadFile } from "~/client/filesystem"; import { resetInput, sleep } from "~/util"; import { PositionsSettings } from "./Positions"; import Modal, { ModalCloseButton } from "../Modal"; import { createValidation } from "~/hooks/validation"; import { MarkdownHelpLabel } from "../Markdown"; const AccordionItemGrid: FlowComponent = (props) => { return (
{props.children}
); }; const AccordionItemEnd: Component = () => { return
; }; const AccordionItemDivider: FlowComponent = (props) => { return
{props.children}
; }; const SettingsOverlay: Component = () => { const [state, setState] = useContext(StoreContext)!; const [localState, setLocalState] = useContext(LocalStoreContext)!; const [loadModal, setLoadModal] = createStore({ open: false, loading: false, errors: null as null | { message?: JSX.Element; parseErrors: { path: string; message: string }[]; }, }); const [uiState, setUiState] = useContext(UiStoreContext)!; const [AccordionItem] = createAccordion(null); autoAnimate; const [DocumentValidationContext, documentDataForm] = createValidation(); const [YourDataValidationContext, yourDataForm] = createValidation(); const [CustomerValidationContext, customerDataForm] = createValidation(); const AddressInputs: Component<{ namePrefix?: string; nameRequired?: boolean; setter: (name: string, value: any) => void; address: () => AddressData; }> = (props) => { const isStructured = createMemo(() => isStructuredAddress(props.address())); const withPrefix = (name: string) => createMemo( () => `${props.namePrefix && props.namePrefix + "_"}${name}` )(); return ( <>
props.setter("name", evt.currentTarget.value)} />
props.setter("line1", evt.currentTarget.value)} /> props.setter("line2", evt.currentTarget.value)} /> props.setter( "zip", parseInt(evt.currentTarget.value) || undefined ) } /> props.setter("city", evt.currentTarget.value)} /> ); }; const createCustomerAddressSetter = (alternative = false) => { const addressField = alternative ? "alternativeAddress" : "debtorAddress"; return (name: any, value: any) => { setState("customer", addressField, name, value); }; }; const contactSetter = (name: any, value: any) => { setLocalState("contact", name, value); }; const fullWidthLabelWidth = "50%"; const FullWidthAccordionInput: Component[0]> = ( props ) => (
); const saveProject = () => { const fileContent = JSON.stringify( { state: unwrap(state), localState: unwrap(localState), }, null, " " ); saveFile( `rappli-${ state.project.projectNumber.length ? state.project.projectNumber.replaceAll(" ", "-") + "-" : "" }${format(fromUnixTime(state.project.date), "yyyy-MM-dd")}.json`, "application/json", fileContent ); setUiState("lastSaved", getUnixTime(new Date())); }; const saveOnCtrlS = (e: KeyboardEvent) => { if (e.ctrlKey && e.key === "s") { e.preventDefault(); saveProject(); } }; onMount(function () { document.addEventListener("keydown", saveOnCtrlS); }); onCleanup(function () { document.removeEventListener("keydown", saveOnCtrlS); }); const AccordionItemLabel: FlowComponent = (props) => ( ); const AccordionContent: FlowComponent = (props) => (
{props.children}
); let logoInputEl: HTMLInputElement = undefined!; return ( <>