feat: dodaj scheduled_date na Task i kalendar widget

- Novo polje Task.scheduled_date (DateField, nullable, db_index) za planiranje
- Migracija 0009_task_scheduled_date
- Celery task notify_upcoming_tasks: dnevno u 08:00 šalje Pusher + email za sutrašnje zadatke
- TaskCalendarWidget: react-spring slide panel s lijeve strane, grid prikaz mjeseca, dot indikatori, klik otvara TaskServiceRecordsModal
- FleetDashboardShell: import + render kalendara, Planirano stupac u tablici zadataka
- TaskCreateModal + TaskServiceRecordsModal: scheduled_date input i prikaz
- Admin + serializer + views: scheduled_date filter i prikaz
- 47 backend testova prolaze (uključuje 8 novih za notify_upcoming_tasks)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
mariomitte
2026-07-19 14:52:10 +02:00
parent bf8e25efe7
commit 0c9e1b7d50
17 changed files with 610 additions and 7 deletions

View File

@@ -6,6 +6,7 @@ import WorkOrderModal from './WorkOrderModal';
import TaskCreateModal from './TaskCreateModal';
import TaskServiceRecordsModal from './TaskServiceRecordsModal';
import WorkOrderDetailModal from './WorkOrderDetailModal';
import TaskCalendarWidget from './TaskCalendarWidget';
import SyncLogPanel from './SyncLogPanel';
import ServiceRecordForm from '../fleet/ServiceRecordForm';
import ServicePhotoUpload from '../fleet/ServicePhotoUpload';
@@ -578,6 +579,7 @@ export default function FleetDashboardShell({ initialSection = 'dashboard', page
const taskColumns = [
{ key: 'title', label: 'Radni zadatak', className: 'px-4 py-3' },
{ key: 'status', label: 'Status', className: 'px-4 py-3' },
{ key: 'scheduledDate', label: 'Planirano', className: 'px-4 py-3' },
{ key: 'createdAt', label: 'Vrijeme izrade', className: 'px-4 py-3' },
{ key: 'vehicle', label: 'Dizalica', className: 'px-4 py-3' },
{ key: 'workOrder', label: 'Putni nalog', className: 'px-4 py-3' },
@@ -591,6 +593,12 @@ export default function FleetDashboardShell({ initialSection = 'dashboard', page
return (
<AnimatedPage className="min-h-screen">
{hasMounted && (
<TaskCalendarWidget
tasks={tasks}
onTaskClick={(task) => setSelectedTask(task)}
/>
)}
<main className="min-w-0">
<DashboardTopbar
activeSection={activeSection}
@@ -750,6 +758,15 @@ export default function FleetDashboardShell({ initialSection = 'dashboard', page
{getStatusLabel(task.status || '-')}
</span>
</td>
<td className="px-4 py-3">
{task.scheduled_date ? (
<span className="font-medium text-indigo-700">
{formatDate(task.scheduled_date)}
</span>
) : (
<span className="text-text-muted">-</span>
)}
</td>
<td
className="px-4 py-3"
title={formatDateTime(task.created_at) !== '-' ? formatDateTime(task.created_at) : undefined}