Add a toggle to display daily totals in hours or days
Update the UI to include a switch that allows users to toggle between displaying time totals in hours (h) or days (j). When in days view, totals are rounded up with 8 hours equaling 1 day. This change affects the display of row totals, column totals, and the grand total. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 55837015-10e9-4be9-b857-7f5e6be73772 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: 22ef23e4-98ff-4918-acea-488d8cc9708f Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1cc377db-7ea0-49f2-97ce-c3e87e0228cc/55837015-10e9-4be9-b857-7f5e6be73772/qXEnLes Replit-Helium-Checkpoint-Created: true
This commit is contained in:
parent
249103b2aa
commit
1d74cd493c
@ -112,6 +112,7 @@ export default function TimesheetDetailPage() {
|
|||||||
const [localDescriptions, setLocalDescriptions] = useState<Record<string, string>>({});
|
const [localDescriptions, setLocalDescriptions] = useState<Record<string, string>>({});
|
||||||
const [isAddingLine, setIsAddingLine] = useState(false);
|
const [isAddingLine, setIsAddingLine] = useState(false);
|
||||||
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
|
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
|
||||||
|
const [showDays, setShowDays] = useState(false);
|
||||||
const dirtyKeysRef = useRef<Set<string>>(new Set());
|
const dirtyKeysRef = useRef<Set<string>>(new Set());
|
||||||
|
|
||||||
const { data: projects } = useListProjects({ query: { queryKey: getListProjectsQueryKey() } });
|
const { data: projects } = useListProjects({ query: { queryKey: getListProjectsQueryKey() } });
|
||||||
@ -421,17 +422,43 @@ export default function TimesheetDetailPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="bg-card rounded-xl border shadow-sm flex-1 min-h-0 flex flex-col overflow-hidden">
|
<div className="bg-card rounded-xl border shadow-sm flex-1 min-h-0 flex flex-col overflow-hidden">
|
||||||
{isEditable && (
|
<div className="px-3 py-2 border-b flex justify-between items-center bg-muted/20 shrink-0">
|
||||||
<div className="px-3 py-2 border-b flex justify-between items-center bg-muted/20 shrink-0">
|
<div>
|
||||||
<Button variant="outline" size="sm" onClick={() => setIsAddingLine(true)} className="gap-2">
|
{isEditable && (
|
||||||
<Plus className="h-4 w-4" />
|
<Button variant="outline" size="sm" onClick={() => setIsAddingLine(true)} className="gap-2">
|
||||||
Ajouter un projet
|
<Plus className="h-4 w-4" />
|
||||||
</Button>
|
Ajouter un projet
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div className="flex items-center gap-1.5 text-xs text-muted-foreground">
|
||||||
|
<span className={!showDays ? "font-semibold text-foreground" : ""}>h</span>
|
||||||
|
<button
|
||||||
|
onClick={() => setShowDays(d => !d)}
|
||||||
|
className={cn(
|
||||||
|
"relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors",
|
||||||
|
showDays ? "bg-primary" : "bg-muted"
|
||||||
|
)}
|
||||||
|
role="switch"
|
||||||
|
aria-checked={showDays}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className={cn(
|
||||||
|
"pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow-sm ring-0 transition-transform",
|
||||||
|
showDays ? "translate-x-4" : "translate-x-0"
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<span className={showDays ? "font-semibold text-foreground" : ""}>j</span>
|
||||||
|
</div>
|
||||||
<div className="text-sm font-medium">
|
<div className="text-sm font-medium">
|
||||||
Total: <span className="text-lg text-primary">{grandTotal}h</span>
|
Total: <span className="text-lg text-primary">
|
||||||
|
{showDays ? `${Math.ceil(grandTotal / 8)}j` : `${grandTotal}h`}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
|
|
||||||
<div className="flex-1 overflow-y-auto">
|
<div className="flex-1 overflow-y-auto">
|
||||||
<table className="w-full text-xs border-collapse table-fixed">
|
<table className="w-full text-xs border-collapse table-fixed">
|
||||||
@ -571,7 +598,9 @@ export default function TimesheetDetailPage() {
|
|||||||
|
|
||||||
<td className="px-1 py-1.5 text-center font-medium bg-card sticky right-0 z-10 group-hover:bg-muted/20">
|
<td className="px-1 py-1.5 text-center font-medium bg-card sticky right-0 z-10 group-hover:bg-muted/20">
|
||||||
{rowTotals[line.id] > 0 ? (
|
{rowTotals[line.id] > 0 ? (
|
||||||
<span className="text-primary text-xs font-bold">{rowTotals[line.id]}h</span>
|
<span className="text-primary text-xs font-bold">
|
||||||
|
{showDays ? `${Math.ceil(rowTotals[line.id] / 8)}j` : `${rowTotals[line.id]}h`}
|
||||||
|
</span>
|
||||||
) : "-"}
|
) : "-"}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -593,12 +622,12 @@ export default function TimesheetDetailPage() {
|
|||||||
total >= 8 ? "text-green-700 font-bold bg-green-50" : ""
|
total >= 8 ? "text-green-700 font-bold bg-green-50" : ""
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{total > 0 ? total : ""}
|
{total > 0 ? (showDays ? `${Math.ceil(total / 8)}j` : total) : ""}
|
||||||
</td>
|
</td>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<td className="px-1 py-1.5 text-center text-primary font-bold border-t sticky right-0 z-20 bg-muted/80">
|
<td className="px-1 py-1.5 text-center text-primary font-bold border-t sticky right-0 z-20 bg-muted/80">
|
||||||
{grandTotal}h
|
{showDays ? `${Math.ceil(grandTotal / 8)}j` : `${grandTotal}h`}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user