-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathAuthActionButton.tsx
More file actions
100 lines (91 loc) · 2.75 KB
/
AuthActionButton.tsx
File metadata and controls
100 lines (91 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import type { IPublicClientApplication } from '@azure/msal-browser';
import type { LucideIcon } from 'lucide-react';
import { Loader2 } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import { getUserAccessToken, initMsalClient } from '../authConfig.ts';
import ErrorPopup, { useErrorPopup } from './ErrorPopup.tsx';
export type ShowErrorFunction = (
code: string | number,
message: string
) => void;
interface AuthActionButtonProps {
icon: LucideIcon;
defaultText: string;
workingText: string;
onAction: (
accessToken: string,
showError: ShowErrorFunction
) => Promise<void>;
returnPath?: string;
buttonClassName?: string;
bgColorClass?: string;
textColorClass?: string;
class?: string;
}
export default function AuthActionButton({
icon: Icon,
defaultText,
workingText,
onAction,
returnPath,
buttonClassName,
bgColorClass = 'bg-tangerine-600 hover:bg-tangerine-700',
textColorClass = 'text-white',
class: className,
}: AuthActionButtonProps) {
const { error, showError, clearError } = useErrorPopup();
const [isWorking, setIsWorking] = useState(false);
const [pca, setPca] = useState<IPublicClientApplication>();
const autoTriggered = useRef(false);
useEffect(() => {
initMsalClient().then(setPca).catch(console.error);
}, []);
useEffect(() => {
if (!pca || autoTriggered.current) return;
const params = new URLSearchParams(window.location.search);
if (!params.has('authButtonClick')) return;
autoTriggered.current = true;
params.delete('authButtonClick');
const qs = params.toString();
const newUrl = window.location.pathname + (qs ? `?${qs}` : '');
window.history.replaceState({}, '', newUrl);
handleClick();
}, [pca]);
const handleClick = async () => {
if (!pca) {
return;
}
setIsWorking(true);
try {
const accessToken = await getUserAccessToken(pca, returnPath);
await onAction(accessToken, showError);
} finally {
setIsWorking(false);
}
};
return (
<div className={`text-center ${className || ''}`}>
<ErrorPopup error={error} onClose={clearError} />
<button
onClick={handleClick}
disabled={isWorking}
className={
buttonClassName ??
`inline-flex w-full items-center justify-center gap-2 rounded-lg ${bgColorClass} px-8 py-4 text-lg font-bold ${textColorClass} shadow-lg transition-all hover:shadow-xl disabled:cursor-not-allowed disabled:opacity-50`
}
>
{isWorking ? (
<>
<Loader2 className="h-5 w-5 animate-spin" />
{workingText}
</>
) : (
<>
<Icon className="h-5 w-5" />
{defaultText}
</>
)}
</button>
</div>
);
}