Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/app/components/ChatInterface.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { FC } from 'react';
import { Plus, Search, Mic, MoreHorizontal } from 'lucide-react';

const ChatInterface: FC = () => {
return (
<div className="flex-1 flex flex-col h-full">
{/* Chat Messages Area */}
<div className="flex-1 overflow-y-auto">
<div className="max-w-3xl mx-auto py-4 px-6">
{/* Messages would go here */}
<div className="flex justify-center items-center h-full text-white text-lg">
What can I help with?
</div>
</div>
</div>

{/* Input Area */}
<div className="border-t border-gray-700 p-4">
<div className="max-w-3xl mx-auto">
<div className="relative">
<div className="flex items-center bg-[#40414f] rounded-lg border border-gray-700">
<button className="p-2 hover:bg-gray-700 rounded-l-lg">
<Plus className="w-5 h-5 text-gray-400" />
</button>

<textarea
rows={1}
className="flex-1 bg-transparent border-0 outline-none resize-none py-3 px-2 text-white placeholder-gray-400"
placeholder="Ask anything"
/>

<div className="flex items-center gap-1 pr-2">
<button className="p-2 hover:bg-gray-700 rounded-lg">
<Search className="w-5 h-5 text-gray-400" />
</button>
<button className="p-2 hover:bg-gray-700 rounded-lg">
<Mic className="w-5 h-5 text-gray-400" />
</button>
<button className="p-2 hover:bg-gray-700 rounded-lg">
<MoreHorizontal className="w-5 h-5 text-gray-400" />
</button>
</div>
</div>
<div className="text-xs text-center text-gray-400 mt-2">
ChatGPT can make mistakes. Check important info.
</div>
</div>
</div>
</div>
</div>
);
};

export default ChatInterface;
117 changes: 117 additions & 0 deletions src/app/components/GameCanvas.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
'use client';

import { useEffect, useRef } from 'react';
import { useGameState } from '../hooks/useGameState';

const GameCanvas = () => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const { gameState, updateGameState } = useGameState();

useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;

const ctx = canvas.getContext('2d');
if (!ctx) return;

// Set canvas size
const setCanvasSize = () => {
const container = canvas.parentElement;
if (!container) return;
canvas.width = container.clientWidth;
canvas.height = container.clientHeight;
};

// Initial size setup
setCanvasSize();
window.addEventListener('resize', setCanvasSize);

// Game loop
let animationFrameId: number;

const render = () => {
// Clear canvas
ctx.fillStyle = '#1a1a1a';
ctx.fillRect(0, 0, canvas.width, canvas.height);

// Draw game elements
drawCharacters(ctx);
drawEnvironment(ctx);

// Update game state
updateGameState();

// Continue game loop
animationFrameId = requestAnimationFrame(render);
};

render();

return () => {
window.removeEventListener('resize', setCanvasSize);
cancelAnimationFrame(animationFrameId);
};
}, [updateGameState]);

const drawCharacters = (ctx: CanvasRenderingContext2D) => {
Object.values(gameState.characters).forEach((char) => {
// Save context state
ctx.save();

// Set character color
ctx.strokeStyle = char.id;
ctx.lineWidth = 2;

// Draw stick figure
ctx.beginPath();

// Head
ctx.arc(char.x, char.y - 20, 10, 0, Math.PI * 2);

// Body
ctx.moveTo(char.x, char.y - 10);
ctx.lineTo(char.x, char.y + 20);

// Arms
ctx.moveTo(char.x - 15, char.y);
ctx.lineTo(char.x + 15, char.y);

// Legs
ctx.moveTo(char.x, char.y + 20);
ctx.lineTo(char.x - 10, char.y + 40);
ctx.moveTo(char.x, char.y + 20);
ctx.lineTo(char.x + 10, char.y + 40);

// Draw the figure
ctx.stroke();

// Restore context state
ctx.restore();
});
};

const drawEnvironment = (ctx: CanvasRenderingContext2D) => {
// Draw ground
ctx.fillStyle = '#333';
ctx.fillRect(0, 450, ctx.canvas.width, 5);

// Draw background elements
ctx.fillStyle = '#222';
for (let i = 0; i < 5; i++) {
const x = Math.random() * ctx.canvas.width;
const y = Math.random() * 400;
const size = Math.random() * 20 + 10;
ctx.fillRect(x, y, size, size);
}
};

return (
<canvas
ref={canvasRef}
className="absolute inset-0 w-full h-full"
style={{ imageRendering: 'pixelated' }}
/>
);
};

export default GameCanvas;
50 changes: 50 additions & 0 deletions src/app/components/GameUI.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
'use client';

import { useState } from 'react';
import { useGameState } from '../hooks/useGameState';

const GameUI = () => {
const [selectedCharacter, setSelectedCharacter] = useState('red');
const { gameState } = useGameState();

const characters = [
{ id: 'red', name: 'Red', color: '#ff0000' },
{ id: 'blue', name: 'Blue', color: '#0000ff' },
{ id: 'green', name: 'Green', color: '#00ff00' },
{ id: 'yellow', name: 'Yellow', color: '#ffff00' },
{ id: 'purple', name: 'Purple', color: '#800080' },
];

return (
<div className="absolute bottom-0 left-0 right-0 p-4">
{/* Character Selection */}
<div className="flex justify-center gap-4 mb-4">
{characters.map((char) => (
<button
key={char.id}
className={`w-12 h-12 rounded-full transition-transform ${
selectedCharacter === char.id ? 'scale-110 ring-2 ring-white' : ''
}`}
style={{ backgroundColor: char.color }}
onClick={() => setSelectedCharacter(char.id)}
/>
))}
</div>

{/* Controls */}
<div className="flex justify-center gap-4">
<div className="bg-black/50 backdrop-blur-sm p-4 rounded-lg">
<div className="text-white text-sm mb-2">Controls:</div>
<div className="text-gray-300 text-xs">
<div>WASD - Move</div>
<div>SPACE - Jump/Special</div>
<div>E - Interact</div>
<div>Q - Switch Character</div>
</div>
</div>
</div>
</div>
);
};

export default GameUI;
44 changes: 44 additions & 0 deletions src/app/components/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { FC } from 'react';
import { Plus, Search, Folder, Clock, Settings } from 'lucide-react';

const Sidebar: FC = () => {
return (
<div className="flex flex-col w-[260px] h-full bg-[#202123] text-white">
{/* New Chat Button */}
<div className="p-2">
<button className="w-full flex items-center gap-2 rounded p-3 hover:bg-gray-700 transition-colors text-sm">
<Plus size={16} />
New chat
</button>
</div>

{/* Chat History */}
<div className="flex-1 overflow-y-auto">
<div className="px-2 py-2">
<div className="text-xs text-gray-500 font-medium mb-2 px-2">Today</div>
{/* Chat items would go here */}
</div>
</div>

{/* Projects Section */}
<div className="px-2 py-2 border-t border-gray-700">
<div className="text-xs text-gray-500 font-medium mb-2 px-2">Projects</div>
<button className="w-full flex items-center gap-2 rounded p-2 hover:bg-gray-700 transition-colors text-sm">
<Folder size={16} />
Business with Marc
</button>
{/* More project items */}
</div>

{/* Bottom Section */}
<div className="p-2 border-t border-gray-700">
<button className="w-full flex items-center gap-2 rounded p-2 hover:bg-gray-700 transition-colors text-sm">
<Settings size={16} />
Settings
</button>
</div>
</div>
);
};

export default Sidebar;
69 changes: 53 additions & 16 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,64 @@
@tailwind utilities;

:root {
--foreground-rgb: 0, 0, 0;
--background-start-rgb: 214, 219, 220;
--background-end-rgb: 255, 255, 255;
--foreground-rgb: 255, 255, 255;
--background-rgb: 26, 26, 26;
}

@media (prefers-color-scheme: dark) {
:root {
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
body {
color: rgb(var(--foreground-rgb));
background: rgb(var(--background-rgb));
overflow: hidden;
}

/* Game specific styles */
.pixel-art {
image-rendering: pixelated;
image-rendering: crisp-edges;
}

/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}

::-webkit-scrollbar-track {
background: transparent;
}

::-webkit-scrollbar-thumb {
background: #4b5563;
border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
background: #6b7280;
}

/* Animation keyframes */
@keyframes float {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}

body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
.float {
animation: float 2s ease-in-out infinite;
}

/* Character selection glow effect */
.character-glow {
filter: drop-shadow(0 0 8px currentColor);
}

/* Textarea autoresize */
textarea {
min-height: 24px;
max-height: 200px;
}

@layer utilities {
Expand Down
Loading