Implement time off management (Issue #3) #12
@@ -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) {
|
func (s *Store) GetByID(ctx context.Context, id int64) (*Request, error) {
|
||||||
req := &Request{}
|
req := &Request{}
|
||||||
var startsAt, endsAt, createdAt, updatedAt string
|
|
||||||
var reason sql.NullString
|
var reason sql.NullString
|
||||||
var reviewedBy sql.NullInt64
|
var reviewedBy sql.NullInt64
|
||||||
var reviewedAt sql.NullString
|
var reviewedAt sql.NullTime
|
||||||
|
|
||||||
err := s.db.QueryRowContext(ctx,
|
err := s.db.QueryRowContext(ctx,
|
||||||
`SELECT id, volunteer_id, starts_at, ends_at, reason, status, reviewed_by, reviewed_at, created_at, updated_at
|
`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,
|
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) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
return nil, ErrNotFound
|
return nil, ErrNotFound
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("get time off request: %w", err)
|
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 {
|
if reason.Valid {
|
||||||
req.Reason = reason.String
|
req.Reason = reason.String
|
||||||
}
|
}
|
||||||
@@ -106,8 +101,7 @@ func (s *Store) GetByID(ctx context.Context, id int64) (*Request, error) {
|
|||||||
req.ReviewedBy = &reviewedBy.Int64
|
req.ReviewedBy = &reviewedBy.Int64
|
||||||
}
|
}
|
||||||
if reviewedAt.Valid {
|
if reviewedAt.Valid {
|
||||||
t, _ := time.Parse("2006-01-02 15:04:05", reviewedAt.String)
|
req.ReviewedAt = &reviewedAt.Time
|
||||||
req.ReviewedAt = &t
|
|
||||||
}
|
}
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
@@ -130,17 +124,12 @@ func (s *Store) List(ctx context.Context, volunteerID int64) ([]Request, error)
|
|||||||
var requests []Request
|
var requests []Request
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var req Request
|
var req Request
|
||||||
var startsAt, endsAt, createdAt, updatedAt string
|
|
||||||
var reason sql.NullString
|
var reason sql.NullString
|
||||||
var reviewedBy sql.NullInt64
|
var reviewedBy sql.NullInt64
|
||||||
var reviewedAt sql.NullString
|
var reviewedAt sql.NullTime
|
||||||
if err := rows.Scan(&req.ID, &req.VolunteerID, &startsAt, &endsAt, &reason, &req.Status, &reviewedBy, &reviewedAt, &createdAt, &updatedAt); err != nil {
|
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
|
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 {
|
if reason.Valid {
|
||||||
req.Reason = reason.String
|
req.Reason = reason.String
|
||||||
}
|
}
|
||||||
@@ -148,8 +137,7 @@ func (s *Store) List(ctx context.Context, volunteerID int64) ([]Request, error)
|
|||||||
req.ReviewedBy = &reviewedBy.Int64
|
req.ReviewedBy = &reviewedBy.Int64
|
||||||
}
|
}
|
||||||
if reviewedAt.Valid {
|
if reviewedAt.Valid {
|
||||||
t, _ := time.Parse("2006-01-02 15:04:05", reviewedAt.String)
|
req.ReviewedAt = &reviewedAt.Time
|
||||||
req.ReviewedAt = &t
|
|
||||||
}
|
}
|
||||||
requests = append(requests, req)
|
requests = append(requests, req)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ export default function TimeOff() {
|
|||||||
onChange={e => setForm(f => ({ ...f, volunteer_id: Number(e.target.value) }))}
|
onChange={e => setForm(f => ({ ...f, volunteer_id: Number(e.target.value) }))}
|
||||||
>
|
>
|
||||||
<option value={0}>Myself</option>
|
<option value={0}>Myself</option>
|
||||||
{volunteers.map(v => (
|
{volunteers.filter(v => v.id !== volunteerID).map(v => (
|
||||||
<option key={v.id} value={v.id}>{v.name}</option>
|
<option key={v.id} value={v.id}>{v.name}</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
@@ -226,8 +226,8 @@ export default function TimeOff() {
|
|||||||
{requests.map(r => (
|
{requests.map(r => (
|
||||||
<tr key={r.id}>
|
<tr key={r.id}>
|
||||||
{role === 'admin' && <td>{volunteerName(r.volunteer_id)}</td>}
|
{role === 'admin' && <td>{volunteerName(r.volunteer_id)}</td>}
|
||||||
<td>{new Date(r.starts_at).toLocaleDateString()}</td>
|
<td>{new Date(r.starts_at).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })}</td>
|
||||||
<td>{new Date(r.ends_at).toLocaleDateString()}</td>
|
<td>{new Date(r.ends_at).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })}</td>
|
||||||
<td>{r.reason ?? '—'}</td>
|
<td>{r.reason ?? '—'}</td>
|
||||||
<td><span className={statusClass(r.status)}>{r.status}</span></td>
|
<td><span className={statusClass(r.status)}>{r.status}</span></td>
|
||||||
<td>
|
<td>
|
||||||
|
|||||||
Reference in New Issue
Block a user