Skip to content

Commit 109ed03

Browse files
committed
wire MicroCoach data hooks into AppSwitch to handle shared state
1 parent 782bec3 commit 109ed03

14 files changed

Lines changed: 113 additions & 89 deletions

‎microcoach_v2/src/App.tsx‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { GOOGLE_OAUTH_CLIENT_ID, ScreenType } from './lib/MicroCoachModels';
1717
import { useAPIClients } from './hooks/useAPIClients';
1818
import { useAuthResolver } from './hooks/useAuthActions';
1919
import { useUserState } from './hooks/useUserState';
20-
import { usePlanItems } from './hooks/usePlanItems';
2120
import AppSwitch from './switches/AppSwitch';
2221
import Preview from './pages/preview/Preview';
2322
import { MicroCoachDataProvider } from './lib/context/MicroCoachDataContext';
@@ -42,11 +41,10 @@ Modal.setAppElement('#root');
4241

4342
function RootLayout({ apiClients }: { apiClients: APIClients }) {
4443
const user = useUserState(apiClients);
45-
const plan = usePlanItems();
4644
useAuthResolver(apiClients, user);
4745
const outletContext = useMemo(
48-
() => ({ apiClients, user, plan }),
49-
[apiClients, user, plan],
46+
() => ({ apiClients, user }),
47+
[apiClients, user],
5048
);
5149
return (
5250
<>

‎microcoach_v2/src/components/TemplateDebugMenu.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import Menu from '@mui/material/Menu';
77
import MenuItem from '@mui/material/MenuItem';
88
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
99
import { ActivityType } from '../lib/PipelineModels';
10-
import { useMisconceptions } from '../hooks/useMisconceptions';
10+
import { useMicroCoachDataState } from '../hooks/context/useMicroCoachDataContext';
1111

1212
/**
1313
* Review scaffolding: jumps straight to any activity template while the
@@ -56,7 +56,7 @@ const DebugFab = styled(Fab)(({ theme }) => ({
5656
export default function TemplateDebugMenu() {
5757
const [anchorEl, setAnchorEl] = React.useState<HTMLElement | null>(null);
5858
const { activityId } = useParams();
59-
const { misconceptions } = useMisconceptions();
59+
const { misconceptions } = useMicroCoachDataState();
6060
const navigate = useNavigate();
6161

6262
// Derived rather than listed, so the menu keeps up with the mock.

‎microcoach_v2/src/hooks/useAppOutletContext.ts‎

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
import { useOutletContext } from 'react-router-dom';
22
import { APIClients } from '../api';
33
import { IUserState } from './useUserState';
4-
import { IPlanItemsState } from './usePlanItems';
54

6-
// The single shared-state read in the app. RootLayout owns the user state and
7-
// hands it (with the API clients) through the router's Outlet; AppSwitch reads
8-
// it once here and passes both down as ordinary props. Mutable state shared by
9-
// sibling routes has to live above them, and Outlet context is React Router's
10-
// own channel for that — this replaces the app's own providers.
5+
// RootLayout now passes the API clients and user actions through the router's
6+
// Outlet. AppSwitch reads them here, while shared data lives in
7+
// MicroCoachDataContext.
118
export interface IAppOutletContext {
129
apiClients: APIClients;
1310
user: IUserState;
14-
plan: IPlanItemsState;
1511
}
1612

1713
// eslint-disable-next-line import/prefer-default-export

‎microcoach_v2/src/hooks/useMisconceptions.ts‎

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,12 @@
1-
import { useEffect, useMemo } from 'react';
1+
import { useEffect } from 'react';
22
import { IAPIClients } from '../api';
3-
import mockPipelineOutput from '../lib/mocks/mockPipelineOutput.json';
4-
import { IMicroCoachMisconception } from '../api/Models/IMicroCoachMisconception';
5-
import { MicroCoachDataStatus } from '../lib/MicroCoachModels';
6-
import { IPipelineOutput, IReflect, ISession } from '../lib/PipelineModels';
7-
import {
8-
useMicroCoachDataDispatch,
9-
useMicroCoachDataState,
10-
} from './context/useMicroCoachDataContext';
11-
12-
const mockMisconceptionsData = mockPipelineOutput as unknown as IPipelineOutput;
13-
14-
export type MisconceptionsStatus = MicroCoachDataStatus;
15-
16-
export interface UseMisconceptionsResult {
17-
session: ISession;
18-
misconceptions: IMicroCoachMisconception[];
19-
reflect: IReflect;
20-
status: MisconceptionsStatus;
21-
error: Error | null;
22-
isReady: boolean;
23-
}
3+
import { useMicroCoachDataDispatch } from './context/useMicroCoachDataContext';
244

255
// eslint-disable-next-line import/prefer-default-export
266
export function useMisconceptions(
277
apiClients: IAPIClients,
288
sessionId: string | null,
29-
): UseMisconceptionsResult {
30-
const { misconceptions, misconceptionsStatus, misconceptionsError } =
31-
useMicroCoachDataState();
9+
): void {
3210
const dispatch = useMicroCoachDataDispatch();
3311

3412
useEffect(() => {
@@ -79,16 +57,4 @@ export function useMisconceptions(
7957
cancelled = true;
8058
};
8159
}, [apiClients, dispatch, sessionId]);
82-
83-
return useMemo(
84-
() => ({
85-
session: mockMisconceptionsData.session,
86-
misconceptions,
87-
reflect: mockMisconceptionsData.reflect,
88-
status: misconceptionsStatus,
89-
error: misconceptionsError,
90-
isReady: misconceptionsStatus === 'ready',
91-
}),
92-
[misconceptions, misconceptionsError, misconceptionsStatus],
93-
);
9460
}

‎microcoach_v2/src/hooks/usePlanItems.ts‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,6 @@ export interface IPlanItemsState {
3838
removePlanItem: (id: string) => void;
3939
}
4040

41-
// Screens receive the plan handle as a prop, alongside their screenSize.
42-
export interface PlanProps {
43-
plan: IPlanItemsState;
44-
}
45-
4641
function combineSavedPlanItemsWithMockData(
4742
savedPlans: IMicroCoachSavedPlan[],
4843
): IPlanItem[] {

‎microcoach_v2/src/pages/ActivityDetail.tsx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {
2727
ScreenSizeProps,
2828
} from '../lib/styledcomponents/ReviewStyledComponents';
2929
import { useAllReady, useI18nReady } from '../hooks/readiness';
30-
import { useMisconceptions } from '../hooks/useMisconceptions';
30+
import { useMicroCoachDataState } from '../hooks/context/useMicroCoachDataContext';
3131
import formatStepAnnotation from '../lib/activityMarks';
3232

3333
interface ActivityDetailViewProps extends ScreenSizeProps {
@@ -238,7 +238,8 @@ function ActivityDetailView({
238238

239239
export default function ActivityDetail({ screenSize }: ScreenSizeProps) {
240240
const { activityId } = useParams();
241-
const { misconceptions, isReady: dataReady } = useMisconceptions();
241+
const { misconceptions, misconceptionsStatus } = useMicroCoachDataState();
242+
const dataReady = misconceptionsStatus === 'ready';
242243
const isReady = useAllReady(useI18nReady(), dataReady);
243244

244245
if (!isReady) return null;

‎microcoach_v2/src/pages/ChooseActivity.tsx‎

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import FlowNav, { FlowTabId } from '../components/FlowNav';
1111
import ActivityCard from '../components/ActivityCard';
1212
import ChooseActivitySkeleton from '../components/ChooseActivitySkeleton';
1313
import { ScreenSize } from '../lib/MicroCoachModels';
14-
import { PlanProps } from '../hooks/usePlanItems';
14+
import { IPlanItem } from '../lib/PipelineModels';
1515
import {
1616
BackButton,
1717
ContextBanner,
@@ -23,26 +23,30 @@ import {
2323
ScreenSizeProps,
2424
} from '../lib/styledcomponents/ReviewStyledComponents';
2525
import { useAllReady, useI18nReady } from '../hooks/readiness';
26-
import { useMisconceptions } from '../hooks/useMisconceptions';
26+
import { useMicroCoachDataState } from '../hooks/context/useMicroCoachDataContext';
2727
import { IMicroCoachActivity } from '../api/Models/IMicroCoachActivity';
2828
import { IMicroCoachMisconception } from '../api/Models/IMicroCoachMisconception';
2929

30-
interface ChooseActivityViewProps extends ScreenSizeProps, PlanProps {
30+
interface ChooseActivityProps extends ScreenSizeProps {
31+
saveActivity: (item: IPlanItem) => void;
32+
}
33+
34+
interface ChooseActivityViewProps extends ChooseActivityProps {
3135
misconception: IMicroCoachMisconception;
36+
planItems: IPlanItem[];
3237
}
3338

3439
function ChooseActivityView({
3540
misconception,
3641
screenSize,
37-
plan,
42+
planItems,
43+
saveActivity,
3844
}: ChooseActivityViewProps) {
3945
const { t } = useTranslation();
4046
const theme = useTheme();
4147
const navigate = useNavigate();
4248
const isLarge = screenSize === ScreenSize.LARGE;
4349

44-
const { planItems, saveActivity } = plan;
45-
4650
// Selection lives in the plan, so choosing here is what populates My Plan.
4751
const selectedActivityId =
4852
planItems.find(
@@ -168,9 +172,14 @@ function ChooseActivityView({
168172
);
169173
}
170174

171-
export default function ChooseActivity({ screenSize, plan }: ScreenSizeProps & PlanProps) {
175+
export default function ChooseActivity({
176+
screenSize,
177+
saveActivity,
178+
}: ChooseActivityProps) {
172179
const { misconceptionId } = useParams();
173-
const { misconceptions, isReady: dataReady } = useMisconceptions();
180+
const { misconceptions, misconceptionsStatus, planItems } =
181+
useMicroCoachDataState();
182+
const dataReady = misconceptionsStatus === 'ready';
174183
const isReady = useAllReady(useI18nReady(), dataReady);
175184

176185
if (!isReady) {
@@ -188,7 +197,8 @@ export default function ChooseActivity({ screenSize, plan }: ScreenSizeProps & P
188197
<ChooseActivityView
189198
misconception={misconception}
190199
screenSize={screenSize}
191-
plan={plan}
200+
planItems={planItems}
201+
saveActivity={saveActivity}
192202
/>
193203
);
194204
}

‎microcoach_v2/src/pages/Dashboard.tsx‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,19 @@ import {
2727
ScreenSizeProps,
2828
} from '../lib/styledcomponents/ReviewStyledComponents';
2929
import { useAllReady, useI18nReady } from '../hooks/readiness';
30-
import { useMisconceptions } from '../hooks/useMisconceptions';
30+
import { useMicroCoachDataState } from '../hooks/context/useMicroCoachDataContext';
31+
import mockPipelineOutput from '../lib/mocks/mockPipelineOutput.json';
32+
import { IPipelineOutput } from '../lib/PipelineModels';
3133

3234
const weekOptions = ['Week of Jul 7', 'Week of Jun 30', 'Week of Jun 23'];
3335

3436
export default function Dashboard({ screenSize }: ScreenSizeProps) {
3537
const { t } = useTranslation();
3638
const theme = useTheme();
3739
const navigate = useNavigate();
38-
const { session, isReady: dataReady } = useMisconceptions();
40+
const { misconceptionsStatus } = useMicroCoachDataState();
41+
const { session } = mockPipelineOutput as unknown as IPipelineOutput;
42+
const dataReady = misconceptionsStatus === 'ready';
3943
const isReady = useAllReady(useI18nReady(), dataReady);
4044

4145
const [selectedClassId, setSelectedClassId] = React.useState(

‎microcoach_v2/src/pages/MyPlan.tsx‎

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import PlanItemRow from '../components/PlanItemRow';
1616
import { PromptIconTile } from '../lib/styledcomponents/ActivityDetailStyledComponents';
1717
import { SignUpCta } from '../lib/styledcomponents/SignUpStyledComponents';
1818
import { ScreenSize } from '../lib/MicroCoachModels';
19-
import { PlanProps } from '../hooks/usePlanItems';
2019
import { IPlanItem } from '../lib/PipelineModels';
20+
import { useMicroCoachDataState } from '../hooks/context/useMicroCoachDataContext';
2121
import {
2222
PlanBackButton,
2323
ChangeActivityButton,
@@ -27,13 +27,22 @@ import {
2727
} from '../lib/styledcomponents/MyPlanStyledComponents';
2828
import { ScreenSizeProps } from '../lib/styledcomponents/ReviewStyledComponents';
2929

30-
export default function MyPlan({ screenSize, plan }: ScreenSizeProps & PlanProps) {
30+
interface MyPlanProps extends ScreenSizeProps {
31+
markPlanItemDone: (id: string) => void;
32+
removePlanItem: (id: string) => void;
33+
}
34+
35+
export default function MyPlan({
36+
screenSize,
37+
markPlanItemDone,
38+
removePlanItem,
39+
}: MyPlanProps) {
3140
const { t } = useTranslation();
3241
const theme = useTheme();
3342
const navigate = useNavigate();
3443
const isLarge = screenSize === ScreenSize.LARGE;
3544

36-
const { planItems, markPlanItemDone, removePlanItem } = plan;
45+
const { planItems } = useMicroCoachDataState();
3746

3847
const saved = planItems.filter((item) => item.status === 'SAVED');
3948
const completed = planItems.filter((item) => item.status === 'COMPLETED');
@@ -123,12 +132,8 @@ export default function MyPlan({ screenSize, plan }: ScreenSizeProps & PlanProps
123132
key={item.id}
124133
item={item}
125134
onOpenDetails={handleOpenDetails}
126-
onMarkDone={(id) =>
127-
markPlanItemDone(id)
128-
}
129-
onRemove={(id) =>
130-
removePlanItem(id)
131-
}
135+
onMarkDone={(id) => markPlanItemDone(id)}
136+
onRemove={(id) => removePlanItem(id)}
132137
/>
133138
))
134139
)}

‎microcoach_v2/src/pages/Reflect.tsx‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ import Typography from '@mui/material/Typography';
88
import AppContentRow from '../components/AppContentRow';
99
import FlowNav, { FlowTabId } from '../components/FlowNav';
1010
import { ScreenSize } from '../lib/MicroCoachModels';
11-
import { useMisconceptions } from '../hooks/useMisconceptions';
11+
import { useMicroCoachDataState } from '../hooks/context/useMicroCoachDataContext';
1212
import { ContentPanel } from '../lib/styledcomponents/ActivityDetailStyledComponents';
1313
import {
1414
CountChip,
1515
ScreenSizeProps,
1616
} from '../lib/styledcomponents/ReviewStyledComponents';
1717
import { useAllReady, useI18nReady } from '../hooks/readiness';
18+
import mockPipelineOutput from '../lib/mocks/mockPipelineOutput.json';
19+
import { IPipelineOutput } from '../lib/PipelineModels';
1820

1921
/**
2022
* Reflect — the impact of the next steps the teacher actually ran.
@@ -28,7 +30,9 @@ export default function Reflect({ screenSize }: ScreenSizeProps) {
2830
const { t } = useTranslation();
2931
const theme = useTheme();
3032
const navigate = useNavigate();
31-
const { reflect, isReady: dataReady } = useMisconceptions();
33+
const { misconceptionsStatus } = useMicroCoachDataState();
34+
const { reflect } = mockPipelineOutput as unknown as IPipelineOutput;
35+
const dataReady = misconceptionsStatus === 'ready';
3236
const isReady = useAllReady(useI18nReady(), dataReady);
3337

3438
if (!isReady) return null;

0 commit comments

Comments
 (0)