313 lines
8.8 KiB
TypeScript
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
|