Skip to content

Commit

Permalink
Merge pull request #58 from pennlabs/aag/uifixes
Browse files Browse the repository at this point in the history
UI Fixes
  • Loading branch information
AaDalal authored Mar 27, 2024
2 parents 5cd887b + 96b3be7 commit 53ebd75
Show file tree
Hide file tree
Showing 14 changed files with 195 additions and 180 deletions.
5 changes: 3 additions & 2 deletions frontend/degree-plan/components/Course/Course.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Draggable } from "../common/DnD";
import Skeleton from "react-loading-skeleton"
import 'react-loading-skeleton/dist/skeleton.css'

const COURSE_BORDER_RADIUS = "10px";
const COURSE_BORDER_RADIUS = "9px";

export const BaseCourseContainer = styled.div<{ $isDragging?: boolean, $isUsed: boolean, $isDisabled: boolean }>`
display: flex;
Expand All @@ -16,11 +16,12 @@ export const BaseCourseContainer = styled.div<{ $isDragging?: boolean, $isUsed:
min-width: 70px;
min-height: 35px;
border-radius: ${COURSE_BORDER_RADIUS};
padding: .5rem;
padding: .75rem;
text-wrap: nowrap;
cursor: ${props => props.$isDisabled || props.$isUsed ? "not-allowed" : "grab"};
opacity: ${props => props.$isDisabled || props.$isDragging ? 0.7 : 1};
background-color: ${props => props.$isDragging ? "#4B9AE7" : "var(--background-grey)"};
box-shadow: rgba(0, 0, 0, 0.01) 0px 6px 5px 0px, rgba(0, 0, 0, 0.04) 0px 0px 0px 1px;
`;

export const PlannedCourseContainer = styled(BaseCourseContainer)`
Expand Down
25 changes: 12 additions & 13 deletions frontend/degree-plan/components/FourYearPlan/DegreeModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
import useSWR, { useSWRConfig } from "swr";
import ModalContainer from "../common/ModalContainer";
import Select from "react-select";
import useSWRMutation from "swr/mutation";
import { schoolOptions } from "@/pages/OnboardingPage";

export type ModalKey =
| "plan-create"
Expand Down Expand Up @@ -116,7 +116,7 @@ const DegreeAddInterior = styled.div`
flex-direction: column;
gap: 2rem;
width: 100%;
padding: 1.2rem 2rem 280px;
padding: 1.2rem 2rem;
`;

interface RemoveDegreeProps {
Expand All @@ -133,12 +133,14 @@ interface ModalInteriorProps {
modalObject: DegreePlan | null | RemoveSemesterProps | RemoveDegreeProps;
setActiveDegreeplan: (arg0: DegreePlan | null) => void;
close: () => void;
modalRef: React.RefObject<HTMLSelectElement | null>;
}
const ModalInterior = ({
modalObject,
modalKey,
setActiveDegreeplan,
close,
modalRef
}: ModalInteriorProps) => {
const {
create: createDegreeplan,
Expand Down Expand Up @@ -166,12 +168,6 @@ const ModalInterior = ({
const { data: degrees, isLoading: isLoadingDegrees } =
useSWR<DegreeListing[]>(`/api/degree/degrees`);

const defaultSchools = ["BSE", "BA", "BAS", "BS"];
const schoolOptions = defaultSchools.map((d) => ({
value: d,
label: d,
}));

/** Create label for major listings */
const createMajorLabel = (degree: DegreeListing) => {
const concentration =
Expand Down Expand Up @@ -289,18 +285,21 @@ const ModalInterior = ({
isClearable
placeholder="Select School or Program"
isLoading={false}
styles={{ menuPortal: base => ({ ...base, zIndex: 999 }) }}
menuPortalTarget={modalRef.current}
/>
<Select
options={getMajorOptions()}
value={major}
onChange={(selectedOption) => setMajor(selectedOption)}
styles={{ menuPortal: base => ({ ...base, zIndex: 999 }) }}
menuPortalTarget={modalRef.current}
isClearable
isDisabled={!school}
placeholder={
school
? isLoadingDegrees
? "loading programs"
: "Major - Concentration"
: "Please Select Program First"
isLoadingDegrees
? "loading programs..."
: "Major - Concentration"
}
isLoading={isLoadingDegrees}
/>
Expand Down
2 changes: 1 addition & 1 deletion frontend/degree-plan/components/FourYearPlan/PlanPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ interface PlanPanelProps {
activeDegreeplan: DegreePlan | null;
degreeplans: DegreePlan[] | undefined;
isLoading: boolean;
currentSemester: string;
currentSemester?: string;
setShowOnboardingModal: (arg0: boolean) => void;
}

Expand Down
90 changes: 34 additions & 56 deletions frontend/degree-plan/components/FourYearPlan/Semesters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,7 @@ const getNextSemester = (semester: string) => {
}
};

const semesterCompare = (a, b) => {
const yearA = parseInt(a.substring(0, 4), 10);
const yearB = parseInt(b.substring(0, 4), 10);
const seasonA = a.substring(4);
const seasonB = b.substring(4);

if (yearA !== yearB) {
return yearA - yearB;
}
const seasonOrder = { A: 1, B: 2, C: 3 };
return seasonOrder[seasonA] - seasonOrder[seasonB];
};

const getLocalSemestersKey = (degreeplanId: DegreePlan["id"]) =>
export const getLocalSemestersKey = (degreeplanId: DegreePlan["id"]) =>
`PDP-${degreeplanId}-semesters`;

const SemestersContainer = styled.div`
Expand All @@ -45,13 +32,6 @@ const SemestersContainer = styled.div`
flex-wrap: wrap;
`;

// const AddSemesterContainer = styled.div`
// flex: 1 1 15rem;
// display: flex;
// flex-direction: column;
// gap: .5rem;
// `;

const AddSemesterContainer = styled.div`
background: #ffffff;
border-style: dashed;
Expand Down Expand Up @@ -86,7 +66,7 @@ const AddButton = styled.div`
gap: 1rem;
`;

const selectStyles = {
const selectStyles = (topOrBottom: boolean) => ({
control: (provided) => ({
...provided,
width: "130px",
Expand All @@ -97,12 +77,17 @@ const selectStyles = {
"&:hover": {
borderColor: "#9FB5EF",
},
...(
topOrBottom ?
{ borderBottomLeftRadius: 0, borderBottomRightRadius: 0, borderBottom: 0 } :
{ borderTopLeftRadius: 0, borderTopRightRadius: 0 }
)
}),
singleValue: (provided) => ({
...provided,
color: "#C1C1C1",
}),
};
});

// TODO: get a consistent color palette across PCx
interface ModifySemestersProps {
Expand All @@ -117,7 +102,7 @@ const ModifySemesters = ({
className,
}: ModifySemestersProps) => {
const latestSemester =
Object.keys(semesters).sort(semesterCompare).pop() || "2026A"; // TODO: Change fallback value to start semester (based on onboarding?)
Object.keys(semesters).sort((a, b) => a.localeCompare(b)).pop() || "2026A"; // TODO: Change fallback value to start semester (based on onboarding?)

const nextSemester = getNextSemester(latestSemester);
const [nextYear, nextSeason] = [
Expand Down Expand Up @@ -162,14 +147,14 @@ const ModifySemesters = ({
</AddButtonContainer>

<Select
styles={selectStyles}
styles={selectStyles(true)}
options={seasonOptions}
value={seasonOptions.find((option) => option.value === selectedSeason)}
onChange={(option) => setSelectedSeason(option.value)}
/>

<Select
styles={selectStyles}
styles={selectStyles(false)}
options={yearOptions}
value={yearOptions.find((option) => option.value === selectedYear)}
onChange={(option) => setSelectedYear(option.value)}
Expand All @@ -178,6 +163,15 @@ const ModifySemesters = ({
);
};

export const interpolateSemesters = (startingYear: number, graduationYear: number) => {
let res = {} as { [semester: string]: Fulfillment[] };
for (let year = startingYear; year < graduationYear; year++) {
res[`${year}C`] = [];
res[`${year + 1}A`] = []; // A is Spring, C is Fall
}
return res;
}

interface SemestersProps {
activeDegreeplan?: DegreePlan;
showStats: any;
Expand All @@ -187,7 +181,7 @@ interface SemestersProps {
setModalObject: (obj: any) => void;
setEditMode: (arg0: boolean) => void;
isLoading: boolean;
currentSemester: string;
currentSemester?: string;
}

const Semesters = ({
Expand All @@ -211,28 +205,8 @@ const Semesters = ({
// semesters is state mostly derived from fulfillments

const getDefaultSemesters = React.useCallback(() => {
if (!currentSemester) return {};

var startingYear, graduationYear;
if (typeof window === "undefined") {
startingYear = Number(currentSemester.substring(0, 4)); // Use current semester as default starting semester
graduationYear = startingYear + 4;
} else {
const startGradYearStr = localStorage.getItem("PDP-start-grad-years");
if (!!startGradYearStr) {
const startGradYear = JSON.parse(startGradYearStr);
startingYear = startGradYear.startingYear;
graduationYear = startGradYear.graduationYear;
} else {
return {};
}
}

var res = {} as { [semester: string]: Fulfillment[] };
for (var year = startingYear; year < graduationYear; year++) {
res = { ...res, [`${year}C`]: [], [`${year + 1}A`]: [] }; // A is Spring, C is Fall
}
return res;
const startingYear = currentSemester ? Number(currentSemester.substring(0, 4)) : new Date().getFullYear(); // Use current semester as default starting semester
return interpolateSemesters(startingYear, startingYear + 4);
}, [currentSemester]);

const [semesters, setSemesters] = useState<{
Expand All @@ -255,15 +229,19 @@ const Semesters = ({
/** Get semesters from local storage */
useEffect(() => {
if (!activeDegreeplan) return;
if (typeof window === "undefined")
return setSemesters(getDefaultSemesters()); // default state
if (typeof window === "undefined") return setSemesters(getDefaultSemesters());
const stickyValue = localStorage.getItem(
getLocalSemestersKey(activeDegreeplan.id)
);
setSemesters(
stickyValue !== null ? JSON.parse(stickyValue) : getDefaultSemesters()
);
}, [activeDegreeplan]);
if (stickyValue === null) return setSemesters(getDefaultSemesters());
let parsed;
try {
parsed = JSON.parse(stickyValue)
} catch {
setSemesters(getDefaultSemesters());
}
setSemesters(parsed);
}, [activeDegreeplan, currentSemester]);

/** Update semesters to local storage */
useEffect(() => {
Expand Down Expand Up @@ -305,7 +283,7 @@ const Semesters = ({
<SkeletonSemester showStats={showStats} />
))
: Object.keys(semesters)
.sort(semesterCompare)
.sort((a,b) => a.localeCompare(b))
.map((semester: any) => (
<FlexSemester
activeDegreeplanId={activeDegreeplan?.id}
Expand Down
5 changes: 2 additions & 3 deletions frontend/degree-plan/components/Infobox/InfoRatings.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ const RatingRow = ({
difficulty,
work
}) => {
const numOrNA = num => (isNaN(num) ? "N/A" : num.toFixed(1));
// TODO: After switching to styled-components or some other styling solution, refactor this code.
const numOrNA = num => (!num || isNaN(num) ? "N/A" : num.toFixed(1));
const getColor = (num, reverse) => {
if (isNaN(num)) {
if (!num || isNaN(num)) {
return "rating-good";
}
num = num.toFixed(1);
Expand Down
10 changes: 8 additions & 2 deletions frontend/degree-plan/components/Requirements/QObject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ const SearchConditionWrapper = styled(BaseCourseContainer)`
background-color: var(--primary-color-light);
box-shadow: 0px 0px 14px 2px rgba(0, 0, 0, 0.05);
cursor: pointer;
padding: .5rem .75rem;
`

const Wrap = styled.span`
Expand Down Expand Up @@ -180,11 +181,16 @@ const SearchCondition = ({ ruleId, ruleQuery, fulfillments, ruleIsSatisfied, q,

return (
<SearchConditionWrapper
$isDisabled={ruleIsSatisfied}>
$isDisabled={false}>
<SearchConditionInner q={q} />
<DarkGrayIcon onClick={() => {
setSearchRuleQuery(ruleQuery);
setSearchRuleId(ruleId);
if ((q.type === "OR" || q.type === "AND") && q.clauses.length == 0) {
// only set search ruleId if the search rule is non-empty
setSearchRuleId(null);
} else {
setSearchRuleId(ruleId)
}
setSearchPanelOpen(true);
setSearchFulfillments(fulfillments)
}}>
Expand Down
13 changes: 7 additions & 6 deletions frontend/degree-plan/components/Requirements/ReqPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import useSWR from 'swr';
import { Icon } from '../common/bulma_derived_components';
import React from 'react';
import { ModalKey } from '../FourYearPlan/DegreeModal';
import { TrashIcon } from '../common/TrashIcon';
import { LightTrashIcon } from '../common/TrashIcon';

const EmptyPanelContainer = styled.div`
display: flex;
Expand Down Expand Up @@ -39,7 +39,8 @@ const DegreeHeaderContainer = styled.div`
align-items: center;
font-size: 1rem;
font-weight: 500;
background-color: var(--primary-color);
background-color: var(--primary-color-xx-dark);
color: #FFF;
padding: 0.75rem 1.25rem;
border-radius: var(--req-item-radius);
`
Expand All @@ -50,6 +51,7 @@ const ReqPanelTitle = styled.div`
`

const DegreeBody = styled.div`
margin-top: .5rem;
overflow-y: auto;
overflow-x: hidden;
`
Expand All @@ -58,9 +60,8 @@ export const DegreeYear = styled.span`
margin-left: .25rem;
font-size: .9rem;
font-weight: 500;
color: #575757;
`
const DegreeTitleWrapper = styled.div`
const DegreeTitleWrapper = styled.div`
display: flex;
flex-direction: row;
align-items: center;
Expand Down Expand Up @@ -107,9 +108,9 @@ const DegreeHeader = ({ degree, remove, setCollapsed, collapsed, editMode, skele
</DegreeTitleWrapper>
<span>
{!skeleton && !!editMode ?
<TrashIcon role="button" onClick={() => remove(degree.id)}>
<LightTrashIcon role="button" onClick={() => remove(degree.id)}>
<i className="fa fa-trash fa-md"/>
</TrashIcon>
</LightTrashIcon>
:
<Icon>
<i className={`fas fa-chevron-${collapsed ? "up" : "down"}`}></i>
Expand Down
Loading

0 comments on commit 53ebd75

Please sign in to comment.