kyd-shared-badge 0.3.123 → 0.3.125

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.123",
3
+ "version": "0.3.125",
4
4
  "private": false,
5
5
  "main": "./src/index.ts",
6
6
  "module": "./src/index.ts",
@@ -3,7 +3,7 @@ import { useRouter } from 'next/navigation';
3
3
  import { ProviderIcon } from '../utils/provider';
4
4
  import { normalizeLinkedInInput } from './linkedin';
5
5
  import type { ConnectAccountsProps } from './types';
6
- import { CheckCircle, Link2, LinkIcon, Unlink, ArrowLeft, ExternalLink, Eye, Lock, InfoIcon } from 'lucide-react';
6
+ import { CheckCircle, Link2, LinkIcon, Unlink, ArrowLeft, ExternalLink, Eye, Lock, InfoIcon, EyeClosed, EyeOffIcon } from 'lucide-react';
7
7
  import { AnimatePresence, motion, useReducedMotion } from 'framer-motion';
8
8
  import { Button, Input, Spinner, Card, CardHeader, CardContent, CardTitle, ConnectProgress } from '../ui';
9
9
  import Link from 'next/link';
@@ -424,15 +424,24 @@ export function ConnectAccounts(props: ConnectAccountsProps) {
424
424
  </Button>
425
425
  </motion.div>
426
426
  <motion.div whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }}>
427
- <Button
428
- className="w-full sm:w-auto bg-[var(--icon-accent)] text-white transition-colors font-semibold"
429
- onClick={onGithubAppInstall}
430
- >
431
- <span className="flex items-center justify-center">
432
- <ExternalLink className="w-4 h-4 mr-2" />
433
- Yes, connect my private repos
434
- </span>
435
- </Button>
427
+ <TooltipProvider>
428
+ <Tooltip>
429
+ <TooltipTrigger asChild>
430
+ <Button
431
+ className="w-full sm:w-auto bg-[var(--icon-accent)] text-white transition-colors font-semibold"
432
+ onClick={onGithubAppInstall}
433
+ >
434
+ <span className="flex items-center justify-center">
435
+ <ExternalLink className="w-4 h-4 mr-2" />
436
+ Yes, connect my private repos
437
+ </span>
438
+ </Button>
439
+ </TooltipTrigger>
440
+ <TooltipContent>
441
+ <p>Connect your private repositories</p>
442
+ </TooltipContent>
443
+ </Tooltip>
444
+ </TooltipProvider>
436
445
  </motion.div>
437
446
  </div>
438
447
  </motion.div>
@@ -530,15 +539,24 @@ export function ConnectAccounts(props: ConnectAccountsProps) {
530
539
  </div>
531
540
  ) : (
532
541
  <motion.div whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }}>
533
- <Button
534
- onClick={() => setSelectedProviderIdAndCallback('github')}
535
- onMouseEnter={() => setPreview('github', 'connect')}
536
- onMouseLeave={clearPreview}
537
- className="bg-[var(--icon-button-secondary)] text-[var(--text-main)] hover:bg-[var(--icon-accent)] hover:text-white border-0 sm:px-4 px-3 py-1 sm:py-2 rounded-lg flex items-center gap-2"
538
- >
539
- <Eye className="size-3 sm:size-4" />
540
- <span className="sm:text-base text-sm">Connect</span>
541
- </Button>
542
+ <TooltipProvider>
543
+ <Tooltip>
544
+ <TooltipTrigger asChild>
545
+ <Button
546
+ onClick={() => setSelectedProviderIdAndCallback('github')}
547
+ onMouseEnter={() => setPreview('github', 'connect')}
548
+ onMouseLeave={clearPreview}
549
+ className="bg-[var(--icon-button-secondary)] text-[var(--text-main)] hover:bg-[var(--icon-accent)] hover:text-white border-0 sm:px-4 px-3 py-1 sm:py-2 rounded-lg flex items-center gap-2"
550
+ >
551
+ <Eye className="size-3 sm:size-4" />
552
+ <span className="sm:text-base text-sm">Connect</span>
553
+ </Button>
554
+ </TooltipTrigger>
555
+ <TooltipContent>
556
+ <p>Connect your public repositories</p>
557
+ </TooltipContent>
558
+ </Tooltip>
559
+ </TooltipProvider>
542
560
  </motion.div>
543
561
  )}
544
562
 
@@ -561,15 +579,24 @@ export function ConnectAccounts(props: ConnectAccountsProps) {
561
579
  </div>
562
580
  ) : (
563
581
  <motion.div whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }}>
564
- <Button
565
- onClick={() => setSelectedProviderIdAndCallback('githubapp')}
566
- onMouseEnter={() => setPreview('githubapp', 'connect')}
567
- onMouseLeave={clearPreview}
568
- className="bg-[var(--icon-button-secondary)] text-[var(--text-main)] hover:bg-[var(--icon-accent)] hover:text-white border-0 sm:px-4 px-3 py-1 sm:py-2 rounded-lg flex items-center gap-2"
569
- >
570
- <Lock className="size-3 sm:size-4" />
571
- <span className="sm:text-base text-sm">Connect</span>
572
- </Button>
582
+ <TooltipProvider>
583
+ <Tooltip>
584
+ <TooltipTrigger asChild>
585
+ <Button
586
+ onClick={() => setSelectedProviderIdAndCallback('githubapp')}
587
+ onMouseEnter={() => setPreview('githubapp', 'connect')}
588
+ onMouseLeave={clearPreview}
589
+ className="bg-[var(--icon-button-secondary)] text-[var(--text-main)] hover:bg-[var(--icon-accent)] hover:text-white border-0 sm:px-4 px-3 py-1 sm:py-2 rounded-lg flex items-center gap-2"
590
+ >
591
+ <EyeOffIcon className="size-3 sm:size-4" />
592
+ <span className="sm:text-base text-sm">Connect</span>
593
+ </Button>
594
+ </TooltipTrigger>
595
+ <TooltipContent>
596
+ <p>Connect your private repositories</p>
597
+ </TooltipContent>
598
+ </Tooltip>
599
+ </TooltipProvider>
573
600
  </motion.div>
574
601
  )}
575
602
  </div>
@@ -58,29 +58,7 @@ export function ConnectProgress(props: ConnectProgressProps) {
58
58
  if (previewAction === 'connect' && !has) next.add(pid)
59
59
  if (previewAction === 'disconnect' && has) next.delete(pid)
60
60
  const val = computePercent(next)
61
- if (process.env.NODE_ENV !== 'production') {
62
- try {
63
- // Debug details for preview behavior
64
- const beforePercent = progressPercent
65
- const beforeOthers = (() => {
66
- let c = 0; normalizedIds.forEach(id => { if (id !== 'github' && id !== 'githubapp' && id !== 'linkedin') c += 1 })
67
- return c
68
- })()
69
- let afterOthers = 0; next.forEach(id => { if (id !== 'github' && id !== 'githubapp' && id !== 'linkedin') afterOthers += 1 })
70
- // eslint-disable-next-line no-console
71
- console.log('[ConnectProgress] preview', {
72
- pid,
73
- previewAction,
74
- hasBefore: normalizedIds.has(pid),
75
- beforePercent,
76
- afterPercent: val,
77
- beforeOthers,
78
- afterOthers,
79
- normalizedIds: Array.from(normalizedIds),
80
- nextIds: Array.from(next),
81
- })
82
- } catch {}
83
- }
61
+
84
62
  return val === progressPercent ? null : val
85
63
  }, [previewProviderId, previewAction, normalizedIds, progressPercent])
86
64
 
@@ -147,6 +125,10 @@ export function ConnectProgress(props: ConnectProgressProps) {
147
125
 
148
126
  const isPreviewing = previewPercent !== null && previewPercent !== undefined
149
127
  const valueToShow = previewPercent ?? progressPercent
128
+ const centerIndicator = useMemo(() => {
129
+ if (previewPercent == null) return null as 'up' | 'down' | null
130
+ return previewPercent > progressPercent ? 'up' : previewPercent < progressPercent ? 'down' : null
131
+ }, [previewPercent, progressPercent])
150
132
 
151
133
  const content = (
152
134
  <Card className={`border-[var(--icon-button-secondary)] ${className || ''}`} style={{ backgroundColor: 'var(--content-card-background)'}}>
@@ -159,9 +141,11 @@ export function ConnectProgress(props: ConnectProgressProps) {
159
141
  highlightFrom={isPreviewing ? undefined : selectedPulse.from}
160
142
  highlightTo={isPreviewing ? undefined : selectedPulse.to}
161
143
  highlightPulse={Boolean(selectedPulse.to) && !isPreviewing}
144
+ centerIndicator={centerIndicator}
145
+ indicatorPulse={Boolean(centerIndicator)}
162
146
  />
163
147
  <div className="min-w-0 max-w-xs flex flex-col gap-2 items-start justify-start">
164
- <div className="text-base font-semibold truncate text-[var(--text-main)]">{progressCopy.headline}</div>
148
+ <div className="text-base font-semibold truncate text-[var(--text-main)]">Profile Depth: {progressCopy.headline}</div>
165
149
  <div className="text-sm text-[var(--text-secondary)]">
166
150
  {progressCopy.body}
167
151
  </div>
@@ -1,6 +1,7 @@
1
1
  'use client'
2
2
  import React from 'react'
3
- import { scoreToCssVar } from '../colors'
3
+ import { scoreToCssVar, red as redHex, green as greenHex } from '../colors'
4
+ import { ArrowUpIcon } from 'lucide-react'
4
5
 
5
6
  export type ProgressCircleProps = {
6
7
  value: number
@@ -13,10 +14,13 @@ export type ProgressCircleProps = {
13
14
  highlightFrom?: number
14
15
  highlightTo?: number
15
16
  highlightPulse?: boolean
17
+ // Optional center indicator arrow: 'up' (green) or 'down' (red)
18
+ centerIndicator?: 'up' | 'down' | null
19
+ indicatorPulse?: boolean
16
20
  }
17
21
 
18
22
  export function ProgressCircle(props: ProgressCircleProps) {
19
- const { value, size = 72, thickness = 6, className, showLabel = true, label, highlightFrom, highlightTo, highlightPulse } = props
23
+ const { value, size = 72, thickness = 6, className, showLabel = true, label, highlightFrom, highlightTo, highlightPulse, centerIndicator, indicatorPulse } = props
20
24
 
21
25
  const rawId = React.useId()
22
26
  const gradientId = React.useMemo(() => `kyd-pc-${String(rawId).replace(/:/g, '')}` , [rawId])
@@ -33,6 +37,10 @@ export function ProgressCircle(props: ProgressCircleProps) {
33
37
  const highlightOffset = hasHighlight ? circumference * (1 - toClamped / 100) : 0
34
38
 
35
39
  const strokeColor = React.useMemo(() => scoreToCssVar(clamped), [clamped])
40
+ const indicatorColor = React.useMemo(() => {
41
+ if (!centerIndicator) return undefined
42
+ return centerIndicator === 'up' ? `var(--status-positive, ${greenHex})` : `var(--status-negative, ${redHex})`
43
+ }, [centerIndicator])
36
44
 
37
45
  return (
38
46
  <div className={`relative inline-flex items-center justify-center ${className || ''}`} style={{ width: size, height: size }}>
@@ -90,11 +98,15 @@ export function ProgressCircle(props: ProgressCircleProps) {
90
98
  stroke={strokeColor}
91
99
  strokeOpacity={0.15}
92
100
  strokeWidth={2}
93
- className="animate-pulse"
94
- style={{ transition: 'stroke 400ms ease, stroke-opacity 400ms ease' }}
101
+ // className="animate-pulse"
102
+ // style={{ transition: 'stroke 200ms ease, stroke-opacity 200ms ease' }}
95
103
  />
96
104
  </svg>
97
-
105
+ {centerIndicator ? (
106
+ <div className={`absolute inset-0 flex items-center justify-center`} aria-hidden>
107
+ <ArrowUpIcon className="w-4 h-4 text-[var(--icon-accent)]" />
108
+ </div>
109
+ ) : null}
98
110
  </div>
99
111
  )
100
112
  }