Skip to content

Commit 8cf2446

Browse files
Bhuvanesh SBhuvanesh S
authored andcommitted
feat: add AI Mentor & Career Growth Engine
Signed-off-by: Bhuvanesh S <YOUR_GITHUB_EMAIL>
1 parent 02320c0 commit 8cf2446

42 files changed

Lines changed: 6362 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script lang="ts">
2+
import InsightFeed from '$lib/components/InsightFeed.svelte';
3+
4+
let {
5+
insights = [
6+
{ type: 'positive', text: 'Peak engagement detected! You just connected with 5 senior engineers in the last hour.' },
7+
{ type: 'warning', text: 'Your event visibility is dropping. Scan 2 more QR codes to stay on the leaderboard.' },
8+
{ type: 'neutral', text: 'You have a 60% skill overlap with the current hackathon attendees.' }
9+
]
10+
} = $props<{
11+
insights?: { type: 'positive' | 'warning' | 'neutral', text: string }[];
12+
}>();
13+
</script>
14+
15+
<InsightFeed title="Engagement Intelligence" items={insights} variant="ai" />
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<script lang="ts">
2+
import InsightFeed from '$lib/components/InsightFeed.svelte';
3+
4+
let {
5+
predictions = [
6+
{ type: 'positive', text: 'You are highly compatible with <strong>DevCard API V2</strong> contributors based on your recent Fastify commits.' },
7+
{ type: 'neutral', text: 'Consider joining the <em>Open Source Saturday</em> meetup. 12 matching developers will be there.' },
8+
{ type: 'warning', text: 'Your backend skill overlap is high, but your profile lacks recent database contributions.' }
9+
]
10+
} = $props<{
11+
predictions?: { type: 'positive' | 'warning' | 'neutral', text: string }[];
12+
}>();
13+
</script>
14+
15+
<InsightFeed
16+
title="AI Collaborator Predictions"
17+
items={predictions}
18+
variant="ai"
19+
accentColor="#22c55e"
20+
/>
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<script lang="ts">
2+
let {
3+
badges = [
4+
{ id: 1, title: 'First PR', icon: 'M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5', locked: false, color: '#3b82f6' },
5+
{ id: 2, title: 'Hackathon Winner', icon: 'M12 15l-8.5-8.5 1.5-1.5L12 12l7-7 1.5 1.5L12 15z', locked: false, color: '#eab308' },
6+
{ id: 3, title: '100 Commits', icon: 'M22 11.08V12a10 10 0 1 1-5.93-9.14', locked: true, color: '#a8a29e' },
7+
{ id: 4, title: 'Diamond Tier', icon: 'M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z', locked: true, color: '#a8a29e' }
8+
]
9+
} = $props<{
10+
badges?: { id: number, title: string, icon: string, locked: boolean, color: string }[];
11+
}>();
12+
</script>
13+
14+
<div class="achievement-badges glass">
15+
<div class="header">
16+
<h3>Achievements</h3>
17+
</div>
18+
19+
<div class="badges-grid">
20+
{#each badges as badge}
21+
<div class="badge-item {badge.locked ? 'locked' : ''}">
22+
<div class="icon-container" style="color: {badge.color}">
23+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
24+
<path d={badge.icon} />
25+
</svg>
26+
</div>
27+
<span class="badge-title">{badge.title}</span>
28+
{#if badge.locked}
29+
<div class="lock-overlay">
30+
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2">
31+
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect>
32+
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
33+
</svg>
34+
</div>
35+
{/if}
36+
</div>
37+
{/each}
38+
</div>
39+
</div>
40+
41+
<style>
42+
.achievement-badges {
43+
padding: 1.5rem;
44+
border-radius: var(--radius-lg);
45+
display: flex;
46+
flex-direction: column;
47+
gap: 1.5rem;
48+
height: 100%;
49+
}
50+
51+
.header h3 {
52+
font-size: 1.125rem;
53+
color: var(--text-primary);
54+
margin: 0;
55+
}
56+
57+
.badges-grid {
58+
display: grid;
59+
grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
60+
gap: 1rem;
61+
flex: 1;
62+
}
63+
64+
.badge-item {
65+
display: flex;
66+
flex-direction: column;
67+
align-items: center;
68+
gap: 0.5rem;
69+
padding: 1rem 0.5rem;
70+
background: rgba(255, 255, 255, 0.02);
71+
border: 1px solid rgba(255, 255, 255, 0.05);
72+
border-radius: var(--radius);
73+
position: relative;
74+
transition: transform 0.2s;
75+
}
76+
77+
.badge-item:not(.locked):hover {
78+
transform: translateY(-4px);
79+
border-color: rgba(255, 255, 255, 0.1);
80+
}
81+
82+
.icon-container {
83+
width: 48px;
84+
height: 48px;
85+
display: flex;
86+
align-items: center;
87+
justify-content: center;
88+
background: rgba(255, 255, 255, 0.05);
89+
border-radius: 50%;
90+
padding: 0.75rem;
91+
}
92+
93+
.badge-title {
94+
font-size: 0.75rem;
95+
color: var(--text-secondary);
96+
text-align: center;
97+
font-weight: 500;
98+
}
99+
100+
.locked {
101+
opacity: 0.5;
102+
filter: grayscale(1);
103+
}
104+
105+
.lock-overlay {
106+
position: absolute;
107+
top: 5px;
108+
right: 5px;
109+
color: var(--text-muted);
110+
}
111+
</style>
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
<script lang="ts">
2+
import { onMount } from 'svelte';
3+
4+
// Generate some dummy data for the heatmap
5+
// 52 weeks * 7 days
6+
const weeks = 52;
7+
const daysPerWeek = 7;
8+
9+
let heatmapData = $state<{ intensity: number, date: Date }[][]>([]);
10+
11+
onMount(() => {
12+
const today = new Date();
13+
const generatedData = [];
14+
for (let w = 0; w < weeks; w++) {
15+
let weekData = [];
16+
for (let d = 0; d < daysPerWeek; d++) {
17+
const date = new Date(today);
18+
date.setDate(date.getDate() - ((weeks - 1 - w) * 7 + (6 - d)));
19+
const random = Math.random();
20+
let intensity = 0;
21+
if (random > 0.85) intensity = 4;
22+
else if (random > 0.7) intensity = 3;
23+
else if (random > 0.5) intensity = 2;
24+
else if (random > 0.3) intensity = 1;
25+
26+
weekData.push({ intensity, date });
27+
}
28+
generatedData.push(weekData);
29+
}
30+
heatmapData = generatedData;
31+
});
32+
33+
function getIntensityColor(intensity: number): string {
34+
switch(intensity) {
35+
case 1: return 'var(--color-level-1)';
36+
case 2: return 'var(--color-level-2)';
37+
case 3: return 'var(--color-level-3)';
38+
case 4: return 'var(--color-level-4)';
39+
default: return 'var(--color-level-0)';
40+
}
41+
}
42+
</script>
43+
44+
<div class="heatmap-container glass">
45+
<div class="heatmap-header">
46+
<h3>Realtime Contributor Activity</h3>
47+
<span class="pulse-indicator">
48+
<span class="pulse-dot"></span> Live
49+
</span>
50+
</div>
51+
52+
<div class="heatmap-scroll-wrapper">
53+
<div class="heatmap-grid">
54+
{#each heatmapData as week, wIndex}
55+
<div class="week">
56+
{#each week as day, dIndex}
57+
<div
58+
class="day"
59+
role="button"
60+
aria-label="Contribution activity on {day.date.toDateString()}"
61+
tabindex="0"
62+
style="background-color: {getIntensityColor(day.intensity)};"
63+
title="{day.date.toDateString()}: {day.intensity * 3} contributions"
64+
></div>
65+
{/each}
66+
</div>
67+
{/each}
68+
</div>
69+
</div>
70+
71+
<div class="heatmap-legend">
72+
<span class="legend-text">Less</span>
73+
<div class="day" role="button" aria-label="Contribution activity" style="background-color: var(--color-level-0);"></div>
74+
<div class="day" role="button" aria-label="Contribution activity" style="background-color: var(--color-level-1);"></div>
75+
<div class="day" role="button" aria-label="Contribution activity" style="background-color: var(--color-level-2);"></div>
76+
<div class="day" role="button" aria-label="Contribution activity" style="background-color: var(--color-level-3);"></div>
77+
<div class="day" role="button" aria-label="Contribution activity" style="background-color: var(--color-level-4);"></div>
78+
<span class="legend-text">More</span>
79+
</div>
80+
</div>
81+
82+
<style>
83+
.heatmap-container {
84+
--color-level-0: rgba(100, 116, 139, 0.1);
85+
--color-level-1: rgba(99, 102, 241, 0.4);
86+
--color-level-2: rgba(99, 102, 241, 0.6);
87+
--color-level-3: rgba(99, 102, 241, 0.8);
88+
--color-level-4: var(--primary);
89+
90+
padding: 1.5rem;
91+
border-radius: var(--radius-lg);
92+
display: flex;
93+
flex-direction: column;
94+
gap: 1.5rem;
95+
}
96+
97+
.heatmap-header {
98+
display: flex;
99+
justify-content: space-between;
100+
align-items: center;
101+
}
102+
103+
.heatmap-header h3 {
104+
font-size: 1.125rem;
105+
color: var(--text-primary);
106+
}
107+
108+
.pulse-indicator {
109+
display: flex;
110+
align-items: center;
111+
gap: 0.5rem;
112+
font-size: 0.875rem;
113+
color: var(--text-muted);
114+
font-weight: 500;
115+
}
116+
117+
.pulse-dot {
118+
width: 8px;
119+
height: 8px;
120+
background-color: #22c55e;
121+
border-radius: 50%;
122+
box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.7);
123+
animation: pulse 2s infinite;
124+
}
125+
126+
@keyframes pulse {
127+
0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.7); }
128+
70% { transform: scale(1); box-shadow: 0 0 0 6px rgba(34, 197, 94, 0); }
129+
100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
130+
}
131+
132+
.heatmap-scroll-wrapper {
133+
overflow-x: auto;
134+
padding-bottom: 0.5rem;
135+
}
136+
137+
/* Custom scrollbar for heatmap */
138+
.heatmap-scroll-wrapper::-webkit-scrollbar {
139+
height: 6px;
140+
}
141+
.heatmap-scroll-wrapper::-webkit-scrollbar-track {
142+
background: var(--bg-secondary);
143+
border-radius: 999px;
144+
}
145+
.heatmap-scroll-wrapper::-webkit-scrollbar-thumb {
146+
background: rgba(99, 102, 241, 0.3);
147+
border-radius: 999px;
148+
}
149+
150+
.heatmap-grid {
151+
display: flex;
152+
gap: 4px;
153+
min-width: max-content;
154+
}
155+
156+
.week {
157+
display: flex;
158+
flex-direction: column;
159+
gap: 4px;
160+
}
161+
162+
.day {
163+
width: 14px;
164+
height: 14px;
165+
border-radius: 3px;
166+
border: 1px solid rgba(255, 255, 255, 0.05);
167+
transition: transform 0.2s ease, box-shadow 0.2s ease;
168+
cursor: pointer;
169+
}
170+
171+
.day:hover {
172+
transform: scale(1.2);
173+
box-shadow: 0 0 8px var(--primary-glow);
174+
z-index: 10;
175+
}
176+
177+
.heatmap-legend {
178+
display: flex;
179+
align-items: center;
180+
gap: 0.5rem;
181+
align-self: flex-end;
182+
font-size: 0.75rem;
183+
color: var(--text-muted);
184+
}
185+
186+
.legend-text {
187+
margin: 0 0.25rem;
188+
}
189+
</style>

0 commit comments

Comments
 (0)