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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kyd-shared-badge",
3
- "version": "0.3.74",
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 sm:mb-1 mb-4 text-[var(--text-secondary)] hover:text-[var(--text-main)] transition-colors">
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
  <>
@@ -36,6 +36,9 @@ export interface ConnectAccountsProps {
36
36
  handleBackButton?: () => void;
37
37
  headerTitle: string;
38
38
  headerDescription: string;
39
+ isDisconnecting?: string | null;
40
+ requiredProviders?: string[];
41
+ companyName?: string;
39
42
  }
40
43
 
41
44
 
package/src/ui/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './button';
2
2
  export * from './card';
3
3
  export * from './input';
4
- export * from './spinner';
4
+ export * from './spinner';
5
+ export * from './tooltip';
@@ -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 }