From 702f3ef6252d76346d89ec8527ab83e1d10008af Mon Sep 17 00:00:00 2001 From: Gizmotronn Date: Wed, 27 Nov 2024 10:49:29 +1100 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=85=F0=9F=93=BC=20=E2=86=9D=20[SSG-76?= =?UTF-8?q?=20SSG-70=20SSG-77]:=20First=20community=20expedition=20-=20jus?= =?UTF-8?q?t=20missing=20missions/achievements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/scenes/mars/page.tsx | 64 ++++----- .../(scenes)/travel/BoardingPassCard.tsx | 29 ++++- .../(scenes)/travel/DestinationList.tsx | 36 ++++-- components/(scenes)/travel/SolarSystem.tsx | 76 ++++++----- components/Layout/Guide.tsx | 122 ++++++++++++------ 5 files changed, 209 insertions(+), 118 deletions(-) diff --git a/app/scenes/mars/page.tsx b/app/scenes/mars/page.tsx index 862caeaf..4b368296 100644 --- a/app/scenes/mars/page.tsx +++ b/app/scenes/mars/page.tsx @@ -4,12 +4,14 @@ import React, { useEffect, useState } from "react"; import { useSupabaseClient, useSession } from "@supabase/auth-helpers-react"; import { useActivePlanet } from "@/context/ActivePlanet"; -import { EarthViewLayout } from "@/components/(scenes)/planetScene/layout"; +import { EarthActionSceneLayout, EarthViewLayout } from "@/components/(scenes)/planetScene/layout"; import InitialisePlanet from "@/components/(scenes)/planetScene/initialisePlanet"; import StructuresOnPlanet, { AtmosphereStructuresOnPlanet, OrbitalStructuresOnPlanet } from "@/components/Structures/Structures"; import { InventoryStructureItem } from "@/types/Items"; import { PlanetarySystem } from "@/components/(scenes)/planetScene/orbitals/system"; import AllAutomatonsOnActivePlanet from "@/components/Structures/Auto/AllAutomatons"; +import { MiningComponentComponent } from "@/components/mining-component"; +import StructureMissionGuide from "@/components/Layout/Guide"; const MarsView: React.FC = () => { const supabase = useSupabaseClient(); @@ -53,33 +55,37 @@ export default MarsView; const MarsStructures: React.FC = () => { return ( - -
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
-
-
-
- -
-
-
- -
-
+ + + + + // + //
+ //
+ //
+ //
+ // + //
+ //
+ // + //
+ //
+ //
+ //
+ //
+ //
+ // + //
+ //
+ //
+ //
+ //
+ // + //
+ //
+ //
+ // + //
+ //
); }; \ No newline at end of file diff --git a/components/(scenes)/travel/BoardingPassCard.tsx b/components/(scenes)/travel/BoardingPassCard.tsx index 0ead8ef7..de2b3d0f 100644 --- a/components/(scenes)/travel/BoardingPassCard.tsx +++ b/components/(scenes)/travel/BoardingPassCard.tsx @@ -1,7 +1,19 @@ import React from 'react'; -import { BoardingPass } from "@/types/Travel"; import Image from 'next/image'; +// Define the BoardingPass interface +interface BoardingPass { + userName: string; + frequentFlyerNumber: string; + frequentFlyerStatus: string; + departurePlanet: string; + departureTemperature: number; + destinationPlanet: string; + destinationTemperature: number; + rocketType: string; + departureTime: string; // ISO 8601 string +} + interface BoardingPassCardProps { boardingPass: BoardingPass; } @@ -19,10 +31,19 @@ const BoardingPassCard: React.FC = ({ boardingPass }) =>

Flight Information

-

From: {boardingPass.departurePlanet} ({boardingPass.departureTemperature}°C)

-

To: {boardingPass.destinationPlanet} ({boardingPass.destinationTemperature}°C)

+

+ From: {boardingPass.departurePlanet} + ({boardingPass.departureTemperature}°C) +

+

+ To: {boardingPass.destinationPlanet} + ({boardingPass.destinationTemperature}°C) +

Rocket: {boardingPass.rocketType}

-

Departure: {new Date(boardingPass.departureTime).toLocaleString()}

+

+ Departure: + {new Date(boardingPass.departureTime).toLocaleString()} +

diff --git a/components/(scenes)/travel/DestinationList.tsx b/components/(scenes)/travel/DestinationList.tsx index ca843536..f25ab9d6 100644 --- a/components/(scenes)/travel/DestinationList.tsx +++ b/components/(scenes)/travel/DestinationList.tsx @@ -1,15 +1,25 @@ import React from 'react'; -import { Destination } from '@/types/Travel'; + +// Define the Destination interface +interface Destination { + id: string; // Unique identifier for each destination + name: string; // Name of the destination + type: 'solar' | 'exoplanet'; // Type of destination +} interface DestinationListProps { - destinations: Destination[]; - onSelect: (destination: Destination) => void; - selectedDestination: Destination | null; + destinations: Destination[]; // List of destinations + onSelect: (destination: Destination) => void; // Callback when a destination is selected + selectedDestination: Destination | null; // Currently selected destination } -const DestinationList: React.FC = ({ destinations, onSelect, selectedDestination }) => { - const solarDestinations = destinations.filter(d => d.type === 'solar'); - const exoplanets = destinations.filter(d => d.type === 'exoplanet'); +const DestinationList: React.FC = ({ + destinations, + onSelect, + selectedDestination, +}) => { + const solarDestinations = destinations.filter((d) => d.type === 'solar'); + const exoplanets = destinations.filter((d) => d.type === 'exoplanet'); return (
@@ -18,11 +28,13 @@ const DestinationList: React.FC = ({ destinations, onSelec

Solar System

    - {solarDestinations.map(destination => ( + {solarDestinations.map((destination) => (
  • onSelect(destination)} > @@ -34,11 +46,13 @@ const DestinationList: React.FC = ({ destinations, onSelec

    Exoplanets

      - {exoplanets.map(destination => ( + {exoplanets.map((destination) => (
    • onSelect(destination)} > diff --git a/components/(scenes)/travel/SolarSystem.tsx b/components/(scenes)/travel/SolarSystem.tsx index e73eb204..bb119d8a 100644 --- a/components/(scenes)/travel/SolarSystem.tsx +++ b/components/(scenes)/travel/SolarSystem.tsx @@ -60,54 +60,54 @@ export default function SwitchPlanet() { exoplanets: Exoplanet[]; }>({ solarSystem: [ + // { + // id: 10, + // name: "Mercury", + // color: "bg-[#2C3A4A]", + // stats: { gravity: "3.7 m/s²", temp: "430°C" }, + // anomaly: 10, + // planetType: 'Arid', + // initialisationMissionId: 100001, + // travelTime: '30 seconds', + // description: '', + // image: '/assets/Planets/Mercury.png', + // }, + // { + // 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: '', + // image: '/assets/Planets/Venus.png', + // }, { - id: 10, - name: "Mercury", - color: "bg-[#2C3A4A]", - stats: { gravity: "3.7 m/s²", temp: "430°C" }, - anomaly: 10, - planetType: 'Arid', - initialisationMissionId: 100001, - travelTime: '30 seconds', - description: '', - image: '/assets/Planets/Mercury.png', - }, - { - id: 20, - name: "Venus", - color: "bg-yellow-200", - stats: { gravity: "8.87 m/s²", temp: "462°C" }, - anomaly: 20, + id: 40, + name: "Mars", + color: "bg-red-500", + stats: { gravity: "3.71 m/s²", temp: "-63°C" }, + anomaly: 40, planetType: 'Arid', - initialisationMissionId: 200001, + initialisationMissionId: 400001, travelTime: '30 seconds', description: '', - image: '/assets/Planets/Venus.png', + image: '/assets/Planets/Mars.png', }, { - id: 69, + id: 30, // 69 name: "Earth", color: "bg-blue-500", stats: { gravity: "9.8 m/s²", temp: "15°C" }, - anomaly: 69, + anomaly: 30, planetType: 'Lush', initialisationMissionId: 300001, travelTime: '30 seconds', description: '', image: '/assets/Planets/Earth.png', }, - { - 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: '', - image: '/assets/Planets/Mars.png', - }, ], exoplanets: [], }); @@ -513,12 +513,20 @@ export default function SwitchPlanet() {

      {currentPlanet.name}

      {currentPlanet.description}

      - */} +
      + +
      diff --git a/components/Layout/Guide.tsx b/components/Layout/Guide.tsx index b73867ab..383cdcff 100644 --- a/components/Layout/Guide.tsx +++ b/components/Layout/Guide.tsx @@ -2,11 +2,13 @@ import React, { useEffect, useState } from "react"; import { Button } from "../ui/button"; import { Card, CardContent } from "../ui/card"; import { motion, AnimatePresence } from "framer-motion"; -import { ChevronLeft, ChevronRight, HelpCircle, XCircle, Expand, Telescope, TreeDeciduous, CloudHail, LightbulbIcon, LucideTestTubeDiagonal, CameraIcon, Shapes, PersonStandingIcon } from "lucide-react"; +import { ChevronLeft, ChevronRight, HelpCircle, XCircle, Expand, Telescope, TreeDeciduous, CloudHail, LightbulbIcon, LucideTestTubeDiagonal, CameraIcon, Shapes, PersonStandingIcon, Pickaxe, DiamondPercent, Rocket } from "lucide-react"; import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react"; import { useActivePlanet } from "@/context/ActivePlanet"; import MissionInfoModal from "../Missions/MissionInfoModal"; import AllClassifications from "@/content/Starnet/YourClassifications"; +import SwitchPlanet from "../(scenes)/travel/SolarSystem"; +import { MiningComponentComponent } from "../mining-component"; export interface Mission { id: number | number[]; @@ -113,6 +115,33 @@ const globalMissions: Mission[] = [ }, ]; +const communityExpeditions: Mission[] = [ + { + id: 3500011, + name: "Travel to Mars", + description: "Join the community expedition to Mars, where you'll be able to use your scientific tooling & understanding to build mining settlements & infrastructure", + icon: Pickaxe, + color: 'text-red-300', + modalContent: , + }, + { + id: 3500012, + name: "Mine some resources", + description: "Use the rovers you've travelled with to mine some anomalies you and the community have found on Mars. This will allow you to produce some materials & more structures for community use", + icon: DiamondPercent, + color: 'text-cyan-300', + modalContent: + }, + { + id: 3500013, + name: "Return to Earth", + description: "Complete your mission on Mars and return to Earth to continue your research and exploration with the new resources you've obtained from Mars with the rest of the community", + icon: Rocket, + color: 'text-green-300', + modalContent: + }, +]; + const StructureMissionGuide = () => { const supabase = useSupabaseClient(); const session = useSession(); @@ -125,13 +154,25 @@ const StructureMissionGuide = () => { const [ownedItems, setOwnedItems] = useState([]); const [scrollableMissions, setScrollableMissions] = useState([]); + const [hideCompleted, setHideCompleted] = useState(false); + const [isExpanded, setIsExpanded] = useState(false); + const toggleHideCompleted = () => { + setHideCompleted((prev) => !prev); + }; + const toggleHeight = () => { + setIsExpanded((prev) => !prev); + }; + const categories = [ { missions: astronomyMissions, name: 'Astronomer' }, { missions: biologistMissions, name: 'Biologist' }, { missions: meteorologyMissions, name: 'Meteorologist' }, + { + missions: communityExpeditions, + name: "Community Expeditions", + }, ]; - // For modals const [selectedMission, setSelectedMission] = useState(null); const handleMissionClick = (mission: Mission) => { @@ -157,7 +198,6 @@ const StructureMissionGuide = () => { const ownedItems = inventoryData ? inventoryData.map((inv: { item: number }) => inv.item) : []; setOwnedItems(ownedItems); - // Fetch completed missions const { data: missionData } = await supabase .from('missions') .select('mission') @@ -165,19 +205,18 @@ const StructureMissionGuide = () => { const completedMissionIds = missionData ? missionData.map((mission: { mission: number }) => mission.mission) : []; - // Fetch specific votes based on mission's voteOn classification type const voteOnMissions = await Promise.all(globalMissions.map(async (mission) => { if (mission.voteOn) { const { data: specificVotes } = await supabase .from('votes') .select('*') .eq("user_id", session.user.id) - .eq("classificationtype", mission.voteOn); // Check vote classification type + .eq("classificationtype", mission.voteOn); if (specificVotes && specificVotes.length > 0) { - // If the user has voted on this classification, mark the mission as completed + if (Array.isArray(mission.id)) { - completedMissionIds.push(mission.id[0]); // Pushing the first element if mission id is an array + completedMissionIds.push(mission.id[0]); } else { completedMissionIds.push(mission.id); } @@ -185,7 +224,6 @@ const StructureMissionGuide = () => { } })); - // Check tableEntry and tableColumn const additionalChecks = await Promise.all(globalMissions.map(async (mission) => { if (mission.tableEntry && mission.tableColumn) { const { data: tableData } = await supabase @@ -194,7 +232,6 @@ const StructureMissionGuide = () => { .eq(mission.tableColumn, session.user.id); if (tableData && tableData.length > 0) { - // If table data exists, mark mission as completed if (Array.isArray(mission.id)) { completedMissionIds.push(mission.id[0]); // Pushing the first element if mission id is an array } else { @@ -214,28 +251,6 @@ const StructureMissionGuide = () => { fetchInventoryAndCompletedMissions(); }, [session, activePlanet, supabase]); - - useEffect(() => { - const currentMissions = categories[currentCategory].missions; - - const filteredGlobalMissions = globalMissions.filter((mission) => { - if (mission.requiredItem && !ownedItems.includes(mission.requiredItem)) { - return false; - } - return true; - }); - - const missionsToDisplay = [ - ...currentMissions, - ...filteredGlobalMissions, - ]; - - const uniqueMissions = [ - ...new Map(missionsToDisplay.map(mission => [Array.isArray(mission.id) ? mission.id[0] : mission.id, mission])).values(), - ]; - - setScrollableMissions(uniqueMissions); - }, [currentCategory, ownedItems]); const [modalMissionContent, setModalMissionContent] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); @@ -243,6 +258,7 @@ const StructureMissionGuide = () => { useEffect(() => { const currentMissions = categories[currentCategory].missions; + // Filter global missions based on ownership of required items const filteredGlobalMissions = globalMissions.filter((mission) => { if (mission.requiredItem && !ownedItems.includes(mission.requiredItem)) { return false; @@ -250,17 +266,30 @@ const StructureMissionGuide = () => { return true; }); - const missionsToDisplay = [ - ...currentMissions, - ...filteredGlobalMissions, - ]; + // Determine missions to display based on the selected category + const missionsToDisplay = currentCategory === 3 + ? [...currentMissions] + : [ + ...currentMissions, + ...filteredGlobalMissions, + ...communityExpeditions, + ]; + // Ensure missions are unique by ID const uniqueMissions = [ - ...new Map(missionsToDisplay.map(mission => [mission.id, mission])).values(), + ...new Map(missionsToDisplay.map((mission) => [Array.isArray(mission.id) ? mission.id[0] : mission.id, mission])).values(), ]; - setScrollableMissions(uniqueMissions); - }, [currentCategory, ownedItems]); + // Apply completed missions filter + const filteredMissions = hideCompleted + ? uniqueMissions.filter((mission) => { + const missionId = Array.isArray(mission.id) ? mission.id[0] : mission.id; + return !completedMissions.includes(missionId); + }) + : uniqueMissions; + + setScrollableMissions(filteredMissions); + }, [currentCategory, ownedItems, hideCompleted]); const nextCategory = () => { setCurrentCategory((prev) => (prev + 1) % categories.length); @@ -311,13 +340,23 @@ const StructureMissionGuide = () => { +
      +

      {categories[currentCategory].name}

      + +
      -
      +
      {loading ? (
      Loading...
      ) : ( @@ -358,6 +397,10 @@ export const StructureMissionGuideMobile = () => { { missions: astronomyMissions, name: 'Astronomer' }, { missions: biologistMissions, name: 'Biologist' }, { missions: meteorologyMissions, name: 'Meteorologist' }, + { + missions: communityExpeditions, + name: "Community Expeditions", + }, ]; useEffect(() => { @@ -410,7 +453,6 @@ export const StructureMissionGuideMobile = () => { }, [session, activePlanet, supabase]); useEffect(() => { - // Display category-specific missions followed by global missions const missionsToDisplay = [ ...categories[currentCategory].missions, // Category missions ...globalMissions, // Global missions