From 855cd6f34faf22dce727a608420f9ef52713e4e0 Mon Sep 17 00:00:00 2001 From: tom_trgr Date: Wed, 24 Dec 2025 01:38:16 +0100 Subject: [PATCH] working compound days + working public holidays --- Backend/Makefile | 14 +- Backend/endpoints/pdf-create.go | 19 +- Backend/models/absence.go | 9 +- Backend/models/compoundDay.go | 105 ++++++ Backend/models/iworkday.go | 64 ++-- Backend/models/publicHoliday.go | 9 +- Backend/models/workDay.go | 5 + Backend/templates/pages.templ | 28 +- Backend/templates/pages_templ.go | 112 ++---- Backend/templates/reportPage.templ | 24 ++ Backend/templates/reportPage_templ.go | 70 ++++ Backend/templates/teamComponents.templ | 71 ++-- Backend/templates/teamComponents_templ.go | 435 ++++++++++++---------- Backend/templates/timeComponents.templ | 14 +- Backend/templates/timeComponents_templ.go | 299 ++++++++------- Backend/templates/timePage.templ | 54 ++- Backend/templates/timePage_templ.go | 188 ++++++---- DB/initdb/02_sample_data.sql | 2 +- DocumentCreator/Dockerfile | 5 +- pnpm-lock.yaml | 269 +++++++++++++ 20 files changed, 1180 insertions(+), 616 deletions(-) create mode 100644 Backend/models/compoundDay.go create mode 100644 Backend/templates/reportPage.templ create mode 100644 Backend/templates/reportPage_templ.go diff --git a/Backend/Makefile b/Backend/Makefile index 34598d0..53655ef 100644 --- a/Backend/Makefile +++ b/Backend/Makefile @@ -2,5 +2,15 @@ test: mkdir -p .test go test ./... -coverprofile=.test/coverage.out -json > .test/report.json -scan: - sonar-scanner -Dsonar.token=sqa_ca8394c93a728d6cff96703955288d8902c15200 +# scan: +# sonar-scanner -Dsonar.token=sqa_ca8394c93a728d6cff96703955288d8902c15200 + +# complete live run +live: + make -j2 live/templ live/tailwindcss + +live/templ: + templ generate --watch --proxy="http://localhost:8080" --cmd="go run ." --open-browser=false + +live/tailwind: + npx --yes tailwindcss -i ./input.css -o ./assets/styles.css --minify --watch diff --git a/Backend/endpoints/pdf-create.go b/Backend/endpoints/pdf-create.go index 443a2a1..2ccfad6 100644 --- a/Backend/endpoints/pdf-create.go +++ b/Backend/endpoints/pdf-create.go @@ -45,7 +45,8 @@ func convertDaysToTypst(days []models.IWorkDay, u models.User) ([]typstDay, erro func convertDayToTypstDayParts(day models.IWorkDay, user models.User) []typstDayPart { var typstDayParts []typstDayPart - if day.IsWorkDay() { + switch day.Type() { + case models.DayTypeWorkday: workDay, _ := day.(*models.WorkDay) for i := 0; i < len(workDay.Bookings); i += 2 { var typstDayPart typstDayPart @@ -64,13 +65,12 @@ func convertDayToTypstDayParts(day models.IWorkDay, user models.User) []typstDay IsWorkDay: true, }) } - if workdayAbsence := workDay.GetWorktimeAbsence(); (workdayAbsence != models.Absence{}) { - typstDayParts = append(typstDayParts, typstDayPart{IsWorkDay: false, WorkType: workdayAbsence.AbwesenheitTyp.Name}) + case models.DayTypeCompound: + for _, c := range day.(*models.CompoundDay).DayParts { + typstDayParts = append(typstDayParts, convertDayToTypstDayParts(c, user)...) } - - } else { - absentDay, _ := day.(*models.Absence) - typstDayParts = append(typstDayParts, typstDayPart{IsWorkDay: false, WorkType: absentDay.AbwesenheitTyp.Name}) + default: + typstDayParts = append(typstDayParts, typstDayPart{IsWorkDay: false, WorkType: day.ToString()}) } return typstDayParts } @@ -91,7 +91,7 @@ func PDFCreateController(w http.ResponseWriter, r *http.Request) { employes, err := models.GetUserByPersonalNrMulti(personalNumbers) if err != nil { slog.Warn("Error getting employes!", slog.Any("Error", err)) - return + // return } n := 0 @@ -102,6 +102,9 @@ func PDFCreateController(w http.ResponseWriter, r *http.Request) { } } employes = employes[:n] + if helper.GetEnv("GO_ENV", "production") == "debug" { + employes = append(employes, user) + } reportData := createReports(employes, startDate) diff --git a/Backend/models/absence.go b/Backend/models/absence.go index afeb79e..8b7e789 100644 --- a/Backend/models/absence.go +++ b/Backend/models/absence.go @@ -22,6 +22,11 @@ type Absence struct { DateTo time.Time } +// IsEmpty implements [IWorkDay]. +func (a *Absence) IsEmpty() bool { + return false +} + func NewAbsence(card_uid string, abwesenheit_typ int, datum time.Time) (Absence, error) { if abwesenheit_typ < 0 { return Absence{ @@ -95,7 +100,7 @@ func (a *Absence) GetTimes(u User, base WorktimeBase, includeKurzarbeit bool) (w } func (a *Absence) ToString() string { - return "Abwesenheit" + return a.AbwesenheitTyp.Name } func (a *Absence) IsWorkDay() bool { @@ -107,7 +112,7 @@ func (a *Absence) IsKurzArbeit() bool { } func (a *Absence) GetDayProgress(u User) int8 { - return 100 + return a.AbwesenheitTyp.WorkTime } func (a *Absence) RequiresAction() bool { diff --git a/Backend/models/compoundDay.go b/Backend/models/compoundDay.go new file mode 100644 index 0000000..618d919 --- /dev/null +++ b/Backend/models/compoundDay.go @@ -0,0 +1,105 @@ +package models + +import ( + "log/slog" + "time" +) + +type CompoundDay struct { + Day time.Time + DayParts []IWorkDay +} + +func NewCompondDay(date time.Time, dayParts ...IWorkDay) *CompoundDay { + return &CompoundDay{Day: date, DayParts: dayParts} +} + +func (c *CompoundDay) AddDayPart(dayPart IWorkDay) { + c.DayParts = append(c.DayParts, dayPart) +} + +func (c *CompoundDay) GetWorkDay() WorkDay { + workday, ok := c.DayParts[0].(*WorkDay) + if ok { + return *workday + } + return WorkDay{} +} + +// IsEmpty implements [IWorkDay]. +func (c *CompoundDay) IsEmpty() bool { + return len(c.DayParts) > 0 +} + +// Date implements [IWorkDay]. +func (c *CompoundDay) Date() time.Time { + return c.Day +} + +// GetDayProgress implements [IWorkDay]. +func (c *CompoundDay) GetDayProgress(u User) int8 { + var dayProcess int8 + for _, day := range c.DayParts { + dayProcess += day.GetDayProgress(u) + } + return dayProcess +} + +// GetOvertime implements [IWorkDay]. +func (c *CompoundDay) GetOvertime(u User, base WorktimeBase, includeKurzarbeit bool) time.Duration { + + var overtime time.Duration + for _, day := range c.DayParts { + overtime += day.GetOvertime(u, base, includeKurzarbeit) + } + return overtime +} + +// GetPausetime implements [IWorkDay]. +func (c *CompoundDay) GetPausetime(u User, base WorktimeBase, includeKurzarbeit bool) time.Duration { + var pausetime time.Duration + for _, day := range c.DayParts { + pausetime += day.GetPausetime(u, base, includeKurzarbeit) + } + return pausetime +} + +// GetTimes implements [IWorkDay]. +func (c *CompoundDay) GetTimes(u User, base WorktimeBase, includeKurzarbeit bool) (work time.Duration, pause time.Duration, overtime time.Duration) { + return c.GetWorktime(u, base, includeKurzarbeit), c.GetPausetime(u, base, includeKurzarbeit), c.GetOvertime(u, base, includeKurzarbeit) +} + +// GetWorktime implements [IWorkDay]. +func (c *CompoundDay) GetWorktime(u User, base WorktimeBase, includeKurzarbeit bool) time.Duration { + var worktime time.Duration + for _, day := range c.DayParts { + worktime += day.GetWorktime(u, base, includeKurzarbeit) + slog.Info("Calc worktime for day", "day", day, "worktime", worktime.String()) + } + return worktime +} + +// IsKurzArbeit implements [IWorkDay]. +func (c *CompoundDay) IsKurzArbeit() bool { + return false +} + +// IsWorkDay implements [IWorkDay]. +func (c *CompoundDay) IsWorkDay() bool { + return true +} + +// RequiresAction implements [IWorkDay]. +func (c *CompoundDay) RequiresAction() bool { + return false +} + +// ToString implements [IWorkDay]. +func (c *CompoundDay) ToString() string { + return "Compound Day" +} + +// Type implements [IWorkDay]. +func (c *CompoundDay) Type() DayType { + return DayTypeCompound +} diff --git a/Backend/models/iworkday.go b/Backend/models/iworkday.go index aff96ba..6305842 100644 --- a/Backend/models/iworkday.go +++ b/Backend/models/iworkday.go @@ -1,8 +1,6 @@ package models import ( - "arbeitszeitmessung/helper" - "log" "log/slog" "time" ) @@ -19,57 +17,73 @@ type IWorkDay interface { GetPausetime(User, WorktimeBase, bool) time.Duration GetTimes(User, WorktimeBase, bool) (work, pause, overtime time.Duration) GetOvertime(User, WorktimeBase, bool) time.Duration + IsEmpty() bool } type DayType int const ( - DayTypeWorkday DayType = 1 - DayTypeAbsence DayType = 2 - DayTypeHoliday DayType = 3 + DayTypeWorkday DayType = 1 + DayTypeAbsence DayType = 2 + DayTypeHoliday DayType = 3 + DayTypeCompound DayType = 4 ) func GetDays(user User, tsFrom, tsTo time.Time, orderedForward bool) []IWorkDay { var allDays map[string]IWorkDay = make(map[string]IWorkDay) - for _, day := range GetWorkDays(user, tsFrom, tsTo) { - allDays[day.Date().Format(time.DateOnly)] = &day - } + workdays := GetWorkDays(user, tsFrom, tsTo) absences, err := GetAbsencesByCardUID(user.CardUID, tsFrom, tsTo) if err != nil { - log.Println("Error gettings absences for all Days!", err) + slog.Warn("Error gettings absences!", slog.Any("Error", err)) return nil } holidays, err := GetHolidaysFromTo(tsFrom, tsTo) if err != nil { - slog.Warn("Error getting holidays from DB!", slog.Any("Error", err)) + slog.Warn("Error getting holidays!", slog.Any("Error", err)) + return nil } - for _, day := range absences { - if helper.IsWeekend(day.Date()) { + + for _, day := range workdays { + allDays[day.Date().Format(time.DateOnly)] = &day + } + + for _, absentDay := range absences { + // Kurzarbeit should be integrated in workday + existingDay, ok := allDays[absentDay.Date().Format(time.DateOnly)] + if !ok { + allDays[absentDay.Date().Format(time.DateOnly)] = &absentDay continue } - // Absence should be integrated in workday switch { - case day.AbwesenheitTyp.WorkTime < 0: - if workDay, ok := allDays[day.Date().Format(time.DateOnly)].(*WorkDay); ok { + case absentDay.AbwesenheitTyp.WorkTime < 0: + if workDay, ok := allDays[absentDay.Date().Format(time.DateOnly)].(*WorkDay); ok { workDay.kurzArbeit = true - workDay.kurzArbeitAbsence = day - } - case day.AbwesenheitTyp.WorkTime < 100: - if workDay, ok := allDays[day.Date().Format(time.DateOnly)].(*WorkDay); ok { - workDay.worktimeAbsece = day + workDay.kurzArbeitAbsence = absentDay } + case !existingDay.IsEmpty(): + allDays[absentDay.Date().Format(time.DateOnly)] = NewCompondDay(absentDay.Date(), existingDay, &absentDay) default: - allDays[day.Date().Format(time.DateOnly)] = &day + allDays[absentDay.Date().Format(time.DateOnly)] = &absentDay } } - for _, day := range holidays { - if helper.IsWeekend(day.Date()) { + for _, holiday := range holidays { + existingDay, ok := allDays[holiday.Date().Format(time.DateOnly)] + if !ok { + allDays[holiday.Date().Format(time.DateOnly)] = &holiday continue } - allDays[day.Date().Format(time.DateOnly)] = &day - slog.Debug("Logging Holiday: ", slog.String("HolidayName", allDays[day.Date().Format(time.DateOnly)].ToString()), slog.Any("Overtime", day.GetOvertime(user, WorktimeBaseDay, false).String()), "wokrtie", float32(day.worktime)/100) + slog.Info("Existing Day", "day", existingDay) + switch { + case existingDay.Type() == DayTypeCompound: + allDays[holiday.Date().Format(time.DateOnly)].(*CompoundDay).AddDayPart(&holiday) + case existingDay.Type() != DayTypeCompound && !existingDay.IsEmpty(): + allDays[holiday.Date().Format(time.DateOnly)] = NewCompondDay(holiday.Date(), existingDay, &holiday) + default: + allDays[holiday.Date().Format(time.DateOnly)] = &holiday + } + slog.Debug("Logging Holiday: ", slog.String("HolidayName", allDays[holiday.Date().Format(time.DateOnly)].ToString()), slog.Any("Overtime", holiday.GetOvertime(user, WorktimeBaseDay, false).String()), "wokrtie", float32(holiday.worktime)/100) } sortedDays := sortDays(allDays, orderedForward) diff --git a/Backend/models/publicHoliday.go b/Backend/models/publicHoliday.go index 97dce3e..567a610 100644 --- a/Backend/models/publicHoliday.go +++ b/Backend/models/publicHoliday.go @@ -14,6 +14,11 @@ type PublicHoliday struct { worktime int8 } +// IsEmpty implements [IWorkDay]. +func (p *PublicHoliday) IsEmpty() bool { + return false +} + func NewHolidayFromFeiertag(f feiertage.Feiertag) PublicHoliday { return PublicHoliday{ Feiertag: f, @@ -106,9 +111,9 @@ func (p *PublicHoliday) RequiresAction() bool { func (p *PublicHoliday) GetWorktime(u User, base WorktimeBase, includeKurzarbeit bool) time.Duration { switch base { case WorktimeBaseDay: - return u.ArbeitszeitProTagFrac(float32(p.worktime / 100)) + return u.ArbeitszeitProTagFrac(float32(p.worktime) / 100) case WorktimeBaseWeek: - return u.ArbeitszeitProWocheFrac(float32(p.worktime/100) * 0.2) + return u.ArbeitszeitProWocheFrac(float32(p.worktime) / 500) } return 0 } diff --git a/Backend/models/workDay.go b/Backend/models/workDay.go index afdcdc9..c995275 100644 --- a/Backend/models/workDay.go +++ b/Backend/models/workDay.go @@ -23,6 +23,11 @@ type WorkDay struct { worktimeAbsece Absence } +// IsEmpty implements [IWorkDay]. +func (d *WorkDay) IsEmpty() bool { + return len(d.Bookings) == 0 +} + type WorktimeBase int const ( diff --git a/Backend/templates/pages.templ b/Backend/templates/pages.templ index 01b142f..55735f8 100644 --- a/Backend/templates/pages.templ +++ b/Backend/templates/pages.templ @@ -1,6 +1,7 @@ package templates import "arbeitszeitmessung/models" +import "arbeitszeitmessung/helper" templ Base() { @@ -29,9 +30,7 @@ templ LoginPage(success bool, errorMsg string) { } templ SettingsPage(status int) { - {{ - user := ctx.Value("user").(models.User) - }} + {{ user := ctx.Value("user").(models.User) }} @Base() @headerComponent()
@@ -59,6 +58,8 @@ templ SettingsPage(status int) {

Nutzername: { user.Vorname } { user.Name }

Personalnummer: { user.PersonalNummer }

+

Arbeitszeit pro Tag: { helper.FormatDuration(user.ArbeitszeitProTag()) }

+

Arbeitszeit pro Woche: { helper.FormatDuration(user.ArbeitszeitProWoche()) }

@@ -82,27 +83,6 @@ templ statusCheckMark(status models.WeekStatus, target models.WeekStatus) { } } -templ TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) { - @Base() - @headerComponent() -
-
-
-

Eigene Abrechnung

-
-
- @workWeekComponent(userWeek, false) - if len(weeks) > 0 { -
-

Abrechnung Mitarbeiter

-
- } - for _, week := range weeks { - @workWeekComponent(week, true) - } -
-} - templ LogoutButton() { } diff --git a/Backend/templates/pages_templ.go b/Backend/templates/pages_templ.go index 933f53c..0e5daff 100644 --- a/Backend/templates/pages_templ.go +++ b/Backend/templates/pages_templ.go @@ -9,6 +9,7 @@ import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" import "arbeitszeitmessung/models" +import "arbeitszeitmessung/helper" func Base() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { @@ -76,7 +77,7 @@ func LoginPage(success bool, errorMsg string) templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(errorMsg) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 24, Col: 46} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 25, Col: 46} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -153,7 +154,7 @@ func SettingsPage(status int) templ.Component { var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 60, Col: 64} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 59, Col: 64} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -166,7 +167,7 @@ func SettingsPage(status int) templ.Component { var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 60, Col: 78} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 59, Col: 78} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -179,13 +180,39 @@ func SettingsPage(status int) templ.Component { var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(user.PersonalNummer) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 61, Col: 75} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 60, Col: 75} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "

Nutzer abmelden

Nutzer von Weboberfläche abmelden.

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "

Arbeitszeit pro Tag: ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var8 string + templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(user.ArbeitszeitProTag())) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 61, Col: 108} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "

Arbeitszeit pro Woche: ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var9 string + templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(user.ArbeitszeitProWoche())) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 62, Col: 112} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "

Nutzer abmelden

Nutzer von Weboberfläche abmelden.

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -209,18 +236,18 @@ func statusCheckMark(status models.WeekStatus, target models.WeekStatus) templ.C }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var8 := templ.GetChildren(ctx) - if templ_7745c5c3_Var8 == nil { - templ_7745c5c3_Var8 = templ.NopComponent + templ_7745c5c3_Var10 := templ.GetChildren(ctx) + if templ_7745c5c3_Var10 == nil { + templ_7745c5c3_Var10 = templ.NopComponent } ctx = templ.ClearChildren(ctx) if status >= target { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -229,63 +256,6 @@ func statusCheckMark(status models.WeekStatus, target models.WeekStatus) templ.C }) } -func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var9 := templ.GetChildren(ctx) - if templ_7745c5c3_Var9 == nil { - templ_7745c5c3_Var9 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = Base().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = headerComponent().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "

Eigene Abrechnung

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = workWeekComponent(userWeek, false).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if len(weeks) > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "

Abrechnung Mitarbeiter

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - for _, week := range weeks { - templ_7745c5c3_Err = workWeekComponent(week, true).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - func LogoutButton() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context @@ -302,12 +272,12 @@ func LogoutButton() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var10 := templ.GetChildren(ctx) - if templ_7745c5c3_Var10 == nil { - templ_7745c5c3_Var10 = templ.NopComponent + templ_7745c5c3_Var11 := templ.GetChildren(ctx) + if templ_7745c5c3_Var11 == nil { + templ_7745c5c3_Var11 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/Backend/templates/reportPage.templ b/Backend/templates/reportPage.templ new file mode 100644 index 0000000..df2bab2 --- /dev/null +++ b/Backend/templates/reportPage.templ @@ -0,0 +1,24 @@ +package templates + +import "arbeitszeitmessung/models" + +templ TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) { + @Base() + @headerComponent() +
+
+
+

Eigene Abrechnung

+
+
+ @workWeekComponent(userWeek, false) + if len(weeks) > 0 { +
+

Abrechnung Mitarbeiter

+
+ } + for _, week := range weeks { + @workWeekComponent(week, true) + } +
+} diff --git a/Backend/templates/reportPage_templ.go b/Backend/templates/reportPage_templ.go new file mode 100644 index 0000000..6a97c20 --- /dev/null +++ b/Backend/templates/reportPage_templ.go @@ -0,0 +1,70 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.960 +package templates + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "arbeitszeitmessung/models" + +func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = Base().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = headerComponent().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

Eigene Abrechnung

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = workWeekComponent(userWeek, false).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if len(weeks) > 0 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

Abrechnung Mitarbeiter

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + for _, week := range weeks { + templ_7745c5c3_Err = workWeekComponent(week, true).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/Backend/templates/teamComponents.templ b/Backend/templates/teamComponents.templ index 26501a4..9790ef7 100644 --- a/Backend/templates/teamComponents.templ +++ b/Backend/templates/teamComponents.templ @@ -9,9 +9,7 @@ import ( ) templ weekPicker(weekStart time.Time) { - {{ - year, kw := weekStart.ISOWeek() - }} + {{ year, kw := weekStart.ISOWeek() }}
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, " class=\"btn\">Bestätigen") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { switch { case week.RequiresAction(): - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "

bitte zuerst Buchungen anpassen

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "

bitte zuerst Buchungen anpassen

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } case time.Since(week.WeekStart) < 24*7*time.Hour: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "

Die Woche kann erst am nächsten Montag gesendet werden!

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "

Die Woche kann erst am nächsten Montag gesendet werden!

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } case week.Status == models.WeekStatusNone: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "

an Vorgesetzten senden

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "

an Vorgesetzten senden

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } case week.Status == models.WeekStatusSent: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "

an Vorgesetzten gesendet

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "

an Vorgesetzten gesendet

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } case week.Status == models.WeekStatusAccepted: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "

vom Vorgesetzten bestätigt

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "

vom Vorgesetzten bestätigt

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, " Korrigieren Korrigieren = models.WeekStatusSent || week.RequiresAction() { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, " disabled") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, " disabled") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, " type=\"submit\" class=\"btn\">Senden") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, " type=\"submit\" class=\"btn\">Senden") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -643,53 +670,53 @@ func userPresenceComponent(user models.User, present bool) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var24 := templ.GetChildren(ctx) - if templ_7745c5c3_Var24 == nil { - templ_7745c5c3_Var24 = templ.NopComponent + templ_7745c5c3_Var25 := templ.GetChildren(ctx) + if templ_7745c5c3_Var25 == nil { + templ_7745c5c3_Var25 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if present { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "
Anwesend
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "
Anwesend
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "
Abwesend
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "
Abwesend
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var25 string - templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 173, Col: 19} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var26 string - templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name) + templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 173, Col: 33} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 170, Col: 19} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var27 string + templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 170, Col: 33} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/Backend/templates/timeComponents.templ b/Backend/templates/timeComponents.templ index 9fad41d..e2f0d62 100644 --- a/Backend/templates/timeComponents.templ +++ b/Backend/templates/timeComponents.templ @@ -77,12 +77,9 @@ templ absenceComponent(a *models.Absence, isKurzarbeit bool) { } }}
- - - - + @absentInput(a)

- { a.AbwesenheitTyp.Name } + { a.ToString() } if a.IsMultiDay() { bis { a.DateTo.Format("02.01.2006") } } @@ -94,6 +91,13 @@ templ absenceComponent(a *models.Absence, isKurzarbeit bool) {

} +templ absentInput(a *models.Absence) { + + + + +} + templ newBookingComponent(d *models.WorkDay) { ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func absentInput(a *models.Absence) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var19 := templ.GetChildren(ctx) + if templ_7745c5c3_Var19 == nil { + templ_7745c5c3_Var19 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -434,58 +471,58 @@ func newBookingComponent(d *models.WorkDay) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var23 := templ.GetChildren(ctx) - if templ_7745c5c3_Var23 == nil { - templ_7745c5c3_Var23 = templ.NopComponent + templ_7745c5c3_Var24 := templ.GetChildren(ctx) + if templ_7745c5c3_Var24 == nil { + templ_7745c5c3_Var24 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -509,74 +546,74 @@ func bookingComponent(booking models.Booking) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var26 := templ.GetChildren(ctx) - if templ_7745c5c3_Var26 == nil { - templ_7745c5c3_Var26 = templ.NopComponent + templ_7745c5c3_Var27 := templ.GetChildren(ctx) + if templ_7745c5c3_Var27 == nil { + templ_7745c5c3_Var27 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var27 string - templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(booking.Timestamp.Format("15:04")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 119, Col: 91} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var28 string - templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs("booking_" + strconv.Itoa(booking.CounterId)) + templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(booking.Timestamp.Format("15:04")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 120, Col: 70} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 123, Col: 91} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "\" type=\"time\" value=\"") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "\" type=\"time\" value=\"") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var30 string - templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(booking.GetBookingType()) + templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(booking.Timestamp.Format("15:04")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 121, Col: 29} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 124, Col: 126} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "\" class=\"text-neutral-700 group-[.edit]:inline hidden bg-neutral-100 text-sm px-3 py-2 cursor-pointer\"> ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var31 string + templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(booking.GetBookingType()) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 125, Col: 29} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if booking.IsSubmittedAndChecked() { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "

submitted

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "

submitted

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -600,12 +637,12 @@ func LegendComponent() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var31 := templ.GetChildren(ctx) - if templ_7745c5c3_Var31 == nil { - templ_7745c5c3_Var31 = templ.NopComponent + templ_7745c5c3_Var32 := templ.GetChildren(ctx) + if templ_7745c5c3_Var32 == nil { + templ_7745c5c3_Var32 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "
Fehler
Arbeitszeit unter regulär
Arbeitszeit vollständig
Überstunden
Keine Buchungen
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "
Fehler
Arbeitszeit unter regulär
Arbeitszeit vollständig
Überstunden
Keine Buchungen
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/Backend/templates/timePage.templ b/Backend/templates/timePage.templ index 3e8723c..d0dd450 100644 --- a/Backend/templates/timePage.templ +++ b/Backend/templates/timePage.templ @@ -87,7 +87,7 @@ templ defaultDayComponent(day models.IWorkDay) { {{ user := ctx.Value("user").(models.User) justify := "justify-center" - if day.IsWorkDay() && len(day.(*models.WorkDay).Bookings) > 1 { + if day.IsWorkDay() && !day.IsEmpty() { justify = "justify-between" } }} @@ -100,9 +100,8 @@ templ defaultDayComponent(day models.IWorkDay) {

if day.IsWorkDay() { {{ - workDay, _ := day.(*models.WorkDay) - work, pause, overtime := workDay.GetTimes(user, models.WorktimeBaseDay, true) - work = workDay.GetWorktime(user, models.WorktimeBaseDay, false) + work, pause, overtime := day.GetTimes(user, models.WorktimeBaseDay, true) + work = day.GetWorktime(user, models.WorktimeBaseDay, false) }} if day.RequiresAction() {

Bitte anpassen

@@ -114,7 +113,7 @@ templ defaultDayComponent(day models.IWorkDay) { if pause > 0 {

{ helper.FormatDuration(pause) }

} - if overtime != 0 && len(workDay.Bookings) > 0 { + if overtime != 0 && day.IsEmpty() == false {

{ helper.FormatDuration(overtime) } @@ -130,20 +129,25 @@ templ defaultDayComponent(day models.IWorkDay) { switch day.Type() { case models.DayTypeWorkday: {{ workDay, _ := day.(*models.WorkDay) }} + @workdayComponent(workDay) @newAbsenceComponent() - if len(workDay.Bookings) < 1 { -

Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!

- } - if workDay.IsKurzArbeit() && len(workDay.Bookings) > 0 { - @absenceComponent(workDay.GetKurzArbeit(), true) - } - for _, booking := range workDay.Bookings { - @bookingComponent(booking) - } - @newBookingComponent(workDay) case models.DayTypeAbsence: {{ absentDay, _ := day.(*models.Absence) }} @absenceComponent(absentDay, false) + case models.DayTypeCompound: + for _, c := range day.(*models.CompoundDay).DayParts { + switch c.Type() { + case models.DayTypeWorkday: + {{ workDay, _ := c.(*models.WorkDay) }} + @workdayComponent(workDay) + @newAbsenceComponent() + case models.DayTypeAbsence: + {{ absentDay, _ := c.(*models.Absence) }} + @absenceComponent(absentDay, false) + default: +

{ c.ToString() }

+ } + } default:

{ day.ToString() }

} @@ -156,9 +160,19 @@ templ defaultDayComponent(day models.IWorkDay) { } -templ absentInput(a models.Absence) { - - - - +templ workdayComponent(workDay *models.WorkDay) { + if len(workDay.Bookings) < 1 { +

Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!

+ } + if workDay.IsKurzArbeit() && len(workDay.Bookings) > 0 { + @absenceComponent(workDay.GetKurzArbeit(), true) + } + for _, booking := range workDay.Bookings { + @bookingComponent(booking) + } + @newBookingComponent(workDay) +} + +templ holidayComponent(d models.IWorkDay) { +

{ d.ToString() }

} diff --git a/Backend/templates/timePage_templ.go b/Backend/templates/timePage_templ.go index d6c1520..3484084 100644 --- a/Backend/templates/timePage_templ.go +++ b/Backend/templates/timePage_templ.go @@ -232,7 +232,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component { ctx = templ.ClearChildren(ctx) user := ctx.Value("user").(models.User) justify := "justify-center" - if day.IsWorkDay() && len(day.(*models.WorkDay).Bookings) > 1 { + if day.IsWorkDay() && !day.IsEmpty() { justify = "justify-between" } var templ_7745c5c3_Var10 = []any{"grid-sub divide-x-1 hover:bg-neutral-200 transition-colors group"} @@ -292,9 +292,8 @@ func defaultDayComponent(day models.IWorkDay) templ.Component { return templ_7745c5c3_Err } if day.IsWorkDay() { - workDay, _ := day.(*models.WorkDay) - work, pause, overtime := workDay.GetTimes(user, models.WorktimeBaseDay, true) - work = workDay.GetWorktime(user, models.WorktimeBaseDay, false) + work, pause, overtime := day.GetTimes(user, models.WorktimeBaseDay, true) + work = day.GetWorktime(user, models.WorktimeBaseDay, false) if day.RequiresAction() { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "

Bitte anpassen

") if templ_7745c5c3_Err != nil { @@ -309,7 +308,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component { var templ_7745c5c3_Var14 string templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(work)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 112, Col: 155} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 111, Col: 155} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) if templ_7745c5c3_Err != nil { @@ -332,7 +331,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component { var templ_7745c5c3_Var15 string templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(pause)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 115, Col: 173} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 114, Col: 173} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) if templ_7745c5c3_Err != nil { @@ -347,7 +346,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - if overtime != 0 && len(workDay.Bookings) > 0 { + if overtime != 0 && day.IsEmpty() == false { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err @@ -355,7 +354,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component { var templ_7745c5c3_Var16 string templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(overtime)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 120, Col: 41} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 119, Col: 41} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) if templ_7745c5c3_Err != nil { @@ -388,7 +387,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component { var templ_7745c5c3_Var18 string templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs("time-" + day.Date().Format(time.DateOnly)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 129, Col: 56} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 128, Col: 56} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) if templ_7745c5c3_Err != nil { @@ -414,7 +413,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component { switch day.Type() { case models.DayTypeWorkday: workDay, _ := day.(*models.WorkDay) - templ_7745c5c3_Err = newAbsenceComponent().Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = workdayComponent(workDay).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -422,33 +421,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - if len(workDay.Bookings) < 1 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "

Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if workDay.IsKurzArbeit() && len(workDay.Bookings) > 0 { - templ_7745c5c3_Err = absenceComponent(workDay.GetKurzArbeit(), true).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - for _, booking := range workDay.Bookings { - templ_7745c5c3_Err = bookingComponent(booking).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = newBookingComponent(workDay).Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = newAbsenceComponent().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -458,17 +431,60 @@ func defaultDayComponent(day models.IWorkDay) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } + case models.DayTypeCompound: + for _, c := range day.(*models.CompoundDay).DayParts { + switch c.Type() { + case models.DayTypeWorkday: + workDay, _ := c.(*models.WorkDay) + templ_7745c5c3_Err = workdayComponent(workDay).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = newAbsenceComponent().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + case models.DayTypeAbsence: + absentDay, _ := c.(*models.Absence) + templ_7745c5c3_Err = absenceComponent(absentDay, false).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + default: + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var20 string + templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(c.ToString()) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 148, Col: 26} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } default: templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var20 string - templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(day.ToString()) + var templ_7745c5c3_Var21 string + templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(day.ToString()) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 148, Col: 25} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 152, Col: 25} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -493,7 +509,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component { }) } -func absentInput(a models.Absence) templ.Component { +func workdayComponent(workDay *models.WorkDay) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -509,64 +525,72 @@ func absentInput(a models.Absence) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var21 := templ.GetChildren(ctx) - if templ_7745c5c3_Var21 == nil { - templ_7745c5c3_Var21 = templ.NopComponent + templ_7745c5c3_Var22 := templ.GetChildren(ctx) + if templ_7745c5c3_Var22 == nil { + templ_7745c5c3_Var22 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + if workDay.IsKurzArbeit() && len(workDay.Bookings) > 0 { + templ_7745c5c3_Err = absenceComponent(workDay.GetKurzArbeit(), true).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + for _, booking := range workDay.Bookings { + templ_7745c5c3_Err = bookingComponent(booking).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = newBookingComponent(workDay).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var22 string - templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(a.DateFrom.Format(time.DateOnly)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 160, Col: 79} + return nil + }) +} + +func holidayComponent(d models.IWorkDay) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "\"> ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var24 string - templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(a.AbwesenheitTyp.Id) + templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(d.ToString()) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 162, Col: 64} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 177, Col: 18} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "\"> ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/DB/initdb/02_sample_data.sql b/DB/initdb/02_sample_data.sql index a0ee8f3..ea7fcf7 100755 --- a/DB/initdb/02_sample_data.sql +++ b/DB/initdb/02_sample_data.sql @@ -5,4 +5,4 @@ INSERT INTO "user_password" ("personal_nummer", "pass_hash") VALUES (123, crypt('max_pass', gen_salt('bf'))); INSERT INTO "s_anwesenheit_typen" ("anwesenheit_id", "anwesenheit_name") VALUES (1, 'Büro'); -INSERT INTO "s_abwesenheit_typen" ("abwesenheit_id", "abwesenheit_name", "arbeitszeit_equivalent") VALUES (1, 'Urlaub', 10), (2, 'Krank', 10), (3, 'Kurzarbeit', 2); +INSERT INTO "s_abwesenheit_typen" ("abwesenheit_id", "abwesenheit_name", "arbeitszeit_equivalent") VALUES (1, 'Urlaub', 100), (2, 'Krank', 100), (3, 'Kurzarbeit', -1), (4, 'Urlaub untertags', 50); diff --git a/DocumentCreator/Dockerfile b/DocumentCreator/Dockerfile index 1989fed..e132f75 100644 --- a/DocumentCreator/Dockerfile +++ b/DocumentCreator/Dockerfile @@ -1,6 +1,7 @@ FROM ghcr.io/typst/typst:0.14.0 -COPY ./templates ./templates -COPY ./static ./static +WORKDIR /app +COPY ./templates /app/templates +COPY ./static /app/static ENTRYPOINT ["sh", "-c", "while true; do sleep 3600; done"] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 18cb121..a07ce83 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,42 @@ importers: tailwindcss: specifier: ^4.1.12 version: 4.1.12 + devDependencies: + '@iconify-json/material-symbols-light': + specifier: ^1.2.33 + version: 1.2.50 + '@iconify/tailwind4': + specifier: ^1.0.6 + version: 1.2.0(tailwindcss@4.1.12) + prettier: + specifier: ^3.6.2 + version: 3.7.4 packages: + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + + '@cyberalien/svg-utils@1.0.11': + resolution: {integrity: sha512-qEE9mnyI+avfGT3emKuRs3ucYkITeaV0Xi7VlYN41f+uGnZBecQP3jwz/AF437H9J4Q7qPClHKm4NiTYpNE6hA==} + + '@iconify-json/material-symbols-light@1.2.50': + resolution: {integrity: sha512-Ehvmar2TPoYxmKgB5szeIMlmvA/mIc7gzUoQ5/AWFG+N6d4T53uCHwxnXFf1nXPWlpf0+cv26AXMJC6W5mkdrQ==} + + '@iconify/tailwind4@1.2.0': + resolution: {integrity: sha512-+t7XqfojOB0zzZdd8gV7IQZGq1AaIHTlsxMVzagxYR0hAlJCLUD63o3iSlNKRMH3ZR7gZ8y5c9dJ7J431avRbA==} + peerDependencies: + tailwindcss: '>= 4.0.0' + + '@iconify/tools@5.0.1': + resolution: {integrity: sha512-/znhBN9WIpJd9UtKhyEDfRKwNo8rrOy8dShF8bwSZ1i27ukTSHjeS6bmVK4tTYBYriwFhBf70JT6g8GIRwFvbw==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@3.1.0': + resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==} + '@isaacs/fs-minipass@4.0.1': resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} @@ -208,6 +241,14 @@ packages: resolution: {integrity: sha512-gM5EoKHW/ukmlEtphNwaGx45fGoEmP10v51t9unv55voWh6WrOL19hfuIdo2FjxIaZzw776/BUQg7Pck++cIVw==} engines: {node: '>= 10'} + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -216,6 +257,32 @@ packages: resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} engines: {node: '>=18'} + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@3.1.0: + resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + detect-libc@1.0.3: resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} engines: {node: '>=0.10'} @@ -225,10 +292,30 @@ packages: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + enhanced-resolve@5.18.3: resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -319,6 +406,12 @@ packages: magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.12.2: + resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -336,6 +429,13 @@ packages: engines: {node: '>=10'} hasBin: true + mlly@1.8.0: + resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + + modern-tar@0.7.3: + resolution: {integrity: sha512-4W79zekKGyYU4JXVmB78DOscMFaJth2gGhgfTl2alWE4rNe3nf4N2pqenQ0rEtIewrnD79M687Ouba3YGTLOvg==} + engines: {node: '>=18.0.0'} + mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -343,6 +443,15 @@ packages: node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -350,10 +459,26 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + prettier@3.7.4: + resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} + engines: {node: '>=14'} + hasBin: true + + sax@1.4.3: + resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + svgo@4.0.0: + resolution: {integrity: sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==} + engines: {node: '>=16'} + hasBin: true + tailwindcss@4.1.12: resolution: {integrity: sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==} @@ -365,16 +490,61 @@ packages: resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} engines: {node: '>=18'} + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + yallist@5.0.0: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} snapshots: + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.6.0 + tinyexec: 1.0.2 + + '@cyberalien/svg-utils@1.0.11': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/material-symbols-light@1.2.50': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify/tailwind4@1.2.0(tailwindcss@4.1.12)': + dependencies: + '@iconify/tools': 5.0.1 + '@iconify/types': 2.0.0 + '@iconify/utils': 3.1.0 + tailwindcss: 4.1.12 + + '@iconify/tools@5.0.1': + dependencies: + '@cyberalien/svg-utils': 1.0.11 + '@iconify/types': 2.0.0 + '@iconify/utils': 3.1.0 + fflate: 0.8.2 + modern-tar: 0.7.3 + pathe: 2.0.3 + svgo: 4.0.0 + + '@iconify/types@2.0.0': {} + + '@iconify/utils@3.1.0': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@iconify/types': 2.0.0 + mlly: 1.8.0 + '@isaacs/fs-minipass@4.0.1': dependencies: minipass: 7.1.2 @@ -532,21 +702,75 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.12 '@tailwindcss/oxide-win32-x64-msvc': 4.1.12 + acorn@8.15.0: {} + + boolbase@1.0.0: {} + braces@3.0.3: dependencies: fill-range: 7.1.1 chownr@3.0.0: {} + commander@11.1.0: {} + + confbox@0.1.8: {} + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + + css-tree@3.1.0: + dependencies: + mdn-data: 2.12.2 + source-map-js: 1.2.1 + + css-what@6.2.2: {} + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + detect-libc@1.0.3: {} detect-libc@2.0.4: {} + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + enhanced-resolve@5.18.3: dependencies: graceful-fs: 4.2.11 tapable: 2.2.2 + entities@4.5.0: {} + + fflate@0.8.2: {} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -612,6 +836,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + mdn-data@2.0.28: {} + + mdn-data@2.12.2: {} + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -625,16 +853,53 @@ snapshots: mkdirp@3.0.1: {} + mlly@1.8.0: + dependencies: + acorn: 8.15.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.1 + + modern-tar@0.7.3: {} + mri@1.2.0: {} node-addon-api@7.1.1: {} + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + package-manager-detector@1.6.0: {} + + pathe@2.0.3: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.0 + pathe: 2.0.3 + + prettier@3.7.4: {} + + sax@1.4.3: {} + source-map-js@1.2.1: {} + svgo@4.0.0: + dependencies: + commander: 11.1.0 + css-select: 5.2.2 + css-tree: 3.1.0 + css-what: 6.2.2 + csso: 5.0.5 + picocolors: 1.1.1 + sax: 1.4.3 + tailwindcss@4.1.12: {} tapable@2.2.2: {} @@ -648,8 +913,12 @@ snapshots: mkdirp: 3.0.1 yallist: 5.0.0 + tinyexec@1.0.2: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 + ufo@1.6.1: {} + yallist@5.0.0: {}