server/web/src/lib/components/PageGrid.svelte
vegard ca27a8077b SvelteKit-app, SpacetimeDB-modul og chat med sanntid
SvelteKit (web/):
- Komplett app-skjelett med Authentik SSO (dev-bypass lokalt)
- Workspace-modell med cookie-basert switching og RLS-kontekst
- Komponerbare sider (PageGrid + BlockShell + block registry)
- Chat med adapter-mønster: PG-polling og SpacetimeDB hybrid-adapter
- Brukeridentitet fra Authentik/dev-login flyter til chat-meldinger
- API-ruter for channels, messages og health

SpacetimeDB (spacetimedb/):
- Rust WASM-modul med ChatMessage og SyncOutbox-tabeller
- send_message reducer med sync outbox for fremtidig PG-persistering
- Genererte TypeScript-bindings for klient-integrasjon

Infra:
- SpacetimeDB lagt til i docker-compose.dev.yml

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 01:40:55 +01:00

61 lines
1.3 KiB
Svelte

<script lang="ts">
import type { Component } from 'svelte';
import type { PageConfig } from '$lib/types/pages';
import { getGridColumns } from '$lib/types/pages';
import { blockRegistry } from '$lib/blocks/registry';
import BlockShell from './BlockShell.svelte';
let { page }: { page: PageConfig } = $props();
let resolved = $state<Record<string, Component>>({});
$effect(() => {
for (const block of page.blocks) {
const meta = blockRegistry[block.type];
if (meta && !resolved[block.id]) {
meta.component().then((m) => {
resolved[block.id] = m.default;
});
}
}
});
let gridColumns = $derived(getGridColumns(page.layout));
</script>
<div class="page-grid" style:grid-template-columns={gridColumns}>
{#each page.blocks as block (block.id)}
<BlockShell title={block.title}>
{@const BlockComponent = resolved[block.id]}
{#if BlockComponent}
<BlockComponent props={block.props ?? {}} />
{:else}
<div class="loading">Laster...</div>
{/if}
</BlockShell>
{/each}
</div>
<style>
.page-grid {
display: grid;
gap: 1rem;
height: calc(100vh - 48px - 3rem);
}
@media (max-width: 768px) {
.page-grid {
grid-template-columns: 1fr !important;
height: auto;
}
}
.loading {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
color: #8b92a5;
font-size: 0.85rem;
}
</style>