Skip to content

Profile Page & Badge System

Profile pageapp/(dashboard)/profile/page.tsx
Badge definitionslib/utils/badges.ts
Badge hooklib/hooks/useAchievements.ts
Badge imagespublic/badges/*.webp
Route/profile

Profile Page

Screenshot: Full profile pageFull profile page

Displays the user's profile with:

  • Avatar, name, email, member-since date
  • Quick stats: stories count, badges earned, quizzes taken
  • Credits card: plan label ("Free Plan" / "Pro Plan"), credits remaining, usage breakdown
    • Pro users: expiry date ("Expires May 31, 2026") + "⭐ Pro" badge
    • Free users: "Upgrade to Pro" button (opens https://www.kidstory.app/upgrade in new tab)
  • Full Achievements section (all badges)
  • Personalized for You section (AI learning recommendations)

Accessible from: dashboard navbar avatar click, dashboard profile card.


Badge System

Screenshot: BadgeBadge

12 custom badges with .webp artwork (not emojis). Each badge has:

  • id — unique identifier
  • image — path to /badges/*.webp
  • name — display name
  • description — how to earn it
  • color — Tailwind gradient for glow effect
  • check(stats) — function that determines if earned

All Badges

BadgeImageRequirement
First Chapter/badges/First-Chapter.webpRead 1 story
Bookworm/badges/Bookworm.webpRead 5 stories
Story Collector/badges/Story-Collector.webpRead 10 stories
Library Hero/badges/Library-Hero.webpRead 25 stories
Quiz Starter/badges/Quiz-Starter.webpComplete 1 quiz
Star Student/badges/Star-Student.webpGet a perfect quiz score
Triple Star/badges/Triple-Star.webpGet 3 perfect scores
Quiz Champion/badges/Quiz-Champion.webpAverage score above 80% (min 3 quizzes)
Story Burst/badges/Story-Burst.webpCreate 3 stories in one day
World Explorer/badges/World-Explorer.webpRead stories in 2+ languages
Young Author/badges/Young-Author.webpDownload a story as PDF
Super Reader/badges/Super-Reader.webp10+ stories AND 70%+ average score

How badges are computed

Story/quiz activity


useAchievements(uid, stories) hook

    ├── buildStats(stories, pdfDownloads) → UserStats
    │       totalStories, totalQuizzesTaken, perfectScores,
    │       avgScore, storiesInOneDay, languagesUsed, pdfDownloads

    ├── computeEarnedBadgeIds(stats) → Set<string>
    │       Runs each badge's check() function against stats

    ├── Compare with Firestore saved earnedIds
    │       New badge? → show BadgeToast + save to Firestore

    └── Return: earnedIds, newBadge, dismissNewBadge

Badge unlock toast

When a new badge is earned, BadgeToast component shows a floating notification at the top of the screen for 4 seconds with the badge image, name, and description.


Persistence

Earned badges are stored in Firestore at:

users/{uid}/settings/achievements
{
  earnedIds: ["first_story", "bookworm", ...],
  pdfDownloads: 2,
  updatedAt: "2026-04-28T..."
}

Released under the MIT License.