From 76bd3e0849c7a554890b20d37d05a711ffb88b62 Mon Sep 17 00:00:00 2001 From: Serena Li Date: Sat, 29 Jul 2023 19:19:44 -0400 Subject: [PATCH 1/4] add user context and private route and some login stuff --- frontend2/src/components/EpisodeLayout.tsx | 1 + .../src/components/elements/Dropdown.tsx | 50 +++++++++++++ frontend2/src/components/elements/Input.tsx | 9 ++- frontend2/src/views/Login.tsx | 34 ++++++++- frontend2/src/views/Register.tsx | 70 ++++++++++++++++++- 5 files changed, 157 insertions(+), 7 deletions(-) create mode 100644 frontend2/src/components/elements/Dropdown.tsx diff --git a/frontend2/src/components/EpisodeLayout.tsx b/frontend2/src/components/EpisodeLayout.tsx index 0086f13fe..06fff31c8 100644 --- a/frontend2/src/components/EpisodeLayout.tsx +++ b/frontend2/src/components/EpisodeLayout.tsx @@ -3,6 +3,7 @@ import Navbar from "./Navbar"; import Sidebar from "./sidebar"; import { Outlet, useParams } from "react-router-dom"; import { EpisodeContext } from "../contexts/EpisodeContext"; +import { useCurrentUser } from "../contexts/CurrentUserContext"; // This component contains the NavBar and SideBar. // Child route components are rendered with diff --git a/frontend2/src/components/elements/Dropdown.tsx b/frontend2/src/components/elements/Dropdown.tsx new file mode 100644 index 000000000..3cb5281bb --- /dev/null +++ b/frontend2/src/components/elements/Dropdown.tsx @@ -0,0 +1,50 @@ +import React, { useMemo, useState } from "react"; +import { Listbox } from "@headlessui/react"; +import { ChevronUpDownIcon } from "@heroicons/react/24/outline"; + +interface DropdownProps { + label: string; + options: Array<{ value: string; label: string }>; + required?: boolean; + value: string | undefined; + onChange: (value: string) => void; + placeholder?: string; +} + +const Dropdown: React.FC = ({ + label, + required = false, + options, + value, + placeholder, + onChange, +}) => { + const optionToValue = useMemo( + () => new Map(options.map((option) => [option.value, option.label])), + [options] + ); + return ( +
+ + + + {label} + {required && *} + + + + {value === undefined ? placeholder : optionToValue.get(value)} + + + {options.map((option) => ( + + {option.label} + + ))} + + +
+ ); +}; + +export default Dropdown; diff --git a/frontend2/src/components/elements/Input.tsx b/frontend2/src/components/elements/Input.tsx index a34adfcc8..8ac92ce76 100644 --- a/frontend2/src/components/elements/Input.tsx +++ b/frontend2/src/components/elements/Input.tsx @@ -6,14 +6,16 @@ interface InputProps extends React.ComponentPropsWithoutRef<"input"> { } const Input = forwardRef(function Input( - { label, required, ...rest }, + { label, required = false, ...rest }, ref ) { - required = required ?? false; return (
{label !== undefined && ( -