Add loading wheels
This commit is contained in:
parent
b965371fe5
commit
a7c03a2703
@ -3,6 +3,7 @@ import React, { useEffect, useState } from "react";
|
|||||||
import { IResourceAccount, IConversionPair, IGameConfig } from "typings";
|
import { IResourceAccount, IConversionPair, IGameConfig } from "typings";
|
||||||
import { resourceToFc, resourceToBg } from "../../../utils/helpers";
|
import { resourceToFc, resourceToBg } from "../../../utils/helpers";
|
||||||
import ResourceModal from "./ResourceModal";
|
import ResourceModal from "./ResourceModal";
|
||||||
|
import { BiLoaderAlt } from "react-icons/bi";
|
||||||
|
|
||||||
const ResourceAccount = (props: {
|
const ResourceAccount = (props: {
|
||||||
account: IResourceAccount;
|
account: IResourceAccount;
|
||||||
@ -14,6 +15,7 @@ const ResourceAccount = (props: {
|
|||||||
IConversionPair | undefined
|
IConversionPair | undefined
|
||||||
>(undefined);
|
>(undefined);
|
||||||
const [conversionRate, setConversionRate] = useState<number>(0);
|
const [conversionRate, setConversionRate] = useState<number>(0);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const handleConversionPair = (amount: number, resourceType: string) => {
|
const handleConversionPair = (amount: number, resourceType: string) => {
|
||||||
const updatedPair = {
|
const updatedPair = {
|
||||||
@ -31,9 +33,20 @@ const ResourceAccount = (props: {
|
|||||||
return rate;
|
return rate;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSellResource = () => {
|
const handleSellResource = async () => {
|
||||||
conversionPair && props.sellResource([conversionPair]);
|
if (conversionPair) {
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
await props.sellResource([conversionPair]);
|
||||||
|
} catch (error) {
|
||||||
|
// Show error here
|
||||||
|
} finally {
|
||||||
setShowModal(false);
|
setShowModal(false);
|
||||||
|
}
|
||||||
|
conversionPair && props.sellResource([conversionPair]);
|
||||||
|
setIsLoading(false);
|
||||||
|
setShowModal(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -67,7 +80,12 @@ const ResourceAccount = (props: {
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<div className="md:h-auto max-w-md max-h-full overflow-y-auto">
|
<div className="relative md:h-auto max-w-md max-h-full overflow-y-auto">
|
||||||
|
{isLoading && (
|
||||||
|
<div className="absolute bg-white/75 text-white w-full h-full grid justify-center items-center rounded-xl">
|
||||||
|
<BiLoaderAlt className="animate-spin w-6 h-6" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<ResourceModal
|
<ResourceModal
|
||||||
resourceAccount={props.account}
|
resourceAccount={props.account}
|
||||||
conversionPair={conversionPair}
|
conversionPair={conversionPair}
|
||||||
|
@ -2,6 +2,8 @@ import React, { useState, useEffect } from "react";
|
|||||||
import { IInventoryItem, IStake, IUpgrade } from "typings";
|
import { IInventoryItem, IStake, IUpgrade } from "typings";
|
||||||
import CardLayout from "../../Layouts/CardLayout";
|
import CardLayout from "../../Layouts/CardLayout";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import { BiLoaderAlt } from "react-icons/bi";
|
||||||
|
|
||||||
const InventoryItem = (props: {
|
const InventoryItem = (props: {
|
||||||
inventoryItem: IInventoryItem;
|
inventoryItem: IInventoryItem;
|
||||||
stakes: IStake[] | null;
|
stakes: IStake[] | null;
|
||||||
@ -19,6 +21,23 @@ const InventoryItem = (props: {
|
|||||||
setCurrentUpgrade(currentUpdade);
|
setCurrentUpgrade(currentUpdade);
|
||||||
}, [props.inventoryItem]);
|
}, [props.inventoryItem]);
|
||||||
|
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
|
const handleUpgradeInventoryItem = async () => {
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
// Create the source
|
||||||
|
await props.upgradeInventoryItem(
|
||||||
|
props.inventoryItem.id,
|
||||||
|
props.inventoryItem.storeItem.id
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
// Handle error if needed (e.g., show a notification or log the error)
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const renderUpgradeButton = () => {
|
const renderUpgradeButton = () => {
|
||||||
// If no staking source
|
// If no staking source
|
||||||
if (!props.stakes) return "No staking source";
|
if (!props.stakes) return "No staking source";
|
||||||
@ -37,14 +56,14 @@ const InventoryItem = (props: {
|
|||||||
// Show price
|
// Show price
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{isLoading ? (
|
||||||
|
<button className="bg-green-600 rounded-full p-1">
|
||||||
|
<BiLoaderAlt className="animate-spin w-6 h-6" />
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
<button
|
<button
|
||||||
onClick={() =>
|
onClick={() => handleUpgradeInventoryItem()}
|
||||||
props.upgradeInventoryItem(
|
className="bg-green-600 rounded-full p-1"
|
||||||
props.inventoryItem.id,
|
|
||||||
props.inventoryItem.storeItem.id
|
|
||||||
)
|
|
||||||
}
|
|
||||||
className="bg-orange-600 rounded-full p-1"
|
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@ -61,6 +80,7 @@ const InventoryItem = (props: {
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
)}
|
||||||
<span className="ml-1">
|
<span className="ml-1">
|
||||||
{`$${
|
{`$${
|
||||||
props.inventoryItem.storeItem.upgrades[currentTierIndex + 1].price
|
props.inventoryItem.storeItem.upgrades[currentTierIndex + 1].price
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
} from "../../../utils/helpers";
|
} from "../../../utils/helpers";
|
||||||
import SelectDropdown from "../SelectDropdown";
|
import SelectDropdown from "../SelectDropdown";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import { BiLoaderAlt } from "react-icons/bi";
|
||||||
|
|
||||||
const StakingSource = (props: {
|
const StakingSource = (props: {
|
||||||
stakingSource: IStakingSource;
|
stakingSource: IStakingSource;
|
||||||
@ -25,7 +26,7 @@ const StakingSource = (props: {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
const [selectedWellId, setSelectedWellId] = useState<string | null>(null);
|
const [selectedWellId, setSelectedWellId] = useState<string | null>(null);
|
||||||
const [showInfo, setShowInfo] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
// Check if claimable every second
|
// Check if claimable every second
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -54,18 +55,33 @@ const StakingSource = (props: {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleStartMining = () => {
|
const handleStartMining = async () => {
|
||||||
if (selectedInventoryItemId && selectedWellId && selectedStoreItemId) {
|
if (selectedInventoryItemId && selectedWellId && selectedStoreItemId) {
|
||||||
props.startStake(
|
setIsLoading(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await props.startStake(
|
||||||
selectedInventoryItemId,
|
selectedInventoryItemId,
|
||||||
selectedStoreItemId,
|
selectedStoreItemId,
|
||||||
selectedWellId
|
selectedWellId
|
||||||
);
|
);
|
||||||
|
} catch (error) {
|
||||||
|
// Handle error if needed (e.g., show a notification or log the error)
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClaim = (stakingEventId: number) => {
|
const handleClaim = async (stakingEventId: number) => {
|
||||||
props.claimStake(stakingEventId);
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
await props.claimStake(stakingEventId);
|
||||||
|
} catch (error) {
|
||||||
|
// Handle error if needed (e.g., show a notification or log the error)
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectChange = (
|
const handleSelectChange = (
|
||||||
@ -129,8 +145,13 @@ const StakingSource = (props: {
|
|||||||
className="mr-4"
|
className="mr-4"
|
||||||
/>
|
/>
|
||||||
<div className="max-w-md text-white bg-gradient-to-tr from-purple-600 via-blue-600 to-indigo-700 md:rounded-xl p-1">
|
<div className="max-w-md text-white bg-gradient-to-tr from-purple-600 via-blue-600 to-indigo-700 md:rounded-xl p-1">
|
||||||
<div className="bg-slate-900 md:rounded-xl p-4">
|
<div className="relative bg-slate-900 md:rounded-xl h-full">
|
||||||
<div className="">
|
{isLoading && (
|
||||||
|
<div className="absolute bg-slate-900 w-full h-full grid justify-center items-center rounded-xl">
|
||||||
|
<BiLoaderAlt className="animate-spin w-6 h-6" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="p-4">
|
||||||
<h3 className="text-3xl font-bold mb-2">
|
<h3 className="text-3xl font-bold mb-2">
|
||||||
{props.stakingSource.name}{" "}
|
{props.stakingSource.name}{" "}
|
||||||
<span>
|
<span>
|
||||||
@ -144,10 +165,9 @@ const StakingSource = (props: {
|
|||||||
</h3>
|
</h3>
|
||||||
<p className="text-sm">{props.stakingSource.description}</p>
|
<p className="text-sm">{props.stakingSource.description}</p>
|
||||||
</div>
|
</div>
|
||||||
<h3 className="mt-4 mb-2 text-2xl font-bold">Inventory</h3>
|
<div className="p-4">
|
||||||
<div className="">
|
|
||||||
{activeStakes.length > 0 && (
|
{activeStakes.length > 0 && (
|
||||||
<div className="">
|
<>
|
||||||
{activeStakes.map((stake, id) => (
|
{activeStakes.map((stake, id) => (
|
||||||
<div
|
<div
|
||||||
key={id}
|
key={id}
|
||||||
@ -172,7 +192,7 @@ const StakingSource = (props: {
|
|||||||
<RenderButtonOrCountdown stake={stake} />
|
<RenderButtonOrCountdown stake={stake} />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</>
|
||||||
)}
|
)}
|
||||||
{props.inventoryItems && (
|
{props.inventoryItems && (
|
||||||
<div className="">
|
<div className="">
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { IInventoryItem, IStakingSource } from "typings";
|
import { IInventoryItem, IStakingSource } from "typings";
|
||||||
import StakingSource from "./StakingSource";
|
import StakingSource from "./StakingSource";
|
||||||
|
import { BiLoaderAlt } from "react-icons/bi";
|
||||||
|
|
||||||
const StakingSourcesView = (props: {
|
const StakingSourcesView = (props: {
|
||||||
stakingSources: IStakingSource[] | null;
|
stakingSources: IStakingSource[] | null;
|
||||||
@ -14,14 +15,33 @@ const StakingSourcesView = (props: {
|
|||||||
) => void;
|
) => void;
|
||||||
createStakingSource: () => void;
|
createStakingSource: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
|
const handleCreateStakingSource = async () => {
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
// Create the source
|
||||||
|
await props.createStakingSource();
|
||||||
|
} catch (error) {
|
||||||
|
// Handle error if needed (e.g., show a notification or log the error)
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-gradient-to-tr from-purple-600 via-blue-600 to-indigo-700 h-auto p-1 rounded-xl h-auto p-1 rounded-xl col-span-5">
|
<div className="bg-gradient-to-tr from-purple-600 via-blue-600 to-indigo-700 h-auto p-1 rounded-xl h-auto p-1 rounded-xl col-span-5">
|
||||||
<div className="bg-slate-900 p-8 rounded-xl h-full">
|
<div className="bg-slate-900 p-8 rounded-xl h-full">
|
||||||
<div className="flex items-center mb-4">
|
<div className="flex items-center mb-4">
|
||||||
<h2 className="text-3xl text-white font-bold">Your Moons</h2>
|
<h2 className="text-3xl text-white font-bold">Your Moons</h2>
|
||||||
|
{isLoading ? (
|
||||||
|
<button className="bg-green-600 text-white rounded-full ml-2 p-1 inline">
|
||||||
|
<BiLoaderAlt className="animate-spin w-6 h-6" />
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
<button
|
<button
|
||||||
className="bg-green-600 text-white rounded-full ml-2 p-1 inline"
|
className="bg-green-600 text-white rounded-full ml-2 p-1 inline"
|
||||||
onClick={() => props.createStakingSource()}
|
onClick={() => handleCreateStakingSource()}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@ -38,6 +58,7 @@ const StakingSourcesView = (props: {
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
{props.stakingSources ? (
|
{props.stakingSources ? (
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
"use client";
|
|
||||||
import React from "react";
|
|
||||||
import { IInventoryItem, IStakingSource } from "typings";
|
|
||||||
import StakingSource from "./StakingSource";
|
|
||||||
|
|
||||||
const StakingSourcesView = (props: {
|
|
||||||
stakingSources: IStakingSource[] | null;
|
|
||||||
inventoryItems: IInventoryItem[] | null | undefined;
|
|
||||||
claimStake: (stakingEventId: number) => void;
|
|
||||||
startStake: (
|
|
||||||
inventoryItemId: number,
|
|
||||||
storeItemId: string,
|
|
||||||
wellId: number
|
|
||||||
) => void;
|
|
||||||
createStakingSource: () => void;
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<div className="bg-slate-800 p-4 rounded-lg text-white col-span-5">
|
|
||||||
<div className="flex items-center mb-4">
|
|
||||||
<h2 className="text-3xl font-bold">Your Moons</h2>
|
|
||||||
<button
|
|
||||||
className="bg-green-600 rounded-full ml-2 p-1 inline"
|
|
||||||
onClick={() => props.createStakingSource()}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
strokeWidth={2}
|
|
||||||
stroke="currentColor"
|
|
||||||
className="w-6 h-6"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
d="M12 4.5v15m7.5-7.5h-15"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div className="grid grid-cols-3 gap-4">
|
|
||||||
{props.stakingSources &&
|
|
||||||
props.stakingSources.length > 0 &&
|
|
||||||
props.stakingSources.map((stakingSource, id) => (
|
|
||||||
<StakingSource
|
|
||||||
key={id}
|
|
||||||
stakingSource={stakingSource}
|
|
||||||
inventoryItems={props.inventoryItems}
|
|
||||||
claimStake={props.claimStake}
|
|
||||||
startStake={props.startStake}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default StakingSourcesView;
|
|
@ -1,13 +1,28 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { IStoreItem } from "typings";
|
import { IStoreItem } from "typings";
|
||||||
import CardLayout from "../../Layouts/CardLayout";
|
import CardLayout from "../../Layouts/CardLayout";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import { BiLoaderAlt } from "react-icons/bi";
|
||||||
|
|
||||||
const StoreItem = (props: {
|
const StoreItem = (props: {
|
||||||
storeItem: IStoreItem;
|
storeItem: IStoreItem;
|
||||||
buyStoreItem: (storeItemId: number) => void;
|
buyStoreItem: (storeItemId: number) => void;
|
||||||
}) => {
|
}) => {
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
|
const handleBuyStoreItem = async () => {
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
// Create the source
|
||||||
|
await props.buyStoreItem(props.storeItem.id);
|
||||||
|
} catch (error) {
|
||||||
|
// Handle error if needed (e.g., show a notification or log the error)
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CardLayout>
|
<CardLayout>
|
||||||
<div className="md:flex">
|
<div className="md:flex">
|
||||||
@ -15,12 +30,18 @@ const StoreItem = (props: {
|
|||||||
<h3 className="text-2xl font-bold mb-2">{props.storeItem.name}</h3>
|
<h3 className="text-2xl font-bold mb-2">{props.storeItem.name}</h3>
|
||||||
<p className="text-sm mb-3">{props.storeItem.description}</p>
|
<p className="text-sm mb-3">{props.storeItem.description}</p>
|
||||||
<div className="py-4 my-2">
|
<div className="py-4 my-2">
|
||||||
|
{isLoading ? (
|
||||||
|
<button className="bg-green-600 text-white px-4 py-2 rounded-lg font-bold w-auto text-center">
|
||||||
|
<BiLoaderAlt className="animate-spin w-6 h-6" />
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
<button
|
<button
|
||||||
onClick={() => props.buyStoreItem(props.storeItem.id)}
|
onClick={() => handleBuyStoreItem()}
|
||||||
className="bg-green-600 text-white px-4 py-2 rounded-lg font-bold w-auto text-center"
|
className="bg-green-600 text-white px-4 py-2 rounded-lg font-bold w-auto text-center"
|
||||||
>
|
>
|
||||||
Buy | ${props.storeItem.price}
|
Buy | ${props.storeItem.price}
|
||||||
</button>
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative object-contain w-48 h-48">
|
<div className="relative object-contain w-48 h-48">
|
||||||
|
@ -338,7 +338,11 @@ export default function Home() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Navbar setUserId={setUserId} />
|
<Navbar setUserId={setUserId} />
|
||||||
<p>Please login</p>
|
<div className="grid justify-center items-center h-96">
|
||||||
|
<h1 className="text-3xl text-white">
|
||||||
|
Connect Your Wallet to Continue
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -346,7 +350,6 @@ export default function Home() {
|
|||||||
return <p>Loading...</p>;
|
return <p>Loading...</p>;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(storeItems);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Navbar setUserId={setUserId} />
|
<Navbar setUserId={setUserId} />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user