From a336c24cb99b0adb3a889f3e41f75b9a6244cd77 Mon Sep 17 00:00:00 2001 From: Arthur1asdf Date: Sun, 25 Jan 2026 07:06:03 -0500 Subject: [PATCH 1/2] some touch ups --- frontend/src/App.tsx | 429 +++++++++++++++++++--------- frontend/src/assets/LOGO_TITLE.png | Bin 0 -> 23057 bytes frontend/src/components/HUD/HUD.tsx | 82 +++--- frontend/src/engine/buckets.ts | 4 +- frontend/src/engine/getinfo.ts | 18 ++ frontend/src/engine/init.ts | 1 + frontend/src/engine/types.ts | 1 + 7 files changed, 357 insertions(+), 178 deletions(-) create mode 100644 frontend/src/assets/LOGO_TITLE.png create mode 100644 frontend/src/engine/getinfo.ts diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 1c15622..cf996e9 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,20 +1,33 @@ -import './App.css'; -import HUD from './components/HUD/HUD'; +import "./App.css"; +import HUD from "./components/HUD/HUD"; import happy from "../src/assets/Happy.gif"; import neutral from "../src/assets/Neutral.gif"; import sad from "../src/assets/Sad.gif"; import happyMusic from "../src/assets/Happy.mp3"; import neutralMusic from "../src/assets/Neutral.mp3"; import sadMusic from "../src/assets/Sad.mp3"; -import { useState, useEffect, useRef } from 'react'; +import { useState, useEffect, useRef } from "react"; import { useGameState } from "../src/state/useGameState"; import GameOverScreen from "../src/components/GameOverScreen"; import bigHouse from "../src/assets/Big_House.png"; import smallHouse from "../src/assets/Small_House.png"; import Dorm from "../src/assets/Dorm.png"; -import { FinalStatsOverlay } from "../src/components/Projection"; -import EventModal from "../src/components/EventModal" - +import { FinalStatsOverlay } from "../src/components/Projection"; +import EventModal from "../src/components/EventModal"; + +import bgImage from "../src/assets/Pop_up.png"; +import career3 from "../src/assets/forms_emojis/career3.png"; +import personal3 from "../src/assets/forms_emojis/personal3.png"; +import insurance3 from "../src/assets/forms_emojis/insurance3.png"; +import idf3 from "../src/assets/forms_emojis/idf1.png"; +import career2 from "../src/assets/forms_emojis/career2.png"; +import personal2 from "../src/assets/forms_emojis/personal2.png"; +import insurance2 from "../src/assets/forms_emojis/insurance2.png"; +import idf2 from "../src/assets/forms_emojis/idf2.png"; +import career1 from "../src/assets/forms_emojis/career1.png"; +import personal1 from "../src/assets/forms_emojis/personal1.png"; +import insurance1 from "../src/assets/forms_emojis/insurance1.png"; +import idf1 from "../src/assets/forms_emojis/idf3.png"; interface InvestmentData { personal?: number; @@ -33,165 +46,313 @@ function App() { const [showFinalStats, setShowFinalStats] = useState(false); + // State to control visibility of the investment form + const [showInvestments, setShowInvestments] = useState(false); - const [personal, setPersonal] = useState(''); - const [career, setCareer] = useState(''); - const [index, setIndex] = useState(''); - const [insurance, setInsurance] = useState(''); + // Inputs + const [personal, setPersonal] = useState(""); + const [career, setCareer] = useState(""); + const [index, setIndex] = useState(""); + const [insurance, setInsurance] = useState(""); const [showRound, setShowRound] = useState(false); + // AI State + const [aiAdvice, setAiAdvice] = useState("Make your first move to get advice."); + const [isAiLoading, setIsAiLoading] = useState(false); - const audioRef = useRef(null); - const currentTrackRef = useRef(''); - + // Client-side trackers for total contributions + const [totalIndexContributed, setTotalIndexContributed] = useState(0); + const [totalPersonalContributed, setTotalPersonalContributed] = useState(0); - const getGif = () => state.sanity >= 50 ? happy : state.sanity >= 25 ? neutral : sad; + const audioRef = useRef(null); + const currentTrackRef = useRef(""); - const { - state, - nextRound, - pendingEvent, - continueEvent, - resetGame - } = useGameState(); + const { state, nextRound, pendingEvent, continueEvent, resetGame } = useGameState(); + const getGif = () => (state.sanity >= 50 ? happy : state.sanity >= 25 ? neutral : sad); useEffect(() => { if (!audioRef.current) return; - const track = state.sanity >= 50 - ? happyMusic - : state.sanity >= 25 - ? neutralMusic - : sadMusic; + const track = state.sanity >= 50 ? happyMusic : state.sanity >= 25 ? neutralMusic : sadMusic; if (track !== currentTrackRef.current) { audioRef.current.pause(); audioRef.current.src = track; audioRef.current.loop = true; audioRef.current.volume = 0.3; - audioRef.current.play().catch(err => console.log("Autoplay blocked", err)); + audioRef.current.play().catch((err) => console.log("Autoplay blocked", err)); currentTrackRef.current = track; } }, [state.sanity]); + const getImageForAmount = (amount: string, img1: string, img2: string, img3: string) => { + const amt = Number(amount); + if (img1 === career1) { + if (amt >= 500) return career1; + if (amt >= 250) return career2; + return career3; + } + if (img2 === personal2) { + if (amt >= 40) return personal1; + if (amt >= 10) return personal2; + return personal3; + } + if (img3 === idf3) { + if (amt >= 350) return idf1; + if (amt >= 200) return idf2; + return idf3; + } + if (img1 === insurance1) { + if (amt >= 300) return insurance1; + if (amt >= 150) return insurance2; + return insurance3; + } + }; + + // --- MOVED getAiAdvice UP HERE so handleInvestSubmit can see it --- + const getAiAdvice = async () => { + setIsAiLoading(true); + + // Construct a prompt based on current game state and CURRENT inputs + const prompt = ` + I am playing a life simulation game. + My Stats: + - Age: ${state.age} + - Cash: $${state.total} + - Sanity: ${state.sanity}/100 + + My Proposed Investments for this round: + - Career: $${career || 0} + - Personal/Hobbies: $${personal || 0} + - Index Funds: $${index || 0} + - Insurance: $${insurance || 0} + + Give me very brief, sarcastic, or helpful financial advice based on these numbers. + Keep it under 20 words. + `; + + try { + const response = await fetch("http://localhost:5004/generate", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ prompt }), + }); + + if (!response.ok) throw new Error("Backend failed"); + + const data = await response.json(); + setAiAdvice(data.reply || "I'm speechless."); + } catch (error) { + console.error(error); + setAiAdvice("My brain is offline (Check backend connection)."); + } finally { + setIsAiLoading(false); + } + }; + const handleInvestSubmit = (isUpgrade = false) => { - const investments: InvestmentData = {}; - - if (personal) investments.personal = parseFloat(personal); - if (career) investments.career = parseFloat(career); - if (index) investments.index = parseFloat(index); - if (insurance) investments.insurance = parseFloat(insurance); - if (isUpgrade) investments.upgradeHouse = true; - - nextRound(investments); - - // show round badge - setShowRound(true); - setTimeout(() => setShowRound(false), 1500); // show for 1.5s - - // Reset inputs - setPersonal(''); - setCareer(''); - setIndex(''); - setInsurance(''); -}; - - - - return ( - <> - {showRound && ( -
- Round {state.level} -
-)} - - - - {showFinalStats && ( - { - console.log("Retire button clicked, closing overlay"); - setShowFinalStats(false); - resetGame(); - }} - /> - )} + // 1. Call AI Advice BEFORE clearing inputs + getAiAdvice(); - {state.gameOver ? ( - - ) : ( -
- {/* Layer 1: The House Image (Z-index -10) */} - house + const investments: InvestmentData = {}; - {/* Layer 2: The Dotted Pattern (Z-index -8) */} -
+ // 2. Handle Personal (Add to tracker) + if (personal) { + const amount = parseFloat(personal); + investments.personal = amount; + setTotalPersonalContributed((prev) => prev + amount); + } - + // 3. Handle Career (State tracks this already) + if (career) investments.career = parseFloat(career); - {/* Layer 3: The Lil Guy (Z-index -5) */} -
- lil guy -
+ // 4. Handle Index (Add to tracker) + if (index) { + const amount = parseFloat(index); + investments.index = amount; + setTotalIndexContributed((prev) => prev + amount); + } - {/* Layer 4: Interactive UI */} -