From bdb5f52f843da732be87632f5623dc5905a02231 Mon Sep 17 00:00:00 2001 From: Gizmotronn Date: Mon, 7 Oct 2024 17:20:55 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=8F=F0=9F=A6=97=20=E2=86=9D=20[SSC-21?= =?UTF-8?q?=20SSC-16]:=20Fixing=20plankton=20portal=20&=20updating=20ui=20?= =?UTF-8?q?for=20planet=20switcher?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/page.tsx | 9 +- app/scenes/earth/page.tsx | 8 - app/tests/page.tsx | 11 +- .../(scenes)/planetScene/SwitchPlanet.tsx | 410 ------------------ components/(scenes)/travel/SolarSystem.tsx | 339 +++++++++++++++ components/(scenes)/travel/SwitchPlanet.tsx | 183 ++++++++ .../(structures)/Launchpad/Dashboard.tsx | 4 +- .../Projects/Zoodex/ClassifyOthersAnimals.tsx | 2 +- components/Projects/Zoodex/planktonPortal.tsx | 65 ++- constants/Structures/Properties.tsx | 15 +- constants/Structures/SandboxProperties.tsx | 1 - content/output.tsx | 158 +++++++ package.json | 2 +- yarn.lock | 8 +- 14 files changed, 738 insertions(+), 477 deletions(-) delete mode 100644 components/(scenes)/planetScene/SwitchPlanet.tsx create mode 100644 components/(scenes)/travel/SolarSystem.tsx create mode 100644 components/(scenes)/travel/SwitchPlanet.tsx create mode 100644 content/output.tsx diff --git a/app/page.tsx b/app/page.tsx index 20a54562..7c9c2c68 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -31,6 +31,7 @@ import { VenusView } from './scenes'; import GlobeView from "./scenes/globe/page"; +import InitialiseChapterOneUser from "@/components/(scenes)/chapters/one/InitialiseUser"; export default function Home() { const session = useSession(); @@ -68,12 +69,18 @@ export default function Home() { return ; }; - if (activePlanet?.id === null || activePlanet?.id == 69) { + if (activePlanet?.id === 69) { return ( ); }; + if (activePlanet?.id === null) { + return ( + + ); + }; + if (activePlanet?.id == 35) { return ( diff --git a/app/scenes/earth/page.tsx b/app/scenes/earth/page.tsx index 2c344c7e..f7e9a1d7 100644 --- a/app/scenes/earth/page.tsx +++ b/app/scenes/earth/page.tsx @@ -13,14 +13,6 @@ import InitialiseChapterOneUser from "@/components/(scenes)/chapters/one/Initial const EarthView: React.FC = () => { const supabase = useSupabaseClient(); const session = useSession(); - - const { activePlanet, updatePlanetLocation } = useActivePlanet(); - - if (activePlanet?.id !== 69 || 35) { - return ( - - ); - }; return (
diff --git a/app/tests/page.tsx b/app/tests/page.tsx index e07e8121..fb083c83 100644 --- a/app/tests/page.tsx +++ b/app/tests/page.tsx @@ -1,15 +1,12 @@ "use client"; -import React, { useEffect, useState, useCallback } from "react"; -import Camera from "@/components/Projects/Zoodex/Upload/Camera"; -import CloudUploadEarthCameraComponent from "@/components/Projects/Lidar/Upload/CloudCamera"; +import React from "react"; +import SwitchPlanet from "@/components/(scenes)/travel/SolarSystem"; export default function TestPage() { return (
- +
); -}; - - +}; \ No newline at end of file diff --git a/components/(scenes)/planetScene/SwitchPlanet.tsx b/components/(scenes)/planetScene/SwitchPlanet.tsx deleted file mode 100644 index 6ff4d5b2..00000000 --- a/components/(scenes)/planetScene/SwitchPlanet.tsx +++ /dev/null @@ -1,410 +0,0 @@ -"use client"; - -import { SetStateAction, useEffect, useState } from "react"; -import { motion, AnimatePresence } from "framer-motion"; -import { ChevronLeft, ChevronRight, Globe } from "lucide-react"; -import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react"; -import { useActivePlanet } from "@/context/ActivePlanet"; -import MissionList from "./availableMissions"; -import { Button } from "antd"; - -const planetTypeColors: { [key: string]: string } = { - Lush: "#4CAF50", - Arid: "#FF9800", - Hellhole: "#FF5722", - Frozen: "#03A9F4", - "GasGiant": "#9C27B0", - Rocky: "#795548", - "IceGiant": "#00BCD4" -}; - -interface Planet { - id: number; - name: string; - color: string; - stats: { - gravity: string; - temp: string; - }; - anomaly: number; - initialisationMissionId: number | null; - planetType: string; -} - -const planets = [ - { - id: 10, - name: "Mercury", - color: "bg-gray-400", - stats: { gravity: "3.7 m/s²", temp: "430°C" }, - anomaly: 10, - planetType: 'Arid', - initialisationMissionId: 100001, - }, - { - id: 20, - name: "Venus", - color: "bg-yellow-200", - stats: { gravity: "8.87 m/s²", temp: "462°C" }, - anomaly: 20, - planetType: 'Arid', - initialisationMissionId: 200001, - }, - { - id: 69, - name: "Earth", - color: "bg-blue-500", - stats: { gravity: "9.8 m/s²", temp: "15°C" }, - anomaly: 69, - planetType: 'Lush', - initialisationMissionId: 300001, - }, - // { - // id: 31, - // name: "Moon", - // color: "bg-gray-300", - // stats: { gravity: "1.62 m/s²", temp: "-53°C" }, - // anomaly: 31, - // planetType: 'Arid', - // initialisationMissionId: null, - // }, - { - id: 40, - name: "Mars", - color: "bg-red-500", - stats: { gravity: "3.71 m/s²", temp: "-63°C" }, - anomaly: 40, - planetType: 'Arid', - initialisationMissionId: 400001, - }, - { - id: 50, - name: "Jupiter", - color: "bg-orange-300", - stats: { gravity: "24.79 m/s²", temp: "-108°C" }, - anomaly: 50, - planetType: 'Arid', - initialisationMissionId: null, - }, - { - id: 55, - name: "Europa", - color: "bg-blue-200", - stats: { gravity: "1.31 m/s²", temp: "-160°C" }, - anomaly: 51, - planetType: 'Arid', - initialisationMissionId: null, - }, - { - id: 52, - name: "Io", - color: "bg-yellow-400", - stats: { gravity: "1.79 m/s²", temp: "-143°C" }, - anomaly: 52, - planetType: 'Arid', - initialisationMissionId: null, - }, - { - id: 51, - name: "Amalthea", - color: "bg-red-400", - stats: { gravity: "0.026 m/s²", temp: "-113°C" }, - anomaly: 53, - planetType: 'Arid', - initialisationMissionId: null, - }, - { - id: 60, - name: "Saturn", - color: "bg-yellow-600", - stats: { gravity: "10.44 m/s²", temp: "-139°C" }, - anomaly: 60, - planetType: 'Arid', - initialisationMissionId: 600001, - }, - { - id: 61, - name: "Enceladus", - color: "bg-white", - stats: { gravity: "0.113 m/s²", temp: "-201°C" }, - anomaly: 61, - planetType: 'Arid', - initialisationMissionId: null, - }, - { - id: 70, - name: "Uranus", - color: "bg-cyan-300", - stats: { gravity: "8.69 m/s²", temp: "-197°C" }, - anomaly: 70, - planetType: 'Arid', - initialisationMissionId: 700001, - }, - { - id: 80, - name: "Neptune", - color: "bg-blue-700", - stats: { gravity: "11.15 m/s²", temp: "-214°C" }, - anomaly: 80, - planetType: 'Arid', - initialisationMissionId: 800001, - }, -]; - -const usePlanetSwitcher = (initialIndex = 0) => { - const [currentIndex, setCurrentIndex] = useState(initialIndex); - - const nextPlanet = () => { - setCurrentIndex((prevIndex) => (prevIndex + 1) % planets.length); - }; - - const prevPlanet = () => { - setCurrentIndex((prevIndex) => (prevIndex - 1 + planets.length) % planets.length); - }; - - return { - currentPlanet: planets[currentIndex], - nextPlanet, - prevPlanet, - currentIndex, - }; -}; - -export function PlanetSwitcher() { - const supabase = useSupabaseClient(); - const session = useSession(); - - const { activePlanet, updatePlanetLocation } = useActivePlanet(); - - const [visitedPlanets, setVisitedPlanets] = useState<{ [key: number]: boolean }>({}); - const [planetStats, setPlanetStats] = useState([]); - const [classificationsByPlanet, setClassificationsByPlanet] = useState>({}); - const [hasRocket, setHasRocket] = useState(false); - const [availableMissions, setAvailableMissions] = useState([]); - - const { currentPlanet, nextPlanet, prevPlanet, currentIndex } = usePlanetSwitcher(); - - useEffect(() => { - const fetchVisitedPlanets = async () => { - if (session?.user?.id) { - try { - const { data: missions, error } = await supabase - .from('missions') - .select('mission') - .eq('user', session.user.id); - - if (error) throw error; - - const visited = missions.reduce((acc: { [key: number]: boolean }, mission: { mission: number }) => { - acc[mission.mission] = true; - return acc; - }, {}); - - setVisitedPlanets(visited); - } catch (error: any) { - console.error('Error fetching missions:', error.message); - } - } - }; - - const fetchPlanetStats = async () => { - try { - const response = await fetch('/api/gameplay/missions/planets/solarsystem/stats'); - const data = await response.json(); - setPlanetStats(data); - } catch (error) { - console.error('Error fetching planet stats:', error); - }; - }; - - const fetchClassifications = async () => { - if (session?.user?.id) { - try { - const { data: classificationsData, error } = await supabase - .from('classifications') - .select('classificationtype, classificationConfiguration') - .eq('author', session.user.id); - - if (error) throw error; - - const classificationsByPlanetTemp: Record = {}; - - classificationsData.forEach((classification: any) => { - const planetAnomaly = parseInt(classification.classificationConfiguration.activePlanet, 10); - - if (!classificationsByPlanetTemp[planetAnomaly]) { - classificationsByPlanetTemp[planetAnomaly] = []; - } - - classificationsByPlanetTemp[planetAnomaly].push(classification); - }); - - setClassificationsByPlanet(classificationsByPlanetTemp); - } catch (error: any) { - console.error('Error fetching classifications:', error.message); - } - } - }; - - const checkRocketInInventory = async () => { - if (session?.user?.id) { - try { - const { data, error } = await supabase - .from('inventory') - .select('id') - .eq('item', 3108) - .eq('anomaly', activePlanet?.id) - .eq('owner', session.user.id); - - if (error) throw error; - - setHasRocket(data.length > 0); - } catch (error: any) { - console.error('Error checking inventory:', error.message); - } - } - }; - - fetchVisitedPlanets(); - fetchPlanetStats(); - fetchClassifications(); - checkRocketInInventory(); - }, [session, supabase, activePlanet]); - - const moveItemsToNewPlanet = async (newPlanetId: number) => { - if (session?.user?.id) { - const itemsToMove = [3108, 3107]; - - try { - await Promise.all( - itemsToMove.map(async (itemId) => { - const { data, error } = await supabase - .from('inventory') - .update({ anomaly: newPlanetId }) - .eq('item', itemId) - .eq('owner', session.user.id); - - if (error) throw error; - return data; - }) - ); - } catch (error: any) { - console.error('Error moving items:', error.message); - } - } - }; - - const handlePlanetClick = async (planet: any) => { - if (planet.anomaly !== activePlanet?.id) { - const { error: missonsError } = await supabase - .from('missions') - .insert([initialisePlanetMissionData]); - - await moveItemsToNewPlanet(planet.anomaly); - updatePlanetLocation(planet.anomaly); - }; - }; - - const isVisited = classificationsByPlanet[currentPlanet.anomaly]?.length > 0; - const planetDetails = planetStats?.find((planet) => planet.id === currentPlanet.initialisationMissionId); - const initialisationMission = currentPlanet.initialisationMissionId; - - const initialisePlanetMissionData = { - user: session?.user.id, - time_of_completion: new Date().toISOString(), - mission: initialisationMission, -}; - - return ( -
-
-
- - -
- -

- - {currentPlanet.name} -

- -
- -
- {Object.entries(currentPlanet.stats).map(([key, value]) => ( -
-

{key}

-

{value}

-
- ))} -
- -
-
    -
  • - {currentPlanet.anomaly !== activePlanet?.id && ( - - )} -
  • -
-
- -
- {currentPlanet.anomaly === activePlanet?.id ? null : isVisited ? ( -
-

Planet Details

- {planetDetails ? ( -
    -
  • - Planet Type:{' '} - - {planetDetails.planetType || 'Unknown'} - -
  • -
- ) : ( -

Loading planet details...

- )} -
- ) : ( -

You haven't visited this planet yet.

- )} -
- {planetDetails?.planetType ? ( - -) : ( -

Planet type information not available.

-)} -
-
-
-
-
- ); -} \ No newline at end of file diff --git a/components/(scenes)/travel/SolarSystem.tsx b/components/(scenes)/travel/SolarSystem.tsx new file mode 100644 index 00000000..91495742 --- /dev/null +++ b/components/(scenes)/travel/SolarSystem.tsx @@ -0,0 +1,339 @@ +"use client"; + +import React, { useEffect, useState } from "react"; +import { motion, AnimatePresence } from "framer-motion"; +import { Star, MapPin, Clock, ThermometerSun, Users, ChevronLeft, ChevronRight } from "lucide-react"; +import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react"; +import { useActivePlanet } from "@/context/ActivePlanet"; + +const planets = { + solarSystem: [ + { + id: 10, + name: "Mercury", + color: "bg-gray-400", + stats: { gravity: "3.7 m/s²", temp: "430°C" }, + anomaly: 10, + planetType: 'Arid', + initialisationMissionId: 100001, + travelTime: '30 seconds', + description: '', // replace with classification list + image: '/images/mercury.jpg' + }, + { + id: 20, + name: "Venus", + color: "bg-yellow-200", + stats: { gravity: "8.87 m/s²", temp: "462°C" }, + anomaly: 20, + planetType: 'Arid', + initialisationMissionId: 200001, + travelTime: '30 seconds', + description: '', // replace with classification list + image: '/images/venus.jpg' + }, + { + id: 69, + name: "Earth", + color: "bg-blue-500", + stats: { gravity: "9.8 m/s²", temp: "15°C" }, + anomaly: 69, + planetType: 'Lush', + initialisationMissionId: 300001, + travelTime: '30 seconds', + description: '', // replace with classification list + image: '/images/earth.jpg' + }, + { + id: 40, + name: "Mars", + color: "bg-red-500", + stats: { gravity: "3.71 m/s²", temp: "-63°C" }, + anomaly: 40, + planetType: 'Arid', + initialisationMissionId: 400001, + travelTime: '30 seconds', + description: '', // replace with classification list + image: '/images/mars.jpg' + }, + ], + exoplanets: [ + // should only show `anomalies` discovered by user + ], +}; + +// ^^ update this to pull from `anomalies` table + +export default function SwitchPlanet() { + const supabase = useSupabaseClient(); + const session = useSession(); + const { activePlanet, updatePlanetLocation } = useActivePlanet(); + + const [activeTab, setActiveTab] = useState<"solarSystem" | "exoplanets">( + "solarSystem" + ); + const [currentIndex, setCurrentIndex] = useState(0); + const currentPlanets = planets[activeTab]; + const currentPlanet = currentPlanets[currentIndex]; + + const [planetStats, setPlanetStats] = useState([]); + const [visitedPlanets, setVisitedPlanets] = useState<{ + [key: number]: boolean; + }>({}); + const [classificationsByPlanet, setClassificationsByPlanet] = useState< + Record + >({}); + const [hasRocket, setHasRocket] = useState(false); + + // Where has the user been, based on missions completed + useEffect(() => { + const fetchVisitedPlanets = async () => { + if (!session) return; + + try { + const { data: missionsData, error } = await supabase + .from("missions") + .select("mission") + .eq("user", session.user.id); + + if (error) throw error; + + const visited = missionsData.reduce( + (acc: { [key: number]: boolean }, mission: { mission: number }) => { + acc[mission.mission] = true; + return acc; + }, + {} + ); + + setVisitedPlanets(visited); + } catch (error: any) { + console.error("Error fetching visited planets: ", error.message); + } + }; + + const fetchPlanetStats = async () => { + try { + const response = await fetch( + "/api/gameplay/missions/planets/solarsystem/stats" + ); + const data = await response.json(); + setPlanetStats(data); + } catch (error) { + console.error("Error fetching planet stats:", error); + } + }; + + const fetchClassifications = async () => { + if (session?.user?.id) { + try { + const { data: classificationsData, error } = await supabase + .from("classifications") + .select("classificationtype, classificationConfiguration") + .eq("author", session.user.id); + + if (error) throw error; + + const classificationsByPlanetTemp: Record = {}; + + classificationsData.forEach((classification: any) => { + const planetAnomaly = parseInt( + classification.classificationConfiguration.activePlanet, + 10 + ); + + if (!classificationsByPlanetTemp[planetAnomaly]) { + classificationsByPlanetTemp[planetAnomaly] = []; + } + + classificationsByPlanetTemp[planetAnomaly].push(classification); + }); + + setClassificationsByPlanet(classificationsByPlanetTemp); + } catch (error: any) { + console.error("Error fetching classifications:", error.message); + } + } + }; + + const checkRocketInInventory = async () => { + if (session?.user?.id) { + try { + const { data, error } = await supabase + .from("inventory") + .select("id") + .eq("item", 3108) + .eq("anomaly", activePlanet?.id) + .eq("owner", session.user.id); + + if (error) throw error; + + setHasRocket(data.length > 0); + } catch (error: any) { + console.error("Error checking inventory:", error.message); + } + } + }; + + fetchVisitedPlanets(); + fetchPlanetStats(); + fetchClassifications(); + checkRocketInInventory(); + }, [session, supabase, activePlanet]); + + const nextPlanet = () => { + setCurrentIndex((currentIndex + 1) % currentPlanets.length); + }; + + const prevPlanet = () => { + setCurrentIndex((currentIndex - 1 + currentPlanets.length) % currentPlanets.length); + }; + + const moveItemsToNewPlanet = async (newPlanetId: number) => { + if (session?.user?.id) { + const itemsToMove = [3108, 3107]; + + try { + await Promise.all( + itemsToMove.map(async (itemId) => { + const { data, error } = await supabase + .from("inventory") + .update({ anomaly: newPlanetId }) + .eq("item", itemId) + .eq("owner", session.user.id); + + if (error) throw error; + return data; + }) + ); + } catch (error: any) { + console.error("Error moving items:", error.message); + } + } + }; + + const handlePlanetClick = async (planet: any) => { + if (planet.anomaly !== activePlanet?.id) { + const { error: missionsError } = await supabase + .from("missions") + .insert([initialisePlanetMissionData]); + + await moveItemsToNewPlanet(planet.anomaly); + updatePlanetLocation(planet.anomaly); + } + }; + + const isVisited = + classificationsByPlanet[currentPlanet.anomaly]?.length > 0; + const planetDetails = planetStats?.find( + (planet) => planet.id === currentPlanet.initialisationMissionId + ); + const initialisationMission = currentPlanet.initialisationMissionId; + + const initialisePlanetMissionData = { + user: session?.user.id, + time_of_completion: new Date().toISOString(), + mission: initialisationMission, + }; + + return ( +
+
+
+ + +
+ + + {currentPlanets.length > 0 ? ( + + {currentPlanet.name} +
+
+

{currentPlanet.name}

+
+
+ + {currentPlanet.planetType} +
+
+ + {currentPlanet.stats.gravity} +
+
+ + {currentPlanet.stats.temp} +
+
+ + {currentPlanet.travelTime} +
+
+
+

+ {visitedPlanets[currentPlanet.id] + ? "You've already visited this planet!" + : "New planet to explore!"} +

+ + {isVisited ? ( +

+ You've completed classifications on this planet. +

+ ) : ( + + )} +
+
+ ) : ( +

No planets available.

+ )} +
+ +
+ + +
+
+
+ ); +}; \ No newline at end of file diff --git a/components/(scenes)/travel/SwitchPlanet.tsx b/components/(scenes)/travel/SwitchPlanet.tsx new file mode 100644 index 00000000..f7517e32 --- /dev/null +++ b/components/(scenes)/travel/SwitchPlanet.tsx @@ -0,0 +1,183 @@ +"use client"; + +import { SetStateAction, useEffect, useState } from "react"; +import { motion, AnimatePresence } from "framer-motion"; +import { ChevronLeft, ChevronRight, Globe } from "lucide-react"; +import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react"; +import { useActivePlanet } from "@/context/ActivePlanet"; +import MissionList from "../planetScene/availableMissions"; +import { Button } from "antd"; + +const planetTypeColors: { [key: string]: string } = { + Lush: "#4CAF50", + Arid: "#FF9800", + Hellhole: "#FF5722", + Frozen: "#03A9F4", + "GasGiant": "#9C27B0", + Rocky: "#795548", + "IceGiant": "#00BCD4" +}; + +interface Planet { + id: number; + name: string; + color: string; + stats: { + gravity: string; + temp: string; + }; + anomaly: number; + initialisationMissionId: number | null; + planetType: string; +} + +const planets = [ + { + id: 10, + name: "Mercury", + color: "bg-gray-400", + stats: { gravity: "3.7 m/s²", temp: "430°C" }, + anomaly: 10, + planetType: 'Arid', + initialisationMissionId: 100001, + travelTime: '30 seconds', + }, + { + id: 20, + name: "Venus", + color: "bg-yellow-200", + stats: { gravity: "8.87 m/s²", temp: "462°C" }, + anomaly: 20, + planetType: 'Arid', + initialisationMissionId: 200001, + travelTime: '30 seconds', + }, + { + id: 69, + name: "Earth", + color: "bg-blue-500", + stats: { gravity: "9.8 m/s²", temp: "15°C" }, + anomaly: 69, + planetType: 'Lush', + initialisationMissionId: 300001, + travelTime: '30 seconds', + }, + // { + // id: 31, + // name: "Moon", + // color: "bg-gray-300", + // stats: { gravity: "1.62 m/s²", temp: "-53°C" }, + // anomaly: 31, + // planetType: 'Arid', + // initialisationMissionId: null, + // }, + { + id: 40, + name: "Mars", + color: "bg-red-500", + stats: { gravity: "3.71 m/s²", temp: "-63°C" }, + anomaly: 40, + planetType: 'Arid', + initialisationMissionId: 400001, + travelTime: '30 seconds', + }, + // { + // id: 50, + // name: "Jupiter", + // color: "bg-orange-300", + // stats: { gravity: "24.79 m/s²", temp: "-108°C" }, + // anomaly: 50, + // planetType: 'Arid', + // initialisationMissionId: null, + // travelTime: '30 seconds', + // }, + // { + // id: 55, + // name: "Europa", + // color: "bg-blue-200", + // stats: { gravity: "1.31 m/s²", temp: "-160°C" }, + // anomaly: 51, + // planetType: 'Arid', + // initialisationMissionId: null, + // travelTime: '30 seconds', + // }, + // { + // id: 52, + // name: "Io", + // color: "bg-yellow-400", + // stats: { gravity: "1.79 m/s²", temp: "-143°C" }, + // anomaly: 52, + // planetType: 'Arid', + // initialisationMissionId: null, + // travelTime: '30 seconds', + // }, + // { + // id: 51, + // name: "Amalthea", + // color: "bg-red-400", + // stats: { gravity: "0.026 m/s²", temp: "-113°C" }, + // anomaly: 53, + // planetType: 'Arid', + // initialisationMissionId: null, + // travelTime: '30 seconds', + // }, + // { + // id: 60, + // name: "Saturn", + // color: "bg-yellow-600", + // stats: { gravity: "10.44 m/s²", temp: "-139°C" }, + // anomaly: 60, + // planetType: 'Arid', + // initialisationMissionId: 600001, + // travelTime: '30 seconds', + // }, + // { + // id: 61, + // name: "Enceladus", + // color: "bg-white", + // stats: { gravity: "0.113 m/s²", temp: "-201°C" }, + // anomaly: 61, + // planetType: 'Arid', + // initialisationMissionId: null, + // travelTime: '30 seconds', + // }, + // { + // id: 70, + // name: "Uranus", + // color: "bg-cyan-300", + // stats: { gravity: "8.69 m/s²", temp: "-197°C" }, + // anomaly: 70, + // planetType: 'Arid', + // initialisationMissionId: 700001, + // travelTime: '30 seconds', + // }, + // { + // id: 80, + // name: "Neptune", + // color: "bg-blue-700", + // stats: { gravity: "11.15 m/s²", temp: "-214°C" }, + // anomaly: 80, + // planetType: 'Arid', + // initialisationMissionId: 800001, + // travelTime: '30 seconds', + // }, +]; + +const usePlanetSwitcher = (initialIndex = 0) => { + const [currentIndex, setCurrentIndex] = useState(initialIndex); + + const nextPlanet = () => { + setCurrentIndex((prevIndex) => (prevIndex + 1) % planets.length); + }; + + const prevPlanet = () => { + setCurrentIndex((prevIndex) => (prevIndex - 1 + planets.length) % planets.length); + }; + + return { + currentPlanet: planets[currentIndex], + nextPlanet, + prevPlanet, + currentIndex, + }; +}; \ No newline at end of file diff --git a/components/(structures)/Launchpad/Dashboard.tsx b/components/(structures)/Launchpad/Dashboard.tsx index 38cdc808..98cbfa3a 100644 --- a/components/(structures)/Launchpad/Dashboard.tsx +++ b/components/(structures)/Launchpad/Dashboard.tsx @@ -4,9 +4,9 @@ import React, { useState, useEffect } from "react"; import { Battery, Droplet, Zap, AlertTriangle, BarChart2, Rocket, Satellite, Box, PieChart, X, Cpu, Navigation, Heart, Radio, Radar } from 'lucide-react'; import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react"; import { useActivePlanet } from "@/context/ActivePlanet"; -import { PlanetSwitcher } from "../../(scenes)/planetScene/SwitchPlanet"; +import SwitchPlanet from "@/components/(scenes)/travel/SolarSystem"; -const TravelLaunch = () =>
; +const TravelLaunch = () =>
; const DeployProbesLaunch = () =>
Not available yet
; const TransportLaunch = () =>
Not available yet
; diff --git a/components/Projects/Zoodex/ClassifyOthersAnimals.tsx b/components/Projects/Zoodex/ClassifyOthersAnimals.tsx index 25be2a27..f8fa8003 100644 --- a/components/Projects/Zoodex/ClassifyOthersAnimals.tsx +++ b/components/Projects/Zoodex/ClassifyOthersAnimals.tsx @@ -433,7 +433,7 @@ export function StarterZoodexGallery() { {imageUrls.length > 0 && anomalyType && ( = ({ - anomalyId -}) => { +export const PlanktonPortalTutorial: React.FC = ({ anomalyId }) => { const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; const imageUrl = `${supabaseUrl}/storage/v1/object/public/zoodex/zoodex-planktonPortal/${anomalyId}.jpeg`; - const [part, setPart] = useState(0); + const [part, setPart] = useState(1); const [line, setLine] = useState(1); const nextLine = () => setLine((prevLine) => prevLine + 1); @@ -29,11 +27,7 @@ export const PlanktonPortalTutorial: React.FC = ({
{part === 1 && ( <> - {line === 1 && ( -

- Hello, and welcome to Plankton Portal! -

- )} + {line === 1 &&

Hello, and welcome to Plankton Portal!

} {line === 2 && (

In this project, you'll be marking images of plankton—tiny oceanic organisms—taken by an underwater imaging system. Because plankton are an important food source and a strong indicator of the health of a marine biome, they can teach us many things about our planet's oceans. @@ -49,11 +43,7 @@ export const PlanktonPortalTutorial: React.FC = ({ Don't worry too much if you aren't 100% sure—we just want your best guess, no matter what! Many people will see each image, and everyone's classifications will be combined to produce a result. The wisdom of crowds tends to give the right answer.

)} - {line === 5 && ( -

- Let's get started! -

- )} + {line === 5 &&

Let's get started!

} {line < 6 && (
@@ -109,33 +99,29 @@ export const PlanktonPortalTutorial: React.FC = ({
{part === 1 && ( -
- {tutorialContent} -
+
{tutorialContent}
)} {part === 2 && ( - <> -
-
-
-
- Plankton image -
+
+
+
+
+ Plankton image
-
+
- +
)}
@@ -180,7 +166,7 @@ export function PlanktonPortal() { const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; const imageUrl = `${supabaseUrl}/storage/v1/object/public/zoodex/zoodex-planktonPortal/${randomAnomaly.id}.jpeg`; - setImageUrl(imageUrl); // Ensure you set the image URL here + setImageUrl(imageUrl); } catch (error: any) { console.error("Error fetching plankton anomaly: ", error.message); setAnomaly(null); @@ -225,6 +211,7 @@ export function PlanktonPortal() {
); }; + if (!hasMission200000012) { return anomaly ? ( @@ -257,10 +244,10 @@ export function PlanktonPortal() {
{imageUrl && ( - {anomaly.content} + {anomaly?.content} )} , sizePercentage: 60, }, + { + icon: , + text: "Plant life", + dynamicComponent: , + sizePercentage: 60, + }, // { // icon: , // text: "Greenhouse", @@ -322,7 +331,7 @@ export const StructuresConfig: StructureConfig = { icon: , text: "Launch a rocket (travel)", // dynamicComponent: , - dynamicComponent: , + dynamicComponent: , sizePercentage: 100, }, diff --git a/constants/Structures/SandboxProperties.tsx b/constants/Structures/SandboxProperties.tsx index b4fdca26..c4bcc6f6 100644 --- a/constants/Structures/SandboxProperties.tsx +++ b/constants/Structures/SandboxProperties.tsx @@ -17,7 +17,6 @@ import MissionsForStructure from "@/components/(structures)/Missions/AvailableMi import { TelescopeSunspotDetector } from "@/components/Projects/Telescopes/Sunspots"; import { TelescopeDiskDetector } from "@/components/Projects/Telescopes/DiskDetector"; import LaunchpadStructure from "@/components/(structures)/Launchpad/Dashboard"; -import { PlanetSwitcher } from "@/components/(scenes)/planetScene/SwitchPlanet"; import CameraComponent from "@/components/Projects/Zoodex/Upload/Camera"; import { PenguinWatch } from "@/components/Projects/Zoodex/penguinWatch"; import { PlanktonPortal, PlanktonPortalTutorial } from "@/components/Projects/Zoodex/planktonPortal"; diff --git a/content/output.tsx b/content/output.tsx new file mode 100644 index 00000000..5c9463ba --- /dev/null +++ b/content/output.tsx @@ -0,0 +1,158 @@ +"use client"; + +import React, { useState, useEffect } from "react"; + +interface Classification { + classification_id: number; + content: string | null; + classificationtype: string; + created_at: string; +}; + +interface AnomaliesGroup { + anomaly_id: number; + content: string | null; + created_at: string; +}; + +interface ClassificationsData { + [anomalytype: string]: { + [anomalySet: string]: { + [author: string]: Classification[]; + }; + }; +}; + +interface AnomaliesData { + [anomalytype: string]: AnomaliesGroup[]; +}; + +interface ClassificationsAndAnomaliesResponse { + classifications: ClassificationsData; + anomalies: AnomaliesData; +}; + +const ClassificationsAndAnomalies: React.FC = () => { + const [data, setData] = useState( + null + ); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchData = async () => { + try { + const response = await fetch("/citizen/output"); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + const result: ClassificationsAndAnomaliesResponse = + await response.json(); + setData(result); + } catch (error) { + setError((error as Error).message); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, []); + + if (loading) return
Loading...
; + if (error) return
Error: {error}
; + + return ( +
+

Classifications and Anomalies

+ + {/* Render Classifications */} + {data && data.classifications ? ( +
+

Classifications

+ {Object.keys(data.classifications).map((anomalyType) => ( +
+

Anomaly Type: {anomalyType}

+ {Object.keys(data.classifications[anomalyType]).map( + (anomalySet) => ( +
+

Anomaly Set: {anomalySet}

+ {Object.keys( + data.classifications[anomalyType][anomalySet] + ).map((author) => ( +
+
Author: {author}
+
    + {data.classifications[anomalyType][anomalySet][ + author + ].map((classification) => ( +
  • +

    + Classification ID:{" "} + {classification.classification_id} +

    +

    + Content:{" "} + {classification.content ?? "N/A"} +

    +

    + Classification Type:{" "} + {classification.classificationtype} +

    +

    + Created At:{" "} + {new Date( + classification.created_at + ).toLocaleString()} +

    +
    +
  • + ))} +
+
+ ))} +
+ ) + )} +
+ ))} +
+ ) : ( +

No classifications found.

+ )} + + {/* Render Anomalies */} + {data && data.anomalies ? ( +
+

Anomalies

+ {Object.keys(data.anomalies).map((anomalyType) => ( +
+

Anomaly Type: {anomalyType}

+
    + {data.anomalies[anomalyType].map((anomaly) => ( +
  • +

    + Anomaly ID: {anomaly.anomaly_id} +

    +

    + Content: {anomaly.content ?? "N/A"} +

    +

    + Created At:{" "} + {new Date(anomaly.created_at).toLocaleString()} +

    +
    +
  • + ))} +
+
+ ))} +
+ ) : ( +

No anomalies found.

+ )} +
+ ); +}; + +export default ClassificationsAndAnomalies; \ No newline at end of file diff --git a/package.json b/package.json index 5a28afe8..6ed67ee9 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "daisyui": "^4.11.1", "date-fns": "^3.6.0", "eslint-config-next": "^15.0.0-rc.0", - "framer-motion": "^11.9.0", + "framer-motion": "^11.11.1", "lodash": "^4.17.21", "lucide-react": "^0.394.0", "mobx": "^6.13.3", diff --git a/yarn.lock b/yarn.lock index ee4d4002..0ca2069f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3750,10 +3750,10 @@ framer-motion@6.5.1: optionalDependencies: "@emotion/is-prop-valid" "^0.8.2" -framer-motion@^11.9.0: - version "11.11.0" - resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-11.11.0.tgz#1814a7abaf69d897fac2ae9e9d6db3b6151d6f29" - integrity sha512-H6Pv12fcXaebinvnLDabTS9vHwtJKAo7XsnVeNLm5t8Yq5LuVvQ3DtL/2yBa2kGmhdIgx9cw8mbj6I8PYx7jPA== +framer-motion@^11.11.1: + version "11.11.1" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-11.11.1.tgz#84c4bf333b445ef8abc59a5567a197b8bc0cd6cb" + integrity sha512-Ucr9eHSrk0d+l6vyl9fvq6omh/PAWHjS+PlczpsoUdhJo1TuF3ULWJNuAMnpWQ1dGyPOyoUVuYlUKjE/s8dyCA== dependencies: tslib "^2.4.0"