Skip to content
Merged
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
Binary file added client/avatars/drdan2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified client/background/codezilla_bkgd.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/minions/pie-thon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3,032 changes: 391 additions & 2,641 deletions client/package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
Expand All @@ -20,7 +20,7 @@
"react": "^19.0.0",
"react-dom": "^19.0.0",

"react-howler": "^5.2.0"
"react-howler": "^5.2.0",

"react-router-dom": "^7.5.2"

Expand Down
Binary file added client/public/codezilla_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 41 additions & 9 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { BrowserRouter as Router, Routes, Route, useNavigate } from 'react-router-dom';
import { Login } from './components/screens/Login';
import GameMap from './components/screens/GameMap';
import GameOver from './components/screens/GameOver';
Expand All @@ -9,20 +9,52 @@ import Questions from './components/screens/Questions';

import './styles/codezilla.css';

const LogoutButton: React.FC = () => {
const navigate = useNavigate();

const handleLogout = () => {
localStorage.clear();
navigate('/signup');
};

return (
<button className="logout-button" onClick={handleLogout}>
Logout
</button>
);
};

const App: React.FC = () => {
return (
<Router>
<Routes>
<Route path="/" element={<Login />} />
<Route path="/map" element={<GameMap />} />
<Route path="/gameover" element={<GameOver />} />
<Route path="/signup" element={<Signup />} />
<Route path="/victory" element={<Victory />} />
<Route path="/question/:id" element={<Questions />} />
<div className="app-wrapper">
{/* Background Image */}
<img
src="/background/codezilla_bkgd.png"
alt="Dark rainy cityscape"
className="background-image"
/>

{/* Logo */}
<img
src="/codezilla_logo.png"
alt="Codezilla Logo"
className="logo-background"
/>

{/* Logout Button */}
<LogoutButton />

</Routes>
{/* Routes */}
<Routes>
<Route path="/" element={<Login />} />
<Route path="/map" element={<GameMap />} />
<Route path="/gameover" element={<GameOver />} />
<Route path="/signup" element={<Signup />} />
<Route path="/victory" element={<Victory />} />
<Route path="/question/:id" element={<Questions />} />
</Routes>
</div>
</Router>
);
};
Expand Down
Binary file added client/src/assets/flame.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 changes: 53 additions & 7 deletions client/src/components/screens/GameMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@
// src/components/screens/GameMap.tsx

// IMPORT LIBRARIES
import * as React from 'react';

import React, { useState } from 'react';

import { useNavigate } from 'react-router-dom';
import Minion from './Minions';
import "../../styles/codezilla.css";
import drDanImg from '../../../avatars/drdan2.png';
import flameImg from '../../assets/flame.png';

const selectedAvatar = localStorage.getItem('selectedAvatar');
const username = localStorage.getItem('username') || 'Player';

const GameMap: React.FC = () => {
const navigate = useNavigate();
const [completedPaths, setCompletedPaths] = useState<string[]>([]);
const [selectedMinionId, setSelectedMinionId] = useState<string | null>(null);

const minions = [
{
Expand Down Expand Up @@ -41,9 +45,9 @@ const GameMap: React.FC = () => {
},
{
id: '4',
xPercent: 72,
yPercent: 50,
image: '/minions/monster-left.png',
xPercent: 70,
yPercent: 45,
image: '/minions/pie-thon.png',
name: 'Pie-Thon',
questionId: 'q4',
},
Expand Down Expand Up @@ -78,7 +82,10 @@ const GameMap: React.FC = () => {
const pathId = `${nodes[currentIndex].id}-${nodes[currentIndex + 1].id}`;
setCompletedPaths(prev => [...prev, pathId]);
}

const minion = minions.find(m => m.questionId === questionId);
if (minion) {
setSelectedMinionId(minion.id);
}
navigate(`/question/${questionId}`);
};

Expand All @@ -103,7 +110,7 @@ const GameMap: React.FC = () => {
/>
);
})}

{/* GLOWING OUTER CIRCLE + DARKER INNER CIRCLE */}
{nodes.map((node, index) => {
const isCompleted = index < completedPaths.length;
Expand All @@ -128,6 +135,42 @@ const GameMap: React.FC = () => {
);
})}
</svg>
<div className="dr-dan-wrapper">
<div className="glow-circle"></div>
<img src={drDanImg} alt="Dr. Dan" className="dr-dan-image" />
</div>

{selectedAvatar && (
<div className="player-avatar-wrapper">
<div className="player-glow-circle"></div>
<img src={selectedAvatar} alt="Your Avatar" className="player-avatar" />


<div className="player-info-wrapper">
<div className="player-info-box">
<p className="player-name">{username}</p>
<p className="player-level">Level 1</p>
</div>

<div className="learning-info-box">
<p className='learning-title'> Studying</p>
<p className="learning-text">Coding Bootcamp</p>
</div>
{/* Lifeline Box */}
<div className='flames'>
<div className="lifeline-info-box">
<div className="lifeline-flames">
<p className='learning-title'> Life Lines</p>
<img src={flameImg} alt="Flame 1" />
<img src={flameImg} alt="Flame 2" />
<img src={flameImg} alt="Flame 3" />
</div>
</div>
</div>
</div>
</div>
)}


{/* MINIONS */}
{minions.map((minion) => (
Expand All @@ -140,8 +183,11 @@ const GameMap: React.FC = () => {
name={minion.name}
questionId={minion.questionId}
goToQuestion={goToQuestion}
size={120}
selectedMinionId={selectedMinionId}
/>
))}

</div>
);
};
Expand Down
9 changes: 7 additions & 2 deletions client/src/components/screens/Minions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ interface MinionProps {
name: string;
questionId: string;
goToQuestion: (questionId: string) => void;
size: number,
size: number;
selectedMinionId: string | null;
}

const Minion: React.FC<MinionProps> = ({
Expand All @@ -19,12 +20,15 @@ const Minion: React.FC<MinionProps> = ({
name,
questionId,
goToQuestion,
selectedMinionId,
}) => {
const isSelected = selectedMinionId === id;

return (
<div
id={`minion-${id}`}
className="minion"
className={`minion ${isSelected ? 'selected' : ''}`}

style={{
position: 'absolute',
top: `${yPercent}%`,
Expand All @@ -41,6 +45,7 @@ const Minion: React.FC<MinionProps> = ({
<img
src={image}
alt={name}
className='minion-image'
style={{
width: '100%',
height: '100%',
Expand Down
49 changes: 37 additions & 12 deletions client/src/components/screens/Signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,20 @@ const SignUp: React.FC = () => {

const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();

if (!username.trim() || !selectedAvatar) {
alert('Please enter a username and select an avatar before proceeding.');
return;
}

localStorage.setItem('selectedAvatar', selectedAvatar);
localStorage.setItem('username', username);

console.log({ username, password, selectedAvatar });
navigate('/map');
};



return (
<div className="login-wrapper">
Expand All @@ -42,18 +53,32 @@ const SignUp: React.FC = () => {
onChange={(e) => setPassword(e.target.value)}
/>

<p>Select Your Avatar</p>
<div className="avatar-grid">
{avatarList.map((avatar, index) => (
<img
key={index}
src={avatar}
alt={`Avatar ${index}`}
className={`avatar-option ${selectedAvatar === avatar ? 'selected' : ''}`}
onClick={() => setSelectedAvatar(avatar)}
/>
))}
</div>
<p>Select Your Avatar</p>
<div className="avatar-grid">
<div className="avatar-row">
{avatarList.slice(0, 3).map((avatar, index) => (
<img
key={index}
src={avatar}
alt={`Avatar ${index}`}
className={`avatar-option ${selectedAvatar === avatar ? 'selected' : ''}`}
onClick={() => setSelectedAvatar(avatar)}
/>
))}
</div>
<div className="avatar-row">
{avatarList.slice(3).map((avatar, index) => (
<img
key={index + 3}
src={avatar}
alt={`Avatar ${index + 3}`}
className={`avatar-option ${selectedAvatar === avatar ? 'selected' : ''}`}
onClick={() => setSelectedAvatar(avatar)}
/>
))}
</div>
</div>


<button className="signup-button" type="submit">Enter the Game</button>
</form>
Expand Down
Loading
Loading