diff --git a/frontend2/public/battlecode-logo-horiz-white.png b/frontend2/public/battlecode-logo-horiz-white.png
new file mode 100644
index 000000000..3fa49c58e
Binary files /dev/null and b/frontend2/public/battlecode-logo-horiz-white.png differ
diff --git a/frontend2/public/battlecode-logo-vert-white.png b/frontend2/public/battlecode-logo-vert-white.png
new file mode 100644
index 000000000..9b54b7a4d
Binary files /dev/null and b/frontend2/public/battlecode-logo-vert-white.png differ
diff --git a/frontend2/public/favicon.ico b/frontend2/public/favicon.ico
deleted file mode 100644
index a11777cc4..000000000
Binary files a/frontend2/public/favicon.ico and /dev/null differ
diff --git a/frontend/public/favicon.png b/frontend2/public/favicon.png
similarity index 100%
rename from frontend/public/favicon.png
rename to frontend2/public/favicon.png
diff --git a/frontend2/public/logo192.png b/frontend2/public/logo192.png
deleted file mode 100644
index fc44b0a37..000000000
Binary files a/frontend2/public/logo192.png and /dev/null differ
diff --git a/frontend2/public/logo512.png b/frontend2/public/logo512.png
deleted file mode 100644
index a4e47a654..000000000
Binary files a/frontend2/public/logo512.png and /dev/null differ
diff --git a/frontend2/src/App.tsx b/frontend2/src/App.tsx
index 1417ce3f4..1cd57f1f4 100644
--- a/frontend2/src/App.tsx
+++ b/frontend2/src/App.tsx
@@ -13,6 +13,7 @@ import {
RouterProvider,
createBrowserRouter,
Navigate,
+ redirect,
} from "react-router-dom";
import { DEFAULT_EPISODE } from "./utils/constants";
import NotFound from "./views/NotFound";
@@ -38,31 +39,38 @@ const router = createBrowserRouter([
{ path: "/register", element: },
{ path: "/password_forgot", element: },
{ path: "/password_change", element: },
- // Pages that will contain the episode specific sidebar and navbar
- {
- element: ,
- children: [
- // Pages that should always be visible
- // TODO: /:episodeId/resources, /:episodeId/tournaments, /:episodeId/queue
- { path: "/:episodeId/home", element: },
- { path: "/:episodeId/quickstart", element: },
- { path: "/:episodeId/*", element: },
- { path: "/:episodeId/rankings", element: },
- ],
- },
// Pages that should only be visible when logged in
{
element: ,
children: [
+ { path: "/account", element: },
{
element: ,
children: [
// TODO: /:episodeId/team, /:episodeId/submissions, /:episodeId/scrimmaging
],
},
- { path: "/account", element: },
],
},
+ // Pages that will contain the episode specific sidebar and navbar
+ {
+ element: ,
+ children: [
+ // Pages that should always be visible
+ // TODO: /:episodeId/resources, /:episodeId/tournaments, /:episodeId/queue
+ { path: "/:episodeId/home", element: },
+ {
+ path: "/:episodeId/",
+ loader: ({ params }) => {
+ return redirect(`/${params.episodeId as string}/home`);
+ },
+ },
+ { path: "/:episodeId/quickstart", element: },
+ { path: "/:episodeId/*", element: },
+ { path: "/:episodeId/rankings", element: },
+ ],
+ },
+
// Pages that should redirect
{ path: "/*", element: },
]);
diff --git a/frontend2/src/components/CurrentUserProvider.tsx b/frontend2/src/components/CurrentUserProvider.tsx
index 7d3035681..297cc4f66 100644
--- a/frontend2/src/components/CurrentUserProvider.tsx
+++ b/frontend2/src/components/CurrentUserProvider.tsx
@@ -8,6 +8,7 @@ import {
import { removeApiTokens } from "../utils/cookies";
import { loginCheck } from "../utils/api/auth";
import { getUserUserProfile } from "../utils/api/user";
+import Cookies from "js-cookie";
export const CurrentUserProvider: React.FC<{ children: React.ReactNode }> = ({
children,
@@ -26,6 +27,8 @@ export const CurrentUserProvider: React.FC<{ children: React.ReactNode }> = ({
});
};
const logout = (): void => {
+ Cookies.remove("access");
+ Cookies.remove("refresh");
setUserData({
authState: AuthStateEnum.NOT_AUTHENTICATED,
});
diff --git a/frontend2/src/components/EpisodeLayout.tsx b/frontend2/src/components/EpisodeLayout.tsx
index 6729ccbd7..15c040199 100644
--- a/frontend2/src/components/EpisodeLayout.tsx
+++ b/frontend2/src/components/EpisodeLayout.tsx
@@ -1,10 +1,10 @@
import React, { useContext } from "react";
-import Navbar from "./Navbar";
+import Header from "./Header";
import Sidebar from "./sidebar";
import { Outlet, useParams } from "react-router-dom";
import { EpisodeContext } from "../contexts/EpisodeContext";
-// This component contains the NavBar and SideBar.
+// This component contains the Header and SideBar.
// Child route components are rendered with
const EpisodeLayout: React.FC = () => {
const episodeContext = useContext(EpisodeContext);
@@ -14,7 +14,7 @@ const EpisodeLayout: React.FC = () => {
}
return (
-
+
diff --git a/frontend2/src/components/Header.tsx b/frontend2/src/components/Header.tsx
new file mode 100644
index 000000000..95ddbbb2e
--- /dev/null
+++ b/frontend2/src/components/Header.tsx
@@ -0,0 +1,148 @@
+import React, { Fragment, useContext } from "react";
+import { Menu, Transition } from "@headlessui/react";
+import { Link, NavLink } from "react-router-dom";
+import { AuthStateEnum, useCurrentUser } from "../contexts/CurrentUserContext";
+import Icon from "./elements/Icon";
+import { EpisodeContext } from "../contexts/EpisodeContext";
+import { SIDEBAR_ITEM_DATA } from "./sidebar";
+
+const Header: React.FC = () => {
+ const { authState, logout, user } = useCurrentUser();
+ const { episodeId } = useContext(EpisodeContext);
+
+ return (
+
+ );
+};
+
+export default Header;
diff --git a/frontend2/src/components/Navbar.tsx b/frontend2/src/components/Navbar.tsx
deleted file mode 100644
index 5b80434ab..000000000
--- a/frontend2/src/components/Navbar.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import React from "react";
-
-const Navbar: React.FC = () => {
- return
navbar here
;
-};
-
-export default Navbar;
diff --git a/frontend2/src/components/elements/Button.tsx b/frontend2/src/components/elements/Button.tsx
index 85f910cb8..e02d4251c 100644
--- a/frontend2/src/components/elements/Button.tsx
+++ b/frontend2/src/components/elements/Button.tsx
@@ -1,6 +1,13 @@
import React from "react";
import Icon, { type IconName } from "./Icon";
+const VARIANTS: Record
= {
+ "": "bg-gray-50 text-gray-800 hover:bg-gray-100 hover:ring-gray-900 hover:text-black ring-gray-500 ring-1 ring-inset",
+ dark: "bg-cyan-700 text-white hover:bg-cyan-800",
+ "light-outline":
+ "ring-2 ring-inset ring-gray-200 text-gray-200 hover:bg-gray-100/20",
+} as const;
+
interface ButtonProps extends React.ComponentPropsWithoutRef<"button"> {
variant?: string;
label?: string;
@@ -9,11 +16,6 @@ interface ButtonProps extends React.ComponentPropsWithoutRef<"button"> {
className?: string;
}
-const variants: Record = {
- "": "bg-gray-50 text-gray-800 hover:bg-gray-100 hover:ring-gray-900 hover:text-black ring-gray-500 ring-1 ring-inset",
- dark: "bg-cyan-700 text-white hover:bg-cyan-800",
-};
-
const Button: React.FC = ({
variant = "",
label,
@@ -22,14 +24,15 @@ const Button: React.FC = ({
className = "",
...rest
}) => {
- const variantStyle = `${variants[variant]} ${
+ const variantStyle = `${VARIANTS[variant]} ${
fullWidth ? "w-full" : ""
} ${className}`;
return (
-
-
+
+
Need an account?{" "}
Register for one!