dev/actions #26

Merged
tom_trgr merged 41 commits from dev/actions into dev/main 2025-08-29 15:36:00 +02:00
13 changed files with 127 additions and 101 deletions
Showing only changes of commit a87bef8c89 - Show all commits

View File

@@ -17,13 +17,10 @@ func TeamHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodPost:
submitReport(w, r)
break
case http.MethodGet:
showWeeks(w, r)
break
default:
http.Error(w, "Method not allowed!", http.StatusMethodNotAllowed)
break
}
}
@@ -47,10 +44,8 @@ func submitReport(w http.ResponseWriter, r *http.Request) {
switch r.FormValue("method") {
case "send":
err = workWeek.Send()
break
case "accept":
err = workWeek.Accept()
break
default:
break
}

View File

@@ -14,14 +14,11 @@ func TeamPresenceHandler(w http.ResponseWriter, r *http.Request){
switch r.Method {
case http.MethodGet:
teamPresence(w, r)
break
case http.MethodOptions:
// just support options header for non GET Requests from SWAGGER
w.WriteHeader(http.StatusOK)
break
default:
http.Error(w, "Method not allowed!", http.StatusMethodNotAllowed)
break
}
}
@@ -37,8 +34,7 @@ func teamPresence(w http.ResponseWriter, r *http.Request){
teamPresence[present] = append(teamPresence[present], user)
}
if(err != nil){
if err != nil {
log.Println("Error getting team", err)
}
templates.TeamPresencePage(teamPresence).Render(r.Context(), w)

View File

@@ -16,17 +16,13 @@ func TimeCreateHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodPut:
createBooking(w, r)
break
case http.MethodGet:
createBooking(w, r)
break
case http.MethodOptions:
// just support options header for non GET Requests from SWAGGER
w.WriteHeader(http.StatusOK)
break
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
break
}
}

View File

@@ -20,17 +20,13 @@ func TimeHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
getBookings(w, r)
break
case http.MethodPost:
updateBooking(w, r)
break
case http.MethodOptions:
// just support options header for non GET Requests from SWAGGER
w.WriteHeader(http.StatusOK)
break
default:
http.Error(w, "Method not allowed!", http.StatusMethodNotAllowed)
break
}
}
@@ -120,7 +116,6 @@ func updateBooking(w http.ResponseWriter, r *http.Request) {
if err != nil {
log.Println("Error inserting booking", err)
}
break
case "change":
absenceType, err := strconv.Atoi(r.FormValue("absence"))
if err != nil {
@@ -151,9 +146,7 @@ func updateBooking(w http.ResponseWriter, r *http.Request) {
booking.UpdateTime(parsedTime)
}
}
break
}
getBookings(w, r)
}

View File

@@ -21,20 +21,6 @@ func CreateSessionManager(lifetime time.Duration) *scs.SessionManager {
return Session
}
func LoginHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
showLoginPage(w, r, false)
break
case http.MethodPost:
loginUser(w, r)
break
default:
http.Error(w, "Method not allowed!", http.StatusMethodNotAllowed)
break
}
}
func showLoginPage(w http.ResponseWriter, r *http.Request, failed bool) {
r = r.WithContext(context.WithValue(r.Context(), "session", Session))
if helper.GetEnv("GO_ENV", "production") == "debug" {
@@ -83,5 +69,13 @@ func loginUser(w http.ResponseWriter, r *http.Request) {
return
}
showLoginPage(w, r, false)
return
}
func logoutUser(w http.ResponseWriter, r *http.Request) {
log.Println("Loggin out user!")
err := Session.Destroy(r.Context())
if err != nil {
log.Println("Error destroying session!", err)
}
http.Redirect(w, r, "/user/login", http.StatusSeeOther)
}

View File

@@ -1,36 +1,12 @@
package endpoints
import (
"arbeitszeitmessung/helper"
"arbeitszeitmessung/models"
"arbeitszeitmessung/templates"
"log"
"net/http"
)
func UserSettingsHandler(w http.ResponseWriter, r *http.Request) {
helper.RequiresLogin(Session, w, r)
switch r.Method {
case http.MethodGet:
showUserPage(w, r, 0)
break
case http.MethodPost:
switch r.FormValue("action") {
case "change-pass":
changePassword(w, r)
break
case "logout-user":
logoutUser(w, r)
break
}
break
default:
http.Error(w, "Method not allowed!", http.StatusMethodNotAllowed)
break
}
}
// change user password and store salted hash in db
func changePassword(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
@@ -61,16 +37,6 @@ func changePassword(w http.ResponseWriter, r *http.Request) {
showUserPage(w, r, http.StatusUnauthorized)
}
func logoutUser(w http.ResponseWriter, r *http.Request) {
err := Session.Destroy(r.Context())
if err != nil {
log.Println("Error destroying session!", err)
}
http.Redirect(w, r, "/user/login", http.StatusSeeOther)
}
func showUserPage(w http.ResponseWriter, r *http.Request, status int) {
templates.UserPage(status).Render(r.Context(), w)
return
}

45
Backend/endpoints/user.go Normal file
View File

@@ -0,0 +1,45 @@
package endpoints
import (
"arbeitszeitmessung/helper"
"net/http"
)
func UserHandler(w http.ResponseWriter, r *http.Request) {
switch r.PathValue("action") {
case "login":
LoginHandler(w, r)
case "settings":
UserSettingsHandler(w, r)
case "logout":
logoutUser(w, r)
}
}
func LoginHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
showLoginPage(w, r, false)
case http.MethodPost:
loginUser(w, r)
default:
http.Error(w, "Method not allowed!", http.StatusMethodNotAllowed)
}
}
func UserSettingsHandler(w http.ResponseWriter, r *http.Request) {
helper.RequiresLogin(Session, w, r)
switch r.Method {
case http.MethodGet:
showUserPage(w, r, 0)
case http.MethodPost:
switch r.FormValue("action") {
case "change-pass":
changePassword(w, r)
case "logout-user":
logoutUser(w, r)
}
default:
http.Error(w, "Method not allowed!", http.StatusMethodNotAllowed)
}
}

View File

@@ -22,7 +22,7 @@ func main() {
if err != nil {
log.Println("No .env file found in directory!")
}
if(helper.GetEnv("GO_ENV", "production") == "debug") {
if helper.GetEnv("GO_ENV", "production") == "debug" {
log.Println("Debug mode enabled")
log.Println("Environment Variables")
envs := os.Environ()
@@ -31,8 +31,6 @@ func main() {
}
}
models.DB, err = OpenDatabase()
if err != nil {
log.Fatal(err)
@@ -48,8 +46,9 @@ func main() {
server.HandleFunc("/time/new", endpoints.TimeCreateHandler)
server.Handle("/time", ParamsMiddleware(endpoints.TimeHandler))
server.HandleFunc("/logout", endpoints.LogoutHandler)
server.HandleFunc("/user/login", endpoints.LoginHandler)
server.HandleFunc("/user/settings", endpoints.UserSettingsHandler)
server.HandleFunc("/user/{action}", endpoints.UserHandler)
// server.HandleFunc("/user/login", endpoints.LoginHandler)
// server.HandleFunc("/user/settings", endpoints.UserSettingsHandler)
server.HandleFunc("/team", endpoints.TeamHandler)
server.HandleFunc("/team/presence", endpoints.TeamPresenceHandler)
server.Handle("/", http.RedirectHandler("/time", http.StatusPermanentRedirect))

View File

@@ -1,7 +1,5 @@
function editDay(element, event, formId) {
var form = element
.closest(".grid-sub")
.querySelector(".all-booking-component > form");
var form = element.closest(".grid-sub").querySelector(".all-booking-component > form");
form.classList.toggle("edit");
element.classList.toggle("edit");
if (element.classList.contains("edit")) {
@@ -15,9 +13,7 @@ function editDay(element, event, formId) {
}
function editAbwesenheit(element, event) {
var newBookingComponent = element
.closest(".grid-sub")
.querySelector(".new-booking-component");
var newBookingComponent = element.closest(".grid-sub").querySelector(".new-booking-component");
if (element.value == 0) {
newBookingComponent.style.display = "";
} else {
@@ -32,3 +28,7 @@ function navigateWeek(element, event, direction) {
date.setHours(10);
dateInput.valueAsDate = date;
}
function logoutUser() {
fetch("/user/logout", {}).then(() => window.location.reload());
}

View File

@@ -1,14 +1,13 @@
package templates
templ headerComponent() {
<div class="flex flex-row justify-between md:mx-[10%] py-2">
<div class="flex flex-row justify-between md:mx-[10%] py-2 items-center">
<a href="/time">Zeitverwaltung</a>
<a href="/team">Abrechnung</a>
if true {
<a href="/team/presence">Anwesenheit</a>
}
<a href="/user/settings">Einstellungen</a>
@LogoutButton()
</div>
}

View File

@@ -29,7 +29,7 @@ func headerComponent() templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"flex flex-row justify-between md:mx-[10%] py-2\"><a href=\"/time\">Zeitverwaltung</a> <a href=\"/team\">Abrechnung</a> ")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"flex flex-row justify-between md:mx-[10%] py-2 items-center\"><a href=\"/time\">Zeitverwaltung</a> <a href=\"/team\">Abrechnung</a> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -39,7 +39,15 @@ func headerComponent() templ.Component {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<a href=\"/user/settings\">Einstellungen</a></div>")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<a href=\"/user/settings\">Einstellungen</a>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = LogoutButton().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View File

@@ -68,15 +68,15 @@ templ UserPage(status int) {
<button name="action" value="change-pass" type="submit" class="w-full cursor-pointer rounded-md text-neutral-800 p-2 md:px-4 border text-center text-sm hover:text-white transition-colors border-neutral-300 focus:bg-neutral-700 active:bg-neutral-700 hover:bg-neutral-700 disabled:pointer-events-none disabled:opacity-50">Ändern</button>
</div>
</form>
<form method="POST" class="grid-sub divide-x-1">
<div class="grid-sub divide-x-1">
<h1 class="grid-cell font-bold uppercase text-xl text-center">Nutzer abmelden</h1>
<div class="grid-cell col-span-3">
<p>Nutzer von Weboberfläche abmelden.</p>
</div>
<div class="grid-cell">
<button name="action" value="logout-user" type="submit" class="w-full cursor-pointer rounded-md text-neutral-800 p-2 md:px-4 border text-center text-sm hover:text-white transition-colors border-neutral-300 focus:bg-neutral-700 active:bg-neutral-700 hover:bg-neutral-700 disabled:pointer-events-none disabled:opacity-50">Abmelden</button>
<button onclick="logoutUser" type="button" class="w-full cursor-pointer rounded-md text-neutral-800 p-2 md:px-4 border text-center text-sm hover:text-white transition-colors border-neutral-300 focus:bg-neutral-700 active:bg-neutral-700 hover:bg-neutral-700 disabled:pointer-events-none disabled:opacity-50">Abmelden</button>
</div>
</div>
</form>
</div>
}
@@ -88,7 +88,9 @@ templ TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) {
@headerComponent()
<div class="grid-main divide-y-1">
<div class="grid-sub divide-x-1 bg-neutral-300">
<div class="grid-cell font-bold uppercase">{ fmt.Sprintf("%s %s", userWeek.User.Vorname, userWeek.User.Name) }</div>
<div class="grid-cell font-bold uppercase">
{ fmt.Sprintf("%s %s", userWeek.User.Vorname, userWeek.User.Name) }
</div>
<div class="grid-cell col-span-3 flex flex-col gap-2">
for _, day := range userWeek.WorkDays {
@weekDayComponent(userWeek.User, day)
@@ -182,3 +184,7 @@ templ TeamPresencePage(teamPresence map[bool][]models.User) {
</div>
</div>
}
templ LogoutButton() {
<button onclick="logoutUser()" type="button" class="cursor-pointer rounded-md text-neutral-800 p-2 md:px-4 border text-center text-sm hover:text-white transition-colors border-neutral-300 focus:bg-neutral-700 active:bg-neutral-700 hover:bg-neutral-700 disabled:pointer-events-none disabled:opacity-50">Abmelden</button>
}

View File

@@ -192,7 +192,7 @@ func UserPage(status int) templ.Component {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "</div><div class=\"grid-cell\"><button name=\"action\" value=\"change-pass\" type=\"submit\" class=\"w-full cursor-pointer rounded-md text-neutral-800 p-2 md:px-4 border text-center text-sm hover:text-white transition-colors border-neutral-300 focus:bg-neutral-700 active:bg-neutral-700 hover:bg-neutral-700 disabled:pointer-events-none disabled:opacity-50\">Ändern</button></div></form><form method=\"POST\" class=\"grid-sub divide-x-1\"><h1 class=\"grid-cell font-bold uppercase text-xl text-center\">Nutzer abmelden</h1><div class=\"grid-cell col-span-3\"><p>Nutzer von Weboberfläche abmelden.</p></div><div class=\"grid-cell\"><button name=\"action\" value=\"logout-user\" type=\"submit\" class=\"w-full cursor-pointer rounded-md text-neutral-800 p-2 md:px-4 border text-center text-sm hover:text-white transition-colors border-neutral-300 focus:bg-neutral-700 active:bg-neutral-700 hover:bg-neutral-700 disabled:pointer-events-none disabled:opacity-50\">Abmelden</button></div></form></div>")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "</div><div class=\"grid-cell\"><button name=\"action\" value=\"change-pass\" type=\"submit\" class=\"w-full cursor-pointer rounded-md text-neutral-800 p-2 md:px-4 border text-center text-sm hover:text-white transition-colors border-neutral-300 focus:bg-neutral-700 active:bg-neutral-700 hover:bg-neutral-700 disabled:pointer-events-none disabled:opacity-50\">Ändern</button></div></form><div class=\"grid-sub divide-x-1\"><h1 class=\"grid-cell font-bold uppercase text-xl text-center\">Nutzer abmelden</h1><div class=\"grid-cell col-span-3\"><p>Nutzer von Weboberfläche abmelden.</p></div><div class=\"grid-cell\"><button onclick=\"logoutUser\" type=\"button\" class=\"w-full cursor-pointer rounded-md text-neutral-800 p-2 md:px-4 border text-center text-sm hover:text-white transition-colors border-neutral-300 focus:bg-neutral-700 active:bg-neutral-700 hover:bg-neutral-700 disabled:pointer-events-none disabled:opacity-50\">Abmelden</button></div></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -238,7 +238,7 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
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: 91, Col: 111}
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))
if templ_7745c5c3_Err != nil {
@@ -261,7 +261,7 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, 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: 99, Col: 110}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 101, Col: 110}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
@@ -291,7 +291,7 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, 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/pages.templ`, Line: 105, Col: 72}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 107, Col: 72}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
@@ -331,7 +331,7 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, 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: 114, Col: 88}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 116, Col: 88}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
@@ -344,7 +344,7 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, 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: 115, Col: 86}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 117, Col: 86}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
@@ -495,4 +495,33 @@ func TeamPresencePage(teamPresence map[bool][]models.User) templ.Component {
})
}
func LogoutButton() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
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_Var15 := templ.GetChildren(ctx)
if templ_7745c5c3_Var15 == nil {
templ_7745c5c3_Var15 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "<button onclick=\"logoutUser()\" type=\"button\" class=\"cursor-pointer rounded-md text-neutral-800 p-2 md:px-4 border text-center text-sm hover:text-white transition-colors border-neutral-300 focus:bg-neutral-700 active:bg-neutral-700 hover:bg-neutral-700 disabled:pointer-events-none disabled:opacity-50\">Abmelden</button>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate