diff --git a/apps/cyberstorm-remix/app/communities/communities.tsx b/apps/cyberstorm-remix/app/communities/communities.tsx index e8749de82..6c1e52141 100644 --- a/apps/cyberstorm-remix/app/communities/communities.tsx +++ b/apps/cyberstorm-remix/app/communities/communities.tsx @@ -121,7 +121,12 @@ export default function CommunitiesPage() { Communities
- + Communities
diff --git a/apps/cyberstorm-remix/cyberstorm/dapper/sessionUtils.ts b/apps/cyberstorm-remix/cyberstorm/dapper/sessionUtils.ts index 1e8c762ee..a956a5d32 100644 --- a/apps/cyberstorm-remix/cyberstorm/dapper/sessionUtils.ts +++ b/apps/cyberstorm-remix/cyberstorm/dapper/sessionUtils.ts @@ -1,19 +1,28 @@ +import { redirect } from "@remix-run/react"; import { DapperTs } from "@thunderstore/dapper-ts"; import { RequestConfig } from "@thunderstore/thunderstore-api"; export async function getDapper(isClient = false) { if (isClient) { + const getCookie = (cookieName: string) => + new RegExp(`${cookieName}=([^;]+);`).exec(document.cookie)?.[1]; + const deleteCookie = (name: string) => { + const date = new Date(); + date.setTime(0); + document.cookie = `${name}=${null}; expires=${date.toUTCString()}; path=/`; + }; + + const removeSession = () => { + deleteCookie("sessionid"); + deleteCookie("csrftoken"); + redirect("/communities"); + }; const dapper = window.Dapper; let shouldRemakeDapper = false; - // const allCookies = new URLSearchParams( - // window.document.cookie.replaceAll("&", "%26").replaceAll("; ", "&") - // ); - // const cookie = allCookies.get("sessionid"); - // const csrftoken = allCookies.get("csrftoken"); - const cookie = null; - const csrftoken = null; + const cookie = getCookie("sessionid"); + const csrftoken = getCookie("csrftoken"); const newConfig: RequestConfig = { apiHost: window.ENV.PUBLIC_API_URL, @@ -65,7 +74,7 @@ export async function getDapper(isClient = false) { } const createNewDapper = () => { - const newDapper = new DapperTs(newConfig); + const newDapper = new DapperTs(newConfig, removeSession); window.Dapper = newDapper; return newDapper; }; @@ -75,7 +84,7 @@ export async function getDapper(isClient = false) { ? createNewDapper() : dapper ? dapper - : new DapperTs(newConfig); + : new DapperTs(newConfig, removeSession); return existingDapper; } else { diff --git a/apps/cyberstorm-remix/cyberstorm/navigation/DesktopLoginPopover.tsx b/apps/cyberstorm-remix/cyberstorm/navigation/DesktopLoginPopover.tsx index d0a3f8e9f..872dda94f 100644 --- a/apps/cyberstorm-remix/cyberstorm/navigation/DesktopLoginPopover.tsx +++ b/apps/cyberstorm-remix/cyberstorm/navigation/DesktopLoginPopover.tsx @@ -1,23 +1,33 @@ import styles from "./Navigation.module.css"; -import { Modal } from "@thunderstore/cyberstorm"; -import { AvatarButton } from "@thunderstore/cyberstorm/src/components/Avatar/AvatarButton"; +import { Modal, NewButton, NewIcon } from "@thunderstore/cyberstorm"; import { LoginList } from "./LoginList"; +import { faArrowRightToBracket } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; export function DesktopLoginPopover() { return ( + + + + + Log In + } > - + ); } diff --git a/apps/cyberstorm-remix/cyberstorm/navigation/DesktopUserDropdown.tsx b/apps/cyberstorm-remix/cyberstorm/navigation/DesktopUserDropdown.tsx index e2396a433..68a01a002 100644 --- a/apps/cyberstorm-remix/cyberstorm/navigation/DesktopUserDropdown.tsx +++ b/apps/cyberstorm-remix/cyberstorm/navigation/DesktopUserDropdown.tsx @@ -1,96 +1,97 @@ import { faSignOut, faUsers, faCog } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import * as RadixDropDown from "@radix-ui/react-dropdown-menu"; import styles from "./Navigation.module.css"; +import dropdownStyles from "../../../../packages/cyberstorm/src/newComponents/DropDown/DropDown.module.css"; import { Avatar, - DropDownDivider, - DropDownItem, - CyberstormLink, - DropDown, + NewDropDown, + NewText, + NewDropDownItem, + NewDropDownDivider, + NewLink, + NewIcon, } from "@thunderstore/cyberstorm"; -import { DropDownLink } from "@thunderstore/cyberstorm/src/components/DropDown/DropDownLink"; -import { emptyUser } from "@thunderstore/dapper-ts/src/methods/currentUser"; import { CurrentUser } from "@thunderstore/dapper/types"; -import { getDapper } from "cyberstorm/dapper/sessionUtils"; -import { useState, useEffect } from "react"; import { AvatarButton } from "@thunderstore/cyberstorm/src/components/Avatar/AvatarButton"; -import { DesktopLoginPopover } from "./DesktopLoginPopover"; +import { classnames } from "@thunderstore/cyberstorm/src/utils/utils"; -export function DesktopUserDropdown() { - const [user, setUser] = useState(emptyUser); - const avatar = user.connections.find((c) => c.avatar !== null)?.avatar; - - useEffect(() => { - const fetchAndSetUser = async () => { - const dapper = await getDapper(true); - const fetchedUser = await dapper.getCurrentUser(); - setUser(fetchedUser); - }; - fetchAndSetUser(); - }, []); +export function DesktopUserDropdown(props: { user: CurrentUser }) { + const { user } = props; - if (!user.username) { - return ; - } + const avatar = user.connections.find((c) => c.avatar !== null)?.avatar; // REMIX TODO: Turn this into a popover return ( - } - content={[ - -
- -
-
- {user.username} -
-
-
-
, - - , - - - } - label="Settings" - /> - } - /> - , - - - } - label="Teams" - /> - } - /> - , - - , - - - } - label="Log Out" - /> - } - /> - , - ]} - /> + csVariant="default" + csColor="surface" + > + + + + {user.username} + + + + + + + + + Settings + + + + + + + + Teams + + + + + + + + Log Out + + + ); } diff --git a/apps/cyberstorm-remix/cyberstorm/navigation/LoginList.tsx b/apps/cyberstorm-remix/cyberstorm/navigation/LoginList.tsx index 6477ce1d7..4d5f7657e 100644 --- a/apps/cyberstorm-remix/cyberstorm/navigation/LoginList.tsx +++ b/apps/cyberstorm-remix/cyberstorm/navigation/LoginList.tsx @@ -2,58 +2,104 @@ import { faDiscord, faGithub } from "@fortawesome/free-brands-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import styles from "./Navigation.module.css"; -import { CyberstormLink, Icon } from "@thunderstore/cyberstorm"; -import { - OverwolfLogo, - ThunderstoreLogo, -} from "@thunderstore/cyberstorm/src/svg/svg"; +import { Heading, NewIcon, NewLink, NewText } from "@thunderstore/cyberstorm"; +import { OverwolfLogo } from "@thunderstore/cyberstorm/src/svg/svg"; import { classnames } from "@thunderstore/cyberstorm/src/utils/utils"; import { buildAuthLoginUrl } from "cyberstorm/utils/ThunderstoreAuth"; export function LoginList() { return (
- - - -

Log in to Thunderstore

+ + + + + + + + + + + Log in to Thunderstore + -

+ By logging in and accessing the site you agree to{" "} - + Terms and Conditions - {" "} + {" "} and{" "} - Privacy Policy -

+ + Privacy Policy + +
); } diff --git a/apps/cyberstorm-remix/cyberstorm/navigation/MobileUserPopover.tsx b/apps/cyberstorm-remix/cyberstorm/navigation/MobileUserPopover.tsx deleted file mode 100644 index d9679c939..000000000 --- a/apps/cyberstorm-remix/cyberstorm/navigation/MobileUserPopover.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { useEffect, useState } from "react"; -import { getDapper } from "cyberstorm/dapper/sessionUtils"; -import { emptyUser } from "@thunderstore/dapper-ts/src/methods/currentUser"; -import { CurrentUser } from "@thunderstore/dapper/types"; -import { MobileUserPopoverContent } from "./MobileUserPopoverContent"; - -export function MobileUserPopover() { - const [user, setUser] = useState(emptyUser); - - useEffect(() => { - const fetchAndSetUser = async () => { - const dapper = await getDapper(true); - const fetchedUser = await dapper.getCurrentUser(); - setUser(fetchedUser); - }; - fetchAndSetUser(); - }, []); - - return ; -} diff --git a/apps/cyberstorm-remix/cyberstorm/navigation/MobileUserPopoverContent.tsx b/apps/cyberstorm-remix/cyberstorm/navigation/MobileUserPopoverContent.tsx index 12df80640..d1ec9d957 100644 --- a/apps/cyberstorm-remix/cyberstorm/navigation/MobileUserPopoverContent.tsx +++ b/apps/cyberstorm-remix/cyberstorm/navigation/MobileUserPopoverContent.tsx @@ -2,13 +2,18 @@ import { faLongArrowLeft } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import styles from "./Navigation.module.css"; -import { CyberstormLink, Icon, Menu } from "@thunderstore/cyberstorm"; +import { + Avatar, + Menu, + NewIcon, + NewLink, + NewText, +} from "@thunderstore/cyberstorm"; import { AvatarButton } from "@thunderstore/cyberstorm/src/components/Avatar/AvatarButton"; import { CurrentUser } from "@thunderstore/dapper/types"; import { faSignOut, faUsers, faCog } from "@fortawesome/free-solid-svg-icons"; -import { DropDownLink } from "@thunderstore/cyberstorm/src/components/DropDown/DropDownLink"; import { LoginList } from "./LoginList"; export function MobileUserPopoverContent(props: { user: CurrentUser }) { @@ -38,62 +43,60 @@ export function MobileUserPopoverContent(props: { user: CurrentUser }) { }} className={styles.popoverCloseButton} > - + - + } > - + {user.username} + + + + + + + Settings + + + + + + Teams + + + + + + Log Out + + + ) : ( + + )} ); } diff --git a/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.module.css b/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.module.css index 71cb192f0..a105b35e0 100644 --- a/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.module.css +++ b/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.module.css @@ -39,21 +39,18 @@ margin: 0 0.75rem; } -.navButtons { +.dropDownItem { display: flex; - gap: var(--space--8); + gap: var(--space--16); + align-items: center; + + --dropdown-item-color: var(--color-primary) !important; } .dropDownUserInfo { display: flex; gap: var(--gap--16); - margin: 0 var(--space--8); - padding: var(--space--8) var(--space--16); - border-radius: var(--border-radius--8); -} - -.dropDownUserInfo:hover { - background-color: var(--color-surface--6); + padding: var(--space--6) var(--space--16); } .dropdownUserInfoDetails { @@ -62,19 +59,6 @@ justify-content: space-around; } -.dropdownUserInfoDetails_userName { - color: var(--color-text--default); - font-weight: var(--font-weight-bold); - font-size: var(--font-size--m); - line-height: 1; -} - -.dropdownUserInfoDetails_description { - color: var(--color-text--tertiary); - font-size: var(--font-size--m); - line-height: 1; -} - .mobileNavRoot { display: none; } @@ -112,32 +96,24 @@ line-height: 1.2rem; } -.mobileNavAccountPopoverRoot { - width: 100%; - height: 100%; -} - -.mobileNavAccountPopoverWrapper { +.accountPopoverItem { display: flex; - flex-direction: column; - gap: 2rem; - align-items: flex-start; - width: 100%; - height: 100%; - padding: 1.5rem; - padding-top: 7rem; - background: #15152d; + gap: 1rem; + align-items: center; + align-self: stretch; + padding: 1rem; } -.accountPopoverItem { +.accountPopoverUser { display: flex; + flex-direction: column; gap: 1rem; align-items: center; align-self: stretch; padding: 1rem; } -.mobileNavPopoverList { +.mobileNavPopover { display: flex; flex-direction: column; width: 100%; @@ -149,9 +125,6 @@ align-items: center; align-self: stretch; padding: 1rem; - color: #f5f5f6; - font-weight: 400; - font-size: 0.875rem; } .popoverCloseButton { @@ -161,23 +134,12 @@ background: transparent; } -.navAccountPopoverCloseButton { - position: absolute; - top: 1rem; - right: 1rem; - width: 2.75rem; - height: 2.75rem; -} - .TSLoginLogo { width: 3.12rem; height: 2.79rem; } .loginTitle { - color: #f5f5f6; - font-weight: 700; - font-size: 1.25rem; text-align: center; } @@ -201,11 +163,9 @@ flex: 1 0 0; gap: 2.5rem; align-items: center; - padding: 0.75rem 1rem; + padding: 0.75rem 3rem 0.75rem 1rem; border-radius: 0.5rem; color: #f5f5f6; - font-weight: 700; - font-size: 0.875rem; } .loginLinkDiscord { @@ -220,57 +180,10 @@ background: #d34037; } -.navAccountPopoverRoot { - position: fixed; - top: 50%; - left: 50%; - float: left; - border: 1px solid #29295b; - border-radius: 0.5rem; - background: #15152d; - transform: translate(-50%, -50%); -} - -.navAccountPopoverRoot::backdrop { - background: rgba(0 0 0 / 0.6); - backdrop-filter: blur(10px); -} - -.navAccountPopoverWrapper { - display: flex; - flex-direction: column; - gap: 2rem; - align-items: flex-start; - align-self: stretch; - justify-content: center; - padding: 3rem 5.5rem; - background: transparent; -} - -.navAccountPopoverCloseButtonIconWrapper { - position: absolute; - top: 1rem; - right: 1rem; - display: flex; - align-items: center; - justify-content: center; - width: 2.75rem; - height: 2.75rem; - color: #635a9f; - font-weight: 900; - font-size: 1rem; -} - .loginLegalText { - color: #8683be; - font-weight: var(--font-weight-medium); - font-size: var(--font-size--s); - line-height: var(--line-height--s); text-align: center; -} -.loginLegalText > a { - color: var(--color-text--tertiary); + --text-color: #8683be; } @media (max-width: 63.5rem) { @@ -293,11 +206,16 @@ } } -.fixed { - block-size: 1em; - inline-size: 1em; -} - .getAppButton { padding: 0.75rem 0.812rem; } + +.loginButton { + height: 2.25rem; + padding: 0.75rem; +} + +.headerRightSide { + display: flex; + gap: 1rem; +} diff --git a/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.tsx b/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.tsx index c33f65cbd..2d6771553 100644 --- a/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.tsx +++ b/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.tsx @@ -15,15 +15,33 @@ import { NewIcon, } from "@thunderstore/cyberstorm"; import { ThunderstoreLogo } from "@thunderstore/cyberstorm/src/svg/svg"; -// import { Suspense } from "react"; +import { useEffect, useRef, useState } from "react"; import { DevelopersDropDown } from "./DevelopersDropDown"; -// import { MobileUserPopover } from "./MobileUserPopover"; -// import { DesktopUserDropdown } from "./DesktopUserDropdown"; -// import { DesktopLoginPopover } from "./DesktopLoginPopover"; -// import { MobileUserPopoverContent } from "./MobileUserPopoverContent"; -// import { getEmptyUser } from "@thunderstore/dapper-ts"; +import { DesktopUserDropdown } from "./DesktopUserDropdown"; +import { DesktopLoginPopover } from "./DesktopLoginPopover"; +import { MobileUserPopoverContent } from "./MobileUserPopoverContent"; +import { emptyUser } from "@thunderstore/dapper-ts/src/methods/currentUser"; +import { CurrentUser } from "@thunderstore/dapper/types"; +import { getDapper } from "cyberstorm/dapper/sessionUtils"; +import { useHydrated } from "remix-utils/use-hydrated"; export function Navigation() { + const isHydrated = useHydrated(); + const startsHydrated = useRef(isHydrated); + const [currentUser, setCurrentUser] = useState(); + + useEffect(() => { + if (!startsHydrated.current && isHydrated) return; + const fetchAndSetUser = async () => { + const dapper = await getDapper(true); + const fetchedUser = await dapper.getCurrentUser(); + if (fetchedUser?.username) { + setCurrentUser(fetchedUser); + } + }; + fetchAndSetUser(); + }, []); + return ( <>
@@ -51,23 +69,24 @@ export function Navigation() { - {/*
*/} - - Get App - - {/* TODO: Enable once working */} - {/*}>*/} - {/* */} - {/**/} - {/*
*/} +
+ + Get App + + {!startsHydrated.current && isHydrated && currentUser ? ( + + ) : ( + + )} +