Skip to content

Commit 0c0fc7d

Browse files
committed
feat: change max time unit to a dropdown
1 parent 2b7ab59 commit 0c0fc7d

14 files changed

Lines changed: 104 additions & 56 deletions

File tree

public/locales/en/common.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,16 @@
231231
"defaultDayRange": "Default day range",
232232
"language": "Language",
233233
"smoothCharts": "Smooth charts",
234-
"timeInHours": "Convert large time units to hours",
235-
"title": "Settings"
234+
"title": "Settings",
235+
"timeUnits": {
236+
"label": "Largest displayed time unit",
237+
"y": "Year",
238+
"mo": "Month",
239+
"d": "Day",
240+
"h": "Hour",
241+
"min": "Minute",
242+
"s": "Second"
243+
}
236244
},
237245
"title": "My profile",
238246
"username": "Username: {{username}}"

public/locales/fi/common.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,16 @@
231231
"defaultDayRange": "Oletuksena näytettävä aikaväli",
232232
"language": "Kieli",
233233
"smoothCharts": "Pehmeät kaaviot",
234-
"timeInHours": "Muunna suuret aikayksiköt tunteihin",
235-
"title": "Asetukset"
234+
"title": "Asetukset",
235+
"timeUnits": {
236+
"label": "Suurin näytettävä aikayksikkö",
237+
"y": "Vuosi",
238+
"mo": "Kuukausi",
239+
"d": "Päivä",
240+
"h": "Tunti",
241+
"min": "Minuutti",
242+
"s": "Sekuntti"
243+
}
236244
},
237245
"title": "Profiili",
238246
"username": "Käyttäjänimi: {{username}}"

src/app/[locale]/profile/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { AuthTokenField } from "./AuthTokenField";
1515
import { redirect } from "next/navigation";
1616
import { getMe } from "../../../api/usersApi";
1717
import ChangeUsernameForm from "../../../components/ChangeUsernameForm";
18-
import { TimeInHoursSelector } from "../../../components/TimeInHoursSelector/TimeInHoursSelector";
18+
import { MaxTimeUnitSelector } from "../../../components/MaxTimeUnitSelector/MaxTimeUnitSelector";
1919

2020
export type ProfilePageProps = {
2121
username: string;
@@ -130,7 +130,7 @@ export default async function ProfilePage({
130130
<SmoothChartsSelector />
131131
<LanguageSelector locale={locale} />
132132
<DefaultDayRangeSelector />
133-
<TimeInHoursSelector />
133+
<MaxTimeUnitSelector />
134134
</Stack>
135135
</Stack>
136136
);

src/components/Dashboard.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import {
1919
getDayCount,
2020
isDayRange,
2121
prettyDuration,
22-
TimeUnit,
2322
} from "../utils/dateUtils";
2423
import { TopProjects } from "./TopProjects/TopProjects";
2524
import { sumBy } from "../utils/arrayUtils";
@@ -57,8 +56,7 @@ export const Dashboard = ({
5756
initialActivity,
5857
}: DashboardProps) => {
5958
const { t } = useTranslation();
60-
const { smoothCharts, defaultDayRange, timeInHours } = useSettings();
61-
const maxTimeUnit: TimeUnit = timeInHours ? "h" : "y";
59+
const { smoothCharts, defaultDayRange, maxTimeUnit } = useSettings();
6260

6361
const [statisticsRange, setStatisticsRange] = useState<DayRange>(
6462
defaultDayRange ?? "week",

src/components/DefaultDayRangeSelector/DefaultDayRangeSelector.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,22 @@ import { useSettings } from "../../hooks/useSettings";
55
import { DayRange } from "../../utils/dateUtils";
66
import { useTranslation } from "react-i18next";
77
import { useRouter } from "next/navigation";
8+
import { useId } from "react";
89

910
export const DefaultDayRangeSelector = () => {
1011
const { defaultDayRange, setDefaultDayRange } = useSettings();
1112
const { t } = useTranslation();
1213
const router = useRouter();
1314

15+
const id = useId();
16+
1417
return (
1518
<Group>
16-
<Text>{t("profile.settings.defaultDayRange")}</Text>
19+
<label htmlFor={id}>
20+
<Text>{t("profile.settings.defaultDayRange")}</Text>
21+
</label>
1722
<SegmentedControl
23+
id={id}
1824
data={[
1925
{ label: t("dashboard.timeFilters.week"), value: "week" },
2026
{ label: t("dashboard.timeFilters.month"), value: "month" },

src/components/LanguageSelector/LanguageSelector.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
import { useSettings } from "../../hooks/useSettings";
1111
import { Locales } from "../../i18next";
1212
import { useTranslation } from "react-i18next";
13+
import { useId } from "react";
1314

1415
type LanguageSelectorType = "segmented" | "dropdown";
1516

@@ -29,6 +30,8 @@ export const LanguageSelector = ({
2930
const { setLanguage } = useSettings();
3031
const { t } = useTranslation();
3132

33+
const id = useId();
34+
3235
const data = [
3336
{ label: "🇺🇸 English", value: "en" },
3437
{ label: "🇫🇮 Suomi", value: "fi" },
@@ -42,13 +45,15 @@ export const LanguageSelector = ({
4245
const Component =
4346
type === "segmented" ? (
4447
<SegmentedControl
48+
id={id}
4549
size={size}
4650
data={data}
4751
value={locale}
4852
onChange={onChange}
4953
/>
5054
) : (
5155
<Select
56+
id={id}
5257
size={size}
5358
data={data}
5459
value={locale}
@@ -59,7 +64,9 @@ export const LanguageSelector = ({
5964

6065
return showLabel ? (
6166
<Group>
62-
{<Text>{t("profile.settings.language")}</Text>}
67+
<label htmlFor={id}>
68+
<Text>{t("profile.settings.language")}</Text>
69+
</label>
6370
{Component}
6471
</Group>
6572
) : (
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"use client";
2+
3+
import { useTranslation } from "react-i18next";
4+
import { useSettings } from "../../hooks/useSettings";
5+
import { Group, Select, Text } from "@mantine/core";
6+
import { TimeUnit, timeUnits } from "../../utils/dateUtils";
7+
import { useId } from "react";
8+
9+
export const MaxTimeUnitSelector = () => {
10+
const { maxTimeUnit, setMaxTimeUnit } = useSettings();
11+
const { t } = useTranslation();
12+
13+
const id = useId();
14+
15+
return (
16+
<Group>
17+
<label htmlFor={id}>
18+
<Text>{t("profile.settings.timeUnits.label")}</Text>
19+
</label>
20+
<Select
21+
id={id}
22+
value={maxTimeUnit}
23+
data={timeUnits.map((x) => ({
24+
value: x.suffix,
25+
label: t(`profile.settings.timeUnits.${x.suffix}`),
26+
}))}
27+
onChange={(v) => {
28+
if (v) {
29+
setMaxTimeUnit(v as unknown as TimeUnit);
30+
}
31+
}}
32+
/>
33+
</Group>
34+
);
35+
};

src/components/SmoothChartsSelector/SmoothChartsSelector.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
"use client";
22

3-
import { Checkbox, Group } from "@mantine/core";
3+
import { Checkbox, Group, Text } from "@mantine/core";
44
import { useSettings } from "../../hooks/useSettings";
55
import { useTranslation } from "react-i18next";
6+
import { useId } from "react";
67

78
export const SmoothChartsSelector = () => {
89
const { smoothCharts, setSmoothCharts } = useSettings();
910
const { t } = useTranslation();
1011

12+
const id = useId();
13+
1114
return (
1215
<Group>
16+
<label htmlFor={id}>
17+
<Text>{t("profile.settings.smoothCharts")}</Text>
18+
</label>
1319
<Checkbox
20+
id={id}
1421
checked={smoothCharts}
1522
onChange={(e) => {
1623
setSmoothCharts(e.target.checked);
1724
}}
18-
label={t("profile.settings.smoothCharts")}
1925
/>
2026
</Group>
2127
);

src/components/TimeInHoursSelector/TimeInHoursSelector.tsx

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/contexts/SettingsContext.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { createContext } from "react";
2-
import { DayRange } from "../utils/dateUtils";
2+
import { DayRange, TimeUnit } from "../utils/dateUtils";
33
import { Locales } from "../i18next";
44
import { MantineColorScheme } from "@mantine/core";
5+
import { DEFAULT_MAX_TIME_UNIT } from "../utils/constants";
56

67
interface SettingsContextValue {
78
smoothCharts: boolean;
@@ -13,8 +14,8 @@ interface SettingsContextValue {
1314
setColorScheme: (colorScheme: MantineColorScheme) => void;
1415
defaultDayRange?: DayRange;
1516
setDefaultDayRange: (defaultDayRange: DayRange) => void;
16-
timeInHours: boolean;
17-
setTimeInHours: (timeInHours: boolean) => void;
17+
maxTimeUnit: TimeUnit;
18+
setMaxTimeUnit: (maxTimeUnit: TimeUnit) => void;
1819
}
1920

2021
const defaultCallback = () => {
@@ -30,8 +31,8 @@ const defaultValue: SettingsContextValue = {
3031
setColorScheme: defaultCallback,
3132
defaultDayRange: undefined,
3233
setDefaultDayRange: defaultCallback,
33-
timeInHours: false,
34-
setTimeInHours: defaultCallback,
34+
maxTimeUnit: DEFAULT_MAX_TIME_UNIT,
35+
setMaxTimeUnit: defaultCallback,
3536
};
3637

3738
export const SettingsContext = createContext(defaultValue);

0 commit comments

Comments
 (0)