0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

feat(console): integrate React SDK

This commit is contained in:
Gao Sun 2022-03-11 19:04:27 +08:00
parent 56c8b6069a
commit 38d8196794
No known key found for this signature in database
GPG key ID: 13EBE123E4773688
32 changed files with 168 additions and 51 deletions

1
.npmrc
View file

@ -1,4 +1,5 @@
# Hoist for Parcel
public-hoist-pattern[]=@parcel/*
public-hoist-pattern[]=postcss
public-hoist-pattern[]=process
public-hoist-pattern[]=*eslint*

View file

@ -32,6 +32,7 @@
},
"alias": {
"html-parse-stringify": "html-parse-stringify/dist/html-parse-stringify.module.js",
"react-hook-form": "react-hook-form/dist/index.esm.mjs"
"react-hook-form": "react-hook-form/dist/index.esm.mjs",
"superstruct": "superstruct/lib/index.es.js"
}
}

View file

@ -17,6 +17,7 @@
},
"dependencies": {
"@logto/phrases": "^0.1.0",
"@logto/react": "^0.1.2",
"@logto/schemas": "^0.1.0",
"@monaco-editor/react": "^4.3.1",
"@silverhand/essentials": "^1.1.6",
@ -55,6 +56,7 @@
"postcss": "^8.4.6",
"postcss-modules": "^4.3.0",
"prettier": "^2.3.2",
"process": "^0.11.10",
"stylelint": "^13.13.1",
"typescript": "^4.6.2"
},

View file

@ -1,9 +0,0 @@
@use '@/scss/underscore' as _;
.content {
flex-grow: 1;
display: flex;
padding-right: _.unit(5);
margin-bottom: _.unit(6);
overflow: hidden;
}

View file

@ -1,14 +1,13 @@
import { LogtoProvider } from '@logto/react';
import React, { useEffect } from 'react';
import { BrowserRouter, Navigate, Route, Routes, useLocation, useNavigate } from 'react-router-dom';
import { SWRConfig } from 'swr';
import './scss/normalized.scss';
import * as styles from './App.module.scss';
import AppContent from './components/AppContent';
import Content from './components/Content';
import Sidebar, { getPath, sections } from './components/Sidebar';
import { getPath, sections } from './components/AppContent/components/Sidebar';
import Callback from './components/Callback';
import Toast from './components/Toast';
import Topbar from './components/Topbar';
import initI18n from './i18n/init';
import ApiResourceDetails from './pages/ApiResourceDetails';
import ApiResources from './pages/ApiResources';
@ -34,39 +33,36 @@ const Main = () => {
}, [location.pathname, navigate]);
return (
<SWRConfig value={{ fetcher }}>
<Toast />
<AppContent theme="light">
<Topbar />
<div className={styles.content}>
<Sidebar />
<Content>
<Routes>
<Route path="applications">
<Route index element={<Applications />} />
<Route path=":id">
<Route index element={<Navigate to="settings" />} />
<Route path="settings" element={<ApplicationDetails />} />
<Route path="advanced-settings" element={<ApplicationDetails />} />
</Route>
<LogtoProvider logtoConfig={{ endpoint: 'https://logto.dev', clientId: 'foo' }}>
<SWRConfig value={{ fetcher }}>
<Toast />
<Routes>
<Route path="callback" element={<Callback />} />
<Route element={<AppContent theme="light" />}>
<Route path="applications">
<Route index element={<Applications />} />
<Route path=":id">
<Route index element={<Navigate to="settings" />} />
<Route path="settings" element={<ApplicationDetails />} />
<Route path="advanced-settings" element={<ApplicationDetails />} />
</Route>
<Route path="api-resources">
<Route index element={<ApiResources />} />
<Route path=":id" element={<ApiResourceDetails />} />
</Route>
<Route path="connectors">
<Route index element={<Connectors />} />
<Route path="social" element={<Connectors />} />
<Route path=":connectorId" element={<ConnectorDetails />} />
</Route>
<Route path="users">
<Route index element={<Users />} />
</Route>
</Routes>
</Content>
</div>
</AppContent>
</SWRConfig>
</Route>
<Route path="api-resources">
<Route index element={<ApiResources />} />
<Route path=":id" element={<ApiResourceDetails />} />
</Route>
<Route path="connectors">
<Route index element={<Connectors />} />
<Route path="social" element={<Connectors />} />
<Route path=":connectorId" element={<ConnectorDetails />} />
</Route>
<Route path="users">
<Route index element={<Users />} />
</Route>
</Route>
</Routes>
</SWRConfig>
</LogtoProvider>
);
};

View file

@ -1,4 +1,5 @@
@use '@/scss/colors' as colors;
@use '@/scss/underscore' as _;
.app {
position: absolute;
@ -7,6 +8,14 @@
flex-direction: column;
}
.content {
flex-grow: 1;
display: flex;
padding-right: _.unit(5);
margin-bottom: _.unit(6);
overflow: hidden;
}
.light {
@include colors.light-theme;
}

View file

@ -1,15 +1,22 @@
import React, { ReactNode, useEffect } from 'react';
import { useLogto } from '@logto/react';
import React, { useEffect } from 'react';
import { Outlet, useHref } from 'react-router-dom';
import Content from './components/Content';
import Sidebar from './components/Sidebar';
import Topbar from './components/Topbar';
import * as styles from './index.module.scss';
type Theme = 'light';
type Props = {
children: ReactNode;
theme: Theme;
};
const AppContent = ({ children, theme }: Props) => {
const AppContent = ({ theme }: Props) => {
const { isAuthenticated, signIn } = useLogto();
const href = useHref('/callback');
useEffect(() => {
const classes = [styles.web, styles[theme]].filter((value): value is string => Boolean(value));
document.body.classList.add(...classes);
@ -19,7 +26,27 @@ const AppContent = ({ children, theme }: Props) => {
};
}, [theme]);
return <div className={styles.app}>{children}</div>;
useEffect(() => {
if (!isAuthenticated) {
void signIn(new URL(href, window.location.origin).toString());
}
}, [href, isAuthenticated, signIn]);
if (!isAuthenticated) {
return <>loading</>;
}
return (
<div className={styles.app}>
<Topbar />
<div className={styles.content}>
<Sidebar />
<Content>
<Outlet />
</Content>
</div>
</div>
);
};
export default AppContent;

View file

@ -0,0 +1,18 @@
import { useLogto } from '@logto/react';
import React, { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
const Callback = () => {
const { isAuthenticated, isLoading } = useLogto();
const navigate = useNavigate();
useEffect(() => {
if (isAuthenticated && !isLoading) {
navigate('/', { replace: true });
}
}, [isAuthenticated, isLoading, navigate]);
return <p>Redirecting...</p>;
};
export default Callback;

View file

@ -21,6 +21,7 @@ importers:
packages/console:
specifiers:
'@logto/phrases': ^0.1.0
'@logto/react': ^0.1.2
'@logto/schemas': ^0.1.0
'@monaco-editor/react': ^4.3.1
'@parcel/core': ^2.3.2
@ -47,6 +48,7 @@ importers:
postcss: ^8.4.6
postcss-modules: ^4.3.0
prettier: ^2.3.2
process: ^0.11.10
react: ^17.0.2
react-dom: ^17.0.2
react-hook-form: ^7.27.1
@ -61,6 +63,7 @@ importers:
typescript: ^4.6.2
dependencies:
'@logto/phrases': link:../phrases
'@logto/react': 0.1.2_react@17.0.2
'@logto/schemas': link:../schemas
'@monaco-editor/react': 4.3.1_e62f1489d5efe674a41c3f8d6971effe
'@silverhand/essentials': 1.1.6
@ -98,6 +101,7 @@ importers:
postcss: 8.4.6
postcss-modules: 4.3.0_postcss@8.4.6
prettier: 2.5.1
process: 0.11.10
stylelint: 13.13.1
typescript: 4.6.2
@ -2233,6 +2237,38 @@ packages:
prop-types: 15.8.1
react: 17.0.2
react-dom: 17.0.2_react@17.0.2
/@logto/browser/0.1.2:
resolution: {integrity: sha512-sTJjnx00BXYEChCbbO/LPs0x0wE1bDSHniFi+u93cynyEHgoT5yjMnH4N39NhrpmRdkXxOxaIkXmyAT1nSmYzQ==}
requiresBuild: true
dependencies:
'@logto/js': 0.1.2
'@silverhand/essentials': 1.1.6
jose: 4.6.0
lodash.get: 4.4.2
superstruct: 0.15.4
dev: false
/@logto/js/0.1.2:
resolution: {integrity: sha512-kz7l++gfpXa1OaUaB5WvnHNXQKEJDFnBzVYAofPADnPftHEF0zYRuQDCa8PJMd6/ECKfL1XPLMlJMNP/5U2fqQ==}
requiresBuild: true
dependencies:
'@silverhand/essentials': 1.1.6
camelcase-keys: 7.0.2
jose: 4.6.0
js-base64: 3.7.2
lodash.get: 4.4.2
superstruct: 0.15.4
dev: false
/@logto/react/0.1.2_react@17.0.2:
resolution: {integrity: sha512-kxLOvxOv3IB8BjpbcoRFsBFX249wAfbOL0tfJlSWmOXrkPouai1bRItEFBHFKDI1zLJATVQRoJNQfaczJy/c0A==}
requiresBuild: true
peerDependencies:
react: '>=16.8.0'
dependencies:
'@logto/browser': 0.1.2
'@silverhand/essentials': 1.1.6
react: 17.0.2
dev: false
/@nodelib/fs.scandir/2.1.5:
@ -4506,6 +4542,16 @@ packages:
quick-lru: 4.0.1
dev: true
/camelcase-keys/7.0.2:
resolution: {integrity: sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==}
engines: {node: '>=12'}
dependencies:
camelcase: 6.3.0
map-obj: 4.3.0
quick-lru: 5.1.1
type-fest: 1.4.0
dev: false
/camelcase/5.3.1:
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
engines: {node: '>=6'}
@ -4515,6 +4561,11 @@ packages:
resolution: {integrity: sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==}
engines: {node: '>=10'}
/camelcase/6.3.0:
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
engines: {node: '>=10'}
dev: false
/caniuse-api/3.0.0:
resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==}
dependencies:
@ -8568,6 +8619,14 @@ packages:
resolution: {integrity: sha512-S7Xfsy8nN9Iw/AZxk+ZxEbd5ImIwJPM0TfAo8zI8FF+3lidQ2yiK4dqzsaPKSbZD0woNVSY0KCql6rlKc5V7ug==}
dev: false
/jose/4.6.0:
resolution: {integrity: sha512-0hNAkhMBNi4soKSAX4zYOFV+aqJlEz/4j4fregvasJzEVtjDChvWqRjPvHwLqr5hx28Ayr6bsOs1Kuj87V0O8w==}
dev: false
/js-base64/3.7.2:
resolution: {integrity: sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==}
dev: false
/js-tokens/4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@ -9073,7 +9132,6 @@ packages:
/lodash.get/4.4.2:
resolution: {integrity: sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=}
dev: true
/lodash.ismatch/4.4.0:
resolution: {integrity: sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=}
@ -11565,6 +11623,11 @@ packages:
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
dev: true
/process/0.11.10:
resolution: {integrity: sha1-czIwDoQBYb2j5podHZGn1LwW8YI=}
engines: {node: '>= 0.6.0'}
dev: true
/promise-deferred/2.0.3:
resolution: {integrity: sha512-n10XaoznCzLfyPFOlEE8iurezHpxrYzyjgq/1eW9Wk1gJwur/N7BdBmjJYJpqMeMcXK4wEbzo2EvZQcqjYcKUQ==}
engines: {node: '>= 0.4'}
@ -13156,6 +13219,10 @@ packages:
- supports-color
dev: true
/superstruct/0.15.4:
resolution: {integrity: sha512-eOoMeSbP9ZJChNOm/9RYjE+F36rYR966AAqeG3xhQB02j2sfAUXDp4EQ/7bAOqnlJnuFDB8yvOu50SocvKpUEw==}
dev: false
/supertest/6.2.2:
resolution: {integrity: sha512-wCw9WhAtKJsBvh07RaS+/By91NNE0Wh0DN19/hWPlBOU8tAfOtbZoVSV4xXeoKoxgPx0rx2y+y+8660XtE7jzg==}
engines: {node: '>=6.0.0'}
@ -13666,6 +13733,11 @@ packages:
engines: {node: '>=8'}
dev: true
/type-fest/1.4.0:
resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==}
engines: {node: '>=10'}
dev: false
/type-fest/2.8.0:
resolution: {integrity: sha512-O+V9pAshf9C6loGaH0idwsmugI2LxVNR7DtS40gVo2EXZVYFgz9OuNtOhgHLdHdapOEWNdvz9Ob/eeuaWwwlxA==}
engines: {node: '>=12.20'}