Skip to content

Commit 4d1b7c0

Browse files
committed
feat: celebrate tutorial completion with a confetti animation 🎉
1 parent 99f937c commit 4d1b7c0

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// src/components/tutorialCompletion.tsx
2+
import React, { useState } from 'react';
3+
import { triggerConfetti } from './ConfettiUtils'; // Import from the separate confetti utility
4+
5+
interface TutorialCompletionProps {
6+
tutorialTitle?: string; // Optional prop for the tutorial name
7+
onComplete?: () => void; // Optional callback for additional logic (e.g., update dashboard)
8+
}
9+
10+
const TutorialCompletion: React.FC<TutorialCompletionProps> = ({
11+
tutorialTitle = 'this tutorial',
12+
onComplete,
13+
}) => {
14+
const [isCompleted, setIsCompleted] = useState(false);
15+
16+
const handleComplete = () => {
17+
if (isCompleted) return; // Prevent multiple triggers
18+
19+
setIsCompleted(true);
20+
21+
// Trigger confetti for celebration
22+
try {
23+
triggerConfetti();
24+
} catch (error) {
25+
console.warn('Confetti failed to trigger:', error);
26+
}
27+
28+
// Optional: Call parent callback (e.g., to save progress or update UI)
29+
if (onComplete) {
30+
onComplete();
31+
}
32+
};
33+
34+
return (
35+
<div style={{ textAlign: 'center', margin: '20px 0' }}>
36+
<h3>Complete {tutorialTitle}</h3>
37+
{!isCompleted ? (
38+
<button
39+
onClick={handleComplete}
40+
style={{
41+
padding: '10px 20px',
42+
backgroundColor: '#2563eb', // Match theme colors
43+
color: 'white',
44+
border: 'none',
45+
borderRadius: '5px',
46+
cursor: 'pointer',
47+
fontSize: '16px',
48+
}}
49+
aria-label={`Mark ${tutorialTitle} as complete`}
50+
>
51+
Mark as Complete
52+
</button>
53+
) : (
54+
<p style={{ color: '#10b981', fontWeight: 'bold' }}>
55+
🎉 {tutorialTitle} Completed! Great job!
56+
</p>
57+
)}
58+
</div>
59+
);
60+
};
61+
62+
export default TutorialCompletion;

src/pages/TutorialPage.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import TutorialCompletion from '../components/tutorialCompletion';
2+
3+
const TutorialPage = () => (
4+
<div>
5+
<h1>My Tutorial</h1>
6+
{/* Tutorial content here */}
7+
<TutorialCompletion tutorialTitle="Git Basics" onComplete={() => console.log('Tutorial done!')} />
8+
</div>
9+
);
10+

src/utils/ConfettiUtils.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// src/components/ConfettiUtils.tsx
2+
import confetti from 'canvas-confetti';
3+
4+
/**
5+
* Triggers a celebratory confetti effect.
6+
* Can be used for achievements, completions, or interactions.
7+
*/
8+
export const triggerConfetti = () => {
9+
confetti({
10+
particleCount: 100, // Number of particles (adjust for intensity)
11+
spread: 70, // Spread angle in degrees
12+
origin: { y: 0.6 }, // Start position (center-ish screen)
13+
colors: ['#2563eb', '#7c3aed', '#10b981'], // Custom colors (blue, purple, green – match leaderboard/theme)
14+
duration: 2000, // Optional: How long it lasts (in ms)
15+
});
16+
};
17+

0 commit comments

Comments
 (0)