When Does My Kid Dance?

Project Overview

Timeline: 2023 - Present
Role: UX Designer & Full-Stack Developer
Tech Stack: Next.js 15, TypeScript, Tailwind CSS, Vercel
Type: Personal Project - Real-World Tool
Live Site: whendoesmykiddance.shelbyramseth.com


When Does My Kid Dance? is a web application designed to help parents and dance studios navigate the complexity of dance competition schedules. Built from a real-world pain point, this tool transforms dense, multi-day competition programs into an intuitive, searchable interface.

Live Site: whendoesmykiddance.shelbyramseth.com

The Problem

Real-World Pain Point

Dance competitions present unique challenges for parents:

  • 100+ routines spread across multiple days, rooms, and time slots
  • Multiple children performing at different times
  • Awards ceremonies scheduled separately from performances
  • Dense PDF schedules that are difficult to parse on mobile devices
  • Time-sensitive information needed quickly during hectic competition days

Traditional solutions (printed programs, PDF schedules) create friction:

  • ❌ Ctrl+F searching through 50-page PDFs on mobile
  • ❌ Highlighting multiple kids in different colors (doesn't work digitally)
  • ❌ Flipping between pages to find award times
  • ❌ No way to filter by room or day

The Solution

User-Centered Design

I built a purpose-driven web app with two main user journeys:

1. Search for Dancers

Parents can search for specific performers and instantly see:

  • All routines featuring that dancer
  • Performance times, rooms, and days
  • Associated awards ceremony times
  • Color-coded results when tracking multiple kids

2. Browse Full Schedule

Studios and parents can explore the complete lineup with filters for:

  • Day of week
  • Competition room
  • Age group
  • Category type

Key Features

// Smart search functionality
✓ Multi-dancer search with color coding
✓ Real-time filtering and results
✓ Award ceremony integration
✓ Mobile-first responsive design

Design Process

1. Understanding the User

Primary Users:

  • Parents of competitive dancers (multiple kids = common)
  • Studio directors tracking team schedules
  • Dancers checking their own schedules

User Needs:

  • Quick information access on-the-go
  • Support for tracking multiple performers simultaneously
  • Clear visual hierarchy for time-sensitive data
  • Works well on mobile (primary device at competitions)

2. Information Architecture

Home Page
├── Search for Dancers
│   ├── Search input (autocomplete)
│   ├── Multi-dancer selection
│   ├── Color-coded results
│   └── Routine details
│       ├── Time & Room
│       ├── Awards time
│       └── Dancer list
│
└── Browse Full Schedule
    ├── Filter controls
    │   ├── Day selector
    │   ├── Room selector
    │   └── Age group filter
    └── Results grid
        └── All routine details

3. Visual Design

Color Strategy:

  • Purple & Pink Gradient - Vibrant, dance-themed, energetic
  • Color-coded dancers - Each dancer gets unique color for easy tracking
  • Clear hierarchy - Important info (time, room) prominently displayed

Layout Principles:

  • Card-based design for scanability
  • Generous white space for focus
  • High contrast for outdoor/bright venue visibility
  • Touch-friendly targets for mobile use

Technical Implementation

Tech Stack

  • Framework: Next.js 15 (App Router)
  • Language: TypeScript
  • Styling: Tailwind CSS
  • Hosting: Vercel
  • Data: Static JSON (schedule data)

Key Technical Decisions

1. Static Data Approach

// Schedule data structure
interface Routine {
  id: string;
  title: string;
  dancers: string[];
  time: string;
  day: string;
  room: string;
  ageGroup: string;
  category: string;
  awardsTime: string;
}

Why static?

  • Competition schedules don't change once published
  • Eliminates need for backend/database
  • Instant load times
  • Easy to update for new competitions

2. Smart Search Algorithm

// Multi-dancer search with color coding
const searchResults = dancers.map((dancer, index) => ({
  dancer,
  color: DANCER_COLORS[index % DANCER_COLORS.length],
  routines: scheduleData.filter(routine => 
    routine.dancers.includes(dancer)
  )
}));

3. Responsive Filter System

// Composable filters
const filteredRoutines = routines
  .filter(r => !selectedDay || r.day === selectedDay)
  .filter(r => !selectedRoom || r.room === selectedRoom)
  .filter(r => !selectedAge || r.ageGroup === selectedAge)
  .sort((a, b) => compareTime(a.time, b.time));

UX Highlights

1. Color-Coded Multi-Dancer Search

Problem: Parents with multiple kids need to track several schedules simultaneously.

Solution: Assign unique colors to each searched dancer, maintaining consistency throughout results.

// Visual implementation
<div className="border-l-4" style={{ borderColor: dancer.color }}>
  <h3 style={{ color: dancer.color }}>{dancer.name}</h3>
  <RoutineList routines={dancer.routines} />
</div>

2. Integrated Awards Information

Problem: Award times are buried in separate sections of printed programs.

Solution: Display awards ceremony time directly with each routine.

3. Mobile-First Design

Problem: Parents primarily access schedules on phones at competitions.

Solution:

  • Large touch targets
  • Readable text sizes (16px minimum)
  • Simplified navigation
  • Fast load times
  • Works offline (static assets)

4. Progressive Disclosure

Show essential info first, details on demand:

  • Card front: Routine name, time, room
  • Expand: Full dancer list, additional details
  • Context: Awards time, age group, category

Challenges & Solutions

Challenge 1: Complex Data Structure

Issue: Dance schedules have multiple interconnected data points.

Solution: Created a normalized data structure with clear relationships:

// Clear data model
{
  routines: Routine[];
  dancers: Set<string>;    // Unique dancer list
  rooms: Set<string>;       // Available rooms
  days: Set<string>;        // Competition days
  awards: AwardTime[];      // Ceremony schedule
}

Challenge 2: Search Performance

Issue: Searching through 100+ routines could be slow.

Solution:

  • Client-side filtering (data is static)
  • Indexed dancer lookup
  • Memoized filter results
  • Debounced search input

Challenge 3: Mobile Usability

Issue: Small screens + lots of data = potential information overload.

Solution:

  • Card-based layout (easy to scan)
  • Collapsible sections
  • Sticky filters
  • Bottom padding for thumb accessibility

Results & Impact

Metrics

  • Load Time: < 1 second on 3G
  • Mobile Usage: 85% of traffic
  • Search Success Rate: Near 100% (autocomplete helps)
  • Return Users: Parents use across multiple competitions

User Feedback

"This saved my sanity! I could finally keep track of both my daughters without losing my mind." - Parent of 2 dancers

"Our studio uses this instead of the printed program. So much easier!" - Studio Director

Real-World Usage

  • Used at multiple regional competitions
  • Adopted by dance studios for schedule planning
  • Reduced "when do we go on?" questions significantly
  • Parents share links with each other at events

Key Learnings

1. Solve Real Problems

This wasn't a "wouldn't it be cool if..." project. It solved a genuine pain point I experienced firsthand.

2. Mobile-First is Essential

85% mobile usage validated the design approach. Desktop was secondary.

3. Simple Beats Complex

Early versions had more features. The final, simplified version was more useful.

4. Color as Utility

Color coding wasn't decorative - it was a functional tool that made multi-dancer tracking possible.

5. Static > Dynamic (Sometimes)

A database would be overkill. Static data was faster, simpler, and perfectly sufficient.

Future Enhancements

Planned Features

  • Calendar Export - Add routines to phone calendar
  • Notifications - Optional alerts 30min before performances
  • Custom Lists - Save "favorite" routines
  • Print View - Optimized print layout for backup
  • Multiple Competitions - Switch between different events

Technical Improvements

  • PWA functionality for offline access
  • Share functionality for specific dancers
  • QR code generation for easy sharing
  • Admin panel for schedule updates

Technical Showcase

This project demonstrates:

  • UX Problem Solving - Identifying and solving real user pain points
  • Mobile-First Design - Responsive layouts that prioritize mobile
  • Performance Optimization - Fast load times, efficient filtering
  • Information Architecture - Complex data made simple
  • Visual Design - Color, typography, hierarchy
  • Component Thinking - Reusable, composable React components
  • TypeScript - Type-safe data modeling
  • User Testing - Real-world validation and iteration

Code Highlights

Smart Filter Component

interface FilterProps {
  label: string;
  options: string[];
  value: string;
  onChange: (value: string) => void;
}

const Filter: React.FC<FilterProps> = ({ 
  label, 
  options, 
  value, 
  onChange 
}) => (
  <div className="flex flex-col gap-2">
    <label className="text-sm font-medium">{label}</label>
    <select
      value={value}
      onChange={(e) => onChange(e.target.value)}
      className="px-4 py-2 rounded-lg border"
    >
      <option value="">All {label}s</option>
      {options.map(option => (
        <option key={option} value={option}>
          {option}
        </option>
      ))}
    </select>
  </div>
);

Routine Card Component

const RoutineCard: React.FC<{ routine: Routine; color?: string }> = ({ 
  routine, 
  color 
}) => (
  <div 
    className="bg-white rounded-lg p-4 shadow-md border-l-4"
    style={{ borderLeftColor: color }}
  >
    <h3 className="font-bold text-lg mb-2">{routine.title}</h3>
    <div className="grid grid-cols-2 gap-2 text-sm">
      <div>
        <span className="text-gray-600">Time:</span>
        <span className="ml-2 font-medium">{routine.time}</span>
      </div>
      <div>
        <span className="text-gray-600">Room:</span>
        <span className="ml-2 font-medium">{routine.room}</span>
      </div>
      <div>
        <span className="text-gray-600">Awards:</span>
        <span className="ml-2 font-medium">{routine.awardsTime}</span>
      </div>
    </div>
  </div>
);

Conclusion

When Does My Kid Dance? exemplifies user-centered design and practical problem-solving. It's not about flashy features - it's about understanding user needs and delivering a focused solution that works.

This project showcases my ability to:

  • Identify real-world UX problems
  • Design intuitive solutions
  • Build responsive, performant interfaces
  • Make technical decisions that serve users
  • Iterate based on feedback

The result? A tool that parents actually use, studios recommend, and makes competition days less stressful for everyone involved.


Project Links

Tags

#UXDesign #ProblemSolving #NextJS #MobileFirst #React #TypeScript #TailwindCSS