Skip to content

Commit

Permalink
refactor: search page and utils
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinWu098 committed Apr 3, 2024
1 parent 86b7c89 commit 9034569
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 150 deletions.
6 changes: 1 addition & 5 deletions __tests__/search-filters.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { FilterValues } from "@/components/search/Search";
import {
endsBefore,
filterData,
startsAfter,
} from "@/components/search/filter-utils";
import { endsBefore, filterData, startsAfter } from "@/lib/utils/filter";
import "@testing-library/jest-dom";

const data = {
Expand Down
276 changes: 136 additions & 140 deletions components/search/Search.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
"use client";

import React, { useEffect, useState } from "react";
import { SortDropdown } from "./FilterComponents";
import { SortDropdown } from "./filter/FilterComponents";
import { useRouter, useSearchParams } from "next/navigation";
import { queryDatabase } from "./query-db";
import { queryDatabase } from "../../lib/utils/query-db";
import SearchResults from "./SearchResults";
import ScrollToTop from "./ScrollToTop";
import { FaFilter } from "react-icons/fa6";
import { SearchFilterPage, SearchFilters } from "./Filters";
import { SearchFilterPage, SearchFilters } from "./filter/Filters";
import Blurb from "./Blurb";
import { filterData } from "./filter-utils";
import { filterData } from "../../lib/utils/filter";
import { UNIVERSITY_GE } from "@/lib/constants";

import { analyticsEnum, logAnalytics } from "@/lib/analytics";
import { useToast } from "../ui/use-toast";
import { ToastAction } from "../ui/toast";
import Link from "next/link";
import { SearchSelect } from "./SearchSelect";
import { getDismissedRecently, getNumSearches } from "@/lib/utils/search";

export interface CollegeObject {
sendingInstitution: string;
Expand Down Expand Up @@ -52,6 +53,38 @@ export type FilterValues = {
sort: string;
};

const FILTER_PAGE_BREAKPOINT = 1280;

const LoadingState = () => {
return (
<div className="mt-16 flex flex-col gap-2 text-2xl">
<div className="flex justify-center">
<img
src="/loading.gif"
alt="loading gif"
className="flex h-16 w-16 justify-center opacity-60"
/>
</div>
<div className="flex justify-center">Loading...</div>
</div>
);
};

const ErrorState = () => {
return (
<div className="mt-16 flex flex-col gap-2 text-2xl">
<div className="flex justify-center">
<img
src="/error.png"
alt="error"
className="flex w-[500px] justify-center"
/>
</div>
<div className="flex justify-center">An error occurred...</div>
</div>
);
};

const Search = () => {
const router = useRouter();
const searchParams = useSearchParams();
Expand Down Expand Up @@ -124,8 +157,6 @@ const Search = () => {
setOpen((open) => !open);
};

const maxWidthForOpen = 1280;

const handleResize = () => {
setWidth(window.innerWidth);
};
Expand Down Expand Up @@ -170,17 +201,8 @@ const Search = () => {
setLoading(false);
setError(false);

const enjoymentDismissalTime = window.localStorage.getItem(
"enjoymentDismissalTime",
);
const dismissedRecently =
enjoymentDismissalTime !== null &&
Date.now() - parseInt(enjoymentDismissalTime) <
4 * 7 * 24 * 3600 * 1000;

const gezSearches = window.localStorage.getItem("gezSearches");

const numSearches = gezSearches ? parseInt(gezSearches) : 0;
const dismissedRecently = getDismissedRecently();
const numSearches = getNumSearches();

if (!dismissedRecently && numSearches > 2) {
toast({
Expand Down Expand Up @@ -239,141 +261,115 @@ const Search = () => {
fetchData();
}, [university, ge, toast]);

if (open && width < FILTER_PAGE_BREAKPOINT) {
return (
<SearchFilterPage
handleClick={handleFilterButtonClick}
setFormat={setFormat}
setEnrollment={setEnrollment}
setAvailable={setAvailable}
setStart={setStart}
setEnd={setEnd}
setInstitution={setInstitution}
setMin={setMin}
setMax={setMax}
filterValues={filterValues}
courses={courses}
/>
);
}

return (
<>
{open && width < maxWidthForOpen ? (
<SearchFilterPage
handleClick={handleFilterButtonClick}
setFormat={setFormat}
setEnrollment={setEnrollment}
setAvailable={setAvailable}
setStart={setStart}
setEnd={setEnd}
setInstitution={setInstitution}
setMin={setMin}
setMax={setMax}
<div className="wrapper my-8 min-h-[calc(100vh-96px)] px-4 md:my-16 lg:px-28 xl:px-36">
<div className="flex flex-wrap text-6xl font-bold">
Search <span className="hidden lg:flex">&nbsp;For Courses</span>
</div>
<div className="mt-8 flex flex-row items-center justify-between">
<div className="flex w-full flex-row flex-wrap gap-x-4 gap-y-2">
<SearchSelect
value={university}
data={Object.keys(UNIVERSITY_GE)}
onChange={handleUniversityChange}
placeholder="University"
/>
<SearchSelect
value={ge}
data={UNIVERSITY_GE[university]}
onChange={handleGeChange}
placeholder="Category"
/>
</div>
</div>

<div>
<Blurb
filterData={filterData}
data={courses}
filterValues={filterValues}
courses={courses}
/>
) : (
<div className="wrapper my-8 min-h-[calc(100vh-96px)] px-4 md:my-16 lg:px-28 xl:px-36">
<div className="flex flex-wrap text-6xl font-bold">
Search{" "}
<span className="hidden lg:flex">
&nbsp;For Courses
</span>
</div>
<div className="mt-8 flex flex-row items-center justify-between">
<div className="flex w-full flex-row flex-wrap gap-x-4 gap-y-2">
<SearchSelect
value={university}
data={Object.keys(UNIVERSITY_GE)}
onChange={handleUniversityChange}
placeholder="University"
/>
<SearchSelect
value={ge}
data={UNIVERSITY_GE[university]}
onChange={handleGeChange}
placeholder="Category"
/>
<div className="mt-8 flex flex-row gap-4 md:mt-16 md:gap-8">
<div className="hidden h-fit rounded-xl bg-bg_secondary p-8 xl:flex xl:flex-col">
<div className="mb-8 text-3xl font-medium">
Search Filters
</div>
</div>
<div>
<Blurb
filterData={filterData}
data={courses}
<SearchFilters
handleClick={handleFilterButtonClick}
setFormat={setFormat}
setEnrollment={setEnrollment}
setAvailable={setAvailable}
setStart={setStart}
setEnd={setEnd}
setInstitution={setInstitution}
setMin={setMin}
setMax={setMax}
filterValues={filterValues}
courses={courses}
/>
<div className="mt-8 flex flex-row gap-4 md:mt-16 md:gap-8">
<div className="hidden h-fit rounded-xl bg-bg_secondary p-8 xl:flex xl:flex-col">
<div className="mb-8 text-3xl font-medium">
Search Filters
</div>
<SearchFilters
handleClick={handleFilterButtonClick}
setFormat={setFormat}
setEnrollment={setEnrollment}
setAvailable={setAvailable}
setStart={setStart}
setEnd={setEnd}
setInstitution={setInstitution}
setMin={setMin}
setMax={setMax}
filterValues={filterValues}
courses={courses}
/>
</div>
</div>

<div className="w-full xl:min-w-[65%]">
<div className="mb-8 flex flex-wrap items-center justify-between gap-y-4 xl:justify-end">
<button
onClick={handleFilterButtonClick}
className="flex items-center gap-2 rounded-full border-2 bg-primary px-4 py-2 text-white transition-all active:border-primary active:bg-transparent active:text-primary xl:hidden"
>
<FaFilter />
Search Filters
</button>

<div className="flex items-center gap-4 md:flex-row">
<div className="hidden text-gray sm:flex">
Sort By:
</div>
<SortDropdown
defaultValue={sort}
data={[
"Default Sort",
"Alphabetical",
"Tuition",
"Shortest Term",
]}
onChange={setSort}
/>
</div>
<div className="w-full xl:min-w-[65%]">
<div className="mb-8 flex flex-wrap items-center justify-between gap-y-4 xl:justify-end">
<button
onClick={handleFilterButtonClick}
className="flex items-center gap-2 rounded-full border-2 bg-primary px-4 py-2 text-white transition-all active:border-primary active:bg-transparent active:text-primary xl:hidden"
>
<FaFilter />
Search Filters
</button>

<div className="flex items-center gap-4 md:flex-row">
<div className="hidden text-gray sm:flex">
Sort By:
</div>
{loading ? (
<div className="mt-16 flex flex-col gap-2 text-2xl">
<div className="flex justify-center">
<img
src="/loading.gif"
alt="loading gif"
className="flex h-16 w-16 justify-center opacity-60"
/>
</div>
<div className="flex justify-center">
Loading...
</div>
</div>
) : error ? (
<div className="mt-16 flex flex-col gap-2 text-2xl">
<div className="flex justify-center">
<img
src="/error.png"
alt="error"
className="flex w-[500px] justify-center"
/>
</div>
<div className="flex justify-center">
An error occurred...
</div>
</div>
) : (
<SearchResults
results={filterData(
courses,
filterValues,
)}
university={university}
ge={ge}
/>
)}
<ScrollToTop />
<SortDropdown
defaultValue={sort}
data={[
"Default Sort",
"Alphabetical",
"Tuition",
"Shortest Term",
]}
onChange={setSort}
/>
</div>
</div>

{loading ? (
<LoadingState />
) : error ? (
<ErrorState />
) : (
<SearchResults
results={filterData(courses, filterValues)}
university={university}
ge={ge}
/>
)}
<ScrollToTop />
</div>
</div>
)}
</>
</div>
</div>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import React, { ChangeEvent, Dispatch, SetStateAction, useState } from "react";
import { FaCheck, FaChevronDown } from "react-icons/fa";
import { CollegeObject } from "./Search";
import { CollegeObject } from "../Search";
import { format } from "date-fns";

import { Calendar } from "@/components/ui/calendar";
Expand All @@ -12,7 +12,7 @@ import {
PopoverTrigger,
} from "@/components/ui/popover";

import { Button } from "../ui/button";
import { Button } from "../../ui/button";
import { CalendarIcon } from "lucide-react";
import { cn } from "@/lib/utils";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
UnitsFilter,
} from "./FilterComponents";
import { FaCircleXmark } from "react-icons/fa6";
import { CollegeObject, FilterValues } from "./Search";
import { CollegeObject, FilterValues } from "../Search";

interface SearchFilterProps {
handleClick: () => void;
Expand Down
2 changes: 1 addition & 1 deletion components/search/filter-utils.ts → lib/utils/filter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CollegeObject, FilterValues } from "./Search";
import { CollegeObject, FilterValues } from "../../components/search/Search";

export const startsAfter = (start: Date, result: CollegeObject) => {
const month = result.startMonth.toString().padStart(2, "0");
Expand Down
2 changes: 1 addition & 1 deletion components/search/query-db.ts → lib/utils/query-db.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CollegeObject } from "./Search";
import { CollegeObject } from "../../components/search/Search";

const cache: Record<string, [Date, CollegeObject[]]> = {};

Expand Down
Loading

0 comments on commit 9034569

Please sign in to comment.