From 58ddfdd4c1361ef83dedad7c565992fd7d4ff9a2 Mon Sep 17 00:00:00 2001 From: Ole Magnus Fon Johnsen Date: Tue, 4 Nov 2025 17:20:14 +0100 Subject: [PATCH 1/6] fix: update emeritus --- .../src/routes/(app)/emeritus/+page.svelte | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/programmerbar-web/src/routes/(app)/emeritus/+page.svelte b/programmerbar-web/src/routes/(app)/emeritus/+page.svelte index 10cc0f2..6306aed 100644 --- a/programmerbar-web/src/routes/(app)/emeritus/+page.svelte +++ b/programmerbar-web/src/routes/(app)/emeritus/+page.svelte @@ -16,14 +16,17 @@ const members = [ 'Erik Fjelltveit Nyhuus', 'Lene Soltveit', - 'Lars Haukland', 'Steffen Andre Pettersen', 'Siren Bjorøy', 'Ole Straumland', 'Tony Lam', 'Eirik Rekve Thorsheim', - 'Ole Magnus Fon Johnsen (første CTO)', - 'August Ebne Røeggen' + 'Ole Magnus Fon Johnsen', + 'August Ebne Røeggen', + 'Fredrik Hast Sørli', + 'Sturla Rognskog Mella', + 'Tord Vikøren Vikestad', + 'Henrik Sætre Breivik' ]; const pastMembers = [ @@ -46,7 +49,8 @@ 'Simen Hauge Østbø', 'Stian Munkejord', 'Gard Heine Kalland', - 'Lars Bysheim' + 'Lars Bysheim', + 'Lars Haukland' ]; From e76df5f1dec8c94878da2fe0d8887fa087a1db8b Mon Sep 17 00:00:00 2001 From: My mac Date: Wed, 5 Nov 2025 21:08:19 +0100 Subject: [PATCH 2/6] refs Referral site, for checking all the logs --- .../lib/server/services/referral.service.ts | 19 +- .../portal/admin/bruker/[id]/+page.server.ts | 10 +- .../portal/admin/refs/+page.server.ts | 33 +++ .../(portal)/portal/admin/refs/+page.svelte | 238 ++++++++++++++++++ 4 files changed, 295 insertions(+), 5 deletions(-) create mode 100644 programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.server.ts create mode 100644 programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.svelte diff --git a/programmerbar-web/src/lib/server/services/referral.service.ts b/programmerbar-web/src/lib/server/services/referral.service.ts index b5535e7..8f0173e 100644 --- a/programmerbar-web/src/lib/server/services/referral.service.ts +++ b/programmerbar-web/src/lib/server/services/referral.service.ts @@ -1,5 +1,5 @@ import type { Database } from '$lib/server/db/drizzle'; -import { eq, and } from 'drizzle-orm'; +import { eq, and, count } from 'drizzle-orm'; import { referrals, users, type ReferralInsert } from '$lib/server/db/schemas'; import { nanoid } from 'nanoid'; import type { ShiftService } from './shift.service'; @@ -179,4 +179,21 @@ export class ReferralService { return stats; } + + async getAllReferrals(options?: { limit?: number; offset?: number }) { + return await this.#db.query.referrals.findMany({ + orderBy: (row, { desc }) => [desc(row.createdAt)], + limit: options?.limit, + offset: options?.offset, + with: { + referrer: true, + referred: true + } + }); + } + + async countAllReferrals() { + const result = await this.#db.select({ count: count() }).from(referrals); + return result[0]?.count ?? 0; + } } diff --git a/programmerbar-web/src/routes/(portal)/portal/admin/bruker/[id]/+page.server.ts b/programmerbar-web/src/routes/(portal)/portal/admin/bruker/[id]/+page.server.ts index 6a946a7..667d359 100644 --- a/programmerbar-web/src/routes/(portal)/portal/admin/bruker/[id]/+page.server.ts +++ b/programmerbar-web/src/routes/(portal)/portal/admin/bruker/[id]/+page.server.ts @@ -18,10 +18,12 @@ export const load: PageServerLoad = async ({ params, locals }) => { throw error(404, 'User not found'); } - const userShifts = await locals.shiftService.findCompletedShiftsByUserId(userId); - const unclaimedBeers = await locals.beerService.getTotalAvailableBeers(userId); - const referrals = await locals.referralService.getReferralStats(userId); - const shifts = await locals.shiftService.findUpcomingShiftsByUserId(userId); + const [userShifts, unclaimedBeers, referrals, shifts] = await Promise.all([ + locals.shiftService.findCompletedShiftsByUserId(userId), + locals.beerService.getTotalAvailableBeers(userId), + locals.referralService.getReferralStats(userId), + locals.shiftService.findUpcomingShiftsByUserId(userId) + ]); return { user, diff --git a/programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.server.ts b/programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.server.ts new file mode 100644 index 0000000..3d9f9e5 --- /dev/null +++ b/programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.server.ts @@ -0,0 +1,33 @@ +import { redirect } from '@sveltejs/kit'; +import type { PageServerLoad } from './$types'; + +const PAGE_SIZE = 20; + +export const load: PageServerLoad = async ({ locals, url }) => { + // Admin check + if (locals.user?.role !== 'board') { + throw redirect(307, '/portal'); + } + + const page = Number(url.searchParams.get('page') ?? '1'); + const requestedPage = Number.isNaN(page) || page < 1 ? 1 : page; + + const totalCount = await locals.referralService.countAllReferrals(); + const pageCount = Math.max(1, Math.ceil(totalCount / PAGE_SIZE)); + const currentPage = Math.min(requestedPage, pageCount); + + const referrals = await locals.referralService.getAllReferrals({ + limit: PAGE_SIZE, + offset: (currentPage - 1) * PAGE_SIZE + }); + + return { + referrals, + pagination: { + currentPage, + pageCount, + pageSize: PAGE_SIZE, + totalCount + } + }; +}; diff --git a/programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.svelte b/programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.svelte new file mode 100644 index 0000000..b1ac052 --- /dev/null +++ b/programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.svelte @@ -0,0 +1,238 @@ + + + + Admin - Referrals + + +
+ +
+ +
+ Referrals +

+ Oversikt over alle referrals i systemet +

+
+
+ +
+
+

Alle referrals

+

+ Viser {data.referrals.length} av {data.pagination.totalCount} totalt. +

+
+ {#if data.referrals.length === 0} +
+ Det er ingen registrerte referrals i databasen ennå. +
+ {:else} +
+ + + + + + + + + + + + {#each data.referrals as referral (referral.id)} + {@const statusBadge = getStatusBadge(referral.status)} + + + + + + + + {/each} + +
OpprettetReferrerRefereeStatusFullført
+ {formatTimestamp(referral.createdAt)} + + {referral.referrer?.name ?? 'Ukjent bruker'} + + {referral.referred?.name ?? 'Ukjent bruker'} + + + {statusBadge.label} + + + {formatTimestamp(referral.completedAt)} +
+
+
+ +
+ {/if} +
+
From 50ad46c323296359228448afb5bb10ebe8c98683 Mon Sep 17 00:00:00 2001 From: My mac Date: Wed, 5 Nov 2025 21:19:00 +0100 Subject: [PATCH 3/6] No as an service --- programmerbar-web/src/routes/+error.svelte | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/programmerbar-web/src/routes/+error.svelte b/programmerbar-web/src/routes/+error.svelte index 5aec439..b3424b2 100644 --- a/programmerbar-web/src/routes/+error.svelte +++ b/programmerbar-web/src/routes/+error.svelte @@ -10,6 +10,7 @@ TriangleAlert, Wifi } from '@lucide/svelte'; + import { onMount } from 'svelte'; type Icon = typeof CircleAlert; @@ -51,6 +52,24 @@ message: 'Noe uventet skjedde. Vennligst prøv igjen.', icon: CircleAlert }; + + let rejectionReason = $state(null); + let isLoadingReason = $state(true); + + onMount(async () => { + try { + const response = await fetch('https://naas.isalman.dev/no'); + if (response.ok) { + const data = await response.json(); + rejectionReason = data.reason; + } + } catch (err) { + // Silently fail - it's just a fun feature + console.error('Failed to fetch rejection reason:', err); + } finally { + isLoadingReason = false; + } + });
@@ -65,6 +84,19 @@

{error.title}

{error.message}

+ {#if rejectionReason} +
+

+ Avslag fra systemet +

+

"{rejectionReason}"

+
+ {:else if isLoadingReason} +
+

Henter avslagsgrunn...

+
+ {/if} + {#if page.status === 404}

Den forespurte URL-en var:

From 5597d04c4926911a2368f483f006ce7566e5d92d Mon Sep 17 00:00:00 2001 From: GardKalland Date: Thu, 6 Nov 2025 12:19:24 +0100 Subject: [PATCH 4/6] Naas and format --- .../src/routes/(app)/api/rejection/+server.ts | 24 +++++++++++++++ .../portal/admin/bruker/[id]/+page.server.ts | 12 ++++---- .../(portal)/portal/admin/refs/+page.svelte | 4 +-- programmerbar-web/src/routes/+error.svelte | 30 ++++++++++++++----- 4 files changed, 54 insertions(+), 16 deletions(-) create mode 100644 programmerbar-web/src/routes/(app)/api/rejection/+server.ts diff --git a/programmerbar-web/src/routes/(app)/api/rejection/+server.ts b/programmerbar-web/src/routes/(app)/api/rejection/+server.ts new file mode 100644 index 0000000..1c3f818 --- /dev/null +++ b/programmerbar-web/src/routes/(app)/api/rejection/+server.ts @@ -0,0 +1,24 @@ +import { json } from '@sveltejs/kit'; +import type { RequestHandler } from './$types'; + +export const GET: RequestHandler = async () => { + try { + const response = await fetch('https://naas.isalman.dev/no'); + + if (!response.ok) { + return json({ error: 'Failed to fetch rejection reason' }, { status: response.status }); + } + + const data = await response.json(); + + // Add CORS headers to allow frontend to access this endpoint + return json(data, { + headers: { + 'Cache-Control': 'public, max-age=60' + } + }); + } catch (error) { + console.error('Error fetching from naas.isalman.dev:', error); + return json({ error: 'Failed to fetch rejection reason' }, { status: 500 }); + } +}; diff --git a/programmerbar-web/src/routes/(portal)/portal/admin/bruker/[id]/+page.server.ts b/programmerbar-web/src/routes/(portal)/portal/admin/bruker/[id]/+page.server.ts index 667d359..8b395b5 100644 --- a/programmerbar-web/src/routes/(portal)/portal/admin/bruker/[id]/+page.server.ts +++ b/programmerbar-web/src/routes/(portal)/portal/admin/bruker/[id]/+page.server.ts @@ -18,12 +18,12 @@ export const load: PageServerLoad = async ({ params, locals }) => { throw error(404, 'User not found'); } - const [userShifts, unclaimedBeers, referrals, shifts] = await Promise.all([ - locals.shiftService.findCompletedShiftsByUserId(userId), - locals.beerService.getTotalAvailableBeers(userId), - locals.referralService.getReferralStats(userId), - locals.shiftService.findUpcomingShiftsByUserId(userId) - ]); + const [userShifts, unclaimedBeers, referrals, shifts] = await Promise.all([ + locals.shiftService.findCompletedShiftsByUserId(userId), + locals.beerService.getTotalAvailableBeers(userId), + locals.referralService.getReferralStats(userId), + locals.shiftService.findUpcomingShiftsByUserId(userId) + ]); return { user, diff --git a/programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.svelte b/programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.svelte index b1ac052..58d5003 100644 --- a/programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.svelte +++ b/programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.svelte @@ -115,9 +115,7 @@
Referrals -

- Oversikt over alle referrals i systemet -

+

Oversikt over alle referrals i systemet

diff --git a/programmerbar-web/src/routes/+error.svelte b/programmerbar-web/src/routes/+error.svelte index b3424b2..8d389d6 100644 --- a/programmerbar-web/src/routes/+error.svelte +++ b/programmerbar-web/src/routes/+error.svelte @@ -55,17 +55,26 @@ let rejectionReason = $state(null); let isLoadingReason = $state(true); + let fetchError = $state(false); onMount(async () => { try { - const response = await fetch('https://naas.isalman.dev/no'); + const response = await fetch('/api/rejection'); if (response.ok) { - const data = await response.json(); - rejectionReason = data.reason; + const data = (await response.json()) as { reason?: string }; + if (data && data.reason) { + rejectionReason = data.reason; + } else { + console.warn('No rejection reason in response:', data); + fetchError = true; + } + } else { + console.error('Failed to fetch rejection reason, status:', response.status); + fetchError = true; } } catch (err) { - // Silently fail - it's just a fun feature console.error('Failed to fetch rejection reason:', err); + fetchError = true; } finally { isLoadingReason = false; } @@ -78,7 +87,7 @@ class="bg-opacity-95 w-full max-w-2xl rounded-xl border-2 border-gray-300 bg-white p-8 text-center" >
- +

{page.status}

{error.title}

@@ -86,15 +95,22 @@ {#if rejectionReason}
-

+

Avslag fra systemet

-

"{rejectionReason}"

+

"{rejectionReason}"

{:else if isLoadingReason}

Henter avslagsgrunn...

+ {:else if fetchError} +
+

+ No as a Service +

+

Kunne ikke hente avslagsgrunn (sjekk konsollen)

+
{/if} {#if page.status === 404} From 3a444dbcb9cdbcf724ecb2c071bd11a0c7e5afc3 Mon Sep 17 00:00:00 2001 From: GardKalland Date: Thu, 6 Nov 2025 12:21:30 +0100 Subject: [PATCH 5/6] format --- .../src/routes/(portal)/portal/admin/refs/+page.server.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.server.ts b/programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.server.ts index 3d9f9e5..7042d16 100644 --- a/programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.server.ts +++ b/programmerbar-web/src/routes/(portal)/portal/admin/refs/+page.server.ts @@ -4,7 +4,6 @@ import type { PageServerLoad } from './$types'; const PAGE_SIZE = 20; export const load: PageServerLoad = async ({ locals, url }) => { - // Admin check if (locals.user?.role !== 'board') { throw redirect(307, '/portal'); } From 4f75d0934d1f7173abb5a1a332f93b8ca1e1ede6 Mon Sep 17 00:00:00 2001 From: GardKalland Date: Thu, 6 Nov 2025 15:42:32 +0100 Subject: [PATCH 6/6] format --- .../(portal)/portal/admin/bruker/[id]/+page.server.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/programmerbar-web/src/routes/(portal)/portal/admin/bruker/[id]/+page.server.ts b/programmerbar-web/src/routes/(portal)/portal/admin/bruker/[id]/+page.server.ts index f8cabea..8b395b5 100644 --- a/programmerbar-web/src/routes/(portal)/portal/admin/bruker/[id]/+page.server.ts +++ b/programmerbar-web/src/routes/(portal)/portal/admin/bruker/[id]/+page.server.ts @@ -14,11 +14,10 @@ export const load: PageServerLoad = async ({ params, locals }) => { } const user = await locals.userService.findById(userId); - if (!user) { - throw error(404, 'User not found'); + if (!user) { + throw error(404, 'User not found'); } - const [userShifts, unclaimedBeers, referrals, shifts] = await Promise.all([ locals.shiftService.findCompletedShiftsByUserId(userId), locals.beerService.getTotalAvailableBeers(userId), @@ -26,7 +25,6 @@ export const load: PageServerLoad = async ({ params, locals }) => { locals.shiftService.findUpcomingShiftsByUserId(userId) ]); - return { user, timesVolunteered: userShifts.length,