refactor to use gameConfig from endpoint

This commit is contained in:
Emil Nielsen 2023-04-15 09:54:46 +07:00
parent 2f809bf889
commit 0668895422
17 changed files with 101 additions and 94 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 417 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 667 KiB

View File

Before

Width:  |  Height:  |  Size: 482 KiB

After

Width:  |  Height:  |  Size: 482 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 KiB

View File

Before

Width:  |  Height:  |  Size: 374 KiB

After

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 KiB

View File

@ -1,28 +1,41 @@
"use client";
import React, { useState } from "react";
import { IResourceAccount, IConversionPair } from "typings";
import React, { useEffect, useState } from "react";
import { IResourceAccount, IConversionPair, IGameConfig } from "typings";
import { resourceToFc } from "../../../utils/helpers";
import ResourceModal from "./ResourceModal";
const ResourceAccount = (props: {
account: IResourceAccount;
sellResource: (pairs: IConversionPair[]) => void;
gameConfig: IGameConfig | undefined;
}) => {
const [showModal, setShowModal] = useState(false);
const [conversionPair, setConversionPair] = useState<
IConversionPair | undefined
>(undefined);
const [conversionRate, setConversionRate] = useState<Number>(0.1);
const [conversionRate, setConversionRate] = useState<number>(0.1);
const handleConversionPair = (amount: number, resourceType: string) => {
const updatedPair = {
resourceType: resourceType,
resourceAmount: amount,
moneyAmount: amount * conversionRate.valueOf(),
moneyAmount: amount * conversionRate,
};
setConversionPair(updatedPair);
};
const getConversionRate = (account: IResourceAccount) => {
if (props.gameConfig === undefined) return 0;
const query = account.resourceType + "ToMoonbucks";
const rate = props.gameConfig.gameConstants[query];
return rate;
};
useEffect(() => {
const rate = getConversionRate(props.account);
setConversionRate(rate);
}, [props.gameConfig]);
return (
<>
{showModal && (

View File

@ -1,12 +1,18 @@
"use client";
import React, { useState, useEffect } from "react";
import { IBankAccount, IConversionPair } from "typings";
import {
IBankAccount,
IConversionPair,
IGameConfig,
IResourceAccount,
} from "typings";
import Account from "./Account";
import { BiLoaderAlt } from "react-icons/bi";
const BankAccountsView = (props: {
bankAccount: IBankAccount | undefined;
sellResource: (pairs: IConversionPair[]) => void;
gameConfig: IGameConfig | undefined;
}) => {
if (props.bankAccount === undefined) {
return (
@ -39,6 +45,7 @@ const BankAccountsView = (props: {
key={id}
account={account}
sellResource={props.sellResource}
gameConfig={props.gameConfig}
/>
);
})}

View File

@ -1,5 +1,5 @@
import React, { useState, useEffect } from "react";
import { IInventoryItem, IStake } from "typings";
import { IInventoryItem, IStake, IUpgrade } from "typings";
import CardLayout from "../../Layouts/CardLayout";
import Image from "next/image";
const InventoryItem = (props: {
@ -10,14 +10,13 @@ const InventoryItem = (props: {
const [currentTierIndex, setCurrentTierIndex] = useState(
props.inventoryItem.currentTierIndex
);
const [currentUpgrade, setCurrentUpgrade] = useState(
props.inventoryItem.storeItem.upgrades[currentTierIndex]
);
const [currentUpgrade, setCurrentUpgrade] = useState<IUpgrade | null>(null);
useEffect(() => {
const index = props.inventoryItem.currentTierIndex;
setCurrentTierIndex(index);
setCurrentUpgrade(props.inventoryItem.storeItem.upgrades[index]);
const currentUpdade = props.inventoryItem.storeItem.upgrades[index];
setCurrentUpgrade(currentUpdade);
}, [props.inventoryItem]);
const isInUse = () => {
@ -47,7 +46,8 @@ const InventoryItem = (props: {
<p>{props.inventoryItem.storeItem.claimAmount}</p>
<p className="font-bold mb-1 mt-4">Tier</p>
<div className="flex items-center">
{props.inventoryItem.storeItem.upgrades.map((upgrade, id) => {
{currentUpgrade &&
props.inventoryItem.storeItem.upgrades.map((upgrade, id) => {
if (upgrade.tier <= currentUpgrade.tier) {
return (
<span key={id} className="bg-green-600 px-4 py-2"></span>
@ -58,7 +58,9 @@ const InventoryItem = (props: {
);
}
})}
<p className="font-bold ml-1">(+{currentUpgrade.claimBoost})</p>
<p className="font-bold ml-1">
(+{currentUpgrade && currentUpgrade.claimBoost})
</p>
</div>
<p className="font-bold mb-1 mt-4">Upgrade</p>
<div className="flex items-center">
@ -97,7 +99,7 @@ const InventoryItem = (props: {
</div>
<div className="relative object-contain w-48 h-48 mt-4 md:mt-0">
<Image
src={props.inventoryItem.storeItem.image}
src={"/assets/items/" + props.inventoryItem.storeItem.image}
alt={props.inventoryItem.storeItem.name}
fill
className="rounded-lg border border-white/20 shadow-lg object-contain"

View File

@ -3,44 +3,6 @@ import React from "react";
import { IInventoryItem, IStakingSource } from "typings";
import StakingSource from "./StakingSource";
const moons = [
{
name: "Caelusium",
description:
"Caelusium is a medium-sized moon with a diverse landscape. Its craters contain a wealth of common resources, making it an ideal starting location for beginners. The moon's relatively mild weather conditions and stable surface offer a friendly environment for establishing mining operations.",
image: "/assets/moon_1.png",
price: 100,
},
{
name: "Caelusium",
description:
"Caelusium is a medium-sized moon with a diverse landscape. Its craters contain a wealth of common resources, making it an ideal starting location for beginners. The moon's relatively mild weather conditions and stable surface offer a friendly environment for establishing mining operations.",
image: "/assets/moon_2.png",
price: 100,
},
{
name: "Caelusium",
description:
"Caelusium is a medium-sized moon with a diverse landscape. Its craters contain a wealth of common resources, making it an ideal starting location for beginners. The moon's relatively mild weather conditions and stable surface offer a friendly environment for establishing mining operations.",
image: "/assets/moon_3.png",
price: 100,
},
{
name: "Caelusium",
description:
"Caelusium is a medium-sized moon with a diverse landscape. Its craters contain a wealth of common resources, making it an ideal starting location for beginners. The moon's relatively mild weather conditions and stable surface offer a friendly environment for establishing mining operations.",
image: "/assets/moon_4.png",
price: 100,
},
{
name: "Caelusium",
description:
"Caelusium is a medium-sized moon with a diverse landscape. Its craters contain a wealth of common resources, making it an ideal starting location for beginners. The moon's relatively mild weather conditions and stable surface offer a friendly environment for establishing mining operations.",
image: "/assets/moon_5.png",
price: 100,
},
];
interface RowProps {
stakingSources: IStakingSource[];
inventoryItems: IInventoryItem[] | undefined | null;

View File

@ -39,7 +39,7 @@ const StoreItem = (props: {
</div>
<div className="relative object-contain w-48 h-48">
<Image
src={props.storeItem.image}
src={"/assets/items/" + props.storeItem.image}
alt={props.storeItem.name}
fill
className="rounded-lg border border-white/20 shadow-lg object-contain mt-4 md:mt-0"

View File

@ -4,7 +4,7 @@ import StoreItem from "./StoreItem";
const StoreItemView = (props: {
inventoryItems: IInventoryItem[] | null | undefined;
storeItems: IStoreItem[];
storeItems: IStoreItem[] | null;
buyStoreItem: (storeItemId: number) => void;
}) => {
return (
@ -12,7 +12,8 @@ const StoreItemView = (props: {
<div className="bg-slate-900 text-white p-8 rounded-xl h-full">
<h2 className="text-3xl font-bold mb-4 text-white">Store</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{props.storeItems
{props.storeItems &&
props.storeItems
.filter((item) => !item.isOwned)
.map((storeItem, id) => (
<StoreItem

View File

@ -5,7 +5,6 @@ import StakingSourcesView from "./Components/Staking/StakingSourcesView";
import BankAccountsView from "./Components/Accounts/AccountsView";
import StoreItemView from "./Components/Store/StoreItemView";
import NotificationPopover from "./Components/NotificationPopover";
import { gameConfig } from "@/utils/gameLogic";
import {
IInventoryItem,
IStakingSource,
@ -13,6 +12,8 @@ import {
IStake,
IConversionPair,
Notification,
IGameConfig,
IStoreItem,
} from "typings";
import Navbar from "./Components/Navigation/Navbar";
import NavbarVertical from "./Components/Navigation/NavbarVertical";
@ -26,13 +27,13 @@ export default function Home() {
);
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 [storeItems, setStoreItems] = useState<IStoreItem[] | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [activeComponent, setActiveComponent] = useState("stakingsourcesview");
const [activeComponent, setActiveComponent] = useState("inventoryitemview");
const [gameConfig, setGameConfig] = useState<IGameConfig>();
const isOwned = (storeItemId: number) => {
if (inventoryItems && inventoryItems?.length > 0) {
@ -46,20 +47,34 @@ export default function Home() {
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
);
// 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
),
};
}
// TODO Can you just return the array?
console.log(DBInventoryItems.inventoryItems);
setInventoryItems(DBInventoryItems.inventoryItems);
);
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();
// TODO Can you just return the array?
setStakingSources(sources.stakingSources);
};
@ -86,11 +101,13 @@ export default function Home() {
fetchStakingSources();
fetchInventoryItems();
fetchStakes();
fetchStoreItems();
setIsLoading(false);
}, [userId]);
// Update data
useEffect(() => {
if (storeItems) {
const updatedStoreItems = storeItems.map((storeItem) => {
return {
...storeItem,
@ -98,9 +115,9 @@ export default function Home() {
};
});
updatedStoreItems && setStoreItems(updatedStoreItems);
}
}, [inventoryItems]);
// Hide error automatically
useEffect(() => {
if (notification) {
const intervalId = setInterval(() => {
@ -332,7 +349,11 @@ export default function Home() {
onClose={handleCloseNotification}
/>
)}
<BankAccountsView bankAccount={bankAccount} sellResource={sellResource} />
<BankAccountsView
bankAccount={bankAccount}
sellResource={sellResource}
gameConfig={gameConfig}
/>
<div className="grid grid-cols-1 md:grid-cols-6 p-4 gap-8">
<NavbarVertical
onMenuItemClick={handleMenuItemClick}

1
typings.d.ts vendored
View File

@ -83,6 +83,7 @@ export interface IGameConfig {
resources: string[];
[key: string]: any;
store: IStoreItem[];
gameConstants: {[key: string]: any;}
}
export interface IConversionPair {