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
All checks were successful
Build and Deploy / build (push) Successful in 1m21s
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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>
|
||||
|
||||
@@ -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' : ''}`}>
|
||||
<div className="flex justify-between items-start">
|
||||
<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="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'}>
|
||||
• < 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}
|
||||
|
||||
Reference in New Issue
Block a user