Files
warmbly/internal/models/user.go
T
Matthew Meszaros c8c4440b50 fix: confirm dialog z + theme, persist folders/tags across reload
User: "when I click on delete the confirm appears behind the form and
it looks really bad, doesn't fit in the theme; and also after I reload
the page, nothing appears after creation".

Two distinct bugs:

1) Confirm dialog stacking + styling
   FoldersModal/TagsModal render at z-[110]. ConfirmProvider rendered
   the confirm overlay at z-101 with bg-black/30 + scale animation +
   poppins styling — visually it landed BEHIND the folders modal and
   clicks went through to the backdrop instead.
   Rewrote ConfirmProvider in the brae chrome:
   - z-[200] so it stacks above page-level overlays AND nested
     dialogs.
   - Hairline-bordered card, 48px header (red alert tile + "Confirm"
     eyebrow), prose body, slate-900 footer (Cancel / red Confirm).
   - Escape closes; backdrop closes (both gated on !loading).
   - Spinner inside Confirm during the awaited action.

2) Created folders/tags disappeared after page reload
   POST /folders + /tags persisted to Postgres fine. The frontend
   optimistic-updated the cached user via setQueryData. But
   /auth/me did not return folders/tags/categories — the User payload
   omitted them entirely. On reload the cache refetched /auth/me,
   got missing fields, defaulted to [], and the items vanished from
   the UI.

   Backend fix:
   - models.User now carries Folders/Tags/Categories ([]Group),
     always serialized as arrays.
   - GroupRepository + GroupService gained a List(ctx, userID)
     method; ordered by position then created_at.
   - /auth/me handler now calls List on FolderService, TagService,
     CategoryService and attaches them to the user before responding.

Verified end-to-end:
  GET /auth/me → 200 with full folders/tags arrays populated.
  Create a folder, reload the page → folder still in the list.
2026-05-23 09:38:20 +00:00

34 lines
899 B
Go

package models
import (
"time"
"github.com/google/uuid"
)
type User struct {
ID uuid.UUID `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Email string `json:"email"`
Roles []uuid.UUID `json:"roles"`
ReferralSource *string `json:"referral_source"`
OnboardingCompletedAt *time.Time `json:"onboarding_completed_at"`
MaxOrganizations int `json:"max_organizations"`
FreeTrialUsed bool `json:"free_trial_used"`
// Per-user label groups. Always serialized as arrays (never null)
// so the frontend can iterate without optional-chaining every
// access. Populated by the /auth/me handler after the base user
// load.
Folders []Group `json:"folders"`
Tags []Group `json:"tags"`
Categories []Group `json:"categories"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}