\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{<Subscription subscription>}
\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{<Episode episode>}
\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{<LastUpdate timestamp>}
\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{<Help>}
\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{<Navbar>}
\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{<Password>}
\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}

