This commit is contained in:
lubiana 2025-07-12 19:56:19 +02:00
parent d2879ae308
commit becdd80716
Signed by: lubiana
SSH key fingerprint: SHA256:vW1EA0fRR3Fw+dD/sM0K+x3Il2gSry6YRYHqOeQwrfk
5 changed files with 32 additions and 32 deletions

View file

@ -149,11 +149,11 @@ function App() {
// --- UI --- // --- UI ---
return ( return (
<div className="min-h-screen bg-gray-100 flex flex-col items-center "> <div className="min-h-screen bg-gray-900 flex flex-col items-center ">
<div className="flex flex-row items-center gap-6 mb-6 mt-2 w-full max-w-4xl justify-center"> <div className="flex flex-row items-center gap-6 mb-6 mt-2 w-full max-w-4xl justify-center">
<h1 className="text-3xl font-bold text-blue-600">Scratch Card Game</h1> <h1 className="text-3xl font-bold text-blue-600">Scratch Card Game</h1>
<div className="text-lg">Money: <span className="font-mono font-bold">${formatter.format(money)}</span></div> <div className="text-lg text-white">Money: <span className="font-mono font-bold">${formatter.format(money)}</span></div>
<div className="text-lg">Gubble Points: <span className="font-mono font-bold">{formatter.format(gubblePoints)}</span></div> <div className="text-lg text-white">Gubble Points: <span className="font-mono font-bold">{formatter.format(gubblePoints)}</span></div>
<button className="px-4 py-2 bg-purple-600 hover:bg-purple-700 text-white font-bold rounded disabled:opacity-50" disabled={gubblePoints < 1} onClick={() => setIsStoreOpen(true)}>Open Gubble Point Store</button> <button className="px-4 py-2 bg-purple-600 hover:bg-purple-700 text-white font-bold rounded disabled:opacity-50" disabled={gubblePoints < 1} onClick={() => setIsStoreOpen(true)}>Open Gubble Point Store</button>
</div> </div>
<GubbleStore <GubbleStore

View file

@ -24,11 +24,11 @@ const Card: React.FC<CardProps> = ({ card, setCard, setMoney, setGubblePoints, u
{ 'notation': 'compact' } { 'notation': 'compact' }
) )
return ( return (
<div className="bg-white rounded-lg shadow p-6 flex flex-col items-center mb-6 w-full max-w-md"> <div className="bg-gray-800 rounded-lg shadow-lg p-6 flex flex-col items-center mb-6 w-full max-w-md">
<div className="mb-2 text-lg font-semibold text-gray-700">{card.tier?.name} Scratch Card</div> <div className="mb-2 text-lg font-semibold text-gray-100">{card.tier?.name} Scratch Card</div>
<div className="mb-4 flex gap-4 justify-center"> <div className="mb-4 flex gap-4 justify-center">
{card.winningNumbers.map((num, i) => ( {card.winningNumbers.map((num, i) => (
<div key={i} className="w-12 h-12 flex items-center justify-center rounded-full bg-blue-100 text-blue-700 text-xl font-bold border-2 border-blue-400"> <div key={i} className="w-12 h-12 flex items-center justify-center rounded-full bg-blue-900 text-blue-300 text-xl font-bold border-2 border-blue-700">
{num} {num}
</div> </div>
))} ))}
@ -38,7 +38,7 @@ const Card: React.FC<CardProps> = ({ card, setCard, setMoney, setGubblePoints, u
<button <button
key={idx} key={idx}
className={`w-16 h-16 flex items-center justify-center rounded-lg border-2 text-2xl font-bold transition className={`w-16 h-16 flex items-center justify-center rounded-lg border-2 text-2xl font-bold transition
${field.scratched ? (field.won ? 'bg-green-200 border-green-500 text-green-700' : 'bg-gray-200 border-gray-400 text-gray-500') : 'bg-yellow-100 border-yellow-400 text-yellow-700 hover:bg-yellow-200'}`} ${field.scratched ? (field.won ? 'bg-green-900 border-green-700 text-green-300' : 'bg-gray-700 border-gray-600 text-gray-400') : 'bg-yellow-900 border-yellow-700 text-yellow-300 hover:bg-yellow-800'}`}
disabled={field.scratched} disabled={field.scratched}
onMouseMove={() => { onMouseMove={() => {
if (field.scratched) return; if (field.scratched) return;
@ -74,14 +74,14 @@ const Card: React.FC<CardProps> = ({ card, setCard, setMoney, setGubblePoints, u
}} }}
> >
{field.scratched ? ( {field.scratched ? (
<span>{field.value}{field.won ? <span className="block text-xs font-normal text-green-700">+${formatter.format(field.won)}</span> : ''}</span> <span>{field.value}{field.won ? <span className="block text-xs font-normal text-green-300">+${formatter.format(field.won)}</span> : ''}</span>
) : ( ) : (
<span className="text-3xl select-none">?</span> <span className="text-3xl select-none">?</span>
)} )}
</button> </button>
))} ))}
</div> </div>
<div className="text-xs text-gray-500">Scratch each field one at a time. Winnings: 1-2 = 50%, 3-4 = 80%, 5-6 = 120% of card price.</div> <div className="text-xs text-gray-400">Scratch each field one at a time. Winnings: 1-2 = 50%, 3-4 = 80%, 5-6 = 120% of card price.</div>
</div> </div>
); );
}; };

View file

@ -27,21 +27,21 @@ const UPGRADE_LIST: { key: keyof Upgrades; label: string; cost: number; descript
const GubbleStore: React.FC<GubbleStoreProps> = ({ isOpen, onClose, gubblePoints, upgrades, onBuyUpgrade }) => { const GubbleStore: React.FC<GubbleStoreProps> = ({ isOpen, onClose, gubblePoints, upgrades, onBuyUpgrade }) => {
if (!isOpen) return null; if (!isOpen) return null;
return ( return (
<div className="fixed inset-0 bg-black bg-opacity-40 flex items-center justify-center z-50"> <div className="fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-50">
<div className="bg-white rounded-lg shadow-lg p-8 w-full max-w-md relative"> <div className="bg-gray-900 rounded-lg shadow-lg p-8 w-full max-w-md relative">
<button className="absolute top-2 right-2 text-gray-500 hover:text-gray-700 text-2xl" onClick={onClose}>&times;</button> <button className="absolute top-2 right-2 text-gray-400 hover:text-gray-200 text-2xl" onClick={onClose}>&times;</button>
<h2 className="text-2xl font-bold mb-4 text-blue-700">Gubble Point Store</h2> <h2 className="text-2xl font-bold mb-4 text-blue-300">Gubble Point Store</h2>
<div className="mb-4">Gubble Points: <span className="font-mono font-bold">{gubblePoints}</span></div> <div className="mb-4 text-gray-100">Gubble Points: <span className="font-mono font-bold">{gubblePoints}</span></div>
<ul className="space-y-4"> <ul className="space-y-4">
{UPGRADE_LIST.map(upg => ( {UPGRADE_LIST.map(upg => (
<li key={upg.key} className="flex flex-col sm:flex-row sm:items-center sm:justify-between bg-gray-50 rounded p-3 border"> <li key={upg.key} className="flex flex-col sm:flex-row sm:items-center sm:justify-between bg-gray-800 rounded p-3 border border-gray-700">
<div> <div>
<div className="font-semibold text-lg">{upg.label}</div> <div className="font-semibold text-lg text-gray-100">{upg.label}</div>
<div className="text-gray-500 text-sm mb-1">{upg.description}</div> <div className="text-gray-400 text-sm mb-1">{upg.description}</div>
<div className="text-gray-700 text-sm">Cost: <span className="font-mono">{upg.cost}</span></div> <div className="text-gray-300 text-sm">Cost: <span className="font-mono">{upg.cost}</span></div>
</div> </div>
<button <button
className={`mt-2 sm:mt-0 px-4 py-1 rounded font-bold text-white ${upgrades[upg.key] ? 'bg-gray-400 cursor-not-allowed' : gubblePoints < upg.cost ? 'bg-yellow-200 cursor-not-allowed' : 'bg-blue-500 hover:bg-blue-600'}`} className={`mt-2 sm:mt-0 px-4 py-1 rounded font-bold text-white ${upgrades[upg.key] ? 'bg-gray-700 cursor-not-allowed' : gubblePoints < upg.cost ? 'bg-yellow-900 cursor-not-allowed' : 'bg-blue-700 hover:bg-blue-800'}`}
disabled={upgrades[upg.key] || gubblePoints < upg.cost} disabled={upgrades[upg.key] || gubblePoints < upg.cost}
onClick={() => onBuyUpgrade(upg.key, upg.cost)} onClick={() => onBuyUpgrade(upg.key, upg.cost)}
> >

View file

@ -15,17 +15,17 @@ const HistoryList: React.FC<HistoryListProps> = React.memo(({ history }) => {
if (history.length === 0) return null; if (history.length === 0) return null;
return ( return (
<div className="w-full max-w-md mb-8"> <div className="w-full max-w-md mb-8">
<div className="font-semibold text-gray-700 mb-2">Play History</div> <div className="font-semibold text-gray-100 mb-2">Play History</div>
<ul className="divide-y divide-gray-200 bg-white rounded-lg shadow"> <ul className="divide-y divide-gray-700 bg-gray-800 rounded-lg shadow-lg">
{history.map((h, i) => ( {history.map((h, i) => (
<li key={i} className="p-3 flex flex-col sm:flex-row sm:items-center sm:justify-between"> <li key={i} className="p-3 flex flex-col sm:flex-row sm:items-center sm:justify-between">
<div> <div>
<span className="font-bold text-blue-600">{h.tier}</span> <span className="font-bold text-blue-300">{h.tier}</span>
<span className="ml-2 text-gray-500">Win: ${h.winnings}</span> <span className="ml-2 text-gray-400">Win: ${h.winnings}</span>
</div> </div>
<div className="flex gap-2 mt-2 sm:mt-0"> <div className="flex gap-2 mt-2 sm:mt-0">
{h.winningNumbers.map((n, j) => ( {h.winningNumbers.map((n, j) => (
<span key={j} className="w-6 h-6 flex items-center justify-center rounded-full bg-blue-100 text-blue-700 text-xs font-bold border border-blue-300">{n}</span> <span key={j} className="w-6 h-6 flex items-center justify-center rounded-full bg-blue-900 text-blue-300 text-xs font-bold border border-blue-700">{n}</span>
))} ))}
</div> </div>
<div className="flex gap-1 mt-2 sm:mt-0"> <div className="flex gap-1 mt-2 sm:mt-0">
@ -34,8 +34,8 @@ const HistoryList: React.FC<HistoryListProps> = React.memo(({ history }) => {
key={j} key={j}
className={`w-5 h-5 flex items-center justify-center rounded text-xs border ${ className={`w-5 h-5 flex items-center justify-center rounded text-xs border ${
h.winningNumbers.includes(n) h.winningNumbers.includes(n)
? 'bg-green-100 text-green-700 border-green-300' ? 'bg-green-900 text-green-300 border-green-700'
: 'bg-gray-100 text-gray-700 border-gray-300' : 'bg-gray-700 text-gray-400 border-gray-600'
}`} }`}
> >
{n} {n}

View file

@ -17,22 +17,22 @@ const TierCard: React.FC<TierCardProps> = React.memo(({ tier, unlocked, money, o
) )
return ( return (
<button <button
className={`rounded-lg shadow p-2 flex flex-col items-center w-32 font-bold text-white mb-1 disabled:opacity-50 ${ className={`rounded-lg shadow-lg p-2 flex flex-col items-center w-32 font-bold text-gray-900 mb-1 disabled:opacity-50 ${
!unlocked !unlocked
? 'bg-yellow-400 hover:bg-yellow-500' ? 'bg-yellow-500 hover:bg-yellow-800'
: 'bg-green-500 hover:bg-green-600' : 'bg-green-500 hover:bg-green-800'
}`} }`}
disabled={!unlocked ? money < tier.unlockPrice : money < tier.buyPrice} disabled={!unlocked ? money < tier.unlockPrice : money < tier.buyPrice}
onClick={() => (!unlocked ? onUnlock(tier) : onBuy(tier))} onClick={() => (!unlocked ? onUnlock(tier) : onBuy(tier))}
> >
<div className="text-lg font-semibold mb-1">{tier.name}</div> <div className="text-lg font-semibold mb-1">{tier.name}</div>
<div className="text-gray-500 text-xs mb-1"> <div className="text-gray-900 text-xs mb-1">
Unlock: ${formatter.format(tier.unlockPrice)} Unlock: ${formatter.format(tier.unlockPrice)}
</div> </div>
<div className="text-gray-500 text-xs mb-1"> <div className="text-gray-900 text-xs mb-1">
Buy: ${formatter.format(tier.buyPrice)} Buy: ${formatter.format(tier.buyPrice)}
</div> </div>
<div className="text-gray-500 text-xs mb-1">Point Chance: {tier.gubblePointChance * 100}%</div> <div className="text-gray-900 text-xs mb-1">Point Chance: {tier.gubblePointChance * 100}%</div>
<div> <div>
{!unlocked ? 'Unlock' : 'Buy Card'} {!unlocked ? 'Unlock' : 'Buy Card'}
</div> </div>