Comprehensive UX polish: fix 19 friction points across all pages
CI / build-and-push (push) Successful in 33s
CI / build-and-push (push) Successful in 33s
Addresses broken interactions (notification bell, browser dialogs), missing feedback states (disabled buttons, pricing changes, paused indicator), unclear affordances (research queue, model tuning, funding requirements), and navigation gaps (hash routing, keyboard shortcuts, clickable dashboard cards, sidebar grouping, tutorial hints). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
import { Brain, Play, Rocket, Globe, SlidersHorizontal, ChevronDown, ChevronUp } from 'lucide-react';
|
||||
import { TutorialHint } from '@/components/game/TutorialHint';
|
||||
import { useGameStore } from '@/store';
|
||||
import { formatNumber, formatPercent, formatDuration } from '@ai-tycoon/shared';
|
||||
import type { TuningPreset } from '@ai-tycoon/shared';
|
||||
@@ -45,6 +46,10 @@ export function ModelsPage() {
|
||||
<div className="space-y-6">
|
||||
<h2 className="text-2xl font-bold">Models</h2>
|
||||
|
||||
<TutorialHint id="models-intro">
|
||||
Split compute between training (building new models) and inference (serving customers). Deploy trained models to start earning revenue.
|
||||
</TutorialHint>
|
||||
|
||||
<div className="bg-surface-900 border border-surface-700 rounded-xl p-4">
|
||||
<h3 className="font-semibold mb-3">Compute Allocation</h3>
|
||||
<div className="flex items-center gap-4">
|
||||
@@ -114,14 +119,22 @@ export function ModelsPage() {
|
||||
<div className="text-sm text-surface-400">
|
||||
Estimated capability score: <span className="text-accent-light font-mono">{estimatedCapability.toFixed(1)}/100</span>
|
||||
</div>
|
||||
<button
|
||||
onClick={handleStartTraining}
|
||||
disabled={trainingFlops === 0}
|
||||
className="flex items-center gap-2 bg-accent hover:bg-accent-dark text-white px-4 py-2 rounded-lg text-sm disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
<Play size={16} />
|
||||
Start Training
|
||||
</button>
|
||||
<div>
|
||||
<button
|
||||
onClick={handleStartTraining}
|
||||
disabled={trainingFlops === 0}
|
||||
className="flex items-center gap-2 bg-accent hover:bg-accent-dark text-white px-4 py-2 rounded-lg text-sm disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
<Play size={16} />
|
||||
Start Training
|
||||
</button>
|
||||
{trainingFlops === 0 && totalFlops === 0 && (
|
||||
<p className="text-xs text-warning mt-1">Build a data center and order racks first</p>
|
||||
)}
|
||||
{trainingFlops === 0 && totalFlops > 0 && (
|
||||
<p className="text-xs text-warning mt-1">Allocate compute to training above</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -137,8 +150,13 @@ export function ModelsPage() {
|
||||
<div key={model.id} className="bg-surface-900 border border-surface-700 rounded-xl p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<button onClick={() => setExpandedModel(isExpanded ? null : model.id)} className="text-surface-400 hover:text-surface-200">
|
||||
{isExpanded ? <ChevronUp size={16} /> : <ChevronDown size={16} />}
|
||||
<button
|
||||
onClick={() => setExpandedModel(isExpanded ? null : model.id)}
|
||||
className="flex items-center gap-1 text-xs text-surface-400 hover:text-surface-200"
|
||||
>
|
||||
<SlidersHorizontal size={12} />
|
||||
<span>{isExpanded ? 'Hide' : 'Tune'}</span>
|
||||
{isExpanded ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
|
||||
</button>
|
||||
<div>
|
||||
<h4 className="font-medium">{model.name}</h4>
|
||||
|
||||
Reference in New Issue
Block a user