// Family Quest v17 โ†’ Database Upgrade Script // Add this BEFORE your existing game code on the WordPress page import React, { useState, useEffect } from ‘react’; import { Trophy, Star, Award, Plus, X, RotateCcw, History, Footprints } from ‘lucide-react’; const FamilyQuestGame = () => { const [players, setPlayers] = useState([ { id: 1, name: ‘Player 1’, points: 0, steps: 0, dailyPoints: 0, hasUsedBonus: false, color: ‘bg-blue-500’ }, { id: 2, name: ‘Player 2’, points: 0, steps: 0, dailyPoints: 0, hasUsedBonus: false, color: ‘bg-purple-500’ }, { id: 3, name: ‘Player 3’, points: 0, steps: 0, dailyPoints: 0, hasUsedBonus: false, color: ‘bg-green-500’ }, { id: 4, name: ‘Player 4’, points: 0, steps: 0, dailyPoints: 0, hasUsedBonus: false, color: ‘bg-orange-500’ } ]); const [weekHistory, setWeekHistory] = useState([]); const [currentWeek, setCurrentWeek] = useState(1); const [showHistory, setShowHistory] = useState(false); const [showRandomizer, setShowRandomizer] = useState(false); const [showRules, setShowRules] = useState(false); const [selectedPlayer, setSelectedPlayer] = useState(null); const [isSpinning, setIsSpinning] = useState(false); const [spinResult, setSpinResult] = useState(null); const defaultTasks = [ // 6 Points { id: 1, name: ‘Work a shift outside of home’, points: 6, category: ‘growth’ }, { id: 2, name: ‘Volunteer (per hour)’, points: 6, category: ‘growth’ }, { id: 3, name: ‘Counseling session (per person/hour)’, points: 6, category: ‘growth’ }, { id: 4, name: ‘Coaching session (per person/hour)’, points: 6, category: ‘growth’ }, { id: 5, name: ‘Cook a meal for the house’, points: 6, category: ‘chore’ }, { id: 6, name: ‘Attend online class/course (1+ hour)’, points: 6, category: ‘growth’ }, // 2 Points { id: 7, name: ‘Write a journal entry’, points: 2, category: ‘growth’ }, { id: 8, name: ‘List 3 items you are grateful for’, points: 2, category: ‘growth’ }, { id: 9, name: ‘One MyGrow droplet’, points: 2, category: ‘growth’ }, { id: 10, name: ‘Write a thank you note for someone’, points: 2, category: ‘growth’ }, { id: 11, name: ‘Attend a church service’, points: 2, category: ‘growth’ }, { id: 12, name: ‘Doctor or dentist appointment’, points: 2, category: ‘growth’ }, { id: 13, name: ‘Job interview’, points: 2, category: ‘growth’ }, { id: 14, name: ‘Practice an instrument’, points: 2, category: ‘growth’ }, { id: 15, name: ‘Duolingo/Babbel lesson (10+ min)’, points: 2, category: ‘growth’ }, { id: 16, name: ‘Playground time with Matthew (no phones)’, points: 2, category: ‘growth’ }, { id: 17, name: ‘Watch Chosen episode with Mom/Dad’, points: 2, category: ‘growth’ }, { id: 18, name: ‘Attend weekly family business meeting’, points: 2, category: ‘growth’ }, { id: 19, name: ‘Meet step goal (3000/5000/10000)’, points: 2, category: ‘growth’ }, { id: 20, name: ‘One of your regular chores’, points: 2, category: ‘chore’ }, { id: 21, name: ’30 min weeding/watering/raking’, points: 2, category: ‘chore’ }, // 1 Point { id: 22, name: ‘Library visit with M’, points: 1, category: ‘growth’ }, { id: 23, name: ‘Read 5 books to M’, points: 1, category: ‘growth’ }, { id: 24, name: ‘Go on a walk (15+ min, 1/day)’, points: 1, category: ‘growth’ }, { id: 25, name: ‘Swim at Y or rec center as family’, points: 1, category: ‘growth’ }, { id: 26, name: ’10 min of calisthenics’, points: 1, category: ‘growth’ }, { id: 27, name: ‘Apply for a job’, points: 1, category: ‘growth’ }, { id: 28, name: ‘One hour without media/phone’, points: 1, category: ‘growth’ }, { id: 29, name: ‘Read a chapter of a book’, points: 1, category: ‘growth’ }, { id: 30, name: ‘Read the Bible (5+ minutes)’, points: 1, category: ‘growth’ }, { id: 31, name: ‘One load of laundry completed’, points: 1, category: ‘chore’ }, { id: 32, name: ‘Wash sheets’, points: 1, category: ‘chore’ }, { id: 33, name: ‘Wash towels’, points: 1, category: ‘chore’ }, { id: 34, name: ‘Make bathroom “guest ready”‘, points: 1, category: ‘chore’ }, { id: 35, name: ‘Three days without fast food’, points: 1, category: ‘growth’ }, { id: 36, name: ‘No meals/snacks after 7pm’, points: 1, category: ‘growth’ }, { id: 37, name: ‘No screen time one hour before bed’, points: 1, category: ‘growth’ } ]; const [tasks, setTasks] = useState(defaultTasks); const [newTaskName, setNewTaskName] = useState(”); const [newTaskPoints, setNewTaskPoints] = useState(”); const [newTaskCategory, setNewTaskCategory] = useState(‘chore’); const addTask = () => { if (newTaskName && newTaskPoints) { const newTask = { id: tasks.length + 1, name: newTaskName, points: parseInt(newTaskPoints), category: newTaskCategory }; setTasks([…tasks, newTask]); setNewTaskName(”); setNewTaskPoints(”); } }; const removeTask = (taskId) => { setTasks(tasks.filter(t => t.id !== taskId)); }; const addPoints = (playerId, points) => { setPlayers(players.map(p => p.id === playerId ? { …p, points: p.points + points, dailyPoints: p.dailyPoints + points } : p )); }; const completeDay = (playerId) => { setPlayers(players.map(p => { if (p.id === playerId && p.dailyPoints >= 10) { return { …p, steps: p.steps + 1, dailyPoints: 0 }; } return p; })); }; const resetDailyPoints = (playerId) => { setPlayers(players.map(p => p.id === playerId ? { …p, dailyPoints: 0 } : p )); }; const updatePlayerName = (playerId, newName) => { setPlayers(players.map(p => p.id === playerId ? { …p, name: newName } : p )); }; const endWeek = () => { const sortedPlayers = […players].sort((a, b) => b.points – a.points); const winners = sortedPlayers.filter(p => p.points >= 50 || p.steps >= 5); const weekData = { week: currentWeek, date: new Date().toLocaleDateString(), winners: winners.length > 0 ? winners.map(w => w.name).join(‘, ‘) : ‘No winners this week’, scores: players.map(p => ({ name: p.name, points: p.points, steps: p.steps })) }; setWeekHistory([weekData, …weekHistory]); setPlayers(players.map(p => ({ …p, points: 0, steps: 0, dailyPoints: 0, hasUsedBonus: false }))); setCurrentWeek(currentWeek + 1); }; const resetGame = () => { setPlayers(players.map(p => ({ …p, points: 0, steps: 0, dailyPoints: 0 }))); }; const spinWheel = (playerId) => { setIsSpinning(true); setSpinResult(null); setTimeout(() => { const won = Math.random() < 0.25; // 25% chance setSpinResult(won); if (won) { setPlayers(players.map(p => p.id === playerId ? { …p, points: p.points + 5, hasUsedBonus: true } : p )); } else { setPlayers(players.map(p => p.id === playerId ? { …p, hasUsedBonus: true } : p )); } setIsSpinning(false); }, 2000); }; const openRandomizer = (playerId) => { setSelectedPlayer(playerId); setShowRandomizer(true); setSpinResult(null); }; const sortedPlayers = […players].sort((a, b) => b.points – a.points); const PathStep = ({ active, isGoal }) => (
{isGoal ? ‘๐Ÿ†’ : active ? ‘๐Ÿ‘ฃ’ : ‘โ—‹’}
); return (
{/* Header */}
๐ŸŽฉ

Family Quest Adventures

Week {currentWeek} – The Temple of Achievement

Daily Goal: 10 points = 1 step forward
Weekly Goal: 5 steps OR 50 points = Winner’s Circle!
{/* History Modal */} {showHistory && (

Adventure Archives

{weekHistory.length === 0 ? (

No adventures completed yet!

) : (
{weekHistory.map((week, idx) => (

Week {week.week} – {week.date}

๐Ÿ† Winners: {week.winners}

{week.scores.map((score, i) => (
{score.name}: {score.points} pts, {score.steps} steps
))}
))}
)}
)} {/* Rules Modal */} {showRules && (

๐Ÿ“– How to Play Family Quest

๐ŸŽฏ The Goal

Reach the Winner’s Circle each week by achieving EITHER:

  • 5 Steps (earned by meeting daily goals)
  • OR 50+ Points in total for the week

๐Ÿ“… Weekly Cycle

  • The week runs from Sunday to Saturday
  • Click “Complete Adventure” on Saturday evening to crown winners and reset for the new week

โญ Daily Goals

  • Each day, try to earn 10 points
  • When you reach 10+ points, click “Take a Step” to add a step to your journey
  • This resets your daily points back to 0, but keeps your weekly total
  • Get 5 steps in one week to reach the Winner’s Circle!

๐ŸŽฐ Saturday Bonus Wheel

  • If you haven’t reached the Winner’s Circle by Saturday morning, you get ONE bonus spin
  • 25% chance to win 5 bonus points
  • Use it wisely – you only get one spin per week!
  • These bonus points could help you reach 50 points or your next step

๐Ÿงฉ How to Earn Points

  • Complete Chores (๐Ÿงน) and Growth Goals (๐ŸŒฑ) from the quest list
  • Click your name button under any quest to earn those points
  • Point values range from 1-6 points depending on the task
  • Add custom quests using the “Add New Quest” section

๐Ÿ† Winning

  • Anyone who reaches 5 steps OR 50+ points enters the Winner’s Circle
  • Multiple family members can win in the same week!
  • Winners are recorded in the History for bragging rights
  • Everyone starts fresh each Sunday

๐Ÿ’ก Pro Tips

  • Consistency wins! Focus on hitting that 10-point daily goal
  • High-value quests (6 points) can help you catch up quickly
  • If you’re close on Saturday, use your bonus wheel spin!
  • The daily reset button (โ†ป) lets you correct mistakes without taking a step
)} {/* Randomizer Modal */} {showRandomizer && selectedPlayer && (
๐ŸŽฐ

Saturday Bonus Wheel!

{players.find(p => p.id === selectedPlayer)?.name} gets one spin for 5 bonus points!

{/* Spinning Wheel Animation */}
{spinResult === null ? ‘๐ŸŽฏ’ : spinResult ? ‘โœจ’ : ‘๐Ÿ˜”’}
{spinResult === null && !isSpinning && ( )} {isSpinning && (
Spinning…
)} {spinResult !== null && (
{spinResult ? ‘๐ŸŽ‰ YOU WIN 5 POINTS! ๐ŸŽ‰’ : ‘Better luck next week!’}
)}
)} {/* Player Progress Trackers */}
{players.map(player => { const inWinnersCircle = player.points >= 50 || player.steps >= 5; return (
{player.name.charAt(0)}
updatePlayerName(player.id, e.target.value)} className=”text-xl font-bold border-2 border-gray-200 rounded px-2 py-1 focus:border-amber-400 focus:outline-none” />
{player.points} pts
{player.steps}/5 steps
{/* Indiana Jones Path */}
{[0, 1, 2, 3, 4].map(step => ( step} isGoal={step === 4 && player.steps >= 5} /> ))}
{inWinnersCircle && (
๐Ÿ† โญ ๐Ÿ†
IN THE WINNER’S CIRCLE!
)} {/* Daily Progress */}
Today’s Progress = 10 ? ‘text-green-600’ : ‘text-gray-600’}`}> {player.dailyPoints}/10 pts
= 10 ? ‘bg-green-500’ : ‘bg-blue-500’ }`} style={{ width: `${Math.min((player.dailyPoints / 10) * 100, 100)}%` }} />
{/* Saturday Bonus – Only show if not in winner’s circle and hasn’t used bonus */} {!inWinnersCircle && !player.hasUsedBonus && ( )} {player.hasUsedBonus && !inWinnersCircle && (
Bonus spin used this week
)}
); })}
{/* Leaderboard */}

Leaderboard

{sortedPlayers.map((player, index) => (
#{index + 1}
{player.name.charAt(0)}
{player.name}
{player.steps} steps
{player.points}
))}
{/* Tasks */}

Quests & Challenges

{tasks.map(task => (
{task.category === ‘chore’ ? ‘๐Ÿงน’ : ‘๐ŸŒฑ’} {task.name}
{task.points}
{players.map(player => ( ))}
))}

Add New Quest

setNewTaskName(e.target.value)} className=”w-full px-3 py-2 border-2 border-gray-200 rounded-lg focus:border-amber-400 focus:outline-none” />
setNewTaskPoints(e.target.value)} className=”w-24 px-3 py-2 border-2 border-gray-200 rounded-lg focus:border-amber-400 focus:outline-none” />
); }; export default FamilyQuestGame;