\section{Weboberfläche} Die Weboberfläche wird mit dem Frontend-Web-Framework Vue.js erstellt. Mit Vue werden wiederverwendbare, auf Datenänderungen reagierende Komponenten erstellt. Die Komponenten nutzen ein fertiges Aussehen von dem Frontend-CSS-Framework Bootstrap. Außerdem werden Icons der freien Schriftart fontawesome verwendet. Das Projekt wird durch den \Gls{bundler} vite aufgesetzt, gebaut und stellt einen Entwicklungswebserver mit Echtzeitvorschau bereit. Durch den vue-router wird bei der \Gls{spa} ein Seitenwechsel durch Manipulation der Browser-Chronik (History Manipulation) simuliert. Dadurch hat der Nutzer eine bessere Erfahrung, weil die Seite nicht neu geladen werden muss, wenn zu einem anderen Menüpunkt gewechselt wird. Wenn der Nutzer sich anmeldet wird die E-Mail-Adresse, der \Gls{session-token} und Spracheinstellungen in dem globallen Zustandsspeicher gespeichert, welcher durch die Pinia-Abhängigkeit bereitgestellt wird. Dadurch haben alle \Glspl{uiComponent} einfachen Zugriff auf die Daten und diese müssen nicht über Props in tiefliegende \Glspl{uiComponent} durchgereicht werden. Die Seiten werden als einzelne Kompontenten erstellt. Andere HTML-Strukturen werden als eigene Komponenten ausgelagert, wenn sie in mehreren Seiten verwendet werden und zur Reduzierung von Komplexität und Duplikation beitragen und selbst Logik beinhalten. Vom Frontend benötigte Abhängigkeiten: \begin{itemize} \item vite \item vue \item vue-router \item Pinia (globaler Zustandsspeicher) \item bootstrap \item fontawesome \item vue-i18n (Support für mehrere Sprachen) \end{itemize} \subsection{Komponentendiagramm Web-Frontend} \includegraphics[width=\textwidth]{assets/diagrams/componentdiagram} \subsection{Komponentenbeschreibung} \begin{minipage}{.7\linewidth} \subsubsection*{SubscriptionComponent} \begin{description} \item[Tag] \texttt{} \item[Props] \mbox{} \\ \emph{subscription} \mbox{} Subscription-Objekt, welches Attribute zu einem \Gls{podcast} und dessen \Glspl{episode} enthält. \item[Beschreibung] Nimmt ein Subscription-Objekt, zeigt Titel und LastUpdate und \Glspl{episode} der Subscription an. \end{description} \end{minipage} \begin{minipage}{.3\linewidth} \begin{figure}[H] \includegraphics[width=\textwidth]{assets/subscription.png} \end{figure} \end{minipage} \vspace{.5cm} \begin{minipage}{.7\linewidth} \subsubsection*{EpisodeComponent} \begin{description} \item[Tag] \texttt{} \item[Props] \mbox{} \\ \emph{episode} \mbox{} EpisodeAction-Objekt, welches Titel, \Gls{podcast}, Timestamp, Dauer und Hörfortschritt der \Gls{episode} enthält. \item[Beschreibung] Nimmt ein EpisodeAction-Object, zeigt Titel, \Gls{podcast}, Dauer, Hörfortschritt und LastUpdate an. \end{description} \end{minipage} \begin{minipage}{.3\linewidth} \begin{figure}[H] \includegraphics[width=\textwidth]{assets/episode.png} \end{figure} \end{minipage} \vspace{.5cm} \begin{minipage}{.7\linewidth} \subsubsection*{LastUpdateComponent} \begin{description} \item[Tag] \texttt{} \item[Props] \mbox{} \\ \emph{timestamp} \mbox{} Date-Objekt, welches die Zeit der letzten Änderung enthält \item[Beschreibung] Nimmt ein Timestamp und gibt die Zeit seit dem Timestamp in einem menschenlesbaren Format aus. \end{description} \end{minipage} \begin{minipage}{.3\linewidth} \begin{figure}[H] \includegraphics[width=\textwidth]{assets/lastupdate.png} \end{figure} \end{minipage} \vspace{.5cm} \begin{minipage}{.7\linewidth} \subsubsection*{HelpComponent} \begin{description} \item[Tag] \texttt{} \item[Beschreibung] Zeigt Hilfestellungen in einem Fenster an. Dieses kann über die Navigationsleiste aufgerufen werden. \end{description} \end{minipage} \begin{minipage}{.3\linewidth} \begin{figure}[H] \includegraphics[width=\textwidth]{assets/help.png} \end{figure} \end{minipage} \vspace{.5cm} \begin{minipage}{.7\linewidth} \subsubsection*{NavbarComponent} \begin{description} \item[Tag] \texttt{} \item[Beschreibung] Enthält route-links zu im vue-router definierten Pfaden. \end{description} \end{minipage} \begin{minipage}{.3\linewidth} \begin{figure}[H] \fbox{\includegraphics[width=\textwidth]{assets/navbar.png}} \end{figure} \end{minipage} \vspace{.5cm} \begin{minipage}{.7\linewidth} \subsubsection*{PasswordValidatorComponent} \begin{description} \item[Tag] \texttt{} \item[Beschreibung] Überprüft ob der eingegebene Text die Bedingungen für ein sicheres Passwort erfüllt. \end{description} \end{minipage} \begin{minipage}{.3\linewidth} \begin{figure}[H] \includegraphics[width=\textwidth]{assets/password-margin.png} \end{figure} \end{minipage}