kyd-shared-badge 0.3.74 → 0.3.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/connect/ConnectAccounts.tsx +32 -2
- package/src/connect/types.ts +3 -0
- package/src/ui/index.ts +2 -1
- package/src/ui/tooltip.tsx +30 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kyd-shared-badge",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.76",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"module": "./src/index.ts",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"@chatscope/chat-ui-kit-react": "^2.1.1",
|
|
23
23
|
"@chatscope/chat-ui-kit-styles": "^1.4.0",
|
|
24
24
|
"@radix-ui/react-slot": "^1.2.3",
|
|
25
|
+
"@radix-ui/react-tooltip": "^1.2.8",
|
|
25
26
|
"ai": "5.0.47",
|
|
26
27
|
"class-variance-authority": "^0.7.1",
|
|
27
28
|
"framer-motion": "^12.23.24",
|
|
@@ -7,6 +7,7 @@ import { CheckCircle, Link2, LinkIcon, Unlink, ArrowLeft, ExternalLink } from 'l
|
|
|
7
7
|
import { AnimatePresence, motion } from 'framer-motion';
|
|
8
8
|
import { Button, Input, Spinner, Card, CardHeader, CardContent, CardFooter, CardTitle } from '../ui';
|
|
9
9
|
import Link from 'next/link';
|
|
10
|
+
import { Tooltip, TooltipTrigger, TooltipProvider, TooltipContent } from '../ui/';
|
|
10
11
|
|
|
11
12
|
function byPriority(a: string, b: string) {
|
|
12
13
|
const pr = (id: string) => (id === 'github' ? 0 : id === 'linkedin' ? 1 : 2);
|
|
@@ -35,12 +36,15 @@ export function ConnectAccounts(props: ConnectAccountsProps) {
|
|
|
35
36
|
handleBackButton,
|
|
36
37
|
headerTitle,
|
|
37
38
|
headerDescription,
|
|
39
|
+
requiredProviders,
|
|
40
|
+
companyName,
|
|
38
41
|
} = props;
|
|
39
42
|
|
|
40
43
|
const router = useRouter();
|
|
41
44
|
const [selectedProviderId, setSelectedProviderId] = useState<string | null>(null);
|
|
42
45
|
const [linkUrl, setLinkUrl] = useState('');
|
|
43
46
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
47
|
+
const [isDisconnecting, setIsDisconnecting] = useState<string | null>(null);
|
|
44
48
|
|
|
45
49
|
const apiBase = apiGatewayUrl || (typeof process !== 'undefined' ? (process.env.NEXT_PUBLIC_API_GATEWAY_URL as string) : '');
|
|
46
50
|
const connectedIds = useMemo(() => new Set((connected || []).map(c => c.id.toLowerCase())), [connected]);
|
|
@@ -78,6 +82,7 @@ export function ConnectAccounts(props: ConnectAccountsProps) {
|
|
|
78
82
|
};
|
|
79
83
|
|
|
80
84
|
const onDisconnect = async (providerId: string) => {
|
|
85
|
+
setIsDisconnecting(providerId);
|
|
81
86
|
try {
|
|
82
87
|
const res = await fetch(`${apiBase}/user/disconnect`, {
|
|
83
88
|
method: 'POST',
|
|
@@ -93,6 +98,8 @@ export function ConnectAccounts(props: ConnectAccountsProps) {
|
|
|
93
98
|
} catch (e) {
|
|
94
99
|
const err = e as Error;
|
|
95
100
|
if (onError) onError(err.message || 'Failed to disconnect');
|
|
101
|
+
} finally {
|
|
102
|
+
setIsDisconnecting(null);
|
|
96
103
|
}
|
|
97
104
|
};
|
|
98
105
|
|
|
@@ -254,7 +261,7 @@ export function ConnectAccounts(props: ConnectAccountsProps) {
|
|
|
254
261
|
<motion.div key="platform-list-shared" variants={cardVariants} initial="initial" animate="animate" exit="exit" transition={{ duration: 0.3 }}>
|
|
255
262
|
<CardHeader className="pb-4">
|
|
256
263
|
{handleBackButton && (
|
|
257
|
-
<button onClick={() => handleBackButton()} className="flex items-center gap-2 text-sm
|
|
264
|
+
<button onClick={() => handleBackButton()} className="flex items-center gap-2 text-sm mb-4 text-[var(--text-secondary)] hover:text-[var(--text-main)] transition-colors">
|
|
258
265
|
<ArrowLeft className="w-4 h-4" /> Back
|
|
259
266
|
</button>
|
|
260
267
|
)}
|
|
@@ -268,6 +275,7 @@ export function ConnectAccounts(props: ConnectAccountsProps) {
|
|
|
268
275
|
|
|
269
276
|
const Row = (provider: typeof list[number]) => {
|
|
270
277
|
const providerId = provider.id;
|
|
278
|
+
const isRequired = requiredProviders?.includes(providerId);
|
|
271
279
|
const isConnected = connectedIds.has(providerId.toLowerCase());
|
|
272
280
|
const needsReconnect = reconnectIds.has(providerId.toLowerCase());
|
|
273
281
|
const isOauth = provider.connectionType === 'oauth'
|
|
@@ -281,6 +289,21 @@ export function ConnectAccounts(props: ConnectAccountsProps) {
|
|
|
281
289
|
</span>
|
|
282
290
|
);
|
|
283
291
|
|
|
292
|
+
const requiredFlag = () => (
|
|
293
|
+
<TooltipProvider>
|
|
294
|
+
<Tooltip>
|
|
295
|
+
<TooltipTrigger>
|
|
296
|
+
<div className="flex items-center justify-center size-4 sm:size-5 rounded-full bg-[var(--icon-accent)] cursor-help">
|
|
297
|
+
<span className="text-white text-xs font-bold -translate-y-px select-none">!</span>
|
|
298
|
+
</div>
|
|
299
|
+
</TooltipTrigger>
|
|
300
|
+
<TooltipContent>
|
|
301
|
+
<p>Required by <span className="font-semibold">{companyName || 'your recruiter'}</span></p>
|
|
302
|
+
</TooltipContent>
|
|
303
|
+
</Tooltip>
|
|
304
|
+
</TooltipProvider>
|
|
305
|
+
);
|
|
306
|
+
|
|
284
307
|
return (
|
|
285
308
|
<div key={providerId} className="group flex items-center justify-between p-2 rounded-lg transition-colors hover:bg-[var(--icon-button-secondary)]/10 transform transition-transform hover:-translate-y-px">
|
|
286
309
|
<div className="flex items-center gap-3">
|
|
@@ -289,17 +312,19 @@ export function ConnectAccounts(props: ConnectAccountsProps) {
|
|
|
289
312
|
<Link href={connectedUrl} target="_blank" rel="noopener noreferrer" className="flex items-center gap-3 hover:underline">
|
|
290
313
|
<ProviderIcon name={provider.id} className={`sm:size-7 size-5 ${provider.iconColor || 'text-gray-500'}`} />
|
|
291
314
|
<span className="font-medium sm:text-base text-sm" style={{ color: 'var(--text-main)'}}>{provider.name}</span>
|
|
315
|
+
{isRequired && !isConnected ? (requiredFlag()) : null}
|
|
292
316
|
</Link>
|
|
293
317
|
) : (
|
|
294
318
|
<div className="flex items-center gap-3">
|
|
295
319
|
<ProviderIcon name={provider.id} className={`sm:size-7 size-5 ${provider.iconColor || 'text-gray-500'}`} />
|
|
296
320
|
<span className="font-medium sm:text-base text-sm" style={{ color: 'var(--text-main)'}}>{provider.name}</span>
|
|
321
|
+
{isRequired && !isConnected ? (requiredFlag()) : null}
|
|
297
322
|
</div>
|
|
298
323
|
)}
|
|
299
324
|
{provider.beta ? betaFlag() : null}
|
|
300
325
|
</div>
|
|
301
326
|
|
|
302
|
-
{isConnected ? (
|
|
327
|
+
{isConnected && isDisconnecting !== providerId ? (
|
|
303
328
|
<div className="relative flex items-center">
|
|
304
329
|
<div className="flex items-center gap-2 transition-opacity group-hover:opacity-0" style={{ color: 'var(--success-green)'}}>
|
|
305
330
|
<CheckCircle className="size-3 sm:size-4" />
|
|
@@ -315,6 +340,11 @@ export function ConnectAccounts(props: ConnectAccountsProps) {
|
|
|
315
340
|
</button>
|
|
316
341
|
</div>
|
|
317
342
|
</div>
|
|
343
|
+
|
|
344
|
+
) : isDisconnecting === providerId ? (
|
|
345
|
+
<div className="relative flex items-center">
|
|
346
|
+
<Spinner />
|
|
347
|
+
</div>
|
|
318
348
|
) : (
|
|
319
349
|
<div className="flex items-center gap-2">
|
|
320
350
|
<>
|
package/src/connect/types.ts
CHANGED
package/src/ui/index.ts
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip"
|
|
5
|
+
|
|
6
|
+
import { cn } from "../utils"
|
|
7
|
+
|
|
8
|
+
const TooltipProvider = TooltipPrimitive.Provider
|
|
9
|
+
|
|
10
|
+
const Tooltip = TooltipPrimitive.Root
|
|
11
|
+
|
|
12
|
+
const TooltipTrigger = TooltipPrimitive.Trigger
|
|
13
|
+
|
|
14
|
+
const TooltipContent = React.forwardRef<
|
|
15
|
+
React.ElementRef<typeof TooltipPrimitive.Content>,
|
|
16
|
+
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
|
|
17
|
+
>(({ className, sideOffset = 4, ...props }, ref) => (
|
|
18
|
+
<TooltipPrimitive.Content
|
|
19
|
+
ref={ref}
|
|
20
|
+
sideOffset={sideOffset}
|
|
21
|
+
className={cn(
|
|
22
|
+
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
23
|
+
className
|
|
24
|
+
)}
|
|
25
|
+
{...props}
|
|
26
|
+
/>
|
|
27
|
+
))
|
|
28
|
+
TooltipContent.displayName = TooltipPrimitive.Content.displayName
|
|
29
|
+
|
|
30
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
|