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}
+
+ {/if}
+
+
+
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' }
+ });
+ }
+};