feat: set timezone space level
All checks were successful
Deploy / build-and-deploy (push) Successful in 2m25s

This commit is contained in:
juancwu 2026-03-03 14:48:11 +00:00
commit 08f6b034f5
12 changed files with 196 additions and 23 deletions

View file

@ -22,7 +22,8 @@ func newTestSettingsHandler(dbi testutil.DBInfo) (*settingsHandler, *service.Aut
emailSvc := service.NewEmailService(nil, "test@example.com", "http://localhost:9999", "Budgit Test", false)
authSvc := service.NewAuthService(emailSvc, userRepo, profileRepo, tokenRepo, spaceSvc, cfg.JWTSecret, cfg.JWTExpiry, cfg.TokenMagicLinkExpiry, false)
userSvc := service.NewUserService(userRepo)
return NewSettingsHandler(authSvc, userSvc), authSvc
profileSvc := service.NewProfileService(profileRepo)
return NewSettingsHandler(authSvc, userSvc, profileSvc), authSvc
}
func TestSettingsHandler_SettingsPage(t *testing.T) {

View file

@ -1177,6 +1177,46 @@ func (h *SpaceHandler) UpdateSpaceName(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}
func (h *SpaceHandler) UpdateSpaceTimezone(w http.ResponseWriter, r *http.Request) {
spaceID := r.PathValue("spaceID")
user := ctxkeys.User(r.Context())
space, err := h.spaceService.GetSpace(spaceID)
if err != nil {
http.Error(w, "Space not found", http.StatusNotFound)
return
}
if space.OwnerID != user.ID {
http.Error(w, "Forbidden", http.StatusForbidden)
return
}
if err := r.ParseForm(); err != nil {
ui.RenderError(w, r, "Bad Request", http.StatusUnprocessableEntity)
return
}
tz := r.FormValue("timezone")
if tz == "" {
ui.RenderError(w, r, "Timezone is required", http.StatusUnprocessableEntity)
return
}
if err := h.spaceService.UpdateSpaceTimezone(spaceID, tz); err != nil {
if err == service.ErrInvalidTimezone {
ui.RenderError(w, r, "Invalid timezone", http.StatusUnprocessableEntity)
return
}
slog.Error("failed to update space timezone", "error", err, "space_id", spaceID)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
w.Header().Set("HX-Refresh", "true")
w.WriteHeader(http.StatusOK)
}
func (h *SpaceHandler) RemoveMember(w http.ResponseWriter, r *http.Request) {
spaceID := r.PathValue("spaceID")
userID := r.PathValue("userID")

View file

@ -19,6 +19,7 @@ func newTestSpaceHandler(t *testing.T, dbi testutil.DBInfo) *SpaceHandler {
listRepo := repository.NewShoppingListRepository(dbi.DB)
itemRepo := repository.NewListItemRepository(dbi.DB)
expenseRepo := repository.NewExpenseRepository(dbi.DB)
profileRepo := repository.NewProfileRepository(dbi.DB)
inviteRepo := repository.NewInvitationRepository(dbi.DB)
accountRepo := repository.NewMoneyAccountRepository(dbi.DB)
methodRepo := repository.NewPaymentMethodRepository(dbi.DB)
@ -36,8 +37,8 @@ func newTestSpaceHandler(t *testing.T, dbi testutil.DBInfo) *SpaceHandler {
service.NewInviteService(inviteRepo, spaceRepo, userRepo, emailSvc),
service.NewMoneyAccountService(accountRepo),
service.NewPaymentMethodService(methodRepo),
service.NewRecurringExpenseService(recurringRepo, expenseRepo),
service.NewRecurringDepositService(recurringDepositRepo, accountRepo, expenseSvc),
service.NewRecurringExpenseService(recurringRepo, expenseRepo, profileRepo, spaceRepo),
service.NewRecurringDepositService(recurringDepositRepo, accountRepo, expenseSvc, profileRepo, spaceRepo),
service.NewBudgetService(budgetRepo),
service.NewReportService(expenseRepo),
)