{"id":1193,"date":"2025-02-26T16:34:40","date_gmt":"2025-02-26T14:34:40","guid":{"rendered":"https:\/\/wesleydegraaf.com\/?page_id=1193"},"modified":"2025-04-16T11:48:38","modified_gmt":"2025-04-16T09:48:38","slug":"z4d-app","status":"publish","type":"page","link":"https:\/\/wesleydegraaf.com\/en\/z4d-app\/","title":{"rendered":"Zwem4Daagse app"},"content":{"rendered":"\n<div class=\"wp-block-cover\" style=\"min-height:280px;aspect-ratio:unset;\"><span aria-hidden=\"true\" class=\"wp-block-cover__background has-palette-color-1-background-color has-background-dim-100 has-background-dim\"><\/span><div class=\"wp-block-cover__inner-container is-layout-flow wp-block-cover-is-layout-flow\">\n<p class=\"has-text-align-center has-x-large-font-size wp-block-paragraph\"><strong>H&amp;H Zwem4Daagse App<\/strong><\/p>\n<\/div><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">Project Info:<\/mark><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Solo Project<br>Project tijd: HKU Jaar 1 Periode 4<br>Software: Cordova<br>Code Languages: JS + (CSS + HTML) &amp; PHP<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"740\" src=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2024\/10\/Z4D-Web-Imgage-1024x740.png\" alt=\"\" class=\"wp-image-1202\" style=\"width:752px;height:auto\" srcset=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2024\/10\/Z4D-Web-Imgage-1024x740.png 1024w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2024\/10\/Z4D-Web-Imgage-300x217.png 300w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2024\/10\/Z4D-Web-Imgage-768x555.png 768w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2024\/10\/Z4D-Web-Imgage-18x12.png 18w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2024\/10\/Z4D-Web-Imgage.png 1494w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">De app voor de gebruiker.<\/figcaption><\/figure>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading has-palette-color-1-color has-text-color has-link-color wp-elements-9e9318eeb2d6e3a52b5fe5702635d478\">Tickets Scannen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">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\u00ebren of de ticket van de gebruiker is. Elke ticket kan maar 1x per dag gescand worden.<\/p>\n\n\n\n<div class=\"dm-code-snippet light dm-normal-version no-background no-background-mobile\" snippet-height=\"\" style=\"background-color:#abb8c3\"><div class=\"control-language\"><div class=\"dm-buttons\"><div class=\"dm-buttons-left\"><div class=\"dm-button-snippet red-button\"><\/div><div class=\"dm-button-snippet orange-button\"><\/div><div class=\"dm-button-snippet green-button\"><\/div><\/div><div class=\"dm-buttons-right\"><a id=\"dm-copy-raw-code\"><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span><span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a><\/div><\/div><pre class=\" line-numbers\"><code id=\"dm-code-raw\" class=\" no-wrap language-javascript\">function SendScanData(type, qrContent) {\n    var ticket = JSON.parse(qrContent);\n\n    const requestData = JSON.stringify({\n        pubToken: ticket.pubToken,\n        ticketID: ticket.ticketID,\n        dayNumber: GetDayNumber(currentDay),\n        emailScanner: sessionStorage.getItem(\"email\"),\n        tokenScanner: sessionStorage.getItem(\"privToken\"),\n        scanType: type\n    });\n\n    const formData = new URLSearchParams();\n    formData.append('request', requestData);\n\n    fetch(\"https:\/\/api.wesleydegraaf.com\/Z4D\/DayScan.php\", {\n        method: \"POST\",\n        body: formData,\n        headers: {\n            \"Content-Type\": \"application\/x-www-form-urlencoded\"\n        }\n    })\n        .then(response => {\n            if (!response.ok) {\n                alert(`HTTP error! Status: ${response.status}`);\n                return null;\n                \/\/throw new Error(`HTTP error! Status: ${response.status}`);\n            }\n\n            return response.json();\n        })\n        .then(json => {\n            if(json == null) return;\n            \n            console.log(JSON.stringify(json));\n            TicketResponse(json)\n        })\n        .catch((error) => {\n            console.log('Error', error)\n            ShowError(\"Dag Scanner\", 'Error:' + error);\n            DoScan();\n        });\n}<\/code><\/pre><\/div><\/div>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">Code voor het versturen van gescande data<\/p>\n\n\n\n<h2 class=\"wp-block-heading has-palette-color-1-color has-text-color has-link-color wp-elements-b8e6252742afacd965e338b40c9a8eae\">API<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">De api van de app werkt met PHP &amp; MySQL. Alle request worden verzonden naar <a href=\"https:\/\/api.wesleydegraaf.com\/\">https:\/\/api.wesleydegraaf.com<\/a> om verwerkt te worden. De gebruiker heeft een private token waarmee hij zichzelf kan verifi\u00ebren 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.<\/p>\n\n\n\n<div class=\"dm-code-snippet light dm-normal-version no-background no-background-mobile\" snippet-height=\"\" style=\"background-color:#abb8c3\"><div class=\"control-language\"><div class=\"dm-buttons\"><div class=\"dm-buttons-left\"><div class=\"dm-button-snippet red-button\"><\/div><div class=\"dm-button-snippet orange-button\"><\/div><div class=\"dm-button-snippet green-button\"><\/div><\/div><div class=\"dm-buttons-right\"><a id=\"dm-copy-raw-code\"><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span><span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a><\/div><\/div><pre class=\" line-numbers\"><code id=\"dm-code-raw\" class=\" no-wrap language-php\">&lt;?php\nrequire_once(\"connection.php\");\n\n$filePath = \".\/Cache\/messages.json\";\ndate_default_timezone_set('Europe\/Amsterdam');\n\nif (!file_exists($filePath)) {\n    \/\/LOAD ALL Messages\n    $sqlMessages = \"SELECT * FROM Berichten ORDER BY CreationDate DESC;\";\n    $resultMessages = $conn->query($sqlMessages);\n\n    if (!$resultMessages) {\n        die(\"Query failed: \" . $conn->error);\n    }\n\n    $messageCache = new Messages();\n    if ($resultMessages->num_rows > 0) {\n        while ($row = $resultMessages->fetch_assoc()) {\n            $messageContent = new stdClass();\n\n            $messageContent->SenderName = $row['SenderName'];\n            $messageContent->SenderURL = $row['SenderProfileURL'];\n            $messageContent->content = mb_convert_encoding($row['Content'], 'UTF-8', 'auto');\n\n            \/\/Creation date format.\n            $creationDate = $row['CreationDate'];\n            $formattedDate = date('H:i:s d-m-Y', strtotime($creationDate));\n            $messageContent->creationDate = $formattedDate;\n\n            array_push($messageCache->messageList, $messageContent);\n        }\n    }\n\n    $date = new DateTime('now', new DateTimeZone('Europe\/Amsterdam'));\n\n    $messageCache->lastUpdated = $date->format('d-m-Y H:i:s');\n    $messageFile = fopen(\".\/Cache\/messages.json\", \"wb\") or die(\"Unable to open file!\");\n    $messageJson = json_encode($messageCache, JSON_PRETTY_PRINT);\n\n    fwrite($messageFile, $messageJson);\n    fclose($messageFile);\n}\n\nreadfile($filePath, \"r\");\n$conn->close();\n?><\/code><\/pre><\/div><\/div>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\">Haalt de berichten op voor de berichten pagina in de app<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading has-palette-color-1-color has-text-color has-link-color wp-elements-a81469b13d4f3da23c0694ff2b2f66bc\">Appstores<\/h2>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\" style=\"border-style:none;border-width:0px;border-radius:0px;padding-right:8vw;padding-left:8vw\">\n<figure class=\"wp-block-image size-full\" style=\"margin-top:0;margin-right:0;margin-bottom:0;margin-left:0\"><a href=\"https:\/\/play.google.com\/store\/apps\/details?id=nl.zenpcdevaart.z4dapp\" target=\"_blank\" rel=\" noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"759\" data-id=\"1243\" src=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/02\/image.png\" alt=\"\" class=\"wp-image-1243\" srcset=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/02\/image.png 2560w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/02\/image-300x89.png 300w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/02\/image-1024x304.png 1024w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/02\/image-768x228.png 768w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/02\/image-1536x455.png 1536w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/02\/image-2048x607.png 2048w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/02\/image-18x5.png 18w\" sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/apps.apple.com\/nl\/app\/h-h-z4d-app\/id6744244595?platform=iphone\" target=\"_blank\" rel=\" noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"238\" data-id=\"1360\" src=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/DownloadApple.png\" alt=\"\" class=\"wp-image-1360\" srcset=\"https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/DownloadApple.png 800w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/DownloadApple-300x89.png 300w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/DownloadApple-768x228.png 768w, https:\/\/wesleydegraaf.com\/wp-content\/uploads\/2025\/04\/DownloadApple-18x5.png 18w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/figure>\n<\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1193","page","type-page","status-publish","hentry"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/pages\/1193","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/comments?post=1193"}],"version-history":[{"count":33,"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/pages\/1193\/revisions"}],"predecessor-version":[{"id":1369,"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/pages\/1193\/revisions\/1369"}],"wp:attachment":[{"href":"https:\/\/wesleydegraaf.com\/en\/wp-json\/wp\/v2\/media?parent=1193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}