Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6f0be1a
add the ability to update a coaching session
calebbourg Apr 2, 2025
3b21b68
separate form from dialog
calebbourg Apr 4, 2025
413981c
PR comments
calebbourg Apr 4, 2025
f18b415
move join session button back out of dropdown
calebbourg Apr 4, 2025
704b933
fix regressions from updating coaching session dialog
calebbourg Apr 5, 2025
e9cb3e7
refactor coaching session creation/updates
calebbourg Apr 5, 2025
d79bbce
refresh coaching session list after delete
calebbourg Apr 5, 2025
dbc6966
only coaches can delete coaching sessions
calebbourg Apr 5, 2025
a17885a
Merge pull request #100 from refactor-group/delete_coaching_sessions
jhodapp Apr 5, 2025
962040b
Removes the SelectCoachingRelationship component from the Dashboard p…
jhodapp Apr 5, 2025
3982109
Move the CoachingSessionSelector into the CoachingSessionList, refact…
jhodapp Apr 7, 2025
c851b3a
Clean up the select coaching relationship placeholder text to be clea…
jhodapp Apr 7, 2025
28cd840
We no longer need to debug print relationships.
jhodapp Apr 7, 2025
e29da27
We no longer need to debug print relationships in useEffect either.
jhodapp Apr 7, 2025
6e64e99
Handle loading/loading error cases better for the coaching session list.
jhodapp Apr 7, 2025
536a763
use edit and delete language
calebbourg Apr 8, 2025
0630dbb
use edit and delete language
calebbourg Apr 8, 2025
66000f8
Address review comments
jhodapp Apr 8, 2025
14ddebb
Merge pull request #104 from refactor-group/remove_org_and_rel_select…
jhodapp Apr 9, 2025
e3ef1f5
merge dashboard-content and dashboard-container
calebbourg Apr 9, 2025
7c6ada9
Move the DashboardContainer component into the components directory.
jhodapp Apr 9, 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
69 changes: 69 additions & 0 deletions src/app/dashboard/dashboard-content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"use client";

import { useState } from "react";
import type * as React from "react";
import { cn } from "@/components/lib/utils";
import SelectCoachingRelationship from "@/components/ui/dashboard/select-coaching-relationship";
import CoachingSessionList from "@/components/ui/dashboard/coaching-session-list";
import AddEntities from "@/components/ui/dashboard/add-entities";
import { CoachingSessionDialog } from "@/components/ui/dashboard/coaching-session-dialog";
import type { CoachingSession } from "@/types/coaching-session";

function DashboardContainer({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div
className={cn(
// Base styles
"p-4",
// Mobile: stack vertically
"flex flex-col gap-6",
// Tablet and up (640px+): side by side
"sm:grid sm:grid-cols-2",
// Never grow wider than the site-header
"max-w-screen-2xl",
// Ensure full width for children
"[&>*]:w-full",
className
)}
{...props}
/>
);
}

export function DashboardContent() {
const [dialogOpen, setDialogOpen] = useState(false);
const [sessionToEdit, setSessionToEdit] = useState<CoachingSession | undefined>();

const handleOpenDialog = (session?: CoachingSession) => {
setSessionToEdit(session);
setDialogOpen(true);
};

const handleCloseDialog = () => {
setDialogOpen(false);
setSessionToEdit(undefined);
};

return (
<>
<div className="p-4 max-w-screen-2xl">
<div className="mb-8 w-full">
<AddEntities onCreateSession={() => handleOpenDialog()} />
</div>
</div>
<DashboardContainer>
Copy link
Member

Choose a reason for hiding this comment

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

I'd like to suggest that we should merge DashboardContainer and DashboardContent and I suggest DashboardContainer as the name since we have precedence for this already. Unless I'm misunderstanding things, I don't see any value or requirement to have the extra div layer.

I do think you did take the right approach though in making the Dashboard page as simple as possible and trying to keep it rendered on the server side.

Copy link
Member

Choose a reason for hiding this comment

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

I did some updating here, but not all of what I suggested. But you'll want to check it out so we don't step on each other directly: https://github.com/refactor-group/refactor-platform-fe/pull/102/files#diff-1b7538b3757a933d976e1a796af3bbf3bc3895ae83f60d5a0562db4d2f6bbc02

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@jhodapp thanks for the heads up! It looks like that branch is based off of this one right? Do you have a preference of making this change in this branch vs yours?

Copy link
Member

Choose a reason for hiding this comment

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

@calebbourg It is based off of this one indeed. I'm good either way. Maybe it makes the most sense to retarget my PR to merge into yours instead of into main?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ok made this change e3ef1f5

<SelectCoachingRelationship />
<CoachingSessionList onUpdateSession={handleOpenDialog} />
</DashboardContainer>

<CoachingSessionDialog
open={dialogOpen}
onOpenChange={handleCloseDialog}
coachingSessionToEdit={sessionToEdit}
/>
</>
);
}
44 changes: 2 additions & 42 deletions src/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,11 @@
import type { Metadata } from "next";
import type * as React from "react";
import { cn } from "@/components/lib/utils";
import SelectCoachingRelationship from "@/components/ui/dashboard/select-coaching-relationship";
import CoachingSessionList from "@/components/ui/dashboard/coaching-session-list";
import AddEntities from "@/components/ui/dashboard/add-entities";
import { DashboardContent } from "./dashboard-content";

export const metadata: Metadata = {
title: "Dashboard",
description: "Coaching dashboard",
};

function DashboardContainer({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div
className={cn(
// Base styles
"p-4",
// Mobile: stack vertically
"flex flex-col gap-6",
// Tablet and up (640px+): side by side
"sm:grid sm:grid-cols-2",
// Never grow wider than the site-header
"max-w-screen-2xl",
// Ensure full width for children
"[&>*]:w-full",
className
)}
{...props}
/>
);
}

export default function DashboardPage() {
return (
<>
<div className="p-4 max-w-screen-2xl">
<div className="mb-8 w-full">
<AddEntities />
</div>
</div>
<DashboardContainer>
<SelectCoachingRelationship />
<CoachingSessionList />
</DashboardContainer>
</>
);
return <DashboardContent />;
}
71 changes: 27 additions & 44 deletions src/components/ui/coaching-session.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import React, { useState } from "react";
import React from "react";
import { format } from "date-fns";
import { Card, CardHeader } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
Expand All @@ -15,56 +15,49 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { MoreHorizontal } from "lucide-react";
import { CoachingSessionDialog } from "@/components/ui/dashboard/coaching-session-dialog";
import { DateTime } from "ts-luxon";
import { CoachingSession as CoachingSessionType } from "@/types/coaching-session";

interface CoachingSessionProps {
coachingSession: {
id: Id;
date: string;
coaching_relationship_id: Id;
created_at: DateTime;
updated_at: DateTime;
};
coachingSession: CoachingSessionType;
onUpdate: () => void;
}

const CoachingSession: React.FC<CoachingSessionProps> = ({
coachingSession,
onUpdate,
}) => {
const { setCurrentCoachingSessionId } = useCoachingSessionStateStore(
(state) => state
);
const [updateDialogOpen, setUpdateDialogOpen] = useState(false);

return (
<>
<Card>
<CardHeader className="p-4">
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-2">
<div className="space-y-1">
<OverarchingGoal coachingSessionId={coachingSession.id} />
<div className="text-sm text-muted-foreground">
{format(new Date(coachingSession.date), "MMMM d, yyyy h:mm a")}
</div>
<Card>
<CardHeader className="p-4">
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-2">
<div className="space-y-1">
<OverarchingGoal coachingSessionId={coachingSession.id} />
<div className="text-sm text-muted-foreground">
{format(new Date(coachingSession.date), "MMMM d, yyyy h:mm a")}
</div>
</div>
<div className="flex items-center gap-2">
<Link href={`/coaching-sessions/${coachingSession.id}`} passHref>
<Button
size="sm"
className="w-full sm:w-auto mt-2 sm:mt-0 text-sm px-3 py-1"
onClick={() => setCurrentCoachingSessionId(coachingSession.id)}
>
Join Session
</Button>
</Link>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon">
<MoreHorizontal className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem asChild>
<Link
href={`/coaching-sessions/${coachingSession.id}`}
onClick={() =>
setCurrentCoachingSessionId(coachingSession.id)
}
>
Join Session
</Link>
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setUpdateDialogOpen(true)}>
<DropdownMenuItem onClick={onUpdate}>
Copy link
Member

Choose a reason for hiding this comment

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

To be consistent with Agreements and Actions, can you update the drop down menu item text to be "Edit" and "Delete" instead of "Update Session" and "Delete Session"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated 536a763

Update Session
</DropdownMenuItem>
<DropdownMenuItem className="text-destructive">
Expand All @@ -73,19 +66,9 @@ const CoachingSession: React.FC<CoachingSessionProps> = ({
</DropdownMenuContent>
</DropdownMenu>
</div>
</CardHeader>
</Card>
<CoachingSessionDialog
open={updateDialogOpen}
onOpenChange={setUpdateDialogOpen}
onCoachingSessionUpdated={() => {
// Refresh the list of coaching sessions
window.location.reload();
}}
existingSession={coachingSession}
mode="update"
/>
</>
</div>
</CardHeader>
</Card>
);
};

Expand Down
32 changes: 9 additions & 23 deletions src/components/ui/dashboard/add-entities.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
"use client";

import { useState } from "react";
import { CoachingSessionDialog } from "./coaching-session-dialog";
import { AddCoachingSessionButton } from "./add-coaching-session-button";
import { AddMemberButton } from "./add-member-button";
import { useRouter } from "next/navigation";
import { useOrganizationStateStore } from "@/lib/providers/organization-state-store-provider";
import { useAuthStore } from "@/lib/providers/auth-store-provider";

export default function AddEntities() {
interface AddEntitiesProps {
onCreateSession: () => void;
}

export default function AddEntities({ onCreateSession }: AddEntitiesProps) {
const router = useRouter();
const [open, setOpen] = useState(false);
const { currentOrganizationId } = useOrganizationStateStore((state) => state);
const { isCoach } = useAuthStore((state) => state);

const onCoachingSessionAdded = () => {
setOpen(false);
};

const onMemberButtonClicked = () => {
router.push(`/organizations/${currentOrganizationId}/members`);
};
Expand All @@ -28,27 +25,16 @@ export default function AddEntities() {
Add New
</h3>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
<CoachingSessionDialog
mode="create"
open={open}
onOpenChange={setOpen}
onCoachingSessionUpdated={onCoachingSessionAdded}
dialogTrigger={
<AddCoachingSessionButton
disabled={!isCoach || !currentOrganizationId}
/>
}
<AddCoachingSessionButton
disabled={!isCoach || !currentOrganizationId}
onClick={onCreateSession}
Comment on lines +33 to +35
Copy link
Member

Choose a reason for hiding this comment

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

Yes!! This fulfills my TODO item, so thank you for refactoring this to match the style of AddMemberButton. What a pleasant surprise to discover. :)

/>

{/* TODO: Refactor the AddMemberButton and AddMemberDialog to work just like
AddCoachingSessionDialog does above, where the dialog is the parent container
and it accepts a AddMemberButton as the dialogTrigger parameter.
*/}
<AddMemberButton
disabled={!isCoach || !currentOrganizationId}
onClick={onMemberButtonClicked}
/>
</div>
</div>
);
}
}
Loading