From 78c1268fc9ff1db67212b7141531565091b54850 Mon Sep 17 00:00:00 2001 From: Gizmotronn Date: Wed, 23 Oct 2024 12:38:31 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=A6=83=F0=9F=A7=9E=20=E2=86=9D=20[SSM-30?= =?UTF-8?q?=20SSM-31]:=20Stations=20are=20now=20being=20created=20with=20p?= =?UTF-8?q?/m=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../communityStations/projects/31011/route.ts | 57 ++++ .../communityStations/projects/route.ts | 61 ++++ app/tests/page.tsx | 15 +- .../Structures/Build/MakeCommunityStation.tsx | 166 ++++++----- .../Community/IndividualStation.tsx | 5 +- .../Structures/Community/StationModal.tsx | 279 +++++++----------- .../Structures/Community/ViewAllStations.tsx | 132 +++++---- components/Structures/Structures.tsx | 12 +- styles/Anims/CommunityStations.css | 16 + 9 files changed, 433 insertions(+), 310 deletions(-) create mode 100644 app/api/gameplay/communityStations/projects/31011/route.ts create mode 100644 app/api/gameplay/communityStations/projects/route.ts create mode 100644 styles/Anims/CommunityStations.css diff --git a/app/api/gameplay/communityStations/projects/31011/route.ts b/app/api/gameplay/communityStations/projects/31011/route.ts new file mode 100644 index 00000000..9f9ed4a3 --- /dev/null +++ b/app/api/gameplay/communityStations/projects/31011/route.ts @@ -0,0 +1,57 @@ +import { NextRequest, NextResponse } from 'next/server'; + +interface Project { + id: string; + name: string; + identifier: string; +} + +interface Mission { + id: string; + name: string; + type: string; + project: string; + missionRouteId?: number; +} + +interface CommunityStationConfig { + stationName: string; + inventoryItemId: number; + projects: Project[]; + missions: Mission[]; +} + +const greenhouseStation: CommunityStationConfig = { + stationName: "Greenhouse", + inventoryItemId: 31011, + projects: [ + { + id: "1", + name: "Wildwatch Burrowing Owls", + identifier: "zoodex-burrOwls", + }, + { + id: "2", + name: "Iguanas from Above", + identifier: "zoodex-iguanasFromAbove", + }, + ], + missions: [ + { + id: "1", + name: "Spot an owl in the wild", + type: "Upload", + project: "1", + }, + { + id: "2", + name: "Track iguana movement", + type: "Analysis", + project: "2", + }, + ], +}; + +export async function GET(req: NextRequest) { + return NextResponse.json(greenhouseStation); +}; \ No newline at end of file diff --git a/app/api/gameplay/communityStations/projects/route.ts b/app/api/gameplay/communityStations/projects/route.ts new file mode 100644 index 00000000..96921325 --- /dev/null +++ b/app/api/gameplay/communityStations/projects/route.ts @@ -0,0 +1,61 @@ +import { NextRequest, NextResponse } from 'next/server'; + +interface Project { + id: string; + name: string; + identifier: string; +// isUnlocked: boolean; +// level: number; +} + +interface Mission { + id: string; + name: string; + type: string; +// completionRate: number; + project: string; +// level: number; +// isUnlocked: boolean; +} + +interface CommunityStationConfig { + stationName: string; + inventoryItemId: number; + projects: Project[]; + missions: Mission[]; +} + +const greenhouseStation: CommunityStationConfig = { + stationName: "Greenhouse", + inventoryItemId: 31011, + projects: [ + { + id: "1", + name: "Wildwatch Burrowing Owls", + identifier: "zoodex-burrOwls", + }, + { + id: "2", + name: "Iguanas from Above", + identifier: "zoodex-iguanasFromAbove", + }, + ], + missions: [ + { + id: "1", + name: "Spot an owl in the wild", + type: "Upload", + project: "1", + }, + { + id: "2", + name: "Track iguana movement", + type: "Analysis", + project: "2", + }, + ], +}; + +export async function GET(req: NextRequest) { + return NextResponse.json(greenhouseStation); +}; \ No newline at end of file diff --git a/app/tests/page.tsx b/app/tests/page.tsx index 373ebc78..b4ce7237 100644 --- a/app/tests/page.tsx +++ b/app/tests/page.tsx @@ -7,10 +7,19 @@ import MissionPathway from "@/components/Missions/Pathway"; import ProfileCardModal from "@/components/profile/form"; import { CommunityScienceStation } from "@/components/Structures/Community/StationModal"; import { CreateCommunityStation } from "@/components/Structures/Build/MakeCommunityStation"; +import StationsOnPlanet from "@/components/Structures/Community/ViewAllStations"; export default function TestPage() { return ( + + + + ); +}; + +/* + - - - ); -}; \ No newline at end of file + +*/ \ No newline at end of file diff --git a/components/Structures/Build/MakeCommunityStation.tsx b/components/Structures/Build/MakeCommunityStation.tsx index e18afde3..0604345b 100644 --- a/components/Structures/Build/MakeCommunityStation.tsx +++ b/components/Structures/Build/MakeCommunityStation.tsx @@ -6,7 +6,7 @@ import { useActivePlanet } from '@/context/ActivePlanet'; import { Plus } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; -import { motion, AnimatePresence } from "framer-motion"; +import { motion } from "framer-motion"; interface InventoryItem { id: number; @@ -17,35 +17,57 @@ interface InventoryItem { locationType?: string; }; +interface Project { + id: string; + name: string; + identifier: string; + level: number; + locked: boolean; +} + +interface Mission { + id: string; + name: string; + type: string; + project: string; + level: number; + locked: boolean; +} + +interface CommunityStationConfig { + stationName: string; + inventoryItemId: number; + projects: Project[]; + missions: Mission[]; +} + export function CreateCommunityStation() { const supabase = useSupabaseClient(); const session = useSession(); - const { activePlanet } = useActivePlanet(); const [unplacedCommunityStations, setUnplacedCommunityStations] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [open, setOpen] = useState(false); - const [selectedCommunityStation, setSelectedCommunityStation] = useState(null); useEffect(() => { async function fetchStructures() { if (!session || !activePlanet) { setLoading(false); return; - }; - + } + try { const { data: userInventory, error: inventoryError } = await supabase .from("inventory") .select("*") - .eq("item", 31011 | 31012 | 31013) + .in("item", [31011, 31012, 31013]) .eq("anomaly", activePlanet.id); if (inventoryError) { throw inventoryError; - }; + } const availableStations = userInventory.map((item: { item: number }) => item.item); const response = await fetch("/api/gameplay/inventory"); @@ -59,17 +81,45 @@ export function CreateCommunityStation() { setUnplacedCommunityStations(unplaced); } catch (error) { console.error("Error fetching structures", error); + setError("Failed to load community stations."); } finally { setLoading(false); - }; - }; + } + } fetchStructures(); }, [session, activePlanet]); + async function fetchStationConfig(itemId: number): Promise { + const response = await fetch(`/api/gameplay/communityStations/projects/${itemId}`); + if (!response.ok) { + console.error("Failed to fetch station config"); + return null; + } + return await response.json(); + } + async function placeCommunityStation(structure: InventoryItem) { if (!session || !activePlanet) { return; + } + + const stationConfig = await fetchStationConfig(structure.id); + if (!stationConfig) return; + + // Prepare the configuration object + const configuration = { + Uses: 5, + projects: stationConfig.projects.map(project => ({ + ...project, + level: 0, + locked: true, + })), + missions: stationConfig.missions.map(mission => ({ + ...mission, + level: 0, + locked: true, + })), }; try { @@ -81,32 +131,31 @@ export function CreateCommunityStation() { anomaly: activePlanet.id, item: structure.id, quantity: 1, - configuration: { - Uses: 5 - }, + configuration: configuration, }, ]); if (error) { throw error; - }; + } console.log("Community station placed"); setOpen(false); + setUnplacedCommunityStations(prev => prev.filter(item => item.id !== structure.id)); // Remove the placed station from the list } catch (error) { console.error("Error placing community station", error); - }; - }; + } + } if (loading) { - return ( -

- Loading... -

- ); - }; + return

Loading...

; + } - if (unplacedCommunityStations.length === 0) { // empty + if (error) { + return

{error}

; + } + + if (unplacedCommunityStations.length === 0) { return (
@@ -115,74 +164,43 @@ export function CreateCommunityStation() { - - -

No community stations available

+ + Select a Community Station +

No unplaced community stations available.

); - }; + } return ( -
+
- - -
- - {selectedCommunityStation ? ( - + Select a Community Station +
+ {unplacedCommunityStations.map(station => ( + -
- {selectedCommunityStation.name} -

{selectedCommunityStation.name}

-

{selectedCommunityStation.description}

+
+ {station.name} + {station.name}
- - ) : ( - - {unplacedCommunityStations.map((structure) => ( - - ))} - - )} - + ))} +
diff --git a/components/Structures/Community/IndividualStation.tsx b/components/Structures/Community/IndividualStation.tsx index 38442b9f..4c0ce5f7 100644 --- a/components/Structures/Community/IndividualStation.tsx +++ b/components/Structures/Community/IndividualStation.tsx @@ -5,8 +5,11 @@ import { Badge } from "@/components/ui/badge"; import { Building2 } from "lucide-react"; export interface IndividualStationProps { + id: number; name: string; - projects: Project[]; + imageSrc: string; + item: number; + projects: Project[]; onClose?: () => void; // Will add more from `StationModal.tsx` script later // For now, the focus is on integrating projects diff --git a/components/Structures/Community/StationModal.tsx b/components/Structures/Community/StationModal.tsx index d7b9ee62..3f225945 100644 --- a/components/Structures/Community/StationModal.tsx +++ b/components/Structures/Community/StationModal.tsx @@ -1,6 +1,6 @@ "use client"; -import React, { useState } from "react"; +import React, { useState, useEffect } from "react"; import { Moon, Sun, @@ -28,7 +28,6 @@ type Project = { type Mission = { id: string; // points to id in `/api/gameplay/missions/route.ts` name: string; - // project: Project; project: string; isUnlocked: boolean; type: string; @@ -45,42 +44,38 @@ type AnomalyPiece = { type CommunityStationProps = { stationName: string; - projects: Project[]; - missions: Mission[]; anomalies?: AnomalyPiece[]; + projects: Project[]; + missions: Mission[]; }; -// Update these to be split between project pathway options +type SectionProps = { + title: string; + items: Project[] | Mission[]; + baseColors: { bg: string; text: string; accent1: string; accent2: string; }; + onItemClick: (item: Project | Mission) => void; + renderItem?: (item: Project | Mission) => JSX.Element; +}; + +const Section: React.FC = ({ + title, + items, + baseColors, + onItemClick, + renderItem, +}) => { + return ( +
+

{title}

+
+ {/* {items.map(renderItem)} */} +
+
+ ); +}; export function CommunityScienceStation({ stationName = "Greenhouse", - projects = [ - { - id: "1", - name: "Wildwatch Burrowing Owls", - identifier: "zoodex-burrOwls", - isUnlocked: false, - level: 0, - }, - { - id: "2", - name: "Iguanas from Above", - identifier: "zoodex-iguanasFromAbove", - isUnlocked: false, - level: 0, - }, - ], - missions = [ - { - id: "1", - name: "Spot an owl in the wild", - type: "Upload", - completionRate: 4, - project: "1", - level: 2, - isUnlocked: false, - }, // add some new ones, not just upload. Maybe finding specific things/anomalies, a completion rate, moving things around and generating, etc - ], anomalies = [ { id: "1", @@ -89,13 +84,18 @@ export function CommunityScienceStation({ "A hardened owl that is ready to be transported to another lush location.", }, ], + projects = [], + missions = [], }: CommunityStationProps) { const supabase = useSupabaseClient(); const session = useSession(); const [activeSection, setActiveSection] = useState(null); - const [selectedItem, setSelectedItem] = useState(null); + const [selectedItem, setSelectedItem] = useState(null); const [isDarkMode, setIsDarkMode] = useState(false); + + const [isLoading, setIsLoading] = useState(true); // Loading state + const toggleDarkMode = () => setIsDarkMode(!isDarkMode); const baseColors = isDarkMode ? { bg: "#303F51", text: "#F7F5E9", accent1: "#85DDA2", accent2: "#5FCBC3" } @@ -106,7 +106,15 @@ export function CommunityScienceStation({ accent2: "#5FCBC3", }; - const handleItemClick = (item: any) => { + useEffect(() => { + console.log("Fetching projects and missions..."); + // Display projects and missions received as props + console.log("Projects:", projects); + console.log("Missions:", missions); + setIsLoading(false); + }, [projects, missions]); + + const handleItemClick = (item: Project | Mission) => { setSelectedItem(item); }; @@ -116,22 +124,24 @@ export function CommunityScienceStation({ }; const toggleUnlock = (item: Project | Mission) => { + console.log("Toggling unlock for item:", item); if (activeSection === "Projects") { const updatedProjects = projects.map((p) => p.id === item.id ? { ...p, isUnlocked: !p.isUnlocked } : p ); - console.log("Updated: ", updatedProjects); + console.log("Updated projects:", updatedProjects); } else if (activeSection === "Missions") { const updatedMissions = missions.map((m) => m.id === item.id ? { ...m, completionRate: m.completionRate + 1 } : m ); - - console.log("Updated: ", updatedMissions); + console.log("Updated missions:", updatedMissions); } setSelectedItem({ ...item, isUnlocked: !item.isUnlocked }); }; + if (isLoading) return
Loading...
; + return (
( -
- {project.name} -
- Lvl {project.level} - {project.isUnlocked ? ( - - ) : ( - - )} -
-
- )} + // renderItem={(item) => { + // if (isProject(item)) { + // return ( + //
handleItemClick(item)} + // className={`flex justify-between items-center p-2 border-b ${ + // item.isUnlocked ? "text-green-600" : "text-red-600" + // }`} + // > + // {item.name} + // + //
+ // ); + // } + // return null; // Should not reach here + // }} /> )} + {activeSection === "Missions" && (
( -
- {mission.name} -
- Lvl {mission.level} - {mission.isUnlocked ? ( - - ) : ( - - )} -
-
- )} - /> - )} - {activeSection === "Items" && ( -
( -
- {item.name} - -
- )} + // renderItem={(item) => { + // if (isMission(item)) { + // return ( + //
handleItemClick(item)} + // className={`flex justify-between items-center p-2 border-b ${ + // item.isUnlocked ? "text-green-600" : "text-red-600" + // }`} + // > + // {item.name} + // + //
+ // ); + // } + // return null; // Should not reach here + // }} /> )} - {activeSection === "AddData" && ( -
-

Add Your Data

-

Submit your research data here:

-