package handler import ( "billit/internal/database" "billit/internal/logic" "billit/internal/view" "net/http" "github.com/labstack/echo/v4" ) // AccountHandlers holds references for account operations type AccountHandlers struct { db database.Service auth *logic.AuthService } // NewAccountHandlers creates handlers with db and auth access func NewAccountHandlers(db database.Service, authService *logic.AuthService) *AccountHandlers { return &AccountHandlers{db: db, auth: authService} } // AccountPageHandler renders the /account page func (h *AccountHandlers) AccountPageHandler(c echo.Context) error { userID := getUserID(c) if userID == "" { return c.Redirect(http.StatusFound, "/") } user, err := h.db.GetUserByID(userID) if err != nil || user == nil { return view.RenderServerError(c, "Failed to load account details.") } return view.Render(c, view.AccountPage(user.Email, user.CreatedAt, user.CompanyDetails, user.BankDetails, user.InvoicePrefix, "", "")) } // UpdateDetailsHandler handles POST /account/details func (h *AccountHandlers) UpdateDetailsHandler(c echo.Context) error { userID := getUserID(c) if userID == "" { return c.Redirect(http.StatusFound, "/") } user, err := h.db.GetUserByID(userID) if err != nil || user == nil { return view.RenderServerError(c, "Failed to load account details.") } companyDetails := c.FormValue("company_details") bankDetails := c.FormValue("bank_details") invoicePrefix := c.FormValue("invoice_prefix") if invoicePrefix == "" { invoicePrefix = "INV" // Default prefix } err = h.db.UpdateUserDetails(userID, companyDetails, bankDetails, invoicePrefix) if err != nil { return view.Render(c, view.AccountPage(user.Email, user.CreatedAt, user.CompanyDetails, user.BankDetails, user.InvoicePrefix, "", "Failed to update details")) } return view.Render(c, view.AccountPage(user.Email, user.CreatedAt, companyDetails, bankDetails, invoicePrefix, "Details updated successfully", "")) } // ChangePasswordHandler handles POST /account/password func (h *AccountHandlers) ChangePasswordHandler(c echo.Context) error { userID := getUserID(c) if userID == "" { return c.Redirect(http.StatusFound, "/") } user, err := h.db.GetUserByID(userID) if err != nil || user == nil { return view.RenderServerError(c, "Failed to load account details.") } currentPassword := c.FormValue("current_password") newPassword := c.FormValue("new_password") confirmPassword := c.FormValue("confirm_password") // Validate current password if !logic.CheckPassword(currentPassword, user.Password) { return view.Render(c, view.AccountPage(user.Email, user.CreatedAt, user.CompanyDetails, user.BankDetails, user.InvoicePrefix, "", "Current password is incorrect")) } // Validate new password if len(newPassword) < 8 { return view.Render(c, view.AccountPage(user.Email, user.CreatedAt, user.CompanyDetails, user.BankDetails, user.InvoicePrefix, "", "New password must be at least 8 characters")) } if newPassword != confirmPassword { return view.Render(c, view.AccountPage(user.Email, user.CreatedAt, user.CompanyDetails, user.BankDetails, user.InvoicePrefix, "", "New passwords do not match")) } // Hash new password hash, err := logic.HashPassword(newPassword) if err != nil { return view.Render(c, view.AccountPage(user.Email, user.CreatedAt, user.CompanyDetails, user.BankDetails, user.InvoicePrefix, "", "Failed to update password")) } // Update password in database err = h.db.UpdateUserPassword(userID, hash) if err != nil { return view.Render(c, view.AccountPage(user.Email, user.CreatedAt, user.CompanyDetails, user.BankDetails, user.InvoicePrefix, "", "Failed to update password")) } return view.Render(c, view.AccountPage(user.Email, user.CreatedAt, user.CompanyDetails, user.BankDetails, user.InvoicePrefix, "Password changed successfully", "")) }