mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-17 01:56:27 +08:00
feat: modify 404 page (#4383)
This commit is contained in:
+31
-40
@@ -1,46 +1,37 @@
|
||||
import { displayFlex, styled } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { Button } from '@toeverything/components/button';
|
||||
import { NotFoundPage } from '@affine/component/not-found-page';
|
||||
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
||||
import { useSession } from 'next-auth/react';
|
||||
import type { ReactElement } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { useNavigateHelper } from '../hooks/use-navigate-helper';
|
||||
|
||||
export const StyledContainer = styled('div')(() => {
|
||||
return {
|
||||
...displayFlex('center', 'center'),
|
||||
flexDirection: 'column',
|
||||
height: '100vh',
|
||||
|
||||
img: {
|
||||
width: '360px',
|
||||
height: '270px',
|
||||
},
|
||||
p: {
|
||||
fontSize: '22px',
|
||||
fontWeight: 600,
|
||||
margin: '24px 0',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export const NotFoundPage = () => {
|
||||
const t = useAFFiNEI18N();
|
||||
const { jumpToIndex } = useNavigateHelper();
|
||||
const handleBackButtonClick = useCallback(() => jumpToIndex(), [jumpToIndex]);
|
||||
|
||||
return (
|
||||
<StyledContainer data-testid="notFound">
|
||||
<img alt="404" src="/imgs/invite-error.svg" width={360} height={270} />
|
||||
|
||||
<p>{t['com.affine.notFoundPage.title']()}</p>
|
||||
<Button onClick={handleBackButtonClick}>
|
||||
{t['com.affine.notFoundPage.backButton']()}
|
||||
</Button>
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
import { RouteLogic, useNavigateHelper } from '../hooks/use-navigate-helper';
|
||||
import { signOutCloud } from '../utils/cloud-utils';
|
||||
|
||||
export const Component = (): ReactElement => {
|
||||
return <NotFoundPage />;
|
||||
const { data: session } = useSession();
|
||||
const { jumpToIndex } = useNavigateHelper();
|
||||
const handleBackButtonClick = useCallback(
|
||||
() => jumpToIndex(RouteLogic.REPLACE),
|
||||
[jumpToIndex]
|
||||
);
|
||||
const handleSignOut = useCallback(async () => {
|
||||
await signOutCloud({
|
||||
callbackUrl: '/signIn',
|
||||
});
|
||||
}, []);
|
||||
return (
|
||||
<NotFoundPage
|
||||
user={
|
||||
session?.user
|
||||
? {
|
||||
name: session.user.name || '',
|
||||
email: session.user.email || '',
|
||||
avatar: session.user.image || '',
|
||||
}
|
||||
: null
|
||||
}
|
||||
onBack={handleBackButtonClick}
|
||||
onSignOut={handleSignOut}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './not-found-page';
|
||||
@@ -0,0 +1,52 @@
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { SignOutIcon } from '@blocksuite/icons';
|
||||
import { Avatar } from '@toeverything/components/avatar';
|
||||
import { Button, IconButton } from '@toeverything/components/button';
|
||||
import { Tooltip } from '@toeverything/components/tooltip';
|
||||
|
||||
import { NotFoundPattern } from './not-found-pattern';
|
||||
import { notFoundPageContainer, wrapper } from './styles.css';
|
||||
|
||||
export interface NotFoundPageProps {
|
||||
user: {
|
||||
name: string;
|
||||
email: string;
|
||||
avatar: string;
|
||||
} | null;
|
||||
onBack: () => void;
|
||||
onSignOut: () => void;
|
||||
}
|
||||
export const NotFoundPage = ({
|
||||
user,
|
||||
onBack,
|
||||
onSignOut,
|
||||
}: NotFoundPageProps) => {
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
return (
|
||||
<div className={notFoundPageContainer}>
|
||||
<div>
|
||||
<div className={wrapper}>
|
||||
<NotFoundPattern />
|
||||
</div>
|
||||
<div className={wrapper}>
|
||||
<Button type="primary" size="extraLarge" onClick={onBack}>
|
||||
{t['404.back']()}
|
||||
</Button>
|
||||
</div>
|
||||
<p className={wrapper}>{t['404.hint']()}</p>
|
||||
{user ? (
|
||||
<div className={wrapper}>
|
||||
<Avatar url={user.avatar} name={user.name} />
|
||||
<span style={{ margin: '0 12px' }}>{user.email}</span>
|
||||
<Tooltip content={t['404.signOut']()}>
|
||||
<IconButton onClick={onSignOut}>
|
||||
<SignOutIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,121 @@
|
||||
export const NotFoundPattern = () => {
|
||||
return (
|
||||
<svg
|
||||
width="240"
|
||||
height="209"
|
||||
viewBox="0 0 240 209"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M24.4197 172.91L119.045 8.64233L213.671 172.91H24.4197Z"
|
||||
stroke="var(--affine-text-disable-color)"
|
||||
strokeOpacity="0.6"
|
||||
/>
|
||||
<path
|
||||
d="M165.921 91.5342L119.045 172.161L72.1684 91.5342L165.921 91.5342Z"
|
||||
stroke="var(--affine-text-disable-color)"
|
||||
strokeOpacity="0.6"
|
||||
/>
|
||||
<path
|
||||
d="M179.022 68.1181C179.022 101.243 152.169 128.096 119.045 128.096C85.9202 128.096 59.0674 101.243 59.0674 68.1181C59.0674 34.9934 85.9202 8.14062 119.045 8.14062C152.169 8.14062 179.022 34.9934 179.022 68.1181Z"
|
||||
stroke="var(--affine-text-disable-color)"
|
||||
strokeOpacity="0.6"
|
||||
/>
|
||||
<circle
|
||||
cx="162.485"
|
||||
cy="142.984"
|
||||
r="59.9775"
|
||||
transform="rotate(120 162.485 142.984)"
|
||||
stroke="var(--affine-text-disable-color)"
|
||||
strokeOpacity="0.6"
|
||||
/>
|
||||
<circle
|
||||
cx="75.2925"
|
||||
cy="142.984"
|
||||
r="59.9775"
|
||||
transform="rotate(-120 75.2925 142.984)"
|
||||
stroke="var(--affine-text-disable-color)"
|
||||
strokeOpacity="0.6"
|
||||
/>
|
||||
<path
|
||||
d="M119.045 7.64062V173.158"
|
||||
stroke="var(--affine-text-disable-color)"
|
||||
strokeOpacity="0.6"
|
||||
/>
|
||||
<path
|
||||
d="M214.536 173.475L71.2998 91.0352"
|
||||
stroke="var(--affine-text-disable-color)"
|
||||
strokeOpacity="0.6"
|
||||
/>
|
||||
<path
|
||||
d="M23.5547 173.475L166.791 91.0352"
|
||||
stroke="var(--affine-text-disable-color)"
|
||||
strokeOpacity="0.6"
|
||||
/>
|
||||
<ellipse
|
||||
cx="119.045"
|
||||
cy="7.63971"
|
||||
rx="5.09284"
|
||||
ry="5.09284"
|
||||
fill="var(--affine-text-primary-color)"
|
||||
/>
|
||||
<ellipse
|
||||
cx="214.536"
|
||||
cy="173.155"
|
||||
rx="5.09284"
|
||||
ry="5.09284"
|
||||
fill="var(--affine-text-primary-color)"
|
||||
/>
|
||||
<ellipse
|
||||
cx="166.79"
|
||||
cy="91.0342"
|
||||
rx="5.09284"
|
||||
ry="5.09284"
|
||||
fill="var(--affine-text-primary-color)"
|
||||
/>
|
||||
<ellipse
|
||||
cx="119.045"
|
||||
cy="173.155"
|
||||
rx="5.09284"
|
||||
ry="5.09284"
|
||||
fill="var(--affine-text-primary-color)"
|
||||
/>
|
||||
<ellipse
|
||||
cx="71.2999"
|
||||
cy="91.0342"
|
||||
rx="5.09284"
|
||||
ry="5.09284"
|
||||
fill="var(--affine-text-primary-color)"
|
||||
/>
|
||||
<ellipse
|
||||
cx="119.045"
|
||||
cy="91.0342"
|
||||
rx="5.09284"
|
||||
ry="5.09284"
|
||||
fill="var(--affine-text-primary-color)"
|
||||
/>
|
||||
<ellipse
|
||||
cx="95.4903"
|
||||
cy="131.776"
|
||||
rx="5.09284"
|
||||
ry="5.09284"
|
||||
fill="var(--affine-text-primary-color)"
|
||||
/>
|
||||
<ellipse
|
||||
cx="143.236"
|
||||
cy="131.776"
|
||||
rx="5.09284"
|
||||
ry="5.09284"
|
||||
fill="var(--affine-text-primary-color)"
|
||||
/>
|
||||
<ellipse
|
||||
cx="23.5548"
|
||||
cy="173.155"
|
||||
rx="5.09284"
|
||||
ry="5.09284"
|
||||
fill="var(--affine-text-primary-color)"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const notFoundPageContainer = style({
|
||||
fontSize: 'var(--affine-font-base)',
|
||||
color: 'var(--affine-text-primary-color)',
|
||||
height: '100vh',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: '100vw',
|
||||
});
|
||||
|
||||
export const wrapper = style({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
margin: '24px auto 0',
|
||||
});
|
||||
@@ -574,5 +574,8 @@
|
||||
"Click to replace photo": "Click to replace photo",
|
||||
"Remove photo": "Remove photo",
|
||||
"Removed successfully": "Removed successfully",
|
||||
"Successfully enabled AFFiNE Cloud": "Successfully enabled AFFiNE Cloud"
|
||||
"Successfully enabled AFFiNE Cloud": "Successfully enabled AFFiNE Cloud",
|
||||
"404.hint": "Sorry, you do not have access or this content does not exist...",
|
||||
"404.back": "Back to My Content",
|
||||
"404.signOut": "Sign in to another account"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user