import React, { useContext, useEffect, useState, useRef } from 'react';
import { motion, useMotionValue, useSpring } from 'framer-motion';
import { DndContext } from '../../context/DndContext';
import DndNavbar from './DndNavbar';
import DndFooter from './DndFooter';
import dndWallpapers from '../../utils/dndWallpapers';
import { parseWallpaperName } from '../../utils/dndUtils';
import '../../styles/dnd-refactor.css';
import { GameController, Flame, TreasureChest } from '@phosphor-icons/react';
import { useToast } from '../../hooks/useToast';
const Lightning = () =>
;
const LootDiscovery = () => {
const { addToast } = useToast();
const [showLoot, setShowLoot] = useState(false);
const [lootPos, setLootPos] = useState({ top: '50%', left: '50%' });
useEffect(() => {
const interval = setInterval(() => {
// 50% chance every 15 seconds
if (Math.random() > 0.5) {
setLootPos({
top: `${30 + Math.random() * 40}%`,
left: `${20 + Math.random() * 60}%`,
});
setShowLoot(true);
setTimeout(() => setShowLoot(false), 8000); // Hide after 8s
}
}, 15000);
return () => clearInterval(interval);
}, []);
if (!showLoot) return null;
return (
{
const currentCount = parseInt(
localStorage.getItem('fezcodex_loot_count') || '0',
10,
);
const newCount = currentCount + 1;
localStorage.setItem('fezcodex_loot_count', newCount.toString());
addToast({
title: 'Loot Discovered!',
message: `You found an ancient relic in the archives. (Total Found: ${newCount})`,
type: 'gold',
});
setShowLoot(false);
}}
className="fixed z-[150] dnd-loot-item text-dnd-gold"
style={{ top: lootPos.top, left: lootPos.left }}
>
);
};
const FireplaceAudio = () => {
const [isPlaying, setIsPlaying] = useState(false);
const audioRef = useRef(null);
const toggleAudio = () => {
if (isPlaying) {
audioRef.current.pause();
} else {
audioRef.current.play();
}
setIsPlaying(!isPlaying);
};
return (
);
};
const FireOverlay = () => ;
const DustMotes = () => (
{[...Array(20)].map((_, i) => (
))}
);
const FloatingRunes = () => {
const runes = [
'ᚠ',
'ᚢ',
'ᚦ',
'ᚨ',
'ᚱ',
'ᚲ',
'ᚷ',
'ᚹ',
'ᚺ',
'ᚾ',
'ᛁ',
'ᛃ',
'ᛈ',
'ᛇ',
'ᛉ',
'ᛊ',
'ᛏ',
'ᛒ',
'ᛖ',
'ᛗ',
'ᛚ',
'ᛜ',
'ᛞ',
'ᛟ',
];
return (
{[...Array(20)].map((_, i) => (
{runes[Math.floor(Math.random() * runes.length)]}
))}
);
};
const ViewportFrame = () => (
<>
>
);
const FireParticles = () => {
const colors = [
'radial-gradient(circle, #ff4500 0%, #ff8c00 70%, transparent 100%)', // Red-Orange
'radial-gradient(circle, #ff8c00 0%, #ffd700 70%, transparent 100%)', // Orange-Gold
'radial-gradient(circle, #ff0000 0%, #ff4500 70%, transparent 100%)', // Pure Red
];
return (
{[...Array(50)].map((_, i) => {
const size = 3 + Math.random() * 8;
return (
);
})}
);
};
const Torchlight = () => {
const mouseX = useMotionValue(0);
const mouseY = useMotionValue(0);
const springX = useSpring(mouseX, { damping: 50, stiffness: 200 });
const springY = useSpring(mouseY, { damping: 50, stiffness: 200 });
useEffect(() => {
const handleMouseMove = (e) => {
mouseX.set(e.clientX);
mouseY.set(e.clientY);
};
window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
}, [mouseX, mouseY]);
return (
);
};
const DiceRoller = () => {
const [roll, setRoll] = useState(null);
const [isRolling, setIsRolling] = useState(false);
const rollDice = () => {
setIsRolling(true);
setTimeout(() => {
setRoll(Math.floor(Math.random() * 20) + 1);
setIsRolling(false);
}, 600);
};
return (
{roll !== null && (
{roll === 20
? 'CRITICAL SUCCESS!'
: roll === 1
? 'CRITICAL FAILURE...'
: `YOU ROLLED: ${roll}`}
)}
);
};
const DndLayout = ({ children }) => {
const {
setBgImageName,
isLightningEnabled,
isLootDiscoveryEnabled,
isFireOverlayEnabled,
isFireParticlesEnabled,
isViewportFrameEnabled,
} = useContext(DndContext);
const [bgImage, setBgImage] = useState('');
useEffect(() => {
const randomImage =
dndWallpapers[Math.floor(Math.random() * dndWallpapers.length)];
setBgImage(randomImage);
setBgImageName(parseWallpaperName(randomImage.split('/').pop()));
}, [setBgImageName]);
return (
{isViewportFrameEnabled && }
{isLightningEnabled && }
{isLootDiscoveryEnabled && }
{isFireOverlayEnabled && }
{isFireParticlesEnabled && }
{/* Immersive Background */}
{/* Content Layer */}
{children}
{/* Global Vignette */}
);
};
export default DndLayout;