CLAUDE: Update all demo pages - add action field and cross-linking footers

Updated all 4 demo pages to use new action field and added navigation footers
for easy cross-linking between demo pages.

Changes:
- demo-decisions.vue: Updated to use action field, added runner prop bindings
- demo.vue: Added footer with links to other demos
- demo-gameplay.vue: Added footer with links to other demos
- demo-substitutions.vue: Added footer with links to other demos

Demo page updates:
- OffensiveDecision now uses action field instead of approach/hit_and_run/bunt
- Action labels properly mapped (swing_away, steal, check_jump, etc.)
- Added runner state props (runnerOnFirst, runnerOnSecond, runnerOnThird)
- Added outs prop for smart filtering

Footer features:
- 3-column grid layout responsive to mobile
- Icons and descriptions for each demo
- Hover effects on links
- Consistent styling across all pages

Demo pages now fully connected:
- /demo → Game State Demo (ScoreBoard, GameBoard, etc.)
- /demo-decisions → Decision Components Demo (new action-based)
- /demo-gameplay → Gameplay Components Demo (DiceRoller, ManualOutcome)
- /demo-substitutions → Substitution Components Demo

Files modified:
- pages/demo-decisions.vue
- pages/demo.vue
- pages/demo-gameplay.vue
- pages/demo-substitutions.vue

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Cal Corum 2025-11-14 15:17:06 -06:00
parent 4bdadeca07
commit cf4fef22d8
4 changed files with 180 additions and 9 deletions

View File

@ -216,6 +216,10 @@
:is-active="demoControls.isActive"
:current-decision="demoState.offensiveDecision"
:has-runners-on-base="demoControls.hasRunners"
:runner-on-first="!!demoRunners.first"
:runner-on-second="!!demoRunners.second"
:runner-on-third="!!demoRunners.third"
:outs="0"
@submit="handleOffensiveSubmit"
/>
</div>
@ -260,6 +264,47 @@
</div>
</div>
</Transition>
<!-- Footer with Demo Links -->
<div class="mt-12 border-t border-gray-200 dark:border-gray-700 pt-8">
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6">
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">
📚 Other Demo Pages
</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<NuxtLink
to="/demo"
class="p-4 rounded-lg border-2 border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-400 transition-colors"
>
<div class="text-2xl mb-2">🎮</div>
<div class="font-semibold text-gray-900 dark:text-white">Game State Demo</div>
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">
Live game state visualization
</div>
</NuxtLink>
<NuxtLink
to="/demo-gameplay"
class="p-4 rounded-lg border-2 border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-400 transition-colors"
>
<div class="text-2xl mb-2">🎲</div>
<div class="font-semibold text-gray-900 dark:text-white">Gameplay Demo</div>
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">
Dice rolling & manual outcomes
</div>
</NuxtLink>
<NuxtLink
to="/demo-substitutions"
class="p-4 rounded-lg border-2 border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-400 transition-colors"
>
<div class="text-2xl mb-2">🔄</div>
<div class="font-semibold text-gray-900 dark:text-white">Substitutions Demo</div>
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">
Player substitution workflow
</div>
</NuxtLink>
</div>
</div>
</div>
</div>
</div>
</template>
@ -307,9 +352,7 @@ const demoState = ref({
hold_runners: [],
} as DefensiveDecision,
offensiveDecision: {
approach: 'normal',
hit_and_run: false,
bunt_attempt: false,
action: 'swing_away',
} as Omit<OffensiveDecision, 'steal_attempts'>,
stealAttempts: [] as number[],
decisionHistory: [
@ -320,7 +363,7 @@ const demoState = ref({
},
{
type: 'Offensive' as const,
summary: 'power approach, Hit & Run',
summary: 'Swing Away',
timestamp: '10:45:18',
},
],
@ -361,16 +404,21 @@ const handleDefensiveSubmit = (decision: DefensiveDecision) => {
const handleOffensiveSubmit = (decision: Omit<OffensiveDecision, 'steal_attempts'>) => {
demoState.value.offensiveDecision = decision
const tactics = []
if (decision.hit_and_run) tactics.push('Hit & Run')
if (decision.bunt_attempt) tactics.push('Bunt')
const summary = `${decision.approach} approach${tactics.length ? ', ' + tactics.join(', ') : ''}`
const actionLabels: Record<string, string> = {
swing_away: 'Swing Away',
steal: 'Steal',
check_jump: 'Check Jump',
hit_and_run: 'Hit and Run',
sac_bunt: 'Sacrifice Bunt',
squeeze_bunt: 'Squeeze Bunt',
}
const summary = actionLabels[decision.action] || decision.action
demoState.value.decisionHistory.unshift({
type: 'Offensive',
summary,
timestamp: new Date().toLocaleTimeString(),
})
showToast(`Offensive decision submitted: ${summary}`)
showToast(`Offensive action selected: ${summary}`)
}
const handleStealSubmit = (attempts: number[]) => {

View File

@ -181,6 +181,47 @@
</div>
</div>
</div>
<!-- Footer with Demo Links -->
<div class="mt-12 border-t border-gray-200 dark:border-gray-700 pt-8">
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6">
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">
📚 Other Demo Pages
</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<NuxtLink
to="/demo"
class="p-4 rounded-lg border-2 border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-400 transition-colors"
>
<div class="text-2xl mb-2">🎮</div>
<div class="font-semibold text-gray-900 dark:text-white">Game State Demo</div>
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">
Live game state visualization
</div>
</NuxtLink>
<NuxtLink
to="/demo-decisions"
class="p-4 rounded-lg border-2 border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-400 transition-colors"
>
<div class="text-2xl mb-2"></div>
<div class="font-semibold text-gray-900 dark:text-white">Decisions Demo</div>
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">
Decision input components
</div>
</NuxtLink>
<NuxtLink
to="/demo-substitutions"
class="p-4 rounded-lg border-2 border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-400 transition-colors"
>
<div class="text-2xl mb-2">🔄</div>
<div class="font-semibold text-gray-900 dark:text-white">Substitutions Demo</div>
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">
Player substitution workflow
</div>
</NuxtLink>
</div>
</div>
</div>
</div>
</div>
</template>

View File

@ -126,6 +126,47 @@
</div>
</div>
</div>
<!-- Footer with Demo Links -->
<div class="mt-12 border-t border-gray-200 dark:border-gray-700 pt-8">
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6">
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">
📚 Other Demo Pages
</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<NuxtLink
to="/demo"
class="p-4 rounded-lg border-2 border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-400 transition-colors"
>
<div class="text-2xl mb-2">🎮</div>
<div class="font-semibold text-gray-900 dark:text-white">Game State Demo</div>
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">
Live game state visualization
</div>
</NuxtLink>
<NuxtLink
to="/demo-decisions"
class="p-4 rounded-lg border-2 border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-400 transition-colors"
>
<div class="text-2xl mb-2"></div>
<div class="font-semibold text-gray-900 dark:text-white">Decisions Demo</div>
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">
Decision input components
</div>
</NuxtLink>
<NuxtLink
to="/demo-gameplay"
class="p-4 rounded-lg border-2 border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-400 transition-colors"
>
<div class="text-2xl mb-2">🎲</div>
<div class="font-semibold text-gray-900 dark:text-white">Gameplay Demo</div>
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">
Dice rolling & manual outcomes
</div>
</NuxtLink>
</div>
</div>
</div>
</div>
</div>
</template>

View File

@ -160,6 +160,47 @@
</span>
</div>
</div>
<!-- Footer with Demo Links -->
<div class="mt-12 border-t border-gray-200 dark:border-gray-700 pt-8">
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6">
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">
📚 Other Demo Pages
</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<NuxtLink
to="/demo-decisions"
class="p-4 rounded-lg border-2 border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-400 transition-colors"
>
<div class="text-2xl mb-2"></div>
<div class="font-semibold text-gray-900 dark:text-white">Decisions Demo</div>
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">
Decision input components
</div>
</NuxtLink>
<NuxtLink
to="/demo-gameplay"
class="p-4 rounded-lg border-2 border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-400 transition-colors"
>
<div class="text-2xl mb-2">🎲</div>
<div class="font-semibold text-gray-900 dark:text-white">Gameplay Demo</div>
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">
Dice rolling & manual outcomes
</div>
</NuxtLink>
<NuxtLink
to="/demo-substitutions"
class="p-4 rounded-lg border-2 border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-400 transition-colors"
>
<div class="text-2xl mb-2">🔄</div>
<div class="font-semibold text-gray-900 dark:text-white">Substitutions Demo</div>
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">
Player substitution workflow
</div>
</NuxtLink>
</div>
</div>
</div>
</div>
<!-- Toast Notification - CENTER (Known working position) -->