GameV1Platafoem
This commit is contained in:
parent
b90e93ba75
commit
45cc629ea0
@ -61,6 +61,10 @@ revoked_reason: {
|
||||
|
||||
},
|
||||
|
||||
guest_id: {
|
||||
type: DataTypes.TEXT,
|
||||
},
|
||||
|
||||
importHash: {
|
||||
type: DataTypes.STRING(255),
|
||||
allowNull: true,
|
||||
@ -138,6 +142,4 @@ revoked_reason: {
|
||||
|
||||
|
||||
return game_access_passes;
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
@ -84,6 +84,10 @@ expires_at: {
|
||||
|
||||
},
|
||||
|
||||
guest_id: {
|
||||
type: DataTypes.TEXT,
|
||||
},
|
||||
|
||||
importHash: {
|
||||
type: DataTypes.STRING(255),
|
||||
allowNull: true,
|
||||
@ -177,6 +181,4 @@ expires_at: {
|
||||
|
||||
|
||||
return orders;
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
const express = require('express');
|
||||
|
||||
const GamesService = require('../services/games');
|
||||
@ -10,6 +9,18 @@ const router = express.Router();
|
||||
|
||||
const { parse } = require('json2csv');
|
||||
|
||||
// Public routes for purchase and verification
|
||||
router.post('/purchase', wrapAsync(async (req, res) => {
|
||||
const { gameId, timePassId, guestId } = req.body;
|
||||
const payload = await GamesService.purchase(gameId, timePassId, guestId, req.currentUser);
|
||||
res.status(200).send(payload);
|
||||
}));
|
||||
|
||||
router.get('/verify-access', wrapAsync(async (req, res) => {
|
||||
const { gameId, guestId } = req.query;
|
||||
const payload = await GamesService.verifyAccess(gameId, guestId, req.currentUser);
|
||||
res.status(200).send(payload);
|
||||
}));
|
||||
|
||||
const {
|
||||
checkCrudPermissions,
|
||||
@ -459,4 +470,4 @@ router.get('/:id', wrapAsync(async (req, res) => {
|
||||
|
||||
router.use('/', require('../helpers').commonErrorHandler);
|
||||
|
||||
module.exports = router;
|
||||
module.exports = router;
|
||||
@ -6,10 +6,7 @@ const csv = require('csv-parser');
|
||||
const axios = require('axios');
|
||||
const config = require('../config');
|
||||
const stream = require('stream');
|
||||
|
||||
|
||||
|
||||
|
||||
const { Op } = require('sequelize');
|
||||
|
||||
module.exports = class GamesService {
|
||||
static async create(data, currentUser) {
|
||||
@ -132,7 +129,77 @@ module.exports = class GamesService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
static async purchase(gameId, timePassId, guestId, currentUser) {
|
||||
const transaction = await db.sequelize.transaction();
|
||||
try {
|
||||
const game = await db.games.findByPk(gameId, { transaction });
|
||||
const timePass = await db.game_time_passes.findByPk(timePassId, { transaction });
|
||||
|
||||
if (!game || !timePass) {
|
||||
throw new ValidationError('Game or Time Pass not found');
|
||||
}
|
||||
|
||||
// Create a simulated order
|
||||
const order = await db.orders.create({
|
||||
status: 'paid',
|
||||
amount: timePass.price,
|
||||
currency: 'USD',
|
||||
userId: currentUser ? currentUser.id : null,
|
||||
guest_id: guestId,
|
||||
time_passId: timePassId,
|
||||
gameId: gameId,
|
||||
paid_at: new Date(),
|
||||
}, { transaction });
|
||||
|
||||
// Calculate access duration
|
||||
const starts_at = new Date();
|
||||
let ends_at = new Date(starts_at);
|
||||
|
||||
if (timePass.duration_days) {
|
||||
ends_at.setDate(ends_at.getDate() + timePass.duration_days);
|
||||
} else {
|
||||
// Default to 1 day if not specified or fallback
|
||||
ends_at.setDate(ends_at.getDate() + 1);
|
||||
}
|
||||
|
||||
const accessPass = await db.game_access_passes.create({
|
||||
starts_at,
|
||||
ends_at,
|
||||
status: 'active',
|
||||
userId: currentUser ? currentUser.id : null,
|
||||
guest_id: guestId,
|
||||
gameId: gameId,
|
||||
orderId: order.id,
|
||||
}, { transaction });
|
||||
|
||||
await transaction.commit();
|
||||
return {
|
||||
success: true,
|
||||
accessPass,
|
||||
playUrl: game.web_play_url
|
||||
};
|
||||
} catch (error) {
|
||||
await transaction.rollback();
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
static async verifyAccess(gameId, guestId, currentUser) {
|
||||
const where = {
|
||||
gameId: gameId,
|
||||
status: 'active',
|
||||
ends_at: {
|
||||
[Op.gt]: new Date()
|
||||
}
|
||||
};
|
||||
|
||||
if (currentUser) {
|
||||
where.userId = currentUser.id;
|
||||
} else {
|
||||
where.guest_id = guestId;
|
||||
}
|
||||
|
||||
const access = await db.game_access_passes.findOne({ where });
|
||||
return !!access;
|
||||
}
|
||||
};
|
||||
@ -11,11 +11,14 @@ import {
|
||||
mdiShieldCheck,
|
||||
mdiChevronRight,
|
||||
mdiBrain,
|
||||
mdiDeveloperBoard
|
||||
mdiDeveloperBoard,
|
||||
mdiLockOutline,
|
||||
mdiCheckCircle
|
||||
} from '@mdi/js'
|
||||
import BaseIcon from '../components/BaseIcon'
|
||||
import axios from 'axios'
|
||||
import Link from 'next/link'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
export default function IndexPage() {
|
||||
const [games, setGames] = useState([])
|
||||
@ -23,8 +26,20 @@ export default function IndexPage() {
|
||||
const [timePasses, setTimePasses] = useState([])
|
||||
const [qrCodes, setQrCodes] = useState([])
|
||||
const [activeCategory, setActiveCategory] = useState('all')
|
||||
const [selectedGame, setSelectedGame] = useState<any>(null)
|
||||
const [selectedPass, setSelectedPass] = useState<any>(null)
|
||||
const [isPurchasing, setIsPurchasing] = useState(false)
|
||||
const [isUnlocked, setIsUnlocked] = useState(false)
|
||||
const [guestId, setGuestId] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
let gid = localStorage.getItem('guestId')
|
||||
if (!gid) {
|
||||
gid = `guest_${Math.random().toString(36).substring(2, 15)}`
|
||||
localStorage.setItem('guestId', gid)
|
||||
}
|
||||
setGuestId(gid)
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const [gamesRes, catsRes, passesRes, qrRes] = await Promise.all([
|
||||
@ -44,6 +59,39 @@ export default function IndexPage() {
|
||||
fetchData()
|
||||
}, [])
|
||||
|
||||
const checkAccess = async (gameId: string) => {
|
||||
try {
|
||||
const res = await axios.get(`/games/verify-access?gameId=${gameId}&guestId=${guestId}`)
|
||||
setIsUnlocked(res.data)
|
||||
} catch (err) {
|
||||
console.error("Failed to verify access", err)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedGame) {
|
||||
checkAccess(selectedGame.id)
|
||||
}
|
||||
}, [selectedGame, guestId])
|
||||
|
||||
const handlePurchase = async () => {
|
||||
if (!selectedGame || !selectedPass) return
|
||||
setIsPurchasing(true)
|
||||
try {
|
||||
await axios.post('/games/purchase', {
|
||||
gameId: selectedGame.id,
|
||||
timePassId: selectedPass.id,
|
||||
guestId: guestId
|
||||
})
|
||||
setIsUnlocked(true)
|
||||
// Scroll to game area if needed
|
||||
} catch (err) {
|
||||
console.error("Purchase failed", err)
|
||||
} finally {
|
||||
setIsPurchasing(false)
|
||||
}
|
||||
}
|
||||
|
||||
const filteredGames = activeCategory === 'all'
|
||||
? games
|
||||
: games.filter((g: any) => g.game_categoryId === activeCategory)
|
||||
@ -51,7 +99,7 @@ export default function IndexPage() {
|
||||
return (
|
||||
<div className="min-h-screen bg-[#020617] text-white selection:bg-violet-500/30">
|
||||
<Head>
|
||||
<title>{getPageTitle('Advanced Gaming & AI Dev Platform')}</title>
|
||||
<title>{getPageTitle('Nexus Gaming - Premium AI Game Platform')}</title>
|
||||
</Head>
|
||||
|
||||
{/* Navbar */}
|
||||
@ -82,66 +130,18 @@ export default function IndexPage() {
|
||||
<div className="max-w-6xl mx-auto text-center">
|
||||
<div className="inline-flex items-center space-x-2 px-3 py-1 rounded-full bg-violet-500/10 border border-violet-500/20 text-violet-400 text-xs font-bold uppercase tracking-widest mb-6">
|
||||
<BaseIcon path={mdiShieldCheck} size={14} />
|
||||
<span>Next-Gen Game Distribution Platform</span>
|
||||
<span>Intelligent Game Development & Distribution</span>
|
||||
</div>
|
||||
<h1 className="text-6xl md:text-8xl font-black tracking-tighter leading-none mb-8">
|
||||
PLAY THE <span className="text-transparent bg-clip-text bg-gradient-to-r from-violet-400 to-cyan-400">FUTURE</span><br/>
|
||||
OF GAMING.
|
||||
REDEFINING <span className="text-transparent bg-clip-text bg-gradient-to-r from-violet-400 to-cyan-400">PLAY</span><br/>
|
||||
WITH AI.
|
||||
</h1>
|
||||
<p className="max-w-2xl mx-auto text-lg text-slate-400 mb-10 leading-relaxed">
|
||||
Instant access to premium high-fidelity games. Powered by AI development tools and decentralized payment systems.
|
||||
Instant access to 2D and 3D premium games. Create your own gaming world with our advanced Developer AI.
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row items-center justify-center space-y-4 sm:space-y-0 sm:space-x-4">
|
||||
<BaseButton label="Explore Gallery" color="info" icon={mdiGamepadVariant} className="px-8 py-4 text-lg" href="#games" />
|
||||
<BaseButton label="AI Developer Portal" color="whiteDark" icon={mdiBrain} className="px-8 py-4 text-lg" href="/ai-developer" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* AI Developer Teaser */}
|
||||
<section className="px-6 py-20 bg-gradient-to-b from-transparent to-violet-900/10">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
|
||||
<div className="order-2 lg:order-1">
|
||||
<div className="w-16 h-16 bg-violet-600/20 rounded-2xl flex items-center justify-center mb-6">
|
||||
<BaseIcon path={mdiBrain} size={32} className="text-violet-500" />
|
||||
</div>
|
||||
<h2 className="text-4xl font-bold mb-6 italic">World's Most Advanced AI Game Creator</h2>
|
||||
<p className="text-slate-400 text-lg mb-8 leading-relaxed">
|
||||
Transform your ideas into high-quality game projects instantly. Our Intelligent Developer AI architects mechanics, design docs, and technical structures for 2D and 3D experiences.
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-6 mb-8">
|
||||
<div className="flex items-start space-x-3">
|
||||
<BaseIcon path={mdiShieldCheck} size={20} className="text-emerald-500 mt-1" />
|
||||
<div>
|
||||
<h4 className="font-bold">Rapid Prototyping</h4>
|
||||
<p className="text-xs text-slate-500">From concept to GDD in seconds.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start space-x-3">
|
||||
<BaseIcon path={mdiDeveloperBoard} size={20} className="text-cyan-500 mt-1" />
|
||||
<div>
|
||||
<h4 className="font-bold">Multi-Platform</h4>
|
||||
<p className="text-xs text-slate-500">Optimized for all modern engines.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<BaseButton label="Start Developing" color="info" icon={mdiRocketLaunch} href="/ai-developer" />
|
||||
</div>
|
||||
<div className="order-1 lg:order-2 relative">
|
||||
<div className="aspect-square bg-gradient-to-br from-violet-600/20 to-cyan-500/20 rounded-3xl border border-white/10 flex items-center justify-center overflow-hidden">
|
||||
<div className="relative w-full h-full flex items-center justify-center">
|
||||
<div className="absolute inset-0 bg-[url('https://images.pexels.com/photos/3165335/pexels-photo-3165335.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1')] bg-cover opacity-30 animate-pulse"></div>
|
||||
<div className="z-10 text-center p-8 bg-black/60 backdrop-blur-xl border border-white/10 rounded-2xl shadow-2xl">
|
||||
<BaseIcon path={mdiBrain} size={64} className="text-violet-500 mx-auto mb-4" />
|
||||
<div className="font-mono text-sm text-emerald-400 mb-2">NEURAL_NET: ACTIVE</div>
|
||||
<div className="w-48 h-1 bg-slate-800 rounded-full overflow-hidden">
|
||||
<div className="bg-violet-500 h-full w-[75%] animate-pulse"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<BaseButton label="Start Playing" color="info" icon={mdiGamepadVariant} className="px-8 py-4 text-lg" href="#games" />
|
||||
<BaseButton label="AI Studio" color="whiteDark" icon={mdiBrain} className="px-8 py-4 text-lg" href="/ai-developer" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -150,8 +150,8 @@ export default function IndexPage() {
|
||||
<section id="games" className="px-6 py-24 max-w-7xl mx-auto">
|
||||
<div className="flex flex-col md:flex-row md:items-end justify-between mb-12 space-y-6 md:space-y-0">
|
||||
<div>
|
||||
<h2 className="text-4xl font-bold mb-4 tracking-tight uppercase italic">Game <span className="text-violet-500">Gallery</span></h2>
|
||||
<p className="text-slate-400">The most curated selection of high-end experiences.</p>
|
||||
<h2 className="text-4xl font-bold mb-4 tracking-tight uppercase italic">Curated <span className="text-violet-500">Gallery</span></h2>
|
||||
<p className="text-slate-400">Unlock premium experiences with instant QR payments.</p>
|
||||
</div>
|
||||
<div className="flex items-center bg-white/5 p-1 rounded-2xl border border-white/5 overflow-x-auto whitespace-nowrap">
|
||||
<button
|
||||
@ -174,98 +174,198 @@ export default function IndexPage() {
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{filteredGames.map((game: any) => (
|
||||
<div key={game.id} className="group relative bg-white/5 rounded-3xl overflow-hidden border border-white/5 hover:border-violet-500/50 transition-all hover:-translate-y-2">
|
||||
<div
|
||||
key={game.id}
|
||||
onClick={() => setSelectedGame(game)}
|
||||
className={`group relative bg-white/5 rounded-3xl overflow-hidden border transition-all cursor-pointer ${selectedGame?.id === game.id ? 'border-violet-500 ring-4 ring-violet-500/20' : 'border-white/5 hover:border-violet-500/50'}`}
|
||||
>
|
||||
<div className="aspect-[4/5] overflow-hidden">
|
||||
<img
|
||||
src={game.game_image || 'https://images.pexels.com/photos/163036/mario-luigi-yoshi-figures-163036.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1'}
|
||||
src={game.game_image || 'https://images.pexels.com/photos/3165335/pexels-photo-3165335.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1'}
|
||||
alt={game.title}
|
||||
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110"
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black via-black/20 to-transparent p-6 flex flex-col justify-end">
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black via-black/40 to-transparent p-6 flex flex-col justify-end">
|
||||
<span className="text-[10px] font-black uppercase tracking-[0.2em] text-violet-400 mb-1">{categories.find((c: any) => c.id === game.game_categoryId)?.name || 'Premium'}</span>
|
||||
<h3 className="text-xl font-bold mb-4 group-hover:text-violet-400 transition-colors">{game.title}</h3>
|
||||
<BaseButton label="View Access" color="white" small className="w-full" icon={mdiChevronRight} />
|
||||
<h3 className="text-xl font-bold mb-2">{game.title}</h3>
|
||||
<div className="flex items-center text-xs text-slate-400">
|
||||
<BaseIcon path={mdiShieldCheck} size={14} className="mr-1 text-emerald-500" />
|
||||
Verified Content
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Payment & QR Section */}
|
||||
<section id="payment" className="px-6 py-24 bg-white/[0.02]">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-4xl font-black mb-4 uppercase italic">Instant <span className="text-cyan-400">Access</span></h2>
|
||||
<p className="text-slate-400">Choose your duration and unlock the experience via secure QR payment.</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
||||
{/* Time Passes */}
|
||||
<div className="lg:col-span-1 space-y-4">
|
||||
{timePasses.map((pass: any) => (
|
||||
<div key={pass.id} className="p-6 bg-white/5 rounded-3xl border border-white/5 hover:bg-violet-600/10 transition-colors">
|
||||
<div className="flex justify-between items-center">
|
||||
{/* Integrated Selection & Payment */}
|
||||
{selectedGame && (
|
||||
<section id="payment" className="px-6 py-24 bg-violet-950/20 border-y border-white/5">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16 items-start">
|
||||
<div>
|
||||
<div className="text-2xl font-black">{pass.duration_minutes} MIN</div>
|
||||
<div className="text-sm text-slate-500">Full Access Pass</div>
|
||||
</div>
|
||||
<div className="text-2xl font-bold text-emerald-400">${pass.price}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* QR Payment UI */}
|
||||
<div className="lg:col-span-2 bg-gradient-to-br from-violet-600/20 to-cyan-500/20 rounded-[40px] p-8 md:p-12 border border-white/10">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 items-center">
|
||||
<div>
|
||||
<h3 className="text-3xl font-bold mb-6 italic">Scan & Play</h3>
|
||||
<p className="text-slate-400 mb-8 leading-relaxed">
|
||||
Select your preferred payment method. Access is granted automatically upon network confirmation.
|
||||
</p>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center space-x-3 text-sm">
|
||||
<BaseIcon path={mdiShieldCheck} size={20} className="text-emerald-500" />
|
||||
<span>Encrypted Transaction</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-3 text-sm">
|
||||
<BaseIcon path={mdiClockOutline} size={20} className="text-cyan-500" />
|
||||
<span>Instant Activation</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center p-8 bg-black/40 backdrop-blur-2xl rounded-[32px] border border-white/10 shadow-2xl">
|
||||
<div className="grid grid-cols-2 gap-4 mb-6 w-full">
|
||||
{qrCodes.slice(0, 2).map((qr: any) => (
|
||||
<div key={qr.id} className="text-center">
|
||||
<div className="aspect-square bg-white p-2 rounded-2xl mb-2">
|
||||
<img src={qr.qr_code_image} alt={qr.payment_method} className="w-full h-full" />
|
||||
<div className="flex items-center space-x-4 mb-8">
|
||||
<div className="w-20 h-20 rounded-2xl overflow-hidden border border-white/10 shadow-2xl">
|
||||
<img src={selectedGame.game_image} alt="" className="w-full h-full object-cover" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-3xl font-black italic">{selectedGame.title}</h3>
|
||||
<p className="text-slate-400">{selectedGame.short_description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<span className="text-[10px] font-bold uppercase tracking-widest text-slate-400">{qr.payment_method}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-xs font-mono text-cyan-400 animate-pulse mb-1">WAITING FOR PAYMENT...</div>
|
||||
<div className="text-[10px] text-slate-500">Transaction ID: 0x{Math.random().toString(16).slice(2, 10).toUpperCase()}</div>
|
||||
</div>
|
||||
|
||||
{isUnlocked ? (
|
||||
<div className="bg-emerald-500/10 border border-emerald-500/20 p-8 rounded-[32px] text-center">
|
||||
<div className="w-20 h-20 bg-emerald-500 rounded-full flex items-center justify-center mx-auto mb-6 shadow-lg shadow-emerald-500/20">
|
||||
<BaseIcon path={mdiCheckCircle} size={48} color="white" />
|
||||
</div>
|
||||
<h4 className="text-2xl font-bold mb-2">Access Granted!</h4>
|
||||
<p className="text-slate-400 mb-8">You have an active pass for this game. Ready to play?</p>
|
||||
<BaseButton
|
||||
label="Launch Game Now"
|
||||
color="success"
|
||||
icon={mdiRocketLaunch}
|
||||
className="w-full py-6 text-lg rounded-2xl"
|
||||
onClick={() => window.open(selectedGame.web_play_url, '_blank')}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<h4 className="text-lg font-bold mb-6 flex items-center">
|
||||
<BaseIcon path={mdiClockOutline} size={20} className="mr-2 text-violet-400" />
|
||||
Choose Your Access Time
|
||||
</h4>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mb-8">
|
||||
{timePasses.map((pass: any) => (
|
||||
<div
|
||||
key={pass.id}
|
||||
onClick={() => setSelectedPass(pass)}
|
||||
className={`p-6 rounded-2xl border cursor-pointer transition-all ${selectedPass?.id === pass.id ? 'bg-violet-600 border-violet-400 shadow-lg shadow-violet-500/20' : 'bg-white/5 border-white/5 hover:bg-white/10'}`}
|
||||
>
|
||||
<div className="text-xl font-black">{pass.duration_days ? `${pass.duration_days} DAYS` : `${pass.duration_minutes} MIN`}</div>
|
||||
<div className="text-sm opacity-60">Full Access</div>
|
||||
<div className="mt-4 text-2xl font-bold">${pass.price}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="p-6 bg-black/40 rounded-2xl border border-white/5 flex items-center justify-between">
|
||||
<div className="flex items-center space-x-3">
|
||||
<BaseIcon path={mdiLockOutline} size={24} className="text-slate-500" />
|
||||
<span className="text-sm text-slate-400 uppercase tracking-widest font-bold">Encrypted Checkout</span>
|
||||
</div>
|
||||
<div className="text-xs text-slate-600 font-mono">ID: {guestId.slice(0, 8)}...</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{!isUnlocked && (
|
||||
<div className="bg-gradient-to-br from-violet-600/10 to-cyan-500/10 p-1 rounded-[40px] border border-white/5">
|
||||
<div className="bg-[#020617]/80 backdrop-blur-3xl rounded-[38px] p-8 md:p-12 h-full">
|
||||
<div className="text-center mb-10">
|
||||
<h3 className="text-2xl font-bold mb-2 italic">Scan to Unlock</h3>
|
||||
<p className="text-slate-400 text-sm">Select payment method below to generate QR</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-6 mb-12">
|
||||
{qrCodes.map((qr: any) => (
|
||||
<div
|
||||
key={qr.id}
|
||||
className="group relative flex flex-col items-center"
|
||||
>
|
||||
<div className="aspect-square bg-white p-3 rounded-3xl mb-4 shadow-2xl transition-transform group-hover:scale-105">
|
||||
<img src={qr.qr_code_image} alt={qr.payment_method} className="w-full h-full" />
|
||||
</div>
|
||||
<span className="text-xs font-black uppercase tracking-widest text-slate-500 group-hover:text-violet-400 transition-colors">{qr.payment_method}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="text-center">
|
||||
<div className="inline-flex items-center space-x-2 text-cyan-400 font-mono text-xs animate-pulse">
|
||||
<div className="w-1.5 h-1.5 bg-cyan-400 rounded-full"></div>
|
||||
<span>SYNCHRONIZING WITH BLOCKCHAIN...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BaseButton
|
||||
label={isPurchasing ? 'Verifying Transaction...' : 'Confirm & Verify Payment'}
|
||||
color="info"
|
||||
className="w-full py-5 rounded-2xl text-lg font-bold"
|
||||
disabled={!selectedPass || isPurchasing}
|
||||
onClick={handlePurchase}
|
||||
/>
|
||||
|
||||
<p className="text-[10px] text-center text-slate-600 uppercase tracking-widest">
|
||||
Access is granted automatically after network confirmation. No registration required.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* AI Studio Teaser */}
|
||||
<section className="px-6 py-24 bg-gradient-to-b from-transparent to-violet-900/10 border-t border-white/5">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
|
||||
<div>
|
||||
<div className="w-16 h-16 bg-violet-600/20 rounded-2xl flex items-center justify-center mb-6">
|
||||
<BaseIcon path={mdiBrain} size={32} className="text-violet-500" />
|
||||
</div>
|
||||
<h2 className="text-4xl font-black mb-6 italic tracking-tight uppercase">Intelligent Developer <span className="text-violet-500">AI</span></h2>
|
||||
<p className="text-slate-400 text-lg mb-8 leading-relaxed font-medium">
|
||||
Our advanced neural engine can generate complete game architectures. From 2D platforms to 3D shooters, the AI builds everything.
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-8 mb-10">
|
||||
<div className="space-y-2">
|
||||
<h4 className="font-bold text-violet-400">2D ENGINE</h4>
|
||||
<p className="text-xs text-slate-500">Optimized physics and sprite management.</p>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<h4 className="font-bold text-cyan-400">3D CORE</h4>
|
||||
<p className="text-xs text-slate-500">Advanced lighting and spatial mechanics.</p>
|
||||
</div>
|
||||
</div>
|
||||
<BaseButton label="Enter Developer Portal" color="info" icon={mdiRocketLaunch} href="/ai-developer" className="px-10 py-5 rounded-2xl shadow-xl shadow-violet-500/20" />
|
||||
</div>
|
||||
<div className="relative">
|
||||
<div className="aspect-video bg-slate-900 rounded-[32px] border border-white/10 overflow-hidden shadow-2xl">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-violet-600/20 to-transparent"></div>
|
||||
<img src="https://images.pexels.com/photos/163036/mario-luigi-yoshi-figures-163036.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" className="w-full h-full object-cover opacity-40 grayscale" />
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div className="p-8 bg-black/60 backdrop-blur-2xl border border-white/10 rounded-3xl text-center">
|
||||
<div className="font-mono text-[10px] text-emerald-400 mb-4 tracking-[0.3em]">AI_PROCESSING_SEQUENCE</div>
|
||||
<div className="space-y-2">
|
||||
<div className="h-1 w-48 bg-slate-800 rounded-full overflow-hidden">
|
||||
<div className="h-full bg-violet-500 w-[85%] animate-pulse"></div>
|
||||
</div>
|
||||
<div className="h-1 w-48 bg-slate-800 rounded-full overflow-hidden">
|
||||
<div className="h-full bg-cyan-500 w-[60%] animate-pulse delay-75"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Footer */}
|
||||
<footer className="px-6 py-12 border-t border-white/5 text-center">
|
||||
<footer className="px-6 py-12 border-t border-white/5 text-center bg-black">
|
||||
<div className="flex items-center justify-center space-x-2 mb-6">
|
||||
<div className="w-8 h-8 bg-violet-600 rounded-lg flex items-center justify-center">
|
||||
<BaseIcon path={mdiGamepadVariant} size={18} color="white" />
|
||||
</div>
|
||||
<span className="text-lg font-black tracking-tighter uppercase italic">Nexus<span className="text-violet-500">Games</span></span>
|
||||
</div>
|
||||
<p className="text-slate-500 text-sm">© 2026 Nexus Gaming Platform. Powered by Intelligent Developer AI.</p>
|
||||
<p className="text-slate-500 text-xs tracking-widest uppercase">© 2026 Nexus Gaming Platform • Intelligent Developer AI Integration</p>
|
||||
</footer>
|
||||
</div>
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user