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

@@ -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}