Modify UI

This commit is contained in:
Emil Nielsen 2023-03-24 15:41:31 +07:00
parent 16eb1405e6
commit e90c0c9809
18 changed files with 231 additions and 416 deletions

View File

@ -12,11 +12,12 @@
"store": [
{
"id": "item1",
"name": "Drill A",
"description": "This is drill A",
"name": "LunarLite L100",
"description": "LunarLite L100 is a lightweight, entry-level drill designed for beginners. With its easy-to-use interface and moderate drilling speed, it's perfect for getting started with lunar resource extraction.",
"image": "/assets/drill_1.jpg",
"price": 250,
"claimAmount": 50,
"completionTimeInMins": 5,
"claimAmount": 10,
"completionTimeInMins": 1,
"upgrades": [
{ "tier": 1, "price": 200, "claimBoost": 10 },
{ "tier": 2, "price": 300, "claimBoost": 20 },
@ -27,41 +28,44 @@
},
{
"id": "item2",
"name": "Drill B",
"description": "This is drill B",
"price": 250,
"claimAmount": 50,
"name": "Lunar Regolith Extractor LRE-3000",
"description": "The LRE-3000 is a high-efficiency drill designed for extracting regolith, the lunar soil composed of small rocks, dust, and other materials. This drill utilizes a unique auger system to bore into the moon's surface and collect regolith for further processing, ensuring minimal waste and maximum resource extraction.",
"image": "/assets/drill_2.jpg",
"price": 400,
"claimAmount": 75,
"completionTimeInMins": 5,
"upgrades": [
{ "tier": 1, "price": 200, "claimBoost": 10 },
{ "tier": 2, "price": 300, "claimBoost": 20 },
{ "tier": 3, "price": 400, "claimBoost": 30 },
{ "tier": 4, "price": 500, "claimBoost": 40 },
{ "tier": 5, "price": 600, "claimBoost": 50 }
{ "tier": 2, "price": 300, "claimBoost": 30 },
{ "tier": 3, "price": 400, "claimBoost": 40 },
{ "tier": 4, "price": 500, "claimBoost": 50 },
{ "tier": 5, "price": 600, "claimBoost": 60 }
]
},
{
"id": "item3",
"name": "Drill C",
"description": "This is drill C",
"price": 250,
"claimAmount": 50,
"completionTimeInMins": 5,
"name": "Electrostatic Dust Excavator EDE-700",
"description": "The EDE-700 is a specialized excavator designed to collect fine lunar dust, which is rich in valuable elements such as helium-3, a potential fuel for future fusion reactors. The machine uses an electrostatic system to attract and capture dust particles, allowing for efficient collection and reduced risk of hazardous dust exposure for operators.",
"image": "/assets/drill_3.jpg",
"price": 1000,
"claimAmount": 100,
"completionTimeInMins": 30,
"upgrades": [
{ "tier": 1, "price": 200, "claimBoost": 10 },
{ "tier": 2, "price": 300, "claimBoost": 20 },
{ "tier": 3, "price": 400, "claimBoost": 30 },
{ "tier": 4, "price": 500, "claimBoost": 40 },
{ "tier": 5, "price": 600, "claimBoost": 50 }
{ "tier": 1, "price": 200, "claimBoost": 25 },
{ "tier": 2, "price": 300, "claimBoost": 50 },
{ "tier": 3, "price": 400, "claimBoost": 75 },
{ "tier": 4, "price": 500, "claimBoost": 100 },
{ "tier": 5, "price": 600, "claimBoost": 150 }
]
},
{
"id": "item4",
"name": "Drill D",
"description": "This is drill D",
"price": 250,
"claimAmount": 50,
"completionTimeInMins": 5,
"name": "Lunar Core Extractor LCE-360",
"description": "The LCE-360 is a sophisticated drill designed to extract core samples from the moon's surface and subsurface layers. With its adjustable coring system, this machine can retrieve samples of various depths and diameters, providing valuable information about the moon's geological history and enabling efficient extraction of embedded resources.",
"image": "/assets/drill_4.jpg",
"price": 5000,
"claimAmount": 500,
"completionTimeInMins": 120,
"upgrades": [
{ "tier": 1, "price": 200, "claimBoost": 10 },
{ "tier": 2, "price": 300, "claimBoost": 20 },
@ -69,51 +73,6 @@
{ "tier": 4, "price": 500, "claimBoost": 40 },
{ "tier": 5, "price": 600, "claimBoost": 50 }
]
},
{
"id": "item5",
"name": "Drill E",
"description": "This is drill E",
"price": 250,
"claimAmount": 50,
"completionTimeInMins": 5,
"upgrades": [
{ "tier": 1, "price": 200, "claimBoost": 10 },
{ "tier": 2, "price": 300, "claimBoost": 20 },
{ "tier": 3, "price": 400, "claimBoost": 30 },
{ "tier": 4, "price": 500, "claimBoost": 40 },
{ "tier": 5, "price": 600, "claimBoost": 50 }
]
},
{
"id": "item6",
"name": "Drill F",
"description": "This is drill F",
"price": 250,
"claimAmount": 50,
"completionTimeInMins": 5,
"upgrades": [
{ "tier": 1, "price": 200, "claimBoost": 10 },
{ "tier": 2, "price": 300, "claimBoost": 20 },
{ "tier": 3, "price": 400, "claimBoost": 30 },
{ "tier": 4, "price": 500, "claimBoost": 40 },
{ "tier": 5, "price": 600, "claimBoost": 50 }
]
},
{
"id": "item7",
"name": "Drill G",
"description": "This is drill G",
"price": 250,
"claimAmount": 50,
"completionTimeInMins": 5,
"upgrades": [
{ "tier": 1, "price": 200, "claimBoost": 10 },
{ "tier": 2, "price": 300, "claimBoost": 20 },
{ "tier": 3, "price": 400, "claimBoost": 30 },
{ "tier": 4, "price": 500, "claimBoost": 40 },
{ "tier": 5, "price": 600, "claimBoost": 50 }
]
}
}
]
}

46
package-lock.json generated
View File

@ -13,12 +13,10 @@
"@types/node": "18.13.0",
"@types/react": "18.0.27",
"@types/react-dom": "18.0.10",
"chart.js": "^4.2.1",
"eslint": "8.33.0",
"eslint-config-next": "13.1.6",
"next": "13.1.6",
"react": "18.2.0",
"react-chartjs-2": "^5.2.0",
"react-dom": "18.2.0",
"sqlite": "^4.1.2",
"sqlite3": "^5.1.4",
@ -99,11 +97,6 @@
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
},
"node_modules/@kurkle/color": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz",
"integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
},
"node_modules/@mapbox/node-pre-gyp": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz",
@ -1245,17 +1238,6 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/chart.js": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.2.1.tgz",
"integrity": "sha512-6YbpQ0nt3NovAgOzbkSSeeAQu/3za1319dPUQTXn9WcOpywM8rGKxJHrhS8V8xEkAlk8YhEfjbuAPfUyp6jIsw==",
"dependencies": {
"@kurkle/color": "^0.3.0"
},
"engines": {
"pnpm": "^7.0.0"
}
},
"node_modules/chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@ -4248,15 +4230,6 @@
"node": ">=0.10.0"
}
},
"node_modules/react-chartjs-2": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz",
"integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==",
"peerDependencies": {
"chart.js": "^4.1.1",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
@ -5317,11 +5290,6 @@
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
},
"@kurkle/color": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz",
"integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
},
"@mapbox/node-pre-gyp": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz",
@ -6062,14 +6030,6 @@
"supports-color": "^7.1.0"
}
},
"chart.js": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.2.1.tgz",
"integrity": "sha512-6YbpQ0nt3NovAgOzbkSSeeAQu/3za1319dPUQTXn9WcOpywM8rGKxJHrhS8V8xEkAlk8YhEfjbuAPfUyp6jIsw==",
"requires": {
"@kurkle/color": "^0.3.0"
}
},
"chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@ -8184,12 +8144,6 @@
"loose-envify": "^1.1.0"
}
},
"react-chartjs-2": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz",
"integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==",
"requires": {}
},
"react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",

View File

@ -14,12 +14,10 @@
"@types/node": "18.13.0",
"@types/react": "18.0.27",
"@types/react-dom": "18.0.10",
"chart.js": "^4.2.1",
"eslint": "8.33.0",
"eslint-config-next": "13.1.6",
"next": "13.1.6",
"react": "18.2.0",
"react-chartjs-2": "^5.2.0",
"react-dom": "18.2.0",
"sqlite": "^4.1.2",
"sqlite3": "^5.1.4",

BIN
public/assets/drill_1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 KiB

BIN
public/assets/drill_2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 KiB

BIN
public/assets/drill_3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

BIN
public/assets/drill_4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 KiB

View File

@ -13,7 +13,9 @@ const BankAccountsView = (props: {
<div className="flex-1 bg-green-800 rounded-lg p-3">
<div className="text-white">
<span className="text-green-400">Moonbucks</span>
<h3 className="text-2xl font-bold">$5,342.23</h3>
<h3 className="text-2xl font-bold">
${props.bankAccount?.primaryBalance}
</h3>
<button
onClick={() => props.setLightBoxIsActive()}
className="px-2 text-sm mt-1 rounded-lg font-bold bg-green-400 text-green-800"

View File

@ -1,99 +0,0 @@
import React from "react";
import { useState, useEffect } from "react";
import { Line } from "react-chartjs-2";
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend,
Filler,
BarElement,
ArcElement,
} from "chart.js";
ChartJS.register(
CategoryScale,
LinearScale,
PointElement,
LineElement,
BarElement,
ArcElement,
Title,
Tooltip,
Legend,
Filler
);
import { IChart, IUpgrade } from "typings";
// https://www.chartjs.org/docs/latest/samples/scale-options/grid.html
const Chart = (props: { upgrades: IUpgrade[] }) => {
const options = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: "bottom" as const,
},
title: {
display: false,
},
},
scales: {
x: {
grid: {
display: false,
},
},
},
};
const [chartData, setChartData] = useState({
labels: props.upgrades.map((upgrade) => `$${upgrade.price}`),
datasets: [
{
label: "Upgrades",
backgroundColor: "rgb(242, 244, 250, 1)",
data: props.upgrades.map((upgrade) => upgrade.claimBoost),
tension: 0.3,
borderWidth: 2,
pointRadius: 4,
pointHoverRadius: 10,
borderColor: "rgb(52, 152, 219)",
fill: {
target: "origin",
above: "rgba(52, 152, 219, 0.05)",
},
},
],
});
/* useEffect(() => {
setChartData({
labels: labels,
datasets: {
label: label,
backgroundColor: "rgb(242, 244, 250, 1)",
data: values,
tension: 0.3,
borderWidth: 5,
pointRadius: 7,
pointHoverRadius: 10,
borderColor: "rgb(52, 152, 219)",
fill: {
target: "origin",
above: "rgba(52, 152, 219, 0.05)",
},
},
});
}, [values]); */
return <Line options={options} data={chartData} />;
};
export default Chart;

View File

@ -1,7 +1,7 @@
import React, { useState, useEffect } from "react";
import { IInventoryItem, IStake } from "typings";
import CardLayout from "../Layouts/CardLayout";
import Image from "next/image";
const InventoryItem = (props: {
inventoryItem: IInventoryItem;
stakes: IStake[] | null;
@ -35,8 +35,14 @@ const InventoryItem = (props: {
};
return (
<CardLayout>
<div className="flex gap-4">
<div className="flex-1">
<h3 className="text-xl font-bold mb-2">
{props.inventoryItem.storeItem.name}
</h3>
<p className="text-sm mb-3">
{props.inventoryItem.storeItem.description}
</p>
<div className="flex">
{props.inventoryItem.storeItem.upgrades.map((upgrade, id) => {
if (upgrade.tier <= currentUpgrade.tier) {
@ -56,22 +62,15 @@ const InventoryItem = (props: {
}
})}
</div>
</h3>
<p className="text-sm">{props.inventoryItem.storeItem.description}</p>
<div className="flex gap-4">
<div className="flex-1">
<p className="font-bold mt-4">Yield</p>
<p>
{props.inventoryItem.storeItem.claimAmount} +{" "}
{currentUpgrade.claimBoost}
</p>
<ul className="list-none"></ul>
</div>
<div className="flex-1 text-center">
<p className="text-lg font-bold mb-2">{getNextUpgradePrice()}</p>
<div className="">
<div className="py-4 my-2">
{isInUse() ? (
<button className="bg-slate-400 text-slate-600 px-4 py-2 rounded-lg font-bold w-28 text-center cursor-not-allowed">
<button className="bg-slate-400 text-slate-600 px-4 py-2 rounded-lg font-bold text-center cursor-not-allowed">
In Use
</button>
) : (
@ -79,14 +78,23 @@ const InventoryItem = (props: {
onClick={() =>
props.upgradeInventoryItem(props.inventoryItem.id)
}
className="bg-slate-100 text-slate-900 px-4 py-2 rounded-lg font-bold w-28 text-center"
className="bg-slate-100 text-slate-900 px-4 py-2 rounded-lg font-bold text-center"
>
Upgrade
Upgrade | {getNextUpgradePrice()}
</button>
)}
</div>
</div>
</div>
<div className="relative object-contain w-48 h-48">
<Image
src={props.inventoryItem.storeItem.image}
alt={props.inventoryItem.storeItem.name}
fill
className="rounded-lg border border-white/20 shadow-lg object-contain"
/>
</div>
</div>
</CardLayout>
);
};

View File

@ -23,10 +23,7 @@ const ResourceStore = (props: {
}
}, []);
const handleAmountChange = (
e: React.ChangeEvent<HTMLInputElement>,
resourceType: string
) => {
const handleConversionPairs = (amount: number, resourceType: string) => {
if (!conversionPairs) return;
const existingObj = conversionPairs.find(
@ -37,8 +34,8 @@ const ResourceStore = (props: {
if (pair.resourceType === existingObj?.resourceType) {
return {
...pair,
resourceAmount: Number(e.target.value),
moneyAmount: Number(e.target.value) * conversionRate.valueOf(),
resourceAmount: amount,
moneyAmount: amount * conversionRate.valueOf(),
};
} else {
return pair;
@ -51,7 +48,11 @@ const ResourceStore = (props: {
return conversionPairs?.find((obj) => obj.resourceType === resourceType);
};
const handleSellResources = () => {
// Do something..
console.log(conversionPairs);
};
return (
<div className="p-4 max-w-5xl">
<h1 className="text-white text-4xl font-extrabold">
@ -68,18 +69,16 @@ const ResourceStore = (props: {
conversionPair={getConversionPair(
resourceAccount.resourceType
)}
handleAmountChange={handleAmountChange}
handleConversionPairs={handleConversionPairs}
/>
</div>
</div>
))}
{conversionPairs && (
<div className="">
<p className="mb-0 mt-5 text-2xl text-white font-bold">
Grand total
</p>
<p className="mb-3 text-2xl text-white font-bold underline">
<div className="bg-slate-200 rounded-lg p-3">
<p className="mb-0 text-2xl font-bold text-black">Grand total</p>
<p className="mb-3 text-2xl font-bold underline text-green-700">
${" "}
{sumValues(conversionPairs, "moneyAmount").toLocaleString(
"en-US",
@ -89,7 +88,10 @@ const ResourceStore = (props: {
}
)}
</p>
<button className="bg-slate-100 py-2 text-slate-900 rounded-lg font-bold w-28 text-center">
<button
onClick={handleSellResources}
className="bg-green-700 py-2 text-slate-900 rounded-lg font-bold w-28 text-center text-white"
>
Sell Now
</button>
</div>

View File

@ -6,11 +6,22 @@ import { resourceToBg, resourceToFc } from "../../utils/helpers";
const ResourceStoreItem = (props: {
resourceAccount: IResourceAccount;
conversionPair: IConversionPair | undefined;
handleAmountChange: (
handleConversionPairs: (amount: number, resourceType: string) => void;
}) => {
const [error, setError] = useState("");
const handleAmountChange = (
e: React.ChangeEvent<HTMLInputElement>,
resourceType: string
) => void;
}) => {
) => {
const amount = Number(e.target.value);
if (amount <= props.resourceAccount.balance) {
props.handleConversionPairs(amount, resourceType);
if (error) setError("");
} else {
setError("You don't have enough");
}
};
return (
<div
className={
@ -59,13 +70,13 @@ const ResourceStoreItem = (props: {
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2.5"
strokeWidth="2.5"
stroke="currentColor"
className="w-6 h-6 mt-4 mx-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
strokeLinecap="round"
strokeLinejoin="round"
d="M17.25 8.25L21 12m0 0l-3.75 3.75M21 12H3"
/>
</svg>
@ -91,15 +102,20 @@ const ResourceStoreItem = (props: {
) : (
<div className="flex-1"></div>
)}
<div className="flex flex-col">
{error && (
<span className="text-red-500 font-bold mb-1 text-sm">{error}</span>
)}
<input
type="text"
className="bg-white px-4 py-2 mr-4 rounded-lg flex-none"
className="bg-white px-4 py-2 mr-2 rounded-lg h-full"
placeholder="0"
onChange={(e) =>
props.handleAmountChange(e, props.resourceAccount.resourceType)
handleAmountChange(e, props.resourceAccount.resourceType)
}
/>
</div>
</div>
);
};

View File

@ -23,7 +23,7 @@ const SelectDropdown: React.FC<ISelectDropdownProps> = (props) => {
onChange={handleChange}
className="text-black flex-1 p-2 border border-gray-300 rounded-lg"
>
<option value="">Select an option</option>
<option value="">Select</option>
{props.options.map((option, index) => (
<option key={index} value={option.value}>
{option.label}

View File

@ -3,7 +3,6 @@ import { IInventoryItem, IStakingSource, IStake, IOption } from "typings";
import CardLayout from "../Layouts/CardLayout";
import {
calculateRemainingTime,
prettifyTime,
getObjectFromArray,
} from "../../utils/helpers";
import SelectDropdown from "./SelectDropdown";
@ -60,6 +59,23 @@ const StakingSource = (props: {
setSelectedItemId(itemId);
};
const Countdown = (props: { remainingTime: number }) => {
const hours = Math.floor((props.remainingTime / (1000 * 60 * 60)) % 24)
.toString()
.padStart(2, "0");
const minutes = Math.floor((props.remainingTime / (1000 * 60)) % 60)
.toString()
.padStart(2, "0");
const seconds = Math.floor((props.remainingTime / 1000) % 60)
.toString()
.padStart(2, "0");
return (
<span className="font-bold">
{hours} : {minutes} : {seconds}
</span>
);
};
const RenderButtonOrCountdown = (props: { stake: IStake }) => {
if (!props.stake.remainingTime) return <p>Error</p>;
@ -75,31 +91,7 @@ const StakingSource = (props: {
} 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>
<Countdown remainingTime={props.stake.remainingTime} />
);
}
};
@ -116,22 +108,28 @@ const StakingSource = (props: {
<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>
<p className="font-bold mt-4 mb-2">Active Drills</p>
{activeStakes &&
activeStakes.map((stake, id) => (
<div key={id} className="mb-3 border border-white p-2">
<div
key={id}
className="border border-white/20 rounded-xl p-3 mb-2 bg-black/20"
>
<p>
<span className="font-bold">Drill: </span>
{props.inventoryItems &&
getObjectFromArray(props.inventoryItems, "id", stake.id)
?.storeItem.name}
getObjectFromArray(
props.inventoryItems,
"id",
stake.inventoryItemId
)?.storeItem.name}
</p>
<p>
<span className="font-bold">Resource: </span>
{stake.resourceType}
</p>
<p>
<span className="font-bold">Stake amount: </span>
<p className="mb-2">
<span className="font-bold">Yield: </span>
{stake.stakeAmount}
</p>
<RenderButtonOrCountdown stake={stake} />
@ -139,21 +137,23 @@ const StakingSource = (props: {
))}
</div>
<div className="flex-1">
<p className="font-bold mt-4 mb-2">Activate Drills</p>
<p className="font-bold mt-4 mb-2">Inactive 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
key={id}
className="border border-white/20 rounded-xl p-3 mb-2 bg-black/20"
>
<p className="font-bold">{item.storeItem.name}</p>
<p className="mt-2">Select Resource</p>
<div className="flex">
<SelectDropdown
options={props.stakingSource.resourceWells.map(
(well): IOption => ({
value: well.id,
label: `${well.resourceType} - ID# ${well.id}`,
label: well.resourceType,
})
)}
onChange={(value) => handleSelectChange(value, item.id)}
@ -162,9 +162,9 @@ const StakingSource = (props: {
{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"
className="bg-slate-100 text-slate-900 px-4 py-2 rounded-lg font-bold w-28 text-center ml-2"
>
Stake
Activate
</button>
) : (
<></>

View File

@ -3,6 +3,7 @@ import React, { useState } from "react";
import { IStoreItem } from "typings";
import CommonCardLayout from "../Layouts/CommonCardLayout";
import Chart from "./Chart";
import Image from "next/image";
const StoreItem = (props: {
storeItem: IStoreItem;
@ -10,39 +11,41 @@ const StoreItem = (props: {
}) => {
return (
<CommonCardLayout>
<div className="flex">
<div className="flex-1">
{props.storeItem.isOwned ? (
<span className="text-green-600 font-bold">Owned</span>
) : (
""
)}
<h3 className="text-xl font-bold mb-2">{props.storeItem.name}</h3>
<div className="flex ">
<div className="flex-1 pr-4 mr-4">
<h3 className="text-2xl font-bold mb-2">{props.storeItem.name}</h3>
<p className="text-sm mb-3">{props.storeItem.description}</p>
<p className="font-bold mt-3">Base Yield</p>
<p className="">{props.storeItem.claimAmount}</p>
</div>
<div className="flex-none items-start h-100 text-center">
{props.storeItem.isOwned ? (
<button className="bg-slate-400 text-slate-600 px-4 py-2 rounded-lg font-bold w-28 text-center cursor-not-allowed">
Owned
</button>
) : (
<>
<p className="text-lg font-bold mb-2">${props.storeItem.price}</p>
<div className="py-4 my-2">
<button
onClick={() => props.buyStoreItem(props.storeItem.id)}
className="bg-slate-100 text-slate-900 px-4 py-2 rounded-lg font-bold w-28 text-center"
>
Buy
Buy | ${props.storeItem.price}
</button>
</>
)}
</div>
<div className="flex">
<div className="mr-3">
<p className="font-bold">Base Yield</p>
<p className="">{props.storeItem.claimAmount}</p>
</div>
<div className="">
<p className="font-bold">Upgrades</p>
{props.storeItem.upgrades.map((upgrade, id) => (
<span key={id} className="mr-2">
{upgrade.claimBoost}
</span>
))}
</div>
</div>
<p className="font-bold mt-3">Upgrades</p>
<div className="max-h-44">
<Chart upgrades={props.storeItem.upgrades} />
</div>
<div className="relative object-contain w-48 h-48">
<Image
src={props.storeItem.image}
alt={props.storeItem.name}
fill
className="rounded-lg border border-white/20 shadow-lg object-contain"
/>
</div>
</div>
</CommonCardLayout>
);

View File

@ -10,10 +10,10 @@ const StoreItemView = (props: {
return (
<div className="bg-slate-800 p-4 rounded-lg">
<h2 className="text-2xl font-bold mb-4 text-white">Store</h2>
<div className="grid grid-cols-2 gap-4">
<div className="grid grid-cols-1 gap-4">
{props.storeItems &&
props.storeItems
.sort((a, b) => (a.isOwned === b.isOwned ? 0 : a.isOwned ? 1 : -1))
.filter((item) => !item.isOwned)
.map((storeItem, id) => (
<StoreItem
key={id}

View File

@ -61,13 +61,6 @@ export const calculateRemainingTime = (startTime: string, durationInMins: number
return remaining;
};
export const prettifyTime = (remainingTime: number) => {
const hours = Math.floor((remainingTime / (1000 * 60 * 60)) % 24);
const minutes = Math.floor((remainingTime / (1000 * 60)) % 60);
const seconds = Math.floor((remainingTime / 1000) % 60);
return { hours, minutes, seconds }
}
export const generateRandomBase64String = (length: number) => {
// Create a random byte array of the desired length.
const byteArray = new Uint8Array(length);
@ -78,25 +71,3 @@ export const generateRandomBase64String = (length: number) => {
return base64String;
}
export function toSnakeCase(str: string) {
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
}
export function toCamelCase(str: string) {
return str.replace(/([-_][a-z])/g, (group) =>
group.toUpperCase().replace("-", "").replace("_", "")
);
}
export const updateAllToCamelCase = (array) => {
const updatedArray = array.map(obj => {
const newObj = {}
Object.keys(obj).forEach(key => {
const camelCaseKey = toCamelCase(key);
newObj[camelCaseKey] = obj[key];
});
return newObj;
})
return updatedArray
}

1
typings.d.ts vendored
View File

@ -52,6 +52,7 @@ export interface IStoreItem {
id: string;
name: string;
description: string;
image: string,
price: number;
completionTimeInMins: number;
claimAmount: number;