Skip to content

Commit

Permalink
feat: switch to React Context
Browse files Browse the repository at this point in the history
  • Loading branch information
jakeaturner committed May 23, 2024
1 parent a2f57b6 commit 5870147
Show file tree
Hide file tree
Showing 26 changed files with 243 additions and 200 deletions.
5 changes: 3 additions & 2 deletions app/(authorized)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import NavMenu from "@/components/NavMenu";
import DemoModeControls from "@/components/DemoModeControls";
import { validateRequest } from "@/lib/auth";
import { redirect } from "next/navigation";
import SessionToContextProvider from "@/components/SessionToContextProvider";

const inter = Inter({ subsets: ["latin"] });

Expand All @@ -29,7 +30,7 @@ export default async function RootLayout({
className={classNames(inter.className, "container mt-4 default-layout")}
>
<Providers>
<>
<SessionToContextProvider>
{process.env.NODE_ENV === "development" && (
<div className="tw-flex tw-flex-row tw-items-center tw-justify-center">
<DemoModeControls />
Expand All @@ -41,7 +42,7 @@ export default async function RootLayout({
</div>
<div className="tw-flex tw-ml-6 !tw-w-full">{children}</div>
</div>
</>
</SessionToContextProvider>
</Providers>
</body>
</html>
Expand Down
6 changes: 2 additions & 4 deletions app/(authorized)/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Image from "next/image";

const PageLoadingIndicator = () => {
export default function Loading() {
return (
<div className="tw-w-full tw-flex tw-flex-col tw-items-center tw-align-center">
<Image
Expand All @@ -16,6 +16,4 @@ const PageLoadingIndicator = () => {
</div>
</div>
);
};

export default PageLoadingIndicator;
}
41 changes: 13 additions & 28 deletions app/(authorized)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,20 @@
"use client";
import InstructorDashboard from "@/components/InstructorDashboard";
import StudentDashboard from "@/components/StudentDashboard";
import { IUser_Raw } from "@/lib/models/user";
import { globalStateAtom } from "@/state/globalState";
import axios from "axios";
import { useAtom } from "jotai";
import { useEffect } from "react";
import { Suspense } from "react";
import Loading from "./loading";
import { useGlobalContext } from "@/state/globalContext";

export default function Dashboard() {
const [globalState, setGlobalState] = useAtom(globalStateAtom);
const [globalState] = useGlobalContext();

useEffect(() => {
async function fetchData() {
const res = await axios.get("/api/auth/session");
if (!res.data?.user) return;
updateStateFromSession(res.data.user);
}
fetchData();
}, []);

function updateStateFromSession(userData: IUser_Raw) {
setGlobalState((prev) => ({
...prev,
role: userData?.role,
viewAs: userData?.role,
courseID: userData?.courses[0] || "",
}));
}

if (globalState.viewAs === "instructor") {
return <InstructorDashboard course_id={globalState.courseID} />;
}
return <StudentDashboard course_id={globalState.courseID} />;
return (
<Suspense fallback={<Loading />}>
{globalState.viewAs === "instructor" ? (
<InstructorDashboard course_id={globalState.courseID} />
) : (
<StudentDashboard course_id={globalState?.courseID ?? ""} />
)}
</Suspense>
);
}
18 changes: 9 additions & 9 deletions app/(authorized)/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { useState } from "react";
import { ReactQueryStreamedHydration } from "@tanstack/react-query-next-experimental";
import { Provider as JotaiProvider } from "jotai";
import { GlobalContextProvider } from "@/state/globalContext";

export function Providers(props: { children: React.ReactNode }) {
const [queryClient] = useState(
Expand All @@ -20,13 +20,13 @@ export function Providers(props: { children: React.ReactNode }) {
);

return (
<JotaiProvider>
<QueryClientProvider client={queryClient}>
<ReactQueryStreamedHydration>
{props.children}
</ReactQueryStreamedHydration>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</JotaiProvider>
<GlobalContextProvider>
<QueryClientProvider client={queryClient}>
<ReactQueryStreamedHydration>
{props.children}
</ReactQueryStreamedHydration>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</GlobalContextProvider>
);
}
3 changes: 2 additions & 1 deletion app/(authorized)/raw-data/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import PageHeader from "@/components/PageHeader";
import GenericPageContainer from "@/components/GenericPageContainer";
import RawDataTable from "@/components/RawDataTable";
import { getCourseRawData } from "@/lib/analytics-functions";

export default function RawDataView() {
return (
Expand All @@ -9,7 +10,7 @@ export default function RawDataView() {
title="Raw Data View"
subtitle="Browse all available analytics/performance data for your course."
/>
<RawDataTable />
<RawDataTable getData={getCourseRawData} />
</GenericPageContainer>
);
}
6 changes: 3 additions & 3 deletions components/CourseSettings/StudentPermissions.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"use client";
import { GlobalState, globalStateAtom } from "@/state/globalState";
import { useAtom } from "jotai";
import { GlobalState } from "@/lib/types";
import React, { useState } from "react";
import { Button, Form, ListGroup, Toast } from "react-bootstrap";
import ToastContainer from "../ToastContainer";
import { Controller, useForm } from "react-hook-form";
import { useGlobalContext } from "@/state/globalContext";

interface StudentPermissionsProps {
saveData: (
Expand All @@ -16,7 +16,7 @@ interface StudentPermissionsProps {
const StudentPermissions: React.FC<StudentPermissionsProps> = ({
saveData,
}) => {
const [globalState, setGlobalState] = useAtom(globalStateAtom);
const [globalState, setGlobalState] = useGlobalContext();
const [saveError, setSaveError] = useState<string | null>(null);
const [showSuccess, setShowSuccess] = useState(false);
const [loading, setLoading] = useState(false);
Expand Down
11 changes: 4 additions & 7 deletions components/DemoModeControls.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
'use client'
import { globalStateAtom } from "@/state/globalState";
"use client";
import { useGlobalContext } from "@/state/globalContext";
import { capitalizeFirstLetter } from "@/utils/text-helpers";
import { useAtom } from "jotai";
import { useState } from "react";

const DemoModeControls = () => {
const [globalState, setGlobalState] = useAtom(globalStateAtom);
// const [courseId, setCourseId] = useState(globalState.adaptId);
const [globalState, setGlobalState] = useGlobalContext();

return (
<div className="tw-w-1/3 tw-flex tw-flex-col tw-items-center tw-border tw-border-solid tw-border-white tw-rounded-md tw-py-1 tw-mb-8 tw-bg-libre-blue tw-text-white">
<div className="tw-flex tw-flex-row tw-items-center tw-mt-0">
<p className="tw-text-center tw-mb-0">
<span className="tw-font-semibold">Viewing as: </span>
<span className="tw-font-semibold">(Demo Mode) Viewing as: </span>
{capitalizeFirstLetter(globalState.viewAs)}
<button
onClick={() => {
Expand Down
4 changes: 2 additions & 2 deletions components/EarlyWarningBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const EarlyWarningBanner: React.FC<EarlyWarningBanner> = ({ variant }) => {
<Card className="tw-shadow-sm">
<Card.Body>
<Card.Title>Quick Look</Card.Title>
<Card.Text>
<Card.Body className="!tw-p-0">
<>
<div className="tw-flex tw-flex-row tw-mt-4">
<div className="tw-mr-4 tw-mt-0.5">{getIcon()}</div>
Expand All @@ -65,7 +65,7 @@ const EarlyWarningBanner: React.FC<EarlyWarningBanner> = ({ variant }) => {
{getMessage()}
</p>
</>
</Card.Text>
</Card.Body>
</Card.Body>
</Card>
);
Expand Down
5 changes: 2 additions & 3 deletions components/FERPAPrivacySwitch.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
"use client";
import CustomToggle from "./CustomToggle";
import { useAtom } from "jotai";
import { globalStateAtom } from "@/state/globalState";
import { useQueryClient } from "@tanstack/react-query";
import { useGlobalContext } from "@/state/globalContext";

interface FERPAPrivacySwitchProps {}

const FERPAPrivacySwitch: React.FC<FERPAPrivacySwitchProps> = () => {
const [globalState, setGlobalState] = useAtom(globalStateAtom);
const [globalState, setGlobalState] = useGlobalContext();
const queryClient = useQueryClient();

const handleToggle = () => {
Expand Down
6 changes: 3 additions & 3 deletions components/InstructorDashboardControls.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
'use client'
import { Card, Dropdown } from "react-bootstrap";
import CustomDropdown from "./CustomDropdown";
import { truncateString } from "@/utils/text-helpers";

import { getAssignments, getStudents } from "@/lib/analytics-functions";
import { useAtom } from "jotai";
import { useQuery } from "@tanstack/react-query";
import { IDWithName } from "@/lib/types";
import { useEffect, useMemo, useRef } from "react";
import { globalStateAtom } from "@/state/globalState";
import { useGlobalContext } from "@/state/globalContext";

const InstructorDashboardControls = () => {
const [globalState, setGlobalState] = useAtom(globalStateAtom);
const [globalState, setGlobalState] = useGlobalContext();
const elementRef = useRef<HTMLDivElement>(null);

const { data: students, status: studentsStatus } = useQuery<IDWithName[]>({
Expand Down
18 changes: 9 additions & 9 deletions components/NavMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
"use client";
import { ListGroup } from "react-bootstrap";
import Links from "./Links";
import { useAtom } from "jotai";
import { globalStateAtom } from "@/state/globalState";
import { usePathname } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import { useMemo } from "react";
import { useGlobalContext } from "@/state/globalContext";

const ACTIVE_CLASSES = "tw-bg-light-gray tw-border-none";

const NavMenu = () => {
const [globalState] = useAtom(globalStateAtom);
const router = useRouter();
const pathname = usePathname();
const [globalState] = useGlobalContext();

const isActive = useMemo(() => {
return (key: string) => {
Expand All @@ -31,7 +31,7 @@ const NavMenu = () => {
active={isActive("dashboard")}
className={isActive("dashboard") ? ACTIVE_CLASSES : ""}
action
href={Links.CLIENT.Dashboard}
onClick={() => router.push(Links.CLIENT.Dashboard)}
>
<span className="tw-text-link-blue">
{globalState.viewAs === "instructor" ? "Instructor" : "Student"}{" "}
Expand All @@ -43,7 +43,7 @@ const NavMenu = () => {
active={isActive("early-warning")}
className={isActive("early-warning") ? ACTIVE_CLASSES : ""}
action
href={Links.CLIENT.EarlyWarning}
onClick={() => router.push(Links.CLIENT.EarlyWarning)}
>
<span className="tw-text-link-blue">Early Warning</span>
</ListGroup.Item>
Expand All @@ -53,7 +53,7 @@ const NavMenu = () => {
active={isActive("raw-data")}
className={isActive("raw-data") ? ACTIVE_CLASSES : ""}
action
href={Links.CLIENT.RawData}
onClick={() => router.push(Links.CLIENT.RawData)}
>
<span className="tw-text-link-blue">Raw Data</span>
</ListGroup.Item>
Expand All @@ -63,15 +63,15 @@ const NavMenu = () => {
active={isActive("course-settings")}
className={isActive("course-settings") ? ACTIVE_CLASSES : ""}
action
href={Links.CLIENT.CourseSettings}
onClick={() => router.push(Links.CLIENT.CourseSettings)}
>
<span className="tw-text-link-blue">Course Settings</span>
</ListGroup.Item>
)}
</ListGroup>
{process.env.NODE_ENV === "development" && (
<p className="tw-text-center tw-mt-2">
Course ID: {globalState.courseID}
Course ID: {globalState?.courseID}
</p>
)}
</>
Expand Down
5 changes: 2 additions & 3 deletions components/PageHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
"use client";
import { useGlobalContext } from "@/state/globalContext";
import FERPAPrivacySwitch from "./FERPAPrivacySwitch";
import { useAtom } from "jotai";
import { globalStateAtom } from "@/state/globalState";

interface PageHeaderProps {
title: string;
subtitle: string;
}

const PageHeader: React.FC<PageHeaderProps> = ({ title, subtitle }) => {
const [globalState] = useAtom(globalStateAtom);
const [globalState] = useGlobalContext();

return (
<div className="tw-flex tw-flex-col tw-w-full tw-mb-2">
Expand Down
Loading

0 comments on commit 5870147

Please sign in to comment.