diff --git a/src/components/JobCardHeader.tsx b/src/components/JobCardHeader.tsx index a270b59..1063e07 100644 --- a/src/components/JobCardHeader.tsx +++ b/src/components/JobCardHeader.tsx @@ -1,3 +1,4 @@ + import { CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Copy, BarChart3 } from 'lucide-react'; @@ -6,6 +7,7 @@ import { useClipboard } from '@/hooks/useClipboard'; import { useJobs } from '@/hooks/useDataService'; import { useState } from 'react'; import JobStatusDropdown from './JobStatusDropdown'; +import JobStatusNavigation from './JobStatusNavigation'; import BOMActions from './BOMActions'; import EditableProduced from './EditableProduced'; import TransactionChart from './TransactionChart'; @@ -69,6 +71,7 @@ const JobCardHeader: React.FC = ({
+ + )} + {nextStatus && ( + + )} +
+ ); +}; + +export default JobStatusNavigation; diff --git a/src/lib/types.ts b/src/lib/types.ts index f2ff4f2..5611eab 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -21,6 +21,7 @@ export type IndJob = { updated?: IsoDateString projectedCost?: number projectedRevenue?: number + runtime?: number } export type IndTransaction = IndTransactionRecord; diff --git a/src/utils/jobAttentionUtils.ts b/src/utils/jobAttentionUtils.ts index 883fa10..3747999 100644 --- a/src/utils/jobAttentionUtils.ts +++ b/src/utils/jobAttentionUtils.ts @@ -33,6 +33,20 @@ export function jobNeedsAttention(job: IndJob): boolean { return allMaterialsSatisfied; } + // Running jobs need attention when they have finished (start date + runtime > current time) + if (job.status === 'Running') { + if (!job.jobStart || !job.runtime) { + return false; + } + + const startTime = new Date(job.jobStart).getTime(); + const runtimeMs = job.runtime * 1000; // Convert seconds to milliseconds + const finishTime = startTime + runtimeMs; + const currentTime = Date.now(); + + return currentTime >= finishTime; + } + // Selling jobs need attention when sold count reaches produced count if (job.status === 'Selling') { const produced = job.produced || 0; diff --git a/src/utils/jobStatusUtils.ts b/src/utils/jobStatusUtils.ts index 50a8d51..f04a82d 100644 --- a/src/utils/jobStatusUtils.ts +++ b/src/utils/jobStatusUtils.ts @@ -5,9 +5,13 @@ export const getStatusColor = (status: string) => { switch (status) { case 'Planned': return 'bg-gray-600'; case 'Acquisition': return 'bg-yellow-600'; + case 'Staging': return 'bg-amber-600'; + case 'Inbound': return 'bg-orange-600'; case 'Running': return 'bg-blue-600'; case 'Done': return 'bg-purple-600'; - case 'Selling': return 'bg-orange-600'; + case 'Delivered': return 'bg-indigo-600'; + case 'Outbound': return 'bg-pink-600'; + case 'Selling': return 'bg-emerald-600'; case 'Closed': return 'bg-green-600'; case 'Tracked': return 'bg-cyan-600'; default: return 'bg-gray-600'; @@ -18,9 +22,13 @@ export const getStatusBackgroundColor = (status: string) => { switch (status) { case 'Planned': return 'bg-gray-600/20'; case 'Acquisition': return 'bg-yellow-600/20'; + case 'Staging': return 'bg-amber-600/20'; + case 'Inbound': return 'bg-orange-600/20'; case 'Running': return 'bg-blue-600/20'; case 'Done': return 'bg-purple-600/20'; - case 'Selling': return 'bg-orange-600/20'; + case 'Delivered': return 'bg-indigo-600/20'; + case 'Outbound': return 'bg-pink-600/20'; + case 'Selling': return 'bg-emerald-600/20'; case 'Closed': return 'bg-green-600/20'; case 'Tracked': return 'bg-cyan-600/20'; default: return 'bg-gray-600/20'; @@ -29,15 +37,31 @@ export const getStatusBackgroundColor = (status: string) => { export const getStatusPriority = (status: IndJobStatusOptions): number => { switch (status) { - case 'Planned': return 6; - case 'Acquisition': return 1; - case 'Running': return 2; - case 'Done': return 3; - case 'Selling': return 4; - case 'Closed': return 5; - case 'Tracked': return 7; + case 'Planned': return 1; + case 'Acquisition': return 2; + case 'Staging': return 3; + case 'Inbound': return 4; + case 'Running': return 5; + case 'Done': return 6; + case 'Delivered': return 7; + case 'Outbound': return 8; + case 'Selling': return 9; + case 'Closed': return 10; + case 'Tracked': return 11; default: return 0; } }; -export const JOB_STATUSES = ['Planned', 'Acquisition', 'Running', 'Done', 'Selling', 'Closed', 'Tracked'] as const; +export const JOB_STATUSES = ['Planned', 'Acquisition', 'Staging', 'Inbound', 'Running', 'Done', 'Delivered', 'Outbound', 'Selling', 'Closed', 'Tracked'] as const; + +export const getNextStatus = (currentStatus: string): string | null => { + const currentIndex = JOB_STATUSES.indexOf(currentStatus as any); + if (currentIndex === -1 || currentIndex === JOB_STATUSES.length - 1) return null; + return JOB_STATUSES[currentIndex + 1]; +}; + +export const getPreviousStatus = (currentStatus: string): string | null => { + const currentIndex = JOB_STATUSES.indexOf(currentStatus as any); + if (currentIndex <= 0) return null; + return JOB_STATUSES[currentIndex - 1]; +};