diff --git a/apps/cyberstorm-remix/app/communities/communities.tsx b/apps/cyberstorm-remix/app/communities/communities.tsx index 6c1e52141..8f7a40a9d 100644 --- a/apps/cyberstorm-remix/app/communities/communities.tsx +++ b/apps/cyberstorm-remix/app/communities/communities.tsx @@ -137,7 +137,7 @@ export default function CommunitiesPage() { csTextStyles={["fontWeightBold", "lineHeightAuto", "fontSizeS"]} >
- Search + setSearchValue(e.target.value)} value={searchValue} @@ -146,15 +146,17 @@ export default function CommunitiesPage() { leftIcon={} csColor="cyber-green" rootClasses={searchAndOrderStyles.searchInput} + id="communitiesSearchInput" />
- Sort by +
@@ -208,7 +210,7 @@ function CommunitiesList(props: { communitiesData: Communities }) { 1000} isNew={ new Date(community.datetime_created).getTime() > new Date().getTime() - 1000 * 60 * 60 * 336 diff --git a/apps/cyberstorm-remix/app/root.tsx b/apps/cyberstorm-remix/app/root.tsx index 275f97145..110aef93f 100644 --- a/apps/cyberstorm-remix/app/root.tsx +++ b/apps/cyberstorm-remix/app/root.tsx @@ -17,7 +17,11 @@ import { import { Footer } from "@thunderstore/cyberstorm/src/components/Footer/Footer"; import { Provider as RadixTooltip } from "@radix-ui/react-tooltip"; -import { Navigation } from "cyberstorm/navigation/Navigation"; +import { + MobileNavigationMenu, + MobileUserPopoverContent, + Navigation, +} from "cyberstorm/navigation/Navigation"; import { LinkLibrary } from "cyberstorm/utils/LinkLibrary"; import { AdContainer, LinkingProvider } from "@thunderstore/cyberstorm"; import { DapperTs } from "@thunderstore/dapper-ts"; @@ -29,10 +33,12 @@ import { getPublicEnvVariables, publicEnvVariables, } from "cyberstorm/security/publicEnvVariables"; -import { useEffect, useRef } from "react"; +import { useEffect, useRef, useState } from "react"; import { useHydrated } from "remix-utils/use-hydrated"; import Toast from "@thunderstore/cyberstorm/src/components/Toast"; import { SessionProvider } from "@thunderstore/ts-api-react"; +import { CurrentUser } from "@thunderstore/dapper/types"; +import { getDapper } from "cyberstorm/dapper/sessionUtils"; // REMIX TODO: https://remix.run/docs/en/main/route/links // export const links: LinksFunction = () => [{ rel: "stylesheet", href: styles }]; @@ -128,6 +134,22 @@ function Root() { ? false : true; + 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 ( @@ -173,7 +195,16 @@ function Root() {
{/* REMIX TODO: For whatever reason the Navigation seems to cause suspense boundary errors. Couldn't find a reason why */} - + + + {!startsHydrated.current && isHydrated && currentUser ? ( + + ) : ( + + )}
diff --git a/apps/cyberstorm-remix/cyberstorm/navigation/DesktopLoginPopover.tsx b/apps/cyberstorm-remix/cyberstorm/navigation/DesktopLoginPopover.tsx index 872dda94f..08114539f 100644 --- a/apps/cyberstorm-remix/cyberstorm/navigation/DesktopLoginPopover.tsx +++ b/apps/cyberstorm-remix/cyberstorm/navigation/DesktopLoginPopover.tsx @@ -1,3 +1,19 @@ +import styles from "./Navigation.module.css"; +import { + Heading, + Modal, + NewButton, + NewIcon, + NewLink, + NewText, +} from "@thunderstore/cyberstorm"; +import { faArrowRightToBracket } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { OverwolfLogo } from "@thunderstore/cyberstorm/src/svg/svg"; +import { classnames } from "@thunderstore/cyberstorm/src/utils/utils"; +import { buildAuthLoginUrl } from "cyberstorm/utils/ThunderstoreAuth"; +import { faDiscord, faGithub } from "@fortawesome/free-brands-svg-icons"; + import styles from "./Navigation.module.css"; import { Modal, NewButton, NewIcon } from "@thunderstore/cyberstorm"; import { LoginList } from "./LoginList"; @@ -27,7 +43,98 @@ export function DesktopLoginPopover() { } > - +
+ + + + + + + + + + + Log in to Thunderstore + +
+ + + + + Connect with Discord + + + + + + Connect with Github + + + + + + Connect with Overwolf + +
+ + By logging in and accessing the site you agree to{" "} + + Terms and Conditions + {" "} + and{" "} + + Privacy Policy + + +
); } diff --git a/apps/cyberstorm-remix/cyberstorm/navigation/DevelopersDropDown.module.css b/apps/cyberstorm-remix/cyberstorm/navigation/DevelopersDropDown.module.css index 50f68cd9b..cf4cb83bc 100644 --- a/apps/cyberstorm-remix/cyberstorm/navigation/DevelopersDropDown.module.css +++ b/apps/cyberstorm-remix/cyberstorm/navigation/DevelopersDropDown.module.css @@ -4,6 +4,10 @@ justify-content: space-between; } +.focus:not([data-highlighted]) a svg { + color: var(--color-tertiary); +} + .root { min-width: 14rem; } diff --git a/apps/cyberstorm-remix/cyberstorm/navigation/DevelopersDropDown.tsx b/apps/cyberstorm-remix/cyberstorm/navigation/DevelopersDropDown.tsx index b62199532..e3a2c8c6d 100644 --- a/apps/cyberstorm-remix/cyberstorm/navigation/DevelopersDropDown.tsx +++ b/apps/cyberstorm-remix/cyberstorm/navigation/DevelopersDropDown.tsx @@ -24,7 +24,7 @@ export function DevelopersDropDown() { } csVariant="default" - csColor="surface" + csColor="surface-alpha" rootClasses={styles.root} > @@ -67,7 +67,7 @@ export function DevelopersDropDown() { Markdown Preview - + Github - + diff --git a/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.module.css b/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.module.css index c9b8f5360..56d026bed 100644 --- a/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.module.css +++ b/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.module.css @@ -15,7 +15,6 @@ height: var(--header-height); padding: 0 var(--space--12); background: var(--body-bg-color-a); - background-color: rgb(16 16 40 / 0.85); box-shadow: 0 1px 10px 0 var(--body-bg-color); backdrop-filter: blur(10px); } @@ -43,8 +42,12 @@ display: flex; gap: var(--space--16); align-items: center; +} - --dropdown-item-color: var(--color-primary) !important; +.dropDownItem[data-highlighted] svg, +.dropDownItem[data-highlighted], +.dropDownItem { + color: var(--color-primary); } .dropDownUserInfo { @@ -63,11 +66,6 @@ display: none; } -.mobileNavItemIconWrapper { - height: 1.75rem; - background: transparent; -} - .mobileNavMenuDevelopersButton { display: flex; gap: 1rem; @@ -75,9 +73,7 @@ align-self: stretch; justify-content: space-between; padding: 1rem; - color: #f5f5f6; - font-weight: 400; - font-size: 0.875rem; + color: var(--color-primary); background: transparent; } @@ -90,12 +86,20 @@ flex-direction: column; flex-grow: 1; align-items: center; - color: #9c9cc4; + color: var(--color-tertiary); font-weight: 400; font-size: 0.75rem; line-height: 1.2rem; } +button.mobileNavItem { + background: transparent; +} + +.mobileNavItemIcon { + height: 1.375rem; +} + .accountPopoverItem { display: flex; gap: 1rem; @@ -137,6 +141,8 @@ .TSLoginLogo { width: 3.12rem; height: 2.79rem; + color: currentcolor; + fill: currentcolor; } .loginTitle { @@ -151,6 +157,15 @@ max-width: 300px; } +.loginListMobile { + display: flex; + flex-direction: column; + gap: 2rem; + align-items: center; + + /* justify-content: center; */ +} + .loginLinkList { display: flex; flex-direction: column; @@ -168,6 +183,16 @@ color: #f5f5f6; } +.loginLinkMobile { + display: flex; + flex: 1 0 0; + gap: 1rem; + align-items: center; + padding: 0.75rem 1rem; + border-radius: 0.5rem; + color: #f5f5f6; +} + .loginLinkDiscord { background: #5865f2; } @@ -186,7 +211,15 @@ --text-color: #8683be; } +.mobileMenu { + display: none; +} + @media (width <= 63.5rem) { + .mobileMenu { + display: flex; + } + .desktopNavRoot { display: none; } @@ -201,7 +234,7 @@ justify-content: space-evenly; width: 100%; padding: 0.5rem 1.5rem 0.25rem; - background: rgb(16 16 40 / 0.85); + background: var(--body-bg-color-a); backdrop-filter: blur(10px); } } diff --git a/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.tsx b/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.tsx index 2d6771553..6b83666b7 100644 --- a/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.tsx +++ b/apps/cyberstorm-remix/cyberstorm/navigation/Navigation.tsx @@ -3,45 +3,40 @@ import { faGamepad, faLongArrowLeft, faCaretRight, + faXmark, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import styles from "./Navigation.module.css"; import { - CyberstormLink, Menu, LinkButton, NewLink, NewIcon, + Avatar, + NewText, + Heading, } from "@thunderstore/cyberstorm"; -import { ThunderstoreLogo } from "@thunderstore/cyberstorm/src/svg/svg"; -import { useEffect, useRef, useState } from "react"; +import { + OverwolfLogo, + ThunderstoreLogo, +} from "@thunderstore/cyberstorm/src/svg/svg"; import { DevelopersDropDown } from "./DevelopersDropDown"; 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(); +import { faSignOut } from "@fortawesome/free-solid-svg-icons"; +import { faDiscord, faGithub } from "@fortawesome/free-brands-svg-icons"; - 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(); - }, []); +import { classnames } from "@thunderstore/cyberstorm/src/utils/utils"; +import { buildAuthLoginUrl } from "cyberstorm/utils/ThunderstoreAuth"; +export function Navigation(props: { + hydrationCheck: boolean; + currentUser?: CurrentUser; +}) { + const { hydrationCheck, currentUser } = props; return ( <>
@@ -62,7 +57,7 @@ export function Navigation() { primitiveType="cyberstormLink" linkId="Communities" csSize="l" - csColor="surface" + csColor="surface-alpha" csVariant="tertiary" > Communities @@ -81,7 +76,7 @@ export function Navigation() { > Get App - {!startsHydrated.current && isHydrated && currentUser ? ( + {hydrationCheck && currentUser ? ( ) : ( @@ -90,146 +85,369 @@ export function Navigation() {
+ + ); +} + +export function MobileNavigationMenu() { + return ( + + + + + + } + rootClasses={styles.mobileMenu} + > +
+ + + } controls={ } > -
- - + + ); +} + +export function MobileUserPopoverContent(props: { user?: CurrentUser }) { + const { user } = props; + const avatar = user?.connections.find((c) => c.avatar !== null)?.avatar; + + return ( + + + + + + } + > + {user && user.username ? ( +
+
+ + - + {user.username} + +
+ {/* + + + + Settings + + + + + + Teams + */} + + + - Browse - + Log Out +
- {!startsHydrated.current && isHydrated && currentUser ? ( - - ) : ( - - )} - - + ) : ( +
+ + + + + + + + + + + Log in to Thunderstore + +
+ + + + + Connect with Discord + + + + + + Connect with Github + + + + + + Connect with Overwolf + +
+ + By logging in and accessing the site you agree to{" "} + + Terms and Conditions + {" "} + and{" "} + + Privacy Policy + + +
+ )} +
); } diff --git a/packages/cyberstorm/src/components/Avatar/Avatar.module.css b/packages/cyberstorm/src/components/Avatar/Avatar.module.css index 0975c9f59..1c5a1ecbe 100644 --- a/packages/cyberstorm/src/components/Avatar/Avatar.module.css +++ b/packages/cyberstorm/src/components/Avatar/Avatar.module.css @@ -43,7 +43,7 @@ } .verySmoll { - --size: 1.75rem; + --size: 1.375rem; } .small { diff --git a/packages/cyberstorm/src/components/Avatar/Avatar.tsx b/packages/cyberstorm/src/components/Avatar/Avatar.tsx index 21d998893..79772b21c 100644 --- a/packages/cyberstorm/src/components/Avatar/Avatar.tsx +++ b/packages/cyberstorm/src/components/Avatar/Avatar.tsx @@ -1,9 +1,12 @@ +import { NewIcon } from "../.."; import { classnames } from "../../utils/utils"; import styles from "./Avatar.module.css"; +import { faUser } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; export interface AvatarProps { src?: string | null; - size?: "small" | "medium" | "large"; + size?: "verySmoll" | "small" | "medium" | "large"; username: string | null; } @@ -13,27 +16,38 @@ export interface AvatarProps { export function Avatar(props: AvatarProps) { const { src, size = "medium", username } = props; - return ( -
- {src ? ( - - ) : ( -
- {username ? username.charAt(0).toUpperCase() : "U"} -
- )} -
- ); + if (username) { + return ( +
+ {src ? ( + + ) : ( +
+ {username ? username.charAt(0).toUpperCase() : "U"} +
+ )} +
+ ); + } else { + return ( +
+ + + +
+ ); + } } Avatar.displayName = "Avatar"; const getSize = (scheme: AvatarProps["size"] = "medium") => { return { + verySmoll: styles.verySmoll, small: styles.small, medium: styles.medium, large: styles.large, diff --git a/packages/cyberstorm/src/components/Footer/Footer.module.css b/packages/cyberstorm/src/components/Footer/Footer.module.css index d92bf4bc0..87b701794 100644 --- a/packages/cyberstorm/src/components/Footer/Footer.module.css +++ b/packages/cyberstorm/src/components/Footer/Footer.module.css @@ -72,10 +72,15 @@ .footnoteCopyright { color: rgb(197 194 255 / 0.6) !important; + text-align: center; } .footnoteInner { display: flex; + flex-direction: column; + gap: 1.5rem; + align-items: center; + align-self: stretch; justify-content: center; width: 100%; max-width: 80rem; @@ -154,6 +159,11 @@ border-radius: var(--border-radius--8); } +.footerPagesLinks { + display: flex; + gap: var(--gap--32); +} + @media (width >= calc(63.5rem + 1px)) { .logoAndLinks { flex-direction: row; @@ -215,7 +225,8 @@ } .footnoteInner { - justify-content: flex-end; + flex-direction: row; + justify-content: space-between; } .ad { diff --git a/packages/cyberstorm/src/components/Footer/Footer.tsx b/packages/cyberstorm/src/components/Footer/Footer.tsx index 86e923472..e0cbedf50 100644 --- a/packages/cyberstorm/src/components/Footer/Footer.tsx +++ b/packages/cyberstorm/src/components/Footer/Footer.tsx @@ -34,7 +34,7 @@ export function Footer() { rootClasses={styles.iconLink} aria-label="Invite link to Thunderstores Discord server" > - + @@ -45,7 +45,7 @@ export function Footer() { rootClasses={styles.iconLink} aria-label="Link to Thunderstores Github" > - + @@ -183,6 +183,23 @@ export function Footer() {
+ + + Contact Us + + + Privacy Policy + +
- Thunderstore development is made possible with ads. - - - - Thanks + Thunderstore development is made possible with ads. Please consider + making an exception to your adblock. .menuWrapper { + display: flex; +} + +.fakeBackdrop { + width: 20%; + height: 100%; + background: transparent; +} + .menuCloseButton { position: absolute; top: 1rem; diff --git a/packages/cyberstorm/src/newComponents/Menu/Menu.tsx b/packages/cyberstorm/src/newComponents/Menu/Menu.tsx index 6a8972321..c2aa46636 100644 --- a/packages/cyberstorm/src/newComponents/Menu/Menu.tsx +++ b/packages/cyberstorm/src/newComponents/Menu/Menu.tsx @@ -8,15 +8,18 @@ import { FramePopoverProps, Frame, } from "../../primitiveComponents/Frame/Frame"; +import { classnames } from "../../utils/utils"; interface Props extends Omit { - trigger: ReactNode; + trigger?: ReactNode; controls?: ReactNode; } // TODO: Add storybook story // TODO: Add support for color, size and text systems export function Menu(props: Props) { + const { rootClasses } = props; + return ( <> {props.trigger} @@ -25,28 +28,40 @@ export function Menu(props: Props) { popoverId={props.popoverId} csColor="pink" csSize="m" - rootClasses={styles.menuRoot} - wrapperClasses={styles.menuWrapper} + rootClasses={classnames(styles.menuRoot, rootClasses)} + noWrapper + popoverMode="manual" > - {props.controls ? ( - props.controls - ) : ( - - - - - - )} - - {props.children} +
+ {props.controls ? ( + props.controls + ) : ( + + + + + + )} + {props.children} +
+