diff --git a/src/components/JobCard.tsx b/src/components/JobCard.tsx index a27c71b..37fe019 100644 --- a/src/components/JobCard.tsx +++ b/src/components/JobCard.tsx @@ -1,4 +1,4 @@ -import { Link } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; import { Card, CardContent, CardHeader } from '@/components/ui/card'; import { IndJob } from '@/lib/types'; import JobCardHeader from './JobCardHeader'; @@ -22,6 +22,8 @@ const JobCard: React.FC = ({ onImportBOM, isTracked = false }) => { + const navigate = useNavigate(); + const getStatusBackgroundColor = (status: string) => { switch (status) { case 'Planned': return 'bg-gray-600/20'; @@ -35,30 +37,40 @@ const JobCard: React.FC = ({ } }; + const handleCardClick = (e: React.MouseEvent) => { + // Check if the click target or any of its parents has the data-no-navigate attribute + const target = e.target as HTMLElement; + const hasNoNavigate = target.closest('[data-no-navigate]'); + + if (hasNoNavigate) { + // Don't navigate if clicking on elements marked as non-navigating + return; + } + + // Only navigate if clicking on areas that aren't marked as non-navigating + navigate(`/${job.id}`); + }; + return ( - - - - - - - -
- - - - + + + + + +
+ + + ); }; diff --git a/src/components/JobCardDetails.tsx b/src/components/JobCardDetails.tsx index f021b61..3c950b1 100644 --- a/src/components/JobCardDetails.tsx +++ b/src/components/JobCardDetails.tsx @@ -28,7 +28,6 @@ const JobCardDetails: React.FC = ({ job }) => { }; const handleFieldClick = (fieldName: string, currentValue: string | null, e: React.MouseEvent) => { - e.stopPropagation(); setEditingField(fieldName); setTempValues({ ...tempValues, [fieldName]: currentValue || '' }); }; @@ -73,15 +72,16 @@ const JobCardDetails: React.FC = ({ job }) => { onChange={(e) => setTempValues({ ...tempValues, [fieldName]: e.target.value })} onBlur={() => handleFieldUpdate(fieldName, tempValues[fieldName])} onKeyDown={(e) => handleKeyPress(fieldName, e)} - onClick={(e) => e.stopPropagation()} className="h-6 px-2 py-1 bg-gray-800 border-gray-600 text-white text-xs" autoFocus + data-no-navigate /> ) : ( handleFieldClick(fieldName, value, e)} className="cursor-pointer hover:text-blue-400 flex-1" title="Click to edit" + data-no-navigate > {formatDateTime(value)} @@ -136,7 +136,10 @@ const JobCardDetails: React.FC = ({ job }) => { {job.billOfMaterials && job.billOfMaterials.length > 0 && ( -
+
BOM: {job.billOfMaterials.length} items (hover to view)
diff --git a/src/components/JobCardHeader.tsx b/src/components/JobCardHeader.tsx index 3bab29d..9490739 100644 --- a/src/components/JobCardHeader.tsx +++ b/src/components/JobCardHeader.tsx @@ -51,7 +51,6 @@ const JobCardHeader: React.FC = ({ }; const handleStatusChange = async (newStatus: string, e: React.MouseEvent) => { - e.stopPropagation(); try { await updateJob(job.id, { status: newStatus }); toast({ @@ -178,7 +177,6 @@ const JobCardHeader: React.FC = ({ }; const handleJobNameClick = async (e: React.MouseEvent) => { - e.stopPropagation(); try { await navigator.clipboard.writeText(job.outputItem); setCopyingName(true); @@ -199,29 +197,24 @@ const JobCardHeader: React.FC = ({ }; const handleProducedClick = (e: React.MouseEvent) => { - e.stopPropagation(); if (job.status !== 'Closed') { setIsEditingProduced(true); } }; const handleEditClick = (e: React.MouseEvent) => { - e.stopPropagation(); onEdit(job); }; const handleDeleteClick = (e: React.MouseEvent) => { - e.stopPropagation(); onDelete(job.id); }; const handleImportClick = (e: React.MouseEvent) => { - e.stopPropagation(); importBillOfMaterials(); }; const handleExportClick = (e: React.MouseEvent) => { - e.stopPropagation(); exportBillOfMaterials(); }; @@ -234,10 +227,11 @@ const JobCardHeader: React.FC = ({
- {job.outputItem} {copyingName && } @@ -254,16 +248,17 @@ const JobCardHeader: React.FC = ({ onChange={(e) => setProducedValue(e.target.value)} onBlur={handleProducedUpdate} onKeyDown={handleProducedKeyPress} - onClick={(e) => e.stopPropagation()} className="w-24 h-6 px-2 py-1 inline-block bg-gray-800 border-gray-600 text-white" min="0" autoFocus + data-no-navigate /> ) : ( {(job.produced || 0).toLocaleString()} @@ -279,7 +274,10 @@ const JobCardHeader: React.FC = ({
-
+
{job.status}
@@ -289,6 +287,7 @@ const JobCardHeader: React.FC = ({ key={status} onClick={(e) => handleStatusChange(status, e)} className="hover:bg-gray-700 cursor-pointer" + data-no-navigate >
{status} @@ -301,6 +300,7 @@ const JobCardHeader: React.FC = ({ size="sm" onClick={handleEditClick} className="border-gray-600 hover:bg-gray-800" + data-no-navigate > Edit @@ -308,6 +308,7 @@ const JobCardHeader: React.FC = ({ variant="destructive" size="sm" onClick={handleDeleteClick} + data-no-navigate > Delete @@ -319,6 +320,7 @@ const JobCardHeader: React.FC = ({ className="p-1 h-6 w-6" onClick={handleImportClick} title="Import BOM from clipboard" + data-no-navigate > @@ -329,6 +331,7 @@ const JobCardHeader: React.FC = ({ onClick={handleExportClick} disabled={!job.billOfMaterials?.length} title="Export BOM to clipboard" + data-no-navigate > {copyingBom ? ( diff --git a/src/components/JobCardMetrics.tsx b/src/components/JobCardMetrics.tsx index d4beaae..abb4f67 100644 --- a/src/components/JobCardMetrics.tsx +++ b/src/components/JobCardMetrics.tsx @@ -1,4 +1,3 @@ - import { useState } from 'react'; import { formatISK, parseISKAmount } from '@/utils/priceUtils'; import { IndJob } from '@/lib/types'; @@ -29,7 +28,6 @@ const JobCardMetrics: React.FC = ({ job }) => { const margin = totalIncome > 0 ? ((profit / totalIncome) * 100) : 0; const handleFieldClick = (fieldName: string, currentValue: number, e: React.MouseEvent) => { - e.stopPropagation(); setEditingField(fieldName); setTempValues({ ...tempValues, [fieldName]: formatISK(currentValue) }); }; @@ -76,15 +74,16 @@ const JobCardMetrics: React.FC = ({ job }) => { onChange={(e) => setTempValues({ ...tempValues, projectedCost: e.target.value })} onBlur={() => handleFieldUpdate('projectedCost', tempValues.projectedCost)} onKeyDown={(e) => handleKeyPress('projectedCost', e)} - onClick={(e) => e.stopPropagation()} className="w-24 h-6 px-2 py-1 inline-block bg-gray-800 border-gray-600 text-white text-xs" autoFocus + data-no-navigate /> ) : ( handleFieldClick('projectedCost', job.projectedCost, e)} className="cursor-pointer hover:text-blue-400" title="Click to edit" + data-no-navigate > {formatISK(job.projectedCost)} @@ -106,15 +105,16 @@ const JobCardMetrics: React.FC = ({ job }) => { onChange={(e) => setTempValues({ ...tempValues, projectedRevenue: e.target.value })} onBlur={() => handleFieldUpdate('projectedRevenue', tempValues.projectedRevenue)} onKeyDown={(e) => handleKeyPress('projectedRevenue', e)} - onClick={(e) => e.stopPropagation()} className="w-24 h-6 px-2 py-1 inline-block bg-gray-800 border-gray-600 text-white text-xs" autoFocus + data-no-navigate /> ) : ( handleFieldClick('projectedRevenue', job.projectedRevenue, e)} className="cursor-pointer hover:text-blue-400" title="Click to edit" + data-no-navigate > {formatISK(job.projectedRevenue)}