Valgfagsprojekt (Front-End Projekt)


Opgavebeskrivelse

Front‑End projektet på 3. semester var et individuelt projekt, hvor hver studerende skulle udvikle en del af en datadreven front‑end løsning. Projektet skulle demonstrere brug af API‑kald og relevante teknologier som f.eks. Vue.js og Firebase. Fokus var på funktionalitet frem for design, og løsningen skulle præsenteres mundtligt med en live demo for resten af holdet.

Idésamling of Forberedelse

Som gruppe besluttede vi at arbejde med noget, der kunne understøtte vores kampagneside fra eksamensprojektet. Efter introduktionen satte vi os sammen og diskuterede idéer og opgavefordeling. Jeg fik idéen og ansvaret for at udvikle et registreringsfelt, hvor brugere kunne indtaste deres tilmeldingsinformationer. Disse data skulle gemmes i en database, kunne hentes frem igen og opdateres ved hjælp af en genereret medlemskode.

Derudover skulle systemet automatisk sende en e‑mail til den angivne adresse, når en tilmelding blev gennemført. Det var en funktion, der både gav værdi til kampagnesiden og samtidig udfordrede mig teknisk.

Proces

I den følgende uge eksperimenterede jeg med konceptet. Jeg havde begrænset kodeerfaring og følte mig usikker på, hvordan jeg skulle bygge projektet op. Det skulle laves i Vue med Firebase hosting og realtime database, og jeg var nervøs for at lave fejl. For at komme videre brugte jeg ChatGPT som sparringspartner, når jeg var i tvivl om, hvordan jeg skulle gribe opgaven an.

Jeg fik oprettet et Vue‑projekt og koblet det sammen med mit Firebase‑projekt, hvor jeg opsatte både databasen og hosting. Derefter gik jeg i gang med selve koden. Da fokus var på funktionalitet og ikke design, lavede jeg ingen designudkast – også fordi tidsrammen var stram.

Jeg byggede en side med to bokse:

  • Tilmeldingsboks: Her kunne brugeren indtaste sine oplysninger, som blev gemt i databasen.
  • Opdateringsboks: Her kunne man indtaste sine medlemskoder, hvorefter en ny boks åbnede, hvor man kunne ændre, gemme eller slette sine informationer.

Jeg samlede det hele på én side for at bevare overblikket og holde løsningen enkel. Med hjælp af Email.js fik jeg opsat en funktion, der automatisk sendte en e‑mail med medlemskoderne til den angivne adresse. Koden genererede en tilfældig medlemskode for hver ny tilmelding, og efter lidt trial‑and‑error fik jeg det hele til at fungere.

Min App.vue kode, som eksempel

<template>
  <div class="container">
    <h1>Bliv medlem</h1>
    <form @submit.prevent="onSubmit">
      <input v-model="name" placeholder="Navn" required />
      <input v-model="email" type="email" placeholder="Email" required />
      <input v-model.number="age" type="number" placeholder="Alder" required />
      <button type="submit">Tilmeld</button>
    </form>

    <p v-if="message">{{ message }}</p>

    <h1>Medlemsadministration</h1>
    <MemberEdit />
  </div> 
  
  <Registration />
</template>

<script setup>
// src/App.vue
import { ref } from 'vue'
import emailjs from 'emailjs-com'
import { db } from './firebase'
import { ref as dbRef, push, set } from 'firebase/database'
import MemberEdit from './components/MemberEdit.vue'
import Registration from "./components/Registration.vue";

const name = ref('')
const email = ref('')
const age = ref(null)
const message = ref('')

// Generate a random membership code
function generateCode(len = 8) {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
  let s = ''
  for (let i = 0; i < len; i++) s += chars.charAt(Math.floor(Math.random() * chars.length))
  return s
}

async function onSubmit() {
  if (!name.value || !email.value || !age.value) {
    message.value = 'Udfyld alle felter.'
    return
  }

  try {
    // 1) Member in Realtime DB erstellen
    const membersRef = dbRef(db, 'members')
    const newMemberRef = push(membersRef)
    const code = generateCode(6)

    await set(newMemberRef, {
      name: name.value,
      email: email.value,
      age: age.value,
      membershipCode: code,
      createdAt: Date.now()
    })

    const memberId = newMemberRef.key

    // 2) E-Mail Template vorbereiten
    const hostingDomain = 'http://localhost:5173/' // <-- deine Hosting URL
    const editUrl = `${hostingDomain}/#/members/${memberId}`

   const templateParams = {
  to_name: name.value,
  to_email: email.value,  // <- hier muss der Wert aus dem Formular kommen
  member_id: memberId,
  membership_code: code,
  edit_url: editUrl
}

    // 3) E-Mail senden via EmailJS
    const serviceID = 'service_viiagc2'      // z. B. gmail
    const templateID = 'template_eh1z8l6'    // z. B. template_abc123
    const publicKey = 'NBxFLic-Wi_ObTiV8'      // EmailJS Public Key

    await emailjs.send(serviceID, templateID, templateParams, publicKey)

    // 4) Nachricht auf der Seite anzeigen
    message.value = `Gemt! Medlems-ID: ${memberId} | Kode: ${code}. E-mail sendt til ${email.value}.`
    name.value = ''
    email.value = ''
    age.value = null
  } catch (err) {
  console.error('Submit / Email error', err)
  message.value = 'Error: ' + JSON.stringify(err)
}
}


</script>

<style>
.container {
  max-width: 420px;
  margin: 40px auto;
  font-family: Arial, sans-serif;
}
input,
button {
  width: 100%;
  padding: 10px;
  margin: 6px 0;
  box-sizing: border-box;
}
</style>

Produkt

Mit produkt blev en funktionel registreringsløsning, der kunne:

  • Gemme tilmeldingsinformationer i Firebase realtime database
  • Generere en unik medlemskode for hver bruger
  • Muliggøre opdatering af informationer via medlemskoder
  • Automatisk sende en e‑mail med medlemskoderne til den angivne emailadresse

Selvom løsningen var samlet på én side og ikke havde et avanceret design, fungerede den som en vigtig del af kampagnesiden og demonstrerede, hvordan man kan bygge en datadreven front‑end funktion med Vue og Firebase.

Link til siden med produktet

Gemte medlemsinformationer i Firebase Realtime Database

Reflektion

Jeg er meget stolt af, at jeg fik det til at virke, især fordi jeg startede med begrænset erfaring og følte mig usikker. Projektet gav mig værdifuld træning i at arbejde med Vue, Firebase, hosting, databaser og integration af e‑mailfunktioner. Jeg fik en bedre forståelse af, hvordan man bygger en funktionel løsning, selv når man ikke har hele systemet på plads.

Der er helt sikkert andre måder at lave en opdateringsboks på, men min løsning virkede, og det gav mig selvtillid og læring. Det eneste, jeg ville forbedre næste gang, er min præsentation af koden. Jeg har brug for lidt tid til at huske, hvad jeg har lavet, og under præsentationer bliver jeg ofte nervøs og glemmer at forklare detaljer. Jeg kunne have præsenteret mere klart og struktureret.

Alt i alt var projektet både sjovt og lærerigt, og det gav mig en vigtig erfaring i at tage ansvar for en funktion, bygge den fra bunden og få den til at fungere i praksis.