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.
|
- [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.
|
- [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.
|
- [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;
|
onGoToLobby: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import { useToast } from '../../components/Toast';
|
||||||
|
|
||||||
export const CubeManager: React.FC<CubeManagerProps> = ({ packs, setPacks, onGoToLobby }) => {
|
export const CubeManager: React.FC<CubeManagerProps> = ({ packs, setPacks, onGoToLobby }) => {
|
||||||
// --- Services ---
|
const { showToast } = useToast();
|
||||||
// --- Services ---
|
// --- Services ---
|
||||||
// Memoize services to persist cache across renders
|
// Memoize services to persist cache across renders
|
||||||
const generatorService = React.useMemo(() => new PackGeneratorService(), []);
|
const generatorService = React.useMemo(() => new PackGeneratorService(), []);
|
||||||
@@ -136,6 +138,32 @@ export const CubeManager: React.FC<CubeManagerProps> = ({ packs, setPacks, onGoT
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// --- Handlers ---
|
// --- 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 handleFileUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const file = event.target.files?.[0];
|
const file = event.target.files?.[0];
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
@@ -649,8 +677,12 @@ export const CubeManager: React.FC<CubeManagerProps> = ({ packs, setPacks, onGoT
|
|||||||
{packs.length > 0 && (
|
{packs.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
onClick={onGoToLobby}
|
onClick={handlePlayOnline}
|
||||||
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"
|
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>
|
<Users className="w-4 h-4" /> <span className="hidden sm:inline">Play Online</span>
|
||||||
</button>
|
</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">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 pt-4 border-t border-slate-700">
|
||||||
{/* Create Room */}
|
{/* Create Room */}
|
||||||
<div className={`space-y-4 ${generatedPacks.length === 0 ? 'opacity-50' : ''}`}>
|
<div className={`space-y-4 ${generatedPacks.length === 0 ? 'opacity-50' : ''}`}>
|
||||||
<h3 className="text-xl font-bold text-white">Create Room</h3>
|
<div className="flex justify-between items-start">
|
||||||
<p className="text-sm text-slate-400">Start a new draft with your {generatedPacks.length} generated packs.</p>
|
<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'}>
|
||||||
|
• < 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
|
<button
|
||||||
onClick={handleCreateRoom}
|
onClick={handleCreateRoom}
|
||||||
disabled={loading || generatedPacks.length === 0}
|
disabled={loading || generatedPacks.length === 0}
|
||||||
|
|||||||
Reference in New Issue
Block a user