@@ -2,16 +2,18 @@ import React, { useEffect, useState } from "react";
2
2
import { Button } from "../ui/button" ;
3
3
import { Card , CardContent } from "../ui/card" ;
4
4
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" ;
6
6
import { useSession , useSupabaseClient } from "@supabase/auth-helpers-react" ;
7
7
import MissionPathway from "../Missions/Pathway" ;
8
+ import { useActivePlanet } from "@/context/ActivePlanet" ;
8
9
9
10
interface Mission {
10
11
id : number ;
11
12
name : string ;
12
13
description : string ;
13
14
icon : React . ElementType ;
14
15
color : string ;
16
+ requiredItem ?: number ;
15
17
} ;
16
18
17
19
interface DialogueStep {
@@ -26,6 +28,7 @@ const astronomyMissions: Mission[] = [
26
28
description : "Click on the 'Telescope' structure to make some classifications" ,
27
29
icon : Telescope ,
28
30
color : 'text-cyan-300' ,
31
+ requiredItem : 3103 ,
29
32
} ,
30
33
{
31
34
id : 10000001 ,
@@ -43,6 +46,7 @@ const biologistMissions: Mission[] = [
43
46
description : "Click on the 'Biodome' structure to make some classifications" ,
44
47
icon : TreeDeciduous ,
45
48
color : 'text-green-300' ,
49
+ requiredItem : 3104 ,
46
50
} ,
47
51
] ;
48
52
@@ -53,23 +57,53 @@ const meteorologyMissions: Mission[] = [
53
57
description : "Click on your LIDAR module to make some classifications" ,
54
58
icon : CloudHail ,
55
59
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' ,
56
85
} ,
57
86
] ;
58
87
59
88
// 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
60
89
// 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
61
91
62
92
const dialogueSteps : DialogueStep [ ] = [
63
93
64
94
] ;
65
95
66
- export default function StructureMissionGuide ( ) {
96
+ const StructureMissionGuide = ( ) => {
67
97
const supabase = useSupabaseClient ( ) ;
68
98
const session = useSession ( ) ;
99
+ const { activePlanet } = useActivePlanet ( ) ;
100
+
69
101
const [ completedMissions , setCompletedMissions ] = useState < number [ ] > ( [ ] ) ;
70
102
const [ loading , setLoading ] = useState ( true ) ;
71
103
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 [ ] > ( [ ] ) ;
73
107
74
108
const categories = [
75
109
{ missions : astronomyMissions , name : 'Astronomer' } ,
@@ -78,57 +112,79 @@ export default function StructureMissionGuide() {
78
112
] ;
79
113
80
114
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 ) ;
93
139
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 ) ;
94
152
}
95
153
96
154
setLoading ( false ) ;
97
155
}
98
156
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 ] ) ;
109
159
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 ;
112
170
} ;
113
171
114
172
return (
115
173
< div className = "p-4 max-w-6xl mx-auto font-mono" >
116
174
{ 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" >
118
176
< HelpCircle className = "w-5 h-5" />
119
177
< span > Help</ span >
120
178
</ Button >
121
179
) : (
122
180
< Card className = "overflow-hidden relative bg-gradient-to-r from-gray-900 via-gray-800 to-gray-900 border-2 border-gray-700" >
123
181
< CardContent className = "p-4" >
124
182
< div className = "flex justify-between mb-4 items-center" >
125
- { /* Mission Group Header */ }
126
183
< 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
128
185
</ h2 >
129
-
130
186
< Button
131
- onClick = { toggleMinimize }
187
+ onClick = { ( ) => setMinimized ( true ) }
132
188
className = "bg-gray-700 text-gray-300 hover:bg-gray-600 px-2 py-1 text-sm"
133
189
>
134
190
Minimize
@@ -137,50 +193,60 @@ export default function StructureMissionGuide() {
137
193
138
194
< div className = "flex justify-between mb-4" >
139
195
< 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 }
142
199
>
143
- < ChevronLeft className = "h-4 w-4" />
200
+ < ChevronLeft />
144
201
</ Button >
145
202
< 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 }
148
206
>
149
- < ChevronRight className = "h-4 w-4" />
207
+ < ChevronRight />
150
208
</ Button >
151
209
</ div >
152
210
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 >
180
244
</ div >
181
245
</ CardContent >
182
246
</ Card >
183
247
) }
184
248
</ div >
185
249
) ;
186
- } ;
250
+ } ;
251
+
252
+ export default StructureMissionGuide ;
0 commit comments