nicolium: migrate tokens page
Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
@ -1,16 +1,13 @@
|
||||
import { useInfiniteQuery, useMutation } from '@tanstack/react-query';
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import { defineMessages, FormattedDate, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import Badge from '@/components/badge';
|
||||
import Button from '@/components/ui/button';
|
||||
import Card, { CardBody, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import Column from '@/components/ui/column';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import Icon from '@/components/ui/icon';
|
||||
import Spinner from '@/components/ui/spinner';
|
||||
import Stack from '@/components/ui/stack';
|
||||
import Text from '@/components/ui/text';
|
||||
import { useAppSelector } from '@/hooks/use-app-selector';
|
||||
import {
|
||||
oauthTokensQueryOptions,
|
||||
@ -62,102 +59,93 @@ const AuthToken: React.FC<IAuthToken> = ({ token, isCurrent }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='rounded-lg bg-gray-100 p-4 dark:bg-primary-800'>
|
||||
<Stack space={2} className='h-full justify-between'>
|
||||
<Stack space={1}>
|
||||
<Text size='md' weight='medium'>
|
||||
<HStack space={1} alignItems='center'>
|
||||
{token.app_name}
|
||||
{token.app_website && (
|
||||
<a href={token.app_website} target='_blank' rel='noopener noreferrer'>
|
||||
<Icon
|
||||
src={require('@phosphor-icons/core/regular/arrow-square-out.svg')}
|
||||
className='inline size-4 text-inherit'
|
||||
<div className={clsx('⁂-token', { '⁂-token--current': isCurrent })}>
|
||||
<div className='⁂-token__info'>
|
||||
<p className='⁂-token__name'>
|
||||
{token.app_name}
|
||||
{token.app_website && (
|
||||
<a href={token.app_website} target='_blank' rel='noopener noreferrer'>
|
||||
<Icon src={require('@phosphor-icons/core/regular/arrow-square-out.svg')} />
|
||||
</a>
|
||||
)}
|
||||
</p>
|
||||
{token.scopes?.length > 0 && (
|
||||
<div className='⁂-token__tokens'>
|
||||
<p>
|
||||
<FormattedMessage id='security.tokens.scopes' defaultMessage='Scopes:' />
|
||||
</p>
|
||||
{token.scopes.map((scope) => (
|
||||
<Badge title={scope} slug='opaque' key={scope} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{token.created_at && (
|
||||
<p className='⁂-token__detail'>
|
||||
<FormattedMessage
|
||||
id='security.tokens.created_at'
|
||||
defaultMessage='Created on {date}'
|
||||
values={{
|
||||
date: (
|
||||
<FormattedDate
|
||||
value={token.created_at}
|
||||
hour12
|
||||
year='numeric'
|
||||
month='short'
|
||||
day='2-digit'
|
||||
hour='numeric'
|
||||
minute='2-digit'
|
||||
/>
|
||||
</a>
|
||||
)}
|
||||
</HStack>
|
||||
</Text>
|
||||
{token.scopes?.length > 0 && (
|
||||
<HStack space={2} alignItems='center' wrap>
|
||||
<Text size='sm' theme='muted'>
|
||||
<FormattedMessage id='security.tokens.scopes' defaultMessage='Scopes:' />
|
||||
</Text>
|
||||
{token.scopes.map((scope) => (
|
||||
<Badge title={scope} slug='opaque' key={scope} />
|
||||
))}
|
||||
</HStack>
|
||||
)}
|
||||
{token.created_at && (
|
||||
<Text size='sm' theme='muted'>
|
||||
<FormattedMessage
|
||||
id='security.tokens.created_at'
|
||||
defaultMessage='Created on {date}'
|
||||
values={{
|
||||
date: (
|
||||
<FormattedDate
|
||||
value={token.created_at}
|
||||
hour12
|
||||
year='numeric'
|
||||
month='short'
|
||||
day='2-digit'
|
||||
hour='numeric'
|
||||
minute='2-digit'
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Text>
|
||||
)}
|
||||
{token.last_used && (
|
||||
<Text size='sm' theme='muted'>
|
||||
<FormattedMessage
|
||||
id='security.tokens.last_used'
|
||||
defaultMessage='Last used on {date}'
|
||||
values={{
|
||||
date: (
|
||||
<FormattedDate
|
||||
value={token.last_used}
|
||||
hour12
|
||||
year='numeric'
|
||||
month='short'
|
||||
day='2-digit'
|
||||
hour='numeric'
|
||||
minute='2-digit'
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Text>
|
||||
)}
|
||||
{token.valid_until && (
|
||||
<Text size='sm' theme='muted'>
|
||||
<FormattedMessage
|
||||
id='security.tokens.valid_until'
|
||||
defaultMessage='Expires on {date}'
|
||||
values={{
|
||||
date: (
|
||||
<FormattedDate
|
||||
value={token.valid_until}
|
||||
hour12
|
||||
year='numeric'
|
||||
month='short'
|
||||
day='2-digit'
|
||||
hour='numeric'
|
||||
minute='2-digit'
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Text>
|
||||
)}
|
||||
</Stack>
|
||||
<HStack justifyContent='end'>
|
||||
<Button theme={isCurrent ? 'danger' : 'primary'} onClick={handleRevoke}>
|
||||
{intl.formatMessage(messages.revoke)}
|
||||
</Button>
|
||||
</HStack>
|
||||
</Stack>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
)}
|
||||
{token.last_used && (
|
||||
<p className='⁂-token__detail'>
|
||||
<FormattedMessage
|
||||
id='security.tokens.last_used'
|
||||
defaultMessage='Last used on {date}'
|
||||
values={{
|
||||
date: (
|
||||
<FormattedDate
|
||||
value={token.last_used}
|
||||
hour12
|
||||
year='numeric'
|
||||
month='short'
|
||||
day='2-digit'
|
||||
hour='numeric'
|
||||
minute='2-digit'
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
)}
|
||||
{token.valid_until && (
|
||||
<p className='⁂-token__detail'>
|
||||
<FormattedMessage
|
||||
id='security.tokens.valid_until'
|
||||
defaultMessage='Expires on {date}'
|
||||
values={{
|
||||
date: (
|
||||
<FormattedDate
|
||||
value={token.valid_until}
|
||||
hour12
|
||||
year='numeric'
|
||||
month='short'
|
||||
day='2-digit'
|
||||
hour='numeric'
|
||||
minute='2-digit'
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className={clsx('⁂-token__actions')}>
|
||||
<button onClick={handleRevoke}>{intl.formatMessage(messages.revoke)}</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -176,7 +164,7 @@ const AuthTokenListPage: React.FC = () => {
|
||||
});
|
||||
|
||||
const body = tokens ? (
|
||||
<div className='grid grid-cols-1 gap-4 sm:grid-cols-2'>
|
||||
<div className='⁂-tokens'>
|
||||
{tokens.map((token) => (
|
||||
<AuthToken
|
||||
key={token.id}
|
||||
|
||||
@ -13,3 +13,4 @@
|
||||
@use 'chats';
|
||||
@use 'events';
|
||||
@use 'directory';
|
||||
@use 'settings';
|
||||
|
||||
46
packages/nicolium/src/styles/new/settings.scss
Normal file
46
packages/nicolium/src/styles/new/settings.scss
Normal file
@ -0,0 +1,46 @@
|
||||
@use 'mixins';
|
||||
|
||||
.⁂-tokens {
|
||||
@apply grid grid-cols-1 gap-4 sm:grid-cols-2;
|
||||
}
|
||||
|
||||
.⁂-token {
|
||||
@apply rounded-lg bg-gray-100 p-4 dark:bg-primary-800 flex flex-col gap-2 h-full justify-between;
|
||||
|
||||
&__content {
|
||||
@apply flex flex-col gap-1;
|
||||
}
|
||||
|
||||
&__name {
|
||||
@apply flex gap-1 items-center;
|
||||
@include mixins.text($size: md, $weight: medium);
|
||||
|
||||
svg {
|
||||
@apply inline size-4 text-inherit;
|
||||
}
|
||||
}
|
||||
|
||||
&__tokens {
|
||||
@apply flex gap-2 items-center flex-wrap;
|
||||
|
||||
p {
|
||||
@include mixins.text($size: sm, $theme: muted);
|
||||
}
|
||||
}
|
||||
|
||||
&__detail {
|
||||
@include mixins.text($size: sm, $theme: muted);
|
||||
}
|
||||
|
||||
&__actions {
|
||||
@apply flex justify-end;
|
||||
|
||||
button {
|
||||
@include mixins.button($theme: primary);
|
||||
}
|
||||
}
|
||||
|
||||
&--current button {
|
||||
@apply border-transparent bg-danger-100 dark:bg-danger-900 text-danger-600 dark:text-danger-200 hover:bg-danger-600 hover:text-gray-100 dark:hover:text-gray-100 dark:hover:bg-danger-500 focus:ring-danger-500;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user