feat(app): initialize product shell
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import '@signature.digital/catalog';
|
||||
import { html, render } from '@design.estate/dees-element';
|
||||
|
||||
type TWorkspaceView = 'inbox' | 'compose' | 'sign' | 'audit' | 'developers' | 'templates' | 'team' | 'settings';
|
||||
|
||||
const workspaceViews: TWorkspaceView[] = ['inbox', 'compose', 'sign', 'audit', 'developers', 'templates', 'team', 'settings'];
|
||||
|
||||
const isWorkspaceView = (view: string): view is TWorkspaceView => workspaceViews.includes(view as TWorkspaceView);
|
||||
|
||||
const viewFromLocation = (): TWorkspaceView => {
|
||||
const view = globalThis.location.hash.replace(/^#/, '');
|
||||
return isWorkspaceView(view) ? view : 'inbox';
|
||||
};
|
||||
|
||||
let currentView = viewFromLocation();
|
||||
let appRoot: HTMLElement | null = null;
|
||||
let routeChangeFrame: number | null = null;
|
||||
|
||||
const createAppRoot = () => {
|
||||
document.getElementById('signature-digital-app')?.remove();
|
||||
appRoot = document.createElement('div');
|
||||
appRoot.id = 'signature-digital-app';
|
||||
document.body.append(appRoot);
|
||||
};
|
||||
|
||||
const handleViewChange = (event: Event) => {
|
||||
const view = (event as CustomEvent<{ view?: TWorkspaceView }>).detail?.view;
|
||||
if (!view || !isWorkspaceView(view)) return;
|
||||
currentView = view;
|
||||
const nextHash = `#${view}`;
|
||||
if (globalThis.location.hash !== nextHash) {
|
||||
globalThis.location.hash = view;
|
||||
}
|
||||
};
|
||||
|
||||
const handleRouteChange = () => {
|
||||
if (routeChangeFrame !== null) {
|
||||
globalThis.cancelAnimationFrame(routeChangeFrame);
|
||||
}
|
||||
routeChangeFrame = globalThis.requestAnimationFrame(() => {
|
||||
routeChangeFrame = null;
|
||||
currentView = viewFromLocation();
|
||||
renderApp();
|
||||
});
|
||||
};
|
||||
|
||||
const renderApp = () => {
|
||||
if (!appRoot) createAppRoot();
|
||||
render(
|
||||
html`
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
background: #09090b;
|
||||
color: #fafafa;
|
||||
font-family: Geist, Inter, Roboto, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
sdig-workspace {
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
<sdig-workspace accent="#3b82f6" density="comfortable" theme="dark" initialView=${currentView} .initialView=${currentView} view=${currentView} .view=${currentView}></sdig-workspace>
|
||||
`,
|
||||
appRoot!
|
||||
);
|
||||
};
|
||||
|
||||
const run = async () => {
|
||||
createAppRoot();
|
||||
document.body.addEventListener('view-change', handleViewChange);
|
||||
globalThis.addEventListener('popstate', handleRouteChange);
|
||||
globalThis.addEventListener('hashchange', handleRouteChange);
|
||||
renderApp();
|
||||
};
|
||||
|
||||
run();
|
||||
Reference in New Issue
Block a user