-
-
-
+
Nutzer abmelden
Nutzer von Weboberfläche abmelden.
-
+
}
+templ statusCheckMark(status models.WeekStatus, target models.WeekStatus) {
+ if status >= target {
+
+ } else {
+
+ }
+}
+
templ TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) {
- {{
- year, kw := userWeek.WeekStart.ISOWeek()
- }}
@Base()
@headerComponent()
+ {{
+ progress := (float32(userWeek.WorkHours.Hours()) / userWeek.User.ArbeitszeitPerWoche) * 100
+ log.Println(userWeek.CheckStatus())
+ }}
-
-
- { fmt.Sprintf("%s %s", userWeek.User.Vorname, userWeek.User.Name) }
+
+
+
+ @weekPicker(userWeek.WeekStart)
+
+
{ fmt.Sprintf("%s %s", userWeek.User.Vorname, userWeek.User.Name) }
+
+
+
+ @statusCheckMark(userWeek.CheckStatus(), models.WeekStatusSent)
+ Gesendet
+
+
+ @statusCheckMark(userWeek.CheckStatus(), models.WeekStatusAccepted)
+ Akzeptiert
+
+
+
+ @timeGaugeComponent(uint8(progress), false, false)
+
+
Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(userWeek.WorkHours)) }
+
Überstunden: { fmt.Sprintf("%s", helper.FormatDuration(userWeek.GetOvertime())) }
+
+
+
-
+
for _, day := range userWeek.WorkDays {
@weekDayComponent(userWeek.User, day)
}
-
@@ -151,17 +160,6 @@ templ TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) {
}
-templ NavPage() {
- @Base()
-
-}
-
templ TeamPresencePage(teamPresence map[bool][]models.User) {
@Base()
@headerComponent()
@@ -186,5 +184,5 @@ templ TeamPresencePage(teamPresence map[bool][]models.User) {
}
templ LogoutButton() {
-
+
}
diff --git a/Backend/templates/pages_templ.go b/Backend/templates/pages_templ.go
index d9d42b6..0628d10 100644
--- a/Backend/templates/pages_templ.go
+++ b/Backend/templates/pages_templ.go
@@ -9,8 +9,10 @@ import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
+ "arbeitszeitmessung/helper"
"arbeitszeitmessung/models"
"fmt"
+ "log"
"strconv"
"time"
)
@@ -171,7 +173,7 @@ func UserPage(status int) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
Nutzer abmelden
Nutzer von Weboberfläche abmelden.
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -200,6 +202,42 @@ func UserPage(status int) templ.Component {
})
}
+func statusCheckMark(status models.WeekStatus, target models.WeekStatus) 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_Var5 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var5 == nil {
+ templ_7745c5c3_Var5 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ if status >= target {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ } else {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ return nil
+ })
+}
+
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
@@ -216,13 +254,11 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var5 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var5 == nil {
- templ_7745c5c3_Var5 = templ.NopComponent
+ templ_7745c5c3_Var6 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var6 == nil {
+ templ_7745c5c3_Var6 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
-
- year, kw := userWeek.WeekStart.ISOWeek()
templ_7745c5c3_Err = Base().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
@@ -231,20 +267,81 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
")
+
+ progress := (float32(userWeek.WorkHours.Hours()) / userWeek.User.ArbeitszeitPerWoche) * 100
+ log.Println(userWeek.CheckStatus())
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var6 string
- templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s %s", userWeek.User.Vorname, userWeek.User.Name))
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 92, Col: 69}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
+ templ_7745c5c3_Err = weekPicker(userWeek.WeekStart).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var7 string
+ templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s %s", userWeek.User.Vorname, userWeek.User.Name))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 110, Col: 101}
+ }
+ _, 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, 16, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = statusCheckMark(userWeek.CheckStatus(), models.WeekStatusSent).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "Gesendet ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = statusCheckMark(userWeek.CheckStatus(), models.WeekStatusAccepted).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "Akzeptiert
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = timeGaugeComponent(uint8(progress), false, false).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "
Arbeitszeit: ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var8 string
+ templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(userWeek.WorkHours)))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 125, Col: 85}
+ }
+ _, 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, 20, "
Überstunden: ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var9 string
+ templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(userWeek.GetOvertime())))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 126, Col: 90}
+ }
+ _, 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, 21, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -254,140 +351,82 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -397,40 +436,7 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- return nil
- })
-}
-
-func NavPage() 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_Var13 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var13 == nil {
- templ_7745c5c3_Var13 = 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 = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -454,9 +460,9 @@ func TeamPresencePage(teamPresence map[bool][]models.User) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var14 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var14 == nil {
- templ_7745c5c3_Var14 = templ.NopComponent
+ templ_7745c5c3_Var12 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var12 == nil {
+ templ_7745c5c3_Var12 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = Base().Render(ctx, templ_7745c5c3_Buffer)
@@ -467,7 +473,7 @@ func TeamPresencePage(teamPresence map[bool][]models.User) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
Anwesend
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
Anwesend
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -477,7 +483,7 @@ func TeamPresencePage(teamPresence map[bool][]models.User) templ.Component {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
Nicht Anwesend
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "
Nicht Anwesend
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -487,7 +493,7 @@ func TeamPresencePage(teamPresence map[bool][]models.User) templ.Component {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -511,12 +517,12 @@ func LogoutButton() templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var15 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var15 == nil {
- templ_7745c5c3_Var15 = templ.NopComponent
+ templ_7745c5c3_Var13 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var13 == nil {
+ templ_7745c5c3_Var13 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
diff --git a/Backend/templates/teamComponents.templ b/Backend/templates/teamComponents.templ
index 6da52f9..1addb91 100644
--- a/Backend/templates/teamComponents.templ
+++ b/Backend/templates/teamComponents.templ
@@ -7,6 +7,29 @@ import (
"time"
)
+templ weekPicker(weekStart time.Time) {
+ {{
+ year, kw := weekStart.ISOWeek()
+ }}
+
+
+
+ KW { fmt.Sprintf("%02d, %d", kw, year) }
+
+
+ if time.Since(weekStart) < 24*7*time.Hour {
+
Die Woche kann erst am nächsten Montag gesendet werden!
+ }
+}
+
templ weekDayComponent(user models.User, day models.WorkDay) {
{{ work, pause := day.GetWorkTimeString() }}
diff --git a/Backend/templates/teamComponents_templ.go b/Backend/templates/teamComponents_templ.go
index eb1d08c..d5d2ad9 100644
--- a/Backend/templates/teamComponents_templ.go
+++ b/Backend/templates/teamComponents_templ.go
@@ -15,7 +15,7 @@ import (
"time"
)
-func weekDayComponent(user models.User, day models.WorkDay) templ.Component {
+func weekPicker(weekStart time.Time) 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 {
@@ -36,8 +36,115 @@ func weekDayComponent(user models.User, day models.WorkDay) templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
+
+ year, kw := weekStart.ISOWeek()
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, templ.JSFuncCall("navigateWeek", templ.JSExpression("this"), templ.JSExpression("event"), "-1"))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "KW ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var4 string
+ templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d, %d", kw, year))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 21, Col: 69}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, templ.JSFuncCall("navigateWeek", templ.JSExpression("this"), templ.JSExpression("event"), "1"))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ if time.Since(weekStart) < 24*7*time.Hour {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
Die Woche kann erst am nächsten Montag gesendet werden!
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ return nil
+ })
+}
+
+func weekDayComponent(user models.User, day 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 {
+ 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_Var6 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var6 == nil {
+ templ_7745c5c3_Var6 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
work, pause := day.GetWorkTimeString()
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -45,118 +152,118 @@ func weekDayComponent(user models.User, day models.WorkDay) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var2 string
- templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(day.Day.Format("Mon"))
+ var templ_7745c5c3_Var7 string
+ templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(day.Day.Format("Mon"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 15, Col: 89}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 38, Col: 89}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
+ _, 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, 3, ": ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, ": ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var3 string
- templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(day.Day.Format("02.01.2006"))
+ var templ_7745c5c3_Var8 string
+ templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(day.Day.Format("02.01.2006"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 15, Col: 130}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 38, Col: 130}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
+ _, 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, 4, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var4 string
- templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(work)
+ var templ_7745c5c3_Var9 string
+ templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(work)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 17, Col: 36}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 40, Col: 36}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
+ _, 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, 5, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var5 string
- templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(pause)
+ var templ_7745c5c3_Var10 string
+ templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(pause)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 18, Col: 42}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 41, Col: 42}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if day.Absence.Datum.Equal(day.Day) {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var6 string
- templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(day.Absence.AbwesenheitTyp.Name)
+ var templ_7745c5c3_Var11 string
+ templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(day.Absence.AbwesenheitTyp.Name)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 26, Col: 41}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 49, Col: 41}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else if !day.TimeFrom.Equal(day.TimeTo) {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var7 string
- templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(day.TimeFrom.Format("15:04"))
+ var templ_7745c5c3_Var12 string
+ templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(day.TimeFrom.Format("15:04"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 28, Col: 41}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 51, Col: 41}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " - ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " - ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var8 string
- templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(day.TimeTo.Format("15:04"))
+ var templ_7745c5c3_Var13 string
+ templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(day.TimeTo.Format("15:04"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 30, Col: 39}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 53, Col: 39}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
Keine Anwesenheit
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
Keine Anwesenheit
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -180,53 +287,53 @@ func employeComponent(week models.WorkWeek) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var9 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var9 == nil {
- templ_7745c5c3_Var9 = templ.NopComponent
+ templ_7745c5c3_Var14 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var14 == nil {
+ templ_7745c5c3_Var14 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
year, kw := week.WeekStart.ISOWeek()
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var10 string
- templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Vorname)
+ var templ_7745c5c3_Var15 string
+ templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Vorname)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 45, Col: 53}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 68, Col: 53}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var11 string
- templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Name)
+ var templ_7745c5c3_Var16 string
+ templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Name)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 45, Col: 72}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 68, Col: 72}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
Arbeitszeit
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
Arbeitszeit
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var12 string
- templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(week.GetWorkHourString())
+ var templ_7745c5c3_Var17 string
+ templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(week.GetWorkHourString())
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 47, Col: 52}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 70, Col: 52}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -236,46 +343,46 @@ func employeComponent(week models.WorkWeek) templ.Component {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "
Woche: ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "
Woche: ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var13 string
- templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d-%d", kw, year))
+ var templ_7745c5c3_Var18 string
+ templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d-%d", kw, year))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 55, Col: 85}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 78, Col: 85}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "\">
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -299,53 +406,53 @@ func userPresenceComponent(user models.User, present bool) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var16 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var16 == nil {
- templ_7745c5c3_Var16 = templ.NopComponent
+ templ_7745c5c3_Var21 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var21 == nil {
+ templ_7745c5c3_Var21 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if present {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
Anwesend
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
Anwesend
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
Abwesend
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
Abwesend
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var17 string
- templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname)
+ var templ_7745c5c3_Var22 string
+ templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 73, Col: 19}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 96, Col: 19}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var18 string
- templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name)
+ var templ_7745c5c3_Var23 string
+ templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 73, Col: 33}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 96, Col: 33}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
diff --git a/Backend/templates/timeComponents.templ b/Backend/templates/timeComponents.templ
index bdd7c10..7648f97 100644
--- a/Backend/templates/timeComponents.templ
+++ b/Backend/templates/timeComponents.templ
@@ -30,7 +30,7 @@ templ inputForm() {
@@ -91,7 +91,7 @@ templ dayComponent(workDay models.WorkDay) {
}
templ changeButtonComponent(id string) {
-
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\" name=\"time_to\" class=\"w-full bg-neutral-100 placeholder:text-neutral-400 text-neutral-700 text-sm border border-neutral-0 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none focus:border-neutral-400 hover:border-neutral-300\" placeholder=\"Zeitraum bis...\">
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -358,7 +358,7 @@ func changeButtonComponent(id string) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "
0 && progress < 90):
+ case (progress > 0 && progress < 95):
bgColor = "bg-orange-500"
break
- case (90 <= progress && progress <= 110):
+ case (95 <= progress && progress <= 105):
bgColor = "bg-accent"
break
- case (progress > 110):
+ case (progress > 105):
bgColor = "bg-purple-600"
break
default:
From 45440b6457d24eff958842009323d7cdbf9f51e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=20Tr=C3=B6ger?=
Date: Wed, 3 Sep 2025 14:31:14 +0200
Subject: [PATCH 48/52] added tests
---
Backend/models/workWeek_test.go | 50 +++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
create mode 100644 Backend/models/workWeek_test.go
diff --git a/Backend/models/workWeek_test.go b/Backend/models/workWeek_test.go
new file mode 100644
index 0000000..b94dd04
--- /dev/null
+++ b/Backend/models/workWeek_test.go
@@ -0,0 +1,50 @@
+package models_test
+
+import (
+ "arbeitszeitmessung/models"
+ "testing"
+ "time"
+)
+
+func SetupWorkWeekFixture(t *testing.T) models.WorkWeek {
+ t.Helper()
+ monday, err := time.Parse("2006-01-02", "2025-01-10")
+ if err != nil {
+ t.Fatal(err)
+ }
+ return models.WorkWeek{User: testUser, WeekStart: monday, Status: models.WeekStatusSent}
+}
+
+func TestNewWorkWeekNoPopulate(t *testing.T) {
+ monday, err := time.Parse("2006-01-02", "2025-01-10")
+ if err != nil {
+ t.Fatal(err)
+ }
+ workWeek := models.NewWorkWeek(testUser, monday, false)
+
+ if workWeek.User != testUser || workWeek.WeekStart != monday {
+ t.Error("No populate workweek does not have right values!")
+ }
+}
+
+func TestCheckStatus(t *testing.T) {
+ testWeek := SetupWorkWeekFixture(t)
+ testCases := []struct {
+ name string
+ weekStatus models.WeekStatus
+ }{
+ {"State=None", models.WeekStatusNone},
+ {"State=Sent", models.WeekStatusSent},
+ {"State=Accepted", models.WeekStatusAccepted},
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ testWeek.Status = tc.weekStatus
+ if testWeek.CheckStatus() != tc.weekStatus {
+ t.Error("WorkWeek Status missmatch!")
+ }
+ })
+ }
+
+}
From 1ae30c11cb64fe20023b8f175fc1894b4d223f93 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=20Tr=C3=B6ger?=
Date: Thu, 4 Sep 2025 00:11:33 +0200
Subject: [PATCH 49/52] added overtime to time and team page + ui improvements
+ mobile support for team page closed #12
---
Backend/endpoints/team.go | 4 +-
Backend/endpoints/time.go | 20 +-
Backend/models/absence.go | 2 +-
Backend/models/user.go | 32 +-
Backend/models/workDay.go | 12 +-
Backend/models/workWeek.go | 76 +-
Backend/src/main.css | 5 +-
Backend/static/css/styles.css | 118 +-
Backend/templates/pages.templ | 33 +-
Backend/templates/pages_templ.go | 44 +-
Backend/templates/teamComponents.templ | 30 +-
Backend/templates/teamComponents_templ.go | 163 ++-
Backend/templates/timeComponents.templ | 23 +-
Backend/templates/timeComponents_templ.go | 479 +++----
DB/initdb/01_schema.sql | 9 +-
DB/initdb/02_sample_data.sql | 2 +-
db.sql | 70 ++
package-lock.json | 1395 +++++++++++++++++++++
package.json | 8 +-
19 files changed, 2138 insertions(+), 387 deletions(-)
create mode 100644 package-lock.json
diff --git a/Backend/endpoints/team.go b/Backend/endpoints/team.go
index 54bed44..33c5569 100644
--- a/Backend/endpoints/team.go
+++ b/Backend/endpoints/team.go
@@ -43,7 +43,7 @@ func submitReport(w http.ResponseWriter, r *http.Request) {
switch r.FormValue("method") {
case "send":
- err = workWeek.Send()
+ err = workWeek.SendWeek()
case "accept":
err = workWeek.Accept()
default:
@@ -63,7 +63,7 @@ func showWeeks(w http.ResponseWriter, r *http.Request) {
return
}
submissionDate := r.URL.Query().Get("submission_date")
- lastSub := user.GetLastSubmission()
+ lastSub := user.GetLastWorkWeekSubmission()
if submissionDate != "" {
submissionDate, err := time.Parse("2006-01-02", submissionDate)
if err == nil {
diff --git a/Backend/endpoints/time.go b/Backend/endpoints/time.go
index 70fd422..c5edf3f 100644
--- a/Backend/endpoints/time.go
+++ b/Backend/endpoints/time.go
@@ -71,6 +71,20 @@ func getBookings(w http.ResponseWriter, r *http.Request) {
return workDays[i].Day.After(workDays[j].Day)
})
+ lastSub := user.GetLastWorkWeekSubmission()
+ var aggregatedOvertime time.Duration
+ for _, days := range workDays {
+ if days.Day.Before(lastSub) {
+ continue
+ }
+ aggregatedOvertime += days.CalcOvertime(user)
+ }
+ if reportedOvertime, err := user.GetReportedOvertime(); err == nil {
+ user.Overtime = (reportedOvertime + aggregatedOvertime).Round(time.Minute)
+ } else {
+ log.Println("Cannot calculate overtime: ", err)
+ }
+
if r.Header.Get("Accept") == "application/json" {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
@@ -78,8 +92,12 @@ func getBookings(w http.ResponseWriter, r *http.Request) {
return
}
+ if err != nil {
+ log.Println("Error calc overtime: ", err)
+ }
+
ctx := context.WithValue(r.Context(), "user", user)
- templates.TimePage(workDays).Render(ctx, w)
+ templates.TimePage(workDays, lastSub).Render(ctx, w)
}
func updateBooking(w http.ResponseWriter, r *http.Request) {
diff --git a/Backend/models/absence.go b/Backend/models/absence.go
index 48a604b..c5184d0 100644
--- a/Backend/models/absence.go
+++ b/Backend/models/absence.go
@@ -68,7 +68,7 @@ func GetAbsenceById(counterId int) (Absence, error) {
return absence, nil
}
-func GetAbsenceByCardUID(card_uid string, tsFrom time.Time, tsTo time.Time) ([]Absence, error) {
+func GetAbsencesByCardUID(card_uid string, tsFrom time.Time, tsTo time.Time) ([]Absence, error) {
var absences []Absence
qStr, err := DB.Prepare("SELECT counter_id, abwesenheit_typ, datum FROM abwesenheit WHERE card_uid = $1 AND datum BETWEEN $2::DATE AND $3::DATE ORDER BY datum;")
if err != nil {
diff --git a/Backend/models/user.go b/Backend/models/user.go
index b542c01..56169d4 100644
--- a/Backend/models/user.go
+++ b/Backend/models/user.go
@@ -19,6 +19,7 @@ type User struct {
PersonalNummer int `json:"personal_nummer"`
ArbeitszeitPerTag float32 `json:"arbeitszeit_per_tag"`
ArbeitszeitPerWoche float32 `json:"arbeitszeit_per_woche"`
+ Overtime time.Duration
}
func (u *User) GetUserFromSession(Session *scs.SessionManager, ctx context.Context) (User, error) {
@@ -40,6 +41,25 @@ func (u *User) GetUserFromSession(Session *scs.SessionManager, ctx context.Conte
return user, nil
}
+// Returns the actual overtime for this moment
+func (u *User) GetReportedOvertime() (time.Duration, error) {
+ var overtime time.Duration
+ var overtimeReport float64
+
+ qStr, err := DB.Prepare("SELECT COALESCE(SUM(ueberstunden), 0) AS total_ueberstunden FROM wochen_report WHERE personal_nummer = $1;")
+ if err != nil {
+ return 0, err
+ }
+ defer qStr.Close()
+ err = qStr.QueryRow(u.PersonalNummer).Scan(&overtimeReport)
+ if err != nil {
+ return 0, err
+ }
+ overtime = time.Duration(overtimeReport * float64(time.Hour)).Round(time.Minute)
+ log.Println("Overtime from wochen_report: ", overtime)
+ return overtime, nil
+}
+
func (u *User) GetAll() ([]User, error) {
qStr, err := DB.Prepare((`SELECT card_uid, vorname, nachname FROM s_personal_daten;`))
var users []User
@@ -147,7 +167,7 @@ func (u *User) ChangePass(password, newPassword string) (bool, error) {
func (u *User) GetTeamMembers() ([]User, error) {
var teamMembers []User
- qStr, err := DB.Prepare(`SELECT personal_nummer, card_uid, vorname, nachname, arbeitszeit_per_tag FROM s_personal_daten WHERE vorgesetzter_pers_nr = $1`)
+ qStr, err := DB.Prepare(`SELECT personal_nummer FROM s_personal_daten WHERE vorgesetzter_pers_nr = $1`)
if err != nil {
return teamMembers, err
}
@@ -159,9 +179,11 @@ func (u *User) GetTeamMembers() ([]User, error) {
}
defer rows.Close()
for rows.Next() {
- user, err := parseUser(rows)
+ var personalNr int
+ err := rows.Scan(&personalNr)
+ user, err := GetUserByPersonalNr(personalNr)
if err != nil {
- log.Println("Error parsing user!")
+ log.Println("Error getting user!")
return teamMembers, err
}
teamMembers = append(teamMembers, user)
@@ -206,8 +228,8 @@ func parseUser(rows *sql.Rows) (User, error) {
return user, nil
}
-// returns the start of the week, the last submission was made, submission == first booking or last send booking_report to team leader
-func (u *User) GetLastSubmission() time.Time {
+// returns the start of the week, the last submission was made, submission == first booking or last send wochen_report to team leader
+func (u *User) GetLastWorkWeekSubmission() time.Time {
var lastSub time.Time
qStr, err := DB.Prepare(`
SELECT COALESCE(
diff --git a/Backend/models/workDay.go b/Backend/models/workDay.go
index 33797f6..734e935 100644
--- a/Backend/models/workDay.go
+++ b/Backend/models/workDay.go
@@ -81,7 +81,7 @@ func (d *WorkDay) GetWorkDays(card_uid string, tsFrom, tsTo time.Time) []WorkDay
LEFT JOIN ordered_bookings b ON d.work_date = b.work_date
LEFT JOIN abwesenheiten a ON d.work_date = a.work_date
GROUP BY d.work_date, a.abwesenheit_typ
- ORDER BY d.work_date;`)
+ ORDER BY d.work_date ASC;`)
if err != nil {
log.Println("Error preparing SQL statement", err)
@@ -126,10 +126,12 @@ func (d *WorkDay) GetWorkDays(card_uid string, tsFrom, tsTo time.Time) []WorkDay
} else {
workDay.calcPauseTime()
}
- if emptyDays || len(workDay.Bookings) > 0 || (workDay.Absence != Absence{}) {
+ if emptyDays && workDay.Day.Weekday() >= 1 && workDay.Day.Weekday() <= 5 {
workDays = append(workDays, workDay)
- } else {
- log.Println("no booking on day", workDay.Day.Format("02.01.2006"))
+ } else if len(workDay.Bookings) > 0 || (workDay.Absence != Absence{}) {
+ workDays = append(workDays, workDay)
+ // } else {
+ // log.Println("no booking on day", workDay.Day.Format("02.01.2006"))
}
}
if err = rows.Err(); err != nil {
@@ -202,8 +204,8 @@ func (d *WorkDay) GetWorkDayProgress(user User) uint8 {
func (d *WorkDay) CalcOvertime(user User) time.Duration {
var overtime time.Duration
- // weekday is WE
overtime = d.workTime - time.Duration(user.ArbeitszeitPerTag*float32(time.Hour)).Round(time.Minute)
+ // weekday is WE
if (d.Day.Weekday() == 6 || d.Day.Weekday() == 0) && len(d.Bookings) == 0 {
overtime = 0
}
diff --git a/Backend/models/workWeek.go b/Backend/models/workWeek.go
index 03ebae3..c093c58 100644
--- a/Backend/models/workWeek.go
+++ b/Backend/models/workWeek.go
@@ -11,13 +11,16 @@ import (
// Workweeks are
type WorkWeek struct {
- Id int
- WorkDays []WorkDay
- Absences []Absence
- User User
- WeekStart time.Time
- WorkHours time.Duration
- Status WeekStatus
+ Id int
+ WorkDays []WorkDay
+ Absences []Absence
+ User User
+ WeekStart time.Time
+ Worktime time.Duration
+ Overtime time.Duration
+ Status WeekStatus
+ overtimeDiff time.Duration
+ worktimeDiff time.Duration
}
type WeekStatus int8
@@ -26,6 +29,7 @@ const (
WeekStatusNone WeekStatus = iota
WeekStatusSent
WeekStatusAccepted
+ WeekStatusDifferences
)
func NewWorkWeek(user User, tsMonday time.Time, populate bool) WorkWeek {
@@ -35,17 +39,32 @@ func NewWorkWeek(user User, tsMonday time.Time, populate bool) WorkWeek {
Status: WeekStatusNone,
}
if populate {
- week.WorkDays = (*WorkDay).GetWorkDays(nil, user.CardUID, tsMonday, tsMonday.Add(7*24*time.Hour))
- if absences, err := GetAbsenceByCardUID(user.CardUID, tsMonday, tsMonday.Add(7*24*time.Hour)); err == nil {
- week.Absences = absences
- } else {
- log.Printf("Error populating absences in workWeek (%s): %v", tsMonday, err)
- }
- week.WorkHours = week.aggregateWorkTime()
+ week.PopulateWithBookings(0, 0)
}
return week
}
+func (w *WorkWeek) PopulateWithBookings(overtime time.Duration, worktime time.Duration) {
+ w.WorkDays = (*WorkDay).GetWorkDays(nil, w.User.CardUID, w.WeekStart, w.WeekStart.Add(7*24*time.Hour))
+ if absences, err := GetAbsencesByCardUID(w.User.CardUID, w.WeekStart, w.WeekStart.Add(7*24*time.Hour)); err == nil {
+ w.Absences = absences
+ } else {
+ log.Printf("Error populating absences in workWeek (%s): %v", w.WeekStart, err)
+ }
+ w.Worktime = w.aggregateWorkTime()
+ w.Overtime = w.Worktime - time.Duration(w.User.ArbeitszeitPerWoche*float32(time.Hour)).Round(time.Minute)
+
+ if overtime == 0 && worktime == 0 {
+ return
+ }
+
+ if overtime != w.Overtime || worktime != w.Worktime {
+ w.Status = WeekStatusDifferences
+ w.overtimeDiff = overtime
+ w.worktimeDiff = worktime
+ }
+}
+
func (w *WorkWeek) CheckStatus() WeekStatus {
if w.Status != WeekStatusNone {
return w.Status
@@ -78,7 +97,7 @@ func (w *WorkWeek) CheckStatus() WeekStatus {
}
func (w *WorkWeek) GetWorkHourString() string {
- return helper.FormatDuration(w.WorkHours)
+ return helper.FormatDuration(w.Worktime)
}
func (w *WorkWeek) aggregateWorkTime() time.Duration {
@@ -95,7 +114,7 @@ func (w *WorkWeek) aggregateWorkTime() time.Duration {
func (w *WorkWeek) GetSendWeeks(user User) []WorkWeek {
var weeks []WorkWeek
- qStr, err := DB.Prepare(`SELECT id, woche_start::DATE FROM wochen_report WHERE bestaetigt = FALSE AND personal_nummer = $1;`)
+ qStr, err := DB.Prepare(`SELECT id, woche_start::DATE, arbeitszeit, ueberstunden FROM wochen_report WHERE bestaetigt = FALSE AND personal_nummer = $1;`)
if err != nil {
log.Println("Error preparing SQL statement", err)
return weeks
@@ -109,14 +128,16 @@ func (w *WorkWeek) GetSendWeeks(user User) []WorkWeek {
}
defer rows.Close()
for rows.Next() {
- var week WorkWeek
- week.User = user
- if err := rows.Scan(&week.Id, &week.WeekStart); err != nil {
+ var week WorkWeek = WorkWeek{User: user}
+ var workHours, overtime sql.NullFloat64
+ if err := rows.Scan(&week.Id, &week.WeekStart, &workHours, &overtime); err != nil {
log.Println("Error scanning row!", err)
return weeks
}
- week.WorkDays = (*WorkDay).GetWorkDays(nil, user.CardUID, week.WeekStart, week.WeekStart.Add(7*24*time.Hour))
- week.WorkHours = week.aggregateWorkTime()
+
+ if workHours.Valid && overtime.Valid {
+ week.PopulateWithBookings(time.Duration(workHours.Float64*float64(time.Hour)).Round(time.Minute), time.Duration(overtime.Float64*float64(time.Hour)).Round(time.Minute))
+ }
weeks = append(weeks, week)
}
if err = rows.Err(); err != nil {
@@ -128,13 +149,8 @@ func (w *WorkWeek) GetSendWeeks(user User) []WorkWeek {
var ErrRunningWeek = errors.New("Week is in running week")
-func (w *WorkWeek) GetOvertime() time.Duration {
- var weekOvertime time.Duration = w.WorkHours - time.Duration(w.User.ArbeitszeitPerWoche*float32(time.Hour)).Round(time.Minute)
- return weekOvertime
-}
-
// creates a new entry in the woche_report table with the given workweek
-func (w *WorkWeek) Send() error {
+func (w *WorkWeek) SendWeek() error {
var qStr *sql.Stmt
var err error
@@ -144,19 +160,19 @@ func (w *WorkWeek) Send() error {
}
if w.CheckStatus() != WeekStatusNone {
- qStr, err = DB.Prepare(`UPDATE "wochen_report" SET bestaetigt = FALSE, ueberstunden = $3 WHERE personal_nummer = $1 AND woche_start = $2;`)
+ qStr, err = DB.Prepare(`UPDATE "wochen_report" SET bestaetigt = FALSE, arbeitszeit = $3, ueberstunden = $4 WHERE personal_nummer = $1 AND woche_start = $2;`)
if err != nil {
log.Println("Error preparing SQL statement", err)
return err
}
} else {
- qStr, err = DB.Prepare(`INSERT INTO wochen_report (personal_nummer, woche_start, ueberstunden) VALUES ($1, $2, $3);`)
+ qStr, err = DB.Prepare(`INSERT INTO wochen_report (personal_nummer, woche_start, arbeitszeit, ueberstunden) VALUES ($1, $2, $3, $4);`)
if err != nil {
log.Println("Error preparing SQL statement", err)
return err
}
}
- _, err = qStr.Exec(w.User.PersonalNummer, w.WeekStart, w.GetOvertime().Hours())
+ _, err = qStr.Exec(w.User.PersonalNummer, w.WeekStart, w.Worktime.Hours(), w.Overtime.Hours())
if err != nil {
log.Println("Error executing query!", err)
return err
diff --git a/Backend/src/main.css b/Backend/src/main.css
index 354f27f..f2b68f0 100644
--- a/Backend/src/main.css
+++ b/Backend/src/main.css
@@ -1,5 +1,8 @@
@import "tailwindcss";
@source "../templates/*.templ";
+@plugin "@iconify/tailwind4" {
+ scale: 1.5;
+}
@theme {
--color-accent-50: #e7fdea;
@@ -74,7 +77,7 @@
.btn:hover {
color: var(--color-white);
- background-color: var(--color-neutral-700) !important;
+ background-color: var(--color-neutral-700);
}
.btn:disabled {
diff --git a/Backend/static/css/styles.css b/Backend/static/css/styles.css
index 3dbc3ba..2f2f5e3 100644
--- a/Backend/static/css/styles.css
+++ b/Backend/static/css/styles.css
@@ -26,6 +26,8 @@
--text-sm--line-height: calc(1.25 / 0.875);
--text-xl: 1.25rem;
--text-xl--line-height: calc(1.75 / 1.25);
+ --text-2xl: 1.5rem;
+ --text-2xl--line-height: calc(2 / 1.5);
--font-weight-bold: 700;
--radius-md: 0.375rem;
--default-transition-duration: 150ms;
@@ -184,12 +186,18 @@
}
}
@layer utilities {
+ .\@container {
+ container-type: inline-size;
+ }
.col-span-2 {
grid-column: span 2 / span 2;
}
.col-span-3 {
grid-column: span 3 / span 3;
}
+ .col-span-full {
+ grid-column: 1 / -1;
+ }
.mx-auto {
margin-inline: auto;
}
@@ -202,6 +210,71 @@
.mb-2 {
margin-bottom: calc(var(--spacing) * 2);
}
+ .icon-\[material-symbols-light--add-circle-outline\] {
+ display: inline-block;
+ width: 1.5em;
+ height: 1.5em;
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M11.5 16.5h1v-4h4v-1h-4v-4h-1v4h-4v1h4zm.503 4.5q-1.867 0-3.51-.708q-1.643-.709-2.859-1.924t-1.925-2.856T3 12.003t.709-3.51Q4.417 6.85 5.63 5.634t2.857-1.925T11.997 3t3.51.709q1.643.708 2.859 1.922t1.925 2.857t.709 3.509t-.708 3.51t-1.924 2.859t-2.856 1.925t-3.509.709M12 20q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m0-8'/%3E%3C/svg%3E");
+ }
+ .icon-\[material-symbols-light--check-circle-outline\] {
+ display: inline-block;
+ width: 1.5em;
+ height: 1.5em;
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='m10.562 15.908l6.396-6.396l-.708-.708l-5.688 5.688l-2.85-2.85l-.708.708zM12.003 21q-1.866 0-3.51-.708q-1.643-.709-2.859-1.924t-1.925-2.856T3 12.003t.709-3.51Q4.417 6.85 5.63 5.634t2.857-1.925T11.997 3t3.51.709q1.643.708 2.859 1.922t1.925 2.857t.709 3.509t-.708 3.51t-1.924 2.859t-2.856 1.925t-3.509.709M12 20q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m0-8'/%3E%3C/svg%3E");
+ }
+ .icon-\[material-symbols-light--circle-outline\] {
+ display: inline-block;
+ width: 1.5em;
+ height: 1.5em;
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M12.003 21q-1.866 0-3.51-.708q-1.643-.709-2.859-1.924t-1.925-2.856T3 12.003t.709-3.51Q4.417 6.85 5.63 5.634t2.857-1.925T11.997 3t3.51.709q1.643.708 2.859 1.922t1.925 2.857t.709 3.509t-.708 3.51t-1.924 2.859t-2.856 1.925t-3.509.709M12 20q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m0-8'/%3E%3C/svg%3E");
+ }
+ .icon-\[material-symbols-light--more-time\] {
+ display: inline-block;
+ width: 1.5em;
+ height: 1.5em;
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M11.003 20q-1.666 0-3.123-.622t-2.545-1.71t-1.712-2.544T3 12.003t.622-3.123t1.711-2.546q1.09-1.089 2.545-1.711T11 4q.525 0 1.013.063T13 4.25V5.3q-.5-.15-.987-.225T11 5Q8.089 5 6.044 7.044T4 12t2.044 4.956T11 19t4.956-2.044T18 11.996q0-.271-.025-.554t-.094-.557h1.011q.05.236.08.538q.028.302.028.577q0 1.667-.622 3.122t-1.71 2.545q-1.089 1.088-2.544 1.71q-1.455.623-3.121.623m3.143-4.146L10.5 12.208V7h1v4.792l3.354 3.354zM18 8.884v-3h-3v-1h3v-3h1v3h3v1h-3v3z'/%3E%3C/svg%3E");
+ }
+ .icon-\[material-symbols-light--motion-photos-paused-outline\] {
+ display: inline-block;
+ width: 1.5em;
+ height: 1.5em;
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M9.808 14.616h1V9.385h-1zm3.384 0h1V9.385h-1zM12.003 21q-1.866 0-3.51-.705q-1.643-.706-2.859-1.915t-1.925-2.843T3 12.039q0-.905.167-1.778t.497-1.713l.78.78q-.219.65-.331 1.32T4 12q0 3.35 2.325 5.675T12 20t5.675-2.325T20 12t-2.325-5.675T12 4q-.675 0-1.332.112t-1.3.332l-.776-.775q.789-.315 1.606-.492T11.885 3q1.887 0 3.546.701t2.894 1.926t1.955 2.866t.72 3.505t-.708 3.509t-1.924 2.859t-2.856 1.925t-3.509.709M5.923 6.808q-.356 0-.62-.265q-.264-.264-.264-.62t.264-.62t.62-.264t.62.264t.265.62t-.265.62t-.62.265M12 12'/%3E%3C/svg%3E");
+ }
.flex {
display: flex;
}
@@ -255,6 +328,9 @@
.w-full {
width: 100%;
}
+ .flex-shrink-0 {
+ flex-shrink: 0;
+ }
.flex-grow {
flex-grow: 1;
}
@@ -279,6 +355,9 @@
.flex-row {
flex-direction: row;
}
+ .content-baseline {
+ align-content: baseline;
+ }
.content-end {
align-content: flex-end;
}
@@ -381,6 +460,10 @@
.text-center {
text-align: center;
}
+ .text-2xl {
+ font-size: var(--text-2xl);
+ line-height: var(--tw-leading, var(--text-2xl--line-height));
+ }
.text-sm {
font-size: var(--text-sm);
line-height: var(--tw-leading, var(--text-sm--line-height));
@@ -501,6 +584,13 @@
}
}
}
+ .hover\:bg-red-600 {
+ &:hover {
+ @media (hover: hover) {
+ background-color: var(--color-red-600);
+ }
+ }
+ }
.hover\:text-accent {
&:hover {
@media (hover: hover) {
@@ -566,12 +656,28 @@
flex-direction: column;
}
}
+ .max-md\:divide-y-1 {
+ @media (width < 48rem) {
+ :where(& > :not(:last-child)) {
+ --tw-divide-y-reverse: 0;
+ border-bottom-style: var(--tw-border-style);
+ border-top-style: var(--tw-border-style);
+ border-top-width: calc(1px * var(--tw-divide-y-reverse));
+ border-bottom-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
+ }
+ }
+ }
.max-md\:border-b-1 {
@media (width < 48rem) {
border-bottom-style: var(--tw-border-style);
border-bottom-width: 1px;
}
}
+ .max-md\:bg-neutral-300 {
+ @media (width < 48rem) {
+ background-color: var(--color-neutral-300);
+ }
+ }
.md\:col-span-1 {
@media (width >= 48rem) {
grid-column: span 1 / span 1;
@@ -649,6 +755,16 @@
}
}
}
+ .\@7xl\:grid {
+ @container (width >= 80rem) {
+ display: grid;
+ }
+ }
+ .\@7xl\:grid-cols-5 {
+ @container (width >= 80rem) {
+ grid-template-columns: repeat(5, minmax(0, 1fr));
+ }
+ }
.print\:hidden {
@media print {
display: none;
@@ -696,7 +812,7 @@
}
.btn:hover {
color: var(--color-white);
- background-color: var(--color-neutral-700) !important;
+ background-color: var(--color-neutral-700);
}
.btn:disabled {
opacity: 50%;
diff --git a/Backend/templates/pages.templ b/Backend/templates/pages.templ
index 90a0c40..7915162 100644
--- a/Backend/templates/pages.templ
+++ b/Backend/templates/pages.templ
@@ -19,13 +19,13 @@ templ Base() {
}
-templ TimePage(workDays []models.WorkDay) {
+templ TimePage(workDays []models.WorkDay, lastSub time.Time) {
@Base()
@headerComponent()
@inputForm()
for _, day := range workDays {
- @dayComponent(day)
+ @dayComponent(day, day.Day.Before(lastSub))
}
@LegendComponent()
@@ -83,14 +83,9 @@ templ UserPage(status int) {
templ statusCheckMark(status models.WeekStatus, target models.WeekStatus) {
if status >= target {
-
+
} else {
-
+
}
}
@@ -98,12 +93,15 @@ templ TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) {
@Base()
@headerComponent()
{{
- progress := (float32(userWeek.WorkHours.Hours()) / userWeek.User.ArbeitszeitPerWoche) * 100
+ progress := (float32(userWeek.Worktime.Hours()) / userWeek.User.ArbeitszeitPerWoche) * 100
log.Println(userWeek.CheckStatus())
}}
-
-
+
+
+
Eigene Abrechnung
+
+
@weekPicker(userWeek.WeekStart)
@@ -122,13 +120,13 @@ templ TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) {
@timeGaugeComponent(uint8(progress), false, false)
-
Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(userWeek.WorkHours)) }
-
Überstunden: { fmt.Sprintf("%s", helper.FormatDuration(userWeek.GetOvertime())) }
+
Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(userWeek.Worktime)) }
+
Überstunden: { fmt.Sprintf("%s", helper.FormatDuration(userWeek.Overtime)) }
-
+
for _, day := range userWeek.WorkDays {
@weekDayComponent(userWeek.User, day)
}
@@ -154,6 +152,11 @@ templ TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) {
+ if len(weeks) > 0 {
+
+
Abrechnung Mitarbeiter
+
+ }
for _, week := range weeks {
@employeComponent(week)
}
diff --git a/Backend/templates/pages_templ.go b/Backend/templates/pages_templ.go
index 0628d10..346d818 100644
--- a/Backend/templates/pages_templ.go
+++ b/Backend/templates/pages_templ.go
@@ -46,7 +46,7 @@ func Base() templ.Component {
})
}
-func TimePage(workDays []models.WorkDay) templ.Component {
+func TimePage(workDays []models.WorkDay, lastSub time.Time) 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 {
@@ -84,7 +84,7 @@ func TimePage(workDays []models.WorkDay) templ.Component {
return templ_7745c5c3_Err
}
for _, day := range workDays {
- templ_7745c5c3_Err = dayComponent(day).Render(ctx, templ_7745c5c3_Buffer)
+ templ_7745c5c3_Err = dayComponent(day, day.Day.Before(lastSub)).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -224,12 +224,12 @@ func statusCheckMark(status models.WeekStatus, target models.WeekStatus) templ.C
}
ctx = templ.ClearChildren(ctx)
if status >= target {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -268,9 +268,9 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
return templ_7745c5c3_Err
}
- progress := (float32(userWeek.WorkHours.Hours()) / userWeek.User.ArbeitszeitPerWoche) * 100
+ progress := (float32(userWeek.Worktime.Hours()) / userWeek.User.ArbeitszeitPerWoche) * 100
log.Println(userWeek.CheckStatus())
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
Eigene Abrechnung
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -285,7 +285,7 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s %s", userWeek.User.Vorname, userWeek.User.Name))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 110, Col: 101}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 108, Col: 101}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
@@ -320,9 +320,9 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
- templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(userWeek.WorkHours)))
+ templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(userWeek.Worktime)))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 125, Col: 85}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 123, Col: 84}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
@@ -333,15 +333,15 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
- templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(userWeek.GetOvertime())))
+ templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(userWeek.Overtime)))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 126, Col: 90}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 124, Col: 85}
}
_, 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, 21, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -366,7 +366,7 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(userWeek.User.PersonalNummer))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 142, Col: 88}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 140, Col: 88}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
@@ -379,7 +379,7 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(userWeek.WeekStart.Format(time.DateOnly))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 143, Col: 86}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 141, Col: 86}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
@@ -430,13 +430,19 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
+ if len(weeks) > 0 {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
Abrechnung Mitarbeiter
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
for _, week := range weeks {
templ_7745c5c3_Err = employeComponent(week).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -473,7 +479,7 @@ func TeamPresencePage(teamPresence map[bool][]models.User) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
Anwesend
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "
Anwesend
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -483,7 +489,7 @@ func TeamPresencePage(teamPresence map[bool][]models.User) templ.Component {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "
Nicht Anwesend
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "
Nicht Anwesend
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -493,7 +499,7 @@ func TeamPresencePage(teamPresence map[bool][]models.User) templ.Component {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -522,7 +528,7 @@ func LogoutButton() templ.Component {
templ_7745c5c3_Var13 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "
Abmelden")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
Abmelden")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
diff --git a/Backend/templates/teamComponents.templ b/Backend/templates/teamComponents.templ
index 1addb91..a43a3f6 100644
--- a/Backend/templates/teamComponents.templ
+++ b/Backend/templates/teamComponents.templ
@@ -1,8 +1,10 @@
package templates
import (
+ "arbeitszeitmessung/helper"
"arbeitszeitmessung/models"
"fmt"
+ "log"
"strconv"
"time"
)
@@ -62,14 +64,21 @@ templ weekDayComponent(user models.User, day models.WorkDay) {
templ employeComponent(week models.WorkWeek) {
{{
year, kw := week.WeekStart.ISOWeek()
+ progress := (float32(week.Worktime.Hours()) / week.User.ArbeitszeitPerWoche) * 100
+ log.Println(progress)
}}
-
-
+
+
{ week.User.Vorname } { week.User.Name }
-
Arbeitszeit
-
{ week.GetWorkHourString() }
+
+ @timeGaugeComponent(uint8(progress), false, false)
+
+
Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(week.Worktime)) }
+
Überstunden: { fmt.Sprintf("%s", helper.FormatDuration(week.Overtime)) }
+
+
-
+
for _, day := range week.WorkDays {
@weekDayComponent(week.User, day)
}
@@ -79,9 +88,14 @@ templ employeComponent(week models.WorkWeek) {
-
- Bestätigen
-
+
+ if week.Status == models.WeekStatusDifferences {
+
Unterschiedliche Arbeitszeit zwischen Abrechnung und individuellen Buchungen
+ }
+
Bestätigen
+ // TODO maybe delete function
+ //
Antrag löschen
+
}
diff --git a/Backend/templates/teamComponents_templ.go b/Backend/templates/teamComponents_templ.go
index d5d2ad9..abe699c 100644
--- a/Backend/templates/teamComponents_templ.go
+++ b/Backend/templates/teamComponents_templ.go
@@ -9,8 +9,10 @@ import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
+ "arbeitszeitmessung/helper"
"arbeitszeitmessung/models"
"fmt"
+ "log"
"strconv"
"time"
)
@@ -45,7 +47,7 @@ func weekPicker(weekStart time.Time) templ.Component {
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(weekStart.Format(time.DateOnly))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 15, Col: 98}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 17, Col: 98}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
@@ -75,7 +77,7 @@ func weekPicker(weekStart time.Time) templ.Component {
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d, %d", kw, year))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 21, Col: 69}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 23, Col: 69}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
@@ -159,7 +161,7 @@ func weekDayComponent(user models.User, day models.WorkDay) templ.Component {
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(day.Day.Format("Mon"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 38, Col: 89}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 40, Col: 89}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
@@ -172,7 +174,7 @@ func weekDayComponent(user models.User, day models.WorkDay) templ.Component {
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(day.Day.Format("02.01.2006"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 38, Col: 130}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 40, Col: 130}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
@@ -185,7 +187,7 @@ func weekDayComponent(user models.User, day models.WorkDay) templ.Component {
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(work)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 40, Col: 36}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 42, Col: 36}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
@@ -198,7 +200,7 @@ func weekDayComponent(user models.User, day models.WorkDay) templ.Component {
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(pause)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 41, Col: 42}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 43, Col: 42}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
@@ -216,7 +218,7 @@ func weekDayComponent(user models.User, day models.WorkDay) templ.Component {
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(day.Absence.AbwesenheitTyp.Name)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 49, Col: 41}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 51, Col: 41}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
@@ -234,7 +236,7 @@ func weekDayComponent(user models.User, day models.WorkDay) templ.Component {
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(day.TimeFrom.Format("15:04"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 51, Col: 41}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 53, Col: 41}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
@@ -247,7 +249,7 @@ func weekDayComponent(user models.User, day models.WorkDay) templ.Component {
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(day.TimeTo.Format("15:04"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 53, Col: 39}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 55, Col: 39}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
@@ -294,14 +296,16 @@ func employeComponent(week models.WorkWeek) templ.Component {
ctx = templ.ClearChildren(ctx)
year, kw := week.WeekStart.ISOWeek()
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
")
+ progress := (float32(week.Worktime.Hours()) / week.User.ArbeitszeitPerWoche) * 100
+ log.Println(progress)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Vorname)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 68, Col: 53}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 72, Col: 53}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
@@ -314,26 +318,47 @@ func employeComponent(week models.WorkWeek) templ.Component {
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Name)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 68, Col: 72}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 72, Col: 72}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
Arbeitszeit
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = timeGaugeComponent(uint8(progress), false, false).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
Arbeitszeit: ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
- templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(week.GetWorkHourString())
+ templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(week.Worktime)))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 70, Col: 52}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 76, Col: 78}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "
Überstunden: ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var18 string
+ templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(week.Overtime)))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 77, Col: 79}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -343,46 +368,66 @@ func employeComponent(week models.WorkWeek) templ.Component {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "
Woche: ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var18 string
- templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d-%d", kw, year))
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 78, Col: 85}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "
Woche: ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var19 string
- templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(week.User.PersonalNummer))
+ templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d-%d", kw, year))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 80, Col: 82}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 87, Col: 85}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "\"> Bestätigen
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "\">
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ if week.Status == models.WeekStatusDifferences {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
Unterschiedliche Arbeitszeit zwischen Abrechnung und individuellen Buchungen
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
Bestätigen")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -406,53 +451,53 @@ func userPresenceComponent(user models.User, present bool) 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, 32, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if present {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
Anwesend
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
Anwesend
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
Abwesend
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "
Abwesend
")
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
- }
- var templ_7745c5c3_Var22 string
- templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 96, Col: 19}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var23 string
- templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name)
+ templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 96, Col: 33}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 110, Col: 19}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "
")
+ 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(user.Name)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 110, Col: 33}
+ }
+ _, 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, 43, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
diff --git a/Backend/templates/timeComponents.templ b/Backend/templates/timeComponents.templ
index 7648f97..3b89eae 100644
--- a/Backend/templates/timeComponents.templ
+++ b/Backend/templates/timeComponents.templ
@@ -19,7 +19,7 @@ templ inputForm() {
{ user.Vorname + " " + user.Name }
Überstunden
-
0h 0min (statisch)
+
{ user.Overtime }
@@ -30,14 +30,14 @@ templ inputForm() {
}
-templ dayComponent(workDay models.WorkDay) {
+templ dayComponent(workDay models.WorkDay, submitted bool) {
{{
work, pause := workDay.GetWorkTimeString()
user := ctx.Value("user").(models.User)
@@ -47,7 +47,7 @@ templ dayComponent(workDay models.WorkDay) {
justify = "justify-content: center"
}
}}
-
+
@timeGaugeComponent(workDay.GetWorkDayProgress(ctx.Value("user").(models.User)), workDay.Day.Equal(time.Now().Truncate(24*time.Hour)), workDay.RequiresAction())
@@ -59,8 +59,10 @@ templ dayComponent(workDay models.WorkDay) {
} else {
{ work }
}
-
{ pause }
-
{ overtime }
+
{ pause }
+ if overtime != "" {
+
{ overtime }
+ }
}
@@ -127,7 +129,7 @@ templ timeGaugeComponent(progress uint8, today bool, warning bool) {
} else {
-
+
}
}
@@ -156,12 +158,7 @@ templ absenceComponent(d models.WorkDay) {
templ newBookingComponent(d models.WorkDay) {
-
-
-
+
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "Überstunden
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var3 string
+ templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(user.Overtime)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 22, Col: 42}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
+ 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
}
@@ -62,33 +75,33 @@ func inputForm() templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\" name=\"time_from\" class=\"w-full bg-neutral-100 placeholder:text-neutral-400 text-neutral-700 text-sm border border-neutral-0 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none focus:border-neutral-400 hover:border-neutral-300\" placeholder=\"Zeitraum von...\">
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -96,7 +109,7 @@ func inputForm() templ.Component {
})
}
-func dayComponent(workDay models.WorkDay) templ.Component {
+func dayComponent(workDay models.WorkDay, submitted bool) 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 {
@@ -112,9 +125,9 @@ func dayComponent(workDay models.WorkDay) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var5 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var5 == nil {
- templ_7745c5c3_Var5 = templ.NopComponent
+ templ_7745c5c3_Var6 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var6 == nil {
+ templ_7745c5c3_Var6 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
@@ -125,7 +138,25 @@ func dayComponent(workDay models.WorkDay) templ.Component {
if len(workDay.Bookings) <= 1 {
justify = "justify-content: center"
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
")
+ var templ_7745c5c3_Var7 = []any{"grid-sub divide-x-1 hover:bg-neutral-200 transition-colors", templ.KV("bg-neutral-100", submitted)}
+ templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -133,97 +164,103 @@ func dayComponent(workDay models.WorkDay) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var6 string
- templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Day.Format("Mon"))
+ var templ_7745c5c3_Var9 string
+ templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Day.Format("Mon"))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 54, Col: 94}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
+ _, 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, 8, ": ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, ": ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var7 string
- templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Day.Format("02.01.2006"))
+ var templ_7745c5c3_Var10 string
+ templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Day.Format("02.01.2006"))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 54, Col: 139}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if work != "" {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
Arbeitszeit:
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
Arbeitszeit:
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if workDay.RequiresAction() {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
Bitte anpassen
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
Bitte anpassen
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var8 string
- templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(work)
+ var templ_7745c5c3_Var11 string
+ templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(work)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 60, Col: 36}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
- 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
}
- var templ_7745c5c3_Var9 string
- templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(pause)
+ var templ_7745c5c3_Var12 string
+ templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(pause)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 62, Col: 40}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 62, Col: 148}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- 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
}
- var templ_7745c5c3_Var10 string
- templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(overtime)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 63, Col: 43}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
+ if overtime != "" {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var13 string
+ templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(overtime)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 64, Col: 133}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -231,57 +268,57 @@ func dayComponent(workDay models.WorkDay) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "\" method=\"post\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if (workDay.Absence != models.Absence{}) {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var13 string
- templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Absence.AbwesenheitTyp.Name)
+ var templ_7745c5c3_Var16 string
+ templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Absence.AbwesenheitTyp.Name)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 71, Col: 45}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 73, Col: 45}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if len(workDay.Bookings) < 1 && (workDay.Absence == models.Absence{}) {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -289,7 +326,7 @@ func dayComponent(workDay models.WorkDay) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -308,7 +345,7 @@ func dayComponent(workDay models.WorkDay) templ.Component {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -317,7 +354,7 @@ func dayComponent(workDay models.WorkDay) templ.Component {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -325,7 +362,7 @@ func dayComponent(workDay models.WorkDay) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -349,25 +386,25 @@ func changeButtonComponent(id string) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var14 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var14 == nil {
- templ_7745c5c3_Var14 = templ.NopComponent
+ templ_7745c5c3_Var17 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var17 == nil {
+ templ_7745c5c3_Var17 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, templ.JSFuncCall("editDay", templ.JSExpression("this"), templ.JSExpression("event"), id))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "
Ändern
Absenden
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "\">
Ändern
Absenden
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -391,9 +428,9 @@ func timeGaugeComponent(progress uint8, today bool, warning bool) templ.Componen
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var16 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var16 == nil {
- templ_7745c5c3_Var16 = templ.NopComponent
+ templ_7745c5c3_Var19 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var19 == nil {
+ templ_7745c5c3_Var19 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
@@ -416,47 +453,11 @@ func timeGaugeComponent(progress uint8, today bool, warning bool) templ.Componen
break
}
if today {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var17 = []any{"flex w-full items-center justify-center overflow-hidden rounded-full", bgColor}
- templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...)
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- } else {
- var templ_7745c5c3_Var20 = []any{"w-2 h-full bg-accent rounded-md", bgColor}
+ var templ_7745c5c3_Var20 = []any{"flex w-full items-center justify-center overflow-hidden rounded-full", bgColor}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
@@ -474,7 +475,43 @@ func timeGaugeComponent(progress uint8, today bool, warning bool) templ.Componen
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "\">
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "\" style=\"")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var22 string
+ templ_7745c5c3_Var22, templ_7745c5c3_Err = templruntime.SanitizeStyleAttributeValues(fmt.Sprintf("height: %d%%", int(progress)))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 129, Col: 149}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
+ 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
+ }
+ } else {
+ var templ_7745c5c3_Var23 = []any{"w-2 h-full bg-accent rounded-md flex-shrink-0", bgColor}
+ templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var23...)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -499,12 +536,12 @@ func lineComponent() templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var22 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var22 == nil {
- templ_7745c5c3_Var22 = 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, 36, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -528,12 +565,12 @@ func absenceComponent(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_Var26 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var26 == nil {
+ templ_7745c5c3_Var26 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -541,52 +578,52 @@ func absenceComponent(d models.WorkDay) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -610,58 +647,58 @@ func newBookingComponent(d models.WorkDay) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var27 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var27 == nil {
- templ_7745c5c3_Var27 = templ.NopComponent
+ templ_7745c5c3_Var30 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var30 == nil {
+ templ_7745c5c3_Var30 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, ">Gehen")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -685,64 +722,64 @@ func bookingComponent(booking models.Booking) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var30 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var30 == nil {
- templ_7745c5c3_Var30 = templ.NopComponent
+ templ_7745c5c3_Var33 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var33 == nil {
+ templ_7745c5c3_Var33 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var31 string
- templ_7745c5c3_Var31, 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: 178, Col: 97}
- }
- _, 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, 52, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var34 string
- templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(booking.GetBookingType())
+ templ_7745c5c3_Var34, 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: 180, Col: 29}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 175, Col: 97}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var37 string
+ templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(booking.GetBookingType())
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 177, Col: 29}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -766,12 +803,12 @@ func LegendComponent() templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var35 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var35 == nil {
- templ_7745c5c3_Var35 = templ.NopComponent
+ templ_7745c5c3_Var38 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var38 == nil {
+ templ_7745c5c3_Var38 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "
Arbeitszeit unter regulär ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "
Arbeitszeit unter regulär ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
diff --git a/DB/initdb/01_schema.sql b/DB/initdb/01_schema.sql
index c1f4174..14b71ad 100644
--- a/DB/initdb/01_schema.sql
+++ b/DB/initdb/01_schema.sql
@@ -41,6 +41,7 @@ CREATE TABLE "s_personal_daten" (
"card_uid" varchar(255),
"hauptbeschaeftigungs_ort" int2,
"arbeitszeit_per_tag" float4,
+ "arbeitszeit_per_woche" float4,
"arbeitszeit_min_start" time(6),
"arbeitszeit_max_ende" time(6),
"vorgesetzter_pers_nr" int4
@@ -80,7 +81,8 @@ CREATE TABLE "wochen_report" (
"personal_nummer" int4,
"woche_start" date,
"bestaetigt" bool DEFAULT FALSE,
- "ueberstunden" smallint,
+ "arbeitszeit" float4,
+ "ueberstunden" float4,
UNIQUE ("personal_nummer", "woche_start")
);
@@ -92,10 +94,11 @@ CREATE TABLE "abwesenheit" (
"datum" timestamptz(6) DEFAULT NOW()::DATE
);
-DROP TABLE IF EXISTS "s_abwesenheit_typen";
+ DROP TABLE IF EXISTS "s_abwesenheit_typen";
CREATE TABLE "s_abwesenheit_typen" (
"abwesenheit_id" int2 PRIMARY KEY,
- "abwesenheit_name" varchar(255)
+ "abwesenheit_name" varchar(255),
+ "arbeitszeit_equivalent" float4
);
-- Adds crypto extension
diff --git a/DB/initdb/02_sample_data.sql b/DB/initdb/02_sample_data.sql
index 44c2cb6..5cf0910 100644
--- 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") VALUES (1, 'Urlaub'), (2, 'Krank'), (3, 'Kurzarbeit');
+INSERT INTO "s_abwesenheit_typen" ("abwesenheit_id", "abwesenheit_name", "arbeitszeit_equivalent") VALUES (1, 'Urlaub', 10), (2, 'Krank', 10), (3, 'Kurzarbeit', 2);
diff --git a/db.sql b/db.sql
index 8f125b8..6f4d7fc 100644
--- a/db.sql
+++ b/db.sql
@@ -194,3 +194,73 @@ SELECT
FROM days d
WHERE random() < 0.2 -- ~20% random absences
ORDER BY d.work_date;
+
+
+WITH params AS (
+ SELECT
+ 'acde-edca'::varchar AS card_uid,
+ 101::int AS geraet_id,
+ 14::int AS start_days_ago, -- how many days back to start
+ 0::int AS end_days_ahead, -- how many days forward (0 = today)
+ 0.5::float AS pause_probability,
+ 0.2::float AS absence_probability
+),
+days AS (
+ SELECT gs::date AS work_date, p.card_uid, p.geraet_id, p.pause_probability, p.absence_probability
+ FROM params p,
+ generate_series(
+ date_trunc('week', CURRENT_DATE) - (p.start_days_ago || ' days')::interval,
+ CURRENT_DATE + (p.end_days_ahead || ' days')::interval,
+ interval '1 day'
+ ) gs
+ WHERE EXTRACT(ISODOW FROM gs) <= 5 -- only Mon–Fri
+),
+base_bookings AS (
+ -- come
+ SELECT
+ d.work_date, d.card_uid, 1 AS check_in_out, d.geraet_id,
+ (d.work_date + make_time(8, floor(random()*40)::int, 0))::timestamptz AS ts
+ FROM days d
+ UNION ALL
+ -- go
+ SELECT
+ d.work_date, d.card_uid, 2 AS check_in_out, d.geraet_id,
+ (d.work_date + make_time(16, floor(random()*40)::int, 0))::timestamptz AS ts
+ FROM days d
+),
+pause_bookings AS (
+ -- pause come
+ SELECT
+ d.work_date, d.card_uid, 3 AS check_in_out, d.geraet_id,
+ (d.work_date + make_time(11, floor(random()*30)::int, 0))::timestamptz AS ts
+ FROM days d
+ WHERE random() < d.pause_probability
+ UNION ALL
+ -- pause go
+ SELECT
+ d.work_date, d.card_uid, 4 AS check_in_out, d.geraet_id,
+ (d.work_date + make_time(12, floor(random()*30)::int, 0))::timestamptz AS ts
+ FROM days d
+ WHERE random() < d.pause_probability
+),
+all_bookings AS (
+ SELECT * FROM base_bookings
+ UNION ALL
+ SELECT * FROM pause_bookings
+),
+ins_anw AS (
+ INSERT INTO anwesenheit ("timestamp", card_uid, check_in_out, geraet_id)
+ SELECT ts, card_uid, check_in_out, geraet_id
+ FROM all_bookings
+ WHERE ts <= NOW()
+ ORDER BY work_date, ts
+ RETURNING 1
+)
+INSERT INTO abwesenheit (card_uid, abwesenheit_typ, datum)
+SELECT
+ d.card_uid,
+ (ARRAY[1, 2])[floor(random()*2 + 1)], -- example types
+ d.work_date::timestamptz
+FROM days d
+WHERE random() < d.absence_probability
+ORDER BY d.work_date;
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..7e4924a
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1395 @@
+{
+ "name": "arbeitszeitmessung",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "dependencies": {
+ "@tailwindcss/cli": "^4.1.12",
+ "tailwindcss": "^4.1.12"
+ },
+ "devDependencies": {
+ "@iconify-json/material-symbols-light": "^1.2.33",
+ "@iconify/tailwind4": "^1.0.6"
+ }
+ },
+ "node_modules/@antfu/install-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz",
+ "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "package-manager-detector": "^1.3.0",
+ "tinyexec": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@antfu/utils": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz",
+ "integrity": "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@iconify-json/material-symbols-light": {
+ "version": "1.2.33",
+ "resolved": "https://registry.npmjs.org/@iconify-json/material-symbols-light/-/material-symbols-light-1.2.33.tgz",
+ "integrity": "sha512-OZNss65ipsMDkcX1a92MV7Bx6idC2UhztlnfdRUSSyfTnljfv4hn3H3SqwqgGbayvF2tDym79sq7lFAaQaCBEQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@iconify/types": "*"
+ }
+ },
+ "node_modules/@iconify/tailwind4": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@iconify/tailwind4/-/tailwind4-1.0.6.tgz",
+ "integrity": "sha512-43ZXe+bC7CuE2LCgROdqbQeFYJi/J7L/k1UpSy8KDQlWVsWxPzLSWbWhlJx4uRYLOh1NRyw02YlDOgzBOFNd+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@iconify/types": "^2.0.0",
+ "@iconify/utils": "^2.2.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/cyberalien"
+ },
+ "peerDependencies": {
+ "tailwindcss": ">= 4"
+ }
+ },
+ "node_modules/@iconify/types": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
+ "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@iconify/utils": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.3.0.tgz",
+ "integrity": "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@antfu/install-pkg": "^1.0.0",
+ "@antfu/utils": "^8.1.0",
+ "@iconify/types": "^2.0.0",
+ "debug": "^4.4.0",
+ "globals": "^15.14.0",
+ "kolorist": "^1.8.0",
+ "local-pkg": "^1.0.0",
+ "mlly": "^1.7.4"
+ }
+ },
+ "node_modules/@isaacs/fs-minipass": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
+ "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.4"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.30",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz",
+ "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@parcel/watcher": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
+ "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "detect-libc": "^1.0.3",
+ "is-glob": "^4.0.3",
+ "micromatch": "^4.0.5",
+ "node-addon-api": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher-android-arm64": "2.5.1",
+ "@parcel/watcher-darwin-arm64": "2.5.1",
+ "@parcel/watcher-darwin-x64": "2.5.1",
+ "@parcel/watcher-freebsd-x64": "2.5.1",
+ "@parcel/watcher-linux-arm-glibc": "2.5.1",
+ "@parcel/watcher-linux-arm-musl": "2.5.1",
+ "@parcel/watcher-linux-arm64-glibc": "2.5.1",
+ "@parcel/watcher-linux-arm64-musl": "2.5.1",
+ "@parcel/watcher-linux-x64-glibc": "2.5.1",
+ "@parcel/watcher-linux-x64-musl": "2.5.1",
+ "@parcel/watcher-win32-arm64": "2.5.1",
+ "@parcel/watcher-win32-ia32": "2.5.1",
+ "@parcel/watcher-win32-x64": "2.5.1"
+ }
+ },
+ "node_modules/@parcel/watcher-android-arm64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
+ "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-arm64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
+ "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-x64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
+ "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-freebsd-x64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
+ "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-glibc": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
+ "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-musl": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
+ "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-glibc": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
+ "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-musl": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
+ "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-glibc": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
+ "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-musl": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
+ "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-arm64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
+ "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-ia32": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
+ "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-x64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
+ "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@tailwindcss/cli": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.12.tgz",
+ "integrity": "sha512-2PyJ5MGh/6JPS+cEaAq6MGDx3UemkX/mJt+/phm7/VOpycpecwNnHuFZbbgx6TNK/aIjvFOhhTVlappM7tmqvQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@parcel/watcher": "^2.5.1",
+ "@tailwindcss/node": "4.1.12",
+ "@tailwindcss/oxide": "4.1.12",
+ "enhanced-resolve": "^5.18.3",
+ "mri": "^1.2.0",
+ "picocolors": "^1.1.1",
+ "tailwindcss": "4.1.12"
+ },
+ "bin": {
+ "tailwindcss": "dist/index.mjs"
+ }
+ },
+ "node_modules/@tailwindcss/node": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.12.tgz",
+ "integrity": "sha512-3hm9brwvQkZFe++SBt+oLjo4OLDtkvlE8q2WalaD/7QWaeM7KEJbAiY/LJZUaCs7Xa8aUu4xy3uoyX4q54UVdQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/remapping": "^2.3.4",
+ "enhanced-resolve": "^5.18.3",
+ "jiti": "^2.5.1",
+ "lightningcss": "1.30.1",
+ "magic-string": "^0.30.17",
+ "source-map-js": "^1.2.1",
+ "tailwindcss": "4.1.12"
+ }
+ },
+ "node_modules/@tailwindcss/oxide": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.12.tgz",
+ "integrity": "sha512-gM5EoKHW/ukmlEtphNwaGx45fGoEmP10v51t9unv55voWh6WrOL19hfuIdo2FjxIaZzw776/BUQg7Pck++cIVw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "detect-libc": "^2.0.4",
+ "tar": "^7.4.3"
+ },
+ "engines": {
+ "node": ">= 10"
+ },
+ "optionalDependencies": {
+ "@tailwindcss/oxide-android-arm64": "4.1.12",
+ "@tailwindcss/oxide-darwin-arm64": "4.1.12",
+ "@tailwindcss/oxide-darwin-x64": "4.1.12",
+ "@tailwindcss/oxide-freebsd-x64": "4.1.12",
+ "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.12",
+ "@tailwindcss/oxide-linux-arm64-gnu": "4.1.12",
+ "@tailwindcss/oxide-linux-arm64-musl": "4.1.12",
+ "@tailwindcss/oxide-linux-x64-gnu": "4.1.12",
+ "@tailwindcss/oxide-linux-x64-musl": "4.1.12",
+ "@tailwindcss/oxide-wasm32-wasi": "4.1.12",
+ "@tailwindcss/oxide-win32-arm64-msvc": "4.1.12",
+ "@tailwindcss/oxide-win32-x64-msvc": "4.1.12"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-android-arm64": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.12.tgz",
+ "integrity": "sha512-oNY5pq+1gc4T6QVTsZKwZaGpBb2N1H1fsc1GD4o7yinFySqIuRZ2E4NvGasWc6PhYJwGK2+5YT1f9Tp80zUQZQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-arm64": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.12.tgz",
+ "integrity": "sha512-cq1qmq2HEtDV9HvZlTtrj671mCdGB93bVY6J29mwCyaMYCP/JaUBXxrQQQm7Qn33AXXASPUb2HFZlWiiHWFytw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-x64": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.12.tgz",
+ "integrity": "sha512-6UCsIeFUcBfpangqlXay9Ffty9XhFH1QuUFn0WV83W8lGdX8cD5/+2ONLluALJD5+yJ7k8mVtwy3zMZmzEfbLg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-freebsd-x64": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.12.tgz",
+ "integrity": "sha512-JOH/f7j6+nYXIrHobRYCtoArJdMJh5zy5lr0FV0Qu47MID/vqJAY3r/OElPzx1C/wdT1uS7cPq+xdYYelny1ww==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.12.tgz",
+ "integrity": "sha512-v4Ghvi9AU1SYgGr3/j38PD8PEe6bRfTnNSUE3YCMIRrrNigCFtHZ2TCm8142X8fcSqHBZBceDx+JlFJEfNg5zQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.12.tgz",
+ "integrity": "sha512-YP5s1LmetL9UsvVAKusHSyPlzSRqYyRB0f+Kl/xcYQSPLEw/BvGfxzbH+ihUciePDjiXwHh+p+qbSP3SlJw+6g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.12.tgz",
+ "integrity": "sha512-V8pAM3s8gsrXcCv6kCHSuwyb/gPsd863iT+v1PGXC4fSL/OJqsKhfK//v8P+w9ThKIoqNbEnsZqNy+WDnwQqCA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.12.tgz",
+ "integrity": "sha512-xYfqYLjvm2UQ3TZggTGrwxjYaLB62b1Wiysw/YE3Yqbh86sOMoTn0feF98PonP7LtjsWOWcXEbGqDL7zv0uW8Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-musl": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.12.tgz",
+ "integrity": "sha512-ha0pHPamN+fWZY7GCzz5rKunlv9L5R8kdh+YNvP5awe3LtuXb5nRi/H27GeL2U+TdhDOptU7T6Is7mdwh5Ar3A==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.12.tgz",
+ "integrity": "sha512-4tSyu3dW+ktzdEpuk6g49KdEangu3eCYoqPhWNsZgUhyegEda3M9rG0/j1GV/JjVVsj+lG7jWAyrTlLzd/WEBg==",
+ "bundleDependencies": [
+ "@napi-rs/wasm-runtime",
+ "@emnapi/core",
+ "@emnapi/runtime",
+ "@tybys/wasm-util",
+ "@emnapi/wasi-threads",
+ "tslib"
+ ],
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "^1.4.5",
+ "@emnapi/runtime": "^1.4.5",
+ "@emnapi/wasi-threads": "^1.0.4",
+ "@napi-rs/wasm-runtime": "^0.2.12",
+ "@tybys/wasm-util": "^0.10.0",
+ "tslib": "^2.8.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.12.tgz",
+ "integrity": "sha512-iGLyD/cVP724+FGtMWslhcFyg4xyYyM+5F4hGvKA7eifPkXHRAUDFaimu53fpNg9X8dfP75pXx/zFt/jlNF+lg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.12.tgz",
+ "integrity": "sha512-NKIh5rzw6CpEodv/++r0hGLlfgT/gFN+5WNdZtvh6wpU2BpGNgdjvj6H2oFc8nCM839QM1YOhjpgbAONUb4IxA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide/node_modules/detect-libc": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
+ "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chownr": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
+ "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/confbox": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz",
+ "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
+ "license": "Apache-2.0",
+ "bin": {
+ "detect-libc": "bin/detect-libc.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.18.3",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
+ "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==",
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/exsolve": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz",
+ "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/globals": {
+ "version": "15.15.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz",
+ "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "license": "ISC"
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/jiti": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz",
+ "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==",
+ "license": "MIT",
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
+ "node_modules/kolorist": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz",
+ "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lightningcss": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz",
+ "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==",
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-darwin-arm64": "1.30.1",
+ "lightningcss-darwin-x64": "1.30.1",
+ "lightningcss-freebsd-x64": "1.30.1",
+ "lightningcss-linux-arm-gnueabihf": "1.30.1",
+ "lightningcss-linux-arm64-gnu": "1.30.1",
+ "lightningcss-linux-arm64-musl": "1.30.1",
+ "lightningcss-linux-x64-gnu": "1.30.1",
+ "lightningcss-linux-x64-musl": "1.30.1",
+ "lightningcss-win32-arm64-msvc": "1.30.1",
+ "lightningcss-win32-x64-msvc": "1.30.1"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz",
+ "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz",
+ "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz",
+ "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz",
+ "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz",
+ "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz",
+ "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz",
+ "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz",
+ "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz",
+ "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz",
+ "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss/node_modules/detect-libc": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
+ "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/local-pkg": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz",
+ "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mlly": "^1.7.4",
+ "pkg-types": "^2.3.0",
+ "quansync": "^0.2.11"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.18",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz",
+ "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/minizlib": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz",
+ "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==",
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
+ "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
+ "license": "MIT",
+ "bin": {
+ "mkdirp": "dist/cjs/src/bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/mlly": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz",
+ "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "pathe": "^2.0.3",
+ "pkg-types": "^1.3.1",
+ "ufo": "^1.6.1"
+ }
+ },
+ "node_modules/mlly/node_modules/confbox": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
+ "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mlly/node_modules/pkg-types": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
+ "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "confbox": "^0.1.8",
+ "mlly": "^1.7.4",
+ "pathe": "^2.0.1"
+ }
+ },
+ "node_modules/mri": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
+ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-addon-api": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
+ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
+ "license": "MIT"
+ },
+ "node_modules/package-manager-detector": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.3.0.tgz",
+ "integrity": "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pkg-types": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz",
+ "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "confbox": "^0.2.2",
+ "exsolve": "^1.0.7",
+ "pathe": "^2.0.3"
+ }
+ },
+ "node_modules/quansync": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
+ "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/antfu"
+ },
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/tailwindcss": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.12.tgz",
+ "integrity": "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==",
+ "license": "MIT"
+ },
+ "node_modules/tapable": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz",
+ "integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/tar": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
+ "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
+ "license": "ISC",
+ "dependencies": {
+ "@isaacs/fs-minipass": "^4.0.0",
+ "chownr": "^3.0.0",
+ "minipass": "^7.1.2",
+ "minizlib": "^3.0.1",
+ "mkdirp": "^3.0.1",
+ "yallist": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tinyexec": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz",
+ "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ufo": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz",
+ "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/yallist": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
+ "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=18"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index dc47876..fd0ca1d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,10 @@
{
"dependencies": {
- "tailwindcss": "^4.1.12",
- "@tailwindcss/cli": "^4.1.12"
+ "@tailwindcss/cli": "^4.1.12",
+ "tailwindcss": "^4.1.12"
+ },
+ "devDependencies": {
+ "@iconify-json/material-symbols-light": "^1.2.33",
+ "@iconify/tailwind4": "^1.0.6"
}
}
From 15e28e1b1800b3387a9b4f9182d2695b68bfc728 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=20Tr=C3=B6ger?=
Date: Thu, 4 Sep 2025 00:48:30 +0200
Subject: [PATCH 50/52] added database migrations
---
migrations/20250901201159_initial.down.sql | 4 +--
.../20250901201250_control_tables.down.sql | 29 ++++---------------
.../20250901201250_control_tables.up.sql | 27 ++++-------------
...20250901201710_triggers_extension.down.sql | 10 +++++++
... 20250901201710_triggers_extension.up.sql} | 0
migrations/20250903221313_overtime.down.sql | 6 ++++
migrations/20250903221313_overtime.up.sql | 6 ++++
migrations/atlas.sum | 15 ++++++----
8 files changed, 44 insertions(+), 53 deletions(-)
create mode 100644 migrations/20250901201710_triggers_extension.down.sql
rename migrations/{20250901201710_triggers_extension.sql => 20250901201710_triggers_extension.up.sql} (100%)
create mode 100644 migrations/20250903221313_overtime.down.sql
create mode 100644 migrations/20250903221313_overtime.up.sql
diff --git a/migrations/20250901201159_initial.down.sql b/migrations/20250901201159_initial.down.sql
index 1f8630e..4051a1f 100644
--- a/migrations/20250901201159_initial.down.sql
+++ b/migrations/20250901201159_initial.down.sql
@@ -1,7 +1,7 @@
--- reverse: create "wochen_report" table
-DROP TABLE "wochen_report";
-- reverse: create "user_password" table
DROP TABLE "user_password";
+-- reverse: create "wochen_report" table
+DROP TABLE "wochen_report";
-- reverse: set comment to column: "geschlecht" on table: "personal_daten"
COMMENT ON COLUMN "personal_daten"."geschlecht" IS NULL;
-- reverse: create "personal_daten" table
diff --git a/migrations/20250901201250_control_tables.down.sql b/migrations/20250901201250_control_tables.down.sql
index b59cc2d..24ae700 100644
--- a/migrations/20250901201250_control_tables.down.sql
+++ b/migrations/20250901201250_control_tables.down.sql
@@ -1,26 +1,6 @@
--- reverse: drop "personal_daten" table
-CREATE TABLE "personal_daten" (
- "personal_nummer" integer NOT NULL,
- "aktiv_beschaeftigt" boolean NULL,
- "vorname" character varying(255) NULL,
- "nachname" character varying(255) NULL,
- "geburtsdatum" date NULL,
- "plz" character varying(255) NULL,
- "adresse" character varying(255) NULL,
- "geschlecht" smallint NULL,
- "card_uid" character varying(255) NULL,
- "hauptbeschaeftigungs_ort" smallint NULL,
- "arbeitszeit_per_tag" real NULL,
- "arbeitszeit_min_start" time NULL,
- "arbeitszeit_max_ende" time NULL,
- "vorgesetzter_pers_nr" integer NULL,
- PRIMARY KEY ("personal_nummer")
-);
-COMMENT ON COLUMN "personal_daten"."geschlecht" IS '1==weiblich, 2==maennlich, 3==divers';
--- reverse: set comment to column: "geschlecht" on table: "s_personal_daten"
-COMMENT ON COLUMN "s_personal_daten"."geschlecht" IS NULL;
--- reverse: create "s_personal_daten" table
-DROP TABLE "s_personal_daten";
+-- reverse: remame "personal_daten" table
+ALTER TABLE "s_personal_daten" RENAME TO "personal_daten";
+
-- reverse: create "s_anwesenheit_typen" table
DROP TABLE "s_anwesenheit_typen";
-- reverse: create "s_abwesenheit_typen" table
@@ -29,3 +9,6 @@ DROP TABLE "s_abwesenheit_typen";
ALTER TABLE "wochen_report" DROP COLUMN "ueberstunden";
-- reverse: modify "anwesenheit" table
ALTER TABLE "anwesenheit" DROP COLUMN "anwesenheit_typ", ALTER COLUMN "check_in_out" DROP NOT NULL, ALTER COLUMN "card_uid" DROP NOT NULL;
+
+-- reverse: rename a constraint from "personal_daten_pkey" to "s_personal_daten_pkey"
+ALTER TABLE "s_personal_daten" RENAME CONSTRAINT "s_personal_daten_pkey" TO "personal_daten_pkey";
diff --git a/migrations/20250901201250_control_tables.up.sql b/migrations/20250901201250_control_tables.up.sql
index 53fa8d8..6e3eb2e 100644
--- a/migrations/20250901201250_control_tables.up.sql
+++ b/migrations/20250901201250_control_tables.up.sql
@@ -14,25 +14,8 @@ CREATE TABLE "s_anwesenheit_typen" (
"anwesenheit_name" character varying(255) NULL,
PRIMARY KEY ("anwesenheit_id")
);
--- create "s_personal_daten" table
-CREATE TABLE "s_personal_daten" (
- "personal_nummer" integer NOT NULL,
- "aktiv_beschaeftigt" boolean NULL,
- "vorname" character varying(255) NULL,
- "nachname" character varying(255) NULL,
- "geburtsdatum" date NULL,
- "plz" character varying(255) NULL,
- "adresse" character varying(255) NULL,
- "geschlecht" smallint NULL,
- "card_uid" character varying(255) NULL,
- "hauptbeschaeftigungs_ort" smallint NULL,
- "arbeitszeit_per_tag" real NULL,
- "arbeitszeit_min_start" time NULL,
- "arbeitszeit_max_ende" time NULL,
- "vorgesetzter_pers_nr" integer NULL,
- PRIMARY KEY ("personal_nummer")
-);
--- set comment to column: "geschlecht" on table: "s_personal_daten"
-COMMENT ON COLUMN "s_personal_daten"."geschlecht" IS '1==weiblich, 2==maennlich, 3==divers';
--- drop "personal_daten" table
-DROP TABLE "personal_daten";
+-- rename "s_personal_daten" table
+ALTER TABLE "personal_daten" RENAME TO "s_personal_daten";
+
+-- rename a constraint from "personal_daten_pkey" to "s_personal_daten_pkey"
+ALTER TABLE "s_personal_daten" RENAME CONSTRAINT "personal_daten_pkey" TO "s_personal_daten_pkey";
diff --git a/migrations/20250901201710_triggers_extension.down.sql b/migrations/20250901201710_triggers_extension.down.sql
new file mode 100644
index 0000000..4260320
--- /dev/null
+++ b/migrations/20250901201710_triggers_extension.down.sql
@@ -0,0 +1,10 @@
+-- update Funktion für pass_hash
+
+DROP FUNCTION update_zuletzt_geandert;
+
+DROP TRIGGER IF EXISTS pass_hash_update ON user_password;
+
+
+-- revert: Adds crypto extension
+
+DROP EXTENSION IF EXISTS pgcrypto;
diff --git a/migrations/20250901201710_triggers_extension.sql b/migrations/20250901201710_triggers_extension.up.sql
similarity index 100%
rename from migrations/20250901201710_triggers_extension.sql
rename to migrations/20250901201710_triggers_extension.up.sql
diff --git a/migrations/20250903221313_overtime.down.sql b/migrations/20250903221313_overtime.down.sql
new file mode 100644
index 0000000..956a8d5
--- /dev/null
+++ b/migrations/20250903221313_overtime.down.sql
@@ -0,0 +1,6 @@
+-- reverse: modify "wochen_report" table
+ALTER TABLE "wochen_report" DROP COLUMN "arbeitszeit", ALTER COLUMN "ueberstunden" TYPE smallint;
+-- reverse: modify "s_personal_daten" table
+ALTER TABLE "s_personal_daten" DROP COLUMN "arbeitszeit_per_woche";
+-- reverse: modify "s_abwesenheit_typen" table
+ALTER TABLE "s_abwesenheit_typen" DROP COLUMN "arbeitszeit_equivalent";
diff --git a/migrations/20250903221313_overtime.up.sql b/migrations/20250903221313_overtime.up.sql
new file mode 100644
index 0000000..e2fb85c
--- /dev/null
+++ b/migrations/20250903221313_overtime.up.sql
@@ -0,0 +1,6 @@
+-- modify "s_abwesenheit_typen" table
+ALTER TABLE "s_abwesenheit_typen" ADD COLUMN "arbeitszeit_equivalent" real NULL;
+-- modify "s_personal_daten" table
+ALTER TABLE "s_personal_daten" ADD COLUMN "arbeitszeit_per_woche" real NULL;
+-- modify "wochen_report" table
+ALTER TABLE "wochen_report" ALTER COLUMN "ueberstunden" TYPE real, ADD COLUMN "arbeitszeit" real NULL;
diff --git a/migrations/atlas.sum b/migrations/atlas.sum
index 306e8b4..18be8b2 100644
--- a/migrations/atlas.sum
+++ b/migrations/atlas.sum
@@ -1,6 +1,9 @@
-h1:M1O+1WNf/zb6bwiQPExxUhhXL9S4TtZ4qAsuRr0/Zq4=
-20250901201159_initial.down.sql h1:BkpujZk5zDCVVoroqrZlXgVR0nvT5Sbzye6aR5e6Z5w=
-20250901201159_initial.up.sql h1:SAruU753YcQ0oFa3Ii6ylzesLulAKD1j74zDvqv3BDQ=
-20250901201250_control_tables.down.sql h1:4jA+wm0/Ag86KdkKPZfnADsAlOQl1FYIDX8pdfsSYlA=
-20250901201250_control_tables.up.sql h1:IGDQ9nT39D12buAi0SUauygXH2ZrCh/YNsZGtk9ztWc=
-20250901201710_triggers_extension.sql h1:2Oki9mr3nJBE/supbY9HIr+wp4XJT76a38JTByjnHf0=
+h1:hyA7xJMv355hJfvtzD9tKSrkAEtsQ/vVixDZDDBxoh0=
+20250901201159_initial.down.sql h1:cmF5CvNGqEfcmbRgiqaqDWERdNNRaMzarbNLJ/Y35o4=
+20250901201159_initial.up.sql h1:Yrak/+wfQ4Tu/dVR/cUZ/75DlAcv4G/OJXDqpgSw47U=
+20250901201250_control_tables.down.sql h1:f/KmhO9pOI45J8ZRjFonvD3CypB+rOoGOPN2WMFHvOw=
+20250901201250_control_tables.up.sql h1:of5E07p0N1aen9CdQNEOrO7ffbKZC6kp4oK5KPzU9+g=
+20250901201710_triggers_extension.down.sql h1:a9va3FSfHBWzODJSJO+ywNa2hiZwjG/vmvYGb3L1lnM=
+20250901201710_triggers_extension.up.sql h1:nUBPd2eDssi/TwMVF/nOJkIM5rUM0iINdg1K9pZRZN0=
+20250903221313_overtime.down.sql h1:X+jJESqcZ6ZTd2H563z6kRaXb4dn4sA02D3ck2795v8=
+20250903221313_overtime.up.sql h1:C3DSiNVpe9v0Un1DEQ0lsy5yToR8iqcggv91GSr6tRE=
From d51b0c12c58aa194697258c5b76d00a5d3d23896 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=20Tr=C3=B6ger?=
Date: Thu, 4 Sep 2025 00:55:35 +0200
Subject: [PATCH 51/52] update
---
Docker/docker-compose.dev.yml | 1 -
Makefile | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/Docker/docker-compose.dev.yml b/Docker/docker-compose.dev.yml
index 5498341..dd75faf 100644
--- a/Docker/docker-compose.dev.yml
+++ b/Docker/docker-compose.dev.yml
@@ -19,7 +19,6 @@ services:
ports:
- 8001:8080
backend:
- build: ../Backend
image: git.letsstein.de/tom/arbeitszeitmessung
restart: unless-stopped
env_file:
diff --git a/Makefile b/Makefile
index 8ad2736..994d36c 100644
--- a/Makefile
+++ b/Makefile
@@ -44,8 +44,8 @@ generateFrontend:
backend: generateFrontend login_registry
- docker buildx build --platform linux/amd64,linux/arm64 -t ${IMAGE_REGISTRY}/${PACKAGE_OWNER}/arbeitszeit-backend:latest Backend --push
- docker buildx build --platform linux/amd64,linux/arm64 -t ${IMAGE_REGISTRY}/${PACKAGE_OWNER}/arbeitszeit-backend:${GIT_COMMIT} Backend --push
+ docker buildx build --platform linux/amd64,linux/arm64 -t ${IMAGE_REGISTRY}/${PACKAGE_OWNER}/arbeitszeitmessung:latest Backend --push
+ docker buildx build --platform linux/amd64,linux/arm64 -t ${IMAGE_REGISTRY}/${PACKAGE_OWNER}/arbeitszeitmessung:${GIT_COMMIT} Backend --push
test:
$(MAKE) -C Backend test
From a2cd118644685feb90ae94335b608676a5e6904d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=20Tr=C3=B6ger?=
Date: Thu, 4 Sep 2025 00:56:20 +0200
Subject: [PATCH 52/52] addin for sonarcube
---
Backend/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Backend/Makefile b/Backend/Makefile
index 23da1d0..34598d0 100644
--- a/Backend/Makefile
+++ b/Backend/Makefile
@@ -3,4 +3,4 @@ test:
go test ./... -coverprofile=.test/coverage.out -json > .test/report.json
scan:
- sonar-scanner
+ sonar-scanner -Dsonar.token=sqa_ca8394c93a728d6cff96703955288d8902c15200