Refactor: Move status navigation buttons
Relocate the status navigation buttons to below the header, between the header and details sections of the job card. This change aims to improve the layout and address the issue of long job names. Also, ensure no duplicate code.
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import { CardTitle } from '@/components/ui/card';
|
import { CardTitle } from '@/components/ui/card';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Copy, BarChart3 } from 'lucide-react';
|
import { Copy, BarChart3 } from 'lucide-react';
|
||||||
@@ -43,68 +42,73 @@ const JobCardHeader: React.FC<JobCardHeaderProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-between items-start">
|
<>
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex justify-between items-start">
|
||||||
<div className="flex items-center gap-2 mb-2">
|
<div className="flex-1 min-w-0">
|
||||||
<CardTitle
|
<div className="flex items-center gap-2 mb-2">
|
||||||
className="text-blue-400 truncate cursor-pointer hover:text-blue-300 transition-colors flex items-center gap-1 leading-normal"
|
<CardTitle
|
||||||
onClick={handleJobNameClick}
|
className="text-blue-400 truncate cursor-pointer hover:text-blue-300 transition-colors flex items-center gap-1 leading-normal"
|
||||||
title="Click to copy job name"
|
onClick={handleJobNameClick}
|
||||||
data-no-navigate
|
title="Click to copy job name"
|
||||||
style={{ lineHeight: '1.4' }}
|
data-no-navigate
|
||||||
>
|
style={{ lineHeight: '1.4' }}
|
||||||
{job.outputItem}
|
>
|
||||||
{copying === 'name' && <Copy className="w-4 h-4 text-green-400" />}
|
{job.outputItem}
|
||||||
</CardTitle>
|
{copying === 'name' && <Copy className="w-4 h-4 text-green-400" />}
|
||||||
|
</CardTitle>
|
||||||
|
</div>
|
||||||
|
<div className="text-gray-400 text-sm leading-relaxed" style={{ lineHeight: '1.4' }}>
|
||||||
|
<div className="mb-1">
|
||||||
|
Runs: {job.outputQuantity.toLocaleString()}
|
||||||
|
<span className="ml-4">
|
||||||
|
Produced: <EditableProduced job={job} onUpdateProduced={onUpdateProduced} />
|
||||||
|
</span>
|
||||||
|
<span className="ml-4 items-center gap-1">
|
||||||
|
Sold: <span className="text-green-400">{itemsSold.toLocaleString()}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-gray-400 text-sm leading-relaxed" style={{ lineHeight: '1.4' }}>
|
<div className="flex flex-col gap-2 flex-shrink-0 items-end">
|
||||||
<div className="mb-1">
|
<div className="flex items-center gap-2">
|
||||||
Runs: {job.outputQuantity.toLocaleString()}
|
<JobStatusDropdown job={job} />
|
||||||
<span className="ml-4">
|
<Button
|
||||||
Produced: <EditableProduced job={job} onUpdateProduced={onUpdateProduced} />
|
variant="outline"
|
||||||
</span>
|
size="sm"
|
||||||
<span className="ml-4 items-center gap-1">
|
onClick={() => onEdit(job)}
|
||||||
Sold: <span className="text-green-400">{itemsSold.toLocaleString()}</span>
|
className="border-gray-600 hover:bg-gray-800"
|
||||||
</span>
|
data-no-navigate
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="destructive"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => onDelete(job.id)}
|
||||||
|
data-no-navigate
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="flex">
|
||||||
|
<button
|
||||||
|
className="text-gray-400 hover:text-blue-300 transition-colors px-2"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
setOverviewChartOpen(true);
|
||||||
|
}}
|
||||||
|
data-no-navigate
|
||||||
|
title="View transaction charts"
|
||||||
|
>
|
||||||
|
<BarChart3 className="w-4 h-4" />
|
||||||
|
</button>
|
||||||
|
<BOMActions job={job} onImportBOM={onImportBOM} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-2 flex-shrink-0 items-end">
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex justify-center mt-2 mb-2">
|
||||||
<JobStatusNavigation job={job} />
|
<JobStatusNavigation job={job} />
|
||||||
<JobStatusDropdown job={job} />
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => onEdit(job)}
|
|
||||||
className="border-gray-600 hover:bg-gray-800"
|
|
||||||
data-no-navigate
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="destructive"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => onDelete(job.id)}
|
|
||||||
data-no-navigate
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<div className="flex">
|
|
||||||
<button
|
|
||||||
className="text-gray-400 hover:text-blue-300 transition-colors px-2"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
setOverviewChartOpen(true);
|
|
||||||
}}
|
|
||||||
data-no-navigate
|
|
||||||
title="View transaction charts"
|
|
||||||
>
|
|
||||||
<BarChart3 className="w-4 h-4" />
|
|
||||||
</button>
|
|
||||||
<BOMActions job={job} onImportBOM={onImportBOM} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<TransactionChart
|
<TransactionChart
|
||||||
@@ -127,7 +131,7 @@ const JobCardHeader: React.FC<JobCardHeaderProps> = ({
|
|||||||
isOpen={totalProfitChartOpen}
|
isOpen={totalProfitChartOpen}
|
||||||
onClose={() => setTotalProfitChartOpen(false)}
|
onClose={() => setTotalProfitChartOpen(false)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -67,7 +67,7 @@ const JobStatusNavigation: React.FC<JobStatusNavigationProps> = ({ job }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex gap-1">
|
<div className="flex gap-2 items-center">
|
||||||
{previousStatus && (
|
{previousStatus && (
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@@ -76,11 +76,12 @@ const JobStatusNavigation: React.FC<JobStatusNavigationProps> = ({ job }) => {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleStatusChange(previousStatus);
|
handleStatusChange(previousStatus);
|
||||||
}}
|
}}
|
||||||
className="border-gray-600 hover:bg-gray-800 p-2"
|
className="border-gray-600 hover:bg-gray-800 px-3"
|
||||||
data-no-navigate
|
data-no-navigate
|
||||||
title={`Move to ${previousStatus}`}
|
title={`Move to ${previousStatus}`}
|
||||||
>
|
>
|
||||||
<ChevronLeft className="w-4 h-4" />
|
<ChevronLeft className="w-4 h-4 mr-1" />
|
||||||
|
{previousStatus}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{nextStatus && (
|
{nextStatus && (
|
||||||
@@ -91,11 +92,12 @@ const JobStatusNavigation: React.FC<JobStatusNavigationProps> = ({ job }) => {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleStatusChange(nextStatus);
|
handleStatusChange(nextStatus);
|
||||||
}}
|
}}
|
||||||
className="border-gray-600 hover:bg-gray-800 p-2"
|
className="border-gray-600 hover:bg-gray-800 px-3"
|
||||||
data-no-navigate
|
data-no-navigate
|
||||||
title={`Move to ${nextStatus}`}
|
title={`Move to ${nextStatus}`}
|
||||||
>
|
>
|
||||||
<ChevronRight className="w-4 h-4" />
|
{nextStatus}
|
||||||
|
<ChevronRight className="w-4 h-4 ml-1" />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@@ -52,16 +52,20 @@ export const getStatusPriority = (status: IndJobStatusOptions): number => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const JOB_STATUSES = ['Planned', 'Acquisition', 'Staging', 'Inbound', 'Running', 'Done', 'Delivered', 'Outbound', 'Selling', 'Closed', 'Tracked'] as const;
|
// Use the actual type values from the enum
|
||||||
|
export const JOB_STATUSES: IndJobStatusOptions[] = [
|
||||||
|
'Planned', 'Acquisition', 'Staging', 'Inbound', 'Running', 'Done',
|
||||||
|
'Delivered', 'Outbound', 'Selling', 'Closed', 'Tracked'
|
||||||
|
];
|
||||||
|
|
||||||
export const getNextStatus = (currentStatus: string): string | null => {
|
export const getNextStatus = (currentStatus: string): IndJobStatusOptions | null => {
|
||||||
const currentIndex = JOB_STATUSES.indexOf(currentStatus as any);
|
const currentIndex = JOB_STATUSES.indexOf(currentStatus as IndJobStatusOptions);
|
||||||
if (currentIndex === -1 || currentIndex === JOB_STATUSES.length - 1) return null;
|
if (currentIndex === -1 || currentIndex === JOB_STATUSES.length - 1) return null;
|
||||||
return JOB_STATUSES[currentIndex + 1];
|
return JOB_STATUSES[currentIndex + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getPreviousStatus = (currentStatus: string): string | null => {
|
export const getPreviousStatus = (currentStatus: string): IndJobStatusOptions | null => {
|
||||||
const currentIndex = JOB_STATUSES.indexOf(currentStatus as any);
|
const currentIndex = JOB_STATUSES.indexOf(currentStatus as IndJobStatusOptions);
|
||||||
if (currentIndex <= 0) return null;
|
if (currentIndex <= 0) return null;
|
||||||
return JOB_STATUSES[currentIndex - 1];
|
return JOB_STATUSES[currentIndex - 1];
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user