Files
billit/internal/handler/account.go
2025-12-06 15:31:18 +05:30

109 lines
3.8 KiB
Go

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", ""))
}