diff --git a/apps/www/src/lib/components/app/header/Header.svelte b/apps/www/src/lib/components/app/header/Header.svelte index 346f4bfb..d963fc75 100644 --- a/apps/www/src/lib/components/app/header/Header.svelte +++ b/apps/www/src/lib/components/app/header/Header.svelte @@ -54,9 +54,11 @@ - + {#if !!$user} + {:else} + {/if} @@ -74,11 +76,11 @@ - + {#if !!$user} {:else} - + {/if} {/if} diff --git a/apps/www/src/lib/services/email.service.tsx b/apps/www/src/lib/services/email.service.tsx index 058f57f1..1288230a 100644 --- a/apps/www/src/lib/services/email.service.tsx +++ b/apps/www/src/lib/services/email.service.tsx @@ -16,6 +16,11 @@ export type InvitationEmailProps = { email: string; }; +export type VolunteerRequestEmailProps = { + name: string; + email: string; +}; + export type ShiftEmailProps = { shift: { id: string; @@ -37,11 +42,10 @@ function generateICS(shift: { summary: string; description?: string; }): string { - // Create a consistent UID based on event details - const uid = shift.id; + const uid = `${shift.startAt}-${shift.endAt}-${shift.summary.replace(/\s+/g, '-')}@programmerbar.no`; + const formatDate = (dateStr: string) => { const date = new Date(dateStr); - // Convert to local time string in YYYYMMDDTHHMMSS format const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); @@ -93,6 +97,23 @@ export class EmailService { }); } + async sendVolunteerRequestEmail(data: VolunteerRequestEmailProps) { + await this.sendEmail({ + from: FROM_EMAIL, + subject: 'Ny frivillig-søknad', + to: ['frivilligansvarlig@programmerbar.no'], + html: ` +

Ny frivillig-søknad

+

En ny person har søkt om å bli frivillig hos Programmerbar:

+
    +
  • Navn: ${data.name}
  • +
  • E-post: ${data.email}
  • +
+

Brukeren har blitt lagt til i databasen og kan nå logge inn med Feide.

+ ` + }); + } + async sendShiftEmail(data: ShiftEmailProps) { const icsContent = generateICS(data.shift); diff --git a/apps/www/src/routes/(app)/bli-frivillig/+page.server.ts b/apps/www/src/routes/(app)/bli-frivillig/+page.server.ts new file mode 100644 index 00000000..71dede4d --- /dev/null +++ b/apps/www/src/routes/(app)/bli-frivillig/+page.server.ts @@ -0,0 +1,10 @@ +// /routes/(app)/bli-frivillig/+page.server.ts +import { redirect } from '@sveltejs/kit'; +import type { PageServerLoad } from './$types'; + +export const load: PageServerLoad = async ({ locals }) => { + if (locals.user) { + throw redirect(302, '/portal'); + } + return {}; +}; diff --git a/apps/www/src/routes/(app)/bli-frivillig/+page.svelte b/apps/www/src/routes/(app)/bli-frivillig/+page.svelte new file mode 100644 index 00000000..73cc71ee --- /dev/null +++ b/apps/www/src/routes/(app)/bli-frivillig/+page.svelte @@ -0,0 +1,125 @@ + + +
+
+

Bli frivillig i Programmerbar

+

+ Som frivillig i Programmerbar får du mulighet til å være med på å skape en fantastisk + studentpub-miljø for informatikkstudenter. +

+
+
+

Hva får du som frivillig?

+
    +
  • En bong for hver vakt du jobber
  • +
  • Mulighet til å møte andre informatikkstudenter
  • +
  • Erfaring med drift av studentpub
  • +
  • Innblikk i hvordan en studentorganisasjon fungerer
  • +
+
+
+

Hva forventes av deg?

+
    +
  • Jobbe minst en vakt i måneden
  • +
  • Være ansvarlig og pålitelig
  • +
  • Ha god tid til å møte opp på vakter du har meldt deg på
  • +
+
+ {#if error} +
+

{error}

+
+ {/if} +
+
+ + +
+
+ + +

Du må bruke din student-e-post fra UiB

+
+ +
+
+

Har du allerede ein konto?

+ Logg inn +
+
diff --git a/apps/www/src/routes/api/volunteer-request/+server.ts b/apps/www/src/routes/api/volunteer-request/+server.ts new file mode 100644 index 00000000..d2304e00 --- /dev/null +++ b/apps/www/src/routes/api/volunteer-request/+server.ts @@ -0,0 +1,59 @@ +import { nanoid } from 'nanoid'; +import type { RequestHandler } from './$types'; +import { users } from '$lib/db/schemas'; + +export const POST: RequestHandler = async ({ request, locals }) => { + try { + const body = await request.json(); + const { name, email } = body as { name: string; email: string }; + + if (!email.endsWith('@student.uib.no')) { + return new Response( + JSON.stringify({ error: 'Email must be a student email (@student.uib.no)' }), + { + status: 400, + headers: { 'Content-Type': 'application/json' } + } + ); + } + + const existingUser = await locals.db.query.users.findFirst({ + where: (row, { eq }) => eq(row.email, email.toLowerCase()) + }); + + if (existingUser) { + return new Response(JSON.stringify({ error: 'User already exists' }), { + status: 400, + headers: { 'Content-Type': 'application/json' } + }); + } + + const userId = nanoid(); + const newUser = await locals.db + .insert(users) + .values({ + id: userId, + name, + email: email.toLowerCase(), + role: 'normal' + }) + .returning() + .then((rows) => rows[0]); + + await locals.emailService.sendVolunteerRequestEmail({ + name, + email + }); + + return new Response(JSON.stringify({ success: true, userId: newUser.id }), { + status: 201, + headers: { 'Content-Type': 'application/json' } + }); + } catch (error) { + console.error('Error processing volunteer request:', error); + return new Response(JSON.stringify({ error: 'Internal server error' }), { + status: 500, + headers: { 'Content-Type': 'application/json' } + }); + } +};