Migrate Tír na nÓg landing page to Next.js
Summary of changes: - Created the 'feature/migration-nextjs' branch. - Initialized a Next.js project with React components and App Router structure. - Created reusable UI components: Viewport, World, Room, and Door in 'app/components/'. - Implemented spatial navigation logic (WASD/Arrows and clicks) using React 'useState' and 'useEffect' in 'app/page.js'. - Migrated the Tír na nÓg pixel-art aesthetic and layout transitions into 'app/globals.css'. - Configured a Gitea Runner CI/CD workflow in '.gitea/workflows/deploy.yml' for automated builds and linting. - Added a '.gitignore' file to manage project artifacts. Co-authored-by: micmug <185775013+micmug@users.noreply.github.com>
This commit is contained in:
+70
@@ -0,0 +1,70 @@
|
||||
'use client';
|
||||
import { useState, useEffect } from 'react';
|
||||
import Viewport from './components/Viewport';
|
||||
import World from './components/World';
|
||||
import Room from './components/Room';
|
||||
import Door from './components/Door';
|
||||
export default function Home() {
|
||||
const [currentPos, setCurrentPos] = useState({ x: 0, y: 0 });
|
||||
const gridSize = { width: 2, height: 2 };
|
||||
const navigateTo = (targetStr) => {
|
||||
const [x, y] = targetStr.split(',').map(Number);
|
||||
if (!isNaN(x) && !isNaN(y)) { setCurrentPos({ x, y }); }
|
||||
};
|
||||
const moveRelative = (dx, dy) => {
|
||||
setCurrentPos((prev) => {
|
||||
const newX = prev.x + dx;
|
||||
const newY = prev.y + dy;
|
||||
if (newX >= 0 && newX < gridSize.width && newY >= 0 && newY < gridSize.height) {
|
||||
return { x: newX, y: newY };
|
||||
}
|
||||
return prev;
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e) => {
|
||||
switch (e.key.toLowerCase()) {
|
||||
case 'arrowup': case 'w': moveRelative(0, -1); break;
|
||||
case 'arrowdown': case 's': moveRelative(0, 1); break;
|
||||
case 'arrowleft': case 'a': moveRelative(-1, 0); break;
|
||||
case 'arrowright': case 'd': moveRelative(1, 0); break;
|
||||
}
|
||||
};
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
return () => window.removeEventListener('keydown', handleKeyDown);
|
||||
}, []);
|
||||
return (
|
||||
<Viewport>
|
||||
<World currentPos={currentPos}>
|
||||
<Room id="room-0-0" isActive={currentPos.x === 0 && currentPos.y === 0}>
|
||||
<div className="content"><h1>Tír na nÓg</h1><p>Welcome to the Land of Eternal Youth.</p></div>
|
||||
<div className="doors">
|
||||
<Door direction="east" target="1,0" label="To the Meadow →" onNavigate={navigateTo} />
|
||||
<Door direction="south" target="0,1" label="Down the Alleys ↓" onNavigate={navigateTo} />
|
||||
</div>
|
||||
</Room>
|
||||
<Room id="room-1-0" isActive={currentPos.x === 1 && currentPos.y === 0}>
|
||||
<div className="content"><h2>The Meadow</h2><p>Where pixels bloom and legends grow.</p></div>
|
||||
<div className="doors">
|
||||
<Door direction="west" target="0,0" label="← Back to the Gate" onNavigate={navigateTo} />
|
||||
<Door direction="south" target="1,1" label="To the Portal ↓" onNavigate={navigateTo} />
|
||||
</div>
|
||||
</Room>
|
||||
<Room id="room-0-1" isActive={currentPos.x === 0 && currentPos.y === 1}>
|
||||
<div className="content"><h2>The Alleys</h2><p>Navigating the narrow paths of creation.</p></div>
|
||||
<div className="doors">
|
||||
<Door direction="north" target="0,0" label="↑ Up to the Gate" onNavigate={navigateTo} />
|
||||
<Door direction="east" target="1,1" label="To the Portal →" onNavigate={navigateTo} />
|
||||
</div>
|
||||
</Room>
|
||||
<Room id="room-1-1" isActive={currentPos.x === 1 && currentPos.y === 1}>
|
||||
<div className="content"><h2>The Portal</h2><p>Step through to join the faebits.</p></div>
|
||||
<div className="doors">
|
||||
<Door direction="north" target="1,0" label="↑ Up to the Meadow" onNavigate={navigateTo} />
|
||||
<Door direction="west" target="0,1" label="← Back to the Alleys" onNavigate={navigateTo} />
|
||||
</div>
|
||||
</Room>
|
||||
</World>
|
||||
</Viewport>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user