From 20c3d4ef149268887107ddcc2b20a84db363dee6 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 18 May 2023 12:48:01 -0300 Subject: add routing --- packages/exchange-backoffice-ui/src/App.tsx | 2 +- packages/exchange-backoffice-ui/src/Dashboard.tsx | 575 +++++++++++++++++++ packages/exchange-backoffice-ui/src/Dashborad.tsx | 638 --------------------- packages/exchange-backoffice-ui/src/pages.ts | 25 + packages/exchange-backoffice-ui/src/pages/Home.tsx | 5 + .../exchange-backoffice-ui/src/pages/Settings.tsx | 5 + .../exchange-backoffice-ui/src/pages/ShowForm.tsx | 20 + .../exchange-backoffice-ui/src/pages/Welcome.tsx | 9 + packages/exchange-backoffice-ui/src/route.ts | 167 ++++++ 9 files changed, 807 insertions(+), 639 deletions(-) create mode 100644 packages/exchange-backoffice-ui/src/Dashboard.tsx delete mode 100644 packages/exchange-backoffice-ui/src/Dashborad.tsx create mode 100644 packages/exchange-backoffice-ui/src/pages.ts create mode 100644 packages/exchange-backoffice-ui/src/pages/Home.tsx create mode 100644 packages/exchange-backoffice-ui/src/pages/Settings.tsx create mode 100644 packages/exchange-backoffice-ui/src/pages/ShowForm.tsx create mode 100644 packages/exchange-backoffice-ui/src/pages/Welcome.tsx create mode 100644 packages/exchange-backoffice-ui/src/route.ts (limited to 'packages/exchange-backoffice-ui/src') diff --git a/packages/exchange-backoffice-ui/src/App.tsx b/packages/exchange-backoffice-ui/src/App.tsx index 95926e634..600131219 100644 --- a/packages/exchange-backoffice-ui/src/App.tsx +++ b/packages/exchange-backoffice-ui/src/App.tsx @@ -1,6 +1,6 @@ import { TranslationProvider } from "@gnu-taler/web-util/browser"; import { h, VNode } from "preact"; -import { Dashboard } from "./Dashborad.js"; +import { Dashboard } from "./Dashboard.js"; import "./scss/main.css"; export function App(): VNode { diff --git a/packages/exchange-backoffice-ui/src/Dashboard.tsx b/packages/exchange-backoffice-ui/src/Dashboard.tsx new file mode 100644 index 000000000..80f33954a --- /dev/null +++ b/packages/exchange-backoffice-ui/src/Dashboard.tsx @@ -0,0 +1,575 @@ +import { Dialog, Menu, Transition } from "@headlessui/react"; +import { + ChevronDownIcon, + MagnifyingGlassIcon, +} from "@heroicons/react/20/solid"; +import { + Bars3Icon, + BellIcon, + Cog6ToothIcon, + DocumentDuplicateIcon, + XMarkIcon, +} from "@heroicons/react/24/outline"; +import { ComponentChildren, Fragment, VNode, h } from "preact"; +import { ForwardedRef, forwardRef } from "preact/compat"; +import { useRef, useState } from "preact/hooks"; +import { v1 as form_902_11e_v1 } from "./forms/902_11e.js"; +import { v1 as form_902_12e_v1 } from "./forms/902_12e.js"; +import { v1 as form_902_13e_v1 } from "./forms/902_13e.js"; +import { v1 as form_902_15e_v1 } from "./forms/902_15e.js"; +import { v1 as form_902_1e_v1 } from "./forms/902_1e.js"; +import { v1 as form_902_4e_v1 } from "./forms/902_4e.js"; +import { v1 as form_902_5e_v1 } from "./forms/902_5e.js"; +import { v1 as form_902_9e_v1 } from "./forms/902_9e.js"; +import { Pages } from "./pages.js"; +import { Router, useCurrentLocation } from "./route.js"; + +/** + * references between forms + * + * 902.1e + * --> 902.11 (operational legal entity or partnership) + * --> 902.12 (a foundation) + * --> 902.13 (a trust) + * --> 902.15 (life insurance policy) + * --> 902.9 (all other cases) + * --> 902.5 (cash transaction with no customer profile) + * --> 902.4 (risk profile) + * + * 902.11 + * --> 902.9 (beneficial owner in fiduciary holding assets) + * + * 902.12 + * + * 902.13 + * + * 902.15 + * + * 902.9 + * + * 902.5 + * + * 902.4 + */ + +export const allForms = [ + { + name: "Identification form (902.1e)", + icon: DocumentDuplicateIcon, + impl: form_902_1e_v1, + }, + { + name: "Operational legal entity or partnership (902.11e)", + icon: DocumentDuplicateIcon, + impl: form_902_11e_v1, + }, + { + name: "Foundations (902.12e)", + icon: DocumentDuplicateIcon, + impl: form_902_12e_v1, + }, + { + name: "Declaration for trusts (902.13e)", + icon: DocumentDuplicateIcon, + impl: form_902_13e_v1, + }, + { + name: "Information on life insurance policies (902.15e)", + icon: DocumentDuplicateIcon, + impl: form_902_15e_v1, + }, + { + name: "Declaration of beneficial owner (902.9e)", + icon: DocumentDuplicateIcon, + impl: form_902_9e_v1, + }, + { + name: "Customer profile (902.5e)", + icon: DocumentDuplicateIcon, + impl: form_902_5e_v1, + }, + { + name: "Risk profile (902.4e)", + icon: DocumentDuplicateIcon, + impl: form_902_4e_v1, + }, +]; +const teams = [ + { id: 1, name: "Heroicons", href: "#", initial: "H", current: false }, + { id: 2, name: "Tailwind Labs", href: "#", initial: "T", current: false }, + { id: 3, name: "Workcation", href: "#", initial: "W", current: false }, +]; +const userNavigation = [ + { name: "Your profile", href: "#" }, + { name: "Sign out", href: "#" }, +]; + +function classNames(...classes: string[]) { + return classes.filter(Boolean).join(" "); +} + +/** + * mapping route to view + * not found (error page) + * nested, index element, relative routes + * link interception + * form POST interception, call action + * fromData => Object.fromEntries + * segments in the URL + * navigationState: idle, submitting, loading + * form GET interception: does a navigateTo + * form GET Sync: + * 1.- back after submit: useEffect to sync URL to form + * 2.- refresh after submit: input default value + * useSubmit for form submission onChange, history replace + * + * post form without redirect + * + * + * @param param0 + * @returns + */ + +const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : undefined; +const VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : undefined; + +const versionText = VERSION + ? GIT_HASH + ? `Version ${VERSION} (${GIT_HASH.substring(0, 8)})` + : VERSION + : ""; + +/** + * TO BE FIXED: + * + * 1.- when the form change to other form and both form share the same structure + * the same input component may be rendered in the same place, + * since input are uncontrolled the are not re-rendered and since they are + * uncontrolled it will keep the value of the previous form. + * One solutions could be to remove the form when unloading and when the new + * form load it will start without previous vdom, preventing the cache + * to create this behavior. + * Other solutions could be using IDs in the fields that are constructed + * with the ID of the form, so two fields of different form will need to re-render + * cleaning up the state of the previous form. + * + * 2.- currently the design prop and the behavior prop of the flexible form + * are two side of the same coin. From the design point of view, it is important + * to design the form in a list-of-field manner and there may be additional + * content that is not directly mapped to the form structure (object) + * So maybe we want to change the current shape so the computation of the state + * of the form is in a field level, but this computation required the field value and + * the whole form values and state (since one field may be disabled/hidden) because + * of the value of other field. + * + * 3.- given the previous requirement, maybe the name of the field of the form could be + * a function (P: F -> V) where F is the form (or parent object) and V is the type of the + * property. That will help with the typing of the forms props + * + * 4.- tooltip are not placed correctly: the arrow should point the question mark + * and the text area should be bigger + * + * 5.- date field should have the calendar icon clickable so the user can select date without + * writing text with the correct format + */ + +export function Dashboard({ + children, +}: { + children?: ComponentChildren; +}): VNode { + const [sidebarOpen, setSidebarOpen] = useState(false); + + const logRef = useRef(null); + function showFormOnSidebar(v: any) { + if (!logRef.current) return; + logRef.current.innerHTML = JSON.stringify(v, undefined, 1); + } + + const Nav = forwardRef(NavigationBar); + return ( + +