refactor: move dashboard screens into shell routes
This commit is contained in:
@@ -13,7 +13,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body
|
<body
|
||||||
data-sveltekit-preload-data="hover"
|
data-sveltekit-preload-data="hover"
|
||||||
class="h-screen overflow-hidden flex bg-[#0a0a0c] text-gray-200"
|
class="bg-[#0a0a0c] text-gray-200"
|
||||||
style="background:#0a0a0c; color:#e5e7eb"
|
style="background:#0a0a0c; color:#e5e7eb"
|
||||||
>
|
>
|
||||||
<div style="display: contents">%sveltekit.body%</div>
|
<div style="display: contents">%sveltekit.body%</div>
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
|
||||||
const PAGE_PATHS = {
|
const PAGE_PATHS = {
|
||||||
auth: '/',
|
auth: '/auth/login',
|
||||||
onboarding: '/onboarding',
|
onboarding: '/app/onboarding',
|
||||||
camera: '/camera',
|
camera: '/app/camera',
|
||||||
client: '/client',
|
client: '/app/client',
|
||||||
activity: '/activity',
|
activity: '/app/activity',
|
||||||
settings: '/settings'
|
settings: '/app/settings'
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEVICE_STORAGE_KEY = 'mobileSimDevice';
|
const DEVICE_STORAGE_KEY = 'mobileSimDevice';
|
||||||
@@ -66,15 +66,21 @@ const normalizePath = (path) => path.replace(/\/+$/, '') || '/';
|
|||||||
|
|
||||||
export const pageFromPath = (path) => {
|
export const pageFromPath = (path) => {
|
||||||
switch (normalizePath(path)) {
|
switch (normalizePath(path)) {
|
||||||
case '/onboarding':
|
case '/auth':
|
||||||
|
case '/auth/login':
|
||||||
|
case '/auth/signup':
|
||||||
|
return 'auth';
|
||||||
|
case '/app':
|
||||||
|
return 'app';
|
||||||
|
case '/app/onboarding':
|
||||||
return 'onboarding';
|
return 'onboarding';
|
||||||
case '/camera':
|
case '/app/camera':
|
||||||
return 'camera';
|
return 'camera';
|
||||||
case '/client':
|
case '/app/client':
|
||||||
return 'client';
|
return 'client';
|
||||||
case '/activity':
|
case '/app/activity':
|
||||||
return 'activity';
|
return 'activity';
|
||||||
case '/settings':
|
case '/app/settings':
|
||||||
return 'settings';
|
return 'settings';
|
||||||
default:
|
default:
|
||||||
return 'auth';
|
return 'auth';
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ let initPromise = null;
|
|||||||
let socket = null;
|
let socket = null;
|
||||||
let pollInterval = null;
|
let pollInterval = null;
|
||||||
let socketHeartbeatInterval = null;
|
let socketHeartbeatInterval = null;
|
||||||
|
const handleBeforeUnload = () => {
|
||||||
|
void cleanupConnectionState();
|
||||||
|
};
|
||||||
|
|
||||||
let clientVideoElement = null;
|
let clientVideoElement = null;
|
||||||
|
|
||||||
@@ -839,7 +842,13 @@ const invalidateSavedDevice = async (message, options = {}) => {
|
|||||||
const enforceRouteForSession = () => {
|
const enforceRouteForSession = () => {
|
||||||
const state = getAppState();
|
const state = getAppState();
|
||||||
const page = pageFromPath(window.location.pathname);
|
const page = pageFromPath(window.location.pathname);
|
||||||
setAppState({ page });
|
const initialPage =
|
||||||
|
page === 'app'
|
||||||
|
? state.deviceToken
|
||||||
|
? getHomePageKeyForRole(state.device?.role)
|
||||||
|
: 'onboarding'
|
||||||
|
: page;
|
||||||
|
setAppState({ page: initialPage });
|
||||||
|
|
||||||
if (!state.session) {
|
if (!state.session) {
|
||||||
if (page !== 'auth') {
|
if (page !== 'auth') {
|
||||||
@@ -856,7 +865,7 @@ const enforceRouteForSession = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const expectedHome = getHomePageKeyForRole(state.device?.role);
|
const expectedHome = getHomePageKeyForRole(state.device?.role);
|
||||||
if ((page === 'auth' || page === 'onboarding') && expectedHome) {
|
if ((page === 'auth' || page === 'onboarding' || page === 'app') && expectedHome) {
|
||||||
navigateToScreen('home', { replace: true, role: state.device?.role });
|
navigateToScreen('home', { replace: true, role: state.device?.role });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -903,9 +912,7 @@ const init = async () => {
|
|||||||
void refreshCameraInputDevices();
|
void refreshCameraInputDevices();
|
||||||
applyMotionDetectionReadiness();
|
applyMotionDetectionReadiness();
|
||||||
|
|
||||||
window.addEventListener('beforeunload', () => {
|
window.addEventListener('beforeunload', handleBeforeUnload);
|
||||||
void cleanupConnectionState();
|
|
||||||
});
|
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
})().finally(() => {
|
})().finally(() => {
|
||||||
@@ -923,6 +930,7 @@ const destroy = async () => {
|
|||||||
if (typeof document !== 'undefined') {
|
if (typeof document !== 'undefined') {
|
||||||
document.removeEventListener('visibilitychange', onVisibilityChange);
|
document.removeEventListener('visibilitychange', onVisibilityChange);
|
||||||
}
|
}
|
||||||
|
window.removeEventListener('beforeunload', handleBeforeUnload);
|
||||||
initialized = false;
|
initialized = false;
|
||||||
await cleanupConnectionState();
|
await cleanupConnectionState();
|
||||||
};
|
};
|
||||||
@@ -955,6 +963,10 @@ const actions = {
|
|||||||
patchAppState((state) => ({ isRegistering: !state.isRegistering }));
|
patchAppState((state) => ({ isRegistering: !state.isRegistering }));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setAuthMode(isRegistering) {
|
||||||
|
setAppState({ isRegistering });
|
||||||
|
},
|
||||||
|
|
||||||
async submitAuth() {
|
async submitAuth() {
|
||||||
const state = getAppState();
|
const state = getAppState();
|
||||||
const { email, password, name } = state.authForm;
|
const { email, password, name } = state.authForm;
|
||||||
|
|||||||
19
WebApp/src/routes/(shell)/+layout.svelte
Normal file
19
WebApp/src/routes/(shell)/+layout.svelte
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
// @ts-nocheck
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import { appController } from '$lib/app/controller';
|
||||||
|
|
||||||
|
let { children } = $props();
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
void appController.init();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
void appController.destroy();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex h-screen overflow-hidden bg-[#0a0a0c] text-gray-200">
|
||||||
|
{@render children()}
|
||||||
|
</div>
|
||||||
34
WebApp/src/routes/(shell)/app/+page.svelte
Normal file
34
WebApp/src/routes/(shell)/app/+page.svelte
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
// @ts-nocheck
|
||||||
|
import { appController } from '$lib/app/controller';
|
||||||
|
import { appState } from '$lib/app/store';
|
||||||
|
|
||||||
|
let redirected = $state(false);
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (redirected || $appState.loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$appState.session) {
|
||||||
|
appController.navigate('auth');
|
||||||
|
redirected = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$appState.deviceToken) {
|
||||||
|
appController.navigate('onboarding');
|
||||||
|
redirected = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
appController.navigate('home');
|
||||||
|
redirected = true;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<section class="flex flex-1 items-center justify-center px-6">
|
||||||
|
<div class="rounded-full border border-white/10 bg-white/5 px-4 py-2 text-sm text-slate-300">
|
||||||
|
Preparing your workspace…
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
import '../app.css';
|
import '../app.css';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import favicon from '$lib/assets/favicon.svg';
|
import favicon from '$lib/assets/favicon.svg';
|
||||||
import { appController } from '$lib/app/controller';
|
|
||||||
import {
|
import {
|
||||||
clearInstallPrompt,
|
clearInstallPrompt,
|
||||||
setInstallPrompt,
|
setInstallPrompt,
|
||||||
@@ -85,14 +84,11 @@
|
|||||||
window.addEventListener('online', handleOnline);
|
window.addEventListener('online', handleOnline);
|
||||||
window.addEventListener('offline', handleOffline);
|
window.addEventListener('offline', handleOffline);
|
||||||
|
|
||||||
void appController.init();
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
|
window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
|
||||||
window.removeEventListener('appinstalled', handleAppInstalled);
|
window.removeEventListener('appinstalled', handleAppInstalled);
|
||||||
window.removeEventListener('online', handleOnline);
|
window.removeEventListener('online', handleOnline);
|
||||||
window.removeEventListener('offline', handleOffline);
|
window.removeEventListener('offline', handleOffline);
|
||||||
void appController.destroy();
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
5
WebApp/src/routes/activity/+page.ts
Normal file
5
WebApp/src/routes/activity/+page.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
export function load() {
|
||||||
|
throw redirect(307, '/app/activity');
|
||||||
|
}
|
||||||
5
WebApp/src/routes/camera/+page.ts
Normal file
5
WebApp/src/routes/camera/+page.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
export function load() {
|
||||||
|
throw redirect(307, '/app/camera');
|
||||||
|
}
|
||||||
5
WebApp/src/routes/client/+page.ts
Normal file
5
WebApp/src/routes/client/+page.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
export function load() {
|
||||||
|
throw redirect(307, '/app/client');
|
||||||
|
}
|
||||||
5
WebApp/src/routes/onboarding/+page.ts
Normal file
5
WebApp/src/routes/onboarding/+page.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
export function load() {
|
||||||
|
throw redirect(307, '/app/onboarding');
|
||||||
|
}
|
||||||
5
WebApp/src/routes/settings/+page.ts
Normal file
5
WebApp/src/routes/settings/+page.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
export function load() {
|
||||||
|
throw redirect(307, '/app/settings');
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user