Skip to content

Commit 157a622

Browse files
committed
🐡🪁 ↝ [SSM-57 SSM-55 SSM-56 SSM-40 SSC-30 SSM-54]: Updating some mining views, new ideas/missions integrated into the flow
1 parent 2a5e5c9 commit 157a622

File tree

10 files changed

+257
-340
lines changed

10 files changed

+257
-340
lines changed

app/scenes/mining/page.tsx

+7-11
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { useActivePlanet } from "@/context/ActivePlanet";
55
import MineralDeposits from "@/components/Structures/Mining/Archive/AvailableDeposits";
66
import { SelectMineralPanel } from "@/components/Structures/Mining/Archive/MiningPanels";
77
import MineralsInventoryGrid from "@/components/Inventory/mineralsPanel";
8-
import { MiningComponentComponent } from "@/components/Structures/Mining/Mining";
9-
import { Card } from "@/components/ui/card";
10-
import { Button } from "@/components/ui/button";
8+
import { MiningComponent } from "@/components/Structures/Mining/Mining";
119
import StarnetLayout from "@/components/Layout/Starnet";
10+
import { EarthActionSceneLayout, EarthViewLayout } from "@/components/(scenes)/planetScene/layout";
11+
import StructureMissionGuide from "@/components/Layout/Guide";
1212

1313
enum Step {
1414
MineralDeposits = "MINERAL_DEPOSITS",
@@ -17,14 +17,10 @@ enum Step {
1717

1818
export default function Mining() {
1919
return (
20-
<StarnetLayout>
21-
<main className="container mx-auto px-4 relative z-10">
22-
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
23-
24-
</div>
25-
<MiningComponentComponent />
26-
</main>
27-
</StarnetLayout>
20+
<EarthActionSceneLayout>
21+
<MiningComponent />
22+
<StructureMissionGuide />
23+
</EarthActionSceneLayout>
2824
);
2925
};
3026

components/(scenes)/planetScene/layout.tsx

+18-3
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ interface PlanetViewLayoutProps {
1717
children: React.ReactNode[];
1818
};
1919

20-
interface PlanetViewLayoutProps {
21-
children: React.ReactNode[];
20+
interface PlanetActionSceneProps {
21+
children: React.ReactNode;
2222
};
2323

2424
const PlanetViewLayout: React.FC<PlanetViewLayoutProps> = ({ children }) => {
@@ -170,7 +170,7 @@ export const EarthViewLayout: React.FC<PlanetViewLayoutProps> = ({
170170
/>
171171

172172
<div className="relative flex flex-1 z-10">
173-
<VerticalToolbar />
173+
{/* <VerticalToolbar /> */}
174174

175175
<div className="relative flex flex-col flex-1">
176176
{children.slice(0, 2).map((child, index) => (
@@ -202,4 +202,19 @@ export const EarthViewLayout: React.FC<PlanetViewLayoutProps> = ({
202202
</div>
203203
</div>
204204
);
205+
};
206+
207+
export const EarthActionSceneLayout: React.FC<PlanetActionSceneProps> = ({
208+
children,
209+
}) => {
210+
return (
211+
<div className="relative min-h-screen h-screen w-full flex flex-col">
212+
<img
213+
className="absolute inset-0 w-full h-full object-cover"
214+
src="/assets/Backdrops/Earth.png"
215+
alt="Earth Background"
216+
/>
217+
{children}
218+
</div>
219+
);
205220
};

components/Layout/BottomMenu.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { Globe, Rss, HelpCircle, Star } from "lucide-react";
1+
import { Globe, HelpCircle, Star, Pickaxe } from "lucide-react";
22
import { usePathname } from "next/navigation";
33
import Link from "next/link";
44
import { useState } from "react";
55

66
const menuItems = [
77
{ icon: Globe, label: "Planet", href: "/" },
8-
{ icon: Rss, label: "Mining", href: "/scenes/mining" },
8+
{ icon: Pickaxe, label: "Mining", href: "/scenes/mining" },
99
{ icon: Star, label: "Travel", href: "/scenes/travel" },
1010
{
1111
icon: HelpCircle,

components/Layout/Guide.tsx

+132-66
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@ import React, { useEffect, useState } from "react";
22
import { Button } from "../ui/button";
33
import { Card, CardContent } from "../ui/card";
44
import { motion, AnimatePresence } from "framer-motion";
5-
import { ChevronLeft, ChevronRight, CloudHail, HelpCircle, LightbulbIcon, Telescope, TreeDeciduous } from "lucide-react";
5+
import { ChevronLeft, ChevronRight, CloudHail, HelpCircle, LightbulbIcon, LucideTestTubeDiagonal, Pickaxe, Telescope, TestTube2, TreeDeciduous } from "lucide-react";
66
import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react";
77
import MissionPathway from "../Missions/Pathway";
8+
import { useActivePlanet } from "@/context/ActivePlanet";
89

910
interface Mission {
1011
id: number;
1112
name: string;
1213
description: string;
1314
icon: React.ElementType;
1415
color: string;
16+
requiredItem?: number;
1517
};
1618

1719
interface DialogueStep {
@@ -26,6 +28,7 @@ const astronomyMissions: Mission[] = [
2628
description: "Click on the 'Telescope' structure to make some classifications",
2729
icon: Telescope,
2830
color: 'text-cyan-300',
31+
requiredItem: 3103,
2932
},
3033
{
3134
id: 10000001,
@@ -43,6 +46,7 @@ const biologistMissions: Mission[] = [
4346
description: "Click on the 'Biodome' structure to make some classifications",
4447
icon: TreeDeciduous,
4548
color: 'text-green-300',
49+
requiredItem: 3104,
4650
},
4751
];
4852

@@ -53,23 +57,53 @@ const meteorologyMissions: Mission[] = [
5357
description: "Click on your LIDAR module to make some classifications",
5458
icon: CloudHail,
5559
color: 'text-blue-300',
60+
requiredItem: 3105,
61+
},
62+
];
63+
64+
const globalMissions: Mission[] = [
65+
{
66+
id: 200000015,
67+
name: "Research a new module",
68+
description: 'Click on your structure and then the "Research" tab to unlock new projects and data sources to contribute to!',
69+
icon: TestTube2,
70+
color: 'text-purple-300',
71+
},
72+
{
73+
id: 200000013,
74+
name: "Collect some fuel",
75+
description: "Click on the mining tab to visit some mineral deposits your probes have found and mine them for fuel",
76+
icon: Pickaxe,
77+
color: 'text-red-300',
78+
},
79+
{
80+
id: 30000001,
81+
name: "Discover a new planet",
82+
description: "Create and use a telescope to discover a new planet using the Planet Hunters module",
83+
icon: Telescope,
84+
color: 'text-purple-300',
5685
},
5786
];
5887

5988
// 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
6089
// As well as researching for other projects/mission modules that aren't in `mission-selector`
90+
// We'll also need to update this for different planets & chapters
6191

6292
const dialogueSteps: DialogueStep[] = [
6393

6494
];
6595

66-
export default function StructureMissionGuide() {
96+
const StructureMissionGuide = () => {
6797
const supabase = useSupabaseClient();
6898
const session = useSession();
99+
const { activePlanet } = useActivePlanet();
100+
69101
const [completedMissions, setCompletedMissions] = useState<number[]>([]);
70102
const [loading, setLoading] = useState(true);
71103
const [currentCategory, setCurrentCategory] = useState(0);
72-
const [minimized, setMinimized] = useState(false); // State to handle minimization
104+
const [minimized, setMinimized] = useState(false);
105+
const [ownedItems, setOwnedItems] = useState<number[]>([]);
106+
const [scrollableMissions, setScrollableMissions] = useState<Mission[]>([]);
73107

74108
const categories = [
75109
{ missions: astronomyMissions, name: 'Astronomer' },
@@ -78,57 +112,79 @@ export default function StructureMissionGuide() {
78112
];
79113

80114
useEffect(() => {
81-
async function fetchCompletedMissions() {
82-
if (!session?.user?.id) return;
83-
84-
const { data, error } = await supabase
85-
.from('missions')
86-
.select('mission')
87-
.eq('user', session.user.id);
88-
89-
if (error) {
90-
console.error("Error fetching completed missions:", error);
91-
} else {
92-
const completedMissionIds = data.map((mission: { mission: number }) => mission.mission);
115+
async function fetchInventoryAndCompletedMissions() {
116+
if (!session?.user?.id || !activePlanet?.id) return;
117+
118+
try {
119+
const { data: inventoryData, error: inventoryError } = await supabase
120+
.from('inventory')
121+
.select('item')
122+
.eq('owner', session.user.id)
123+
.eq('anomaly', activePlanet.id)
124+
.in('item', [3103, 3104, 3105, 3106]);
125+
126+
if (inventoryError) throw inventoryError;
127+
128+
const ownedItems = inventoryData.map((inv: { item: number }) => inv.item);
129+
setOwnedItems(ownedItems);
130+
131+
const { data: missionData, error: missionError } = await supabase
132+
.from('missions')
133+
.select('mission')
134+
.eq('user', session.user.id);
135+
136+
if (missionError) throw missionError;
137+
138+
const completedMissionIds = missionData.map((mission: { mission: number }) => mission.mission);
93139
setCompletedMissions(completedMissionIds);
140+
141+
if (ownedItems.includes(3103)) {
142+
setCurrentCategory(0); // Astronomy
143+
} else if (ownedItems.includes(3104)) {
144+
setCurrentCategory(1); // Biology
145+
} else if (ownedItems.includes(3105)) {
146+
setCurrentCategory(2); // Meteorology
147+
} else {
148+
setCurrentCategory(Math.floor(Math.random() * categories.length)); // Random category if no specific items are owned
149+
}
150+
} catch (error) {
151+
console.error("Error fetching inventory or missions:", error);
94152
}
95153

96154
setLoading(false);
97155
}
98156

99-
fetchCompletedMissions();
100-
}, [session, supabase]);
101-
102-
const handleNextCategory = () => {
103-
setCurrentCategory((prevCategory) => (prevCategory + 1) % categories.length);
104-
};
105-
106-
const handlePreviousCategory = () => {
107-
setCurrentCategory((prevCategory) => (prevCategory - 1 + categories.length) % categories.length);
108-
};
157+
fetchInventoryAndCompletedMissions();
158+
}, [session, activePlanet, supabase]);
109159

110-
const toggleMinimize = () => {
111-
setMinimized(!minimized);
160+
useEffect(() => {
161+
const missionsToDisplay = [
162+
...categories[currentCategory].missions.slice(0, 2), // Get only the first 2 missions
163+
...globalMissions.slice(0, 2), // Add 2 global missions
164+
];
165+
setScrollableMissions(missionsToDisplay);
166+
}, [currentCategory]);
167+
168+
const userHasRequiredItem = (requiredItem?: number) => {
169+
return requiredItem ? ownedItems.includes(requiredItem) : false;
112170
};
113171

114172
return (
115173
<div className="p-4 max-w-6xl mx-auto font-mono">
116174
{minimized ? (
117-
<Button onClick={toggleMinimize} className="bg-blue-600 text-white flex items-center space-x-2">
175+
<Button onClick={() => setMinimized(false)} className="bg-blue-600 text-white flex items-center space-x-2">
118176
<HelpCircle className="w-5 h-5" />
119177
<span>Help</span>
120178
</Button>
121179
) : (
122180
<Card className="overflow-hidden relative bg-gradient-to-r from-gray-900 via-gray-800 to-gray-900 border-2 border-gray-700">
123181
<CardContent className="p-4">
124182
<div className="flex justify-between mb-4 items-center">
125-
{/* Mission Group Header */}
126183
<h2 className="text-xl font-semibold text-gray-300">
127-
Mission guide for {categories[currentCategory].name} pathway
184+
Mission Guide for {categories[currentCategory].name} Pathway
128185
</h2>
129-
130186
<Button
131-
onClick={toggleMinimize}
187+
onClick={() => setMinimized(true)}
132188
className="bg-gray-700 text-gray-300 hover:bg-gray-600 px-2 py-1 text-sm"
133189
>
134190
Minimize
@@ -137,50 +193,60 @@ export default function StructureMissionGuide() {
137193

138194
<div className="flex justify-between mb-4">
139195
<Button
140-
onClick={handlePreviousCategory}
141-
className="bg-gray-700 text-gray-300 hover:bg-gray-600 px-2 py-1 text-sm"
196+
onClick={() => setCurrentCategory((currentCategory - 1 + categories.length) % categories.length)}
197+
className="bg-gray-700 text-gray-300 hover:bg-gray-600 p-2"
198+
disabled={categories.length <= 1}
142199
>
143-
<ChevronLeft className="h-4 w-4" />
200+
<ChevronLeft />
144201
</Button>
145202
<Button
146-
onClick={handleNextCategory}
147-
className="bg-blue-600 text-white hover:bg-blue-500 px-2 py-1 text-sm"
203+
onClick={() => setCurrentCategory((currentCategory + 1) % categories.length)}
204+
className="bg-gray-700 text-gray-300 hover:bg-gray-600 p-2"
205+
disabled={categories.length <= 1}
148206
>
149-
<ChevronRight className="h-4 w-4" />
207+
<ChevronRight />
150208
</Button>
151209
</div>
152210

153-
<div className="grid grid-cols-1 gap-2">
154-
{loading ? (
155-
<p>Loading missions...</p>
156-
) : (
157-
categories[currentCategory].missions.map((mission) => (
158-
<Card
159-
key={mission.id}
160-
className={`cursor-pointer hover:shadow-lg transition-all duration-300 ${
161-
completedMissions.includes(mission.id) ? 'bg-gray-700' : 'bg-gray-800'
162-
} border border-gray-600 relative overflow-hidden`}
163-
>
164-
<CardContent className="p-2 flex items-center">
165-
<mission.icon className={`w-6 h-6 mr-2 ${mission.color}`} />
166-
<div>
167-
<h3 className={`text-xs font-semibold ${mission.color}`}>{mission.name}</h3>
168-
{completedMissions.includes(mission.id) ? (
169-
<p className="text-xs text-gray-400 line-through decoration-dotted decoration-green-400">
170-
{mission.description}
171-
</p>
172-
) : (
173-
<p className="text-xs text-gray-400">{mission.description}</p>
174-
)}
175-
</div>
176-
</CardContent>
177-
</Card>
178-
))
179-
)}
211+
<div className="mb-4 p-4 border border-gray-600 rounded bg-gray-800 text-gray-200">
212+
<p className="mt-1">
213+
Welcome! Build structures like the Telescope to complete missions and expand your research.
214+
Click the 'Guide' button to view your missions.
215+
</p>
216+
</div>
217+
218+
{/* Scrollable Missions Section */}
219+
<div className="overflow-y-auto max-h-40 relative">
220+
<div className="grid grid-cols-1 gap-4">
221+
{scrollableMissions.map((mission) => (
222+
<div key={mission.id} className="flex">
223+
<Card
224+
className={`cursor-pointer hover:shadow-lg transition-all duration-300 ${
225+
completedMissions.includes(mission.id) ? 'bg-gray-700' : 'bg-gray-800'
226+
} border border-gray-600 relative overflow-hidden w-full`}
227+
>
228+
<CardContent className="p-2 flex items-center">
229+
<mission.icon className={`w-6 h-6 mr-2 ${mission.color}`} />
230+
<div>
231+
<h3 className={`font-semibold text-gray-300 ${completedMissions.includes(mission.id) ? 'line-through text-green-400' : ''}`}>
232+
{mission.name}
233+
</h3>
234+
<p className="text-gray-400">{mission.description}</p>
235+
{userHasRequiredItem(mission.requiredItem) && (
236+
<span className="text-green-300 text-sm">Ready to complete!</span>
237+
)}
238+
</div>
239+
</CardContent>
240+
</Card>
241+
</div>
242+
))}
243+
</div>
180244
</div>
181245
</CardContent>
182246
</Card>
183247
)}
184248
</div>
185249
);
186-
};
250+
};
251+
252+
export default StructureMissionGuide;

0 commit comments

Comments
 (0)