initial project structure

This commit is contained in:
Jonas_Jones 2025-01-20 00:28:24 +01:00
commit 3976aa6566
24 changed files with 1941 additions and 0 deletions

57
src/routes/+layout.svelte Normal file
View file

@ -0,0 +1,57 @@
<script>
import Header from './Header.svelte';
import '../app.css';
let { children } = $props();
</script>
<div class="app">
<Header />
<main>
{@render children()}
</main>
<footer>
<p>
visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to learn about SvelteKit
</p>
</footer>
</div>
<style>
.app {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1;
display: flex;
flex-direction: column;
padding: 1rem;
width: 100%;
max-width: 64rem;
margin: 0 auto;
box-sizing: border-box;
}
footer {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 12px;
}
footer a {
font-weight: bold;
}
@media (min-width: 480px) {
footer {
padding: 12px 0;
}
}
</style>

3
src/routes/+page.js Normal file
View file

@ -0,0 +1,3 @@
// since there's no dynamic data here, we can prerender
// it so that it gets served as a static asset in production
export const prerender = true;

17
src/routes/+page.svelte Normal file
View file

@ -0,0 +1,17 @@
<script>
import { onMount } from 'svelte';
import { ensureAuthenticated } from '../utils/session.js';
onMount(() => {
ensureAuthenticated(); // This will check the session key and redirect if necessary
});
</script>
<svelte:head>
<title>Home</title>
<meta name="description" content="Svelte demo app" />
</svelte:head>
<h2>Welcome to the Dashboard</h2>
<p>You are logged in and have access to this page.</p>

129
src/routes/Header.svelte Normal file
View file

@ -0,0 +1,129 @@
<script>
import { page } from '$app/state';
import logo from '$lib/images/svelte-logo.svg';
import github from '$lib/images/github.svg';
</script>
<header>
<div class="corner">
<a href="https://svelte.dev/docs/kit">
<img src={logo} alt="SvelteKit" />
</a>
</div>
<nav>
<svg viewBox="0 0 2 3" aria-hidden="true">
<path d="M0,0 L1,2 C1.5,3 1.5,3 2,3 L2,0 Z" />
</svg>
<ul>
<li aria-current={page.url.pathname === '/' ? 'page' : undefined}>
<a href="/">Home</a>
</li>
<li aria-current={page.url.pathname === '/about' ? 'page' : undefined}>
<a href="/about">About</a>
</li>
<li aria-current={page.url.pathname.startsWith('/sverdle') ? 'page' : undefined}>
<a href="/sverdle">Sverdle</a>
</li>
</ul>
<svg viewBox="0 0 2 3" aria-hidden="true">
<path d="M0,0 L0,3 C0.5,3 0.5,3 1,2 L2,0 Z" />
</svg>
</nav>
<div class="corner">
<a href="https://github.com/sveltejs/kit">
<img src={github} alt="GitHub" />
</a>
</div>
</header>
<style>
header {
display: flex;
justify-content: space-between;
}
.corner {
width: 3em;
height: 3em;
}
.corner a {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.corner img {
width: 2em;
height: 2em;
object-fit: contain;
}
nav {
display: flex;
justify-content: center;
--background: rgba(255, 255, 255, 0.7);
}
svg {
width: 2em;
height: 3em;
display: block;
}
path {
fill: var(--background);
}
ul {
position: relative;
padding: 0;
margin: 0;
height: 3em;
display: flex;
justify-content: center;
align-items: center;
list-style: none;
background: var(--background);
background-size: contain;
}
li {
position: relative;
height: 100%;
}
li[aria-current='page']::before {
--size: 6px;
content: '';
width: 0;
height: 0;
position: absolute;
top: 0;
left: calc(50% - var(--size));
border: var(--size) solid transparent;
border-top: var(--size) solid var(--color-theme-1);
}
nav a {
display: flex;
height: 100%;
align-items: center;
padding: 0 0.5rem;
color: var(--color-text);
font-weight: 700;
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.1em;
text-decoration: none;
transition: color 0.2s linear;
}
a:hover {
color: var(--color-theme-1);
}
</style>

View file

@ -0,0 +1,9 @@
import { dev } from '$app/environment';
// we don't need any JS on this page, though we'll load
// it in dev so that we get hot module replacement
export const csr = dev;
// since there's no dynamic data here, we can prerender
// it so that it gets served as a static asset in production
export const prerender = true;

View file

@ -0,0 +1,26 @@
<svelte:head>
<title>About</title>
<meta name="description" content="About this app" />
</svelte:head>
<div class="text-column">
<h1>About this app</h1>
<p>
This is a <a href="https://svelte.dev/docs/kit">SvelteKit</a> app. You can make your own by typing
the following into your command line and following the prompts:
</p>
<pre>npx sv create</pre>
<p>
The page you're looking at is purely static HTML, with no client-side interactivity needed.
Because of that, we don't need to load any JavaScript. Try viewing the page's source, or opening
the devtools network panel and reloading.
</p>
<p>
The <a href="/sverdle">Sverdle</a> page illustrates SvelteKit's data loading and form handling. Try
using it with JavaScript disabled!
</p>
</div>

View file

@ -0,0 +1,47 @@
<script>
import { navigate } from 'svelte-routing';
import { setSessionKey } from '../../utils/session.js';
let username = '';
let password = '';
let errorMessage = '';
const handleLogin = async () => {
try {
const response = await fetch('https://your-backend-api/login', {
method: 'POST',
body: JSON.stringify({ username, password }),
headers: {
'Content-Type': 'application/json'
}
});
const data = await response.json();
if (data.sessionKey) {
// Set session key as a cookie
setSessionKey(data.sessionKey);
// Get the return URL from query parameters
const returnUrl = new URLSearchParams(window.location.search).get('returnUrl') || '/';
navigate(returnUrl); // Redirect back to the requested path
} else {
errorMessage = 'Invalid login credentials';
}
} catch (error) {
errorMessage = 'Error logging in. Please try again later.';
}
};
</script>
<h2>Login</h2>
{#if errorMessage}
<p style="color: red;">{errorMessage}</p>
{/if}
<form on:submit|preventDefault={handleLogin}>
<label for="username">Username:</label>
<input id="username" bind:value={username} required />
<label for="password">Password:</label>
<input type="password" id="password" bind:value={password} required />
<button type="submit">Login</button>
</form>