Skip to content

Commit

Permalink
Refactor jam-specific styling to avoid not-this-page checks everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
Willdotwhite committed Mar 21, 2024
1 parent 5b9345a commit 3ac3a0a
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 112 deletions.
52 changes: 22 additions & 30 deletions ui/src/AppRoutes.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import * as React from "react";
import {Routes, Route, BrowserRouter} from "react-router-dom";
import { JamHome } from "./pages/jamhome/JamHome.tsx";
import {Header} from "./pages/components/Header.tsx";
import {QueryClient, QueryClientProvider} from "react-query";
import {AuthContextProvider} from "./api/AuthContext.tsx";
import {MyPostWrapper} from "./pages/mypost/MyPostWrapper.tsx";
import {Callback} from "./pages/callback/Callback.tsx";
import {Post} from "./pages/post/Post.tsx";
import {Logout} from "./pages/logout/Logout.tsx";
import Footer from "./pages/components/Footer.tsx";
import {About} from "./pages/about/About.tsx";
import {Index} from "./pages/index/Index.tsx";
import {JamSpecificStyling} from "./common/components/JamSpecificStyling.tsx";

const queryClient = new QueryClient({
defaultOptions: {
Expand All @@ -26,36 +23,31 @@ export const AppRoutes: React.FC = () => {
return (
<BrowserRouter>
<ReactQuerySiteWrapper>
<JamSpecificStyling>
<Header />
<div style={{
width: '100%',
padding: '1rem',
backgroundColor: '#FFA726',
border: '3px solid black',
color: "black",
fontSize: '2rem',
textAlign: 'center',
}}>
The team finder is in development mode, please come back later!
</div>
<div style={{
width: '100%',
padding: '1rem',
backgroundColor: '#FFA726',
border: '3px solid black',
color: "black",
fontSize: '2rem',
textAlign: 'center',
}}>
The team finder is in development mode, please come back later!
</div>

<Routes>
<Route path="/" element={<Index/>}/>
<Route path="/about" element={<About/>}/>
<Route path="/login/authorized" element={<Callback/>}/>
<Route path="/logout" element={<Logout/>}/>
<Routes>
<Route path="/" element={<Index/>}/>
<Route path="/about" element={<About/>}/>
<Route path="/login/authorized" element={<Callback/>}/>
<Route path="/logout" element={<Logout/>}/>

<Route path="/:jamId" element={<JamHome/>}/>
<Route path="/:jamId/:postId" element={<Post/>}/>
<Route path="/:jamId/my-post" element={<MyPostWrapper/>}/>
<Route path="/:jamId" element={<JamHome/>}/>
<Route path="/:jamId/:postId" element={<Post/>}/>
<Route path="/:jamId/my-post" element={<MyPostWrapper/>}/>

{/* TODO: replace with a proper Not Found page */}
<Route path="*" element={<p>u wot m8</p>}/>
</Routes>

<Footer />
</JamSpecificStyling>
{/* TODO: replace with a proper Not Found page */}
<Route path="*" element={<p>u wot m8</p>}/>
</Routes>

</ReactQuerySiteWrapper>
</BrowserRouter>
Expand Down
61 changes: 22 additions & 39 deletions ui/src/common/components/JamSpecificStyling.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React, {createContext, useEffect, useState} from "react";
import {useMatch} from "react-router-dom";
import {useParams} from "react-router-dom";
import {Header} from "../../pages/components/Header.tsx";
import Footer from "../../pages/components/Footer.tsx";

type Jam = {
jamId: string,
Expand All @@ -9,28 +11,19 @@ type Jam = {
expiry: number,
}

// Used on homepage etc. which don't have a theme
const defaultThemeContext: Jam = {
jamId: "",
logoLargeUrl: "",
logoStackedUrl: "",
styles: {},
expiry: Date.now()
}

export const JamSpecificThemeContext = createContext<Jam>(defaultThemeContext)
// TODO: How do you handle createContext properly?
export const JamSpecificContext = createContext<Jam>(undefined!)

export const JamSpecificStyling: React.FC<{children: any}> = ({children}) => {
const jamId = useMatch("/:jamId/:postId?")?.params.jamId!!;
const [activeTheme, setActiveTheme] = useState<Jam>()
useEffect(() => {
if (!jamId) return
const { jamId } = useParams()
const [activeJam, setActiveJam] = useState<Jam>()

const cachedThemeStr = localStorage.getItem(`theme_${jamId}`)
if (cachedThemeStr) {
const cachedTheme = JSON.parse(cachedThemeStr) as Jam
if (cachedTheme.expiry > Date.now()) {
setActiveTheme(cachedTheme)
useEffect(() => {
const cachedJamStr = localStorage.getItem(`theme_${jamId}`)
if (cachedJamStr) {
const cachedJam = JSON.parse(cachedJamStr) as Jam
if (cachedJam.expiry > Date.now()) {
setActiveJam(cachedJam)
return
}
}
Expand All @@ -45,34 +38,24 @@ export const JamSpecificStyling: React.FC<{children: any}> = ({children}) => {

return Promise.reject(data['message'])
})
.then(jam => setActiveTheme(jam))
.then(jam => setActiveJam(jam))

}, [jamId])

// Ignore theme handling for non-jam pages
// TODO: Fix this, it's just so so gross; should be fixed when a base site theme exists
console.log(window.location.pathname)
if (['/', '/about', '/login', '/login/authorized', '/logout'].includes(window.location.pathname)) {
return (
<JamSpecificThemeContext.Provider value={defaultThemeContext}>
{children}
</JamSpecificThemeContext.Provider>
)
}

// If searching for a jam by ID and not finding it:
if (jamId && activeTheme == null) {
if (activeJam == null) {
return (<>No jam of that ID could be found</>)
}

localStorage.setItem(`theme_${jamId}`, JSON.stringify(activeTheme))
localStorage.setItem(`theme_${jamId}`, JSON.stringify(activeJam))

const styles = Object.entries(activeTheme?.styles || {})
styles.map(style => document.documentElement.style.setProperty(style[0], style[1]))
// Set each CSS rule in the DB active on the page
Object.entries(activeJam.styles).map(style => document.documentElement.style.setProperty(style[0], style[1]))

return (
<JamSpecificThemeContext.Provider value={activeTheme!!}>
<JamSpecificContext.Provider value={activeJam}>
<Header />
{children}
</JamSpecificThemeContext.Provider>
<Footer />
</JamSpecificContext.Provider>
)
}
14 changes: 8 additions & 6 deletions ui/src/pages/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ import myPostIcon from "../../assets/icons/posts/my-post.svg"
import {toast} from "react-hot-toast";
import {useMyPostQuery} from "../../api/myPost.ts";
import {ReactSVG} from "react-svg";
import {JamSpecificThemeContext} from "../../common/components/JamSpecificStyling.tsx";
import {JamSpecificContext} from "../../common/components/JamSpecificStyling.tsx";

export const Header: React.FC = () => {

const theme = useContext(JamSpecificThemeContext)
const theme = useContext(JamSpecificContext)
const navigate = useNavigate();
const [isOnHomePage, setIsOnHomePage] = useState(window.location.pathname === "/");

const [isOnSearchPage, setIsOnSearchPage] = useState(window.location.pathname === `/${theme.jamId}`);

useEffect(() => {
setIsOnHomePage(window.location.pathname === "/")
setIsOnSearchPage(window.location.pathname === `/${theme.jamId}`)
}, [navigate]);

const userInfo = useUserInfo();
Expand Down Expand Up @@ -45,7 +47,7 @@ export const Header: React.FC = () => {
<Link to="/" className="bg-theme-d-4 block border border-white rounded-lg mr-2 sm:hidden">
<img src={theme.logoStackedUrl} width="40" height="40" alt={"jamName" + " Team Finder logo"}/>
</Link>
{isOnHomePage && <ToggleBookmarks />}
{isOnSearchPage && <ToggleBookmarks />}
<MyPostButton />
<LoginLogout />
</div>
Expand Down Expand Up @@ -126,7 +128,7 @@ const MyPostButton: React.FC = () => {
}

const LoginLogout: React.FC = () => {
const theme = useContext(JamSpecificThemeContext)
const theme = useContext(JamSpecificContext)
const userInfo = useUserInfo();
const shouldDisplayLogin = !userInfo.data;

Expand Down
21 changes: 12 additions & 9 deletions ui/src/pages/jamhome/JamHome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {Onboarding} from "./components/Onboarding.tsx";
import {SiteIntro} from "./components/SiteIntro.tsx";
import {useAuth} from "../../api/AuthContext.tsx";
import {Post} from "../../common/models/post.ts";
import { JamSpecificStyling } from "../../common/components/JamSpecificStyling.tsx";

export const JamHome: React.FC = () => {
const [searchParams, setSearchParams] = useSearchParams();
Expand Down Expand Up @@ -39,16 +40,18 @@ export const JamHome: React.FC = () => {
}, [searchParams])

return (
<main>
<Onboarding />
<SiteIntro />
<SearchFormWrapper searchParams={searchParams} setSearchParams={setSearchParams} />
<JamSpecificStyling>
<main>
<Onboarding />
<SiteIntro />
<SearchFormWrapper searchParams={searchParams} setSearchParams={setSearchParams} />

{posts?.length > 0
? <PostsToDisplay posts={posts} />
: <NoPostsToDisplay isViewingBookmarks={isViewingBookmarks} />
}
</main>
{posts?.length > 0
? <PostsToDisplay posts={posts} />
: <NoPostsToDisplay isViewingBookmarks={isViewingBookmarks} />
}
</main>
</JamSpecificStyling>
)
}

Expand Down
4 changes: 2 additions & 2 deletions ui/src/pages/jamhome/components/SiteIntro.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {useContext, useEffect, useState} from "react";
import {JamSpecificThemeContext} from "../../../common/components/JamSpecificStyling.tsx";
import {JamSpecificContext} from "../../../common/components/JamSpecificStyling.tsx";

const jamName = import.meta.env.VITE_JAM_NAME;
const jamStartDate = new Date(import.meta.env.VITE_JAM_START);

// Set the date we're counting down to
export const SiteIntro = () => {
const theme = useContext(JamSpecificThemeContext)
const theme = useContext(JamSpecificContext)

return (<div className="mb-8 sm:mb-8">
<img
Expand Down
51 changes: 27 additions & 24 deletions ui/src/pages/mypost/MyPostWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {Button} from "../../common/components/Button.tsx";
import {useEnsureLoggedIn} from "../../api/ensureLoggedIn.ts";
import {useUserInfo} from "../../api/userInfo.ts";
import {useParams} from "react-router-dom";
import {JamSpecificStyling} from "../../common/components/JamSpecificStyling.tsx";

// @ts-ignore
const defaultFormValues: Post = {
Expand Down Expand Up @@ -77,30 +78,32 @@ export const MyPostWrapper: React.FC = () => {
if (myPostQuery?.isLoading) {return (<></>)}

return (
<main>
<div className="c-form bg-black">
<Formik
initialValues={ initialValues }
validate={ onValidateForm }
validateOnChange={false}
validateOnBlur={false}
onSubmit={ (values, { setSubmitting }) => onSubmitForm(values, setSubmitting) }
>
{(params: FormikProps<Post>) => (
<>
<h1 className="text-3xl my-4">Create New Post</h1>
<MyPost params={params}
jamId={jamId!!}
author={userInfo.data!.username as string}
authorId={userInfo.data!.userId as string}
hasPost={Boolean(post)}
/>
</>
)}
</Formik>
{post && <DeletePostButton postId={post.id} onClickHandler={() => deletePostMutation.mutate({ postId: post.id })} />}
</div>
</main>
<JamSpecificStyling>
<main>
<div className="c-form bg-black">
<Formik
initialValues={ initialValues }
validate={ onValidateForm }
validateOnChange={false}
validateOnBlur={false}
onSubmit={ (values, { setSubmitting }) => onSubmitForm(values, setSubmitting) }
>
{(params: FormikProps<Post>) => (
<>
<h1 className="text-3xl my-4">Create New Post</h1>
<MyPost params={params}
jamId={jamId!!}
author={userInfo.data!.username as string}
authorId={userInfo.data!.userId as string}
hasPost={Boolean(post)}
/>
</>
)}
</Formik>
{post && <DeletePostButton postId={post.id} onClickHandler={() => deletePostMutation.mutate({ postId: post.id })} />}
</div>
</main>
</JamSpecificStyling>
)
}

Expand Down
5 changes: 3 additions & 2 deletions ui/src/pages/post/Post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {ReportBrokenDMsButton} from "./components/ReportBrokenDMsButton.tsx";
import {FavouritePostIndicator} from "../../common/components/FavouritePostIndicator.tsx";
import {iiicon} from "../../common/utils/iiicon.tsx";
import {JoinDiscordButton} from "./components/JoinDiscordButton.tsx";
import {JamSpecificStyling} from "../../common/components/JamSpecificStyling.tsx";

export const Post: React.FC<{}> = () => {

Expand All @@ -35,7 +36,7 @@ export const Post: React.FC<{}> = () => {
}

return (
<>
<JamSpecificStyling>
<header className="container mx-auto px-4 pb-6 pt-4 text-xl">
<a className="text-grey-200 mr-2 cursor-pointer hover:underline" onClick={() => navigate(-1)}>Search results</a>
<span className="mr-2">{iiicon('right-arrow', "#FFFFFF", 16, 16)}</span>
Expand Down Expand Up @@ -100,7 +101,7 @@ export const Post: React.FC<{}> = () => {
</div>
</section>
</main>
</>
</JamSpecificStyling>
)
}

Expand Down

0 comments on commit 3ac3a0a

Please sign in to comment.