Skip to content

Commit

Permalink
Merge pull request #22 from Jim-Hodapp-Coaching/fetch_coaching_sessions
Browse files Browse the repository at this point in the history
Fetch coaching sessions for selecting the coaching session to join
  • Loading branch information
jhodapp committed Jul 2, 2024
2 parents 0adf782 + 200183c commit 759c8d1
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 81 deletions.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,9 @@ import { PresetShare } from "@/components/ui/preset-share";
import { TemperatureSelector } from "@/components/ui/temperature-selector";
import { TopPSelector } from "@/components/ui/top-p-selector";
import { cn } from "@/lib/utils";
// import { fetchOrganizations, fetchOrganization, deleteOrganization, createOrganization, updateOrganization } from "@/lib/api/organizations";
import { useAuthStore } from "@/lib/providers/auth-store-provider";
import { models, types } from "../../data/models";
import { current, future, past } from "../../data/presets";
// import { useEffect, useState } from "react";
// import { Organization } from "@/types/organization";
// import { DateTime } from "ts-luxon";
import { models, types } from "@/data/models";
import { current, future, past } from "@/data/presets";

// export const metadata: Metadata = {
// title: "Coaching Session",
Expand All @@ -51,76 +47,7 @@ import { current, future, past } from "../../data/presets";

export default function CoachingSessionsPage() {
const [isOpen, setIsOpen] = React.useState(false);
const { isLoggedIn, userUUID } = useAuthStore(
(state) => state,
)

// FIXME: these are here as "unit tests" ahead of adding real unit testing in a
// near future commit.

// const [organization, setOrganization] = useState<Organization | null>(null);
// useEffect(() => {
// async function loadOrganization() {
// const fetchedOrganization = await fetchOrganization(1);
// console.debug("Organization(1): " + JSON.stringify(fetchedOrganization[0]));
// setOrganization(fetchedOrganization[0]);
// }
// loadOrganization();
// }, []);

// const [organizations, setOrganizations] = useState<Organization[] | null>(null);
// useEffect(() => {
// async function loadOrganizations() {
// const fetchedOrganizations = await fetchOrganizations();
// console.debug("Organizations: " + JSON.stringify(fetchedOrganizations[0]));
// setOrganizations(fetchedOrganizations[0]);
// }
// loadOrganizations();
// }, []);

// const [createdOrganization, setCreatedOrganization] = useState<Organization | null>(null);
// useEffect(() => {
// async function loadOrganization() {
// var organization: Organization = {
// external_id: "fa594ab3-fad0-4be9-a8fe-9088b2911914",
// name: "New test organization",
// logo: "http://www.fake.org/logo",
// created_at: DateTime.now(),
// updated_at: DateTime.now()
// }
// const createdOrganization = await createOrganization(organization);
// console.debug("createdOrganization: " + JSON.stringify(createdOrganization[0]));
// setCreatedOrganization(createdOrganization[0]);
// }
// loadOrganization();
// }, []);

// const [updatedOrganization, setUpdatedOrganization] = useState<Organization | null>(null);
// useEffect(() => {
// async function loadOrganization() {
// var organization: Organization = {
// external_id: "fa594ab3-fad0-4be9-a8fe-9088b2911914",
// name: "Jim Hodapp Coaching",
// logo: "http://www.fake.org/logo",
// created_at: DateTime.now(),
// updated_at: DateTime.now()
// }
// const updatedOrganization = await updateOrganization(1, organization);
// console.debug("updatedOrganization: " + JSON.stringify(updatedOrganization[0]));
// setUpdatedOrganization(updatedOrganization[0]);
// }
// loadOrganization();
// }, []);

// const [deletedOrganization, setDeletedOrganization] = useState<string | null>(null);
// useEffect(() => {
// async function loadOrganization() {
// const deletedOrganizationId = await deleteOrganization(1);
// console.debug("deletedOrganizationId: " + JSON.stringify(deletedOrganizationId[0]));
// setDeletedOrganization(deletedOrganizationId[0]);
// }
// loadOrganization();
// }, []);
const { isLoggedIn, userUUID } = useAuthStore((state) => state);

return (
<>
Expand Down
74 changes: 71 additions & 3 deletions src/components/ui/dashboard/select-coaching-session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,21 @@ import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { fetchCoachingRelationshipsWithUserNames } from "@/lib/api/coaching-relationships";
import { fetchCoachingSessions } from "@/lib/api/coaching-sessions";
import { fetchOrganizationsByUserId } from "@/lib/api/organizations";
import { CoachingSession } from "@/types/coaching-session";
import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship_with_user_names";
import { Organization } from "@/types/organization";
import Link from "next/link";
import { useEffect, useState } from "react";
import { DateTime } from "ts-luxon";

export interface CoachingSessionProps {
/** The current logged in user's UUID */
Expand All @@ -40,6 +46,9 @@ export function SelectCoachingSession({
const [coachingRelationships, setCoachingRelationships] = useState<
CoachingRelationshipWithUserNames[]
>([]);
const [coachingSessions, setCoachingSessions] = useState<CoachingSession[]>(
[]
);

useEffect(() => {
async function loadOrganizations() {
Expand Down Expand Up @@ -78,6 +87,24 @@ export function SelectCoachingSession({
loadCoachingRelationships();
}, [organizationUUID]);

useEffect(() => {
async function loadCoachingSessions() {
if (!organizationUUID) return;

await fetchCoachingSessions(relationshipUUID)
.then(([coaching_sessions]) => {
console.debug(
"setCoachingSessions: " + JSON.stringify(coaching_sessions)
);
setCoachingSessions(coaching_sessions);
})
.catch(([err]) => {
console.error("Failed to fetch coaching sessions: " + err);
});
}
loadCoachingSessions();
}, [relationshipUUID]);

return (
<Card>
<CardHeader>
Expand All @@ -103,6 +130,11 @@ export function SelectCoachingSession({
{organization.name}
</SelectItem>
))}
{organizations.length == 0 && (
<SelectItem disabled={true} value="none">
None found
</SelectItem>
)}
</SelectContent>
</Select>
</div>
Expand All @@ -125,6 +157,11 @@ export function SelectCoachingSession({
{relationship.coachee_last_name}
</SelectItem>
))}
{coachingRelationships.length == 0 && (
<SelectItem disabled={true} value="none">
None found
</SelectItem>
)}
</SelectContent>
</Select>
</div>
Expand All @@ -140,8 +177,39 @@ export function SelectCoachingSession({
<SelectValue placeholder="Select coaching session" />
</SelectTrigger>
<SelectContent>
<SelectItem value="today">Today @ 5 pm</SelectItem>
<SelectItem value="tomorrow">Tomorrow @ 5 pm</SelectItem>
{coachingSessions.some(
(session) => session.date < DateTime.now()
) && (
<SelectGroup>
<SelectLabel>Previous Sessions</SelectLabel>
{coachingSessions
.filter((session) => session.date < DateTime.now())
.map((session) => (
<SelectItem value={session.id} key={session.id}>
{session.date.toLocaleString(DateTime.DATETIME_FULL)}
</SelectItem>
))}
</SelectGroup>
)}
{coachingSessions.some(
(session) => session.date >= DateTime.now()
) && (
<SelectGroup>
<SelectLabel>Upcoming Sessions</SelectLabel>
{coachingSessions
.filter((session) => session.date >= DateTime.now())
.map((session) => (
<SelectItem value={session.id} key={session.id}>
{session.date.toLocaleString(DateTime.DATETIME_FULL)}
</SelectItem>
))}
</SelectGroup>
)}
{coachingSessions.length == 0 && (
<SelectItem disabled={true} value="none">
None found
</SelectItem>
)}
</SelectContent>
</Select>
</div>
Expand All @@ -152,7 +220,7 @@ export function SelectCoachingSession({
className="w-full"
disabled={!coachingSessionUUID}
>
Join
<Link href={`/coaching-sessions/${coachingSessionUUID}`}>Join</Link>
</Button>
</CardFooter>
</Card>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/main-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export function MainNav() {
return (
<div className="mr-4 hidden md:flex">
{/* TODO: make the href target for this link send the user back to the coaching-sessions page */}
<Link href="/" className="mr-2 flex items-center space-x-2">
<Link href="/dashboard" className="mr-2 flex items-center space-x-2">
<div
className={cn(
buttonVariants({
Expand Down
79 changes: 79 additions & 0 deletions src/lib/api/coaching-sessions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Interacts with the coaching_session endpoints

import {
CoachingSession,
coachingSessionsToString,
defaultCoachingSessions,
isCoachingSessionArray,
parseCoachingSession,
sortCoachingSessionArray
} from "@/types/coaching-session";
import { Id, SortOrder } from "@/types/general";
import { AxiosError, AxiosResponse } from "axios";
import { DateTime } from "ts-luxon";

export const fetchCoachingSessions = async (
coachingRelationshipId: Id
): Promise<[CoachingSession[], string]> => {
const axios = require("axios");

var coaching_sessions: CoachingSession[] = [];
var err: string = "";

// 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}).toISODate();
const toDate = DateTime.now().plus({month: 1}).toISODate();

console.debug("fromDate: " + fromDate);
console.debug("toDate: " + toDate);

const data = await axios
.get(`http://localhost:4000/coaching_sessions`, {
params: {
coaching_relationship_id: coachingRelationshipId,
from_date: fromDate,
to_date: toDate
},
withCredentials: true,
setTimeout: 5000, // 5 seconds before timing out trying to log in with the backend
headers: {
"X-Version": "0.0.1",
},
})
.then(function (response: AxiosResponse) {
// handle success
console.debug(response);
var sessions_data = response.data.data;
if (isCoachingSessionArray(sessions_data)) {
// Sort returned sessions in ascending order by their date field
sessions_data = sortCoachingSessionArray(sessions_data, SortOrder.Ascending);

sessions_data.forEach((session_data: any) => {
//console.debug("session_data: " + JSON.stringify(session_data));
coaching_sessions.push(parseCoachingSession(session_data))
});
console.debug(
`CoachingSessions: ` + coachingSessionsToString(coaching_sessions) + `.`
);
}
})
.catch(function (error: AxiosError) {
// handle error
console.error(error.response?.status);
if (error.response?.status == 401) {
console.error("Retrieval of CoachingSessions failed: unauthorized.");
err = "Retrieval of CoachingSessions failed: unauthorized.";
} else {
console.log(error);
console.error(
`Retrieval of CoachingSessions by coaching relationship Id (` + coachingRelationshipId + `) failed.`
);
err =
`Retrieval of CoachingSessions by coaching relationship Id (` + coachingRelationshipId + `) failed.`;
}
});

return [coaching_sessions, err];
};
Loading

0 comments on commit 759c8d1

Please sign in to comment.