In deze repository is gewerkt aan een webapplicatie die podcasts aanbied aan de leden van De Correspondent.
https://sprint-12-de-correspondent.onrender.com/
Dit project is de webversie van de native app van de Correspondent. De functie van deze webapplicatie is het te beluisteren naar diverse podcasts.
De user stories die werden toegepast luidden alsvolgt:
- Als gebruiker wil ik een overzicht van alle podcasts
- Als gebruiker wil ik zien of de podcast app getest is op toegankelijkheid
- Als ontwikkelaar wil ik de API gekoppeld hebben aan de site zodat data correct word ingeladen
Gebruikers van de Correspondent kunnen shows uitkiezen waarnaar ze kunnen luisteren. Voor de ontwikkelaar is de gekregen API gekoppeld zodat de data correct word ingeladen en dat zo de site dynamisch word gemaakt.
Voor dit project zijn de volgende technieken toegepast:
- html
- css
- javascript
- node
- express
De html in dit project is opgebouwd met een javascript template genaamd ejs. Hierdoor was onder anderen het laden van item in een array mogelijk op de homepage.
<% if (data && data.length) { %> <%
data.forEach(collection => { %>
<article>
<picture>
<source
srcset="/public<%= imageFiles[mainVisuals[collection.relationships.mainVisual.data.id]] %>"
alt="<%= collection.attributes.title %>"
width="320"
height="320"
loading="lazy"
/>
<img
src="/public<%= imageFiles[mainVisuals[collection.relationships.mainVisual.data.id]] %>"
alt="<%= collection.attributes.title %>"
width="320"
height="320"
loading="lazy"
/>
</picture>
<h2><%= collection.attributes.title %></h2>
<p><%= collection.attributes.intro %></p>
<a
id="<%= collection.attributes.slug %>"
class="default-link"
href="/collection/<%= collection.attributes.slug %>"
>
Ga naar deze show
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-player-play"
width="24"
height="24"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
stroke="none"
d="M0 0h24v24H0z"
fill="none"
></path>
<path d="M7 4v16l13 -8z"></path>
</svg>
</a>
</article>
<% }); %> <% } %>
Met css heb ik de volledige stijling gemaakt voor de website. Zo had ik diverse custom properties aangemaakt en toegepast op mijn product.
:root {
/* Animaties */
--a-quick: 0.2s;
--a-default: 0.3s;
--a-medium: 0.6s;
--a-large: 1s;
--a-loading: 3s;
/* Kleuren */
--color-default: #ffffff;
--color-invert: #121212;
--color-primary: #df5b57;
--color-secundary-150: #194d49;
--color-secundary-125: #2f736e;
--color-secundary-100: #70b3ad;
--color-secundary-75: #9dceca;
--color-secundary-50: #c7ece9;
--color-secundary-0: #eaf6f5;
--color-accent-100: #666666;
--color-accent-75: #b2b2b2;
--color-accent-50: #e5e4e4;
/* Eenheden */
--u-nano: 0.125em;
--u-micro: 0.25em;
--u-small: 0.4em;
--u-medium: 0.5em;
--u-default: 1em;
--u-large: 2em;
--u-round: 50%;
/* Schaduwen en effecten */
--shadow-default: 0px 1px var(--u-micro) rgba(0, 0, 0, 0.1), 0px var(--u-micro) var(--u-micro) -2px rgba(0, 0, 0, 0.12), 0px 10px 12px -5px rgba(0, 0, 0, 0.2);
}
Niet alleen voor de default stijl, maar ook voor de dark mode.
/* Activeert donkere modus */
@media (prefers-color-scheme: dark) {
:root {
/* Kleuren */
--color-default: #121212;
--color-invert: #ffffff ;
--color-primary: #df5b57;
--color-secundary-150: #eaf6f5;
--color-secundary-125: #c7ece9;
--color-secundary-100: #9dceca;
--color-secundary-75: #70b3ad;
--color-secundary-50: #2f736e;
--color-secundary-0: #194d49 ;
--color-accent-100: #666666;
--color-accent-75: #b2b2b2;
--color-accent-50: #e5e4e4;
}
Dit project bevat, naast node, ook client-side javascript. Het bevat een enhancement op de links die linken naar de detailpagina en terug naar de homepage. De enhancement is een geluidseffect wanneer de gebruiker klikt.
Deze code verzorgt het geluidseffect voor de link naar de detailpagina.
const interfaceSound = new Audio(
"./assets/interface-124464.mp3"
);
const interfaceClicks =
document.querySelectorAll(".default-link");
interfaceClicks.forEach((interfaceClick) => {
interfaceClick.addEventListener("click", (event) => {
event.preventDefault(); // Voorkomt dat de standaard linkactie wordt uitgevoerd
interfaceSound.play();
setTimeout(() => {
window.location.href = event.target.href; // Doorsturen naar de volgende pagina
}, 800); // Wacht 0.8 seconden voordat de doorstuuring plaatsvindt
});
});
Deze onderstaande code het geluidseffect voor de link naar de homepage terug.
const interfaceBackSound = new Audio(
"../assets/interface-124476.mp3"
);
const interfaceBackClick =
document.querySelector(".link-retro");
interfaceBackClick.addEventListener("click", (event) => {
interfaceBackSound.play();
setTimeout(() => {
window.location.href = event.target.href; // Doorsturen naar de volgende pagina
}, 600); // Wacht 0.6 seconden voordat de doorstuuring plaatsvindt
});
Dit project gebruikt node als basis. Hierin heb ik verschillende routes aangemaakt voor de pagina's met behulp van express
Zo maakte ik een GET-request aan voor de index pagina:
// Definieer de route voor de hoofdpagina ("/")
app.get("/", (request, response) => {
// Fetch the data from the url
fetchJson(collectionsJson).then((data) => {
var mainVisuals = {};
var imageFiles = {};
// Loop door alle included variabelen heen
data.included.forEach((element) => {
if (element.type == "MainVisual") {
mainVisuals[element.id] = element.relationships.image.data.id;
} else if (element.type == "ImageFile") {
imageFiles[element.id] = element.attributes.sourceSet;
}
});
response.render("index", {
...data,
mainVisuals: mainVisuals,
imageFiles: imageFiles
});
});
});
Ook zette ik een complexere detailpagina op en maakte daar een GET request voor:
// Definieer de route voor de overzichtspagina ("/collection/:slug")
app.get("/collection/:slug", (request, response) => {
const slug = request.params.slug;
fetchJson(collectionsJson).then((data) => {
const collections = data.data;
const item = collections.find(
(collection) => collection.attributes.slug === slug
);
if (item) {
const itemId = item.id;
const itemJsonUrl = `https://raw.githubusercontent.com/Stefan-Espant/de-correspondent-sprint-12-proof-of-concept/main/course/collection/${itemId}.json`;
fetchJson(itemJsonUrl).then((itemData) => {
// Fetch main visuals and image files
var mainVisuals = {};
var imageFiles = {};
data.included.forEach((element) => {
if (element.type === "MainVisual") {
mainVisuals[element.id] = element.relationships.image.data.id;
} else if (element.type === "ImageFile") {
imageFiles[element.id] = element.attributes.sourceSet;
}
});
fetchJson(collectionsJson).then((data) => {
})
const message = "De Correspondent - " + item.attributes.title;
response.render("collection", {
...data,
item,
itemData,
message,
mainVisuals,
imageFiles,
});
console.log(itemJsonUrl)
});
}
});
});
In dit project is gebruik gemaakt van onder anderen:
- Node
- Express
- EJS
Voor het installeren van node gebruikte ik het commando npm init
om node te initialiseren. Volgens
Deze modules kunnen geinstalleerd worden doormiddel van:
npm install
express
ejs
Om de applicatie te laten werken, voer dan het volgende commando uit:
npm start
Afbeelding naar tekst converter
This project is licensed under the terms of the MIT license.