diff --git a/src/app/components/ChatInterface.tsx b/src/app/components/ChatInterface.tsx
new file mode 100644
index 00000000..59ee69f2
--- /dev/null
+++ b/src/app/components/ChatInterface.tsx
@@ -0,0 +1,54 @@
+import { FC } from 'react';
+import { Plus, Search, Mic, MoreHorizontal } from 'lucide-react';
+
+const ChatInterface: FC = () => {
+ return (
+
+ {/* Chat Messages Area */}
+
+
+ {/* Messages would go here */}
+
+ What can I help with?
+
+
+
+
+ {/* Input Area */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ChatGPT can make mistakes. Check important info.
+
+
+
+
+
+ );
+};
+
+export default ChatInterface;
\ No newline at end of file
diff --git a/src/app/components/GameCanvas.tsx b/src/app/components/GameCanvas.tsx
new file mode 100644
index 00000000..6660a495
--- /dev/null
+++ b/src/app/components/GameCanvas.tsx
@@ -0,0 +1,117 @@
+'use client';
+
+import { useEffect, useRef } from 'react';
+import { useGameState } from '../hooks/useGameState';
+
+const GameCanvas = () => {
+ const canvasRef = useRef(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 (
+
+ );
+};
+
+export default GameCanvas;
\ No newline at end of file
diff --git a/src/app/components/GameUI.tsx b/src/app/components/GameUI.tsx
new file mode 100644
index 00000000..077bb9f0
--- /dev/null
+++ b/src/app/components/GameUI.tsx
@@ -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 (
+
+ {/* Character Selection */}
+
+ {characters.map((char) => (
+ setSelectedCharacter(char.id)}
+ />
+ ))}
+
+
+ {/* Controls */}
+
+
+
Controls:
+
+
WASD - Move
+
SPACE - Jump/Special
+
E - Interact
+
Q - Switch Character
+
+
+
+
+ );
+};
+
+export default GameUI;
\ No newline at end of file
diff --git a/src/app/components/Sidebar.tsx b/src/app/components/Sidebar.tsx
new file mode 100644
index 00000000..5b21ad61
--- /dev/null
+++ b/src/app/components/Sidebar.tsx
@@ -0,0 +1,44 @@
+import { FC } from 'react';
+import { Plus, Search, Folder, Clock, Settings } from 'lucide-react';
+
+const Sidebar: FC = () => {
+ return (
+
+ {/* New Chat Button */}
+
+
+ {/* Chat History */}
+
+
+
Today
+ {/* Chat items would go here */}
+
+
+
+ {/* Projects Section */}
+
+
Projects
+
+
+ Business with Marc
+
+ {/* More project items */}
+
+
+ {/* Bottom Section */}
+
+
+
+ Settings
+
+
+
+ );
+};
+
+export default Sidebar;
\ No newline at end of file
diff --git a/src/app/globals.css b/src/app/globals.css
index 875c01e8..16883328 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -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 {
diff --git a/src/app/hooks/useGameState.ts b/src/app/hooks/useGameState.ts
new file mode 100644
index 00000000..87100f4b
--- /dev/null
+++ b/src/app/hooks/useGameState.ts
@@ -0,0 +1,127 @@
+import { useState, useCallback, useEffect } from 'react';
+
+interface Character {
+ id: string;
+ x: number;
+ y: number;
+ velocityX: number;
+ velocityY: number;
+ isJumping: boolean;
+ specialAbility: string;
+}
+
+interface GameState {
+ characters: Record;
+ activeCharacter: string;
+ score: number;
+}
+
+export const useGameState = () => {
+ const [gameState, setGameState] = useState({
+ characters: {
+ red: {
+ id: 'red',
+ x: 100,
+ y: 100,
+ velocityX: 0,
+ velocityY: 0,
+ isJumping: false,
+ specialAbility: 'multiply',
+ },
+ blue: {
+ id: 'blue',
+ x: 200,
+ y: 100,
+ velocityX: 0,
+ velocityY: 0,
+ isJumping: false,
+ specialAbility: 'fly',
+ },
+ // Add more characters with their initial positions and abilities
+ },
+ activeCharacter: 'red',
+ score: 0,
+ });
+
+ const handleKeyPress = useCallback((event: KeyboardEvent) => {
+ const { key } = event;
+ const character = gameState.characters[gameState.activeCharacter];
+
+ setGameState((prev) => {
+ const updatedCharacter = { ...character };
+
+ switch (key.toLowerCase()) {
+ case 'w':
+ if (!updatedCharacter.isJumping) {
+ updatedCharacter.velocityY = -10;
+ updatedCharacter.isJumping = true;
+ }
+ break;
+ case 'a':
+ updatedCharacter.velocityX = -5;
+ break;
+ case 'd':
+ updatedCharacter.velocityX = 5;
+ break;
+ case 's':
+ // Implement crouch or special down action
+ break;
+ case ' ':
+ // Implement special ability
+ break;
+ }
+
+ return {
+ ...prev,
+ characters: {
+ ...prev.characters,
+ [gameState.activeCharacter]: updatedCharacter,
+ },
+ };
+ });
+ }, [gameState]);
+
+ const updateGameState = useCallback(() => {
+ setGameState((prev) => {
+ const updatedCharacters = { ...prev.characters };
+
+ // Update each character's position and physics
+ Object.keys(updatedCharacters).forEach((charId) => {
+ const char = updatedCharacters[charId];
+
+ // Apply gravity
+ char.velocityY += 0.5;
+
+ // Update position
+ char.x += char.velocityX;
+ char.y += char.velocityY;
+
+ // Ground collision
+ if (char.y > 400) {
+ char.y = 400;
+ char.velocityY = 0;
+ char.isJumping = false;
+ }
+
+ // Apply friction
+ char.velocityX *= 0.9;
+ });
+
+ return {
+ ...prev,
+ characters: updatedCharacters,
+ };
+ });
+ }, []);
+
+ // Set up keyboard event listeners
+ useEffect(() => {
+ window.addEventListener('keydown', handleKeyPress);
+ return () => window.removeEventListener('keydown', handleKeyPress);
+ }, [handleKeyPress]);
+
+ return {
+ gameState,
+ updateGameState,
+ };
+};
\ No newline at end of file
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 3ca8f2da..ed303c37 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,13 +1,26 @@
-import "./globals.css";
+import type { Metadata } from 'next'
+import { Inter } from 'next/font/google'
+import './globals.css'
+
+const inter = Inter({ subsets: ['latin'] })
+
+export const metadata: Metadata = {
+ title: 'ChatGPT Clone',
+ description: 'A ChatGPT clone built with Next.js',
+}
export default function RootLayout({
children,
}: {
- children: React.ReactNode;
+ children: React.ReactNode
}) {
return (
- {children}
+
+
+ {children}
+
+
- );
+ )
}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index a41c2cd2..e417628a 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,47 +1,12 @@
-import Link from "next/link";
+import GameCanvas from './components/GameCanvas';
+import GameUI from './components/GameUI';
export default function Home() {
return (
-
-
-
- Get started by choosing a template path from the /paths/ folder.
-
-
-
-
Make anything you imagine 🪄
-
- This whole page will be replaced when you run your template path.
-
-
-
-
-
AI Chat App
-
- An intelligent conversational app powered by AI models, featuring real-time responses
- and seamless integration with Next.js and various AI providers.
-
-
-
-
AI Image Generation App
-
- Create images from text prompts using AI, powered by the Replicate API and Next.js.
-
-
-
-
Social Media App
-
- A feature-rich social platform with user profiles, posts, and interactions using
- Firebase and Next.js.
-
-
-
-
Voice Notes App
-
- A voice-based note-taking app with real-time transcription using Deepgram API,
- Firebase integration for storage, and a clean, simple interface built with Next.js.
-
-
+
+
+
+
);