Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7c9ce87
Change OrganizationAPI to proper camel-case.
jhodapp Mar 8, 2025
f9475ef
Refactor the Coaching Relationships API to use the new function/hook …
jhodapp Mar 8, 2025
f6aa87e
Update function documentation.
jhodapp Mar 8, 2025
1b4d63a
Refactor the OverarchingGoal API to use the new function/hook pattern.
jhodapp Mar 12, 2025
e520cc2
add CollaborationCursor
calebbourg Feb 28, 2025
4afa804
add more console logging and check for existing provider
calebbourg Mar 3, 2025
900fe9a
Get collab cursor working
zgavin1 Mar 6, 2025
d15a6d1
Update entity-api to include an optional response data parsing/transf…
jhodapp Mar 13, 2025
5d2f4f8
Update Agreements to use new EntityApi functions/hooks.
jhodapp Mar 13, 2025
26eabe5
Remove the parseAgreement() function that is replaced by the transfor…
jhodapp Mar 13, 2025
9abbadf
Refactor Actions to use the new API/hook pattern. Also move the new t…
jhodapp Mar 13, 2025
305ca0e
Create an ORGANIZATIONS_BASEURL const like the other entities have an…
jhodapp Mar 13, 2025
ff19326
Refactor coaching sessions to use the new API/Hook pattern.
jhodapp Mar 14, 2025
dadf69b
Refactor user session login/logout functions to use new hook/API patt…
jhodapp Mar 15, 2025
1088d2b
Factor out the repititous URL strings for coaching relationships
jhodapp Mar 15, 2025
e5c6c7b
Remove parsing function for the coaching relationship with user names…
jhodapp Mar 16, 2025
c74c9c7
Improve the loading/error message of the CoachingNotes component.
jhodapp Mar 16, 2025
f2409bd
Fix non-escaped text build error.
jhodapp Mar 16, 2025
bea8419
Add missing function documentation for createNested() hook mutation.
jhodapp Mar 17, 2025
85730c7
Set error state with message rather than with error object
zgavin1 Mar 18, 2025
5f395ce
Merge branch 'refactor_other_entity_apis_and_hooks' into issue-81-fix…
jhodapp Mar 18, 2025
fb7ce05
Merge pull request #82 from refactor-group/issue-81-fix-auth-error-ha…
jhodapp Mar 18, 2025
50e2c28
Address review comments, fetcher config as non-optional and remove us…
jhodapp Mar 19, 2025
9af2ac4
Merge branch 'main' into refactor_other_entity_apis_and_hooks
jhodapp Mar 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/ui/coaching-relationship-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
SelectValue,
} from "@/components/ui/select";
import { Id } from "@/types/general";
import { useCoachingRelationships } from "@/lib/api/coaching-relationships";
import { useCoachingRelationshipList } from "@/lib/api/coaching-relationships";
import { useEffect } from "react";
import { useAuthStore } from "@/lib/providers/auth-store-provider";
import { useCoachingRelationshipStateStore } from "@/lib/providers/coaching-relationship-state-store-provider";
Expand All @@ -30,7 +30,7 @@ function CoachingRelationshipsSelectItems({
organizationId: Id;
}) {
const { relationships, isLoading, isError } =
useCoachingRelationships(organizationId);
useCoachingRelationshipList(organizationId);
const { setCurrentCoachingRelationships } = useCoachingRelationshipStateStore(
(state) => state
);
Expand Down
19 changes: 12 additions & 7 deletions src/components/ui/coaching-session-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import {
SelectValue,
} from "@/components/ui/select";
import { getDateTimeFromString, Id } from "@/types/general";
import { useCoachingSessions } from "@/lib/api/coaching-sessions";
import { useCoachingSessionList } from "@/lib/api/coaching-sessions";
import { useEffect, useState } from "react";
import { DateTime } from "ts-luxon";
import { useCoachingSessionStateStore } from "@/lib/providers/coaching-session-state-store-provider";
import { fetchOverarchingGoalsByCoachingSessionId } from "@/lib/api/overarching-goals";
import { OverarchingGoalApi } from "@/lib/api/overarching-goals";
import { OverarchingGoal } from "@/types/overarching-goal";
import { CoachingSession } from "@/types/coaching-session";

Expand All @@ -33,11 +33,18 @@ function CoachingSessionsSelectItems({
}: {
relationshipId: Id;
}) {
// TODO: for now we hardcode a 2 month window centered around now,
// eventually we want to make this be configurable somewhere
// (either on the page or elsewhere)
const fromDate = DateTime.now().minus({ month: 1 });
const toDate = DateTime.now().plus({ month: 1 });

const {
coachingSessions,
isLoading: isLoadingSessions,
isError: isErrorSessions,
} = useCoachingSessions(relationshipId);
refresh,
} = useCoachingSessionList(relationshipId, fromDate, toDate);

const { setCurrentCoachingSessions } = useCoachingSessionStateStore(
(state) => state
Expand All @@ -56,7 +63,7 @@ function CoachingSessionsSelectItems({
try {
const sessionIds = coachingSessions?.map((session) => session.id) || [];
const goalsPromises = sessionIds.map((id) =>
fetchOverarchingGoalsByCoachingSessionId(id)
OverarchingGoalApi.list(id)
Copy link
Member Author

@jhodapp jhodapp Mar 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This component and others should ideally be updated to use hooks instead of the direct function calls, but I decided it was out of the scope of this PR to refactor to this level since it would be a pretty major component code restructuring change.

The main reason being, this will give us automatic updates of list of entities when they're changed locally by the current user without having to refresh the page. For example, in the CoachingSessionList component.

);
const fetchedGoals = await Promise.all(goalsPromises);
setGoals(fetchedGoals);
Expand Down Expand Up @@ -163,9 +170,7 @@ export default function CoachingSessionSelector({

setIsLoadingGoal(true);
try {
const goals = await fetchOverarchingGoalsByCoachingSessionId(
currentCoachingSessionId
);
const goals = await OverarchingGoalApi.list(currentCoachingSessionId);
setCurrentGoal(goals[0]);
} catch (error) {
console.error("Error fetching goal:", error);
Expand Down
6 changes: 3 additions & 3 deletions src/components/ui/coaching-session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Card, CardHeader } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import Link from "next/link";
import { useCoachingSessionStateStore } from "@/lib/providers/coaching-session-state-store-provider";
import { useOverarchingGoalByCoachingSessionId } from "@/lib/api/overarching-goals";
import { useOverarchingGoalBySession } from "@/lib/api/overarching-goals";
import { Id } from "@/types/general";

interface CoachingSessionProps {
Expand Down Expand Up @@ -59,7 +59,7 @@ const OverarchingGoal: React.FC<OverarchingGoalProps> = ({
overarchingGoal,
isLoading: isLoadingOverarchingGoal,
isError: isErrorOverarchingGoal,
} = useOverarchingGoalByCoachingSessionId(coachingSessionId);
} = useOverarchingGoalBySession(coachingSessionId);

let titleText: string;

Expand All @@ -74,4 +74,4 @@ const OverarchingGoal: React.FC<OverarchingGoalProps> = ({
return <div>{titleText}</div>;
};

export default CoachingSession;
export { CoachingSession };
125 changes: 47 additions & 78 deletions src/components/ui/coaching-sessions/actions-list.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { useEffect, useState } from "react";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Calendar } from "@/components/ui/calendar";
import {
Expand Down Expand Up @@ -37,7 +37,7 @@ import {
Id,
stringToActionStatus,
} from "@/types/general";
import { fetchActionsByCoachingSessionId } from "@/lib/api/actions";
import { useActionList } from "@/lib/api/actions";
import { DateTime } from "ts-luxon";
import { siteConfig } from "@/site.config";
import { Action, actionToString } from "@/types/action";
Expand Down Expand Up @@ -74,7 +74,8 @@ const ActionsList: React.FC<{
UpdatedAt = "updated_at",
}

const [actions, setActions] = useState<Action[]>([]);
const { actions, isLoading, isError, refresh } =
useActionList(coachingSessionId);
const [newBody, setNewBody] = useState("");
const [newStatus, setNewStatus] = useState<ItemStatus>(ItemStatus.NotStarted);
const [newDueBy, setNewDueBy] = useState<DateTime>(DateTime.now());
Expand All @@ -89,26 +90,28 @@ const ActionsList: React.FC<{
);
const [sortDirection, setSortDirection] = useState<"asc" | "desc">("desc");

const addAction = () => {
const addAction = async () => {
if (newBody.trim() === "") return;

// Call the external onActionAdded handler function which should
// store this action in the backend database
onActionAdded(newBody, newStatus, newDueBy)
.then((action) => {
console.trace(
"Newly created Action (onActionAdded): " + actionToString(action)
);
setActions((prevActions) => [...prevActions, action]);
})
.catch((err) => {
console.error("Failed to create new Action: " + err);
throw err;
});
try {
// Call the external handler to create the action
const action = await onActionAdded(newBody, newStatus, newDueBy);

console.trace(
"Newly created Action (onActionAdded): " + actionToString(action)
);

setNewBody("");
setNewStatus(ItemStatus.NotStarted);
setNewDueBy(DateTime.now());
// Refresh the actions list from the hook
refresh();

// Clear input fields
setNewBody("");
setNewStatus(ItemStatus.NotStarted);
setNewDueBy(DateTime.now());
} catch (err) {
console.error("Failed to create new Action: " + err);
throw err;
}
};

const updateAction = async (
Expand All @@ -121,32 +124,18 @@ const ActionsList: React.FC<{
if (body === "") return;

try {
const updatedActions = await Promise.all(
actions.map(async (action) => {
if (action.id === id) {
// Call the external onActionEdited handler function which should
// update the stored version of this action in the backend database
action = await onActionEdited(id, body, newStatus, newDueBy)
.then((updatedAction) => {
console.trace(
"Updated Action (onActionUpdated): " +
actionToString(updatedAction)
);
// Call the external onActionEdited handler function which should
// update the stored version of this action in the backend database
const updatedAction = await onActionEdited(id, body, newStatus, newDueBy);

return updatedAction;
})
.catch((err) => {
console.error(
"Failed to update Action (id: " + id + "): " + err
);
throw err;
});
}
return action;
})
console.trace(
"Updated Action (onActionUpdated): " + actionToString(updatedAction)
);

setActions(updatedActions);
// Refresh the actions list from the hook
refresh();

// Reset editing UI state
setEditingId(null);
setEditBody("");
setEditStatus(ItemStatus.NotStarted);
Expand All @@ -157,22 +146,23 @@ const ActionsList: React.FC<{
}
};

const deleteAction = (id: Id) => {
const deleteAction = async (id: Id) => {
if (id === "") return;

// Call the external onActionDeleted handler function which should
// delete this action from the backend database
onActionDeleted(id)
.then((action) => {
console.trace(
"Deleted Action (onActionDeleted): " + actionToString(action)
);
setActions(actions.filter((action) => action.id !== id));
})
.catch((err) => {
console.error("Failed to Action (id: " + id + "): " + err);
throw err;
});
try {
// Delete action in backend
const deletedAction = await onActionDeleted(id);

console.trace(
"Deleted Action (onActionDeleted): " + actionToString(deletedAction)
);

// Refresh the actions list from the hook
refresh();
} catch (err) {
console.error("Failed to delete Action (id: " + id + "): " + err);
throw err;
}
};

const sortActions = (column: keyof Action) => {
Expand All @@ -193,27 +183,6 @@ const ActionsList: React.FC<{
return 0;
});

useEffect(() => {
async function loadActions() {
if (!coachingSessionId) {
console.error(
"Failed to fetch Actions since coachingSessionId is not set."
);
return;
}

await fetchActionsByCoachingSessionId(coachingSessionId)
.then((actions) => {
console.debug("setActions: " + JSON.stringify(actions));
setActions(actions);
})
.catch(([err]) => {
console.error("Failed to fetch Actions: " + err);
});
}
loadActions();
}, [coachingSessionId]);

return (
<div>
<div className="bg-inherit rounded-lg border border-gray-200 p-6">
Expand Down
Loading