Skip to content

Commit 7ce0c03

Browse files
committed
Switch to CoachingSession.date as a string type and convert to DateTime type at render or calculation time to prevent TypeError exceptions and down-casting issues to just a Date.
1 parent 2464ac5 commit 7ce0c03

11 files changed

+287
-177
lines changed

package-lock.json

+2-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
"class-variance-authority": "^0.7.0",
3434
"clsx": "^2.1.0",
3535
"cmdk": "^0.2.1",
36-
"date-fns": "^3.3.1",
3736
"lucide-react": "^0.314.0",
3837
"next": "^14.2.3",
3938
"next-themes": "^0.2.1",

src/app/coaching-sessions/[id]/page.tsx

-3
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ import { Action } from "@/types/action";
6161
import { createAction, deleteAction, updateAction } from "@/lib/api/actions";
6262
import { DateTime } from "ts-luxon";
6363
import { CoachingSessionTitle } from "@/components/ui/coaching-sessions/coaching-session-title";
64-
import { SessionTitle, SessionTitleStyle } from "@/types/session-title";
6564

6665
// export const metadata: Metadata = {
6766
// title: "Coaching Session",
@@ -228,8 +227,6 @@ export default function CoachingSessionsPage() {
228227
<div className="h-full flex-col md:flex">
229228
<div className="flex flex-col items-start justify-between space-y-2 py-4 px-4 sm:flex-row sm:items-center sm:space-y-0 md:h-16">
230229
<CoachingSessionTitle
231-
coachingSession={coachingSession}
232-
coachingRelationship={coachingRelationship}
233230
locale={siteConfig.locale}
234231
style={siteConfig.titleStyle}
235232
onRender={handleTitleRender}

src/components/ui/coaching-sessions/coaching-session-title.tsx

+30-13
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,58 @@
22

33
import { useEffect, useState } from "react";
44
import {
5+
defaultSessionTitle,
56
generateSessionTitle,
67
SessionTitle,
78
SessionTitleStyle,
89
} from "@/types/session-title";
9-
import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship_with_user_names";
10-
import { CoachingSession } from "@/types/coaching-session";
10+
import {
11+
CoachingRelationshipWithUserNames,
12+
coachingRelationshipWithUserNamesToString,
13+
} from "@/types/coaching_relationship_with_user_names";
14+
import {
15+
CoachingSession,
16+
coachingSessionToString,
17+
} from "@/types/coaching-session";
18+
import { useAppStateStore } from "@/lib/providers/app-state-store-provider";
1119

1220
const CoachingSessionTitle: React.FC<{
13-
coachingSession: CoachingSession;
14-
coachingRelationship: CoachingRelationshipWithUserNames;
1521
locale: string | "us";
1622
style: SessionTitleStyle;
1723
onRender: (sessionTitle: string) => void;
18-
}> = ({ coachingSession, coachingRelationship, locale, style, onRender }) => {
24+
}> = ({ locale, style, onRender }) => {
25+
const [isLoading, setIsLoading] = useState(true);
1926
const [sessionTitle, setSessionTitle] = useState<SessionTitle>();
27+
const { coachingSession, coachingRelationship } = useAppStateStore(
28+
(state) => state
29+
);
30+
useState<CoachingRelationshipWithUserNames>();
2031

2132
useEffect(() => {
22-
async function getSessionTitle() {
23-
const sessionTitle = generateSessionTitle(
33+
if (coachingSession && coachingRelationship) {
34+
setIsLoading(false);
35+
const title = generateSessionTitle(
2436
coachingSession,
2537
coachingRelationship,
2638
style,
2739
locale
2840
);
29-
setSessionTitle(sessionTitle);
30-
console.debug("sessionTitle: " + JSON.stringify(sessionTitle));
31-
onRender(sessionTitle.title);
41+
setSessionTitle(title);
42+
onRender(title.title);
3243
}
44+
}, [coachingSession, coachingRelationship, style, locale, onRender]);
3345

34-
getSessionTitle();
35-
}, [coachingSession, coachingRelationship]);
46+
if (isLoading) {
47+
return (
48+
<h4 className="font-semibold break-words w-full px-2 md:px-4 lg:px-6 md:text-clip">
49+
{defaultSessionTitle().title}
50+
</h4>
51+
);
52+
}
3653

3754
return (
3855
<h4 className="font-semibold break-words w-full px-2 md:px-4 lg:px-6 md:text-clip">
39-
{sessionTitle ? sessionTitle.title : "Untitled Session"}
56+
{sessionTitle ? sessionTitle.title : defaultSessionTitle().title}
4057
</h4>
4158
);
4259
};

src/components/ui/dashboard/select-coaching-session.tsx

+19-8
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import {
3333
coachingRelationshipWithUserNamesToString,
3434
getCoachingRelationshipById,
3535
} from "@/types/coaching_relationship_with_user_names";
36-
import { Id } from "@/types/general";
36+
import { getDateTimeFromString, Id } from "@/types/general";
3737
import { Organization } from "@/types/organization";
3838
import Link from "next/link";
3939
import { useEffect, useState } from "react";
@@ -220,37 +220,48 @@ export function SelectCoachingSession({
220220
defaultValue="today"
221221
disabled={!relationshipId}
222222
value={coachingSessionId}
223-
// TODO: set CoachingSession in the app state!!
224223
onValueChange={handleSetCoachingSession}
225224
>
226225
<SelectTrigger id="session">
227226
<SelectValue placeholder="Select coaching session" />
228227
</SelectTrigger>
229228
<SelectContent>
230229
{coachingSessions.some(
231-
(session) => session.date < DateTime.now()
230+
(session) =>
231+
getDateTimeFromString(session.date) < DateTime.now()
232232
) && (
233233
<SelectGroup>
234234
<SelectLabel>Previous Sessions</SelectLabel>
235235
{coachingSessions
236-
.filter((session) => session.date < DateTime.now())
236+
.filter(
237+
(session) =>
238+
getDateTimeFromString(session.date) < DateTime.now()
239+
)
237240
.map((session) => (
238241
<SelectItem value={session.id} key={session.id}>
239-
{session.date.toLocaleString(DateTime.DATETIME_FULL)}
242+
{getDateTimeFromString(session.date).toLocaleString(
243+
DateTime.DATETIME_FULL
244+
)}
240245
</SelectItem>
241246
))}
242247
</SelectGroup>
243248
)}
244249
{coachingSessions.some(
245-
(session) => session.date >= DateTime.now()
250+
(session) =>
251+
getDateTimeFromString(session.date) >= DateTime.now()
246252
) && (
247253
<SelectGroup>
248254
<SelectLabel>Upcoming Sessions</SelectLabel>
249255
{coachingSessions
250-
.filter((session) => session.date >= DateTime.now())
256+
.filter(
257+
(session) =>
258+
getDateTimeFromString(session.date) >= DateTime.now()
259+
)
251260
.map((session) => (
252261
<SelectItem value={session.id} key={session.id}>
253-
{session.date.toLocaleString(DateTime.DATETIME_FULL)}
262+
{getDateTimeFromString(session.date).toLocaleString(
263+
DateTime.DATETIME_FULL
264+
)}
254265
</SelectItem>
255266
))}
256267
</SelectGroup>

src/lib/api/coaching-relationships.ts

+57-31
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import {
66
defaultCoachingRelationshipWithUserNames,
77
defaultCoachingRelationshipsWithUserNames,
88
isCoachingRelationshipWithUserNames,
9-
isCoachingRelationshipWithUserNamesArray
9+
isCoachingRelationshipWithUserNamesArray,
10+
parseCoachingRelationshipWithUserNames,
1011
} from "@/types/coaching_relationship_with_user_names";
1112
import { Id } from "@/types/general";
1213
import { AxiosError, AxiosResponse } from "axios";
@@ -17,39 +18,51 @@ export const fetchCoachingRelationshipWithUserNames = async (
1718
): Promise<CoachingRelationshipWithUserNames> => {
1819
const axios = require("axios");
1920

20-
var relationship: CoachingRelationshipWithUserNames = defaultCoachingRelationshipWithUserNames();
21+
var relationship: CoachingRelationshipWithUserNames =
22+
defaultCoachingRelationshipWithUserNames();
2123
var err: string = "";
2224

2325
const data = await axios
24-
.get(`http://localhost:4000/organizations/${organization_id}/coaching_relationships/${relationship_id}`, {
25-
withCredentials: true,
26-
setTimeout: 5000, // 5 seconds before timing out trying to log in with the backend
27-
headers: {
28-
"X-Version": "0.0.1",
29-
},
30-
})
26+
.get(
27+
`http://localhost:4000/organizations/${organization_id}/coaching_relationships/${relationship_id}`,
28+
{
29+
withCredentials: true,
30+
setTimeout: 5000, // 5 seconds before timing out trying to log in with the backend
31+
headers: {
32+
"X-Version": "0.0.1",
33+
},
34+
}
35+
)
3136
.then(function (response: AxiosResponse) {
3237
// handle success
33-
if (isCoachingRelationshipWithUserNames(response.data.data)) {
34-
relationship = response.data.data;
38+
const relationshipData = response.data.data;
39+
if (isCoachingRelationshipWithUserNames(relationshipData)) {
40+
relationship = parseCoachingRelationshipWithUserNames(relationshipData);
3541
}
3642
})
3743
.catch(function (error: AxiosError) {
3844
// handle error
3945
console.error(error.response?.status);
4046
if (error.response?.status == 401) {
41-
err = "Retrieval of CoachingRelationshipWithUserNames failed: unauthorized.";
47+
err =
48+
"Retrieval of CoachingRelationshipWithUserNames failed: unauthorized.";
4249
} else if (error.response?.status == 500) {
43-
err = "Retrieval of CoachingRelationshipWithUserNames failed, system error: " + error.response.data;
50+
err =
51+
"Retrieval of CoachingRelationshipWithUserNames failed, system error: " +
52+
error.response.data;
4453
} else {
45-
err = `Retrieval of CoachingRelationshipWithUserNames(` + relationship_id + `) failed: ` + error.response?.data;
54+
err =
55+
`Retrieval of CoachingRelationshipWithUserNames(` +
56+
relationship_id +
57+
`) failed: ` +
58+
error.response?.data;
4659
}
4760
});
4861

49-
if (err) {
50-
console.error(err);
51-
throw err;
52-
}
62+
if (err) {
63+
console.error(err);
64+
throw err;
65+
}
5366

5467
return relationship;
5568
};
@@ -59,40 +72,53 @@ export const fetchCoachingRelationshipsWithUserNames = async (
5972
): Promise<[CoachingRelationshipWithUserNames[], string]> => {
6073
const axios = require("axios");
6174

62-
var relationships: CoachingRelationshipWithUserNames[] = defaultCoachingRelationshipsWithUserNames();
75+
var relationships: CoachingRelationshipWithUserNames[] =
76+
defaultCoachingRelationshipsWithUserNames();
6377
var err: string = "";
6478

6579
const data = await axios
66-
.get(`http://localhost:4000/organizations/${organizationId}/coaching_relationships`, {
67-
withCredentials: true,
68-
setTimeout: 5000, // 5 seconds before timing out trying to log in with the backend
69-
headers: {
70-
"X-Version": "0.0.1",
71-
},
72-
})
80+
.get(
81+
`http://localhost:4000/organizations/${organizationId}/coaching_relationships`,
82+
{
83+
withCredentials: true,
84+
setTimeout: 5000, // 5 seconds before timing out trying to log in with the backend
85+
headers: {
86+
"X-Version": "0.0.1",
87+
},
88+
}
89+
)
7390
.then(function (response: AxiosResponse) {
7491
// handle success
7592
console.debug(response);
7693
if (isCoachingRelationshipWithUserNamesArray(response.data.data)) {
7794
relationships = response.data.data;
7895
console.debug(
79-
`CoachingRelationshipsWithUserNames: ` + coachingRelationshipsWithUserNamesToString(relationships) + `.`
96+
`CoachingRelationshipsWithUserNames: ` +
97+
coachingRelationshipsWithUserNamesToString(relationships) +
98+
`.`
8099
);
81100
}
82101
})
83102
.catch(function (error: AxiosError) {
84103
// handle error
85104
console.error(error.response?.status);
86105
if (error.response?.status == 401) {
87-
console.error("Retrieval of CoachingRelationshipsWithUserNames failed: unauthorized.");
88-
err = "Retrieval of CoachingRelationshipsWithUserNames failed: unauthorized.";
106+
console.error(
107+
"Retrieval of CoachingRelationshipsWithUserNames failed: unauthorized."
108+
);
109+
err =
110+
"Retrieval of CoachingRelationshipsWithUserNames failed: unauthorized.";
89111
} else {
90112
console.log(error);
91113
console.error(
92-
`Retrieval of CoachingRelationshipsWithUserNames by organization Id (` + organizationId + `) failed.`
114+
`Retrieval of CoachingRelationshipsWithUserNames by organization Id (` +
115+
organizationId +
116+
`) failed.`
93117
);
94118
err =
95-
`Retrieval of CoachingRealtionshipsWithUserNames by organization Id (` + organizationId + `) failed.`;
119+
`Retrieval of CoachingRealtionshipsWithUserNames by organization Id (` +
120+
organizationId +
121+
`) failed.`;
96122
}
97123
});
98124

src/lib/api/coaching-sessions.ts

+15-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
CoachingSession,
55
isCoachingSessionArray,
66
parseCoachingSession,
7-
sortCoachingSessionArray
7+
sortCoachingSessionArray,
88
} from "@/types/coaching-session";
99
import { Id, SortOrder } from "@/types/general";
1010
import { AxiosError, AxiosResponse } from "axios";
@@ -21,8 +21,8 @@ export const fetchCoachingSessions = async (
2121
// TODO: for now we hardcode a 2 month window centered around now,
2222
// eventually we want to make this be configurable somewhere
2323
// (either on the page or elsewhere)
24-
const fromDate = DateTime.now().minus({month: 1}).toISODate();
25-
const toDate = DateTime.now().plus({month: 1}).toISODate();
24+
const fromDate = DateTime.now().minus({ month: 1 }).toISODate();
25+
const toDate = DateTime.now().plus({ month: 1 }).toISODate();
2626

2727
console.debug("fromDate: " + fromDate);
2828
console.debug("toDate: " + toDate);
@@ -32,7 +32,7 @@ export const fetchCoachingSessions = async (
3232
params: {
3333
coaching_relationship_id: coachingRelationshipId,
3434
from_date: fromDate,
35-
to_date: toDate
35+
to_date: toDate,
3636
},
3737
withCredentials: true,
3838
setTimeout: 5000, // 5 seconds before timing out trying to log in with the backend
@@ -45,10 +45,13 @@ export const fetchCoachingSessions = async (
4545
var sessions_data = response.data.data;
4646
if (isCoachingSessionArray(sessions_data)) {
4747
// Sort returned sessions in ascending order by their date field
48-
sessions_data = sortCoachingSessionArray(sessions_data, SortOrder.Ascending);
48+
sessions_data = sortCoachingSessionArray(
49+
sessions_data,
50+
SortOrder.Ascending
51+
);
4952

5053
sessions_data.forEach((session_data: any) => {
51-
coaching_sessions.push(parseCoachingSession(session_data))
54+
coaching_sessions.push(parseCoachingSession(session_data));
5255
});
5356
}
5457
})
@@ -61,10 +64,14 @@ export const fetchCoachingSessions = async (
6164
} else {
6265
console.log(error);
6366
console.error(
64-
`Retrieval of CoachingSessions by coaching relationship Id (` + coachingRelationshipId + `) failed.`
67+
`Retrieval of CoachingSessions by coaching relationship Id (` +
68+
coachingRelationshipId +
69+
`) failed.`
6570
);
6671
err =
67-
`Retrieval of CoachingSessions by coaching relationship Id (` + coachingRelationshipId + `) failed.`;
72+
`Retrieval of CoachingSessions by coaching relationship Id (` +
73+
coachingRelationshipId +
74+
`) failed.`;
6875
}
6976
});
7077

0 commit comments

Comments
 (0)