Skip to content
This repository was archived by the owner on Oct 22, 2025. It is now read-only.

Commit ea25815

Browse files
committed
feat: create new header navbar
1 parent 2873396 commit ea25815

File tree

8 files changed

+113
-72
lines changed

8 files changed

+113
-72
lines changed

.github/copilot-instructions.md

Lines changed: 62 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -926,39 +926,39 @@ Forms containing `<input type="file">` must use `enctype="multipart/form-data"`.
926926

927927
# SVELTEKIT + TAILWIND + TYPESCRIPT OPERATIONAL GUIDELINES
928928

929-
## PRIME DIRECTIVE
930-
Always prioritize maintainability, accessibility, and clean developer ergonomics.
931-
Collaborate via conversation while coding — **explain what, how, and why**.
929+
## PRIME DIRECTIVE
930+
Always prioritize maintainability, accessibility, and clean developer ergonomics.
931+
Collaborate via conversation while coding — **explain what, how, and why**.
932932
Avoid making multiple concurrent changes to the same file to prevent conflict or corruption.
933933

934934
---
935935

936936
## LARGE FILE & COMPLEX CHANGE PROTOCOL
937937

938-
### MANDATORY PLANNING PHASE
939-
When editing files larger than 300 lines or implementing deeply integrated features:
938+
### MANDATORY PLANNING PHASE
939+
When editing files larger than 300 lines or implementing deeply integrated features:
940940

941-
1. **Always begin with a detailed, structured edit plan**
941+
1. **Always begin with a detailed, structured edit plan**
942942
2. The plan must include:
943943
- A breakdown of all affected components, stores, routes, or layouts
944944
- The order of operations for each edit
945945
- Dependencies and known side effects
946-
- An estimated count of isolated edits required
946+
- An estimated count of isolated edits required
947947

948-
**Plan format**:
948+
**Plan format**:
949949
```md
950-
## PROPOSED EDIT PLAN
951-
Working with: [filename or route]
952-
Total planned edits: [number]
950+
## PROPOSED EDIT PLAN
951+
Working with: [filename or route]
952+
Total planned edits: [number]
953953
```
954954

955955
---
956956

957-
### MAKING EDITS
958-
- Focus on **one conceptual change at a time**
959-
- Use "before/after" snippets to demonstrate changes
960-
- Explain the **purpose** and benefit of each change clearly
961-
- Ensure edits comply with the project’s structure and coding conventions
957+
### MAKING EDITS
958+
- Focus on **one conceptual change at a time**
959+
- Use "before/after" snippets to demonstrate changes
960+
- Explain the **purpose** and benefit of each change clearly
961+
- Ensure edits comply with the project’s structure and coding conventions
962962

963963
**Edit Sequence Template**:
964964
```md
@@ -969,9 +969,9 @@ Do you approve this plan? I will proceed with Edit [#] upon your confirmation.
969969

970970
---
971971

972-
### EXECUTION PHASE
973-
- After completing each step:
974-
✅ Completed edit [#] of [total]. Ready for next edit?
972+
### EXECUTION PHASE
973+
- After completing each step:
974+
✅ Completed edit [#] of [total]. Ready for next edit?
975975
- If additional issues arise, **pause**, revise the plan, and **seek user approval before continuing**
976976

977977
---
@@ -985,46 +985,46 @@ Use the following folder layout:
985985
messages/ # Paraglide translations
986986
src/
987987
├── lib/ # Reusable UI components and utilities
988-
│ ├── components/
988+
│ ├── components/
989989
├── routes/ # SvelteKit endpoints, pages, and layouts
990990
├── app.d.ts # App-wide type definitions
991991
└── hooks.server.ts # Server hooks for session/auth
992992
```
993993

994994
---
995995

996-
### TYPING & TOOLING
996+
### TYPING & TOOLING
997997
- Use **TypeScript 5.7+** syntax and features
998998
- Prefer **Zod** for runtime validation and schema definition
999999
- Ensure all components and functions are typed strictly
10001000
- Use `readonly` for immutable structures when possible
10011001

10021002
---
10031003

1004-
### UI COMPONENTS
1005-
- Use `bits-ui`, `lucide-svelte`, and `tailwind-variants` for consistent styling
1006-
- Create generic variants using **tailwind-variants** for composability
1007-
- Favor `clsx` for class merging where conditional logic is needed
1004+
### UI COMPONENTS
1005+
- Use `bits-ui`, `lucide-svelte`, and `tailwind-variants` for consistent styling
1006+
- Create generic variants using **tailwind-variants** for composability
1007+
- Favor `clsx` for class merging where conditional logic is needed
10081008

10091009
---
10101010

1011-
### STYLING
1012-
- Use **Tailwind CSS 3.4+**
1013-
- Leverage `tailwind-merge` to prevent class duplication
1014-
- Enable `prefers-color-scheme` dark mode
1015-
- Use `tailwindcss-animate` for smooth, native animations
1011+
### STYLING
1012+
- Use **Tailwind CSS 3.4+**
1013+
- Leverage `tailwind-merge` to prevent class duplication
1014+
- Enable `prefers-color-scheme` dark mode
1015+
- Use `tailwindcss-animate` for smooth, native animations
10161016
- Organize custom styles using component-scoped `<style>` blocks or utility classes
10171017

10181018
---
10191019

1020-
### FORM MANAGEMENT
1021-
- Use **sveltekit-superforms** with **Zod** for server-enhanced forms
1022-
- Apply `formsnap` components where structured UI patterns are needed
1023-
- Always display validation feedback using `aria-invalid`, `aria-describedby`, etc.
1020+
### FORM MANAGEMENT
1021+
- Use **sveltekit-superforms** with **Zod** for server-enhanced forms
1022+
- Apply `formsnap` components where structured UI patterns are needed
1023+
- Always display validation feedback using `aria-invalid`, `aria-describedby`, etc.
10241024

10251025
---
10261026

1027-
### ACCESSIBILITY
1027+
### ACCESSIBILITY
10281028
Always meet **WCAG 2.1 AA minimum**, AAA where feasible:
10291029
- Use semantic HTML tags (`<main>`, `<section>`, etc.)
10301030
- Add labels and `aria-*` attributes to interactive elements
@@ -1033,55 +1033,55 @@ Always meet **WCAG 2.1 AA minimum**, AAA where feasible:
10331033

10341034
---
10351035

1036-
### ESLINT & FORMATTER
1037-
- Use **ESLint 9+** and **Prettier 3+**
1038-
- Extend from `eslint-config-prettier` and `eslint-plugin-svelte`
1039-
- Auto-format with `prettier-plugin-svelte`
1036+
### ESLINT & FORMATTER
1037+
- Use **ESLint 9+** and **Prettier 3+**
1038+
- Extend from `eslint-config-prettier` and `eslint-plugin-svelte`
1039+
- Auto-format with `prettier-plugin-svelte`
10401040
- TypeScript rules managed via `typescript-eslint`
10411041

10421042
---
10431043

1044-
### TESTING
1045-
- Use **Vitest** for unit and integration testing
1046-
- Use **Playwright** (recommended, not listed but consider) for E2E
1047-
- Prefer `describe`, `test`, `expect` for clarity
1044+
### TESTING
1045+
- Use **Vitest** for unit and integration testing
1046+
- Use **Playwright** (recommended, not listed but consider) for E2E
1047+
- Prefer `describe`, `test`, `expect` for clarity
10481048
- Structure tests under `/tests` with a mirrored folder structure of `/src`
10491049

10501050
---
10511051

1052-
### PERFORMANCE & BUNDLING
1053-
- Use **Vite 5** with **@sveltejs/vite-plugin-svelte**
1054-
- Enable code-splitting via dynamic imports
1055-
- Optimize assets (use `WebP`, `AVIF`, lazy loading)
1056-
- Use `@iconify-json/flag` and `unplugin-icons` for scalable icon support
1052+
### PERFORMANCE & BUNDLING
1053+
- Use **Vite 5** with **@sveltejs/vite-plugin-svelte**
1054+
- Enable code-splitting via dynamic imports
1055+
- Optimize assets (use `WebP`, `AVIF`, lazy loading)
1056+
- Use `@iconify-json/flag` and `unplugin-icons` for scalable icon support
10571057

10581058
---
10591059

1060-
### ERROR HANDLING
1061-
- Use `try/catch` consistently in load functions and API calls
1062-
- Provide user-friendly messages via `svelte-sonner`
1063-
- Log dev details to the console or a remote logger when applicable
1060+
### ERROR HANDLING
1061+
- Use `try/catch` consistently in load functions and API calls
1062+
- Provide user-friendly messages via `svelte-sonner`
1063+
- Log dev details to the console or a remote logger when applicable
10641064
- Handle:
10651065
- Network errors
10661066
- Business logic errors
1067-
- Runtime exceptions
1067+
- Runtime exceptions
10681068
- Use global event handlers like `window.addEventListener('unhandledrejection')`
10691069

10701070
---
10711071

1072-
## SECURITY BEST PRACTICES
1073-
- Sanitize all form input using Zod schemas
1074-
- Avoid client-side secrets (e.g., in `.env`)
1075-
- Enforce proper CORS and CSP headers
1076-
- Store cookies securely: `SameSite=Strict`, `HttpOnly`, `Secure`
1072+
## SECURITY BEST PRACTICES
1073+
- Sanitize all form input using Zod schemas
1074+
- Avoid client-side secrets (e.g., in `.env`)
1075+
- Enforce proper CORS and CSP headers
1076+
- Store cookies securely: `SameSite=Strict`, `HttpOnly`, `Secure`
10771077
- Use role-based access control in hooks and endpoints
10781078

10791079
---
10801080

1081-
### DEPLOYMENT CONSIDERATIONS
1082-
- Use **adapter-auto** for portability
1083-
- Consider replacing it with `adapter-vercel` or `adapter-static` depending on target platform
1084-
- Ensure SSR + client hydration is functioning
1081+
### DEPLOYMENT CONSIDERATIONS
1082+
- Use **adapter-auto** for portability
1083+
- Consider replacing it with `adapter-vercel` or `adapter-static` depending on target platform
1084+
- Ensure SSR + client hydration is functioning
10851085
- Use `.env` and `config/` files for environment-specific settings
10861086

10871087
---

messages/en.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@
2727
"cancel": "Cancel",
2828

2929
"loading": "Loading",
30+
"admin": "Admin",
31+
"profile": "Profile",
32+
"my_profile": "My profile",
33+
"settings": "Settings",
34+
"tasks": "Tasks",
3035

3136
"users_table_title": "A list of all registered Users.",
3237
"user_id": "User ID",

messages/pl.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@
2727
"cancel": "Anuluj",
2828

2929
"loading": "Ładowanie",
30+
"admin": "Admin",
31+
"profile": "Profil",
32+
"my_profile": "Mój profil",
33+
"settings": "Ustawienia",
34+
"tasks": "Zadania",
3035

3136
"users_table_title": "Lista wszystkich zarejestrowanych użytkowników.",
3237
"user_id": "ID użytkownika",

src/lib/components/ChangeLanguage.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
}
1515
</script>
1616

17-
<div class="right-2 absolute">
17+
<div class="mr-2">
1818
<button onclick={() => switchToLanguage('en')}><FlagGb4x3 /></button>
1919
<button onclick={() => switchToLanguage('pl')}><FlagPl4x3 /></button>
2020
</div>

src/lib/components/Header.svelte

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,35 @@
22
import Button from './ui/button/button.svelte';
33
import ChangeLanguage from './ChangeLanguage.svelte';
44
import * as m from '$lib/paraglide/messages.js';
5+
import { UserRole, type UserData } from '$lib/backendSchemas';
6+
import { enhance } from '$app/forms';
7+
8+
let { localUser }: { localUser: UserData | null } = $props();
59
</script>
610

7-
<header class="z-50 sticky top-0 flex items-center justify-center bg-white shadow-md">
8-
<Button href="/dashboard" size="lg" class="absolute left-2" variant="outline"
9-
>{m.dashboard_header_button()}</Button
10-
>
11-
<a href="/">
12-
<img src="/MaxitLogo.svg" alt="Maxit Logo" class="h-16 w-16" />
11+
<header class="z-50 sticky top-0 flex items-center justify-between bg-white shadow-md">
12+
<a href="/" class="flex items-center space-x-2">
13+
<img src="/MaxitLogo.svg" alt="Maxit Logo" class="h-10 w-10" />
14+
<span class="text-lg font-semibold hidden sm:block">Maxit</span>
1315
</a>
16+
<nav class="flex space-x-4 px-4">
17+
<Button href="/dashboard" variant="link" class="my-2">{m.dashboard_header_button()}</Button>
18+
<Button href="/dashboard/tasks" variant="link" class="my-2 hidden sm:block">{m.tasks()}</Button>
19+
{#if localUser?.role ?? UserRole.Student !== UserRole.Student}
20+
<Button href="/dashboard/admin" variant="link" class="my-2">{m.admin()}</Button>
21+
{/if}
22+
{#if localUser}
23+
<div class="relative group py-2 hidden sm:block">
24+
<Button variant="link">{m.profile()}</Button>
25+
<div class="absolute right-0 w-48 mt-2 bg-white border rounded shadow-lg hidden group-hover:block">
26+
<Button href="/dashboard/users/{localUser.id}" variant="ghost" class="block w-full text-left">{m.my_profile()}</Button>
27+
<Button href="/dashboard/users/{localUser.id}" variant="ghost" class="block w-full text-left">{m.settings()}</Button>
28+
<form method="post" action="/dashboard?/logout" use:enhance>
29+
<Button variant="ghost" class="block w-full text-left" type="submit">{m.logout()}</Button>
30+
</form>
31+
</div>
32+
</div>
33+
{/if}
34+
</nav>
1435
<ChangeLanguage />
1536
</header>

src/routes/+layout.server.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type { LayoutServerLoad } from './$types';
2+
3+
export const load: LayoutServerLoad = async ({ locals }) => {
4+
return {
5+
localUser: locals.user,
6+
};
7+
};

src/routes/+layout.svelte

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
import { ParaglideJS } from '@inlang/paraglide-sveltekit';
55
import { Toaster } from '$components/ui/sonner/index.js';
66
import Header from '$components/Header.svelte';
7-
let { children } = $props();
7+
import type { UserData } from '$lib/backendSchemas';
8+
let { children, data } = $props();
9+
10+
let localUser = $derived(data.localUser);
811
</script>
912

1013
<ParaglideJS {i18n}>
1114
<Toaster richColors />
1215
<main class="min-h-screen w-full flex flex-col">
13-
<Header />
16+
<Header {localUser} />
1417
{@render children?.()}
1518
</main>
1619
</ParaglideJS>

src/routes/auth/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
<LoginForm data={data.loginForm} />
1717
</div>
1818
</div>
19-
</div>
19+
</div>

0 commit comments

Comments
 (0)