diff --git a/__tests__/app/coaching-sessions/coaching-session-page.test.tsx b/__tests__/app/coaching-sessions/coaching-session-page.test.tsx index 5d35c8a5..ffd9514f 100644 --- a/__tests__/app/coaching-sessions/coaching-session-page.test.tsx +++ b/__tests__/app/coaching-sessions/coaching-session-page.test.tsx @@ -3,6 +3,9 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' import { useRouter, useParams, useSearchParams } from 'next/navigation' import CoachingSessionsPage from '@/app/coaching-sessions/[id]/page' import { TestProviders } from '@/test-utils/providers' +import { useCurrentCoachingSession } from '@/lib/hooks/use-current-coaching-session' +import { useCurrentCoachingRelationship } from '@/lib/hooks/use-current-coaching-relationship' +import { createMockCoachingSession } from '../../factories/coaching-session.factory' // Mock Next.js navigation hooks vi.mock('next/navigation', () => ({ @@ -12,24 +15,8 @@ vi.mock('next/navigation', () => ({ })) // Mock the coaching session hooks -vi.mock('@/lib/hooks/use-current-coaching-session', () => ({ - useCurrentCoachingSession: vi.fn(() => ({ - currentCoachingSessionId: 'session-123', - currentCoachingSession: { - id: 'session-123', - title: 'Test Session', - coaching_relationship_id: 'rel-123' - }, - isError: false, - })) -})) - -vi.mock('@/lib/hooks/use-current-coaching-relationship', () => ({ - useCurrentCoachingRelationship: vi.fn(() => ({ - currentCoachingRelationshipId: 'rel-123', - setCurrentCoachingRelationshipId: vi.fn(), - })) -})) +vi.mock('@/lib/hooks/use-current-coaching-session') +vi.mock('@/lib/hooks/use-current-coaching-relationship') // Mock auth store vi.mock('@/lib/providers/auth-store-provider', () => ({ @@ -84,16 +71,39 @@ describe('CoachingSessionsPage URL Parameter Persistence', () => { const mockRouter = { push: vi.fn(), replace: vi.fn(), - } + } as const const mockParams = { id: 'session-123' - } + } as const beforeEach(() => { vi.clearAllMocks() ;(useRouter as any).mockReturnValue(mockRouter) ;(useParams as any).mockReturnValue(mockParams) + + // Set default mocks for relationship hooks + vi.mocked(useCurrentCoachingSession).mockReturnValue({ + currentCoachingSessionId: 'session-123', + currentCoachingSession: createMockCoachingSession({ + id: 'session-123', + coaching_relationship_id: 'rel-123' + }), + isError: false, + isLoading: false, + refresh: vi.fn(), + }) + + vi.mocked(useCurrentCoachingRelationship).mockReturnValue({ + currentCoachingRelationshipId: 'rel-123', + setCurrentCoachingRelationshipId: vi.fn(), + currentCoachingRelationship: null, + isLoading: false, + isError: false, + currentOrganizationId: 'org-123', + resetCoachingRelationshipState: vi.fn(), + refresh: vi.fn(), + }) }) /** @@ -217,4 +227,254 @@ describe('CoachingSessionsPage URL Parameter Persistence', () => { ) }) }) +}) + +/** + * Test Suite: Relationship Auto-Sync Behavior + * + * Purpose: Validates that the coaching relationship ID is correctly synced from the current + * session data to the store in various navigation scenarios, fixing Bug #228 while preserving + * the fix for Issue #79 (new tab support). + */ +describe('CoachingSessionsPage - Relationship Auto-Sync', () => { + const mockRouter = { + push: vi.fn(), + replace: vi.fn(), + } as const + + const mockParams = { + id: 'session-123' + } as const + + beforeEach(() => { + vi.clearAllMocks() + ;(useRouter as any).mockReturnValue(mockRouter) + ;(useParams as any).mockReturnValue(mockParams) + ;(useSearchParams as any).mockReturnValue(new URLSearchParams()) + }) + + /** + * Test: First Load with Empty Store (Issue #79) + * + * Scenario: User opens a session URL in a new tab/window with empty sessionStorage + * Expected: Relationship ID should be synced from session data to store AND refresh called + * This ensures Issue #79 (new tab support) continues to work + */ + it('should sync relationship ID on first load with empty store', () => { + const mockSetRelationshipId = vi.fn() + const mockRefresh = vi.fn() + + // Session has relationship ID, but store is empty (new tab scenario) + vi.mocked(useCurrentCoachingSession).mockReturnValue({ + currentCoachingSessionId: 'session-123', + currentCoachingSession: createMockCoachingSession({ + id: 'session-123', + coaching_relationship_id: 'rel-123' + }), + isError: false, + isLoading: false, + refresh: vi.fn(), + }) + + vi.mocked(useCurrentCoachingRelationship).mockReturnValue({ + currentCoachingRelationshipId: null, // Empty store + setCurrentCoachingRelationshipId: mockSetRelationshipId, + currentCoachingRelationship: null, + isLoading: false, + isError: false, + currentOrganizationId: 'org-123', + resetCoachingRelationshipState: vi.fn(), + refresh: mockRefresh, + }) + + render( + + + + ) + + // Should call setCurrentCoachingRelationshipId with the session's relationship ID + expect(mockSetRelationshipId).toHaveBeenCalledWith('rel-123') + // Should call refresh to fetch the relationship data + expect(mockRefresh).toHaveBeenCalled() + }) + + /** + * Test: Switching Between Sessions with Different Relationships (Bug #228) + * + * Scenario: User navigates from Session A (rel-1) to Session B (rel-2) + * Expected: Relationship ID should update from rel-1 to rel-2 AND refresh called + * This is the primary fix for Bug #228 + */ + it('should update relationship ID when switching to session with different relationship', () => { + const mockSetRelationshipId = vi.fn() + const mockRefresh = vi.fn() + + // Session has relationship ID 'rel-456', but store has stale 'rel-123' + vi.mocked(useCurrentCoachingSession).mockReturnValue({ + currentCoachingSessionId: 'session-456', + currentCoachingSession: createMockCoachingSession({ + id: 'session-456', + coaching_relationship_id: 'rel-456' // Different relationship + }), + isError: false, + isLoading: false, + refresh: vi.fn(), + }) + + vi.mocked(useCurrentCoachingRelationship).mockReturnValue({ + currentCoachingRelationshipId: 'rel-123', // Stale relationship from previous session + setCurrentCoachingRelationshipId: mockSetRelationshipId, + currentCoachingRelationship: null, + isLoading: false, + isError: false, + currentOrganizationId: 'org-123', + resetCoachingRelationshipState: vi.fn(), + refresh: mockRefresh, + }) + + render( + + + + ) + + // Should call setCurrentCoachingRelationshipId to update to the new relationship + expect(mockSetRelationshipId).toHaveBeenCalledWith('rel-456') + // Should call refresh to fetch the new relationship data (fixes stale cache bug) + expect(mockRefresh).toHaveBeenCalled() + }) + + /** + * Test: Same Relationship, Different Session + * + * Scenario: User navigates from Session A to Session B, both in the same relationship + * Expected: setCurrentCoachingRelationshipId should NOT be called (optimization) + * This ensures we don't trigger unnecessary updates + */ + it('should not update relationship ID when switching to session with same relationship', () => { + const mockSetRelationshipId = vi.fn() + + // Session and store both have the same relationship ID + vi.mocked(useCurrentCoachingSession).mockReturnValue({ + currentCoachingSessionId: 'session-456', + currentCoachingSession: createMockCoachingSession({ + id: 'session-456', + coaching_relationship_id: 'rel-123' // Same relationship + }), + isError: false, + isLoading: false, + refresh: vi.fn(), + }) + + vi.mocked(useCurrentCoachingRelationship).mockReturnValue({ + currentCoachingRelationshipId: 'rel-123', // Same relationship already in store + setCurrentCoachingRelationshipId: mockSetRelationshipId, + currentCoachingRelationship: null, + isLoading: false, + isError: false, + currentOrganizationId: 'org-123', + resetCoachingRelationshipState: vi.fn(), + refresh: vi.fn(), + }) + + render( + + + + ) + + // Should NOT call setCurrentCoachingRelationshipId since they match + expect(mockSetRelationshipId).not.toHaveBeenCalled() + }) + + /** + * Test: Session Without Relationship ID + * + * Scenario: Session data is loaded but doesn't have a coaching_relationship_id + * Expected: setCurrentCoachingRelationshipId should NOT be called + * This handles edge cases where session data might be incomplete + */ + it('should not update relationship ID when session has no relationship', () => { + const mockSetRelationshipId = vi.fn() + + // Session without relationship ID + vi.mocked(useCurrentCoachingSession).mockReturnValue({ + currentCoachingSessionId: 'session-123', + currentCoachingSession: createMockCoachingSession({ + id: 'session-123', + coaching_relationship_id: undefined as any // No coaching_relationship_id + }), + isError: false, + isLoading: false, + refresh: vi.fn(), + }) + + vi.mocked(useCurrentCoachingRelationship).mockReturnValue({ + currentCoachingRelationshipId: 'rel-123', + setCurrentCoachingRelationshipId: mockSetRelationshipId, + currentCoachingRelationship: null, + isLoading: false, + isError: false, + currentOrganizationId: 'org-123', + resetCoachingRelationshipState: vi.fn(), + refresh: vi.fn(), + }) + + render( + + + + ) + + // Should NOT call setCurrentCoachingRelationshipId + expect(mockSetRelationshipId).not.toHaveBeenCalled() + }) + + /** + * Test: Direct URL Access with Stale Store + * + * Scenario: User manually types a session URL while store has a different relationship + * Expected: Relationship ID should update to match the session from the URL AND refresh called + * This ensures URL is always the source of truth + */ + it('should handle direct URL access with stale relationship ID in store', () => { + const mockSetRelationshipId = vi.fn() + const mockRefresh = vi.fn() + + // User types URL for session-789 which belongs to rel-789 + // But store has stale rel-123 from previous browsing + vi.mocked(useCurrentCoachingSession).mockReturnValue({ + currentCoachingSessionId: 'session-789', + currentCoachingSession: createMockCoachingSession({ + id: 'session-789', + coaching_relationship_id: 'rel-789' + }), + isError: false, + isLoading: false, + refresh: vi.fn(), + }) + + vi.mocked(useCurrentCoachingRelationship).mockReturnValue({ + currentCoachingRelationshipId: 'rel-123', // Stale from previous session + setCurrentCoachingRelationshipId: mockSetRelationshipId, + currentCoachingRelationship: null, + isLoading: false, + isError: false, + currentOrganizationId: 'org-123', + resetCoachingRelationshipState: vi.fn(), + refresh: mockRefresh, + }) + + render( + + + + ) + + // Should update to match the URL-based session + expect(mockSetRelationshipId).toHaveBeenCalledWith('rel-789') + // Should call refresh to fetch the new relationship data + expect(mockRefresh).toHaveBeenCalled() + }) }) \ No newline at end of file diff --git a/__tests__/app/coaching-sessions/relationship-sync.test.ts b/__tests__/app/coaching-sessions/relationship-sync.test.ts new file mode 100644 index 00000000..7e97e9e7 --- /dev/null +++ b/__tests__/app/coaching-sessions/relationship-sync.test.ts @@ -0,0 +1,50 @@ +import { describe, it, expect } from 'vitest' +import { shouldSyncRelationship } from '@/app/coaching-sessions/[id]/relationship-sync' + +describe('shouldSyncRelationship', () => { + describe('when session has no relationship ID', () => { + it('returns false with null store', () => { + expect(shouldSyncRelationship(undefined, null)).toBe(false) + }) + + it('returns false with populated store', () => { + expect(shouldSyncRelationship(undefined, 'rel-123')).toBe(false) + }) + }) + + describe('when store is empty', () => { + it('returns true (Issue #79: new tab scenario)', () => { + expect(shouldSyncRelationship('rel-123', null)).toBe(true) + }) + }) + + describe('when relationship IDs differ', () => { + it('returns true (Bug #228: switching between sessions)', () => { + expect(shouldSyncRelationship('rel-456', 'rel-123')).toBe(true) + }) + + it('returns true for any different ID', () => { + expect(shouldSyncRelationship('rel-999', 'rel-000')).toBe(true) + }) + }) + + describe('when relationship IDs match', () => { + it('returns false (optimization: no sync needed)', () => { + expect(shouldSyncRelationship('rel-123', 'rel-123')).toBe(false) + }) + + it('returns false for any matching ID', () => { + expect(shouldSyncRelationship('rel-xyz', 'rel-xyz')).toBe(false) + }) + }) + + describe('edge cases', () => { + it('handles empty string as session ID', () => { + expect(shouldSyncRelationship('', 'rel-123')).toBe(false) + }) + + it('handles empty string in both params', () => { + expect(shouldSyncRelationship('', '')).toBe(false) + }) + }) +}) diff --git a/__tests__/factories/coaching-session.factory.ts b/__tests__/factories/coaching-session.factory.ts new file mode 100644 index 00000000..86fae755 --- /dev/null +++ b/__tests__/factories/coaching-session.factory.ts @@ -0,0 +1,28 @@ +import type { CoachingSession } from '@/types/coaching-session' + +/** + * Creates a mock CoachingSession for testing purposes. + * + * @param overrides - Partial CoachingSession to override default values + * @returns A complete CoachingSession object with sensible defaults + * + * @example + * const session = createMockCoachingSession({ + * id: 'session-456', + * coaching_relationship_id: 'rel-456' + * }) + */ +export function createMockCoachingSession( + overrides?: Partial +): CoachingSession { + const now = new Date().toISOString() + + return { + id: 'session-123', + coaching_relationship_id: 'rel-123', + date: now, + created_at: now, + updated_at: now, + ...overrides, + } +} diff --git a/src/app/coaching-sessions/[id]/page.tsx b/src/app/coaching-sessions/[id]/page.tsx index 1ed5bc9e..6a700bc7 100644 --- a/src/app/coaching-sessions/[id]/page.tsx +++ b/src/app/coaching-sessions/[id]/page.tsx @@ -19,6 +19,7 @@ import ShareSessionLink from "@/components/ui/share-session-link"; import { toast } from "sonner"; import { ForbiddenError } from "@/components/ui/errors/forbidden-error"; import { EntityApiError } from "@/types/general"; +import { shouldSyncRelationship } from "./relationship-sync"; export default function CoachingSessionsPage() { const router = useRouter(); @@ -37,25 +38,32 @@ export default function CoachingSessionsPage() { const { currentCoachingSession, currentCoachingSessionId, isError } = useCurrentCoachingSession(); // Get current coaching relationship state and data - const { currentCoachingRelationshipId, setCurrentCoachingRelationshipId } = + const { currentCoachingRelationshipId, setCurrentCoachingRelationshipId, refresh } = useCurrentCoachingRelationship(); - - // Auto-sync relationship ID when session data loads (if not already set) + // Auto-sync relationship ID when session data loads + // This ensures the relationship selector always matches the current session useEffect(() => { if ( currentCoachingSession?.coaching_relationship_id && - !currentCoachingRelationshipId + shouldSyncRelationship( + currentCoachingSession.coaching_relationship_id, + currentCoachingRelationshipId + ) ) { setCurrentCoachingRelationshipId( currentCoachingSession.coaching_relationship_id ); + + // Force immediate fetch of new relationship data to prevent showing stale cached data + // This ensures the coaching session title shows the correct coach/coachee names + refresh(); } - // setCurrentCoachingRelationshipId is stable and doesn't need to be in deps - // eslint-disable-next-line react-hooks/exhaustive-deps }, [ currentCoachingSession?.coaching_relationship_id, currentCoachingRelationshipId, + setCurrentCoachingRelationshipId, + refresh, ]); // Check for 403 Forbidden error AFTER all hooks are called @@ -109,7 +117,7 @@ export default function CoachingSessionsPage() { onError={handleShareError} /> diff --git a/src/app/coaching-sessions/[id]/relationship-sync.ts b/src/app/coaching-sessions/[id]/relationship-sync.ts new file mode 100644 index 00000000..2a297392 --- /dev/null +++ b/src/app/coaching-sessions/[id]/relationship-sync.ts @@ -0,0 +1,36 @@ +/** + * Determines if coaching relationship ID should be synced from session data. + * + * The URL is the source of truth for the current session. We sync the relationship ID + * from the session data in two cases: + * 1. Store is empty (e.g., new tab/window) - fixes Issue #79 + * 2. Store has a different relationship (e.g., navigating between sessions) - fixes Bug #228 + * + * @param sessionRelationshipId - The relationship ID from the current session + * @param currentRelationshipId - The relationship ID currently in the store + * @returns true if we should sync the relationship ID + * + * @example + * // Store is empty (new tab) + * shouldSyncRelationship('rel-123', null) // returns true + * + * @example + * // Store has different relationship (switching sessions) + * shouldSyncRelationship('rel-456', 'rel-123') // returns true + * + * @example + * // Store matches session (same relationship) + * shouldSyncRelationship('rel-123', 'rel-123') // returns false + * + * @example + * // Session has no relationship (incomplete data) + * shouldSyncRelationship(undefined, 'rel-123') // returns false + */ +export function shouldSyncRelationship( + sessionRelationshipId: string | undefined, + currentRelationshipId: string | null +): boolean { + if (!sessionRelationshipId) return false + // Always sync when empty (new tab) or when different (switching sessions) + return !currentRelationshipId || sessionRelationshipId !== currentRelationshipId +} diff --git a/src/components/ui/members/member-card.tsx b/src/components/ui/members/member-card.tsx index f5168fc4..d150d1af 100644 --- a/src/components/ui/members/member-card.tsx +++ b/src/components/ui/members/member-card.tsx @@ -27,7 +27,7 @@ import { SelectContent, SelectItem, } from "@/components/ui/select"; -import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship"; +import { CoachingRelationshipWithUserNames } from "@/types/coaching-relationship"; import { AuthStore } from "@/lib/stores/auth-store"; import { Id } from "@/types/general"; import { User, isAdminOrSuperAdmin, UserRoleState } from "@/types/user"; diff --git a/src/components/ui/members/member-container.tsx b/src/components/ui/members/member-container.tsx index 61778581..e7875f0c 100644 --- a/src/components/ui/members/member-container.tsx +++ b/src/components/ui/members/member-container.tsx @@ -1,7 +1,7 @@ import { MemberList } from "./member-list"; import { AddMemberButton } from "./add-member-button"; import { User, isAdminOrSuperAdmin, sortUsersAlphabetically } from "@/types/user"; -import { CoachingRelationshipWithUserNames, isUserCoach } from "@/types/coaching_relationship"; +import { CoachingRelationshipWithUserNames, isUserCoach } from "@/types/coaching-relationship"; import { UserSession } from "@/types/user-session"; import { useAuthStore } from "@/lib/providers/auth-store-provider"; import { useCurrentUserRole } from "@/lib/hooks/use-current-user-role"; diff --git a/src/components/ui/members/member-list.tsx b/src/components/ui/members/member-list.tsx index 6a3c5b71..2157c3f6 100644 --- a/src/components/ui/members/member-list.tsx +++ b/src/components/ui/members/member-list.tsx @@ -1,7 +1,7 @@ import { Card, CardContent } from "@/components/ui/card"; import { User, UserRoleState } from "@/types/user"; import { MemberCard } from "./member-card"; -import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship"; +import { CoachingRelationshipWithUserNames } from "@/types/coaching-relationship"; import { Id } from "@/types/general"; interface MemberListProps { diff --git a/src/lib/api/coaching-relationships.ts b/src/lib/api/coaching-relationships.ts index d6873071..f00e6849 100644 --- a/src/lib/api/coaching-relationships.ts +++ b/src/lib/api/coaching-relationships.ts @@ -6,7 +6,7 @@ import { NewCoachingRelationship, CoachingRelationshipWithUserNames, defaultCoachingRelationshipWithUserNames, -} from "@/types/coaching_relationship"; +} from "@/types/coaching-relationship"; import { EntityApi } from "./entity-api"; const ORGANIZATIONS_BASEURL: string = `${siteConfig.env.backendServiceURL}/organizations`; diff --git a/src/lib/hooks/use-auto-select-single-relationship.ts b/src/lib/hooks/use-auto-select-single-relationship.ts index 6b65e0d4..20cd191e 100644 --- a/src/lib/hooks/use-auto-select-single-relationship.ts +++ b/src/lib/hooks/use-auto-select-single-relationship.ts @@ -2,7 +2,7 @@ import { useEffect } from "react"; import { Id } from "@/types/general"; -import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship"; +import { CoachingRelationshipWithUserNames } from "@/types/coaching-relationship"; /** * Custom hook that automatically selects a coaching relationship when: @@ -12,14 +12,14 @@ import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship * * @param relationships Array of available coaching relationships * @param isLoading Whether relationships are currently being loaded - * @param currentId Currently selected coaching relationship ID + * @param currentId Currently selected coaching relationship ID (can be null) * @param setCurrentId Function to set the current coaching relationship ID * @param onSelect Optional callback fired when auto-selection occurs */ export const useAutoSelectSingleRelationship = ( relationships: CoachingRelationshipWithUserNames[] | undefined, isLoading: boolean, - currentId: Id, + currentId: Id | null, setCurrentId: (id: Id) => void, onSelect?: (relationshipId: Id) => void ) => { diff --git a/src/lib/hooks/use-current-coaching-relationship.ts b/src/lib/hooks/use-current-coaching-relationship.ts index 50aaa92d..52462625 100644 --- a/src/lib/hooks/use-current-coaching-relationship.ts +++ b/src/lib/hooks/use-current-coaching-relationship.ts @@ -3,15 +3,39 @@ import { useCoachingRelationship } from "@/lib/api/coaching-relationships"; import { useCoachingRelationshipStateStore } from "@/lib/providers/coaching-relationship-state-store-provider"; import { useCurrentOrganization } from "./use-current-organization"; +import type { CoachingRelationshipWithUserNames } from "@/types/coaching-relationship"; +import type { EntityApiError } from "@/types/general"; + +/** + * Return type for the useCurrentCoachingRelationship hook. + */ +export interface UseCurrentCoachingRelationshipReturn { + /** Current coaching relationship ID from state store */ + currentCoachingRelationshipId: string | null; + /** Full coaching relationship data from SWR (null if no IDs set) */ + currentCoachingRelationship: CoachingRelationshipWithUserNames | null; + /** Loading state from SWR */ + isLoading: boolean; + /** Error state from SWR */ + isError: EntityApiError | false; + /** Current organization ID (needed for relationship operations) */ + currentOrganizationId: string | null; + /** Function to set the current coaching relationship ID in store */ + setCurrentCoachingRelationshipId: (id: string) => void; + /** Function to reset the coaching relationship state */ + resetCoachingRelationshipState: () => void; + /** Function to refresh/revalidate the relationship data */ + refresh: () => Promise; +} /** * Hook that provides current coaching relationship state and data. * Tracks the active coaching relationship ID and fetches the full relationship * data using SWR when both organization ID and relationship ID are available. - * + * * @returns Object containing current relationship ID, full relationship data, loading state, and error state */ -export const useCurrentCoachingRelationship = () => { +export const useCurrentCoachingRelationship = (): UseCurrentCoachingRelationshipReturn => { const { currentCoachingRelationshipId, setCurrentCoachingRelationshipId, resetCoachingRelationshipState } = useCoachingRelationshipStateStore((state) => state); diff --git a/src/lib/hooks/use-current-coaching-session.ts b/src/lib/hooks/use-current-coaching-session.ts index b1daee9f..7b363e58 100644 --- a/src/lib/hooks/use-current-coaching-session.ts +++ b/src/lib/hooks/use-current-coaching-session.ts @@ -3,16 +3,34 @@ import { useParams } from "next/navigation"; import { useCoachingSession } from "@/lib/api/coaching-sessions"; import { Id } from "@/types/general"; +import type { CoachingSession } from "@/types/coaching-session"; +import type { EntityApiError } from "@/types/general"; + +/** + * Return type for the useCurrentCoachingSession hook. + */ +export interface UseCurrentCoachingSessionReturn { + /** Current coaching session ID from URL path parameter */ + currentCoachingSessionId: string | null; + /** Full coaching session data from SWR (null if no ID in URL) */ + currentCoachingSession: CoachingSession | null; + /** Loading state from SWR */ + isLoading: boolean; + /** Error state from SWR */ + isError: EntityApiError | false; + /** Function to refresh/revalidate the session data */ + refresh: () => Promise; +} /** * Hook that gets the current coaching session ID from URL path parameters * and fetches the full coaching session data using SWR. - * + * * URL structure: /coaching-sessions/[id] - * + * * @returns Object containing current session ID, full session data, loading state, and error state */ -export const useCurrentCoachingSession = () => { +export const useCurrentCoachingSession = (): UseCurrentCoachingSessionReturn => { const params = useParams(); // Extract coaching session ID from URL path params (/coaching-sessions/123) diff --git a/src/lib/relationships/relationship-utils.ts b/src/lib/relationships/relationship-utils.ts index ca35a4b5..8f21ac73 100644 --- a/src/lib/relationships/relationship-utils.ts +++ b/src/lib/relationships/relationship-utils.ts @@ -1,4 +1,4 @@ -import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship"; +import { CoachingRelationshipWithUserNames } from "@/types/coaching-relationship"; import { User } from "@/types/user"; import { RelationshipRole } from "@/types/relationship-role"; diff --git a/src/lib/sessions/session-utils.ts b/src/lib/sessions/session-utils.ts index 54d01d0a..1d9a5f96 100644 --- a/src/lib/sessions/session-utils.ts +++ b/src/lib/sessions/session-utils.ts @@ -1,6 +1,6 @@ import { DateTime } from "ts-luxon"; import { CoachingSession } from "@/types/coaching-session"; -import { CoachingRelationshipWithUserNames } from "@/types/coaching_relationship"; +import { CoachingRelationshipWithUserNames } from "@/types/coaching-relationship"; import { User } from "@/types/user"; import { SessionUrgency, diff --git a/src/lib/utils/user-roles.ts b/src/lib/utils/user-roles.ts index 0f2e6670..89e660c8 100644 --- a/src/lib/utils/user-roles.ts +++ b/src/lib/utils/user-roles.ts @@ -1,5 +1,5 @@ import { User, Role } from "@/types/user"; -import { CoachingRelationshipWithUserNames, isUserCoach, isUserCoachee } from "@/types/coaching_relationship"; +import { CoachingRelationshipWithUserNames, isUserCoach, isUserCoachee } from "@/types/coaching-relationship"; import { RelationshipRole } from "@/types/relationship-role"; import { Id } from "@/types/general"; diff --git a/src/types/coaching_relationship.ts b/src/types/coaching-relationship.ts similarity index 100% rename from src/types/coaching_relationship.ts rename to src/types/coaching-relationship.ts diff --git a/src/types/coaching-session.ts b/src/types/coaching-session.ts index aa061aac..8800dafa 100644 --- a/src/types/coaching-session.ts +++ b/src/types/coaching-session.ts @@ -1,7 +1,7 @@ import { DateTime } from "ts-luxon"; import { Id } from "@/types/general"; import { SortOrder } from "@/types/sorting"; -import { CoachingRelationship } from "@/types/coaching_relationship"; +import { CoachingRelationship } from "@/types/coaching-relationship"; import { User } from "@/types/user"; import { Organization } from "@/types/organization"; import { OverarchingGoal } from "@/types/overarching-goal"; diff --git a/src/types/session-title.ts b/src/types/session-title.ts index 09e4f695..ec365526 100644 --- a/src/types/session-title.ts +++ b/src/types/session-title.ts @@ -1,5 +1,5 @@ import { DateTime } from "ts-luxon"; -import { CoachingRelationshipWithUserNames } from "./coaching_relationship"; +import { CoachingRelationshipWithUserNames } from "./coaching-relationship"; import { CoachingSession } from "./coaching-session"; import { siteConfig } from "@/site.config"; import { getDateTimeFromString } from "./general";