('');
+ const [, setSearch] = useSearchParams();
const service = useContext(AFConfigContext)?.service;
const handleSubmit = async () => {
+ if (loading) return;
const isValidEmail = isEmail(email);
if (!isValidEmail) {
@@ -20,29 +24,47 @@ function MagicLink ({ redirectTo }: { redirectTo: string }) {
return;
}
+ setError('');
setLoading(true);
- try {
- void service?.signInMagicLink({
- email,
- redirectTo,
- });
+ void (async () => {
+ try {
+ await service?.signInMagicLink({
+ email,
+ redirectTo,
+ });
+ // eslint-disable-next-line
+ } catch (e: any) {
+ if (e.code === 429 || e.response?.status === 429) {
+ toast.error(t('tooManyRequests'));
+ } else {
+ toast.error(e.message);
+ }
+ } finally {
+ setLoading(false);
+ }
+ })();
+
+ setSearch(prev => {
+ prev.set('email', email);
+ prev.set('action', 'checkEmail');
+ return prev;
+ });
- window.location.href = `/login?action=checkEmail&email=${email}&redirectTo=${redirectTo}`;
- } catch (e) {
- toast.error(t('web.signInError'));
- } finally {
- setLoading(false);
- }
};
return (
setEmail(e.target.value)}
+ onChange={(e) => {
+ setError('');
+ setEmail(e.target.value);
+ }}
value={email}
placeholder={t('signIn.pleaseInputYourEmail')}
onKeyDown={e => {
@@ -56,8 +78,9 @@ function MagicLink ({ redirectTo }: { redirectTo: string }) {
onClick={handleSubmit}
size={'lg'}
className={'w-[320px]'}
+ loading={loading}
>
- {t('signIn.signInWithEmail')}
+ {loading ? t('loading') : t('signIn.signInWithEmail')}
);
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx
index 6bcb3d5d..8fef04fc 100644
--- a/src/components/ui/button.tsx
+++ b/src/components/ui/button.tsx
@@ -1,3 +1,4 @@
+import { Progress } from '@/components/ui/progress';
import * as React from 'react';
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
@@ -20,6 +21,7 @@ const buttonVariants = cva(
ghost:
'hover:bg-fill-primary-alpha-5 text-text-primary disabled:bg-fill-transparent disabled:text-text-tertiary',
link: 'hover:bg-transparent text-text-theme hover:text-text-theme-hover !h-fit',
+ loading: 'opacity-50 cursor-not-allowed',
},
size: {
sm: 'h-7 text-sm px-4 rounded-300 gap-2 font-normal',
@@ -29,22 +31,29 @@ const buttonVariants = cva(
icon: 'size-7 p-1 text-icon-primary disabled:text-icon-tertiary',
'icon-lg': 'size-10 p-[10px] text-icon-primary disabled:text-icon-tertiary',
},
+ loading: {
+ true: 'opacity-70 cursor-not-allowed hover:bg-fill-theme-thick',
+ false: '',
+ },
},
defaultVariants: {
variant: 'default',
size: 'default',
+ loading: false,
},
},
);
const Button = React.forwardRef &
VariantProps & {
- asChild?: boolean
+ asChild?: boolean;
}>(({
className,
variant,
size,
+ loading,
asChild = false,
+ children,
...props
}, ref) => {
const Comp = asChild ? Slot : 'button';
@@ -53,9 +62,22 @@ const Button = React.forwardRef {
+ if (loading) return;
+ if (props.onClick) {
+ props.onClick(e);
+ }
+ }}
{...props}
- />
+ >
+ {loading && (
+ // eslint-disable-next-line
+ // @ts-ignore
+
+ )}
+ {children}
+
);
});
diff --git a/src/components/ui/progress.tsx b/src/components/ui/progress.tsx
index 57e8b52c..bb88b4a0 100644
--- a/src/components/ui/progress.tsx
+++ b/src/components/ui/progress.tsx
@@ -6,12 +6,6 @@ const progressVariants = cva(
'relative block',
{
variants: {
- size: {
- sm: 'h-4 w-4',
- md: 'h-6 w-6',
- lg: 'h-8 w-8',
- xl: 'h-10 w-10',
- },
variant: {
default: '',
success: '',
@@ -25,7 +19,6 @@ const progressVariants = cva(
},
},
defaultVariants: {
- size: 'md',
variant: 'default',
isIndeterminate: false,
},
@@ -33,7 +26,7 @@ const progressVariants = cva(
);
const circleVariants = cva(
- 'fill-fill-transparent ',
+ 'fill-fill-transparent h-5 w-5',
{
variants: {
variant: {
@@ -51,7 +44,7 @@ const circleVariants = cva(
);
const progressCircleVariants = cva(
- 'fill-fill-transparent transition-all',
+ 'fill-fill-transparent transition-all h-5 w-5',
{
variants: {
variant: {
@@ -79,22 +72,16 @@ export interface ProgressProps
export function Progress ({
value,
- size = 'md',
variant = 'default',
strokeLinecap = 'round',
className,
...props
}: ProgressProps) {
// Calculate dimensions based on size variant
- const dimensions: number = {
- sm: 16,
- md: 24,
- lg: 32,
- xl: 40,
- }[size as string] || 24;
+ const dimensions: number = 20;
+
+ const strokeWidth = 2.5;
- const strokeWidth = Math.ceil(dimensions * 0.125); // 12.5% of dimensions
-
const radius = dimensions / 2 - strokeWidth;
const circumference = Math.ceil(2 * Math.PI * radius);
const isIndeterminate = value === undefined;
@@ -111,7 +98,7 @@ export function Progress ({
return (