kyd-shared-badge 0.3.46 → 0.3.48
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
|
@@ -8,13 +8,13 @@ import EnterpriseCoaching from './components/EnterpriseCoaching';
|
|
|
8
8
|
import AppendixTables from './components/AppendixTables';
|
|
9
9
|
import BusinessRuleLink from './components/BusinessRuleLink';
|
|
10
10
|
import IpRiskAnalysisDisplay from './components/IpRiskAnalysisDisplay';
|
|
11
|
-
// import Image from 'next/image';
|
|
12
11
|
import GraphInsights from './components/GraphInsights';
|
|
13
12
|
import ConnectedPlatforms from './components/ConnectedPlatforms';
|
|
14
13
|
import { FaGithub, FaGitlab, FaStackOverflow, FaLinkedin, FaGoogle, FaKaggle } from 'react-icons/fa';
|
|
15
14
|
import { SiCredly, SiFiverr } from 'react-icons/si';
|
|
16
15
|
import GaugeCard from './components/GaugeCard';
|
|
17
16
|
import RiskCard from './components/RiskCard';
|
|
17
|
+
import Image from 'next/image';
|
|
18
18
|
|
|
19
19
|
import { yellow, green } from './colors';
|
|
20
20
|
import Skills from './components/Skills';
|
|
@@ -115,7 +115,7 @@ const SharedBadgeDisplay = ({ badgeData, chatProps, headless }: { badgeData: Pub
|
|
|
115
115
|
const tabs = useMemo(() => {
|
|
116
116
|
const arr = [
|
|
117
117
|
{ key: 'overview', label: 'Overview' },
|
|
118
|
-
|
|
118
|
+
{ key: 'role', label: 'Role Fit & Coaching' },
|
|
119
119
|
{ key: 'technical', label: 'KYD Technical' },
|
|
120
120
|
{ key: 'risk', label: 'KYD Risk' },
|
|
121
121
|
{ key: 'ai', label: 'KYD AI' },
|
|
@@ -133,7 +133,7 @@ const SharedBadgeDisplay = ({ badgeData, chatProps, headless }: { badgeData: Pub
|
|
|
133
133
|
const keys = new Set(tabs.map(t => t.key));
|
|
134
134
|
if (hash && keys.has(hash)) setActiveTab(hash);
|
|
135
135
|
// If the hash targets a skills appendix anchor, switch to Appendix
|
|
136
|
-
if (hash && (hash.startsWith('appendix-skills') || hash.includes('appendix-skills-cat-'))) {
|
|
136
|
+
if (hash && (hash.startsWith('appendix-skills') || hash.includes('appendix-skills-cat-') || hash.includes('appendix-connected'))) {
|
|
137
137
|
setActiveTab('appendix');
|
|
138
138
|
}
|
|
139
139
|
} catch {}
|
|
@@ -162,24 +162,41 @@ const SharedBadgeDisplay = ({ badgeData, chatProps, headless }: { badgeData: Pub
|
|
|
162
162
|
<div className={'sticky z-10'} style={{ top: computeStickyTop(), background: 'var(--background)', borderBottom: '1px solid var(--icon-button-secondary)' }}>
|
|
163
163
|
<div className={`${wrapperMaxWidth} mx-auto px-2 sm:px-0 overflow-x-auto`}>
|
|
164
164
|
<div className="flex gap-1 sm:gap-2">
|
|
165
|
-
{tabs.map(t =>
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
165
|
+
{tabs.map(t => {
|
|
166
|
+
// Determine if this tab should have an icon
|
|
167
|
+
let iconSrc: string | null = null;
|
|
168
|
+
if (t.key === 'ai') iconSrc = '/badge/ai.svg';
|
|
169
|
+
if (t.key === 'technical') iconSrc = '/badge/code.svg';
|
|
170
|
+
if (t.key === 'risk') iconSrc = '/badge/risk.svg';
|
|
171
|
+
return (
|
|
172
|
+
<button
|
|
173
|
+
key={t.key}
|
|
174
|
+
onClick={() => {
|
|
175
|
+
setActiveTab(t.key);
|
|
176
|
+
try { if (typeof window !== 'undefined') window.history.replaceState(null, '', `#${t.key}`); } catch {}
|
|
177
|
+
}}
|
|
178
|
+
className={`px-3 sm:px-4 py-2 text-sm rounded-t flex items-center gap-2 ${activeTab === t.key ? 'font-semibold' : ''}`}
|
|
179
|
+
style={{
|
|
180
|
+
color: 'var(--text-main)',
|
|
181
|
+
background: activeTab === t.key ? 'var(--content-card-background)' : 'transparent',
|
|
182
|
+
border: activeTab === t.key ? '1px solid var(--icon-button-secondary)' : '1px solid transparent',
|
|
183
|
+
borderBottomColor: 'transparent'
|
|
184
|
+
}}
|
|
185
|
+
>
|
|
186
|
+
{iconSrc && (
|
|
187
|
+
<Image
|
|
188
|
+
src={iconSrc}
|
|
189
|
+
alt=""
|
|
190
|
+
width={18}
|
|
191
|
+
height={18}
|
|
192
|
+
className="text-[var(--text-main)]"
|
|
193
|
+
style={{ display: 'inline-block', verticalAlign: 'middle', color: 'var(--text-main)' }}
|
|
194
|
+
/>
|
|
195
|
+
)}
|
|
196
|
+
{t.label}
|
|
197
|
+
</button>
|
|
198
|
+
);
|
|
199
|
+
})}
|
|
183
200
|
</div>
|
|
184
201
|
</div>
|
|
185
202
|
</div>
|
|
@@ -219,8 +236,9 @@ const SharedBadgeDisplay = ({ badgeData, chatProps, headless }: { badgeData: Pub
|
|
|
219
236
|
const RoleFitSection = () => {
|
|
220
237
|
// Local state for expanding long role descriptions
|
|
221
238
|
const [showFullRoleDescription, setShowFullRoleDescription] = useState(false);
|
|
239
|
+
const rec = assessmentResult?.recommendations;
|
|
222
240
|
|
|
223
|
-
return
|
|
241
|
+
return (
|
|
224
242
|
<div className={`${wrapperMaxWidth} mx-auto`}>
|
|
225
243
|
<div className={'rounded-xl shadow-xl p-6 sm:p-8 mt-6 border'} style={{ backgroundColor: 'var(--content-card-background)', borderColor: 'var(--icon-button-secondary)' }}>
|
|
226
244
|
<div className="space-y-10">
|
|
@@ -237,19 +255,8 @@ const SharedBadgeDisplay = ({ badgeData, chatProps, headless }: { badgeData: Pub
|
|
|
237
255
|
const isLong = primaryDescription.length > 500;
|
|
238
256
|
const visibleText = isLong && !showFullRoleDescription ? `${primaryDescription.slice(0, 500)}…` : primaryDescription;
|
|
239
257
|
return (
|
|
240
|
-
<div className=
|
|
241
|
-
<div className=
|
|
242
|
-
<div className={'text-base font-semibold'} style={{ color: 'var(--text-main)' }}>{roleName}</div>
|
|
243
|
-
<span>-</span>
|
|
244
|
-
<div
|
|
245
|
-
className={
|
|
246
|
-
`px-3 py-1 inline-block rounded-md font-semibold shadow-sm text-[var(--text-main)] border`
|
|
247
|
-
}
|
|
248
|
-
style={{ borderColor: matchLabelToColor(em.label) }}
|
|
249
|
-
>
|
|
250
|
-
{em.label}
|
|
251
|
-
</div>
|
|
252
|
-
</div>
|
|
258
|
+
<div className='mt-3' style={{ color: 'var(--text-secondary)' }}>
|
|
259
|
+
<div className={'text-base font-semibold'} style={{ color: 'var(--text-main)' }}>{roleName}</div>
|
|
253
260
|
{primaryDescription ? (
|
|
254
261
|
<div>
|
|
255
262
|
<span>{visibleText}</span>
|
|
@@ -265,6 +272,22 @@ const SharedBadgeDisplay = ({ badgeData, chatProps, headless }: { badgeData: Pub
|
|
|
265
272
|
)}
|
|
266
273
|
</div>
|
|
267
274
|
) : null}
|
|
275
|
+
|
|
276
|
+
{em.description ? (
|
|
277
|
+
<div>
|
|
278
|
+
<div className="flex items-center text-start gap-2 mt-3">
|
|
279
|
+
<div className={'text-base font-semibold'} style={{ color: 'var(--text-main)' }}>Alignment Description</div>
|
|
280
|
+
<span>-</span>
|
|
281
|
+
<div
|
|
282
|
+
className={`px-2 py-1 inline-block rounded-md font-semibold shadow-sm text-[var(--text-main)] border`}
|
|
283
|
+
style={{ borderColor: matchLabelToColor(em.label) }}
|
|
284
|
+
>
|
|
285
|
+
{em.label}
|
|
286
|
+
</div>
|
|
287
|
+
</div>
|
|
288
|
+
<div className={'text-sm'} style={{ color: 'var(--text-secondary)' }}>{em.description}</div>
|
|
289
|
+
</div>
|
|
290
|
+
) : null}
|
|
268
291
|
</div>
|
|
269
292
|
);
|
|
270
293
|
})()}
|
|
@@ -289,6 +312,25 @@ const SharedBadgeDisplay = ({ badgeData, chatProps, headless }: { badgeData: Pub
|
|
|
289
312
|
<UseCases useCases={assessmentResult?.enterprise_use_cases} headless={isHeadless} badgeId={badgeId} />
|
|
290
313
|
</div>
|
|
291
314
|
)}
|
|
315
|
+
<div>
|
|
316
|
+
<Reveal headless={isHeadless} as={'h4'} offsetY={8} className={'text-2xl font-semibold mb-3'} style={{ color: 'var(--text-main)' }}>Recommendations</Reveal>
|
|
317
|
+
<Reveal headless={isHeadless}>
|
|
318
|
+
<div className={'space-y-3'}>
|
|
319
|
+
{rec?.summary ? (
|
|
320
|
+
<div className={'text-sm'} style={{ color: 'var(--text-secondary)' }}>{rec.summary}</div>
|
|
321
|
+
) : null}
|
|
322
|
+
{Array.isArray(rec?.bullet_points) && (rec?.bullet_points?.length || 0) > 0 ? (
|
|
323
|
+
<ul className={'list-disc pl-5 text-sm'} style={{ color: 'var(--text-secondary)' }}>
|
|
324
|
+
{rec?.bullet_points?.map((bp, idx) => (
|
|
325
|
+
<li key={idx}>{bp}</li>
|
|
326
|
+
))}
|
|
327
|
+
</ul>
|
|
328
|
+
) : (!rec?.summary ? (
|
|
329
|
+
<div className={'text-sm'} style={{ color: 'var(--text-secondary)' }}>No recommendations available.</div>
|
|
330
|
+
) : null)}
|
|
331
|
+
</div>
|
|
332
|
+
</Reveal>
|
|
333
|
+
</div>
|
|
292
334
|
</div>
|
|
293
335
|
</div>
|
|
294
336
|
</div>
|
|
@@ -459,7 +501,7 @@ const SharedBadgeDisplay = ({ badgeData, chatProps, headless }: { badgeData: Pub
|
|
|
459
501
|
})()}
|
|
460
502
|
</div>
|
|
461
503
|
)}
|
|
462
|
-
<div>
|
|
504
|
+
<div id="appendix-connected">
|
|
463
505
|
<ConnectedPlatforms accounts={connected} authenticity={assessmentResult?.account_authenticity} />
|
|
464
506
|
</div>
|
|
465
507
|
</div>
|
|
@@ -492,7 +534,7 @@ const SharedBadgeDisplay = ({ badgeData, chatProps, headless }: { badgeData: Pub
|
|
|
492
534
|
</style>
|
|
493
535
|
{/* Long-form original layout retained for headless/print */}
|
|
494
536
|
{OverviewSection()}
|
|
495
|
-
|
|
537
|
+
<RoleFitSection />
|
|
496
538
|
{TechnicalSection()}
|
|
497
539
|
{RiskSection()}
|
|
498
540
|
{AiSection()}
|
|
@@ -70,7 +70,7 @@ const ReportHeader = ({ badgeId, developerName, updatedAt, score = 0, badgeImage
|
|
|
70
70
|
<div className={'mb-4 rounded-md border p-3 flex items-start gap-2'} style={{ backgroundColor: 'var(--content-card-background)', borderColor: 'var(--icon-button-secondary)' }}>
|
|
71
71
|
<span className={'mt-0.5'} style={{ color: isCritical ? '#B00020' : '#9f580a' }}><FiAlertTriangle size={18} /></span>
|
|
72
72
|
<div className={'text-sm'}>
|
|
73
|
-
<div className={'font-semibold'} style={{ color: 'var(--text-main)' }}>
|
|
73
|
+
<div className={'font-semibold'} style={{ color: 'var(--text-main)' }}>{isCritical ? 'Warning' : 'Attention'}</div>
|
|
74
74
|
<div className={'mt-1'} style={{ color: 'var(--text-secondary)' }}>{accountAuthenticity?.description || (isCritical ? 'We detected signals that some linked accounts may be inauthentic. Review sources below.' : 'Some inconsistencies were observed across linked accounts. Review sources below.')}</div>
|
|
75
75
|
<div className={'mt-2'}>
|
|
76
76
|
<a href="#appendix-connected" className={'text-xs font-medium underline underline-offset-2'} style={{ color: 'var(--text-secondary)' }}>See more</a>
|
|
@@ -35,7 +35,7 @@ export default function UseCases({ useCases, headless, badgeId }: { useCases?: E
|
|
|
35
35
|
return (
|
|
36
36
|
<Reveal headless={!!headless}>
|
|
37
37
|
<div className={'pt-8 kyd-avoid-break'}>
|
|
38
|
-
<h3 className={'text-2xl font-semibold mb-3'} style={{ color: 'var(--text-main)' }}>
|
|
38
|
+
<h3 className={'text-2xl font-semibold mb-3'} style={{ color: 'var(--text-main)' }}>Project Capabilities</h3>
|
|
39
39
|
<div className={'grid grid-cols-1 md:grid-cols-2 gap-4'}>
|
|
40
40
|
{items.map((uc, idx) => {
|
|
41
41
|
const imgIndex = getUniqueIndex(idx);
|