feat: Implement pack count validation for online play, adding a dynamic rules tooltip and button state based on available packs.
All checks were successful
Build and Deploy / build (push) Successful in 1m21s

This commit is contained in:
2025-12-17 02:32:58 +01:00
parent 3194be382f
commit 80de286777
5 changed files with 107 additions and 5 deletions

View File

@@ -71,3 +71,5 @@
- [Enhanced Toast Visibility](./devlog/2025-12-17-023000_enhanced_toast_visibility.md): Completed. Updated toasts to be top-center, animated, and highly visible with premium styling.
- [Unified Toast Design](./devlog/2025-12-17-023500_unified_toast_design.md): Completed. Refined toast aesthetics to match the global dark/slate theme with subtle colored accents.
- [Animated Copy Button](./devlog/2025-12-17-024000_animated_copy_button.md): Completed. Replaced copy toast with an in-place animated tick button for immediate feedback.
- [Play Online Logic](./devlog/2025-12-17-031500_play_online_logic.md): Completed. Implemented strict pack limits (min 12 for 4 players) and visual feedback for the online lobby button.
- [Lobby Rules Tooltip](./devlog/2025-12-17-032000_lobby_rules_tooltip.md): Completed. Added dynamic rules explanation and supported player indicators to the lobby creation screen.

View File

@@ -0,0 +1,19 @@
### Play Online Logic Implementation
**Status**: Completed
**Date**: 2025-12-17
**Description**
Implemented pack count validation logic for "Play Online" to strictly enforce draft player limits.
**Changes**
1. **Rule Enforcement**:
- **< 12 packs**: Button visual disabled (slate color), shows error toast explaining rules if clicked.
- **12-17 packs**: Allows entry, shows toast "Enough for 4 players only" (Info).
- **18-23 packs**: Allows entry, shows toast "Enough for 4 or 6 players" (Info).
- **24+ packs**: Allows entry, shows toast "Enough for 8 players!" (Success).
2. **UI Feedback**: Updated button class logic to visually reflect availability based on pack count.
**Effect**
Prevents users from starting unplayable drafts and informs them of the capacity their current pool supports.

View File

@@ -0,0 +1,16 @@
### Lobby Rules Tooltip
**Status**: Completed
**Date**: 2025-12-17
**Description**
Added a dynamic tooltip and status indicator to the Online Lobby to explain draft capacity rules based on pack count.
**Changes**
1. **Info Icon**: Added an `AlertCircle` icon with a hoverable tooltip explaining the pack requirements (3 packs/player).
2. **Dynamic Rules**: The list of rules highlights the currently applicable tier based on pack count (e.g., turning green for "12-17 Packs" if 15 packs are available).
3. **Status Line**: A summary line explicitly states "Supported Players: [Status]" under the pack count.
**Effect**
Users can now clearly see why they might need more packs before creating a room, and what player counts are supported with their current pool.

View File

@@ -10,8 +10,10 @@ interface CubeManagerProps {
onGoToLobby: () => void;
}
import { useToast } from '../../components/Toast';
export const CubeManager: React.FC<CubeManagerProps> = ({ packs, setPacks, onGoToLobby }) => {
// --- Services ---
const { showToast } = useToast();
// --- Services ---
// Memoize services to persist cache across renders
const generatorService = React.useMemo(() => new PackGeneratorService(), []);
@@ -136,6 +138,32 @@ export const CubeManager: React.FC<CubeManagerProps> = ({ packs, setPacks, onGoT
}, []);
// --- Handlers ---
const handlePlayOnline = () => {
const totalPacks = packs.length;
// Rules:
// < 12: No draft
// 12 <= p < 18: 4 players
// 18 <= p < 24: 4 or 6 players
// >= 24: 4, 6 or 8 players
if (totalPacks < 12) {
showToast('Need at least 12 packs for a 4-player draft (3 packs/player).', 'error');
return;
}
if (totalPacks >= 12 && totalPacks < 18) {
showToast('Enough packs for 4 players only.', 'info');
} else if (totalPacks >= 18 && totalPacks < 24) {
showToast('Enough packs for 4 or 6 players.', 'info');
} else {
showToast('Enough packs for 8 players!', 'success');
}
// Proceed to lobby
onGoToLobby();
};
const handleFileUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file) return;
@@ -649,8 +677,12 @@ export const CubeManager: React.FC<CubeManagerProps> = ({ packs, setPacks, onGoT
{packs.length > 0 && (
<>
<button
onClick={onGoToLobby}
className="px-4 py-2 bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-500 hover:to-pink-500 text-white font-bold rounded-lg shadow-lg flex items-center gap-2 animate-in fade-in zoom-in whitespace-nowrap"
onClick={handlePlayOnline}
className={`px-4 py-2 font-bold rounded-lg shadow-lg flex items-center gap-2 animate-in fade-in zoom-in whitespace-nowrap transition-colors
${packs.length < 12
? 'bg-slate-700 text-slate-400 cursor-not-allowed hover:bg-slate-600'
: 'bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-500 hover:to-pink-500 text-white'
}`}
>
<Users className="w-4 h-4" /> <span className="hidden sm:inline">Play Online</span>
</button>

View File

@@ -234,8 +234,41 @@ export const LobbyManager: React.FC<LobbyManagerProps> = ({ generatedPacks }) =>
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 pt-4 border-t border-slate-700">
{/* Create Room */}
<div className={`space-y-4 ${generatedPacks.length === 0 ? 'opacity-50' : ''}`}>
<h3 className="text-xl font-bold text-white">Create Room</h3>
<p className="text-sm text-slate-400">Start a new draft with your {generatedPacks.length} generated packs.</p>
<div className="flex justify-between items-start">
<h3 className="text-xl font-bold text-white">Create Room</h3>
<div className="group relative">
<AlertCircle className="w-5 h-5 text-slate-500 cursor-help hover:text-white transition-colors" />
<div className="absolute w-64 right-0 bottom-full mb-2 bg-slate-900 border border-slate-700 p-3 rounded-lg shadow-xl text-xs text-slate-300 hidden group-hover:block z-50">
<strong className="block text-white mb-2 pb-1 border-b border-slate-700">Draft Rules (3 packs/player)</strong>
<ul className="space-y-1">
<li className={generatedPacks.length < 12 ? 'text-red-400' : 'text-slate-500'}>
&lt; 12 Packs: Not enough for draft
</li>
<li className={(generatedPacks.length >= 12 && generatedPacks.length < 18) ? 'text-emerald-400 font-bold' : 'text-slate-500'}>
12-17 Packs: 4 Players
</li>
<li className={(generatedPacks.length >= 18 && generatedPacks.length < 24) ? 'text-emerald-400 font-bold' : 'text-slate-500'}>
18-23 Packs: 4 or 6 Players
</li>
<li className={generatedPacks.length >= 24 ? 'text-emerald-400 font-bold' : 'text-slate-500'}>
24+ Packs: 4, 6 or 8 Players
</li>
</ul>
</div>
</div>
</div>
<div className="text-sm text-slate-400">
Start a new draft with your <span className="text-white font-bold">{generatedPacks.length}</span> generated packs.
<div className="mt-1 text-xs">
Supported Players: {' '}
{generatedPacks.length < 12 && <span className="text-red-400 font-bold">None (Generate more packs)</span>}
{generatedPacks.length >= 12 && generatedPacks.length < 18 && <span className="text-emerald-400 font-bold">4 Only</span>}
{generatedPacks.length >= 18 && generatedPacks.length < 24 && <span className="text-emerald-400 font-bold">4 or 6</span>}
{generatedPacks.length >= 24 && <span className="text-emerald-400 font-bold">4, 6 or 8</span>}
</div>
</div>
<button
onClick={handleCreateRoom}
disabled={loading || generatedPacks.length === 0}