From 975225e6506aa5ca457a2320ed8e48ced97069b4 Mon Sep 17 00:00:00 2001 From: James Griffin Date: Thu, 9 Apr 2026 16:07:42 -0300 Subject: [PATCH] Fix time-off date display and improve UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scan datetime columns directly into time.Time instead of strings in the timeoff store — the intermediate string parse silently failed with parseTime=true, producing zero-value dates. Display dates with month names and filter admin's own entry from the volunteer dropdown. Co-Authored-By: Claude Opus 4.6 --- internal/timeoff/timeoff.go | 24 ++++++------------------ web/src/pages/TimeOff.tsx | 6 +++--- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/internal/timeoff/timeoff.go b/internal/timeoff/timeoff.go index 64e0e52..7f184c5 100644 --- a/internal/timeoff/timeoff.go +++ b/internal/timeoff/timeoff.go @@ -80,25 +80,20 @@ func (s *Store) Create(ctx context.Context, volunteerID int64, in CreateInput) ( func (s *Store) GetByID(ctx context.Context, id int64) (*Request, error) { req := &Request{} - var startsAt, endsAt, createdAt, updatedAt string var reason sql.NullString var reviewedBy sql.NullInt64 - var reviewedAt sql.NullString + var reviewedAt sql.NullTime err := s.db.QueryRowContext(ctx, `SELECT id, volunteer_id, starts_at, ends_at, reason, status, reviewed_by, reviewed_at, created_at, updated_at FROM time_off_requests WHERE id = ?`, id, - ).Scan(&req.ID, &req.VolunteerID, &startsAt, &endsAt, &reason, &req.Status, &reviewedBy, &reviewedAt, &createdAt, &updatedAt) + ).Scan(&req.ID, &req.VolunteerID, &req.StartsAt, &req.EndsAt, &reason, &req.Status, &reviewedBy, &reviewedAt, &req.CreatedAt, &req.UpdatedAt) if errors.Is(err, sql.ErrNoRows) { return nil, ErrNotFound } if err != nil { return nil, fmt.Errorf("get time off request: %w", err) } - req.StartsAt, _ = time.Parse("2006-01-02 15:04:05", startsAt) - req.EndsAt, _ = time.Parse("2006-01-02 15:04:05", endsAt) - req.CreatedAt, _ = time.Parse("2006-01-02 15:04:05", createdAt) - req.UpdatedAt, _ = time.Parse("2006-01-02 15:04:05", updatedAt) if reason.Valid { req.Reason = reason.String } @@ -106,8 +101,7 @@ func (s *Store) GetByID(ctx context.Context, id int64) (*Request, error) { req.ReviewedBy = &reviewedBy.Int64 } if reviewedAt.Valid { - t, _ := time.Parse("2006-01-02 15:04:05", reviewedAt.String) - req.ReviewedAt = &t + req.ReviewedAt = &reviewedAt.Time } return req, nil } @@ -130,17 +124,12 @@ func (s *Store) List(ctx context.Context, volunteerID int64) ([]Request, error) var requests []Request for rows.Next() { var req Request - var startsAt, endsAt, createdAt, updatedAt string var reason sql.NullString var reviewedBy sql.NullInt64 - var reviewedAt sql.NullString - if err := rows.Scan(&req.ID, &req.VolunteerID, &startsAt, &endsAt, &reason, &req.Status, &reviewedBy, &reviewedAt, &createdAt, &updatedAt); err != nil { + var reviewedAt sql.NullTime + if err := rows.Scan(&req.ID, &req.VolunteerID, &req.StartsAt, &req.EndsAt, &reason, &req.Status, &reviewedBy, &reviewedAt, &req.CreatedAt, &req.UpdatedAt); err != nil { return nil, err } - req.StartsAt, _ = time.Parse("2006-01-02 15:04:05", startsAt) - req.EndsAt, _ = time.Parse("2006-01-02 15:04:05", endsAt) - req.CreatedAt, _ = time.Parse("2006-01-02 15:04:05", createdAt) - req.UpdatedAt, _ = time.Parse("2006-01-02 15:04:05", updatedAt) if reason.Valid { req.Reason = reason.String } @@ -148,8 +137,7 @@ func (s *Store) List(ctx context.Context, volunteerID int64) ([]Request, error) req.ReviewedBy = &reviewedBy.Int64 } if reviewedAt.Valid { - t, _ := time.Parse("2006-01-02 15:04:05", reviewedAt.String) - req.ReviewedAt = &t + req.ReviewedAt = &reviewedAt.Time } requests = append(requests, req) } diff --git a/web/src/pages/TimeOff.tsx b/web/src/pages/TimeOff.tsx index 949ac86..a62df67 100644 --- a/web/src/pages/TimeOff.tsx +++ b/web/src/pages/TimeOff.tsx @@ -157,7 +157,7 @@ export default function TimeOff() { onChange={e => setForm(f => ({ ...f, volunteer_id: Number(e.target.value) }))} > - {volunteers.map(v => ( + {volunteers.filter(v => v.id !== volunteerID).map(v => ( ))} @@ -226,8 +226,8 @@ export default function TimeOff() { {requests.map(r => ( {role === 'admin' && {volunteerName(r.volunteer_id)}} - {new Date(r.starts_at).toLocaleDateString()} - {new Date(r.ends_at).toLocaleDateString()} + {new Date(r.starts_at).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })} + {new Date(r.ends_at).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })} {r.reason ?? '—'} {r.status}