From c0c298df83949e5c5f3a81046a079f06fdae9394 Mon Sep 17 00:00:00 2001 From: Katja Lutz Date: Wed, 22 Jun 2022 21:51:02 +0200 Subject: [PATCH] feat: implement index route --- src/routes/index.tsx | 358 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 src/routes/index.tsx diff --git a/src/routes/index.tsx b/src/routes/index.tsx new file mode 100644 index 0000000..817c483 --- /dev/null +++ b/src/routes/index.tsx @@ -0,0 +1,358 @@ +import { Link, Params } from "solid-app-router"; + +import { + Component, + createMemo, + JSX, + Show, + FlowComponent, + mergeProps, + ParentComponent, + createSignal, + onMount, +} from "solid-js"; +import SwissInvoice, { InvoiceData } from "~/components/SwissInvoice"; +import { Style, Title } from "solid-meta"; +import Page from "~/components/Page"; +// import HelpIcon from "~icons/carbon/help-filled"; +import LufraiLogoWww from "~icons/custom/lufrai-logo-www"; +import AppIcon from "~icons/custom/icon"; + +import { getLine1, getLine2, isStructuredAddress } from "~/components/Address"; +import Positions, { + calculatePositionsPrice, + calculatePositionsTax, +} from "~/components/Positions"; +import SettingsOverlay from "~/components/Settings/Overlay"; +import { + createLocalStore, + createStore, + createUiStore, + LocalStoreContext, + PRINT_TYPE_CONFIRMATION, + PRINT_TYPE_INVOICE, + PRINT_TYPE_OFFER, + StoreContext, + UiStoreContext, +} from "~/stores"; +import Big from "big.js"; +import { getDisplayDateFromUnix, roundToStep } from "~/util"; +import WelcomeModal from "~/components/WelcomeModal"; +import Markdown from "~/components/Markdown"; + +export default function Home() { + const store = createStore(); + const [state, setState] = store; + const localStore = createLocalStore(); + const [localState, setLocalState] = localStore; + const uiStore = createUiStore(); + const [uiState, setUiState] = uiStore; + + const invoiceData = createMemo((): InvoiceData => { + const amountBeforeTax = calculatePositionsPrice(state.positions, state); + const tax = calculatePositionsTax(amountBeforeTax, localState); + const totalAmount = new Big(amountBeforeTax).plus(tax).toNumber(); + const totalAmountRounded = roundToStep(totalAmount, 0.05); + + const creditor = localState.creditor; + + return { + iban: localState.iban || "", + amount: totalAmountRounded, + amountBeforeTax, + tax, + currency: "CHF", + message: state.invoice.message, + reference: state.invoice.reference, //generate("12345 12345 12345 12345 1"), + creditor: { + type: isStructuredAddress(creditor) ? "S" : "K", + name: creditor.name, + city: creditor.city, + zip: creditor.zip || 8500, + country: "CH", + line1: creditor.line1, + line2: creditor.line2, + }, + debtor: state.customer.debtorAddress.name + ? { + type: isStructuredAddress(state.customer.debtorAddress) ? "S" : "K", + name: state.customer.debtorAddress.name, + city: state.customer.debtorAddress.city, + zip: state.customer.debtorAddress.zip, + country: "CH", + line1: state.customer.debtorAddress.line1, + line2: state.customer.debtorAddress.line2, + } + : undefined, + }; + }); + + const InnerPadding: FlowComponent = (props) => ( +
{props.children}
+ ); + + const PageHeader: Component = () => { + const RightItem: ParentComponent< + { label: string; value?: any } & JSX.HTMLAttributes + > = (p) => { + const props = mergeProps({ show: true }, p); + + return ( + +
{props.label}
+
+ {props.children || props.value} +
+
+ ); + }; + + const address = createMemo(() => { + const value = + (localState.useCustomAddress && localState.customAddress + ? localState.customAddress + : localState.creditor) || invoiceData().creditor; + + return value; + }); + + const customerAddress = createMemo(() => { + return state.useCustomerAlternativeAddress + ? state.customer.alternativeAddress + : state.customer.debtorAddress; + }); + + const titleMemo = createMemo( + () => + (state.positions.length > 0 && `(${state.positions.length}) `) + + "Räppli" + + (state.project.projectNumber.length + ? ` - ${state.project.projectNumber}` + : "") + ); + + return ( +
+ {titleMemo()} + +
+ +
+
+
+ {address().name + ? [address().name, getLine1(address()), getLine2(address())] + .filter((x) => x != "") + .join(" · ") + : ""} +
+
+
+
{customerAddress().name}
+
{getLine1(customerAddress())}
+
{getLine2(customerAddress())}
+
+
+ + + + + + + + +
+ + + +
+ + +
+ +
+
+
+
+ ); + }; + + const PrintPreview: Component = () => { + const Title: FlowComponent = (props) => ( +
{props.children}
+ ); + + const PositionsWithData = () => ( + + ); + + const Preface = () => ( + + + + ); + + const Conclusion = () => ( + + + + ); + + const LufraiWatermark = () => ( + + + + ); + + return ( + <> + + + + + + Offerte + + + + + + + + + + + + Auftragsbestätigung + + + + + + + + + + + + Rechnung + + + +

+ Zahlungsbedingungen: {localState.paymentTerms} +

+
+ + +
+ +
+
+ + ); + }; + + const [pulsingLogo, setPulsingLogo] = createSignal(false); + onMount(function () { + setPulsingLogo(true); + setTimeout(function () { + setPulsingLogo(false); + }, 4000); + }); + + return ( + + + +
+
setLocalState("showWelcome", true)} + classList={{ + "animate-pulse": pulsingLogo() && !localState.showWelcome, + "print:hidden hover:!opacity-100 fixed z-10 right-2 top-0 text-slate-600 m-4 transition-all duration-75 hover:text-swiss-red fill-current cursor-pointer hover:scale-110 text-6xl drop-shadow-md": + true, + }} + > + +
+ + + +
+
+
+
+ ); +}