Tell us what’s happening:
I can’t get test 4 to pass. (4. When the input is given a value and the button is pressed, the form should no longer be visible).
I’ve tried many methods for the form view to game view switch but the test isn’t picking up on it. Therefore most of the tests after 4 also keep failing.
Your code so far
/* file: index.tsx */
const { useState } = React;
export enum PetAction {
EAT = 'EAT',
PLAY = 'PLAY',
SLEEP = 'SLEEP',
}
export enum PetMood {
Happy = 'Happy',
Excited = 'Excited',
Content = 'Content',
Sad = 'Sad',
Tired = 'Tired',
Sick = 'Sick',
Hungry = 'Hungry',
}
export const MOOD_VISUALS: Record<PetMood, string> = {
[PetMood.Happy]: '😀',
[PetMood.Excited]: '🤩',
[PetMood.Content]: '🙂',
[PetMood.Sad]: '😢',
[PetMood.Tired]: '🥱',
[PetMood.Sick]: '🤢',
[PetMood.Hungry]: '🤤',
};
interface PetStats {
hunger: number;
happiness: number;
energy: number;
}
export const PetGame = () => {
const [isGameStarted, setIsGameStarted] = useState<boolean>(false);
const [petName, setPetName] = useState<string>('');
const [errorMsg, setErrorMsg] = useState<string>('');
const [stats, setStats] = useState<PetStats>({
hunger: 50,
happiness: 50,
energy: 50,
});
const handleSubmit = (e: React.FormEvent<HTMLFormElement>): void => {
e.preventDefault();
if (petName.trim() === '') {
setErrorMsg('Please name your pet before starting.');
return;
}
setErrorMsg('');
setIsGameStarted(true);
};
const clamp = (val: number): number => Math.max(0, Math.min(100, val));
const handleAction = (action: PetAction): void => {
setStats((prev) => {
switch (action) {
case PetAction.EAT:
return {
...prev,
hunger: clamp(prev.hunger - 15),
energy: clamp(prev.energy + 10),
};
case PetAction.PLAY:
return {
...prev,
energy: clamp(prev.energy - 15),
happiness: clamp(prev.happiness + 20),
};
case PetAction.SLEEP:
return {
...prev,
hunger: clamp(prev.hunger + 10),
energy: clamp(prev.energy + 30),
};
default:
return prev;
}
});
};
const getPetMood = (): PetMood => {
if (stats.hunger > 70) return PetMood.Hungry;
if (stats.energy < 30) return PetMood.Tired;
if (stats.happiness < 30) return PetMood.Sad;
if (stats.happiness > 80 && stats.energy > 70) return PetMood.Excited;
if (stats.happiness > 60) return PetMood.Happy;
return PetMood.Content;
};
const currentMood: PetMood = getPetMood();
return (
<div style={{ fontFamily: 'sans-serif', maxWidth: '400px', margin: '20px auto', textAlign: 'center' }}>
<h1>Digital Pet Game</h1>
{/* Form View */}
{!isGameStarted ? (
<form onSubmit={handleSubmit} style={{ border: '1px solid #ccc', padding: '20px', borderRadius: '8px' }}>
<label htmlFor="pet-name" style={{ display: 'block', marginBottom: '10px', fontWeight: 'bold' }}>
What is your pet's name?
</label>
<input
id="pet-name"
type="text"
value={petName}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setPetName(e.target.value)}
style={{ padding: '8px', width: '80%', marginBottom: '10px' }}
/>
{errorMsg && <p style={{ color: 'red', margin: '5px 0' }}>{errorMsg}</p>}
<button type="submit" style={{ padding: '8px 16px', cursor: 'pointer' }}>
Start Game
</button>
</form>
) : (
/* Game View */
<div style={{ border: '1px solid #4CAF50', padding: '20px', borderRadius: '8px' }}>
<h2 className="pet-name" style={{ textTransform: 'capitalize' }}>{petName}</h2>
<div style={{ fontSize: '4rem', margin: '10px 0' }}>
{MOOD_VISUALS[currentMood]}
</div>
<p style={{ fontWeight: 'bold' }}>Mood: {currentMood}</p>
<div style={{ textAlign: 'left', background: '#f9f9f9', padding: '10px', borderRadius: '4px', margin: '15px 0' }}>
<div style={{ margin: '5px 0' }}>Hunger: <strong>{stats.hunger}</strong></div>
<div style={{ margin: '5px 0' }}>Happiness: <strong>{stats.happiness}</strong></div>
<div style={{ margin: '5px 0' }}>Energy: <strong>{stats.energy}</strong></div>
</div>
<div style={{ display: 'flex', justifyContent: 'space-around', marginTop: '15px' }}>
<button id="eat-action" onClick={() => handleAction(PetAction.EAT)} style={{ padding: '8px 12px' }}>
Eat
</button>
<button id="play-action" onClick={() => handleAction(PetAction.PLAY)} style={{ padding: '8px 12px' }}>
Play
</button>
<button id="sleep-action" onClick={() => handleAction(PetAction.SLEEP)} style={{ padding: '8px 12px' }}>
Sleep
</button>
</div>
</div>
)}
</div>
);
};
/* file: styles.css */Left as provided by assignment
```html (also untouched)`````````
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Digital Pet Game</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Tektur:wght@400..900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="styles.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.development.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.development.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.26.5/babel.min.js"></script>
<script
data-plugins="transform-modules-umd"
type="text/babel"
src="index.tsx"
></script>
</head>
<body>
<div id="root"></div>
<script
data-plugins="transform-modules-umd"
type="text/babel"
data-presets="react"
data-type="module"
>
import { PetGame } from './index.tsx';
ReactDOM.createRoot(document.getElementById('root')).render(<PetGame />);
</script>
</body>
</html>
```
### Your browser information:
User Agent is: <code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/ (KHTML, like Gecko) Chrome/145.0.0.0 Safari/</code>
### Challenge Information:
Build a Digital Pet Game - Build a Digital Pet Game
https://www.freecodecamp.org/learn/front-end-development-libraries-v9/lab-digital-pet-game/lab-digital-pet-game
GitHub Link: https://github.com/freeCodeCamp/freeCodeCamp/blob/main/curriculum/challenges/english/blocks/lab-digital-pet-game/68c362b379059c388d3874f2.md