H&H Zwem4Daagse App

Tijdens App Development op het HKU heb ik een app voor een evenement bij ons in het dorp. De Zwem4Daagse is een evenement van de KNZB en wordt jaarlijks georganiseerd. Voordat de app er was gebruikte we knipkaartjes voor de toegang. Dit begon erg ouderwets te worden en mensen raakte deze constant kwijt. Met de app kunnen we makkelijk bij houden hoeveel keer iedereen is geweest en kunnen we alle kaartjes van iemand in een keer scannen, zodat we niet 6x te hoeven scannen. Als de gebruiker minimaal 4 dagen heeft meegedaan wordt het medaille vakje zichtbaar. De app wordt in juni (2025) voor het eerst gebruikt door ongeveer 250 gebruikers.


Project Info:

Solo Project
Project tijd: HKU Jaar 1 Periode 4
Software: Cordova
Code Languages: JS + (CSS + HTML) & PHP

De app voor de gebruiker.

Deelnemers van de Z4D moeten elke dag hun ticket laten scannen bij de ingang voor toegang. Na 4 dagen kunnen ze hun ticket laten scannen voor een medaille. De ticket scanner kan een individueel ticket scannen of alle tickets op het account van de deelnemer. De scanner heeft 3 display statussen: Gelukt, Problemen, Mislukt. Die door de persoon bij de ingang zichtbaar zijn. De persoon bij de ingang scant de QRcode van de gebruiker en de app verstuurt de ticket gegevens naar de server. De gegevens in de QRcode zijn de ID van het ticket en de publiekelijke token van de user om te verifiëren of de ticket van de gebruiker is. Elke ticket kan maar 1x per dag gescand worden.

function SendScanData(type, qrContent) {
    var ticket = JSON.parse(qrContent);

    const requestData = JSON.stringify({
        pubToken: ticket.pubToken,
        ticketID: ticket.ticketID,
        dayNumber: GetDayNumber(currentDay),
        emailScanner: sessionStorage.getItem("email"),
        tokenScanner: sessionStorage.getItem("privToken"),
        scanType: type
    });

    const formData = new URLSearchParams();
    formData.append('request', requestData);

    fetch("https://api.wesleydegraaf.com/Z4D/DayScan.php", {
        method: "POST",
        body: formData,
        headers: {
            "Content-Type": "application/x-www-form-urlencoded"
        }
    })
        .then(response => {
            if (!response.ok) {
                alert(`HTTP error! Status: ${response.status}`);
                return null;
                //throw new Error(`HTTP error! Status: ${response.status}`);
            }

            return response.json();
        })
        .then(json => {
            if(json == null) return;
            
            console.log(JSON.stringify(json));
            TicketResponse(json)
        })
        .catch((error) => {
            console.log('Error', error)
            ShowError("Dag Scanner", 'Error:' + error);
            DoScan();
        });
}

Code voor het versturen van gescande data

De api van de app werkt met PHP & MySQL. Alle request worden verzonden naar https://api.wesleydegraaf.com om verwerkt te worden. De gebruiker heeft een private token waarmee hij zichzelf kan verifiëren aan de server. Requests worden alleen geaccepteerd als deze data klopt. Er zijn een aantal functionaliteiten die geen autorisatie nodig hebben, zoals de berichten service. Hier kunnen gebruikers berichten zien die relevant zijn voor het evenement.

<?php
require_once("connection.php");

$filePath = "./Cache/messages.json";
date_default_timezone_set('Europe/Amsterdam');

if (!file_exists($filePath)) {
    //LOAD ALL Messages
    $sqlMessages = "SELECT * FROM Berichten ORDER BY CreationDate DESC;";
    $resultMessages = $conn->query($sqlMessages);

    if (!$resultMessages) {
        die("Query failed: " . $conn->error);
    }

    $messageCache = new Messages();
    if ($resultMessages->num_rows > 0) {
        while ($row = $resultMessages->fetch_assoc()) {
            $messageContent = new stdClass();

            $messageContent->SenderName = $row['SenderName'];
            $messageContent->SenderURL = $row['SenderProfileURL'];
            $messageContent->content = mb_convert_encoding($row['Content'], 'UTF-8', 'auto');

            //Creation date format.
            $creationDate = $row['CreationDate'];
            $formattedDate = date('H:i:s d-m-Y', strtotime($creationDate));
            $messageContent->creationDate = $formattedDate;

            array_push($messageCache->messageList, $messageContent);
        }
    }

    $date = new DateTime('now', new DateTimeZone('Europe/Amsterdam'));

    $messageCache->lastUpdated = $date->format('d-m-Y H:i:s');
    $messageFile = fopen("./Cache/messages.json", "wb") or die("Unable to open file!");
    $messageJson = json_encode($messageCache, JSON_PRETTY_PRINT);

    fwrite($messageFile, $messageJson);
    fclose($messageFile);
}

readfile($filePath, "r");
$conn->close();
?>

Haalt de berichten op voor de berichten pagina in de app

(Binnenkort Apple Appstore)