all repos — weimar @ a8921d226b7ab5b6d366d88c51d3308362388cf7

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				<button class="link logout" onclick={handleLogout}>LOGOUT</button>
 37			{:else}
 38				<a href="/login">LOGIN</a>
 39			{/if}
 40		{/if}
 41	</div>
 42</nav>
 43
 44<div class="main">
 45	{@render children()}
 46</div>
 47
 48<style>
 49	:global(*) {
 50		margin: 0;
 51		padding: 0;
 52		box-sizing: border-box;
 53	}
 54
 55	:global(body) {
 56		font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
 57		background: #f5f5f5;
 58		color: #1a1a1a;
 59		-webkit-font-smoothing: antialiased;
 60	}
 61
 62	:global(h1) {
 63		font-family: 'Oswald', sans-serif;
 64		font-weight: 700;
 65		font-size: 2.5rem;
 66		text-transform: uppercase;
 67		letter-spacing: 0.03em;
 68		line-height: 1.1;
 69		color: #1a1a1a;
 70	}
 71
 72	:global(h2) {
 73		font-family: 'Oswald', sans-serif;
 74		font-weight: 600;
 75		font-size: 1.5rem;
 76		text-transform: uppercase;
 77		letter-spacing: 0.05em;
 78	}
 79
 80	:global(a) {
 81		color: #c62828;
 82		text-decoration: none;
 83		font-weight: 600;
 84	}
 85
 86	:global(a:hover) {
 87		text-decoration: underline;
 88	}
 89
 90	nav {
 91		display: flex;
 92		align-items: center;
 93		justify-content: space-between;
 94		padding: 0 1.5rem;
 95		height: 3.5rem;
 96		background: #1a1a1a;
 97		border-bottom: 3px solid #c62828;
 98	}
 99
100	.nav-brand {
101		display: flex;
102		align-items: center;
103		gap: 1rem;
104	}
105
106	.nav-logo {
107		font-family: 'Oswald', sans-serif;
108		font-weight: 700;
109		font-size: 1.4rem;
110		letter-spacing: 0.15em;
111		color: #fff;
112		text-decoration: none;
113	}
114	.nav-logo:hover {
115		text-decoration: none;
116		color: #ef5350;
117	}
118
119	.nav-divider {
120		display: block;
121		width: 1px;
122		height: 1.6rem;
123		background: rgba(255,255,255,0.2);
124	}
125
126	.nav-links {
127		display: flex;
128		align-items: center;
129		gap: 0;
130		height: 100%;
131	}
132
133	.nav-links a, .logout {
134		display: flex;
135		align-items: center;
136		height: 100%;
137		padding: 0 1.25rem;
138		font-family: 'Oswald', sans-serif;
139		font-weight: 500;
140		font-size: 0.85rem;
141		letter-spacing: 0.12em;
142		color: rgba(255,255,255,0.8);
143		text-decoration: none;
144		text-transform: uppercase;
145		transition: background 0.15s, color 0.15s;
146		position: relative;
147	}
148
149	.nav-links a:hover, .logout:hover {
150		background: #c62828;
151		color: #fff;
152		text-decoration: none;
153	}
154
155	.nav-links a::after {
156		content: '';
157		position: absolute;
158		bottom: 0;
159		left: 0;
160		right: 0;
161		height: 0;
162		background: #c62828;
163		transition: height 0.15s;
164	}
165
166	.nav-links a:hover::after {
167		height: 3px;
168	}
169
170	.logout {
171		background: none;
172		border: none;
173		cursor: pointer;
174		font-size: 0.85rem;
175	}
176
177	.main {
178		max-width: 1400px;
179		margin: 0 auto;
180		padding: 1.5rem;
181	}
182</style>