mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
feat: add 'not found' view
This commit is contained in:
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 392 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 415 KiB |
+17
-4
@@ -1,11 +1,12 @@
|
||||
import { useEffect } from 'react';
|
||||
import { Outlet, Route, Routes, useLocation, useParams } from 'react-router-dom';
|
||||
import { isHomeView } from './lib/utils/view-utils';
|
||||
import { isHomeView, isNotFoundView } from './lib/utils/view-utils';
|
||||
import useTheme from './hooks/use-theme';
|
||||
import styles from './app.module.css';
|
||||
import Board from './views/board';
|
||||
import Catalog from './views/catalog';
|
||||
import Home from './views/home';
|
||||
import NotFound from './views/not-found';
|
||||
import PendingPost from './views/pending-post';
|
||||
import PostPage from './views/post-page';
|
||||
import Settings from './views/settings';
|
||||
@@ -17,9 +18,17 @@ import SubplebbitStats from './components/subplebbit-stats';
|
||||
import PostForm from './components/post-form';
|
||||
|
||||
const BoardLayout = () => {
|
||||
const { subplebbitAddress } = useParams();
|
||||
const { accountCommentIndex, commentCid, subplebbitAddress } = useParams();
|
||||
const location = useLocation();
|
||||
|
||||
const isValidAccountCommentIndex = !accountCommentIndex || (!isNaN(parseInt(accountCommentIndex)) && parseInt(accountCommentIndex) >= 0);
|
||||
const isValidCommentCid = !commentCid || /^Qm[a-zA-Z0-9]{44}$/.test(commentCid);
|
||||
const isValidSubplebbitAddress = subplebbitAddress && (subplebbitAddress.includes('.') || /^12D3K[a-zA-Z0-9]{44}$/.test(subplebbitAddress));
|
||||
|
||||
if (!isValidAccountCommentIndex || !isValidCommentCid || !isValidSubplebbitAddress) {
|
||||
return <NotFound />;
|
||||
}
|
||||
|
||||
// force rerender of post form when navigating between pages
|
||||
const key = `${subplebbitAddress}-${location.pathname}`;
|
||||
|
||||
@@ -38,14 +47,16 @@ const BoardLayout = () => {
|
||||
|
||||
const App = () => {
|
||||
const location = useLocation();
|
||||
const params = useParams();
|
||||
const isInHomeView = isHomeView(location.pathname);
|
||||
const isInNotFoundPage = isNotFoundView(location.pathname, params);
|
||||
const [theme] = useTheme();
|
||||
|
||||
useEffect(() => {
|
||||
document.body.classList.forEach((className) => document.body.classList.remove(className));
|
||||
const classToAdd = isInHomeView ? 'yotsuba' : theme;
|
||||
const classToAdd = isInHomeView || isInNotFoundPage ? 'yotsuba' : theme;
|
||||
document.body.classList.add(classToAdd);
|
||||
}, [theme, isInHomeView]);
|
||||
}, [theme, isInHomeView, isInNotFoundPage]);
|
||||
|
||||
const globalLayout = (
|
||||
<>
|
||||
@@ -71,6 +82,8 @@ const App = () => {
|
||||
<Route path='/profile/:accountCommentIndex' element={<PendingPost />} />
|
||||
</Route>
|
||||
<Route path='/settings' element={<Settings />} />
|
||||
|
||||
<Route path='*' element={<NotFound />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</div>
|
||||
|
||||
@@ -96,9 +96,7 @@ const Challenge = ({ challenge, closeModal }: ChallengeProps) => {
|
||||
/>
|
||||
<div className={styles.challengeMediaWrapper}>
|
||||
{isTextChallenge && <div className={styles.challengeMedia}>{challenges[currentChallengeIndex]?.challenge}</div>}
|
||||
{isImageChallenge && (
|
||||
<img alt={t('loading')} className={styles.challengeMedia} src={`data:image/png;base64,${challenges[currentChallengeIndex]?.challenge}`} />
|
||||
)}
|
||||
{isImageChallenge && <img alt='' className={styles.challengeMedia} src={`data:image/png;base64,${challenges[currentChallengeIndex]?.challenge}`} />}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.challengeFooter}>
|
||||
|
||||
@@ -34,3 +34,14 @@ export const isCatalogView = (pathname: string, params: ParamsType): boolean =>
|
||||
export const isPendingPostView = (pathname: string, params: ParamsType): boolean => {
|
||||
return pathname === `/profile/${params.accountCommentIndex}`;
|
||||
};
|
||||
|
||||
export const isNotFoundView = (pathname: string, params: ParamsType): boolean => {
|
||||
return (
|
||||
!isHomeView(pathname) &&
|
||||
!isDescriptionView(pathname, params) &&
|
||||
!isRulesView(pathname, params) &&
|
||||
!isPostPageView(pathname, params) &&
|
||||
!isCatalogView(pathname, params) &&
|
||||
!isPendingPostView(pathname, params)
|
||||
);
|
||||
};
|
||||
|
||||
+11
-5
@@ -472,6 +472,16 @@ const Footer = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const HomeLogo = () => {
|
||||
return (
|
||||
<Link to='/'>
|
||||
<div className={styles.logo}>
|
||||
<img alt='' src='/assets/logo/logo-transparent.png' />
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
const Home = () => {
|
||||
const defaultSubplebbits = useDefaultSubplebbits();
|
||||
const subplebbitAddresses = useDefaultSubplebbitAddresses();
|
||||
@@ -479,11 +489,7 @@ const Home = () => {
|
||||
|
||||
return (
|
||||
<div className={styles.content}>
|
||||
<Link to='/'>
|
||||
<div className={styles.logo}>
|
||||
<img alt='' src='/assets/logo/logo-transparent.png' />
|
||||
</div>
|
||||
</Link>
|
||||
<HomeLogo />
|
||||
<SearchBar />
|
||||
<InfoBox />
|
||||
<Boards multisub={defaultSubplebbits} subplebbits={subplebbits} />
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { default } from './home';
|
||||
export { HomeLogo, default } from './home';
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from './not-found';
|
||||
@@ -0,0 +1,56 @@
|
||||
.content {
|
||||
margin: auto;
|
||||
text-align: left;
|
||||
width: 57.69em;
|
||||
min-width: 750px;
|
||||
}
|
||||
|
||||
.boxOuter {
|
||||
background: #fff;
|
||||
border: 1px solid;
|
||||
zoom: 100%;
|
||||
margin-bottom: .5em;
|
||||
padding-bottom: .5em;
|
||||
}
|
||||
|
||||
.boxBar {
|
||||
background: #fca;
|
||||
color: #800;
|
||||
position: relative;
|
||||
zoom: 100%;
|
||||
padding-left: .5em;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
.boxBar h2 {
|
||||
text-align: center;
|
||||
font-size: 131%;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.boxContent {
|
||||
margin-top: 10px;
|
||||
color: #000;
|
||||
line-height: 1.5em;
|
||||
font-size: 93%;
|
||||
padding: .5em;
|
||||
padding-top: .25em;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.boxContent img {
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.backToBoard {
|
||||
text-align: center;
|
||||
font-size: 12pt !important;
|
||||
margin: 0 20px 10px 20px;
|
||||
color: #800;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.backToBoard a {
|
||||
color: blue;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { useState } from 'react';
|
||||
import { Link, useParams } from 'react-router-dom';
|
||||
import { HomeLogo } from '../home';
|
||||
import styles from './not-found.module.css';
|
||||
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
|
||||
|
||||
const totalNotFoundImages = 2;
|
||||
|
||||
const NotFoundImage = () => {
|
||||
const [imagePath] = useState(() => {
|
||||
const randomBannerIndex = Math.floor(Math.random() * totalNotFoundImages) + 1;
|
||||
return `assets/not-found/not-found-${randomBannerIndex}.jpg`;
|
||||
});
|
||||
|
||||
return <img src={imagePath} alt='' />;
|
||||
};
|
||||
|
||||
const NotFound = () => {
|
||||
const { subplebbitAddress } = useParams();
|
||||
|
||||
return (
|
||||
<div className={styles.content}>
|
||||
<HomeLogo />
|
||||
<div className={styles.boxOuter}>
|
||||
<div className={styles.boxInner}>
|
||||
<div className={styles.boxBar}>
|
||||
<h2>404 Not Found</h2>
|
||||
</div>
|
||||
<div className={styles.boxContent}>
|
||||
<NotFoundImage />
|
||||
{subplebbitAddress && (
|
||||
<>
|
||||
<br />
|
||||
<div className={styles.backToBoard}>
|
||||
[<Link to={`/p/${subplebbitAddress}`}>Back to p/{Plebbit.getShortAddress(subplebbitAddress)}</Link>]
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NotFound;
|
||||
Reference in New Issue
Block a user