Compare commits
3 Commits
704f11cec3
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
668397104a
|
|||
|
0446e8f8a7
|
|||
|
975225e650
|
@@ -36,7 +36,7 @@ jobs:
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: web
|
||||
run: npm install
|
||||
run: npm install && npm exec -- allow-scripts
|
||||
|
||||
- name: Type check
|
||||
working-directory: web
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Stage 1: Build React frontend
|
||||
FROM node:22-alpine AS frontend
|
||||
WORKDIR /app/web
|
||||
COPY web/package*.json ./
|
||||
RUN npm install
|
||||
COPY web/package*.json web/.npmrc ./
|
||||
RUN npm install && npm exec -- allow-scripts
|
||||
COPY web/ ./
|
||||
RUN npm run build
|
||||
|
||||
|
||||
@@ -15,7 +15,9 @@ tasks:
|
||||
web:install:
|
||||
desc: Install frontend dependencies
|
||||
dir: "{{.WEB_DIR}}"
|
||||
cmd: npm install
|
||||
cmds:
|
||||
- npm install
|
||||
- npm exec -- allow-scripts
|
||||
sources:
|
||||
- package.json
|
||||
generates:
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
1
web/.npmrc
Normal file
1
web/.npmrc
Normal file
@@ -0,0 +1 @@
|
||||
ignore-scripts=true
|
||||
1281
web/package-lock.json
generated
1281
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@lavamoat/preinstall-always-fail": "^3.0.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"react-router-dom": "^7.13.1"
|
||||
@@ -15,6 +16,7 @@
|
||||
"test": "vitest run"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lavamoat/allow-scripts": "^5.0.1",
|
||||
"@testing-library/dom": "^10.4.1",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@testing-library/react": "^16.3.2",
|
||||
@@ -28,5 +30,10 @@
|
||||
"typescript": "^6.0.2",
|
||||
"vite": "^8.0.8",
|
||||
"vitest": "^4.1.4"
|
||||
},
|
||||
"lavamoat": {
|
||||
"allowScripts": {
|
||||
"@lavamoat/preinstall-always-fail": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ export default function TimeOff() {
|
||||
onChange={e => setForm(f => ({ ...f, volunteer_id: Number(e.target.value) }))}
|
||||
>
|
||||
<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>
|
||||
))}
|
||||
</select>
|
||||
@@ -226,8 +226,8 @@ export default function TimeOff() {
|
||||
{requests.map(r => (
|
||||
<tr key={r.id}>
|
||||
{role === 'admin' && <td>{volunteerName(r.volunteer_id)}</td>}
|
||||
<td>{new Date(r.starts_at).toLocaleDateString()}</td>
|
||||
<td>{new Date(r.ends_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(undefined, { year: 'numeric', month: 'long', day: 'numeric' })}</td>
|
||||
<td>{r.reason ?? '—'}</td>
|
||||
<td><span className={statusClass(r.status)}>{r.status}</span></td>
|
||||
<td>
|
||||
|
||||
Reference in New Issue
Block a user