0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-30 20:33:54 -05:00

feat(console): init app create form

This commit is contained in:
Gao Sun 2022-03-06 13:39:14 +08:00
parent 387ee50684
commit 2196b217fd
No known key found for this signature in database
GPG key ID: 13EBE123E4773688
10 changed files with 143 additions and 15 deletions

View file

@ -26,6 +26,7 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-i18next": "^11.15.4",
"react-modal": "^3.14.4",
"react-router-dom": "^6.2.2",
"swr": "^1.2.2"
},
@ -39,6 +40,7 @@
"@types/lodash.kebabcase": "^4.1.6",
"@types/react": "^17.0.14",
"@types/react-dom": "^17.0.9",
"@types/react-modal": "^3.13.1",
"eslint": "^8.10.0",
"lint-staged": "^11.1.1",
"parcel": "^2.3.1",

View file

@ -1,9 +1,6 @@
.app {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
inset: 0;
display: flex;
flex-direction: column;
}

View file

@ -1,5 +1,4 @@
import classNames from 'classnames';
import React, { ReactNode } from 'react';
import React, { ReactNode, useEffect } from 'react';
import * as styles from './index.module.scss';
@ -11,7 +10,16 @@ type Props = {
};
const AppContent = ({ children, theme }: Props) => {
return <div className={classNames(styles.app, styles.web, styles[theme])}>{children}</div>;
useEffect(() => {
const classes = [styles.web, styles[theme]].filter((value): value is string => Boolean(value));
document.body.classList.add(...classes);
return () => {
document.body.classList.remove(...classes);
};
}, [theme]);
return <div className={styles.app}>{children}</div>;
};
export default AppContent;

View file

@ -1,13 +1,15 @@
import classNames from 'classnames';
import React, { ReactNode } from 'react';
import * as styles from './index.module.scss';
type Props = {
children: ReactNode;
className?: string;
};
const Card = ({ children }: Props) => {
return <div className={styles.card}>{children}</div>;
const Card = ({ children, className }: Props) => {
return <div className={classNames(styles.card, className)}>{children}</div>;
};
export default Card;

View file

@ -0,0 +1,18 @@
@use '@/scss/underscore' as _;
.card {
padding: _.unit(8);
}
.headline {
display: flex;
justify-content: space-between;
> *:not(:first-child) {
margin-left: _.unit(3);
}
> svg {
cursor: pointer;
}
}

View file

@ -0,0 +1,32 @@
import React, { SVGProps } from 'react';
import Card from '@/components/Card';
import CardTitle from '@/components/CardTitle';
import * as styles from './index.module.scss';
const Close = (props: SVGProps<SVGSVGElement>) => (
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" {...props}>
<path
d="M7.05727 7.05703C7.57797 6.53633 8.42219 6.53633 8.94289 7.05703L16.0001 14.1142L23.0573 7.05703C23.578 6.53633 24.4222 6.53633 24.9429 7.05703C25.4636 7.57773 25.4636 8.42195 24.9429 8.94265L17.8857 15.9998L24.9429 23.057C25.4636 23.5777 25.4636 24.4219 24.9429 24.9426C24.4222 25.4633 23.578 25.4633 23.0573 24.9426L16.0001 17.8855L8.94289 24.9426C8.42219 25.4633 7.57797 25.4633 7.05727 24.9426C6.53657 24.4219 6.53657 23.5777 7.05727 23.057L14.1145 15.9998L7.05727 8.94265C6.53657 8.42195 6.53657 7.57773 7.05727 7.05703Z"
fill="#333333"
/>
</svg>
);
type Props = {
onClose?: () => void;
};
const Create = ({ onClose }: Props) => {
return (
<Card className={styles.card}>
<div className={styles.headline}>
<CardTitle title="applications.create" subtitle="applications.subtitle" />
<Close onClick={onClose} />
</div>
</Card>
);
};
export default Create;

View file

@ -1,6 +1,7 @@
import { Application } from '@logto/schemas';
import React from 'react';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import Modal from 'react-modal';
import useSWR from 'swr';
import Button from '@/components/Button';
@ -9,12 +10,15 @@ import CardTitle from '@/components/CardTitle';
import CopyToClipboard from '@/components/CopyToClipboard';
import ImagePlaceholder from '@/components/ImagePlaceholder';
import ItemPreview from '@/components/ItemPreview';
import * as modalStyles from '@/scss/modal.module.scss';
import { RequestError } from '@/swr';
import { applicationTypeI18nKey } from '@/types/applications';
import Create from './components/Create';
import * as styles from './index.module.scss';
const Applications = () => {
const [isCreateFormOpen, setIsCreateFormOpen] = useState(false);
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { data, error } = useSWR<Application[], RequestError>('/api/applications');
const isLoading = !data && !error;
@ -23,7 +27,23 @@ const Applications = () => {
<Card>
<div className={styles.headline}>
<CardTitle title="applications.title" subtitle="applications.subtitle" />
<Button disabled title="admin_console.applications.create" />
<Button
title="admin_console.applications.create"
onClick={() => {
setIsCreateFormOpen(true);
}}
/>
<Modal
isOpen={isCreateFormOpen}
className={modalStyles.content}
overlayClassName={modalStyles.overlay}
>
<Create
onClose={() => {
setIsCreateFormOpen(false);
}}
/>
</Modal>
</div>
<table className={styles.table}>
<thead>

View file

@ -0,0 +1,13 @@
.content {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
outline: none;
}
.overlay {
position: fixed;
background: rgba(0, 0, 0, 40%);
inset: 0;
}

View file

@ -1,9 +1,6 @@
.content {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
inset: 0;
background: var(--color-background);
color: var(--color-body);
}

View file

@ -32,6 +32,7 @@ importers:
'@types/lodash.kebabcase': ^4.1.6
'@types/react': ^17.0.14
'@types/react-dom': ^17.0.9
'@types/react-modal': ^3.13.1
classnames: ^2.3.1
eslint: ^8.10.0
i18next: ^21.6.12
@ -45,6 +46,7 @@ importers:
react: ^17.0.2
react-dom: ^17.0.2
react-i18next: ^11.15.4
react-modal: ^3.14.4
react-router-dom: ^6.2.2
stylelint: ^13.13.1
swr: ^1.2.2
@ -60,6 +62,7 @@ importers:
react: 17.0.2
react-dom: 17.0.2_react@17.0.2
react-i18next: 11.15.4_2c37a602a29bb6bd53f3de707a8cfcc5
react-modal: 3.14.4_react-dom@17.0.2+react@17.0.2
react-router-dom: 6.2.2_react-dom@17.0.2+react@17.0.2
swr: 1.2.2_react@17.0.2
devDependencies:
@ -72,6 +75,7 @@ importers:
'@types/lodash.kebabcase': 4.1.6
'@types/react': 17.0.37
'@types/react-dom': 17.0.11
'@types/react-modal': 3.13.1
eslint: 8.10.0
lint-staged: 11.2.6
parcel: 2.3.1_postcss@8.4.6
@ -3566,6 +3570,12 @@ packages:
'@types/react': 17.0.37
dev: true
/@types/react-modal/3.13.1:
resolution: {integrity: sha512-iY/gPvTDIy6Z+37l+ibmrY+GTV4KQTHcCyR5FIytm182RQS69G5ps4PH2FxtC7bAQ2QRHXMevsBgck7IQruHNg==}
dependencies:
'@types/react': 17.0.37
dev: true
/@types/react-router-dom/5.3.2:
resolution: {integrity: sha512-ELEYRUie2czuJzaZ5+ziIp9Hhw+juEw8b7C11YNA4QdLCVbQ3qLi2l4aq8XnlqM7V31LZX8dxUuFUCrzHm6sqQ==}
dependencies:
@ -6004,6 +6014,10 @@ packages:
clone-regexp: 2.2.0
dev: true
/exenv/1.2.2:
resolution: {integrity: sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=}
dev: false
/exit/0.1.2:
resolution: {integrity: sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=}
engines: {node: '>= 0.8.0'}
@ -11251,6 +11265,25 @@ packages:
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
dev: true
/react-lifecycles-compat/3.0.4:
resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==}
dev: false
/react-modal/3.14.4_react-dom@17.0.2+react@17.0.2:
resolution: {integrity: sha512-8surmulejafYCH9wfUmFyj4UfbSJwjcgbS9gf3oOItu4Hwd6ivJyVBETI0yHRhpJKCLZMUtnhzk76wXTsNL6Qg==}
engines: {node: '>=8'}
peerDependencies:
react: ^0.14.0 || ^15.0.0 || ^16 || ^17
react-dom: ^0.14.0 || ^15.0.0 || ^16 || ^17
dependencies:
exenv: 1.2.2
prop-types: 15.8.1
react: 17.0.2
react-dom: 17.0.2_react@17.0.2
react-lifecycles-compat: 3.0.4
warning: 4.0.3
dev: false
/react-refresh/0.9.0:
resolution: {integrity: sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==}
engines: {node: '>=0.10.0'}
@ -13245,6 +13278,12 @@ packages:
makeerror: 1.0.12
dev: true
/warning/4.0.3:
resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==}
dependencies:
loose-envify: 1.4.0
dev: false
/wcwidth/1.0.1:
resolution: {integrity: sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=}
dependencies: