MoonMiners/src/app/page.tsx
2023-03-22 08:55:00 +07:00

313 lines
8.8 KiB
TypeScript

"use client";
import { useState, useEffect } from "react";
import InventoryItemView from "./Components/InventoryItemView";
import StakingSourcesView from "./Components/StakingSourcesView";
import BankAccountsView from "./Components/BankAccountsView";
import StoreItemView from "./Components/StoreItemView";
import ResourceStore from "./Components/ResourceStore";
import NotificationPopover from "./Components/NotificationPopover";
import { gameConfig } from "@/utils/gameLogic";
import {
IInventoryItem,
IStakingSource,
IBankAccount,
IStake,
Notification,
} from "typings";
export default function Home() {
const [inventoryItems, setInventoryItems] = useState<
IInventoryItem[] | null | undefined
>([]);
const [stakingSources, setStakingSources] = useState<IStakingSource[] | null>(
[]
);
const [bankAccount, setBankAccount] = useState<IBankAccount>();
const [userStakes, setUserStakes] = useState<IStake[]>([]);
const [lightBoxIsActive, setLightBoxIsActive] = useState(false);
const [userId, setUserId] = useState<number | null>(null);
const [notification, setNotification] = useState<Notification | null>(null);
const [notificationTime, setNotificationTime] = useState(30);
const [storeItems, setStoreItems] = useState(gameConfig.store);
const isOwned = (storeItemId: string) => {
if (inventoryItems) {
return inventoryItems?.some((item) => item.storeItem.id == storeItemId);
} else {
return false;
}
};
const fetchInventoryItems = async () => {
const response = await fetch(`/api/user/${userId}/inventory-items`);
const DBInventoryItems = await response.json();
for (const invItem of DBInventoryItems) {
invItem.storeItem = gameConfig.store.find(
(item) => item.id === invItem.storeItemId
);
}
setInventoryItems(DBInventoryItems);
};
const fetchStakingSources = async () => {
const response = await fetch(`/api/user/${userId}/staking-sources`);
const sources = await response.json();
setStakingSources(sources);
};
const fetchStakes = async () => {
const response = await fetch(`/api/user/${userId}/stakes`);
const stakes = await response.json();
setUserStakes(
stakes.map((stake: IStake) => ({
...stake,
unclaimed: stake.unclaimed == 1,
}))
);
};
useEffect(() => {
const fetchUser = async (wallet: string) => {
const response = await fetch(`/api/user/login`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
wallet: wallet,
}),
});
if (response.status === 200) {
console.log("Logged in");
const { userId } = await response.json();
setUserId(userId);
}
};
const fetchBankAccount = async () => {
const response = await fetch(`/api/user/${userId}/bank-account`);
const bankAccount = await response.json();
setBankAccount(bankAccount);
};
fetchUser("abcdefg"); // Public key goes here
// Nico is there a better way of checking if a user is logged in?
if (userId) {
fetchBankAccount();
fetchStakingSources();
fetchInventoryItems();
fetchStakes();
}
}, [userId]);
// Update data
useEffect(() => {
const updatedStoreItems = storeItems.map((storeItem) => {
return {
...storeItem,
isOwned: isOwned(storeItem.id),
};
});
updatedStoreItems && setStoreItems(updatedStoreItems);
}, [inventoryItems]);
// Hide error automatically
useEffect(() => {
if (notification) {
const intervalId = setInterval(() => {
setNotificationTime((prev) => prev - 1);
}, 1000);
if (notificationTime === 0) {
setNotification(null);
clearInterval(intervalId);
setNotificationTime(30);
}
return () => {
clearInterval(intervalId);
};
}
}, [notification, notificationTime]);
const claimStake = async (stakingEventId: number) => {
const response = await fetch(`/api/user/${userId}/stakes/claim`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ stakingEventId: stakingEventId }),
});
return await response.json();
};
const startStake = async (inventoryItemId: number, wellId: number) => {
const response = await fetch(`/api/user/${userId}/stakes/start`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
inventoryItemId: inventoryItemId,
wellId: wellId,
}),
});
if (!response.ok) {
const error = await response.text();
setNotification({ message: error, type: "Error" });
}
if (response.status == 200) {
const data = await response.json();
setNotification({
message: `You've successfully staked`,
type: "Success",
});
fetchStakes();
fetchStakingSources();
}
};
// Which object is it?
const sellResource = async (obj: any) => {
const response = await fetch(`/api/user/${userId}/bank-account`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
obj: obj,
}),
});
return await response.json();
};
const buyStoreItem = async (itemId: string) => {
try {
const response = await fetch(`/api/user/${userId}/inventory-items`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
itemId: itemId,
}),
});
if (!response.ok) {
const error = await response.text();
setNotification({ message: error, type: "Error" });
return;
}
const data = await response.json();
if (response.status == 200) {
// Return success message
console.log(data.message);
setNotification({
message: "Item has been purchased",
type: "Success",
});
fetchInventoryItems();
}
} catch (error) {
if (error instanceof Error) {
setNotification({ message: error.message, type: "Error" });
} else {
setNotification({ message: "An unknown error occured", type: "Error" });
}
}
};
const upgradeInventoryItem = async (itemId: number) => {
try {
const response = await fetch(`/api/user/${userId}/inventory-items`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
itemId: itemId,
}),
});
if (!response.ok) {
const error = await response.text();
setNotification({ message: error, type: "Error" });
return;
}
const data = await response.json();
if (response.status == 200) {
// Return success message
console.log(data);
setNotification({ message: "Item has been upgraded", type: "Success" });
fetchInventoryItems();
}
if (response.status == 400) {
// return error message
setNotification({ message: data.error, type: "Error" });
}
} catch (error) {
if (error instanceof Error) {
setNotification({ message: error.message, type: "Error" });
} else {
setNotification({ message: "An unknown error occured", type: "Error" });
}
}
};
const createStakingSource = async () => {
const response = await fetch(`/api/user/${userId}/staking-sources`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({}),
});
return await response.json();
};
const handleSetLightBox = () => {
setLightBoxIsActive(!lightBoxIsActive);
};
const handleCloseNotification = () => {
setNotification(null);
};
if (!userId) return <p>Please login</p>;
return (
<>
{notification && (
<NotificationPopover
notification={notification}
onClose={handleCloseNotification}
/>
)}
<BankAccountsView
bankAccount={bankAccount}
setLightBoxIsActive={handleSetLightBox}
/>
{lightBoxIsActive && (
<ResourceStore
bankAccount={bankAccount}
setLightBoxIsActive={handleSetLightBox}
/>
)}
<div className="grid grid-cols-3 gap-8 p-4">
<StakingSourcesView
stakingSources={stakingSources}
inventoryItems={inventoryItems}
claimStake={claimStake}
startStake={startStake}
/>
<InventoryItemView
stakingSources={stakingSources}
inventoryItems={inventoryItems}
upgradeInventoryItem={upgradeInventoryItem}
/>
<StoreItemView
inventoryItems={inventoryItems}
storeItems={storeItems}
buyStoreItem={buyStoreItem}
/>
</div>
</>
);
}
// Pass data from storeComponent to parentComponent
// re-fetch data of inventory