抽選
import React, { useState, useEffect, useCallback } from ‘react’; import { Gift, RefreshCcw, History, TrendingUp, Info, AlertCircle, ChevronDown, ChevronUp } from ‘lucide-react’; // 初期景品データ(ユーザー指定の配分) const INITIAL_PRIZES = [ { id: 1, name: ‘1等:6,000円’, bonus: 4000, initialCount: 10, color: ‘bg-yellow-500’, icon: ‘🏆’ }, { id: 2, name: ‘2等:5,000円’, bonus: 3000, initialCount: 20, color: ‘bg-orange-500’, icon: ‘🥈’ }, { id: 3, name: ‘3等:4,000円’, bonus: 2000, initialCount: 50, color: ‘bg-blue-500’, icon: ‘🥉’ }, { id: 4, name: ‘4等:3,000円’, bonus: 1000, initialCount: 100, color: ‘bg-green-500’, icon: ‘✨’ }, { id: 5, name: ‘5等:2,000円’, bonus: 0, initialCount: 820, color: ‘bg-gray-400’, icon: ‘🎈’ }, ]; const App = () => { const [prizes, setPrizes] = useState(INITIAL_PRIZES.map(p => ({ …p, count: p.initialCount }))); const [history, setHistory] = useState([]); const [isSpinning, setIsSpinning] = useState(false); const [currentWinner, setCurrentWinner] = useState(null); const [showAdmin, setShowAdmin] = useState(false); // 統計計算 const totalRemaining = prizes.reduce((sum, p) => sum + p.count, 0); const totalBonusSpent = prizes.reduce((sum, p) => sum + (p.initialCount – p.count) * p.bonus, 0); const totalBonusBudget = 300000; // 抽選実行 const drawLottery = useCallback(() => { if (totalRemaining === 0 || isSpinning) return; setIsSpinning(true); setCurrentWinner(null); // 演出のためのウェイト setTimeout(() => { let random = Math.floor(Math.random() * totalRemaining) + 1; let cumulative = 0; let winner = null; const newPrizes = prizes.map(p => { if (!winner && p.count > 0) { cumulative += p.count; if (random <= cumulative) { winner = { ...p }; return { ...p, count: p.count - 1 }; } } return p; }); setPrizes(newPrizes); setCurrentWinner(winner); setHistory(prev => [{ …winner, time: new Date().toLocaleTimeString() }, …prev].slice(0, 10)); setIsSpinning(false); }, 800); }, [prizes, totalRemaining, isSpinning]); // リセット const resetSystem = () => { if (confirm(‘全てのデータをリセットして初期状態に戻しますか?’)) { setPrizes(INITIAL_PRIZES.map(p => ({ …p, count: p.initialCount }))); setHistory([]); setCurrentWinner(null); } }; return (
{/* ヘッダー */}
{/* 抽選エリア */}
{/* 履歴 */}
{history.length > 0 && (
)}
{/* 管理者パネル(トグル式) */}
)}
PRESENT LOTTERY
1,000名様限定・総額30万円上乗せキャンペーン
{/* 抽選アニメーション中の表示 */}
{isSpinning && (
)}
{/* 結果表示 */}
{!isSpinning && currentWinner && (
)}
{/* 初期状態 */}
{!isSpinning && !currentWinner && (
)}
抽選中…
{currentWinner.icon}
おめでとうございます!
{currentWinner.name}
{currentWinner.bonus > 0 && (
🎉 プレミアム上乗せ獲得!
)}ボタンを押してスタート
REMAINING: {totalRemaining} / 1,000
最近の当選履歴
{history.map((item, i) => (
))}
{item.name}
{item.time}
{showAdmin && (
)}
{totalRemaining === 0 && (
上乗せ予算消費
¥{totalBonusSpent.toLocaleString()}
上限: ¥300,000
総配布完了数
{1000 – totalRemaining} / 1,000
現在の在庫明細
{prizes.map(p => (
))}
{p.name}
{p.count} / {p.initialCount}
全ての景品が配布されました。追加の予算設定を行うか、システムをリセットしてください。