Skip to content

Commit dbcaaf0

Browse files
committed
autoscroll to current semester
1 parent 080c6e0 commit dbcaaf0

7 files changed

Lines changed: 264 additions & 247 deletions

File tree

frontend/degree-plan/components/FourYearPlan/OnboardingTutorial.tsx

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -137,25 +137,14 @@ interface TutorialModalContextProps {
137137
tutorialModalKey: TutorialModalKey;
138138
setTutorialModalKey: (key: TutorialModalKey) => void;
139139
highlightedComponentRef: any;
140-
// componentRefs: any[];
141-
// requirementsPanelRef: any;
142-
// editButtonRef: any;
143-
// calendarPanelRef: any;
144-
// pastSemestersRef: any;
145-
// currentSemesterRef: any;
146-
// futureSemestersRef: any;
147-
// editModeRef: any;
148-
// showStatsRef: any;
149-
// coursesDockRef: any;
150-
// generalSearchRef: any;
151-
// setHighlightedComponent: (component: any) => void;
140+
componentRefs: any;
152141
}
153142

154143
export const TutorialModalContext = createContext<TutorialModalContextProps>({
155144
tutorialModalKey: null,
156145
setTutorialModalKey: (key: TutorialModalKey) => { }, // placeholder
157146
highlightedComponentRef: null,
158-
// componentRefs: [],
147+
componentRefs: null,
159148
// setHighlightedComponent: (component: any) => { } // placeholder
160149
});
161150

@@ -192,7 +181,7 @@ const ModalInterior = ({
192181
case "edit-mode":
193182
return "-65%";
194183
case "show-stats":
195-
return "-65%";
184+
return "-62%";
196185
case "courses-dock":
197186
return "60%";
198187
case "general-search":
@@ -207,7 +196,7 @@ const ModalInterior = ({
207196
const leftLocation = () => {
208197
switch (modalKey) {
209198
case "welcome":
210-
return "-10%";
199+
return "0%";
211200
case "requirements-panel-1":
212201
return "-25%";
213202
case "requirements-panel-2":
@@ -237,6 +226,15 @@ const ModalInterior = ({
237226
}
238227
}
239228

229+
const arrowLocation = () => {
230+
switch (modalKey) {
231+
case "welcome":
232+
return { top: 0, left: 0 };
233+
case "requirements-panel-1":
234+
return { top: 50, left: 50 };
235+
}
236+
}
237+
240238
return (
241239
<>
242240
<ModalBackground />

frontend/degree-plan/components/FourYearPlan/OnboardingTutorialPanel.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ const ModalContainer = styled.div<{ $top?: string; $left?: string; $position?: s
1717
color: #4a4a4a;
1818
`;
1919

20-
21-
2220
const ModalCard = styled.div`
2321
max-width: 400px !important;
2422
max-height: 400px !important;
@@ -64,17 +62,18 @@ const ModalCardBody = styled.div`
6462
display: block;
6563
`;
6664

67-
const ModalCardArrow = styled.div`
65+
const ModalCardArrow = styled.div<{ $top?: number, $left?: number, $rotation?: number }>`
6866
position: relative;
69-
top: 20%;
70-
left: -20%;
67+
top: ${({ $top }) => $top || 0}%;
68+
left: ${({ $left }) => $left || 0}%;
7169
width: 0;
7270
height: 0;
7371
border-left: 10px solid transparent;
7472
border-right: 10px solid white;
7573
border-top: 10px solid transparent;
7674
border-bottom: 10px solid transparent;
77-
border-right-color: red;
75+
transform: rotate(${({ $rotation }) => $rotation || 90}deg);
76+
z-index: 1;
7877
`;
7978

8079
const CloseButton = styled.button`
@@ -99,6 +98,7 @@ interface PanelProps {
9998
left?: string;
10099
position?: string;
101100
headerIcon?: string;
101+
arrowPosition?: { top?: number, left?: number };
102102
close?: () => void;
103103
}
104104

@@ -109,11 +109,12 @@ const OnboardingTutorialPanel = ({
109109
left,
110110
position,
111111
headerIcon,
112+
arrowPosition,
112113
close,
113114
}: PropsWithChildren<PanelProps>) => (
114115
<ModalContainer $top={top} $left={left} $position={position}>
115116
{/* <ModalBackground /> */}
116-
{/* <ModalCardArrow /> */}
117+
{/* <ModalCardArrow $top={arrowPosition?.top} $left={15} /> */}
117118
<ModalCard>
118119
<ModalCardHead $center={!headerIcon}>
119120
<header>{title}</header>

frontend/degree-plan/components/FourYearPlan/PlanPanel.tsx

Lines changed: 54 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import SelectListDropdown from "./SelectListDropdown";
22
import Semesters from "./Semesters";
33
import styled from "@emotion/styled";
44
import type { DegreePlan } from "@/types";
5-
import React, { useEffect, useState, forwardRef, useContext } from "react";
5+
import React, { useEffect, useState, useContext } from "react";
66
import { useSWRCrud } from '@/hooks/swrcrud';
77
import { EditButton } from './EditButton';
88
import { PanelTopBarButton, PanelTopBarIcon } from "./PanelCommon";
@@ -37,7 +37,7 @@ interface PlanPanelProps {
3737
setShowOnboardingModal: (arg0: boolean) => void;
3838
}
3939

40-
const PlanPanel = forwardRef(({
40+
const PlanPanel = ({
4141
setModalKey,
4242
modalKey,
4343
setModalObject,
@@ -47,81 +47,78 @@ const PlanPanel = forwardRef(({
4747
degreeplans,
4848
isLoading,
4949
currentSemester,
50-
}: PlanPanelProps, semesterRefs) => {
50+
}: PlanPanelProps) => {
5151
const { copy: copyDegreeplan } = useSWRCrud<DegreePlan>('/api/degree/degreeplans');
5252
const [showStats, setShowStats] = useState(true);
5353
const [editMode, setEditMode] = useState(false);
5454

55-
const { tutorialModalKey, highlightedComponentRef } = useContext(TutorialModalContext);
55+
const { tutorialModalKey, componentRefs } = useContext(TutorialModalContext);
5656
const planPanelRef = React.useRef<HTMLDivElement | null>(null);
5757

5858
useEffect(() => {
5959
if (!planPanelRef.current) return;
6060

6161
if (tutorialModalKey === "calendar-panel" || tutorialModalKey === "current-semester" || tutorialModalKey === "future-semesters" || tutorialModalKey === "past-semesters" || tutorialModalKey === "edit-mode" || tutorialModalKey === "show-stats") {
6262
planPanelRef.current.style.zIndex = "11";
63-
highlightedComponentRef.current = planPanelRef.current;
63+
componentRefs.current["planPanel"] = planPanelRef.current;
6464
} else {
6565
planPanelRef.current.style.zIndex = "0";
6666
}
67-
}, [tutorialModalKey, highlightedComponentRef]);
67+
}, [tutorialModalKey, componentRefs]);
6868

6969
return (
70-
<div style={{ position: "relative" }} ref={(el) => {
70+
<PanelContainer style={{ position: "relative" }} ref={(el) => {
7171
planPanelRef.current = el;
7272
if (tutorialModalKey === "calendar-panel" || tutorialModalKey === "current-semester" || tutorialModalKey === "future-semesters" || tutorialModalKey === "past-semesters" || tutorialModalKey === "edit-mode" || tutorialModalKey === "show-stats") {
73-
highlightedComponentRef.current = el;
73+
componentRefs.current["planPanel"] = el;
7474
}
7575
}}>
76-
<PanelContainer>
77-
<PanelHeader>
78-
<SelectListDropdown
79-
itemType="degree plan"
80-
active={activeDegreeplan || undefined}
81-
getItemName={(item: DegreePlan) => item.name}
82-
allItems={degreeplans || []}
83-
selectItem={(id: DegreePlan["id"]) => setActiveDegreeplan(degreeplans?.filter(d => d.id === id)[0] || null)}
84-
mutators={{
85-
copy: (item: DegreePlan) => {
86-
(copyDegreeplan({ ...item, name: `${item.name} (copy)` }, item.id) as Promise<any>)
87-
.then((copied) => copied && setActiveDegreeplan(copied.id))
88-
},
89-
remove: (item: DegreePlan) => {
90-
setModalKey("plan-remove")
91-
setModalObject(item)
92-
},
93-
rename: (item: DegreePlan) => {
94-
setModalKey("plan-rename")
95-
setModalObject(item)
96-
},
97-
create: () => {
98-
setShowOnboardingModal(true);
99-
}
100-
}}
101-
isLoading={isLoading}
102-
/>
103-
<PanelTopBarIconList>
104-
<ShowStatsButton showStats={showStats} setShowStats={setShowStats} />
105-
<EditButton editMode={editMode} setEditMode={setEditMode} />
106-
</PanelTopBarIconList>
107-
</PanelHeader>
108-
{/** map to semesters */}
109-
<PanelBody>
110-
<Semesters
111-
activeDegreeplan={activeDegreeplan || undefined}
112-
showStats={showStats}
113-
editMode={editMode}
114-
setEditMode={setEditMode}
115-
setModalKey={setModalKey}
116-
setModalObject={setModalObject}
117-
isLoading={isLoading}
118-
currentSemester={currentSemester}
119-
// ref={semesterRefs}
120-
/>
121-
</PanelBody>
122-
</PanelContainer>
123-
</div>
76+
<PanelHeader>
77+
<SelectListDropdown
78+
itemType="degree plan"
79+
active={activeDegreeplan || undefined}
80+
getItemName={(item: DegreePlan) => item.name}
81+
allItems={degreeplans || []}
82+
selectItem={(id: DegreePlan["id"]) => setActiveDegreeplan(degreeplans?.filter(d => d.id === id)[0] || null)}
83+
mutators={{
84+
copy: (item: DegreePlan) => {
85+
(copyDegreeplan({ ...item, name: `${item.name} (copy)` }, item.id) as Promise<any>)
86+
.then((copied) => copied && setActiveDegreeplan(copied.id))
87+
},
88+
remove: (item: DegreePlan) => {
89+
setModalKey("plan-remove")
90+
setModalObject(item)
91+
},
92+
rename: (item: DegreePlan) => {
93+
setModalKey("plan-rename")
94+
setModalObject(item)
95+
},
96+
create: () => {
97+
setShowOnboardingModal(true);
98+
}
99+
}}
100+
isLoading={isLoading}
101+
/>
102+
<PanelTopBarIconList>
103+
<ShowStatsButton showStats={showStats} setShowStats={setShowStats} />
104+
<EditButton editMode={editMode} setEditMode={setEditMode} />
105+
</PanelTopBarIconList>
106+
</PanelHeader>
107+
{/** map to semesters */}
108+
<PanelBody>
109+
<Semesters
110+
activeDegreeplan={activeDegreeplan || undefined}
111+
showStats={showStats}
112+
editMode={editMode}
113+
setEditMode={setEditMode}
114+
setModalKey={setModalKey}
115+
setModalObject={setModalObject}
116+
isLoading={isLoading}
117+
currentSemester={currentSemester}
118+
/>
119+
</PanelBody>
120+
</PanelContainer>
124121
);
125-
});
122+
};
126123

127124
export default PlanPanel;

frontend/degree-plan/components/FourYearPlan/Semester.tsx

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useRef, useEffect, forwardRef } from "react";
1+
import React, { useState, useRef, useEffect, useContext } from "react";
22
import { useDrag, useDrop } from "react-dnd";
33
import { ItemTypes } from "../dnd/constants";
44
import CoursesPlanned, { SkeletonCoursesPlanned } from "./CoursesPlanned";
@@ -12,6 +12,7 @@ import 'react-loading-skeleton/dist/skeleton.css'
1212
import { mutate } from "swr";
1313
import { ModalKey } from "./DegreeModal";
1414
import { TRANSFER_CREDIT_SEMESTER_KEY } from "@/constants";
15+
import { SemestersContext } from "./Semesters";
1516

1617
const SEMESTER_REGEX = /\d{4}[ABC]/
1718

@@ -118,7 +119,7 @@ interface SemesterProps {
118119
isLoading?: boolean
119120
}
120121

121-
const FlexSemester = forwardRef<HTMLDivElement, SemesterProps>(({
122+
const FlexSemester = ({
122123
showStats,
123124
semester,
124125
fulfillments,
@@ -129,7 +130,9 @@ const FlexSemester = forwardRef<HTMLDivElement, SemesterProps>(({
129130
removeSemester,
130131
currentSemester,
131132
isLoading = false
132-
}, ref) => {
133+
}: SemesterProps) => {
134+
const { semesterRefs } = useContext(SemestersContext);
135+
133136
const credits = fulfillments.reduce((acc, curr) => acc + (curr.course?.credits || 1), 0)
134137

135138
const { createOrUpdate: addToDock } = useSWRCrud<DockedCourse>(`/api/degree/docked`, { idKey: 'full_code' });
@@ -185,17 +188,17 @@ const FlexSemester = forwardRef<HTMLDivElement, SemesterProps>(({
185188
ref={drop}
186189
$semesterComparison={currentSemester ? semester.localeCompare(currentSemester) : 1}
187190
>
188-
<div ref={ref}>
189-
<SemesterHeader>
190-
<SemesterLabel>
191-
{translateSemester(semester)}
192-
</SemesterLabel>
193-
{!!editMode &&
194-
<TrashIcon role="button" onClick={handleRemoveSemester}>
195-
<i className="fa fa-trash fa-md" />
196-
</TrashIcon>}
197-
</SemesterHeader>
198-
</div>
191+
<SemesterHeader ref={(el) => {
192+
semesterRefs.current[semester] = el;
193+
}}>
194+
<SemesterLabel>
195+
{translateSemester(semester)}
196+
</SemesterLabel>
197+
{!!editMode &&
198+
<TrashIcon role="button" onClick={handleRemoveSemester}>
199+
<i className="fa fa-trash fa-md" />
200+
</TrashIcon>}
201+
</SemesterHeader>
199202
<SemesterContent>
200203
<FlexCoursesPlanned
201204
semester={semester}
@@ -208,6 +211,6 @@ const FlexSemester = forwardRef<HTMLDivElement, SemesterProps>(({
208211
</CreditsLabel>
209212
</SemesterCard>
210213
)
211-
});
214+
};
212215

213216
export default FlexSemester;

frontend/degree-plan/components/FourYearPlan/Semesters.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import styled from "@emotion/styled";
33
import { Icon } from "../common/bulma_derived_components";
44
import { Course, DegreePlan, Fulfillment } from "@/types";
55
import useSWR from "swr";
6-
import React, { useEffect, useState, forwardRef } from "react";
6+
import React, { useEffect, useState } from "react";
77
import Select from "react-select";
88
import { ModalKey } from "./DegreeModal";
99

@@ -182,6 +182,14 @@ export const interpolateSemesters = (startingYear: number, graduationYear: numbe
182182
return res;
183183
}
184184

185+
interface SemestersContextProps {
186+
semesterRefs: React.MutableRefObject<{ [semester: string]: HTMLDivElement | null }>;
187+
}
188+
189+
export const SemestersContext = React.createContext<SemestersContextProps>({
190+
semesterRefs: { current: {} },
191+
});
192+
185193
interface SemestersProps {
186194
activeDegreeplan?: DegreePlan;
187195
showStats: any;
@@ -195,7 +203,7 @@ interface SemestersProps {
195203
ref?: any;
196204
}
197205

198-
const Semesters = forwardRef(({
206+
const Semesters = ({
199207
activeDegreeplan,
200208
showStats,
201209
className,
@@ -205,7 +213,7 @@ const Semesters = forwardRef(({
205213
setEditMode,
206214
currentSemester,
207215
isLoading
208-
}: SemestersProps, semesterRefs) => {
216+
}: SemestersProps) => {
209217
const { data: fulfillments, isLoading: isLoadingFulfillments } = useSWR<
210218
Fulfillment[]
211219
>(
@@ -307,8 +315,6 @@ const Semesters = forwardRef(({
307315
setModalKey={setModalKey}
308316
setModalObject={setModalObject}
309317
currentSemester={currentSemester}
310-
/* @ts-ignore */
311-
// ref={(el) => (semesterRefs.current[semester] = el)}
312318
/>
313319
)
314320
}
@@ -319,6 +325,6 @@ const Semesters = forwardRef(({
319325
}
320326
</SemestersContainer >
321327
);
322-
});
328+
};
323329

324330
export default Semesters;

0 commit comments

Comments
 (0)