feat: Introduce mobile simulator UI with new routes, screens, shared application chrome, and updated dependencies.

This commit is contained in:
2026-02-26 13:45:00 +00:00
parent 50760ae664
commit 1ee6b21808
22 changed files with 3727 additions and 5 deletions

View File

@@ -1,9 +1,34 @@
<script lang="ts">
import './layout.css';
import { onMount } from 'svelte';
import favicon from '$lib/assets/favicon.svg';
let { children } = $props();
onMount(() => {
const bodyClasses = ['h-screen', 'bg-[#0a0a0c]', 'text-gray-200', 'overflow-hidden', 'flex'];
document.body.classList.add(...bodyClasses);
document.documentElement.dataset.theme = 'black';
const simWindow = window as Window & { __mobileSimLoaded?: boolean };
if (!simWindow.__mobileSimLoaded) {
simWindow.__mobileSimLoaded = true;
void import('$lib/sim/mobile-sim.js');
}
return () => {
document.body.classList.remove(...bodyClasses);
};
});
</script>
<svelte:head><link rel="icon" href={favicon} /></svelte:head>
<svelte:head>
<title>SecureCam Web Dashboard</title>
<link rel="icon" href={favicon} />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous" />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"
rel="stylesheet"
/>
</svelte:head>
{@render children()}

View File

@@ -1,2 +1,8 @@
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
<script lang="ts">
import AuthScreen from '$lib/sim/screens/AuthScreen.svelte';
import AppChrome from '$lib/sim/ui/AppChrome.svelte';
</script>
<AppChrome pageKey="auth">
<AuthScreen />
</AppChrome>

View File

@@ -0,0 +1,8 @@
<script lang="ts">
import ActivityScreen from '$lib/sim/screens/ActivityScreen.svelte';
import AppChrome from '$lib/sim/ui/AppChrome.svelte';
</script>
<AppChrome pageKey="activity">
<ActivityScreen />
</AppChrome>

View File

@@ -0,0 +1,8 @@
<script lang="ts">
import CameraScreen from '$lib/sim/screens/CameraScreen.svelte';
import AppChrome from '$lib/sim/ui/AppChrome.svelte';
</script>
<AppChrome pageKey="camera">
<CameraScreen />
</AppChrome>

View File

@@ -0,0 +1,8 @@
<script lang="ts">
import ClientScreen from '$lib/sim/screens/ClientScreen.svelte';
import AppChrome from '$lib/sim/ui/AppChrome.svelte';
</script>
<AppChrome pageKey="client">
<ClientScreen />
</AppChrome>

View File

@@ -1 +1,81 @@
@import 'tailwindcss';
@plugin "daisyui";
body {
font-family: 'Inter', sans-serif;
}
/* Custom Scrollbar */
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
background: rgb(0 0 0 / 20%);
}
::-webkit-scrollbar-thumb {
background: rgb(255 255 255 / 10%);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: rgb(255 255 255 / 20%);
}
.glass-panel {
background: rgb(15 15 20 / 70%);
backdrop-filter: blur(16px);
border: 1px solid rgb(255 255 255 / 5%);
}
.glass-card {
background: rgb(25 25 30 / 60%);
border: 1px solid rgb(255 255 255 / 8%);
}
.btn-premium {
background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
border: none;
color: white;
transition: all 0.2s ease;
}
.btn-premium:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgb(37 99 235 / 30%);
}
.status-dot {
height: 8px;
width: 8px;
border-radius: 50%;
display: inline-block;
}
.status-online {
background-color: #10b981;
box-shadow: 0 0 8px rgb(16 185 129 / 40%);
}
.status-offline {
background-color: #ef4444;
box-shadow: 0 0 8px rgb(239 68 68 / 40%);
}
@keyframes slideIn {
from {
transform: translateY(100%);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.toast-enter {
animation: slideIn 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

View File

@@ -0,0 +1,8 @@
<script lang="ts">
import OnboardingScreen from '$lib/sim/screens/OnboardingScreen.svelte';
import AppChrome from '$lib/sim/ui/AppChrome.svelte';
</script>
<AppChrome pageKey="onboarding">
<OnboardingScreen />
</AppChrome>

View File

@@ -4,10 +4,10 @@ import { render } from 'vitest-browser-svelte';
import Page from './+page.svelte';
describe('/+page.svelte', () => {
it('should render h1', async () => {
it('should render simulator auth heading', async () => {
render(Page);
const heading = page.getByRole('heading', { level: 1 });
const heading = page.getByRole('heading', { name: 'SecureCam Web' });
await expect.element(heading).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,8 @@
<script lang="ts">
import SettingsScreen from '$lib/sim/screens/SettingsScreen.svelte';
import AppChrome from '$lib/sim/ui/AppChrome.svelte';
</script>
<AppChrome pageKey="settings">
<SettingsScreen />
</AppChrome>