diff --git a/app/starnet/page.tsx b/app/starnet/page.tsx index 88ed4522..66dcd382 100644 --- a/app/starnet/page.tsx +++ b/app/starnet/page.tsx @@ -4,11 +4,12 @@ import React from "react"; import StarnetLayout from "@/components/Layout/Starnet"; import MissionPathway from "@/components/Missions/Pathway"; import ProfileCardModal from "@/components/profile/form"; +import StructureMissionGuide, { StructureMissionGuideMobile } from "@/components/Layout/Guide"; export default function Starnet() { return ( - + ); }; \ No newline at end of file diff --git a/components/Data/unlockNewDataSources.tsx b/components/Data/unlockNewDataSources.tsx index d6265df7..252f6002 100644 --- a/components/Data/unlockNewDataSources.tsx +++ b/components/Data/unlockNewDataSources.tsx @@ -169,18 +169,22 @@ export function DataSourcesModal({ structureId, structure }: DataSourcesModalPro .eq("item", structureId) .single(); + const { data: updateDataO } = await supabase + .from("missions") + .insert([{ user: session.user.id, time_of_completion: new Date().toISOString(), mission: 200000015 }]); + if (error) throw error; const newConfiguration: { "missions unlocked"?: string[] } = data?.configuration || {}; if (!newConfiguration["missions unlocked"]) { newConfiguration["missions unlocked"] = []; - } + }; const missionsUnlocked = newConfiguration["missions unlocked"]; if (!missionsUnlocked.includes(item.identifier)) { missionsUnlocked.push(item.identifier); - } + }; const { error: updateError } = await supabase .from("inventory") diff --git a/components/Layout/BottomMenu.tsx b/components/Layout/BottomMenu.tsx index 70949701..78587f8b 100644 --- a/components/Layout/BottomMenu.tsx +++ b/components/Layout/BottomMenu.tsx @@ -6,7 +6,7 @@ import { useState } from "react"; const menuItems = [ { icon: Globe, label: "Planet", href: "/" }, { icon: Pickaxe, label: "Mining", href: "/scenes/mining" }, - { icon: Star, label: "Travel", href: "/scenes/travel" }, + { icon: Star, label: "Discoveries", href: "/starnet/feed" }, { icon: HelpCircle, label: "Guide", diff --git a/components/Layout/Guide.tsx b/components/Layout/Guide.tsx index 57bd4e95..eca39645 100644 --- a/components/Layout/Guide.tsx +++ b/components/Layout/Guide.tsx @@ -2,13 +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, CloudHail, HelpCircle, LightbulbIcon, LucideTestTubeDiagonal, Pickaxe, Telescope, TestTube2, TreeDeciduous } from "lucide-react"; +import { ChevronLeft, HelpCircleIcon, ChevronRight, CloudHail, HelpCircle, LightbulbIcon, LucideTestTubeDiagonal, Pickaxe, Telescope, TestTube2, TreeDeciduous, XCircle, Shapes, Expand } from "lucide-react"; import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react"; import MissionPathway from "../Missions/Pathway"; import { useActivePlanet } from "@/context/ActivePlanet"; interface Mission { - id: number; + id: number | number[]; name: string; description: string; icon: React.ElementType; @@ -23,7 +23,7 @@ interface DialogueStep { const astronomyMissions: Mission[] = [ { - id: 3000001 | 20000004 | 3000002, + id: [3000001, 20000004, 3000002], name: "Complete an astronomy mission using your telescope", description: "Click on the 'Telescope' structure to make some classifications", icon: Telescope, @@ -31,17 +31,18 @@ const astronomyMissions: Mission[] = [ requiredItem: 3103, }, { - id: 10000001, - name: "This is a test mission", - description: 'Not needed', - icon: LightbulbIcon, - color: 'text-yellow-300', - }, + id: 200000015, + name: "Research Disk Detector project", + description: "Use your telescope to research the Disk Detector project, where you'll be able to discover early solar systems", + icon: Shapes, + color: 'text-purple-300', + requiredItem: 3103, + } ]; const biologistMissions: Mission[] = [ { - id: 3000004 | 3000004, + id: [3000004 | 3000004], name: "Classify some animals using your Biodome", description: "Click on the 'Biodome' structure to make some classifications", icon: TreeDeciduous, @@ -52,7 +53,7 @@ const biologistMissions: Mission[] = [ const meteorologyMissions: Mission[] = [ { - id: 3000010 | 20000007, + id: [3000010 | 20000007], name: "Study some weather events using your atmospheric probe", description: "Click on your LIDAR module to make some classifications", icon: CloudHail, @@ -83,6 +84,20 @@ const globalMissions: Mission[] = [ icon: Telescope, color: 'text-purple-300', }, + { + id: 1, + name: "Continue researching & investigating", + description: "Keep researching new projects and building new structures, and wait for new missions and expeditions to be added", + icon: LightbulbIcon, + color: 'text-yellow-300', + }, + { + id: 2, + name: "Vote & advise other's discoveries", + description: "Click on the 'Discoveries' button to view and vote on other player\'s discoveries", + icon: LucideTestTubeDiagonal, + color: 'text-blue-300', + }, ]; // Research station - walk the user through this. Then upload data, verify/vet (consensus), then we introduce travel. Add a "close"/swipe-down option so that the tutorial section can be hidden/minimised. Then we go through the guide for the different views....and determine the differentials from Pathway.tsx and this new list @@ -104,6 +119,9 @@ const StructureMissionGuide = () => { const [minimized, setMinimized] = useState(false); const [ownedItems, setOwnedItems] = useState([]); const [scrollableMissions, setScrollableMissions] = useState([]); + const [showWelcome, setShowWelcome] = useState(false); + const [showPopup, setShowPopup] = useState(false); + const [showModal, setShowModal] = useState(false); // State to manage modal visibility const categories = [ { missions: astronomyMissions, name: 'Astronomer' }, @@ -121,7 +139,7 @@ const StructureMissionGuide = () => { .select('item') .eq('owner', session.user.id) .eq('anomaly', activePlanet.id) - .in('item', [3103, 3104, 3105, 3106]); + .in('item', [3103, 3104, 3105]); if (inventoryError) throw inventoryError; @@ -147,6 +165,9 @@ const StructureMissionGuide = () => { } else { setCurrentCategory(Math.floor(Math.random() * categories.length)); // Random category if no specific items are owned } + + setShowWelcome(completedMissionIds.length === 0); + } catch (error) { console.error("Error fetching inventory or missions:", error); } @@ -158,9 +179,10 @@ const StructureMissionGuide = () => { }, [session, activePlanet, supabase]); useEffect(() => { + // Display category-specific missions followed by global missions const missionsToDisplay = [ - ...categories[currentCategory].missions.slice(0, 2), // Get only the first 2 missions - ...globalMissions.slice(0, 2), // Add 2 global missions + ...categories[currentCategory].missions, // Category missions + ...globalMissions, // Global missions ]; setScrollableMissions(missionsToDisplay); }, [currentCategory]); @@ -169,84 +191,328 @@ const StructureMissionGuide = () => { return requiredItem ? ownedItems.includes(requiredItem) : false; }; + const renderMission = (mission: Mission) => { + const missionId = Array.isArray(mission.id) ? mission.id[0] : mission.id; + const isCompleted = completedMissions.includes(missionId); + + return ( + + + +
+

+ {mission.name} +

+

+ {mission.description} +

+
+
+
+ ); + }; + return (
- {minimized ? ( - - ) : ( - +
{/* Hide everything below md */} + -
-

- Mission Guide for {categories[currentCategory].name} Pathway -

+
+ + {/* Expansion Button */} + +
+ + {showPopup && ( +
+
+
+

Welcome!

+ +
+

+ Follow this mission guide for a walkthrough of different projects and actions. Use your research station (Plus icon) to unlock new projects and data sources. +

+
+
+ )} + +
+

+ Mission Guide for {categories[currentCategory].name} Pathway +

-
-

- Welcome! Build structures like the Telescope to complete missions and expand your research. - Click the 'Guide' button to view your missions. -

+
+ {scrollableMissions.map(renderMission)}
+ + +
- {/* Scrollable Missions Section */} -
-
- {scrollableMissions.map((mission) => ( -
- - - -
-

- {mission.name} -

-

{mission.description}

- {userHasRequiredItem(mission.requiredItem) && ( - Ready to complete! - )} -
-
-
+ {/* Modal for expanded view */} + + {showModal && ( // Only show modal if showModal state is true + +
+
+

Mission Guide

+ +
+ {/* Modal Content */} +
+
+ )} +
+
+ ); +}; + +export default StructureMissionGuide; + +export const StructureMissionGuideMobile = () => { + const supabase = useSupabaseClient(); + const session = useSession(); + const { activePlanet } = useActivePlanet(); + + const [completedMissions, setCompletedMissions] = useState([]); + const [loading, setLoading] = useState(true); + const [currentCategory, setCurrentCategory] = useState(0); + const [minimized, setMinimized] = useState(false); + const [ownedItems, setOwnedItems] = useState([]); + const [scrollableMissions, setScrollableMissions] = useState([]); + const [showWelcome, setShowWelcome] = useState(false); + const [showPopup, setShowPopup] = useState(false); + const [showModal, setShowModal] = useState(false); // State to manage modal visibility + + const categories = [ + { missions: astronomyMissions, name: 'Astronomer' }, + { missions: biologistMissions, name: 'Biologist' }, + { missions: meteorologyMissions, name: 'Meteorologist' }, + ]; + + useEffect(() => { + async function fetchInventoryAndCompletedMissions() { + if (!session?.user?.id || !activePlanet?.id) return; + + try { + const { data: inventoryData, error: inventoryError } = await supabase + .from('inventory') + .select('item') + .eq('owner', session.user.id) + .eq('anomaly', activePlanet.id) + .in('item', [3103, 3104, 3105]); + + if (inventoryError) throw inventoryError; + + const ownedItems = inventoryData.map((inv: { item: number }) => inv.item); + setOwnedItems(ownedItems); + + const { data: missionData, error: missionError } = await supabase + .from('missions') + .select('mission') + .eq('user', session.user.id); + + if (missionError) throw missionError; + + const completedMissionIds = missionData.map((mission: { mission: number }) => mission.mission); + setCompletedMissions(completedMissionIds); + + if (ownedItems.includes(3103)) { + setCurrentCategory(0); // Astronomy + } else if (ownedItems.includes(3104)) { + setCurrentCategory(1); // Biology + } else if (ownedItems.includes(3105)) { + setCurrentCategory(2); // Meteorology + } else { + setCurrentCategory(Math.floor(Math.random() * categories.length)); // Random category if no specific items are owned + } + + setShowWelcome(completedMissionIds.length === 0); + + } catch (error) { + console.error("Error fetching inventory or missions:", error); + } + + setLoading(false); + } + + fetchInventoryAndCompletedMissions(); + }, [session, activePlanet, supabase]); + + useEffect(() => { + // Display category-specific missions followed by global missions + const missionsToDisplay = [ + ...categories[currentCategory].missions, // Category missions + ...globalMissions, // Global missions + ]; + setScrollableMissions(missionsToDisplay); + }, [currentCategory]); + + const userHasRequiredItem = (requiredItem?: number) => { + return requiredItem ? ownedItems.includes(requiredItem) : false; + }; + + const renderMission = (mission: Mission) => { + const missionId = Array.isArray(mission.id) ? mission.id[0] : mission.id; + const isCompleted = completedMissions.includes(missionId); + + return ( + + + +
+

+ {mission.name} +

+

+ {mission.description} +

+
+
+
+ ); + }; + + return ( +
+ {minimized ? ( + + ) : ( + + +
+ + + {/* Expansion Button */} + +
+ + {showPopup && ( +
+
+
+

Welcome!

+
- ))} +

+ Follow this mission guide for a walkthrough of different projects and actions. Use your research station (Plus icon) to unlock new projects and data sources. +

+
+ )} + +
+

+ Mission Guide for {categories[currentCategory].name} Pathway +

+
+ +
+ + +
+ +
+ {scrollableMissions.map(renderMission)}
)} + + {/* Modal for expanded view */} + + {showModal && ( // Only show modal if showModal state is true + +
+
+

Mission Guide

+ +
+
+ {scrollableMissions.map(renderMission)} {/* Display expanded list of missions */} +
+
+
+ )} +
); -}; - -export default StructureMissionGuide; \ No newline at end of file +}; \ No newline at end of file