mirror of
https://github.com/logto-io/logto.git
synced 2024-12-30 20:33:54 -05:00
refactor: update per review
This commit is contained in:
parent
01df8f46a2
commit
e67187126d
11 changed files with 43 additions and 35 deletions
|
@ -1,18 +1,30 @@
|
|||
import type { Nullable } from '@silverhand/essentials';
|
||||
import { type Nullable } from '@silverhand/essentials';
|
||||
import { isValid } from 'date-fns';
|
||||
|
||||
type Props = {
|
||||
readonly children: Nullable<string | number>;
|
||||
};
|
||||
|
||||
function DateTime({ children }: Props) {
|
||||
const date = children && new Date(children);
|
||||
|
||||
if (!date || !isValid(date)) {
|
||||
return <span>-</span>;
|
||||
const parseDate = (date: Nullable<string | number | Date>) => {
|
||||
if (!date) {
|
||||
return;
|
||||
}
|
||||
|
||||
return <span>{date.toLocaleDateString()}</span>;
|
||||
const parsed = new Date(date);
|
||||
return isValid(parsed) ? parsed : undefined;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
readonly children: Nullable<string | number | Date>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Safely display a date in the user's locale. If the date is invalid, it will display a dash.
|
||||
*/
|
||||
export function LocaleDate({ children }: Props) {
|
||||
return <span>{parseDate(children)?.toLocaleDateString() ?? '-'}</span>;
|
||||
}
|
||||
|
||||
export default DateTime;
|
||||
/**
|
||||
* Safely display a date and time in the user's locale. If the date is invalid, it will display a
|
||||
* dash.
|
||||
*/
|
||||
export function LocaleDateTime({ children }: Props) {
|
||||
return <span>{parseDate(children)?.toLocaleString() ?? '-'}</span>;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import { type GuideMetadata } from '@/assets/docs/guides/types';
|
|||
import Button from '@/ds-components/Button';
|
||||
import OverlayScrollbar from '@/ds-components/OverlayScrollbar';
|
||||
import MdxProvider from '@/mdx-components/MdxProvider';
|
||||
import { type ApplicationSecretRow } from '@/pages/ApplicationDetails/ApplicationDetailsContent/EndpointsAndCredentials';
|
||||
import NotFound from '@/pages/NotFound';
|
||||
|
||||
import StepsSkeleton from './StepsSkeleton';
|
||||
|
@ -19,6 +20,7 @@ export type GuideContextType = {
|
|||
| ((props: { readonly className?: string }) => JSX.Element);
|
||||
isCompact: boolean;
|
||||
app?: ApplicationResponse;
|
||||
secrets?: ApplicationSecretRow[];
|
||||
endpoint?: string;
|
||||
redirectUris?: string[];
|
||||
postLogoutRedirectUris?: string[];
|
||||
|
@ -40,6 +42,7 @@ export const GuideContext = createContext<GuideContextType>({
|
|||
metadata: {} as GuideMetadata,
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, no-restricted-syntax
|
||||
app: {} as ApplicationResponse,
|
||||
secrets: [],
|
||||
endpoint: '',
|
||||
redirectUris: [],
|
||||
postLogoutRedirectUris: [],
|
||||
|
|
|
@ -72,11 +72,6 @@
|
|||
}
|
||||
|
||||
.dot {
|
||||
flex-shrink: 0;
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-text-secondary);
|
||||
-webkit-text-stroke: 1px var(--color-text);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,10 +60,7 @@ function CopyToClipboard(
|
|||
return value;
|
||||
}
|
||||
|
||||
return Array.from({ length: Math.max(Math.floor((value.length / 5) * 3), 1) }).map(
|
||||
// eslint-disable-next-line react/no-array-index-key -- No need to persist the key
|
||||
(_, index) => <span key={index} className={styles.dot} />
|
||||
);
|
||||
return <span className={styles.dot}>{'•'.repeat(value.length)}</span>;
|
||||
}, [hasVisibilityToggle, showHiddenContent, value]);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -9,8 +9,8 @@ import TextLink from '@/ds-components/TextLink';
|
|||
import styles from './index.module.scss';
|
||||
|
||||
function ApplicationCredentials() {
|
||||
const { app } = useContext(GuideContext);
|
||||
const { id, secret } = app ?? {};
|
||||
const { app, secrets } = useContext(GuideContext);
|
||||
const { id } = app ?? {};
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
|
||||
return (
|
||||
|
@ -37,12 +37,12 @@ function ApplicationCredentials() {
|
|||
<CopyToClipboard displayType="block" value={id} variant="border" />
|
||||
</FormField>
|
||||
)}
|
||||
{secret && (
|
||||
{secrets?.[0] && (
|
||||
<FormField title="application_details.application_secret">
|
||||
<CopyToClipboard
|
||||
hasVisibilityToggle
|
||||
displayType="block"
|
||||
value={secret}
|
||||
value={secrets[0].value}
|
||||
variant="border"
|
||||
/>
|
||||
</FormField>
|
||||
|
|
|
@ -31,7 +31,7 @@ button.add {
|
|||
}
|
||||
|
||||
.expired {
|
||||
color: var(--color-text-secondary);
|
||||
color: var(--color-placeholder);
|
||||
}
|
||||
|
||||
.copyToClipboard {
|
||||
|
|
|
@ -4,6 +4,7 @@ import { useMemo } from 'react';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import ActionsButton from '@/components/ActionsButton';
|
||||
import { LocaleDateTime } from '@/components/DateTime';
|
||||
import CopyToClipboard from '@/ds-components/CopyToClipboard';
|
||||
import { type Column } from '@/ds-components/Table/types';
|
||||
import { Tooltip } from '@/ds-components/Tip';
|
||||
|
@ -68,7 +69,7 @@ export const useSecretTableColumns = ({ appId, onUpdated }: UseSecretTableColumn
|
|||
compareDesc(expiresAt, new Date()) === 1 ? (
|
||||
<Expired expiresAt={new Date(expiresAt)} />
|
||||
) : (
|
||||
new Date(expiresAt).toLocaleString()
|
||||
<LocaleDateTime>{expiresAt}</LocaleDateTime>
|
||||
)
|
||||
) : (
|
||||
t('application_details.secrets.never')
|
||||
|
|
|
@ -6,7 +6,7 @@ import useSWR from 'swr';
|
|||
|
||||
import Plus from '@/assets/icons/plus.svg?react';
|
||||
import ActionsButton from '@/components/ActionsButton';
|
||||
import DateTime from '@/components/DateTime';
|
||||
import { LocaleDate } from '@/components/DateTime';
|
||||
import EmptyDataPlaceholder from '@/components/EmptyDataPlaceholder';
|
||||
import UserPreview from '@/components/ItemPreview/UserPreview';
|
||||
import { RoleOption } from '@/components/OrganizationRolesSelect';
|
||||
|
@ -96,7 +96,7 @@ function Members() {
|
|||
dataIndex: 'lastSignInAt',
|
||||
title: t('users.latest_sign_in'),
|
||||
colSpan: 5,
|
||||
render: ({ lastSignInAt }) => <DateTime>{lastSignInAt}</DateTime>,
|
||||
render: ({ lastSignInAt }) => <LocaleDate>{lastSignInAt}</LocaleDate>,
|
||||
},
|
||||
{
|
||||
dataIndex: 'actions',
|
||||
|
|
|
@ -9,7 +9,7 @@ import useSWR from 'swr';
|
|||
import Delete from '@/assets/icons/delete.svg?react';
|
||||
import Plus from '@/assets/icons/plus.svg?react';
|
||||
import ApplicationName from '@/components/ApplicationName';
|
||||
import DateTime from '@/components/DateTime';
|
||||
import { LocaleDate } from '@/components/DateTime';
|
||||
import EmptyDataPlaceholder from '@/components/EmptyDataPlaceholder';
|
||||
import UserPreview from '@/components/ItemPreview/UserPreview';
|
||||
import { defaultPageSize } from '@/consts';
|
||||
|
@ -103,7 +103,7 @@ function RoleUsers() {
|
|||
title: t('role_details.users.latest_sign_in_column'),
|
||||
dataIndex: 'latestSignIn',
|
||||
colSpan: 5,
|
||||
render: ({ lastSignInAt }) => <DateTime>{lastSignInAt}</DateTime>,
|
||||
render: ({ lastSignInAt }) => <LocaleDate>{lastSignInAt}</LocaleDate>,
|
||||
},
|
||||
{
|
||||
title: null,
|
||||
|
|
|
@ -8,7 +8,7 @@ import Plus from '@/assets/icons/plus.svg?react';
|
|||
import UsersEmptyDark from '@/assets/images/users-empty-dark.svg?react';
|
||||
import UsersEmpty from '@/assets/images/users-empty.svg?react';
|
||||
import ApplicationName from '@/components/ApplicationName';
|
||||
import DateTime from '@/components/DateTime';
|
||||
import { LocaleDate } from '@/components/DateTime';
|
||||
import EmptyDataPlaceholder from '@/components/EmptyDataPlaceholder';
|
||||
import ItemPreview from '@/components/ItemPreview';
|
||||
import ListPage from '@/components/ListPage';
|
||||
|
@ -104,7 +104,7 @@ function Users() {
|
|||
title: t('users.latest_sign_in'),
|
||||
dataIndex: 'lastSignInAt',
|
||||
colSpan: 5,
|
||||
render: ({ lastSignInAt }) => <DateTime>{lastSignInAt}</DateTime>,
|
||||
render: ({ lastSignInAt }) => <LocaleDate>{lastSignInAt}</LocaleDate>,
|
||||
},
|
||||
],
|
||||
filter: (
|
||||
|
|
|
@ -179,7 +179,7 @@ const application_details = {
|
|||
expiration: 'Expiration',
|
||||
expiration_description: 'The secret will expire at {{date}}.',
|
||||
expiration_description_never:
|
||||
'The secret will never expire. We recommend setting an expiration date for better security.',
|
||||
'The secret will never expire. We recommend setting an expiration date for enhanced security.',
|
||||
days: '{{count}} day',
|
||||
days_other: '{{count}} days',
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue