Skip to content

Commit 3360f00

Browse files
committed
💄 Update bottom bar styling
1 parent d824f34 commit 3360f00

File tree

3 files changed

+73
-28
lines changed

3 files changed

+73
-28
lines changed

src/app/features/TimeEntries/TimeEntriesList/TimeEntriesList.tsx

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useState } from "react";
22
import { EmptyState } from "./EmptyState";
33
import { useAppSelector } from "../../../hooks";
4-
import { formatElapsedTime } from "../../../utils";
4+
import { formatElapsedTime, hoursToMs } from "../../../utils";
55
import { GroupedTimeEntryRow } from "./GroupedTimeEntryRow";
66
import {
77
selectTimeEntriesGroupedByDate,
@@ -88,15 +88,11 @@ function DayHeader({
8888
<span className="mr-2 text-lg font-semibold text-neutral-700 opacity-50">
8989
{formatElapsedTime(elapsedTimePerDay)}
9090
</span>
91-
92-
<div className="flex items-center text-xs font-semibold">
93-
<span className="rounded rounded-r-none border border-neutral-500 bg-neutral-500 pl-2 pr-1 text-white">
94-
Logged
95-
</span>
96-
<span className="flex items-center rounded rounded-l-none border bg-neutral-100 pl-1 pr-2 text-neutral-700 opacity-50">
97-
{formatElapsedTime(reportedTimePerDay)}
98-
</span>
99-
</div>
91+
<LoggedTimeBadge
92+
label="Logged"
93+
reportedTimePerDay={reportedTimePerDay}
94+
targetHours={6}
95+
/>
10096
</div>
10197
);
10298
} else {
@@ -144,3 +140,51 @@ const PaginationButtons = ({
144140
</div>
145141
);
146142
};
143+
144+
// TODO: move to separate file
145+
export const LoggedTimeBadge = ({
146+
label,
147+
reportedTimePerDay,
148+
targetHours,
149+
}: {
150+
label: string;
151+
targetHours: number;
152+
reportedTimePerDay: number;
153+
}) => {
154+
const percentage = (reportedTimePerDay / hoursToMs(targetHours)) * 100;
155+
156+
const colors = {
157+
low: "#ba4244",
158+
medium: "#d2812c",
159+
high: "#59b173",
160+
beyond: "#546cc0",
161+
};
162+
163+
return (
164+
<div className="relative" title={`${percentage.toFixed(0)}% of target`}>
165+
<div className="flex items-center text-xs font-semibold">
166+
<span className="rounded rounded-r-none rounded-b-none border border-neutral-500 bg-neutral-500 pl-2 pr-1 text-white">
167+
{label}
168+
</span>
169+
<span className="flex items-center rounded rounded-l-none rounded-b-none border bg-neutral-100 pl-1 pr-2 text-neutral-700 opacity-50">
170+
{formatElapsedTime(reportedTimePerDay)}
171+
</span>
172+
</div>
173+
<div className="absolute w-[100%] h-1 rounded-t-none rounded border-0 border-neutral-200 bg-neutral-100">
174+
<div
175+
className={`h-full rounded rounded-t-none`}
176+
style={{
177+
width: `${Math.min(percentage, 100)}%`,
178+
backgroundColor:
179+
percentage < 50
180+
? colors.low
181+
: percentage < 80
182+
? colors.medium
183+
: colors.high,
184+
borderBottomRightRadius: percentage < 100 ? "0px" : "4px",
185+
}}
186+
/>
187+
</div>
188+
</div>
189+
);
190+
};

src/app/features/TimeEntries/components/LoggedStats/LoggedStats.tsx

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { CircleSlash2, Frown, Laugh, Meh, Smile } from "lucide-react";
1+
import { Frown, Laugh, Meh, Smile } from "lucide-react";
22
import { useAppSelector } from "../../../../hooks";
33
import {
44
selectLast7DaysReportedTime,
55
selectTodayReportedTime,
66
} from "../../store";
7-
import { formatElapsedTimeHM, msToHours } from "../../../../utils";
7+
import { msToHours } from "../../../../utils";
88
import { RootState } from "../../../../store/store";
9+
import { LoggedTimeBadge } from "../../TimeEntriesList";
910

1011
const WORKING_DAYS = 5;
1112

@@ -27,24 +28,20 @@ export const TimeReportedStats = () => {
2728
return (
2829
<div className="flex gap-3 mobile:flex-col ml-auto">
2930
<div className="flex gap-1 items-center">
30-
<div className="text-[9px] bg-neutral-300 text-neutral-600 rounded px-1 leading-none py-0.5 font-semibold">
31-
TODAY
32-
</div>
33-
<div>
34-
<span className="font-medium text-neutral-600">
35-
{formatElapsedTimeHM(todayReportedTime)}
36-
</span>
37-
/<span className="text-[11px] text-neutral-600">06:00</span>
38-
</div>
31+
<LoggedTimeBadge
32+
label="Today"
33+
reportedTimePerDay={todayReportedTime}
34+
// TODO: move constant to settings
35+
targetHours={6}
36+
/>
3937
</div>
4038
<div className="flex gap-1 items-center">
41-
<div className="text-[9px] bg-neutral-300 text-neutral-600 rounded px-1 leading-none py-0.5 font-semibold">
42-
WEEK
43-
</div>
44-
<CircleSlash2 className="w-2 h-2 text-neutral-600" />
45-
<span className="text-neutral-600 font-medium">
46-
{formatElapsedTimeHM(last7DaysReportedTime / WORKING_DAYS)}
47-
</span>
39+
<LoggedTimeBadge
40+
label="Week"
41+
reportedTimePerDay={last7DaysReportedTime}
42+
targetHours={6 * 5}
43+
/>
44+
{/* // TODO: refactor this icon logic */}
4845
{last7DaysStatus === "BAD" && (
4946
<Frown className="w-3 h-3 text-red-600" />
5047
)}

src/app/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ export const msToHours = (ms: number) => {
2828
return ms / (1000 * 60 * 60);
2929
};
3030

31+
export const hoursToMs = (hours: number) => {
32+
return hours * 60 * 60 * 1000;
33+
};
34+
3135
export const parseElapsedTime = (timeString: string): number => {
3236
const [hours, minutes, seconds] = timeString.split(":").map(Number);
3337
const totalMilliseconds = (hours * 60 * 60 + minutes * 60 + seconds) * 1000;

0 commit comments

Comments
 (0)