Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

user management panel UI #406

Open
wants to merge 59 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
5bef324
progress
aehnh Jul 24, 2024
7661773
Merge branch 'develop' into user-management-panel
aehnh Jul 29, 2024
5c86637
modify fullname and username
aehnh Jul 29, 2024
6b14c3a
revert corbado/types
aehnh Jul 30, 2024
cf7b9a6
change types
aehnh Jul 30, 2024
d6ddc18
revert changes to corbado/types
aehnh Jul 30, 2024
93c3f95
update full name works
aehnh Jul 30, 2024
9450c86
udpate username works
aehnh Jul 30, 2024
30c63bd
email address component wip
aehnh Aug 5, 2024
901f6b7
progress
aehnh Aug 6, 2024
d5e8fcf
identifier list config needs to be debugged
aehnh Aug 6, 2024
9a40d61
incorporate identifier-list-config
aehnh Aug 12, 2024
bec747d
error handling
aehnh Aug 12, 2024
7be1634
phone
aehnh Aug 12, 2024
7781143
prettier
aehnh Aug 13, 2024
77971b3
add translations, add delete-user card
aehnh Aug 13, 2024
da33a84
prettier
aehnh Aug 13, 2024
9ddd6ed
change component name to userdetails
aehnh Aug 13, 2024
49634b9
adds name edit component
Dopeamin Aug 14, 2024
db96d73
Merge remote-tracking branch 'origin/develop' into user-management-panel
Dopeamin Aug 16, 2024
26a8259
refactors corbado user details logic into a context
Dopeamin Aug 16, 2024
9031db5
refactors UserDetails screen
Dopeamin Aug 16, 2024
0d37c34
fixes build issues
Dopeamin Aug 16, 2024
20736eb
fixes lint issues
Dopeamin Aug 16, 2024
1f867f4
fixes formatting issues
Dopeamin Aug 16, 2024
4eaf0ca
finish user deletion block
Dopeamin Aug 16, 2024
96f3071
finishes name edit block
Dopeamin Aug 16, 2024
d52409e
adds dropdown menu
Dopeamin Aug 16, 2024
171edb4
fixes lint and format issues
Dopeamin Aug 16, 2024
c8568d3
PR
aehnh Aug 19, 2024
b3e5c52
adds identifier deletion process
Dopeamin Aug 19, 2024
daea1bd
change endpoint name getIdentifierConfigList --> getUserDetailsList
aehnh Aug 19, 2024
fe1c1b2
remove unused code
aehnh Aug 19, 2024
74ebdd6
finishes otp dialogues
Dopeamin Aug 19, 2024
e12afd4
adds loading to OTP
Dopeamin Aug 19, 2024
df9ab33
fixes lint issues
Dopeamin Aug 19, 2024
1c4b403
fixes prettier issue
Dopeamin Aug 19, 2024
438e63c
fixes themes
Dopeamin Aug 19, 2024
3f00b84
adds error handling for username input
Dopeamin Aug 19, 2024
8f3e41a
Merge branch 'develop' into user-management-panel
aehnh Aug 20, 2024
11ef9d5
finishes error handling
Dopeamin Aug 21, 2024
eb92551
adds auto verification on adding new identifier
Dopeamin Aug 21, 2024
71b194e
submit on enter
Dopeamin Aug 21, 2024
1752753
fixes lint issues
Dopeamin Aug 21, 2024
5559588
adds missing dark variables
Dopeamin Aug 21, 2024
5045d10
resolves comments
Dopeamin Aug 22, 2024
cd5bd45
adds copy button effect
Dopeamin Aug 22, 2024
d1bce55
fixes text overflow in identifiers
Dopeamin Aug 22, 2024
6430923
fixes verification timeout
Dopeamin Aug 22, 2024
a939680
fixes lint issues
Dopeamin Aug 22, 2024
6641e26
adds loading states to buttons
Dopeamin Aug 22, 2024
56a575a
fixes lint issues
Dopeamin Aug 22, 2024
0af28af
adds fields validation
Dopeamin Aug 27, 2024
1077773
adds validation
Dopeamin Aug 27, 2024
0fd5182
fixes verification screen not closing
Dopeamin Aug 27, 2024
7fe2dec
mark primary emails with badges
aehnh Aug 27, 2024
08c7e30
phone primary
aehnh Aug 27, 2024
299eb72
fixes loading issue
Dopeamin Aug 28, 2024
85998ae
Merge remote-tracking branch 'origin/develop' into user-management-panel
Dopeamin Aug 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion packages/react/src/components/ui/buttons/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
ref={ref}
{...rest}
>
{isLoading ? <LoadingSpinner className={spinnerClassName} /> : children}
{children}
{isLoading && (
<div className='cb-button-loading'>
<LoadingSpinner className={spinnerClassName} />
</div>
)}
</button>
);
},
Expand Down
60 changes: 60 additions & 0 deletions packages/react/src/components/ui/buttons/CopyButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import type { FC } from 'react';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { CopyIcon } from '../icons/CopyIcon';
import { TickIcon } from '../icons/TickIcon';
import { Text } from '../typography';

interface Props {
text: string | undefined;
}

const RESET_TIMEOUT = 4 * 1000;

const CopyButton: FC<Props> = ({ text }) => {
const { t } = useTranslation();
const [copied, setCopied] = useState(false);

useEffect(() => {
const reset = () => {
setCopied(false);
};

if (copied) {
const timeout = setTimeout(reset, RESET_TIMEOUT);

return () => clearTimeout(timeout);
}

return;
}, [copied]);

const onClick = async () => {
if (text) {
await navigator.clipboard.writeText(text);
setCopied(true);
}
};

if (copied) {
return (
<div className='cb-tooltip-container'>
<TickIcon className='cb-user-details-body-row-icon' />
<div className='cb-tooltip'>
<Text level='1'>{t('user-details.copied')}</Text>
</div>
</div>
);
}

return (
<CopyIcon
className='cb-user-details-body-row-icon'
color='secondary'
onClick={() => void onClick()}
/>
);
};

export default CopyButton;
4 changes: 3 additions & 1 deletion packages/react/src/components/ui/buttons/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import React from 'react';
export interface LinkProps {
href: string;
className?: string;
onClick?: (e: React.MouseEvent<HTMLAnchorElement>) => void;
}

export const Link: FC<PropsWithChildren<LinkProps>> = ({ href, className, children }) => {
export const Link: FC<PropsWithChildren<LinkProps>> = ({ href, className, children, onClick }) => {
return (
<a
href={href}
onClick={onClick}
className={`cb-link cb-secondary-link ${className}`}
>
{children}
Expand Down
16 changes: 12 additions & 4 deletions packages/react/src/components/ui/icons/AddIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import addSrc from '@corbado/shared-ui/assets/add.svg';
import type { FC } from 'react';
import { memo, useRef } from 'react';
import { useRef } from 'react';
import React from 'react';

import { useIconWithTheme } from '../../../hooks/useIconWithTheme';
import type { IconProps } from './Icon';
import { Icon } from './Icon';

export const AddIcon: FC<IconProps> = memo(props => {
export interface AddIconProps extends IconProps {
color?: 'primary' | 'secondary';
}

export const AddIcon: FC<AddIconProps> = ({ color, ...props }) => {
const svgRef = useRef<HTMLImageElement>(null);
const { logoSVG } = useIconWithTheme(svgRef, addSrc, '--cb-button-text-primary-color');
const { logoSVG } = useIconWithTheme(
svgRef,
addSrc,
color === 'secondary' ? '--cb-text-primary-color' : '--cb-button-text-primary-color',
);

return (
<Icon
Expand All @@ -19,4 +27,4 @@ export const AddIcon: FC<IconProps> = memo(props => {
{...props}
/>
);
});
};
38 changes: 38 additions & 0 deletions packages/react/src/components/ui/icons/AlertIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import alertSrc from '@corbado/shared-ui/assets/alert.svg';
import type { FC } from 'react';
import { useRef } from 'react';
import React from 'react';

import { useIconWithTheme } from '../../../hooks/useIconWithTheme';
import type { IconProps } from './Icon';
import { Icon } from './Icon';

export interface AlertIconProps extends IconProps {
color?: 'primary' | 'secondary' | 'error';
}

export const AlertIcon: FC<AlertIconProps> = ({ color, ...props }) => {
const svgRef = useRef<HTMLImageElement>(null);

const getColor = () => {
switch (color) {
case 'secondary':
return '--cb-text-primary-color';
case 'error':
return '--cb-error-text-color';
default:
return '--cb-button-text-primary';
}
};

const { logoSVG } = useIconWithTheme(svgRef, alertSrc, getColor());

return (
<Icon
src={logoSVG}
ref={svgRef}
alt='alert'
{...props}
/>
);
};
30 changes: 30 additions & 0 deletions packages/react/src/components/ui/icons/ChangeIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import changeIconSrc from '@corbado/shared-ui/assets/change.svg';
import type { FC } from 'react';
import { useRef } from 'react';
import React from 'react';

import { useIconWithTheme } from '../../../hooks/useIconWithTheme';
import type { IconProps } from './Icon';
import { Icon } from './Icon';

export interface ChangeIconProps extends IconProps {
color?: 'primary' | 'secondary';
}

export const ChangeIcon: FC<ChangeIconProps> = ({ color, ...props }) => {
const svgRef = useRef<HTMLImageElement>(null);
const { logoSVG } = useIconWithTheme(
svgRef,
changeIconSrc,
color === 'secondary' ? '--cb-text-secondary-color' : '--cb-text-primary-color',
);

return (
<Icon
src={logoSVG}
ref={svgRef}
alt='copy-icon'
{...props}
/>
);
};
30 changes: 30 additions & 0 deletions packages/react/src/components/ui/icons/CopyIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import copyIconSrc from '@corbado/shared-ui/assets/copy.svg';
import type { FC } from 'react';
import { useRef } from 'react';
import React from 'react';

import { useIconWithTheme } from '../../../hooks/useIconWithTheme';
import type { IconProps } from './Icon';
import { Icon } from './Icon';

export interface CopyIconProps extends IconProps {
color?: 'primary' | 'secondary';
}

export const CopyIcon: FC<CopyIconProps> = ({ color, ...props }) => {
const svgRef = useRef<HTMLImageElement>(null);
const { logoSVG } = useIconWithTheme(
svgRef,
copyIconSrc,
color === 'secondary' ? '--cb-text-secondary-color' : '--cb-text-primary-color',
);

return (
<Icon
src={logoSVG}
ref={svgRef}
alt='copy-icon'
{...props}
/>
);
};
22 changes: 22 additions & 0 deletions packages/react/src/components/ui/icons/PendingIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import pendingIconSrc from '@corbado/shared-ui/assets/pending.svg';
import type { FC } from 'react';
import { memo, useRef } from 'react';
import React from 'react';

import { useIconWithTheme } from '../../../hooks/useIconWithTheme';
import type { IconProps } from './Icon';
import { Icon } from './Icon';

export const PendingIcon: FC<IconProps> = memo(props => {
const svgRef = useRef<HTMLImageElement>(null);
const { logoSVG } = useIconWithTheme(svgRef, pendingIconSrc, '--cb-passkey-list-badge-color');

return (
<Icon
src={logoSVG}
ref={svgRef}
alt='pending-icon'
{...props}
/>
);
});
22 changes: 22 additions & 0 deletions packages/react/src/components/ui/icons/PrimaryIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import primaryIconSrc from '@corbado/shared-ui/assets/primary.svg';
import type { FC } from 'react';
import { memo, useRef } from 'react';
import React from 'react';

import { useIconWithTheme } from '../../../hooks/useIconWithTheme';
import type { IconProps } from './Icon';
import { Icon } from './Icon';

export const PrimaryIcon: FC<IconProps> = memo(props => {
const svgRef = useRef<HTMLImageElement>(null);
const { logoSVG } = useIconWithTheme(svgRef, primaryIconSrc, '--cb-passkey-list-badge-color');

return (
<Icon
src={logoSVG}
ref={svgRef}
alt='primary-icon'
{...props}
/>
);
});
22 changes: 22 additions & 0 deletions packages/react/src/components/ui/icons/TickIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import syncIconSrc from '@corbado/shared-ui/assets/tick.svg';
import type { FC } from 'react';
import { memo, useRef } from 'react';
import React from 'react';

import { ColorType, useIconWithTheme } from '../../../hooks/useIconWithTheme';
import type { IconProps } from './Icon';
import { Icon } from './Icon';

export const TickIcon: FC<IconProps> = memo(props => {
const svgRef = useRef<HTMLImageElement>(null);
const { logoSVG } = useIconWithTheme(svgRef, syncIconSrc, '--cb-success-color', ColorType.Stroke);

return (
<Icon
src={logoSVG}
ref={svgRef}
alt='success-icon'
{...props}
/>
);
});
22 changes: 22 additions & 0 deletions packages/react/src/components/ui/icons/VerifiedIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import verifiedIconSrc from '@corbado/shared-ui/assets/verified.svg';
import type { FC } from 'react';
import { memo, useRef } from 'react';
import React from 'react';

import { useIconWithTheme } from '../../../hooks/useIconWithTheme';
import type { IconProps } from './Icon';
import { Icon } from './Icon';

export const VerifiedIcon: FC<IconProps> = memo(props => {
const svgRef = useRef<HTMLImageElement>(null);
const { logoSVG } = useIconWithTheme(svgRef, verifiedIconSrc, '--cb-passkey-list-badge-color');

return (
<Icon
src={logoSVG}
ref={svgRef}
alt='verified-icon'
{...props}
/>
);
});
24 changes: 24 additions & 0 deletions packages/react/src/components/user-details/Alert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { FC } from 'react';
import React from 'react';

import { Text } from '../ui';
import { AlertIcon } from '../ui/icons/AlertIcon';

interface Props {
text: string;
variant?: 'error' | 'info';
}

const Alert: FC<Props> = ({ text, variant = 'error' }) => {
return (
<div className='cb-user-details-alert-container'>
<AlertIcon
color={variant === 'error' ? 'error' : 'secondary'}
className='cb-user-details-alert-icon'
/>
<Text className={`cb-user-details-text${variant === 'error' ? ' cb-error-text-color' : ''}`}>{text}</Text>
</div>
);
};

export default Alert;
Loading
Loading