Skip to content

Commit

Permalink
💇🏻🏄🏼‍♀️ ↝ [SSM-15 SSM-38]: Community missions are presented alongside…
Browse files Browse the repository at this point in the history
… the playguide
  • Loading branch information
Gizmotronn committed Oct 26, 2024
1 parent e3d9c90 commit 92b6e38
Show file tree
Hide file tree
Showing 7 changed files with 241 additions and 13 deletions.
1 change: 0 additions & 1 deletion app/starnet/consensus/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import StationsOnPlanet from "@/components/Structures/Community/ViewAllStations"
export default function TestPage() {
return (
<StarnetLayout>
<CreateCommunityStation />
<StationsOnPlanet />
</StarnetLayout>
);
Expand Down
2 changes: 1 addition & 1 deletion app/starnet/requests/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import StarnetLayout from "@/components/Layout/Starnet";
import CommunityMissionList from "@/components/Missions/CommunityMissionsList";
import CommunityMissionList from "@/components/Missions/Requests";

export default function CMEPage() {
return (
Expand Down
192 changes: 192 additions & 0 deletions components/Missions/CommunityMissions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { MapPin, Rocket, Navigation } from "lucide-react";
import Link from "next/link";
import { useActivePlanet } from "@/context/ActivePlanet";
import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react";
import CommunityMissionList from "./Requests";

const missions = [
{ id: 1, title: "Clean up Space Debris", location: "Orbit", reward: "500 credits" },
{ id: 2, title: "Alien Flora Survey", location: "Jungle", reward: "300 credits" },
{ id: 3, title: "Mineral Extraction", location: "Mountains", reward: "600 credits" },
{ id: 4, title: "Atmospheric Data Collection", location: "Sky City", reward: "400 credits" },
];

const stations = [
{ id: 31011, name: "Greenhouse" },
{ id: 31012, name: "Weather balloon" },
{ id: 31013, name: "Space telescope" },
];

export default function CommunityMissions() {
const supabase = useSupabaseClient();
const session = useSession();
const { activePlanet } = useActivePlanet();

const [stationStatus, setStationStatus] = useState<Record<number, boolean>>({});

useEffect(() => {
const fetchStationData = async () => {
try {
if (!activePlanet?.id) return;

const { data, error } = await supabase
.from("inventory")
.select("item")
.eq("anomaly", activePlanet?.id)
.in("item", stations.map((station) => station.id));

if (error) throw error;

const existingStationIds = new Set(data.map((row: { item: number }) => row.item));
const statusMap: Record<number, boolean> = {};

stations.forEach((station) => {
statusMap[station.id] = existingStationIds.has(station.id);
});

setStationStatus(statusMap);
} catch (error) {
console.error("Error fetching station data:", error);
}
};

fetchStationData();
}, [activePlanet, supabase]);

const handleBuildClick = async (stationName: string) => {
await addSpecificStructure(stationName);
};

async function addSpecificStructure(structureType: string) {
if (!session || !activePlanet) {
return;
}

const structureItem = stations.find((station) => station.name === structureType);

if (!structureItem) {
console.error("Invalid structure type");
return;
}

try {
const { error: inventoryError } = await supabase
.from("inventory")
.insert([
{
owner: session?.user.id,
anomaly: activePlanet?.id,
item: structureItem.id,
quantity: 1,
configuration: { Uses: 5 },
},
]);

if (inventoryError) {
throw inventoryError;
}

// Update the status to reflect that the station is now built
setStationStatus((prev) => ({
...prev,
[structureItem.id]: true,
}));
} catch (error: any) {
console.error("Error adding structure to inventory", error.message);
}
}

return (
<div className="bg-[#2C4F64] text-[#CFD1D1] min-h-screen overflow-auto">
<div className="container mx-auto p-4 space-y-6 max-w-2xl">
<h1 className="text-3xl font-bold text-center mb-6 text-[#5FCBC3]">
Available community missions
</h1>

<Card className="bg-[#1D2833] border-[#2C3A4A] border">
<CardHeader>
<CardTitle className="flex items-center gap-2 text-[#5FCBC3]">
<MapPin className="h-6 w-6" />
Community Stations
</CardTitle>
<CardDescription className="text-[#CFD1D1] opacity-80">
Community stations are facilities where users can add and collate new data, collaborate on combined missions and pool resources. If your planet or area doesn't have a station you need, you can create one for free.
</CardDescription>
</CardHeader>
<CardContent>
<ul className="space-y-4">
{stations.map((station) => (
<li key={station.id}>
<Card
className={`bg-[#2C3A4A] border ${
stationStatus[station.id] ? "border-[#85DDA2]" : "border-[#5FCBC3]"
}`}
>
<CardHeader>
<CardTitle className="text-[#CFD1D1]">{station.name}</CardTitle>
</CardHeader>
<CardContent>
{stationStatus[station.id] ? (
<Button variant="outline" className="border-[#85DDA2] text-[#85DDA2] hover:bg-[#85DDA2] hover:text-[#1D2833]" asChild>
<Link href={`/starnet/consensus`}>
<Navigation className="mr-2 h-4 w-4" />
Navigate & browse missions
</Link>
</Button>
) : (
<Button
variant="outline"
className="border-[#5FCBC3] text-[#5FCBC3] hover:bg-[#5FCBC3] hover:text-[#1D2833]"
onClick={() => handleBuildClick(station.name)}
>
Build Station
</Button>
)}
</CardContent>
</Card>
</li>
))}
</ul>
</CardContent>
</Card>

{/* <Card className="bg-[#1D2833] border-[#2C3A4A] border">
<CardHeader>
<CardTitle className="flex items-center gap-2 text-[#5FCBC3]">
<Rocket className="h-6 w-6" />
Available Missions
</CardTitle>
<CardDescription className="text-[#CFD1D1] opacity-80">
Complete missions to earn rewards
</CardDescription>
</CardHeader>
<CardContent>
<ul className="space-y-4">
{missions.map((mission) => (
<li key={mission.id}>
<Card className="bg-[#2C3A4A] border-[#5FCBC3] border">
<CardHeader>
<CardTitle className="text-[#CFD1D1]">{mission.title}</CardTitle>
<CardDescription className="text-[#CFD1D1] opacity-80">
Location: {mission.location}
</CardDescription>
</CardHeader>
<CardContent>
<p className="text-sm mb-2 text-[#5FCBC3]">Reward: {mission.reward}</p>
<Button className="bg-[#5FCBC3] text-[#1D2833] hover:bg-[#CFD1D1] hover:text-[#1D2833]" asChild>
<Link href={`/missions/${mission.id}`}>Start Mission</Link>
</Button>
</CardContent>
</Card>
</li>
))}
</ul>
</CardContent>
</Card> */}
</div>
</div>
);
};
20 changes: 16 additions & 4 deletions components/Missions/Pathway.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SwitchPlanet from "../(scenes)/travel/SolarSystem";
import { DataSourcesModal } from "../Data/unlockNewDataSources";
import Link from "next/link";
import { Button } from "../ui/button";
import CommunityMissions from "./CommunityMissions";

type Planet = "Earth" | "Mars" | "Mercury" | "New Planet";
type Mission = {
Expand Down Expand Up @@ -190,6 +191,10 @@ export default function MissionPathway() {
setSelectedPlayStyle(playStyle);
};

const handleBackButtonClick = () => {
setSelectedPlayStyle(null);
};

useEffect(() => {
const fetchCompletedMissions = async () => {
if (!session) return;
Expand All @@ -214,9 +219,9 @@ export default function MissionPathway() {
const planetMissions = missionsData[playStyle as PlayStyle][planet as Planet];
if (planetMissions) {
allMissionsList.push(...planetMissions);
}
}
}
};
};
};

setAllMissions(allMissionsList);
fetchCompletedMissions();
Expand All @@ -241,7 +246,7 @@ export default function MissionPathway() {
}
}
setFilteredMissions(allMissionsList);
}
};
};

fetchMissionsByPlayStyle();
Expand Down Expand Up @@ -272,9 +277,16 @@ export default function MissionPathway() {
>
Meteorologist
</button>
<CommunityMissions />
</div>
) : (
<div className="flex flex-col gap-8 max-w-screen-md mx-auto">
<button
onClick={handleBackButtonClick}
className="self-center px-6 py-3 bg-red-600 text-white text-lg rounded-lg hover:bg-red-500 transition-colors mb-4"
>
Go Back
</button>
{filteredMissions.map((mission) => (
<div
key={mission.id}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const missions: CommunityMission[] = [
{
id: 1,
title: "Build Greenhouses",
steps: [
steps: [
"Classify some animals on Earth",
"Fly to a planet of your choice and create a community mission",
"Share your structure - now everyone can use your greenhouse on that planet",
Expand Down
12 changes: 6 additions & 6 deletions components/Structures/Build/CreateDedicatedStructure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function CreateStructure({ structureType }: { structureType: string }) {

items.forEach(item => {
if (item.ItemCategory === 'Structure') {
map[item.name] = item; // Store the entire item
map[item.name] = item;
}
});

Expand All @@ -41,7 +41,7 @@ export function CreateStructure({ structureType }: { structureType: string }) {
if (!session || !activePlanet) {
setLoading(false);
return;
}
};

const structureItem = structureItemMap[structureType];

Expand All @@ -59,21 +59,21 @@ export function CreateStructure({ structureType }: { structureType: string }) {
{
owner: session.user.id,
anomaly: activePlanet.id,
item: structureItem.id, // Use the item id from the object
item: structureItem.id,
quantity: 1,
configuration: { Uses: 5 },
},
]);

if (inventoryError) {
throw inventoryError;
}
};
} catch (error: any) {
console.error("Error adding structure to inventory", error.message);
} finally {
setLoading(false);
}
}
};
};

return (
<div className="max-w-full max-h-[90vh] w-full sm:w-[90vw] h-full sm:h-[90vh] p-0 bg-gradient-to-br from-[#1a1b26] via-[#292e42] to-[#565f89] rounded-3xl overflow-hidden">
Expand Down
25 changes: 25 additions & 0 deletions components/ui/modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ReactNode } from "react";

interface ModalProps {
isOpen: boolean;
onClose: () => void;
children: ReactNode;
}

export function Modal({ isOpen, onClose, children }: ModalProps) {
if (!isOpen) return null;

return (
<div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50">
<div className="bg-[#2C4F64] rounded-lg shadow-lg p-6 max-w-lg w-full relative">
<button
onClick={onClose}
className="absolute top-2 right-2 text-[#CFD1D1] hover:text-white"
>
&times;
</button>
{children}
</div>
</div>
);
};

0 comments on commit 92b6e38

Please sign in to comment.