all repos — weimar @ cf03eeda27ccb78fc82bbbb91a92e2b30bd2eb18

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