all repos — weimar @ 8d72190a752e3e1eaff992da40d75e01c6149993

Unnamed repository; edit this file 'description' to name the repository.

web/src/routes/+layout.svelte (view raw)

  1<script lang="ts">
  2	import { onMount } from 'svelte';
  3	import { logout } from '$lib/api';
  4
  5	let { children } = $props();
  6
  7	let loggedIn = $state(false);
  8	let checking = $state(true);
  9
 10	onMount(() => {
 11		fetch('/api/images?per_page=1', { credentials: 'include' })
 12			.then((r) => {
 13				if (r.ok) loggedIn = true;
 14			})
 15			.catch(() => {})
 16			.finally(() => { checking = false; });
 17	});
 18
 19	async function handleLogout() {
 20		await logout();
 21		loggedIn = false;
 22		window.location.href = '/login';
 23	}
 24</script>
 25
 26<nav>
 27	<div class="nav-brand">
 28		<a href="/" class="nav-logo">WEIMAR</a>
 29		<span class="nav-divider"></span>
 30	</div>
 31	<div class="nav-links">
 32		<a href="/browse">BROWSE</a>
 33		<a href="/upload">UPLOAD</a>
 34		{#if !checking}
 35			{#if loggedIn}
 36				<a href="/settings">SETTINGS</a>
 37				<button class="link logout" onclick={handleLogout}>LOGOUT</button>
 38			{:else}
 39				<a href="/login">LOGIN</a>
 40			{/if}
 41		{/if}
 42	</div>
 43</nav>
 44
 45<div class="main">
 46	{@render children()}
 47</div>
 48
 49<style>
 50	:global(*) {
 51		margin: 0;
 52		padding: 0;
 53		box-sizing: border-box;
 54	}
 55
 56	:global(body) {
 57		font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
 58		background: #f5f5f5;
 59		color: #1a1a1a;
 60		-webkit-font-smoothing: antialiased;
 61	}
 62
 63	:global(h1) {
 64		font-family: 'Oswald', sans-serif;
 65		font-weight: 700;
 66		font-size: 2.5rem;
 67		text-transform: uppercase;
 68		letter-spacing: 0.03em;
 69		line-height: 1.1;
 70		color: #1a1a1a;
 71	}
 72
 73	:global(h2) {
 74		font-family: 'Oswald', sans-serif;
 75		font-weight: 600;
 76		font-size: 1.5rem;
 77		text-transform: uppercase;
 78		letter-spacing: 0.05em;
 79	}
 80
 81	:global(a) {
 82		color: #c62828;
 83		text-decoration: none;
 84		font-weight: 600;
 85	}
 86
 87	:global(a:hover) {
 88		text-decoration: underline;
 89	}
 90
 91	nav {
 92		display: flex;
 93		align-items: center;
 94		justify-content: space-between;
 95		padding: 0 1.5rem;
 96		height: 3.5rem;
 97		background: #1a1a1a;
 98		border-bottom: 3px solid #c62828;
 99	}
100
101	.nav-brand {
102		display: flex;
103		align-items: center;
104		gap: 1rem;
105	}
106
107	.nav-logo {
108		font-family: 'Oswald', sans-serif;
109		font-weight: 700;
110		font-size: 1.4rem;
111		letter-spacing: 0.15em;
112		color: #fff;
113		text-decoration: none;
114	}
115	.nav-logo:hover {
116		text-decoration: none;
117		color: #ef5350;
118	}
119
120	.nav-divider {
121		display: block;
122		width: 1px;
123		height: 1.6rem;
124		background: rgba(255,255,255,0.2);
125	}
126
127	.nav-links {
128		display: flex;
129		align-items: center;
130		gap: 0;
131		height: 100%;
132	}
133
134	.nav-links a, .logout {
135		display: flex;
136		align-items: center;
137		height: 100%;
138		padding: 0 1.25rem;
139		font-family: 'Oswald', sans-serif;
140		font-weight: 500;
141		font-size: 0.85rem;
142		letter-spacing: 0.12em;
143		color: rgba(255,255,255,0.8);
144		text-decoration: none;
145		text-transform: uppercase;
146		transition: background 0.15s, color 0.15s;
147		position: relative;
148	}
149
150	.nav-links a:hover, .logout:hover {
151		background: #c62828;
152		color: #fff;
153		text-decoration: none;
154	}
155
156	.nav-links a::after {
157		content: '';
158		position: absolute;
159		bottom: 0;
160		left: 0;
161		right: 0;
162		height: 0;
163		background: #c62828;
164		transition: height 0.15s;
165	}
166
167	.nav-links a:hover::after {
168		height: 3px;
169	}
170
171	.logout {
172		background: none;
173		border: none;
174		cursor: pointer;
175		font-size: 0.85rem;
176	}
177
178	.main {
179		max-width: 1400px;
180		margin: 0 auto;
181		padding: 1.5rem;
182	}
183</style>