147 lines
5.1 KiB
Plaintext
147 lines
5.1 KiB
Plaintext
package templates
|
|
|
|
import (
|
|
"arbeitszeitmessung/helper"
|
|
"arbeitszeitmessung/models"
|
|
"fmt"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
templ TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) {
|
|
@Base()
|
|
@headerComponent()
|
|
<div class="grid-main divide-y-1 @container">
|
|
<div class="grid-sub lg:divide-x-1 max-md:divide-y-1 responsive">
|
|
<div class="grid-cell col-span-full bg-neutral-300 lg:border-0">
|
|
<h2 class="text-xl uppercase font-bold">Eigene Abrechnung</h2>
|
|
</div>
|
|
</div>
|
|
@workWeekComponent(userWeek, false)
|
|
if len(weeks) > 0 {
|
|
<div class="grid-cell col-span-full bg-neutral-300">
|
|
<h2 class="text-xl uppercase font-bold">Abrechnung Mitarbeiter</h2>
|
|
</div>
|
|
}
|
|
for _, week := range weeks {
|
|
@workWeekComponent(week, true)
|
|
}
|
|
</div>
|
|
}
|
|
|
|
templ workWeekComponent(week models.WorkWeek, onlyAccept bool) {
|
|
{{
|
|
year, kw := week.WeekStart.ISOWeek()
|
|
progress := (float32(week.WorktimeVirtual.Hours()) / week.User.ArbeitszeitPerWoche) * 100
|
|
}}
|
|
<div class="employeComponent grid-sub responsive lg:divide-x-1 max-md:divide-y-1">
|
|
<div class="grid-cell flex flex-col max-md:bg-neutral-300 gap-2">
|
|
if !onlyAccept {
|
|
<div class="lg:hidden">
|
|
@weekPicker(week.WeekStart)
|
|
</div>
|
|
}
|
|
<p class="font-bold uppercase">{ week.User.Vorname } { week.User.Name }</p>
|
|
<div class="grid grid-cols-5 gap-2 lg:grid-cols-1">
|
|
if !onlyAccept {
|
|
<div class="col-span-2">
|
|
<span class="flex flex-row gap-2 items-center">
|
|
@statusCheckMark(week.CheckStatus(), models.WeekStatusSent)
|
|
Gesendet
|
|
</span>
|
|
<span class="flex flex-row gap-2 items-center">
|
|
@statusCheckMark(week.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(week.Worktime)) }</p>
|
|
<p>Überstunden: { fmt.Sprintf("%s", helper.FormatDurationFill(week.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 week.Days {
|
|
@defaultWeekDayComponent(week.User, day)
|
|
}
|
|
</div>
|
|
<div class="grid-cell flex flex-col gap-2 justify-between">
|
|
if onlyAccept {
|
|
<p class="text-sm"><span class="">Woche:</span> { fmt.Sprintf("%02d-%d", kw, year) }</p>
|
|
} else {
|
|
<div class="max-md:hidden">
|
|
@weekPicker(week.WeekStart)
|
|
</div>
|
|
}
|
|
<form method="post" class="flex flex-col gap-2">
|
|
{{
|
|
week.CheckStatus()
|
|
method := "accept"
|
|
if !onlyAccept {
|
|
method = "send"
|
|
}
|
|
}}
|
|
<input type="hidden" name="method" value={ method }/>
|
|
<input type="hidden" name="user" value={ strconv.Itoa(week.User.PersonalNummer) }/>
|
|
<input type="hidden" name="week" value={ week.WeekStart.Format(time.DateOnly) }/>
|
|
if onlyAccept {
|
|
if week.Status == models.WeekStatusDifferences {
|
|
<p class="text-red-600 text-sm">Unterschiedliche Arbeitszeit zwischen Abrechnung und individuellen Buchungen</p>
|
|
}
|
|
<button type="submit" disabled?={ week.Status == models.WeekStatusDifferences } class="btn">Bestätigen</button>
|
|
} else {
|
|
switch {
|
|
case week.RequiresAction():
|
|
<p class="text-sm text-red-500">bitte zuerst Buchungen anpassen</p>
|
|
case time.Since(week.WeekStart) < 24*7*time.Hour:
|
|
<p class="text-sm text-red-500">Die Woche kann erst am nächsten Montag gesendet werden!</p>
|
|
case week.Status == models.WeekStatusNone:
|
|
<p class="text-sm">an Vorgesetzten senden</p>
|
|
case week.Status == models.WeekStatusSent:
|
|
<p class="text-sm">an Vorgesetzten gesendet</p>
|
|
case week.Status == models.WeekStatusAccepted:
|
|
<p class="text-sm">vom Vorgesetzten bestätigt</p>
|
|
}
|
|
<button disabled?={ week.Status < models.WeekStatusSent } type="submit" class="btn">Korrigieren</button>
|
|
<button disabled?={ time.Since(week.WeekStart) < 24*7*time.Hour || week.Status >= models.WeekStatusSent || week.RequiresAction() } type="submit" class="btn">Senden</button>
|
|
}
|
|
</form>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
templ defaultWeekDayComponent(u models.User, day models.IWorkDay) {
|
|
<div class="flex flex-row gap-2">
|
|
@timeGaugeComponent(day.GetDayProgress(u), false)
|
|
<div class="flex flex-col">
|
|
<p class=""><span class="font-bold uppercase hidden md:inline">{ helper.FormatGermanDayOfWeek(day.Date()) }:</span> { day.Date().Format("02.01.2006") }</p>
|
|
{{ work, pause, _ := day.GetTimes(u, models.WorktimeBaseDay, false) }}
|
|
if day.IsWorkDay() || day.GetDayProgress(u) < 100 {
|
|
<div class="flex flex-row gap-2">
|
|
<span class="text-accent">{ helper.FormatDuration(work) }</span>
|
|
<span class="text-neutral-500">{ helper.FormatDuration(pause) }</span>
|
|
</div>
|
|
}
|
|
@weekDayTypeSwitcher(day)
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
templ weekDayTypeSwitcher(day models.IWorkDay) {
|
|
switch day.Type() {
|
|
case models.DayTypeWorkday:
|
|
{{ workDay, _ := day.(*models.WorkDay) }}
|
|
@workDayWeekComponent(workDay)
|
|
case models.DayTypeCompound:
|
|
for _, c := range day.(*models.CompoundDay).DayParts {
|
|
@weekDayTypeSwitcher(c)
|
|
}
|
|
default:
|
|
<div>{ day.ToString() }</div>
|
|
}
|
|
}
|