MoonMiners/src/app/page.tsx
2023-04-22 08:25:06 +07:00

396 lines
11 KiB
TypeScript

"use client";
import { useState, useEffect } from "react";
import InventoryItemView from "./Components/Inventory/InventoryItemView";
import StakingSourcesView from "./Components/Staking/StakingSourcesView";
import BankAccountsView from "./Components/Accounts/AccountsView";
import StoreItemView from "./Components/Store/StoreItemView";
import NotificationPopover from "./Components/NotificationPopover";
import {
IInventoryItem,
IStakingSource,
IBankAccount,
IStake,
IConversionPair,
Notification,
IGameConfig,
IStoreItem,
} from "typings";
import Navbar from "./Components/Navigation/Navbar";
import NavbarVertical from "./Components/Navigation/NavbarVertical";
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 [userId, setUserId] = useState<string>("");
const [notification, setNotification] = useState<Notification | null>(null);
const [notificationTime, setNotificationTime] = useState(30);
const [storeItems, setStoreItems] = useState<IStoreItem[] | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [activeComponent, setActiveComponent] = useState("stakingsourcesview");
const [gameConfig, setGameConfig] = useState<IGameConfig>();
const isOwned = (storeItemId: number) => {
if (inventoryItems && inventoryItems?.length > 0) {
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();
// Calling the endpoint here because state might not be ready
const gameConfig = await fetch(`/api/get-game-config`);
const gameConfigData = await gameConfig.json();
const updatedInventoryItems = DBInventoryItems.inventoryItems.map(
(invItem: IInventoryItem) => {
return {
...invItem,
storeItem: gameConfigData.storeItems?.find(
(item: IStoreItem) => item.id === invItem.storeItemId
),
};
}
);
setInventoryItems(updatedInventoryItems);
};
const fetchStoreItems = async () => {
const response = await fetch(`/api/get-game-config`);
const data = await response.json();
setGameConfig(data);
setStoreItems(data.storeItems);
};
const fetchStakingSources = async () => {
const response = await fetch(`/api/user/${userId}/staking-sources`);
const sources = await response.json();
setStakingSources(sources.stakingSources);
};
const fetchStakes = async () => {
const response = await fetch(`/api/user/${userId}/stakes`);
const stakes = await response.json();
setUserStakes(
stakes.stakes.map((stake: IStake) => ({
...stake,
unclaimed: stake.unclaimed,
}))
);
};
const fetchBankAccount = async () => {
const response = await fetch(`/api/user/${userId}/account`);
const bankAccount = await response.json();
setBankAccount(bankAccount);
};
useEffect(() => {
if (userId === "") return;
fetchBankAccount();
fetchStakingSources();
fetchInventoryItems();
fetchStakes();
fetchStoreItems();
setIsLoading(false);
}, [userId]);
// Update data
useEffect(() => {
if (storeItems) {
const updatedStoreItems = storeItems.map((storeItem) => {
return {
...storeItem,
isOwned: isOwned(storeItem.id),
};
});
updatedStoreItems && setStoreItems(updatedStoreItems);
}
}, [inventoryItems]);
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 }),
});
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 claimed`,
type: "Success",
});
fetchStakes();
fetchStakingSources();
fetchInventoryItems();
fetchBankAccount();
}
};
const startStake = async (
inventoryItemId: string,
storeItemId: number,
wellId: string
) => {
const response = await fetch(`/api/user/${userId}/stakes/start`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
inventoryItemId: inventoryItemId,
storeItemId,
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();
}
};
const sellResource = async (pairs: IConversionPair[]) => {
const response = await fetch(`/api/user/${userId}/account`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
pairs: pairs,
}),
});
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 received ${data[0].returnAmount.toLocaleString(
"en-US",
{
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}
)} $MoonBucks`,
type: "Success",
});
fetchBankAccount();
}
};
const buyStoreItem = async (storeItemId: number) => {
console.log(`Buying item with id ${storeItemId}`);
try {
const response = await fetch(`/api/user/${userId}/inventory-items`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
storeItemId: storeItemId,
}),
});
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
setNotification({
message: "Item has been purchased",
type: "Success",
});
fetchInventoryItems();
fetchBankAccount();
}
} catch (error) {
if (error instanceof Error) {
setNotification({ message: error.message, type: "Error" });
} else {
setNotification({ message: "An unknown error occured", type: "Error" });
}
}
};
const upgradeInventoryItem = async (
inventoryItemId: string,
storeItemId: number
) => {
try {
const response = await fetch(`/api/user/${userId}/inventory-items`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
inventoryItemId: inventoryItemId,
storeItemId: storeItemId,
}),
});
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
setNotification({ message: "Item has been upgraded", type: "Success" });
fetchInventoryItems();
fetchBankAccount();
}
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 () => {
try {
const response = await fetch(`/api/user/${userId}/staking-sources`, {
method: "POST",
headers: { "Content-Type": "application/json" },
});
const data = await response.json();
if (response.status == 200) {
// Return success message
setNotification({ message: "Moon has been minted", type: "Success" });
fetchInventoryItems();
fetchStakingSources();
fetchBankAccount();
}
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 handleCloseNotification = () => {
setNotification(null);
};
const handleMenuItemClick = (componentKey: string) => {
setActiveComponent(componentKey);
};
if (!userId)
return (
<>
<Navbar setUserId={setUserId} />
<p>Please login</p>
</>
);
if (isLoading) {
return <p>Loading...</p>;
}
console.log(bankAccount);
return (
<>
<Navbar setUserId={setUserId} />
{notification && (
<NotificationPopover
notification={notification}
onClose={handleCloseNotification}
/>
)}
<BankAccountsView
bankAccount={bankAccount}
sellResource={sellResource}
gameConfig={gameConfig}
/>
<div className="grid grid-cols-1 md:grid-cols-6 p-4 gap-8">
<NavbarVertical
onMenuItemClick={handleMenuItemClick}
activeItem={activeComponent}
/>
{activeComponent === "stakingsourcesview" && (
<StakingSourcesView
stakingSources={stakingSources}
inventoryItems={inventoryItems}
claimStake={claimStake}
startStake={startStake}
createStakingSource={createStakingSource}
/>
)}
{activeComponent === "inventoryitemview" && (
<InventoryItemView
stakes={userStakes}
inventoryItems={inventoryItems}
upgradeInventoryItem={upgradeInventoryItem}
/>
)}
{activeComponent === "storeitemview" && (
<StoreItemView
inventoryItems={inventoryItems}
storeItems={storeItems}
buyStoreItem={buyStoreItem}
/>
)}
</div>
</>
);
}