Skip to content

Commit 7e27fc7

Browse files
committed
πŸ›ΈπŸŒπŸΌβ€β™€οΈ ↝ [SSG-70 SSM-64 SSG-72 SSG-73 SSG-74]: Structures, deposits & mining handling now included.
1 parent 412641d commit 7e27fc7

File tree

4 files changed

+330
-68
lines changed

4 files changed

+330
-68
lines changed

β€Žcomponents/mining-component.tsx

+229-58
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,6 @@ type Landmark = {
3030
isOpen: boolean
3131
};
3232

33-
const MINERALS = ['Iron', 'Copper', 'Coal', 'Nickel'];
34-
35-
const LANDMARKS: Landmark[] = [
36-
{ id: '1', name: 'Base Camp', description: 'Main operations center for the mining colony.', position: { x: 10, y: 10 }, isOpen: false },
37-
{ id: '2', name: 'Power Plant', description: 'Generates power for the entire mining operation.', position: { x: 80, y: 30 }, isOpen: false },
38-
{ id: '3', name: 'Research Lab', description: 'Conducts studies on Martian geology and potential life.', position: { x: 30, y: 70 }, isOpen: false },
39-
];
40-
4133
export function MiningComponentComponent() {
4234
const supabase = useSupabaseClient();
4335
const session = useSession();
@@ -51,67 +43,149 @@ export function MiningComponentComponent() {
5143
const [inventory, setInventory] = useState<InventoryItem[]>([])
5244
const [isMining, setIsMining] = useState(false)
5345
const [activeMap, setActiveMap] = useState<'2D' | '3D'>('2D')
54-
const [landmarks, setLandmarks] = useState<Landmark[]>(LANDMARKS);
46+
const [landmarks, setLandmarks] = useState<Landmark[]>([]);
5547

5648
useEffect(() => {
57-
const fetchDeposits = async () => {
49+
const fetchLandmarks = async () => {
5850
if (!session?.user?.id || !activePlanet?.id) {
5951
console.error("User or activePlanet is undefined.");
6052
return;
6153
}
6254

63-
const { data, error } = await supabase
55+
// Fetch inventory from Supabase
56+
const { data: inventoryData, error: inventoryError } = await supabase
57+
.from("inventory")
58+
.select("id, item, quantity")
59+
.eq("owner", session.user.id)
60+
.eq("anomaly", activePlanet.id)
61+
.gt("quantity", 0);
62+
63+
if (inventoryError) {
64+
console.error("Error fetching inventory:", inventoryError);
65+
return;
66+
}
67+
68+
// Fetch all item details from API
69+
const res = await fetch('/api/gameplay/inventory');
70+
const items = await res.json();
71+
72+
// Filter for structures and map to landmarks
73+
const structures = inventoryData
74+
?.filter((inventoryItem) =>
75+
items.some(
76+
(item: { id: any; ItemCategory: string }) =>
77+
item.id === inventoryItem.item && item.ItemCategory === "Structure"
78+
)
79+
)
80+
.map((inventoryItem) => {
81+
const itemDetails = items.find(
82+
(item: { id: any }) => item.id === inventoryItem.item
83+
);
84+
85+
return {
86+
id: inventoryItem.id.toString(),
87+
name: itemDetails?.name || "Unknown",
88+
description: itemDetails?.description || "No description available",
89+
position: itemDetails?.position || { x: Math.random() * 100, y: Math.random() * 100 }, // Default to random position
90+
isOpen: false,
91+
};
92+
});
93+
94+
setLandmarks(structures || []);
95+
};
96+
97+
fetchLandmarks();
98+
}, [session, activePlanet, supabase]);
99+
100+
useEffect(() => {
101+
const fetchDepositsAndInventory = async () => {
102+
if (!session?.user?.id || !activePlanet?.id) {
103+
console.error("User or activePlanet is undefined.");
104+
return;
105+
}
106+
107+
// Fetch deposits
108+
const { data: deposits, error: depositsError } = await supabase
64109
.from("mineralDeposits")
65-
.select('id, mineralconfiguration')
66-
.eq('owner', session?.user.id)
67-
.eq('anomaly', activePlanet?.id)
68-
.limit(4);
110+
.select("id, mineralconfiguration")
111+
.eq("owner", session?.user.id)
112+
.eq("anomaly", activePlanet?.id);
69113

70-
if (error) {
71-
console.error("Error fetching mineral deposits:", error);
114+
if (depositsError) {
115+
console.error("Error fetching mineral deposits:", depositsError);
72116
return;
73117
}
74118

75-
const formattedDeposits = data?.map((deposit) => ({
76-
id: deposit.id,
119+
const formattedDeposits = deposits?.map((deposit, index) => ({
120+
id: `${deposit.id}-${index}`, // Ensure uniqueness
77121
name: deposit.mineralconfiguration.mineral || "Unknown",
78122
mineral: deposit.mineralconfiguration.mineral || "Unknown",
79-
amount: deposit.mineralconfiguration.quantity || 0, // Use 'amount'
123+
amount: deposit.mineralconfiguration.quantity || 0,
80124
icon_url: deposit.mineralconfiguration.icon_url || "",
81125
level: deposit.mineralconfiguration.level || 1,
82126
uses: deposit.mineralconfiguration.uses || [],
83127
position: deposit.mineralconfiguration.position || { x: 50, y: 50 },
84128
}));
85129

86130
setMineralDeposits(formattedDeposits || []);
131+
132+
// Fetch inventory and filter structures
133+
const { data: inventoryData, error: inventoryError } = await supabase
134+
.from("inventory")
135+
.select("id, item, quantity")
136+
.eq("owner", session?.user.id)
137+
.eq("anomaly", activePlanet?.id)
138+
.gt("quantity", 0);
139+
140+
if (inventoryError) {
141+
console.error("Error fetching inventory:", inventoryError);
142+
return;
143+
}
144+
145+
// Fetch all items from the API route
146+
const res = await fetch('/api/gameplay/inventory');
147+
const items = await res.json();
148+
149+
// Filter inventory to include only items of type "Structure"
150+
const structures = inventoryData
151+
?.filter((inventoryItem) =>
152+
items.some(
153+
(item: { id: any; ItemCategory: string; }) =>
154+
item.id === inventoryItem.item &&
155+
item.ItemCategory === "Structure"
156+
)
157+
)
158+
.map((inventoryItem) => {
159+
const itemDetails = items.find(
160+
(item: { id: any; }) => item.id === inventoryItem.item
161+
);
162+
return {
163+
id: inventoryItem.id.toString(),
164+
name: itemDetails?.name || "Unknown",
165+
description: itemDetails?.description || "",
166+
amount: inventoryItem.quantity || 0,
167+
icon_url: itemDetails?.icon_url || "",
168+
locationType: itemDetails?.locationType || "Unknown",
169+
};
170+
});
171+
172+
setInventory(structures || []);
173+
setRover({
174+
id: "1",
175+
name: "Mars Rover",
176+
speed: 15,
177+
efficiency: 0.8,
178+
miningLevel: 2,
179+
});
87180
};
88181

89-
fetchDeposits();
90-
}, [session, activePlanet, supabase]);
91-
92-
// useEffect(() => {
93-
// const generateDeposits = () => {
94-
// const deposits: MineralDeposit[] = []
95-
// for (let i = 0; i < 4; i++) {
96-
// const mineral = MINERALS[Math.floor(Math.random() * MINERALS.length)]
97-
// deposits.push({
98-
// id: `${i + 1}`,
99-
// name: mineral,
100-
// amount: Math.floor(Math.random() * 500) + 500,
101-
// position: { x: Math.random() * 80 + 10, y: Math.random() * 80 + 10 },
102-
// })
103-
// }
104-
// return deposits
105-
// }
106-
107-
// setMineralDeposits(generateDeposits())
108-
// setRover({ id: '1', name: 'Mars Rover', speed: 15, efficiency: 0.8, miningLevel: 2 })
109-
// setInventory(MINERALS.map((mineral, index) => ({ id: `${index + 1}`, name: mineral, amount: 0 })))
110-
// }, [])
111-
182+
fetchDepositsAndInventory();
183+
}, [session, activePlanet, supabase]);
184+
112185
const handleDepositSelect = (deposit: MineralDeposit) => {
113-
setSelectedDeposit(deposit)
114-
}
186+
console.log("Deposit selected:", deposit); // Debugging line
187+
setSelectedDeposit(deposit);
188+
};
115189

116190
const handleStartMining = () => {
117191
if (selectedDeposit && rover) {
@@ -138,9 +212,9 @@ export function MiningComponentComponent() {
138212
setTimeout(() => {
139213
setRoverPosition({ x: 5, y: 5 }); // Return to base
140214
setIsMining(false);
141-
updateInventory(selectedDeposit.name, 50); // Add mined resources to inventory
215+
updateInventory(selectedDeposit.name, 50); // Update Supabase with mined resources
142216
setSelectedDeposit(null); // Reset selected deposit
143-
}, 5000); // 5 seconds at deposit
217+
}, 5000); // 5 seconds at deposit
144218
}
145219
};
146220

@@ -150,21 +224,86 @@ export function MiningComponentComponent() {
150224
}
151225
};
152226

153-
const updateInventory = (resourceName: string, amount: number) => {
154-
setInventory(prev => prev.map(item =>
155-
item.name === resourceName ? { ...item, amount: item.amount + amount } : item
156-
))
157-
}
227+
const updateInventory = async (resourceName: string, minedAmount: number) => {
228+
if (!session?.user?.id || !activePlanet?.id) {
229+
console.error("User or activePlanet is undefined.");
230+
return;
231+
}
232+
233+
const existingItem = inventory.find(item => item.name === resourceName);
234+
235+
if (existingItem) {
236+
// Update existing item in inventory
237+
const { error } = await supabase
238+
.from("inventory")
239+
.update({ quantity: existingItem.amount + minedAmount })
240+
.eq("id", existingItem.id)
241+
.eq("owner", session.user.id)
242+
.eq("anomaly", activePlanet.id);
243+
244+
if (error) {
245+
console.error("Error updating inventory:", error);
246+
} else {
247+
setInventory(prev =>
248+
prev.map(item =>
249+
item.id === existingItem.id
250+
? { ...item, amount: item.amount + minedAmount }
251+
: item
252+
)
253+
);
254+
}
255+
} else {
256+
// Insert new item into inventory
257+
const { data, error } = await supabase
258+
.from("inventory")
259+
.insert([
260+
{
261+
item: resourceName, // Map this to an ID if needed
262+
owner: session.user.id,
263+
quantity: minedAmount,
264+
anomaly: activePlanet.id,
265+
configuration: { Uses: 1 },
266+
},
267+
])
268+
.select();
269+
270+
if (error) {
271+
console.error("Error inserting new item into inventory:", error);
272+
} else {
273+
setInventory(prev => [
274+
...prev,
275+
{ id: data[0].id.toString(), name: resourceName, amount: minedAmount },
276+
]);
277+
}
278+
}
279+
};
158280

159281
const toggleMap = () => {
160282
setActiveMap(prev => prev === '2D' ? '3D' : '2D')
161283
}
162284

285+
const [activeLandmark, setActiveLandmark] = useState<Landmark | null>(null);
286+
163287
const handleLandmarkClick = (id: string) => {
164-
setLandmarks(prev => prev.map(landmark =>
165-
landmark.id === id ? { ...landmark, isOpen: !landmark.isOpen } : landmark
166-
))
167-
}
288+
console.log("Landmark clicked:", id);
289+
const landmark = landmarks.find((l) => l.id === id);
290+
if (landmark) {
291+
setActiveLandmark({ ...landmark, isOpen: true });
292+
}
293+
};
294+
295+
const closeModal = () => {
296+
if (activeLandmark) {
297+
setLandmarks((prev: Landmark[] = []) =>
298+
prev.map((landmark: Landmark) =>
299+
landmark.id === activeLandmark.id
300+
? { ...landmark, isOpen: false }
301+
: landmark
302+
)
303+
);
304+
setActiveLandmark(null);
305+
}
306+
};
168307

169308
return (
170309
<div className="relative h-screen w-full overflow-hidden bg-gray-100 text-[#2C4F64] flex flex-col">
@@ -226,6 +365,38 @@ export function MiningComponentComponent() {
226365
<div className="bg-white bg-opacity-90 p-4 border-t border-gray-200">
227366
<Inventory />
228367
</div>
368+
{activeLandmark && (
369+
<LandmarkModal
370+
landmark={activeLandmark}
371+
isOpen={activeLandmark.isOpen}
372+
onClose={closeModal}
373+
/>
374+
)}
375+
</div>
376+
);
377+
};
378+
379+
type LandmarkModalProps = {
380+
landmark: Landmark | null;
381+
isOpen: boolean;
382+
onClose: () => void;
383+
};
384+
385+
const LandmarkModal: React.FC<LandmarkModalProps> = ({ landmark, isOpen, onClose }) => {
386+
if (!isOpen || !landmark) return null;
387+
388+
return (
389+
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
390+
<div className="bg-white rounded-lg shadow-lg max-w-md w-full p-6 relative">
391+
<button
392+
className="absolute top-3 right-3 text-gray-500 hover:text-gray-800"
393+
onClick={onClose}
394+
>
395+
&times;
396+
</button>
397+
<h2 className="text-2xl font-bold mb-2">{landmark.name}</h2>
398+
<p className="text-gray-700">{landmark.description}</p>
399+
</div>
229400
</div>
230-
)
231-
}
401+
);
402+
};

β€Žcomponents/topographic-map.tsx

+3-7
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,11 @@ export function TopographicMap({
121121
{landmarks.map((landmark) => (
122122
<div
123123
key={landmark.id}
124-
className="absolute"
125-
style={{
126-
left: `${landmark.position.x}%`,
127-
top: `${landmark.position.y}%`,
128-
transform: 'translate(-50%, -50%)',
129-
}}
124+
className="absolute transform -translate-x-1/2 -translate-y-1/2 cursor-pointer"
125+
style={{ top: `${landmark.position.y}%`, left: `${landmark.position.x}%` }}
130126
onClick={() => onLandmarkClick(landmark.id)}
131127
>
132-
<MapPin />
128+
<MapPin className="text-blue-500 hover:text-blue-700" />
133129
</div>
134130
))}
135131
</div>

β€Žpackage.json

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"knip": "knip"
1212
},
1313
"dependencies": {
14+
"@headlessui/react": "^2.2.0",
1415
"@hello-pangea/dnd": "^16.5.0",
1516
"@radix-ui/react-accordion": "^1.2.0",
1617
"@radix-ui/react-avatar": "^1.1.0",

0 commit comments

Comments
Β (0)