Skip to content

Commit 3b6aca9

Browse files
authored
Merge pull request #463 from openscript-ch/444-inconsistent-birthdate-display-in-participant-view-vs-edit-mode
fix: timezone date handling
2 parents dff2237 + 6f5fad1 commit 3b6aca9

File tree

11 files changed

+78
-68
lines changed

11 files changed

+78
-68
lines changed

.changeset/large-eyes-strive.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@quassel/frontend": patch
3+
"@quassel/utils": patch
4+
---
5+
6+
Enhance timezone handling

apps/frontend/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"@quassel/ui": "workspace:*",
2828
"@quassel/utils": "workspace:*",
2929
"@tanstack/react-query": "^5.85.3",
30-
"@tanstack/react-router": "^1.131.13",
30+
"@tanstack/react-router": "^1.131.14",
3131
"nanostores": "^1.0.1",
3232
"openapi-fetch": "0.14.0",
3333
"openapi-react-query": "0.5.0",
@@ -37,8 +37,8 @@
3737
"devDependencies": {
3838
"@anolilab/unplugin-favicons": "^1.0.5",
3939
"@sinclair/typebox": "^0.34.39",
40-
"@tanstack/router-devtools": "^1.131.13",
41-
"@tanstack/router-plugin": "^1.131.13",
40+
"@tanstack/router-devtools": "^1.131.14",
41+
"@tanstack/router-plugin": "^1.131.15",
4242
"@testing-library/jest-dom": "^6.7.0",
4343
"@testing-library/react": "^16.3.0",
4444
"@types/react": "^19.1.10",

apps/frontend/src/routes/_auth/administration/participants/edit.$id.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { $api } from "../../../../stores/api";
33
import { useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
44
import { Button, DateInput, Stack, TextInput, useForm } from "@quassel/ui";
55
import { useEffect } from "react";
6+
import { toMantineUTCDate } from "@quassel/utils";
67

78
type FormValues = {
89
id: string;
@@ -39,7 +40,7 @@ function AdministrationParticipantsEdit() {
3940
useEffect(() => {
4041
const { birthday, id } = participant.data;
4142

42-
f.setValues({ birthday, id: id.toString() });
43+
f.setValues({ birthday: birthday && toMantineUTCDate(birthday), id: id.toString() });
4344
}, [participant.isSuccess, participant.data]);
4445

4546
return (

apps/frontend/src/routes/_auth/administration/participants/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ function AdministrationParticipantsIndex() {
4343
{participants.data?.map((p) => (
4444
<Table.Tr key={p.id}>
4545
<Table.Td>{p.id}</Table.Td>
46-
<Table.Td>{p.birthday && time(new Date(p.birthday))}</Table.Td>
46+
<Table.Td>{p.birthday && time(new Date(p.birthday), { timeZone: "UTC" })}</Table.Td>
4747
<Table.Td>
4848
<Button variant="default" renderRoot={(props) => <Link to={`/administration/participants/edit/${p.id}`} {...props} />}>
4949
Edit

apps/frontend/src/routes/_auth/administration/questionnaires/edit.$id.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { useEffect } from "react";
66
import { QuestionnaireEntries } from "../../../../components/questionnaire/QuestionnaireEntries";
77
import { format, i18n } from "../../../../stores/i18n";
88
import { useStore } from "@nanostores/react";
9+
import { toMantineUTCDate } from "@quassel/utils";
910

1011
type FormValues = {
1112
startedAt: string;
@@ -58,7 +59,7 @@ function AdministrationQuestionnairesEdit() {
5859

5960
useEffect(() => {
6061
const { startedAt, endedAt, title, remark } = data;
61-
f.initialize({ startedAt, endedAt, title, remark });
62+
f.initialize({ startedAt: toMantineUTCDate(startedAt), endedAt: toMantineUTCDate(endedAt), title, remark });
6263
}, [isSuccess, data]);
6364

6465
return (
@@ -68,7 +69,7 @@ function AdministrationQuestionnairesEdit() {
6869
<Table.Tr>
6970
<Table.Th>{t.labelParticipant}</Table.Th>
7071
<Table.Td>{data.participant.id}</Table.Td>
71-
<Table.Td>{data.participant.birthday && time(new Date(data.participant.birthday))}</Table.Td>
72+
<Table.Td>{data.participant.birthday && time(new Date(data.participant.birthday), { timeZone: "UTC" })}</Table.Td>
7273
</Table.Tr>
7374
</Table.Tbody>
7475
</Table>

apps/frontend/src/routes/_auth/administration/studies/$id.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import { useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
44
import { Stack, Table, Title, Button } from "@quassel/ui";
55
import { useStore } from "@nanostores/react";
66
import { $session } from "../../../../stores/session";
7+
import { format } from "../../../../stores/i18n";
78

89
function AdministrationStudiesEdit() {
10+
const { time } = useStore(format);
911
const sessionStore = useStore($session);
1012
const p = Route.useParams();
1113
const q = useQueryClient();
@@ -46,7 +48,7 @@ function AdministrationStudiesEdit() {
4648
{study.data?.participants.map((p) => (
4749
<Table.Tr key={p.id}>
4850
<Table.Td>{p.id}</Table.Td>
49-
<Table.Td>{p.birthday}</Table.Td>
51+
<Table.Td>{p.birthday && time(new Date(p.birthday), { timeZone: "UTC" })}</Table.Td>
5052
<Table.Td>
5153
{sessionStore.role === "ADMIN" && (
5254
<Button

apps/frontend/src/routes/_auth/questionnaire/_questionnaire/participant.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ function QuestionnaireParticipant() {
5757
<Table.Tr>
5858
<Table.Th>{t.participantLabel}</Table.Th>
5959
<Table.Td>{questionnaire?.participant.id}</Table.Td>
60-
<Table.Td>{birthday ? time(new Date(birthday)) : <i>{t.birthdateMissing}</i>}</Table.Td>
60+
<Table.Td>{birthday ? time(new Date(birthday), { timeZone: "UTC" }) : <i>{t.birthdateMissing}</i>}</Table.Td>
6161
</Table.Tr>
6262
<Table.Tr>
6363
<Table.Th>{t.studyLabel}</Table.Th>

apps/website/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"dependencies": {
1313
"@fontsource-variable/montserrat": "^5.2.6",
1414
"@fontsource-variable/onest": "^5.2.9",
15-
"astro": "^5.13.0",
15+
"astro": "^5.13.2",
1616
"reveal.js": "^5.2.1"
1717
},
1818
"devDependencies": {

libs/utils/src/date.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export function formatDate(date: Date, dayjsFormatTemplate: string) {
1212
}
1313

1414
export const getTime = (date: Date) => formatDate(date, "HH:mm");
15+
export const toMantineUTCDate = (date: string) => dayjs(date).utc().format("YYYY-MM-DD");
1516

1617
export const getNext = (unit: dayjs.ManipulateType, date: Date) => dayjs(date).utc().add(1, unit).startOf(unit).toDate();
1718

libs/utils/src/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
export { formatDate, getTime, getDateFromTimeAndWeekday, getNext, isSameOrAfter, isSame, getStartOf, getEndOf } from "./date";
2-
3-
export { type Gap, type GapsPerDay, groupByWeekday, resolveGaps, entriesByInterval } from "./entry";
1+
export * from "./date";
2+
export * from "./entry";

0 commit comments

Comments
 (0)