0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-24 22:41:28 -05:00

feat(console): modal layout ()

This commit is contained in:
Xiao Yijun 2022-03-21 17:29:06 +08:00 committed by GitHub
parent e9a3d7c434
commit 3e99ac172a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 120 additions and 73 deletions
packages/console/src
components/ModalLayout
pages/ApiResourceDetails/components/DeleteForm
scss

View file

@ -0,0 +1,21 @@
@use '@/scss/underscore' as _;
.container {
display: flex;
flex-direction: column;
max-width: 800px;
padding: _.unit(8);
.header {
display: flex;
align-items: flex-start;
justify-content: space-between;
flex-shrink: 0;
}
.footer {
flex-shrink: 0;
padding-top: _.unit(6);
border-top: 1px solid var(--color-neutral-90);
}
}

View file

@ -0,0 +1,40 @@
import { AdminConsoleKey } from '@logto/phrases';
import React, { ReactNode } from 'react';
import Close from '@/icons/Close';
import Card from '../Card';
import CardTitle from '../CardTitle';
import IconButton from '../IconButton';
import * as styles from './index.module.scss';
type Props = {
title: AdminConsoleKey;
subtitle?: AdminConsoleKey;
children: ReactNode;
footer?: ReactNode;
onClose?: () => void;
};
const ModalLayout = ({ title, subtitle, children, footer, onClose }: Props) => {
return (
<Card className={styles.container}>
<div className={styles.header}>
<CardTitle title={title} subtitle={subtitle} />
{onClose && (
<IconButton
onClick={() => {
onClose();
}}
>
<Close />
</IconButton>
)}
</div>
<div>{children}</div>
{footer && <div className={styles.footer}>{footer}</div>}
</Card>
);
};
export default ModalLayout;

View file

@ -1,27 +1,12 @@
@use '@/scss/underscore' as _;
.card {
padding: _.unit(8);
max-width: 800px;
.content {
padding: _.unit(6) 0;
> :not(:first-child) {
margin-top: _.unit(6);
}
.headline {
display: flex;
align-items: center;
justify-content: space-between;
.close {
cursor: pointer;
}
}
.line {
border-top: 1px solid var(--color-neutral-90);
}
.description {
font: var(--font-body-2);
}
@ -29,13 +14,13 @@
.hightlight {
color: var(--color-primary-50);
}
.actions {
text-align: right;
> :not(:first-child) {
margin-left: _.unit(4);
}
}
}
.actions {
display: flex;
justify-content: flex-end;
> :not(:first-child) {
margin-left: _.unit(4);
}
}

View file

@ -4,12 +4,9 @@ import { Trans, useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import Button from '@/components/Button';
import Card from '@/components/Card';
import CardTitle from '@/components/CardTitle';
import IconButton from '@/components/IconButton';
import ModalLayout from '@/components/ModalLayout';
import TextInput from '@/components/TextInput';
import useApi from '@/hooks/use-api';
import Close from '@/icons/Close';
import * as styles from './index.module.scss';
@ -44,45 +41,44 @@ const DeleteForm = ({ id, name, onClose }: Props) => {
};
return (
// TODO LOG-1907: Modal
<Card className={styles.card}>
<div className={styles.headline}>
<CardTitle title="api_resource_details.reminder" />
<IconButton size="large" onClick={onClose}>
<Close />
</IconButton>
</div>
<div className={styles.description}>
<Trans
t={t}
i18nKey="api_resource_details.delete_description"
values={{ name }}
components={{ span: <span className={styles.hightlight} /> }}
<ModalLayout
title="api_resource_details.reminder"
footer={
<div className={styles.actions}>
<Button
type="outline"
title="admin_console.api_resource_details.cancel"
onClick={onClose}
/>
<Button
disabled={inputMismatched || loading}
type="danger"
title="admin_console.api_resource_details.delete"
onClick={handleDelete}
/>
</div>
}
onClose={onClose}
>
<div className={styles.content}>
<div className={styles.description}>
<Trans
t={t}
i18nKey="api_resource_details.delete_description"
values={{ name }}
components={{ span: <span className={styles.hightlight} /> }}
/>
</div>
<TextInput
value={inputName}
placeholder={t('api_resource_details.enter_your_api_resource_name')}
hasError={inputMismatched}
onChange={(event) => {
setInputName(event.currentTarget.value);
}}
/>
</div>
<TextInput
value={inputName}
placeholder={t('api_resource_details.enter_your_api_resource_name')}
hasError={inputMismatched}
onChange={(event) => {
setInputName(event.currentTarget.value);
}}
/>
<div className={styles.line} />
<div className={styles.actions}>
<Button
type="outline"
title="admin_console.api_resource_details.cancel"
onClick={onClose}
/>
<Button
disabled={inputMismatched || loading}
type="danger"
title="admin_console.api_resource_details.delete"
onClick={handleDelete}
/>
</div>
</Card>
</ModalLayout>
);
};

View file

@ -1,15 +1,20 @@
.content {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
outline: none;
}
@use '@/scss/underscore' as _;
.overlay {
position: fixed;
background: rgba(0, 0, 0, 40%);
inset: 0;
overflow-y: auto;
padding: _.unit(12) 0;
}
.content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex: 0 0;
min-height: 100%;
}
.fullScreen {