mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 12:55:00 +00:00
init: the first public commit for AFFiNE
This commit is contained in:
221
libs/components/account/src/error.tsx
Normal file
221
libs/components/account/src/error.tsx
Normal file
@@ -0,0 +1,221 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import style9 from 'style9';
|
||||
import { getAuth, signOut } from 'firebase/auth';
|
||||
|
||||
import { MuiBox as Box } from '@toeverything/components/ui';
|
||||
import { keyframes } from '@emotion/react';
|
||||
import { LOGOUT_LOCAL_STORAGE, LOGOUT_COOKIES } from '@toeverything/utils';
|
||||
|
||||
const styles = style9.create({
|
||||
container: {
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
height: 'calc( 100vh - 64px )',
|
||||
},
|
||||
});
|
||||
|
||||
type ErrorProps = {
|
||||
title?: string;
|
||||
subTitle?: string;
|
||||
action1Text?: string;
|
||||
action1Route?: string;
|
||||
action2Text?: string;
|
||||
action2Route?: string;
|
||||
clearOnClick?: boolean;
|
||||
};
|
||||
|
||||
const floatAnimation = keyframes`
|
||||
100% { transform: translateY(20px) }
|
||||
`;
|
||||
|
||||
/**
|
||||
* Exception related pages
|
||||
*/
|
||||
export function Error({
|
||||
title = 'Page Not Found',
|
||||
subTitle,
|
||||
action1Text,
|
||||
action1Route,
|
||||
action2Text,
|
||||
action2Route,
|
||||
clearOnClick = false,
|
||||
}: ErrorProps) {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
height: '100vh',
|
||||
backgroundColor: '#2F3242',
|
||||
position: 'relative',
|
||||
'& svg': {
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '45%',
|
||||
marginTop: '-250px',
|
||||
marginLeft: '-400px',
|
||||
},
|
||||
'& .message-box': {
|
||||
height: '200px',
|
||||
minWidth: '380px',
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '45%',
|
||||
marginTop: '-100px',
|
||||
marginLeft: '0',
|
||||
color: '#FFF',
|
||||
// font-family: Roboto;
|
||||
// font-weight: 300;
|
||||
},
|
||||
'& .message-box h1': {
|
||||
fontSize: '60px',
|
||||
lineHeight: '46px',
|
||||
marginBottom: '40px',
|
||||
color: '#FFF',
|
||||
},
|
||||
'& .message-box h3': {
|
||||
fontSize: '32px',
|
||||
fontWeight: 400,
|
||||
lineHeight: '32px',
|
||||
color: '#FFF',
|
||||
},
|
||||
'& .buttons-con .action-link-wrap': {
|
||||
marginTop: '40px',
|
||||
},
|
||||
'& .buttons-con .action-link-wrap a': {
|
||||
backgroundColor: '#3E6FDB',
|
||||
padding: ' 8px 25px',
|
||||
borderRadius: '4px',
|
||||
color: '#FFF',
|
||||
fontWeight: 'bold',
|
||||
// font-size: 14px;
|
||||
transition: 'all 0.3s linear',
|
||||
cursor: 'pointer',
|
||||
textDecoration: 'none',
|
||||
marginRight: '10px',
|
||||
},
|
||||
'& .buttons-con .action-link-wrap a:hover': {
|
||||
backgroundColor: '#5A5C6C',
|
||||
color: '#fff',
|
||||
},
|
||||
'& #Polygon-1': {
|
||||
animation: 'float 1s infinite ease-in-out alternate',
|
||||
},
|
||||
'& #Polygon-2': {
|
||||
animation: `${floatAnimation} 1s infinite ease-in-out alternate`,
|
||||
animationDelay: '0.2s',
|
||||
},
|
||||
'& #Polygon-3': {
|
||||
animation: `${floatAnimation} 1s infinite ease-in-out alternate`,
|
||||
animationDelay: '0.4s',
|
||||
},
|
||||
'& #Polygon-4': {
|
||||
animation: `${floatAnimation} 1s infinite ease-in-out alternate`,
|
||||
animationDelay: '0.6s',
|
||||
},
|
||||
'& #Polygon-5': {
|
||||
animation: `${floatAnimation} 1s infinite ease-in-out alternate`,
|
||||
animationDelay: '0.8s',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<div className="root">
|
||||
<svg
|
||||
width="380px"
|
||||
height="500px"
|
||||
viewBox="0 0 837 1045"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
id="Page-1"
|
||||
stroke="none"
|
||||
strokeWidth="1"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
// sketch:type="MSPage"
|
||||
>
|
||||
<path
|
||||
d="M353,9 L626.664028,170 L626.664028,487 L353,642 L79.3359724,487 L79.3359724,170 L353,9 Z"
|
||||
id="Polygon-1"
|
||||
stroke="#007FB2"
|
||||
strokeWidth="6"
|
||||
// sketch:type="MSShapeGroup"
|
||||
/>
|
||||
<path
|
||||
d="M78.5,529 L147,569.186414 L147,648.311216 L78.5,687 L10,648.311216 L10,569.186414 L78.5,529 Z"
|
||||
id="Polygon-2"
|
||||
stroke="#EF4A5B"
|
||||
strokeWidth="6"
|
||||
// sketch:type="MSShapeGroup"
|
||||
/>
|
||||
<path
|
||||
d="M773,186 L827,217.538705 L827,279.636651 L773,310 L719,279.636651 L719,217.538705 L773,186 Z"
|
||||
id="Polygon-3"
|
||||
stroke="#795D9C"
|
||||
strokeWidth="6"
|
||||
// sketch:type="MSShapeGroup"
|
||||
/>
|
||||
<path
|
||||
d="M639,529 L773,607.846761 L773,763.091627 L639,839 L505,763.091627 L505,607.846761 L639,529 Z"
|
||||
id="Polygon-4"
|
||||
stroke="#F2773F"
|
||||
strokeWidth="6"
|
||||
// sketch:type="MSShapeGroup"
|
||||
/>
|
||||
<path
|
||||
d="M281,801 L383,861.025276 L383,979.21169 L281,1037 L179,979.21169 L179,861.025276 L281,801 Z"
|
||||
id="Polygon-5"
|
||||
stroke="#36B455"
|
||||
strokeWidth="6"
|
||||
// sketch:type="MSShapeGroup"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
<div className="message-box">
|
||||
<h1>{title}</h1>
|
||||
{subTitle ? <h3>{subTitle}</h3> : null}
|
||||
<div className="buttons-con">
|
||||
<div className="action-link-wrap">
|
||||
{/* {action1Text ? (
|
||||
<Link
|
||||
to={action1Route || '/login'}
|
||||
className="link-button link-back-button"
|
||||
onClick={event => {
|
||||
if (clearOnClick) {
|
||||
event.preventDefault();
|
||||
LOGOUT_LOCAL_STORAGE.forEach(name =>
|
||||
localStorage.removeItem(name)
|
||||
);
|
||||
document.cookie =
|
||||
LOGOUT_COOKIES.map(
|
||||
name =>
|
||||
name +
|
||||
'=; expires=Thu, 01 Jan 1970 00:00:01 GMT;'
|
||||
).join(' ');
|
||||
|
||||
signOut(getAuth());
|
||||
|
||||
window.location.href =
|
||||
action1Route || '/login';
|
||||
}
|
||||
}}
|
||||
>
|
||||
{action1Text}
|
||||
</Link>
|
||||
) : null} */}
|
||||
{/* {action2Text ? (
|
||||
<Link
|
||||
to={action2Route || '/login'}
|
||||
className="link-button link-back-button"
|
||||
>
|
||||
{action2Text}
|
||||
</Link>
|
||||
) : null} */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
3
libs/components/account/src/index.ts
Normal file
3
libs/components/account/src/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export { Login } from './login';
|
||||
export { Error } from './error';
|
||||
export { PageLoading } from './loading';
|
||||
23
libs/components/account/src/loading.tsx
Normal file
23
libs/components/account/src/loading.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import style9 from 'style9';
|
||||
import { MuiCircularProgress as CircularProgress } from '@toeverything/components/ui';
|
||||
|
||||
const styles = style9.create({
|
||||
container: {
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
height: 'calc( 100vh - 64px )',
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Loading components occupy the entire page
|
||||
*/
|
||||
export function PageLoading() {
|
||||
return (
|
||||
<div className={styles('container')}>
|
||||
<CircularProgress />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
78
libs/components/account/src/login/authing.tsx
Normal file
78
libs/components/account/src/login/authing.tsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import style9 from 'style9';
|
||||
import { MuiBox as Box } from '@toeverything/components/ui';
|
||||
import { Guard as AuthingGuard } from '@authing/react-ui-components';
|
||||
import type { User as AuthingUser } from 'authing-js-sdk';
|
||||
|
||||
import {
|
||||
AUTHING_APP_ID_US,
|
||||
AUTHING_APP_ID_CN,
|
||||
AUTHING_APP_HOST_US,
|
||||
} from '@toeverything/utils';
|
||||
import { useUserAndSpaces } from '@toeverything/datasource/state';
|
||||
|
||||
import '@authing/react-ui-components/lib/index.min.css';
|
||||
|
||||
export function Authing() {
|
||||
const navigate = useNavigate();
|
||||
const { handleUserLoginSuccess, currentSpaceId } = useUserAndSpaces();
|
||||
|
||||
/**
|
||||
* Refer to Authing documentation https://docs.authing.cn/v2/reference/guard/react.html
|
||||
*/
|
||||
const handle_login_success = useCallback(
|
||||
async (authingUser: AuthingUser) => {
|
||||
handleUserLoginSuccess(authingUser);
|
||||
},
|
||||
[handleUserLoginSuccess]
|
||||
);
|
||||
|
||||
const authing_config = useMemo(() => {
|
||||
return {
|
||||
host: AUTHING_APP_HOST_US,
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentSpaceId) {
|
||||
const targetRoute = `/${currentSpaceId}`;
|
||||
navigate(targetRoute);
|
||||
}
|
||||
}, [currentSpaceId, navigate]);
|
||||
|
||||
return (
|
||||
<div className={styles('loginContainer')}>
|
||||
<Box
|
||||
sx={{
|
||||
'.g2-view-header': {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
'.authing-g2-render-module': {
|
||||
boxShadow: '0 2px 10px 0 rgb(57 106 255 / 20%)',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<AuthingGuard
|
||||
onLogin={handle_login_success}
|
||||
appId={AUTHING_APP_ID_US}
|
||||
config={authing_config}
|
||||
/>
|
||||
<Box sx={{ height: '56px' }} />
|
||||
</Box>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = style9.create({
|
||||
loginContainer: {
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
height: 'calc( 100vh - 64px )',
|
||||
},
|
||||
});
|
||||
135
libs/components/account/src/login/firebase.tsx
Normal file
135
libs/components/account/src/login/firebase.tsx
Normal file
@@ -0,0 +1,135 @@
|
||||
/* eslint-disable filename-rules/match */
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { initializeApp } from 'firebase/app';
|
||||
import { Error } from './../error';
|
||||
import {
|
||||
GoogleAuthProvider,
|
||||
getAuth,
|
||||
signInWithPopup,
|
||||
browserLocalPersistence,
|
||||
} from 'firebase/auth';
|
||||
|
||||
import { LogoImg } from '@toeverything/components/common';
|
||||
import {
|
||||
MuiButton,
|
||||
MuiBox,
|
||||
MuiTypography,
|
||||
MuiContainer,
|
||||
MuiGrid,
|
||||
} from '@toeverything/components/ui';
|
||||
|
||||
const _firebaseConfig = {
|
||||
apiKey: 'AIzaSyD7A_VyGaKTXsPqtga9IbwrEsbWWc4rH3Y',
|
||||
authDomain: 'login.affine.pro',
|
||||
projectId: 'affine-346417',
|
||||
storageBucket: 'affine-346417.appspot.com',
|
||||
messagingSenderId: '690608236388',
|
||||
appId: '1:690608236388:web:ccc7ee97b59a4cf2677c71',
|
||||
};
|
||||
|
||||
const _app = initializeApp(_firebaseConfig);
|
||||
|
||||
const GoogleIcon = () => (
|
||||
<svg width="24px" height="24px" viewBox="0 0 118 120">
|
||||
<g
|
||||
id="Page-1"
|
||||
stroke="none"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
>
|
||||
<g id="Artboard-1" transform="translate(-332.000000, -639.000000)">
|
||||
<g
|
||||
id="google_buttn"
|
||||
transform="translate(332.000000, 639.000000)"
|
||||
>
|
||||
<g id="logo_googleg_48dp">
|
||||
<path
|
||||
d="M117.6,61.3636364 C117.6,57.1090909 117.218182,53.0181818 116.509091,49.0909091 L60,49.0909091 L60,72.3 L92.2909091,72.3 C90.9,79.8 86.6727273,86.1545455 80.3181818,90.4090909 L80.3181818,105.463636 L99.7090909,105.463636 C111.054545,95.0181818 117.6,79.6363636 117.6,61.3636364 L117.6,61.3636364 Z"
|
||||
id="Shape"
|
||||
fill="#4285F4"
|
||||
/>
|
||||
<path
|
||||
d="M60,120 C76.2,120 89.7818182,114.627273 99.7090909,105.463636 L80.3181818,90.4090909 C74.9454545,94.0090909 68.0727273,96.1363636 60,96.1363636 C44.3727273,96.1363636 31.1454545,85.5818182 26.4272727,71.4 L6.38181818,71.4 L6.38181818,86.9454545 C16.2545455,106.554545 36.5454545,120 60,120 L60,120 Z"
|
||||
id="Shape"
|
||||
fill="#34A853"
|
||||
/>
|
||||
<path
|
||||
d="M26.4272727,71.4 C25.2272727,67.8 24.5454545,63.9545455 24.5454545,60 C24.5454545,56.0454545 25.2272727,52.2 26.4272727,48.6 L26.4272727,33.0545455 L6.38181818,33.0545455 C2.31818182,41.1545455 0,50.3181818 0,60 C0,69.6818182 2.31818182,78.8454545 6.38181818,86.9454545 L26.4272727,71.4 L26.4272727,71.4 Z"
|
||||
id="Shape"
|
||||
fill="#FBBC05"
|
||||
/>
|
||||
<path
|
||||
d="M60,23.8636364 C68.8090909,23.8636364 76.7181818,26.8909091 82.9363636,32.8363636 L100.145455,15.6272727 C89.7545455,5.94545455 76.1727273,0 60,0 C36.5454545,0 16.2545455,13.4454545 6.38181818,33.0545455 L26.4272727,48.6 C31.1454545,34.4181818 44.3727273,23.8636364 60,23.8636364 L60,23.8636364 Z"
|
||||
id="Shape"
|
||||
fill="#EA4335"
|
||||
/>
|
||||
<path
|
||||
d="M0,0 L120,0 L120,120 L0,120 L0,0 Z"
|
||||
id="Shape"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const Firebase = () => {
|
||||
const [auth, provider] = useMemo(() => {
|
||||
const auth = getAuth(_app);
|
||||
auth.setPersistence(browserLocalPersistence);
|
||||
const provider = new GoogleAuthProvider();
|
||||
return [auth, provider];
|
||||
}, []);
|
||||
|
||||
const handleAuth = useCallback(() => {
|
||||
signInWithPopup(auth, provider).catch(error => {
|
||||
const errorCode = error.code;
|
||||
const errorMessage = error.message;
|
||||
const email = error.customData.email;
|
||||
const credential = GoogleAuthProvider.credentialFromError(error);
|
||||
console.log(errorCode, errorMessage, email, credential);
|
||||
});
|
||||
}, [auth, provider]);
|
||||
|
||||
return (
|
||||
<MuiGrid container>
|
||||
<MuiGrid item xs={8}>
|
||||
<Error
|
||||
title="Welcome to Affine"
|
||||
subTitle="blocks of knowledge to power your team"
|
||||
action1Text="Login or Register"
|
||||
/>
|
||||
</MuiGrid>
|
||||
|
||||
<MuiGrid item xs={4}>
|
||||
<MuiBox
|
||||
onSubmit={handleAuth}
|
||||
onClick={handleAuth}
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
width: '300px',
|
||||
margin: '300px auto 20px auto',
|
||||
}}
|
||||
sx={{ mt: 1 }}
|
||||
>
|
||||
<LogoImg
|
||||
style={{
|
||||
width: '100px',
|
||||
}}
|
||||
/>
|
||||
|
||||
<MuiButton
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
style={{ textTransform: 'none' }}
|
||||
startIcon={<GoogleIcon />}
|
||||
>
|
||||
Continue with Google
|
||||
</MuiButton>
|
||||
</MuiBox>
|
||||
</MuiGrid>
|
||||
</MuiGrid>
|
||||
);
|
||||
};
|
||||
11
libs/components/account/src/login/index.tsx
Normal file
11
libs/components/account/src/login/index.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
// import { Authing } from './authing';
|
||||
import { Firebase } from './firebase';
|
||||
|
||||
export function Login() {
|
||||
return (
|
||||
<>
|
||||
{/* <Authing /> */}
|
||||
<Firebase />
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user