Fix status button colors and runtime display

Fixed status button colors. Added remaining runtime display for running jobs below "sale start" and "sale end" in job details.
This commit is contained in:
gpt-engineer-app[bot]
2025-07-09 23:09:18 +00:00
committed by PhatPhuckDave
parent f697f38e4f
commit 85f55da57b
3 changed files with 74 additions and 2 deletions

View File

@@ -1,3 +1,4 @@
import { useState, useEffect } from 'react';
import { Calendar, Factory, Clock, Copy, DollarSign } from 'lucide-react';
import { Input } from '@/components/ui/input';
@@ -6,6 +7,7 @@ import { useJobs } from '@/hooks/useDataService';
import { useToast } from '@/hooks/use-toast';
import { useClipboard } from '@/hooks/useClipboard';
import { formatISK } from '@/utils/priceUtils';
import { formatDuration, calculateRemainingTime } from '@/utils/timeUtils';
interface JobCardDetailsProps {
job: IndJob;
@@ -14,11 +16,26 @@ interface JobCardDetailsProps {
const JobCardDetails: React.FC<JobCardDetailsProps> = ({ job }) => {
const [editingField, setEditingField] = useState<string | null>(null);
const [tempValues, setTempValues] = useState<{ [key: string]: string }>({});
const [remainingTime, setRemainingTime] = useState<number>(0);
const { updateJob } = useJobs();
const { toast } = useToast();
const { copying, copyToClipboard } = useClipboard();
// Update remaining time for running jobs
useEffect(() => {
if (job.status === 'Running' && job.jobStart && job.runtime) {
const updateRemainingTime = () => {
const remaining = calculateRemainingTime(job.jobStart, job.runtime);
setRemainingTime(remaining);
};
updateRemainingTime();
const interval = setInterval(updateRemainingTime, 1000);
return () => clearInterval(interval);
}
}, [job.status, job.jobStart, job.runtime]);
const formatDateTime = (dateString: string | null | undefined) => {
if (!dateString) return 'Not set';
return new Date(dateString).toLocaleString('en-CA', {
@@ -183,6 +200,26 @@ const JobCardDetails: React.FC<JobCardDetailsProps> = ({ job }) => {
fieldName="saleEnd"
icon={<Calendar className="w-4 h-4" />}
/>
{job.status === 'Running' && job.runtime && (
<>
<div className="flex items-center gap-2 text-sm text-gray-400">
<Clock className="w-4 h-4" />
<span>Runtime:</span>
</div>
<div className="text-sm text-white">
{formatDuration(job.runtime)}
</div>
<div className="flex items-center gap-2 text-sm text-gray-400">
<Clock className="w-4 h-4" />
<span>Remaining:</span>
</div>
<div className="text-sm text-green-400">
{formatDuration(remainingTime)}
</div>
</>
)}
</div>
{job.projectedRevenue > 0 && job.produced > 0 && (

View File

@@ -74,7 +74,7 @@ const JobStatusNavigation: React.FC<JobStatusNavigationProps> = ({ job }) => {
e.stopPropagation();
handleStatusChange(previousStatus);
}}
className={`${getStatusColor(previousStatus)}/60 text-white px-4 py-2 rounded flex items-center justify-center gap-1 hover:opacity-80 transition-opacity w-32`}
className={`${getStatusColor(previousStatus)} text-white px-4 py-2 rounded flex items-center justify-center gap-1 hover:opacity-80 transition-opacity w-32`}
data-no-navigate
title={`Move to ${previousStatus}`}
>
@@ -88,7 +88,7 @@ const JobStatusNavigation: React.FC<JobStatusNavigationProps> = ({ job }) => {
e.stopPropagation();
handleStatusChange(nextStatus);
}}
className={`${getStatusColor(nextStatus)}/60 text-white px-4 py-2 rounded flex items-center justify-center gap-1 hover:opacity-80 transition-opacity w-32`}
className={`${getStatusColor(nextStatus)} text-white px-4 py-2 rounded flex items-center justify-center gap-1 hover:opacity-80 transition-opacity w-32`}
data-no-navigate
title={`Move to ${nextStatus}`}
>

35
src/utils/timeUtils.ts Normal file
View File

@@ -0,0 +1,35 @@
export const formatDuration = (seconds: number): string => {
if (seconds <= 0) return 'Ready!';
const units = [
{ name: 'w', value: 604800 }, // weeks
{ name: 'd', value: 86400 }, // days
{ name: 'h', value: 3600 }, // hours
{ name: 'm', value: 60 }, // minutes
{ name: 's', value: 1 } // seconds
];
const parts: string[] = [];
let remaining = Math.floor(seconds);
for (const unit of units) {
if (remaining >= unit.value) {
const count = Math.floor(remaining / unit.value);
parts.push(`${count}${unit.name}`);
remaining %= unit.value;
}
}
return parts.length > 0 ? parts.join(' ') : '0s';
};
export const calculateRemainingTime = (jobStart: string | null, runtime: number): number => {
if (!jobStart || !runtime) return 0;
const startTime = new Date(jobStart).getTime();
const currentTime = Date.now();
const elapsedSeconds = (currentTime - startTime) / 1000;
return Math.max(0, runtime - elapsedSeconds);
};