367 lines
10 KiB
TypeScript
367 lines
10 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";
|
|
import Navbar from "./Components/Navbar";
|
|
import NavbarVertical from "./Components/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 [lightBoxIsActive, setLightBoxIsActive] = useState(false);
|
|
const [userId, setUserId] = useState<string>("");
|
|
const [notification, setNotification] = useState<Notification | null>(null);
|
|
const [notificationTime, setNotificationTime] = useState(30);
|
|
const [storeItems, setStoreItems] = useState(gameConfig.store);
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
const [activeComponent, setActiveComponent] = useState("stakingsourcesview");
|
|
|
|
const isOwned = (storeItemId: string) => {
|
|
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();
|
|
|
|
for (const invItem of DBInventoryItems.inventoryItems) {
|
|
invItem.storeItem = gameConfig.store.find(
|
|
(item) => item.id === invItem.storeItemId
|
|
);
|
|
}
|
|
// TODO Can you just return the array?
|
|
setInventoryItems(DBInventoryItems.inventoryItems);
|
|
};
|
|
|
|
const fetchStakingSources = async () => {
|
|
const response = await fetch(`/api/user/${userId}/staking-sources`);
|
|
const sources = await response.json();
|
|
// TODO Can you just return the array?
|
|
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}/bank-account`);
|
|
const bankAccount = await response.json();
|
|
setBankAccount(bankAccount);
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (userId === "") return;
|
|
fetchBankAccount();
|
|
fetchStakingSources();
|
|
fetchInventoryItems();
|
|
fetchStakes();
|
|
setIsLoading(false);
|
|
}, [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 }),
|
|
});
|
|
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: number,
|
|
storeItemId: string,
|
|
wellId: number
|
|
) => {
|
|
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();
|
|
}
|
|
};
|
|
|
|
// 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) => {
|
|
console.log(`Buying item with id ${itemId}`);
|
|
try {
|
|
const response = await fetch(`/api/user/${userId}/inventory-items`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
storeItemId: 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
|
|
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 (
|
|
inventoryItemId: number,
|
|
storeItemId: string
|
|
) => {
|
|
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 () => {
|
|
console.log("Minting...");
|
|
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 handleSetLightBox = () => {
|
|
setLightBoxIsActive(!lightBoxIsActive);
|
|
};
|
|
|
|
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(stakingSources);
|
|
return (
|
|
<>
|
|
<Navbar setUserId={setUserId} />
|
|
{notification && (
|
|
<NotificationPopover
|
|
notification={notification}
|
|
onClose={handleCloseNotification}
|
|
/>
|
|
)}
|
|
<BankAccountsView
|
|
bankAccount={bankAccount}
|
|
setLightBoxIsActive={handleSetLightBox}
|
|
/>
|
|
<div className="grid 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}
|
|
/>
|
|
)}
|
|
{activeComponent === "resourcestore" && (
|
|
<ResourceStore bankAccount={bankAccount} />
|
|
)}
|
|
</div>
|
|
</>
|
|
);
|
|
}
|