Skip to content

Story Map ​

Pageapp/(dashboard)/story-map/page.tsx
Route/story-map
AccessDashboard navbar (πŸ—ΊοΈ button)

What it does ​

A visual, interactive world map that shows where each child's stories take place. Every story is automatically placed on the map based on keywords detected in the story prompt and title. Kids can tap a location pin to see all stories set in that place.

Screenshot: World mapWorld map


How location detection works ​

The system scans the story's prompt and title fields for keywords and maps them to predefined locations on the map.

User creates story: "A brave bunny explores the ocean"
    β”‚
    β–Ό
detectLocation() finds keyword "ocean"
    β”‚
    β–Ό
Pin placed at Ocean coordinates (x: 35%, y: 60%) with 🌊 emoji

Supported locations (30+) ​

Keyword(s)LocationEmoji
ocean, seaOcean🌊
underwaterDeep Sea🐠
forestEnchanted Forest🌲
jungleJungle🌴
mountainMountains⛰️
castle, kingdom, princess, princeKingdom🏰
dragonDragon's LairπŸ‰
space, planetOuter SpaceπŸš€
moonThe MoonπŸŒ™
desertDesert🏜️
islandTreasure Island🏝️
piratePirate CoveπŸ΄β€β˜ οΈ
farmSunny Farm🌾
gardenMagic Garden🌸
cityBig CityπŸ™οΈ
snow, ice, winter, arcticFrozen North❄️
dinosaurDino ValleyπŸ¦•
fairyFairy Meadow🧚
magic, wizardWizard TowerπŸͺ„
rainbowRainbow Valley🌈
cloud, skyCloud Kingdom☁️
animal, zooAnimal Kingdom🦁
safariSafari PlainsπŸ¦’
robotFuture CityπŸ€–
superheroHero HQ🦸
candy, cakeCandy Land🍭

If no keyword matches, the story defaults to "Storybook Land" at the center of the map.


UI features ​

  • Animated pins β€” each pin gently bounces with a staggered delay
  • Story count badge β€” pins with multiple stories show a count indicator
  • Pin detail panel β€” tapping a pin reveals all stories at that location with cover images
  • Navigate to story β€” tap any story in the detail panel to open the story reader
  • Dark/light theme β€” respects the user's dashboard theme preference
  • Empty state β€” friendly message encouraging kids to create their first story
  • Decorative map β€” abstract land masses and dot grid for a fantasy map feel

Data flow ​

Page loads
    β”‚
    β–Ό
useUserStories(uid) β†’ fetches all stories from Firestore
    β”‚
    β–Ό
For each story:
    detectLocation(story.prompt, story.title)
    β”‚
    β–Ό
Group stories by location label β†’ Map<label, MapPin>
    β”‚
    β–Ό
Render pins on the map at (x%, y%) coordinates

Design decisions ​

  • No external map API β€” the map is a styled div with CSS, not Google Maps. This keeps it lightweight, kid-friendly, and avoids API costs.
  • Keyword-based detection β€” simple and deterministic. No LLM call needed. Works instantly.
  • Multiple stories per pin β€” stories at the same location are grouped, showing a count badge.
  • Responsive β€” the map uses percentage-based positioning so it works on all screen sizes.

Released under the MIT License.