187 lines
6.2 KiB
TypeScript
187 lines
6.2 KiB
TypeScript
import React, { useState, useEffect } from "react";
|
|
import { IInventoryItem, IStakingSource, IStake, IOption } from "typings";
|
|
import CardLayout from "../Layouts/CardLayout";
|
|
import {
|
|
calculateRemainingTime,
|
|
prettifyTime,
|
|
getObjectFromArray,
|
|
} from "../../utils/helpers";
|
|
import SelectDropdown from "./SelectDropdown";
|
|
|
|
const StakingSource = (props: {
|
|
stakingSource: IStakingSource;
|
|
inventoryItems: IInventoryItem[] | null | undefined;
|
|
claimStake: (stakingEventId: number) => void;
|
|
startStake: (inventoryItemId: number, wellId: number) => void;
|
|
}) => {
|
|
const [activeStakes, setActiveStakes] = useState<IStake[]>([]);
|
|
const [selectedItemId, setSelectedItemId] = useState<number | null>(null);
|
|
const [selectedWellId, setSelectedWellId] = useState<number | null>(null);
|
|
|
|
// Check if claimable every second
|
|
useEffect(() => {
|
|
const updatedActiveStakes = props.stakingSource.activeStakes.map(
|
|
(stake) => {
|
|
const remainingTime = calculateRemainingTime(
|
|
stake.startTime,
|
|
stake.durationInMins
|
|
);
|
|
|
|
const obj = {
|
|
...stake,
|
|
remainingTime: remainingTime,
|
|
};
|
|
|
|
return obj;
|
|
}
|
|
);
|
|
|
|
const intervalId = setInterval(() => {
|
|
setActiveStakes(updatedActiveStakes);
|
|
}, 1000);
|
|
|
|
return () => {
|
|
clearInterval(intervalId);
|
|
};
|
|
});
|
|
|
|
const handleStartMining = () => {
|
|
if (selectedItemId && selectedWellId) {
|
|
props.startStake(selectedItemId, selectedWellId);
|
|
}
|
|
};
|
|
|
|
const handleClaim = (stakingEventId: number) => {
|
|
props.claimStake(stakingEventId);
|
|
};
|
|
|
|
const handleSelectChange = (wellId: string, itemId: number) => {
|
|
setSelectedWellId(Number(wellId));
|
|
setSelectedItemId(itemId);
|
|
};
|
|
|
|
const RenderButtonOrCountdown = (props: { stake: IStake }) => {
|
|
if (!props.stake.remainingTime) return <p>Error</p>;
|
|
|
|
if (props.stake.remainingTime <= 0) {
|
|
return (
|
|
<button
|
|
onClick={() => handleClaim(props.stake.id)}
|
|
className="bg-slate-100 text-slate-900 px-4 py-2 rounded-lg font-bold text-center"
|
|
>
|
|
Claim
|
|
</button>
|
|
);
|
|
} else {
|
|
return (
|
|
// I'll fix it
|
|
<div className="flex">
|
|
<div className="flex block gap-1 p-1 rounded-lg border ">
|
|
<span className="bg-white rounded-lg text-black p-1">
|
|
{prettifyTime(props.stake.remainingTime).hours == 0
|
|
? "00"
|
|
: prettifyTime(props.stake.remainingTime).hours}
|
|
</span>
|
|
<span className="p-1">:</span>
|
|
<span className="bg-white rounded-lg text-black p-1">
|
|
{prettifyTime(props.stake.remainingTime).minutes.toString()
|
|
.length > 0
|
|
? prettifyTime(props.stake.remainingTime).minutes
|
|
: "0" +
|
|
prettifyTime(props.stake.remainingTime).minutes.toString()}
|
|
</span>
|
|
<span className="p-1">:</span>
|
|
<span className="bg-white rounded-lg text-black p-1">
|
|
{prettifyTime(props.stake.remainingTime).minutes.toString()
|
|
.length > 0
|
|
? prettifyTime(props.stake.remainingTime).seconds
|
|
: "0" +
|
|
prettifyTime(props.stake.remainingTime).seconds.toString()}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
};
|
|
|
|
const isActive = (item: IInventoryItem): boolean => {
|
|
return props.stakingSource.activeStakes.some(
|
|
(obj) => obj.inventoryItemId === item.id
|
|
);
|
|
};
|
|
|
|
return (
|
|
<CardLayout>
|
|
<h3 className="text-xl font-bold mb-2">{props.stakingSource.name}</h3>
|
|
<p className="text-sm">{props.stakingSource.description}</p>
|
|
<div className="flex gap-4">
|
|
<div className="flex-1">
|
|
<p className="font-bold mt-4 mb-2">Stakes</p>
|
|
{activeStakes &&
|
|
activeStakes.map((stake, id) => (
|
|
<div key={id} className="mb-3 border border-white p-2">
|
|
<p>
|
|
<span className="font-bold">Drill: </span>
|
|
{props.inventoryItems &&
|
|
getObjectFromArray(props.inventoryItems, "id", stake.id)
|
|
?.storeItem.name}
|
|
</p>
|
|
<p>
|
|
<span className="font-bold">Resource: </span>
|
|
{stake.resourceType}
|
|
</p>
|
|
<p>
|
|
<span className="font-bold">Stake amount: </span>
|
|
{stake.stakeAmount}
|
|
</p>
|
|
<p>
|
|
<span className="font-bold">Start Time:</span>{" "}
|
|
{stake.startTime}
|
|
</p>
|
|
<RenderButtonOrCountdown stake={stake} />
|
|
</div>
|
|
))}
|
|
</div>
|
|
<div className="flex-1">
|
|
<p className="font-bold mt-4 mb-2">Activate Drills</p>
|
|
{props.inventoryItems &&
|
|
props.inventoryItems.map(
|
|
(item, id) =>
|
|
!isActive(item) && (
|
|
<div key={id} className="border border-white p-2 mb-2">
|
|
<p>
|
|
{item.storeItem.name} ID{item.storeItem.id}
|
|
</p>
|
|
<div className="flex">
|
|
<SelectDropdown
|
|
options={props.stakingSource.resourceWells.map(
|
|
(well): IOption => ({
|
|
value: well.id,
|
|
label: `${well.resourceType} - ID# ${well.id}`,
|
|
})
|
|
)}
|
|
onChange={(value) => handleSelectChange(value, item.id)}
|
|
isActive={selectedItemId === item.id}
|
|
/>
|
|
{selectedItemId === item.id ? (
|
|
<button
|
|
onClick={handleStartMining}
|
|
className="bg-slate-100 text-slate-900 px-4 py-2 rounded-lg font-bold w-28 text-center"
|
|
>
|
|
Stake
|
|
</button>
|
|
) : (
|
|
<></>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)
|
|
)}
|
|
</div>
|
|
</div>
|
|
</CardLayout>
|
|
);
|
|
};
|
|
|
|
export default StakingSource;
|