Skip to content

Commit

Permalink
Make search panel scroll + fix styling
Browse files Browse the repository at this point in the history
  • Loading branch information
AaDalal committed Mar 8, 2024
1 parent c8316e6 commit 13116bb
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 46 deletions.
32 changes: 28 additions & 4 deletions frontend/degree-plan/components/Search/Course.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { ItemTypes } from "../dnd/constants";

import Badge from "./Badge";
import { Draggable } from "../common/DnD";
import { Course as CourseType } from "@/types";
import Skeleton from "react-loading-skeleton";
import 'react-loading-skeleton/dist/skeleton.css'

// import { Course as CourseType } from "../../types";
// import { Icon } from "../bulma_derived_components";

Expand Down Expand Up @@ -98,6 +102,28 @@ const InfoPopup = styled.div<{ $show: boolean }>`
box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1);
`;

export const SkeletonCourse = () => (
// eslint-disable-next-line
<RowSelectors>
<CourseContainer>
<CourseInfoContainer role="button">
<CourseIdentityContainer>
<CourseIDContainer>
<CourseID><Skeleton width="5rem"/></CourseID>
</CourseIDContainer>
<CourseTitle></CourseTitle>
</CourseIdentityContainer>
<CourseQualityContainer>
<Badge />
</CourseQualityContainer>
<CourseDifficultyContainer>
<Badge />
</CourseDifficultyContainer>
</CourseInfoContainer>
</CourseContainer>
</RowSelectors>
)

interface CourseProps {
course: CourseType;
onClick: () => void;
Expand All @@ -114,17 +140,15 @@ export default function Course({
isStar,
}: CourseProps) {
/** React dnd */
const [{ isDragging, color }, drag, dragPreview] = useDrag(() => ({
const [{ isDragging }, drag, dragPreview] = useDrag(() => ({
type: ItemTypes.COURSE,
item: {full_code: course.id, semester:-1},
collect: (monitor) => ({
isDragging: !!monitor.isDragging(),
color: monitor.isDragging() ? 'none' : 'none'
})
}))

return (
// eslint-disable-next-line
<RowSelectors>
<CourseContainer>
<CourseInfoContainer
Expand All @@ -134,7 +158,7 @@ export default function Course({
<CourseIdentityContainer ref={drag}>
<Draggable isDragging={isDragging}>
<CourseIDContainer>
<CourseID style={{color}}>{course.id.replace(/-/g, " ")}</CourseID>
<CourseID>{course.id.replace(/-/g, " ")}</CourseID>
</CourseIDContainer>
<CourseTitle>{course.title}</CourseTitle>
</Draggable>
Expand Down
29 changes: 8 additions & 21 deletions frontend/degree-plan/components/Search/ResultsList.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useRef } from "react";
import styled from '@emotion/styled';
import Course from "./Course";
import Course, { SkeletonCourse } from "./Course";
import { Course as CourseType, DegreePlan, Fulfillment, Rule, SortMode } from "../../types";
import { useSWRCrud } from "@/hooks/swrcrud";

Expand Down Expand Up @@ -71,8 +71,6 @@ const Header = styled.div`
const CoursesContainer = styled.ul`
height: 100%;
padding-left: 0;
overflow-y: auto;
overflow-x: hidden;
font-size: 0.7em;
list-style: none;
Expand All @@ -86,49 +84,38 @@ export interface CourseListProps {
courses: CourseType[];
getCourse: (id: string) => void;
sortMode: SortMode;
scrollPos: number;
setScrollPos: (pos: number) => void;
recCoursesId: string[];
activeDegreeplanId: DegreePlan["id"] | null;
ruleId: Rule["id"];
isLoading: boolean;
}
const ResultsList = ({
ruleId,
activeDegreeplanId,
courses,
sortMode,
scrollPos,
setScrollPos
isLoading
}: CourseListProps) => {
// TODO: what if activeDegreeplan is not defined
const { createOrUpdate } = useSWRCrud<Fulfillment>(`/api/degree/degreeplans/${activeDegreeplanId}/fulfillments`, { idKey: "full_code" });

const listRef = useRef<HTMLUListElement>(null);
useEffect(() => {
// Set sections list scroll position to stored position
if (listRef.current) {
listRef.current.scrollTop = scrollPos;
}
// Return cleanup function that stores current sections scroll position
return () => setScrollPos(listRef.current?.scrollTop || 0);
}, [scrollPos, setScrollPos]);

return (
<CourseListContainer>
<HeaderContainer>
<Header width="60%">COURSE</Header>
<Header width="20%">QUAL</Header>
<Header width="20%">DIFF</Header>
</HeaderContainer>
<CoursesContainer ref={listRef}>
{courses.map((course) =>
<CoursesContainer>
{!isLoading ? courses.map((course) =>
<Course
key={course.id + course.semester}
course={course}
onClick={() => createOrUpdate({ rules: [ruleId] }, course.full_code)}
isStar={false}
//showCourseDetail={} searchReqId={}
/>)}
/>) :
Array.from(Array(3).keys()).map(() => <SkeletonCourse />)
}
</CoursesContainer>
</CourseListContainer>
);
Expand Down
35 changes: 14 additions & 21 deletions frontend/degree-plan/components/Search/SearchPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { createContext, useContext } from "react";
import useSWR from "swr";
import ResultsList from "./ResultsList";
import styled from "@emotion/styled";
import { DegreePlan, Rule } from "@/types";
import { DegreePlan, Rule, Course as CourseType } from "@/types";
import { PanelHeader } from "../FourYearPlan/PanelCommon";
import { GrayIcon } from "../common/bulma_derived_components";

Expand All @@ -27,25 +27,28 @@ export const SearchPanelContext = createContext<SearchPanelContextType>({

const SearchPanelBody = styled.div`
margin: 10px;
overflow-y: auto;
`

const SearchPanelResult = styled.div`
margin-top: 8px;
`

const SearchContainer = styled.div`
margin: 0 0.5rem;
padding: .5rem .25rem;
background-color: var(--background-color-blue-grey);
position: sticky;
top: 0;
padding: .5rem .75rem;
background-color: var(--background-grey);
border-radius: .75rem;
display: flex;
align-items: center;
gap: 1rem;
`

const SearchField = styled.input`
flex-grow: 1;
flex: 1;
border: none;
outline: none;
color: black;
background: none;
font: inherit;
Expand Down Expand Up @@ -102,8 +105,6 @@ export const SearchPanel = ({ activeDegreeplanId }: { activeDegreeplanId: Degree
</SearchPanelHeader>
<SearchPanelBody>
<SearchContainer
role="button"
className="control has-icons-left"
>
<GrayIcon>
<i className="fas fa-search fa-lg" />
Expand All @@ -115,7 +116,7 @@ export const SearchPanel = ({ activeDegreeplanId }: { activeDegreeplanId: Degree
value={queryString}
onChange={(e) => {setQueryString(e.target.value)}}
autoComplete="off"
placeholder={ruleId == -1 ? "General Search!" : `Filtering for ${ruleQuery ? ruleQuery : 'requirement'}`}
placeholder={!ruleId ? "Search for a course!" : `Filtering for ${ruleQuery ? ruleQuery : 'a requirement'}`}
/>
</SearchContainer>
<SearchResult ruleId={ruleId} query={queryString} activeDegreeplanId={activeDegreeplanId}/>
Expand All @@ -141,30 +142,22 @@ export const useDebounce = (value: any, delay: number) => {
}

const buildSearchKey = (ruleId: Rule["id"] | null, query: string): string | null => {
return query.length >= 3 || ruleId !== null ? `api/base/all/search/courses?search=${query}${ruleId ? `&rule_ids=${ruleId}` : ""}` : null
return query.length >= 3 || ruleId ? `api/base/all/search/courses?search=${query}${ruleId ? `&rule_ids=${ruleId}` : ""}` : null
}

const SearchResult = ({ ruleId, query, activeDegreeplanId }: any) => {
const debouncedQuery = useDebounce(query, 400)
const [scrollPos, setScrollPos] = React.useState<number>(0);
const { data: courses = [], isLoading: isLoadingCourses, error } = useSWR(buildSearchKey(ruleId, debouncedQuery));
return (
<>
{isLoadingCourses ?
<LoadingComponentContainer>
<LoadingComponent>
loading courses...
</LoadingComponent>
</LoadingComponentContainer>
: <SearchPanelResult>
<ResultsList
<SearchPanelResult>
<ResultsList
activeDegreeplanId={activeDegreeplanId}
ruleId={ruleId}
courses={courses}
scrollPos={scrollPos}
setScrollPos={setScrollPos}
isLoading={isLoadingCourses}
/>
</SearchPanelResult>}
</SearchPanelResult>
</>
)
}
1 change: 1 addition & 0 deletions frontend/degree-plan/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
--background-white: #F7F9FC;
--background-blue-grey:#F7F9FC;
--background-light-grey: #F8F8F8;
--background-grey: #f5f5f5;

/* Edit mode */
--plus-button-color: #9FB5EF;
Expand Down

0 comments on commit 13116bb

Please sign in to comment.