187 lines
8.2 KiB
Plaintext
187 lines
8.2 KiB
Plaintext
package templates
|
|
|
|
import "arbeitszeitmessung/models"
|
|
import "arbeitszeitmessung/helper"
|
|
|
|
templ Base() {
|
|
<!DOCTYPE html>
|
|
<head>
|
|
<title>Arbeitszeit</title>
|
|
<link rel="stylesheet" href="/static/css/styles.css"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
<script src="/static/script.js" defer></script>
|
|
</head>
|
|
}
|
|
|
|
templ LoginPage(success bool, errorMsg string) {
|
|
@Base()
|
|
<div class="w-full h-[100vh] flex flex-col justify-center items-center">
|
|
<form method="POST" class="w-9/10 md:w-1/2 flex flex-col gap-4 p-2 mb-2">
|
|
<h1 class="font-bold uppercase text-xl text-center mb-2">Benutzer Anmelden</h1>
|
|
<input name="personal_nummer" placeholder="Personalnummer" type="text" class="w-full placeholder:text-neutral-400 text-neutral-700 text-sm border border-neutral-300 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none hover:border-neutral-500"/>
|
|
<input name="password" placeholder="Passwort" type="password" class="w-full placeholder:text-neutral-400 text-neutral-700 text-sm border border-neutral-300 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none hover:border-neutral-500"/>
|
|
if !success {
|
|
<p class="text-red-600 text-sm">Login fehlgeschlagen, bitte erneut versuchen!</p>
|
|
<p class="text-red-600 text-sm">{ errorMsg }</p>
|
|
}
|
|
<button type="submit" class="cursor-pointer rounded-md text-neutral-800 p-2 md:px-4 border text-center text-sm hover:text-white transition-colors border-neutral-300 focus:bg-neutral-700 active:bg-neutral-700 hover:bg-neutral-700 disabled:pointer-events-none disabled:opacity-50">Login</button>
|
|
</form>
|
|
</div>
|
|
}
|
|
|
|
templ UserPage(status int) {
|
|
@Base()
|
|
@headerComponent()
|
|
<div class="grid-main divide-y-1">
|
|
<form method="POST" class="grid-sub responsive lg:divide-x-1">
|
|
<h1 class="grid-cell font-bold uppercase text-xl text-center">Passwort ändern</h1>
|
|
<div class="grid-cell col-span-3 flex flex-col gap-2">
|
|
<input name="password" placeholder="Aktuelles Passwort" type="password" class="w-full placeholder:text-neutral-400 text-neutral-700 text-sm border border-neutral-300 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none hover:border-neutral-500"/>
|
|
<input name="new_password" placeholder="Neues Passwort" type="password" class="w-full placeholder:text-neutral-400 text-neutral-700 text-sm border border-neutral-300 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none hover:border-neutral-500"/>
|
|
<input name="new_password_repeat" placeholder="Neues Passwort wiederholen" type="password" class="w-full placeholder:text-neutral-400 text-neutral-700 text-sm border border-neutral-300 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none hover:border-neutral-500"/>
|
|
switch {
|
|
case status == 401:
|
|
<p class="text-red-600 text-sm">Aktuelles Passwort nicht korrekt!</p>
|
|
case status >= 400:
|
|
<p class="text-red-600 text-sm">Passwortwechsel fehlgeschlagen, bitte erneut versuchen!</p>
|
|
case status == 202:
|
|
<p class="text-accent text-sm">Passwortänderung erfolgreich</p>
|
|
}
|
|
</div>
|
|
<div class="grid-cell">
|
|
<button name="action" value="change-pass" type="submit" class="btn">Ändern</button>
|
|
</div>
|
|
</form>
|
|
<div class="grid-sub responsive lg:divide-x-1">
|
|
<h1 class="grid-cell font-bold uppercase text-xl text-center">Nutzer abmelden</h1>
|
|
<div class="grid-cell col-span-3">
|
|
<p>Nutzer von Weboberfläche abmelden.</p>
|
|
</div>
|
|
<div class="grid-cell">
|
|
<button onclick="logoutUser" type="button" class="btn">Abmelden</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
templ statusCheckMark(status models.WeekStatus, target models.WeekStatus) {
|
|
if status >= target {
|
|
<div class="icon-[material-symbols-light--check-circle-outline]"></div>
|
|
} else {
|
|
<div class="icon-[material-symbols-light--circle-outline]"></div>
|
|
}
|
|
}
|
|
|
|
templ TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) {
|
|
@Base()
|
|
@headerComponent()
|
|
<div class="grid-main divide-y-1">
|
|
<div class="grid-sub lg:divide-x-1 max-md:divide-y-1 responsive @container">
|
|
<div class="grid-cell col-span-full bg-neutral-300 lg:border-0">
|
|
<h2 class="text-2xl uppercase font-bold">Eigene Abrechnung</h2>
|
|
</div>
|
|
</div>
|
|
@workWeekComponent(userWeek, false)
|
|
// <div class="grid-sub lg:divide-x-1 max-md:divide-y-1 responsive @container">
|
|
// <div class="grid-cell col-span-full bg-neutral-300 lg:border-0">
|
|
// <h2 class="text-2xl uppercase font-bold">Eigene Abrechnung</h2>
|
|
// </div>
|
|
// <div class="grid-cell flex flex-col max-md:border-b-1 max-md:bg-neutral-300 gap-2 ">
|
|
// <div class="lg:hidden">
|
|
// @weekPicker(userWeek.WeekStart)
|
|
// </div>
|
|
// <h2 class="uppercase font-bold">{ fmt.Sprintf("%s %s", userWeek.User.Vorname, userWeek.User.Name) }</h2>
|
|
// <div class="grid grid-cols-5 gap-2 lg:grid-cols-1">
|
|
// <div class="col-span-2">
|
|
// <span class="flex flex-row gap-2 items-center">
|
|
// @statusCheckMark(userWeek.CheckStatus(), models.WeekStatusSent)
|
|
// Gesendet
|
|
// </span>
|
|
// <span class="flex flex-row gap-2 items-center">
|
|
// @statusCheckMark(userWeek.CheckStatus(), models.WeekStatusAccepted)
|
|
// Akzeptiert
|
|
// </span>
|
|
// </div>
|
|
// <div class="flex flex-row gap-2 col-span-3">
|
|
// @timeGaugeComponent(int8(progress), false)
|
|
// <div>
|
|
// <p>Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(userWeek.Worktime)) }</p>
|
|
// <p>Überstunden: { fmt.Sprintf("%s", helper.FormatDurationFill(userWeek.Overtime, true)) }</p>
|
|
// </div>
|
|
// </div>
|
|
// </div>
|
|
// </div>
|
|
// <div class="grid-cell col-span-3 flex flex-col @7xl:grid @7xl:grid-cols-5 gap-2 py-4 content-baseline">
|
|
// for _, day := range userWeek.Days {
|
|
// @defaultWeekDayComponent(userWeek.User, day)
|
|
// }
|
|
// </div>
|
|
// <div class="grid-cell flex flex-col gap-2 justify-between">
|
|
// <div class="max-md:hidden">
|
|
// @weekPicker(userWeek.WeekStart)
|
|
// </div>
|
|
// <form method="post" class="flex flex-col gap-2">
|
|
// <input type="hidden" name="method" value="send"/>
|
|
// <input type="hidden" name="user" value={ strconv.Itoa(userWeek.User.PersonalNummer) }/>
|
|
// <input type="hidden" name="week" value={ userWeek.WeekStart.Format(time.DateOnly) }/>
|
|
// switch userWeek.CheckStatus() {
|
|
// case models.WeekStatusNone:
|
|
// <p class="text-sm">an Vorgesetzten senden</p>
|
|
// case models.WeekStatusSent:
|
|
// <p class="text-sm">an Vorgesetzten gesendet</p>
|
|
// case models.WeekStatusAccepted:
|
|
// <p class="text-sm">vom Vorgesetzten bestätigt</p>
|
|
// }
|
|
// <button disabled?={ userWeek.Status < models.WeekStatusSent } type="submit" class="btn">Korrigieren</button>
|
|
// <button disabled?={ time.Since(userWeek.WeekStart) < 24*7*time.Hour || userWeek.Status >= models.WeekStatusSent || userWeek.RequiresAction() } type="submit" class="btn">Senden</button>
|
|
// </form>
|
|
// </div>
|
|
// </div>
|
|
if len(weeks) > 0 {
|
|
<div class="grid-cell col-span-full bg-neutral-300">
|
|
<h2 class="text-2xl uppercase font-bold">Abrechnung Mitarbeiter</h2>
|
|
</div>
|
|
}
|
|
for _, week := range weeks {
|
|
@workWeekComponent(week, true)
|
|
}
|
|
</div>
|
|
}
|
|
|
|
templ TeamPresencePage(teamPresence map[models.User]bool) {
|
|
@Base()
|
|
@headerComponent()
|
|
<div class="grid-main divide-y-1">
|
|
<div class="grid-sub divide-x-1">
|
|
<h2 class="grid-cell font-bold uppercase">Mitarbeiter</h2>
|
|
</div>
|
|
for user, present := range teamPresence {
|
|
<div class="grid-sub">
|
|
<div class="grid-cell flex flex-row gap-2 col-span-2 md:col-span-1">
|
|
@timeGaugeComponent(helper.BoolToInt8(present)*100-1, false)
|
|
<p>{ user.Vorname } { user.Name }</p>
|
|
</div>
|
|
<div class="grid-cell col-span-2">
|
|
if present {
|
|
<span class="text-neutral-500">Anwesend</span>
|
|
} else {
|
|
<span class="text-neutral-500">Abwesend</span>
|
|
}
|
|
</div>
|
|
</div>
|
|
}
|
|
// <div class="grid-sub divide-x-1">
|
|
// <h2 class="grid-cell font-bold uppercase">Nicht Anwesend</h2>
|
|
// <div class="flex flex-col col-span-2 md:col-span-4">
|
|
// for _, user := range teamPresence[false] {
|
|
// @userPresenceComponent(user, false)
|
|
// }
|
|
// </div>
|
|
// </div>
|
|
</div>
|
|
}
|
|
|
|
templ LogoutButton() {
|
|
<button onclick="logoutUser()" type="button" class="cursor-pointer">Abmelden</button>
|
|
}
|