2022-06-06 07:06:34 -05:00
|
|
|
import { LogtoProvider, useLogto, UserInfoResponse } from '@logto/react';
|
2022-06-02 03:05:27 -05:00
|
|
|
import { signInNotificationStorageKey } from '@logto/schemas';
|
2022-06-02 02:32:46 -05:00
|
|
|
import { demoAppApplicationId } from '@logto/schemas/lib/seeds';
|
2022-06-06 07:06:34 -05:00
|
|
|
import React, { useEffect, useState } from 'react';
|
|
|
|
import { useTranslation } from 'react-i18next';
|
2022-05-29 08:11:58 -05:00
|
|
|
|
|
|
|
import '@/scss/normalized.scss';
|
2022-05-30 23:39:03 -05:00
|
|
|
import * as styles from './App.module.scss';
|
|
|
|
import Callback from './Callback';
|
|
|
|
import congrats from './assets/congrats.svg';
|
2022-06-06 07:06:34 -05:00
|
|
|
import initI18n from './i18n/init';
|
|
|
|
|
|
|
|
void initI18n();
|
2022-05-30 23:39:03 -05:00
|
|
|
|
|
|
|
const Main = () => {
|
2022-06-06 07:06:34 -05:00
|
|
|
const { isAuthenticated, fetchUserInfo, signIn, signOut } = useLogto();
|
|
|
|
const [user, setUser] = useState<UserInfoResponse>();
|
|
|
|
const { t } = useTranslation(undefined, { keyPrefix: 'demo_app' });
|
2022-05-30 23:39:03 -05:00
|
|
|
const isInCallback = Boolean(new URL(window.location.href).searchParams.get('code'));
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (!isAuthenticated && !isInCallback) {
|
2022-06-06 07:06:34 -05:00
|
|
|
sessionStorage.setItem(signInNotificationStorageKey, t('notification'));
|
2022-05-30 23:39:03 -05:00
|
|
|
void signIn(window.location.href);
|
|
|
|
}
|
2022-06-06 07:06:34 -05:00
|
|
|
}, [isAuthenticated, isInCallback, signIn, t]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
(async () => {
|
|
|
|
if (isAuthenticated) {
|
|
|
|
const userInfo = await fetchUserInfo();
|
|
|
|
setUser(userInfo);
|
|
|
|
}
|
|
|
|
})();
|
|
|
|
}, [isAuthenticated, fetchUserInfo]);
|
2022-05-30 23:39:03 -05:00
|
|
|
|
|
|
|
if (isInCallback) {
|
|
|
|
return <Callback />;
|
|
|
|
}
|
|
|
|
|
2022-06-06 07:06:34 -05:00
|
|
|
if (!isAuthenticated || !user) {
|
2022-05-30 23:39:03 -05:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className={styles.app}>
|
|
|
|
<div className={styles.card}>
|
|
|
|
<img src={congrats} alt="Congrats" />
|
2022-06-06 07:06:34 -05:00
|
|
|
<div className={styles.title}>{t('title')}</div>
|
|
|
|
<div className={styles.text}>{t('subtitle')}</div>
|
2022-05-30 23:39:03 -05:00
|
|
|
<div className={styles.infoCard}>
|
2022-06-06 07:06:34 -05:00
|
|
|
<div>
|
|
|
|
{t('username')}
|
|
|
|
<span>{user.username}</span>
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
{t('user_id')}
|
|
|
|
<span>{user.sub}</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
className={styles.button}
|
|
|
|
onClick={async () => signOut(`${window.location.origin}/demo-app`)}
|
|
|
|
>
|
|
|
|
{t('sign_out')}
|
2022-05-30 23:39:03 -05:00
|
|
|
</div>
|
|
|
|
<div className={styles.continue}>
|
|
|
|
<div className={styles.hr} />
|
2022-06-06 07:06:34 -05:00
|
|
|
{t('continue_explore')}
|
2022-05-30 23:39:03 -05:00
|
|
|
<div className={styles.hr} />
|
|
|
|
</div>
|
|
|
|
<div className={styles.actions}>
|
2022-06-06 07:06:34 -05:00
|
|
|
<a href="#">{t('customize_sign_in_experience')}</a>
|
2022-05-30 23:39:03 -05:00
|
|
|
<span />
|
2022-06-06 07:06:34 -05:00
|
|
|
<a href="#">{t('enable_passwordless')}</a>
|
2022-05-30 23:39:03 -05:00
|
|
|
<span />
|
2022-06-06 07:06:34 -05:00
|
|
|
<a href="#">{t('add_social_connector')}</a>
|
2022-05-30 23:39:03 -05:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
2022-05-29 08:11:58 -05:00
|
|
|
|
|
|
|
const App = () => {
|
2022-05-30 23:39:03 -05:00
|
|
|
return (
|
|
|
|
<LogtoProvider
|
|
|
|
config={{
|
|
|
|
endpoint: window.location.origin,
|
|
|
|
appId: demoAppApplicationId,
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<Main />
|
|
|
|
</LogtoProvider>
|
|
|
|
);
|
2022-05-29 08:11:58 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
export default App;
|