Feature #9
closedFeature #7: Feature list
Calendar view for jobs
0%
Description
Codex Task: Add Job Calendar View¶
Objective¶
Add a simple calendar view for jobs to the existing Task App.
The calendar should help admins and dispatchers see scheduled jobs by date without changing the existing lightweight architecture.
Keep the implementation simple and consistent with the current plain PHP, PDO and CSS codebase.
Do not introduce Laravel, React, Vue, a build system or a large frontend framework.
Existing Project Context¶
Task App is a lightweight field-service management application built with:
-
Plain PHP
-
PDO
-
MariaDB
-
Server-rendered PHP views
-
Simple CSS
-
Session-based authentication
-
Roles:
admindispatcherworker
Jobs already contain scheduling information and can be viewed and managed through the existing job routes.
The existing job list and worker workflow must continue to work unchanged.
Required Feature¶
Create a calendar page where admins and dispatchers can see scheduled jobs grouped by date.
New Route¶
Add:
GET /jobs/calendar
Access must be limited to:
- Admins
- Dispatchers
Workers must receive the same existing 403 response used elsewhere in the application.
Calendar Views¶
Implement a simple monthly calendar.
The page should include:
- Current month name and year
- Previous month navigation
- Next month navigation
- A “Today” link or button
- Seven weekday columns
- One cell for each calendar date
- Jobs displayed inside the relevant date cell
Use a query parameter for month navigation:
/jobs/calendar?month=2026-07
When no valid month parameter is supplied, show the current month.
Validate the parameter strictly using the YYYY-MM format.
Invalid values should safely fall back to the current month.
Job Scheduling Rules¶
Use the existing planned or scheduled job date field already present in the database.
Before implementing, inspect the existing schema and job repository to identify the correct field. Do not add a duplicate scheduling field.
Only place a job on the calendar when it has a valid scheduled date.
Jobs without a scheduled date should not appear in a date cell.
Add a small section above or below the calendar showing the number of unscheduled active jobs, with a link to the existing jobs list filtered appropriately if the current list supports such filtering.
Do not build a new unscheduled-job management workflow as part of this task.
Job Information Shown¶
Each calendar entry should show only compact, useful information:
- Job number
- Customer name
- Location name or address
- Assigned worker, when assigned
- Current job status
The job number or full calendar entry should link to:
/jobs/{id}
Do not place full job descriptions or long notes inside the calendar.
Status Handling¶
Use the existing job statuses and existing status-label styling where possible.
Cancelled jobs should either:
- be excluded from the calendar, or
- remain visible with clearly muted styling
Use whichever approach is most consistent with the existing job list behaviour.
Do not introduce new statuses.
Calendar Navigation¶
Add a Calendar link to the admin/dispatcher navigation near the existing Jobs link.
Do not show this navigation item to workers.
The existing Jobs navigation and /jobs list page must remain available.
The calendar is an additional view, not a replacement for the job list.
Repository Changes¶
Add a focused repository function for retrieving jobs within a date range.
For example:
find_jobs_for_calendar(PDO $pdo, string $startDate, string $endDate): array
Use a range query covering the visible calendar grid, including dates from the previous or next month that appear in the first and last calendar rows.
Avoid querying the database once per calendar day.
The calendar should use one efficient query for the displayed date range.
Join or retrieve the required related information using the existing repository conventions:
- Customer
- Location
- Assigned worker
Avoid unnecessary columns and avoid SELECT * where practical.
Date and Time Handling¶
Use PHP date utilities such as:
DateTimeImmutableDateIntervalDatePeriod
Do not manually hardcode month lengths.
The calendar week should start on Monday.
Weekday headings should be:
Mon
Tue
Wed
Thu
Fri
Sat
Sun
Use the application/server timezone already configured by the project.
Do not add a new timezone setting unless one is already needed by the current application.
Visual Requirements¶
Keep the visual design aligned with the current Task App interface.
The calendar should:
- Work on desktop
- Remain usable on mobile
- Avoid horizontal page overflow where reasonably possible
- Clearly distinguish dates outside the selected month
- Clearly highlight today
- Keep job cards compact
- Avoid oversized spacing
For smaller screens, it is acceptable for each day cell to stack vertically or for the calendar to use controlled horizontal scrolling, provided the page remains usable.
Do not redesign the whole application.
Do not include the previously tracked header, footer or dashboard-counter polish items in this task.
Empty States¶
Provide clear empty states.
Examples:
- No jobs scheduled during the displayed month
- No jobs scheduled on a particular date
- No unscheduled active jobs
Do not fill every empty date cell with repetitive text. Empty date cells may remain visually empty.
Security and Validation¶
Maintain the existing project security patterns:
- Require authentication
- Enforce admin/dispatcher role access
- Escape all output
- Validate the
monthquery parameter - Do not trust IDs or date values directly from requests
- Use prepared statements for database queries
This feature is read-only, so no new CSRF-protected POST actions are required.
Suggested Files¶
Inspect the existing project structure first.
Likely files include:
public/index.php
app/repositories/jobs.php
app/views/jobs/calendar.php
app/views/layout.php
public/assets/css/app.css
README.md
Use the actual existing layout and navigation files found in the repository.
Do not create duplicate layout or helper systems.
README Update¶
Update the README with:
- The new calendar route
- Access roles
- Month query format
- A brief description of how scheduled and unscheduled jobs are handled
Acceptance Criteria¶
The task is complete when:
- Admins and dispatchers can open
/jobs/calendar. - Workers cannot access the calendar.
- The current month is shown by default.
- Previous and next month navigation works.
- The calendar week starts on Monday.
- Jobs appear on their correct scheduled dates.
- Calendar entries link to the existing job detail page.
- Customer, location, worker and status information are displayed compactly.
- Dates outside the selected month are visually muted.
- Today is visually highlighted.
- Invalid
monthvalues do not cause errors. - Jobs are retrieved using a date-range query rather than one query per day.
- Existing job list, job management and worker workflows continue to work.
- The calendar remains usable on mobile.
- No large frontend framework or unnecessary dependency is introduced.
Validation¶
Run relevant validation available in the repository.
At minimum:
php -l public/index.php
php -l app/repositories/jobs.php
php -l app/views/jobs/calendar.php
Also manually verify:
/jobs/calendar
/jobs/calendar?month=2026-07
/jobs/calendar?month=2026-08
/jobs/calendar?month=invalid
Test access as:
- Admin
- Dispatcher
- Worker
Confirm that existing pages still function:
/jobs
/jobs/{id}
/work
/work/jobs/{id}
Final Response¶
When complete, report:
- Summary of the implementation
- Files changed
- Route added
- Database fields used
- Calendar behaviour
- Access-control behaviour
- Validation commands and results
- Any assumptions made
- Any remaining limitations
Do not implement attachments, photos, signatures, maps, materials, inventory, dark mode or API integrations as part of this task.