Skip to content

Commit f0e3bb0

Browse files
authored
Merge pull request #35 from Jim-Hodapp-Coaching/add_coaching_session_title
2 parents 29f47cd + 7ce0c03 commit f0e3bb0

15 files changed

+615
-182
lines changed

package-lock.json

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
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

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import { ActionsList } from "@/components/ui/coaching-sessions/actions-list";
6060
import { Action } from "@/types/action";
6161
import { createAction, deleteAction, updateAction } from "@/lib/api/actions";
6262
import { DateTime } from "ts-luxon";
63+
import { CoachingSessionTitle } from "@/components/ui/coaching-sessions/coaching-session-title";
6364

6465
// export const metadata: Metadata = {
6566
// title: "Coaching Session",
@@ -72,26 +73,28 @@ export default function CoachingSessionsPage() {
7273
const [note, setNote] = useState<string>("");
7374
const [syncStatus, setSyncStatus] = useState<string>("");
7475
const { userId } = useAuthStore((state) => state);
75-
const { coachingSessionId } = useAppStateStore((state) => state);
76+
const { coachingSession, coachingRelationship } = useAppStateStore(
77+
(state) => state
78+
);
7679

7780
useEffect(() => {
7881
async function fetchNote() {
79-
if (!coachingSessionId) {
82+
if (!coachingSession.id) {
8083
console.error(
81-
"Failed to fetch Note since coachingSessionId is not set."
84+
"Failed to fetch Note since coachingSession.id is not set."
8285
);
8386
return;
8487
}
8588

86-
await fetchNotesByCoachingSessionId(coachingSessionId)
89+
await fetchNotesByCoachingSessionId(coachingSession.id)
8790
.then((notes) => {
8891
const note = notes[0];
8992
if (notes.length > 0) {
9093
console.trace("note: " + noteToString(note));
9194
setNoteId(note.id);
9295
setNote(note.body);
9396
} else {
94-
console.trace("No Notes associated with this coachingSessionId");
97+
console.trace("No Notes associated with this coachingSession.id");
9598
}
9699
})
97100
.catch((err) => {
@@ -101,11 +104,11 @@ export default function CoachingSessionsPage() {
101104
});
102105
}
103106
fetchNote();
104-
}, [coachingSessionId, noteId]);
107+
}, [coachingSession.id, noteId]);
105108

106109
const handleAgreementAdded = (body: string): Promise<Agreement> => {
107110
// Calls the backend endpoint that creates and stores a full Agreement entity
108-
return createAgreement(coachingSessionId, userId, body)
111+
return createAgreement(coachingSession.id, userId, body)
109112
.then((agreement) => {
110113
return agreement;
111114
})
@@ -116,7 +119,7 @@ export default function CoachingSessionsPage() {
116119
};
117120

118121
const handleAgreementEdited = (id: Id, body: string): Promise<Agreement> => {
119-
return updateAgreement(id, coachingSessionId, userId, body)
122+
return updateAgreement(id, coachingSession.id, userId, body)
120123
.then((agreement) => {
121124
return agreement;
122125
})
@@ -143,7 +146,7 @@ export default function CoachingSessionsPage() {
143146
dueBy: DateTime
144147
): Promise<Action> => {
145148
// Calls the backend endpoint that creates and stores a full Action entity
146-
return createAction(coachingSessionId, body, status, dueBy)
149+
return createAction(coachingSession.id, body, status, dueBy)
147150
.then((action) => {
148151
return action;
149152
})
@@ -159,7 +162,7 @@ export default function CoachingSessionsPage() {
159162
status: ActionStatus,
160163
dueBy: DateTime
161164
): Promise<Action> => {
162-
return updateAction(id, coachingSessionId, body, status, dueBy)
165+
return updateAction(id, coachingSession.id, body, status, dueBy)
163166
.then((action) => {
164167
return action;
165168
})
@@ -183,8 +186,8 @@ export default function CoachingSessionsPage() {
183186
const handleInputChange = (value: string) => {
184187
setNote(value);
185188

186-
if (noteId && coachingSessionId && userId) {
187-
updateNote(noteId, coachingSessionId, userId, value)
189+
if (noteId && coachingSession.id && userId) {
190+
updateNote(noteId, coachingSession.id, userId, value)
188191
.then((note) => {
189192
console.trace("Updated Note: " + noteToString(note));
190193
setSyncStatus("All changes saved");
@@ -193,8 +196,8 @@ export default function CoachingSessionsPage() {
193196
setSyncStatus("Failed to save changes");
194197
console.error("Failed to update Note: " + err);
195198
});
196-
} else if (!noteId && coachingSessionId && userId) {
197-
createNote(coachingSessionId, userId, value)
199+
} else if (!noteId && coachingSession.id && userId) {
200+
createNote(coachingSession.id, userId, value)
198201
.then((note) => {
199202
console.trace("Newly created Note: " + noteToString(note));
200203
setNoteId(note.id);
@@ -206,7 +209,7 @@ export default function CoachingSessionsPage() {
206209
});
207210
} else {
208211
console.error(
209-
"Could not update or create a Note since coachingSessionId or userId are not set."
212+
"Could not update or create a Note since coachingSession.id or userId are not set."
210213
);
211214
}
212215
};
@@ -215,11 +218,19 @@ export default function CoachingSessionsPage() {
215218
setSyncStatus("");
216219
};
217220

221+
const handleTitleRender = (sessionTitle: string) => {
222+
document.title = sessionTitle;
223+
};
224+
218225
return (
219226
<>
220-
<div className="hidden h-full flex-col md:flex">
227+
<div className="h-full flex-col md:flex">
221228
<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">
222-
<h4 className="w-16 md:w-32 lg:w-48 font-semibold">Session Title</h4>
229+
<CoachingSessionTitle
230+
locale={siteConfig.locale}
231+
style={siteConfig.titleStyle}
232+
onRender={handleTitleRender}
233+
></CoachingSessionTitle>
223234
<div className="ml-auto flex w-full space-x-2 sm:justify-end">
224235
<PresetSelector current={current} future={future} past={past} />
225236
<PresetActions />
@@ -289,7 +300,7 @@ export default function CoachingSessionsPage() {
289300
<TabsContent value="agreements">
290301
<div className="w-full">
291302
<AgreementsList
292-
coachingSessionId={coachingSessionId}
303+
coachingSessionId={coachingSession.id}
293304
userId={userId}
294305
locale={siteConfig.locale}
295306
onAgreementAdded={handleAgreementAdded}
@@ -301,7 +312,7 @@ export default function CoachingSessionsPage() {
301312
<TabsContent value="actions">
302313
<div className="w-full">
303314
<ActionsList
304-
coachingSessionId={coachingSessionId}
315+
coachingSessionId={coachingSession.id}
305316
userId={userId}
306317
locale={siteConfig.locale}
307318
onActionAdded={handleActionAdded}

src/components/ui/coaching-sessions/actions-list.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,12 @@ const ActionsList: React.FC<{
201201

202202
useEffect(() => {
203203
async function loadActions() {
204-
if (!coachingSessionId) return;
204+
if (!coachingSessionId) {
205+
console.error(
206+
"Failed to fetch Actions since coachingSession.id is not set."
207+
);
208+
return;
209+
}
205210

206211
await fetchActionsByCoachingSessionId(coachingSessionId)
207212
.then((actions) => {

src/components/ui/coaching-sessions/agreements-list.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,7 @@ import {
1919
} from "@/components/ui/dropdown-menu";
2020
import { MoreHorizontal, ArrowUpDown, Save } from "lucide-react";
2121
import { Id } from "@/types/general";
22-
import {
23-
createAgreement,
24-
deleteAgreement as deleteAgreementApi,
25-
updateAgreement as updateAgreementApi,
26-
fetchAgreementsByCoachingSessionId,
27-
} from "@/lib/api/agreements";
22+
import { fetchAgreementsByCoachingSessionId } from "@/lib/api/agreements";
2823
import { Agreement, agreementToString } from "@/types/agreement";
2924
import { DateTime } from "ts-luxon";
3025
import { siteConfig } from "@/site.config";
@@ -158,7 +153,12 @@ const AgreementsList: React.FC<{
158153

159154
useEffect(() => {
160155
async function loadAgreements() {
161-
if (!coachingSessionId) return;
156+
if (!coachingSessionId) {
157+
console.error(
158+
"Failed to fetch Agreements since coachingSession.id is not set."
159+
);
160+
return;
161+
}
162162

163163
await fetchAgreementsByCoachingSessionId(coachingSessionId)
164164
.then((agreements) => {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"use client";
2+
3+
import { useEffect, useState } from "react";
4+
import {
5+
defaultSessionTitle,
6+
generateSessionTitle,
7+
SessionTitle,
8+
SessionTitleStyle,
9+
} from "@/types/session-title";
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";
19+
20+
const CoachingSessionTitle: React.FC<{
21+
locale: string | "us";
22+
style: SessionTitleStyle;
23+
onRender: (sessionTitle: string) => void;
24+
}> = ({ locale, style, onRender }) => {
25+
const [isLoading, setIsLoading] = useState(true);
26+
const [sessionTitle, setSessionTitle] = useState<SessionTitle>();
27+
const { coachingSession, coachingRelationship } = useAppStateStore(
28+
(state) => state
29+
);
30+
useState<CoachingRelationshipWithUserNames>();
31+
32+
useEffect(() => {
33+
if (coachingSession && coachingRelationship) {
34+
setIsLoading(false);
35+
const title = generateSessionTitle(
36+
coachingSession,
37+
coachingRelationship,
38+
style,
39+
locale
40+
);
41+
setSessionTitle(title);
42+
onRender(title.title);
43+
}
44+
}, [coachingSession, coachingRelationship, style, locale, onRender]);
45+
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+
}
53+
54+
return (
55+
<h4 className="font-semibold break-words w-full px-2 md:px-4 lg:px-6 md:text-clip">
56+
{sessionTitle ? sessionTitle.title : defaultSessionTitle().title}
57+
</h4>
58+
);
59+
};
60+
61+
export { CoachingSessionTitle };

0 commit comments

Comments
 (0)