Modify UI
This commit is contained in:
parent
16eb1405e6
commit
e90c0c9809
@ -11,57 +11,13 @@
|
||||
},
|
||||
"store": [
|
||||
{
|
||||
"id": "item1",
|
||||
"name": "Drill A",
|
||||
"description": "This is drill A",
|
||||
"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": "item2",
|
||||
"name": "Drill B",
|
||||
"description": "This is drill B",
|
||||
"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": "item3",
|
||||
"name": "Drill C",
|
||||
"description": "This is drill C",
|
||||
"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": "item4",
|
||||
"name": "Drill D",
|
||||
"description": "This is drill D",
|
||||
"id": "item1",
|
||||
"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 },
|
||||
@ -69,51 +25,54 @@
|
||||
{ "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 }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "item2",
|
||||
"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": 30 },
|
||||
{ "tier": 3, "price": 400, "claimBoost": 40 },
|
||||
{ "tier": 4, "price": 500, "claimBoost": 50 },
|
||||
{ "tier": 5, "price": 600, "claimBoost": 60 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "item3",
|
||||
"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": 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": "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 },
|
||||
{ "tier": 3, "price": 400, "claimBoost": 30 },
|
||||
{ "tier": 4, "price": 500, "claimBoost": 40 },
|
||||
{ "tier": 5, "price": 600, "claimBoost": 50 }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
46
package-lock.json
generated
46
package-lock.json
generated
@ -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",
|
||||
|
@ -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
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
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
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
BIN
public/assets/drill_4.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 405 KiB |
@ -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"
|
||||
|
@ -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;
|
@ -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,57 +35,65 @@ const InventoryItem = (props: {
|
||||
};
|
||||
return (
|
||||
<CardLayout>
|
||||
<h3 className="text-xl font-bold mb-2">
|
||||
{props.inventoryItem.storeItem.name}
|
||||
<div className="flex">
|
||||
{props.inventoryItem.storeItem.upgrades.map((upgrade, id) => {
|
||||
if (upgrade.tier <= currentUpgrade.tier) {
|
||||
return (
|
||||
<span
|
||||
key={id}
|
||||
className="bg-green-600 px-2 py-2 border border-black"
|
||||
></span>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<span
|
||||
key={id}
|
||||
className="bg-slate-200 px-2 py-2 border border-black"
|
||||
></span>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
</h3>
|
||||
<p className="text-sm">{props.inventoryItem.storeItem.description}</p>
|
||||
<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) {
|
||||
return (
|
||||
<span
|
||||
key={id}
|
||||
className="bg-green-600 px-2 py-2 border border-black"
|
||||
></span>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<span
|
||||
key={id}
|
||||
className="bg-slate-200 px-2 py-2 border border-black"
|
||||
></span>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
<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="">
|
||||
{isInUse() ? (
|
||||
<button className="bg-slate-400 text-slate-600 px-4 py-2 rounded-lg font-bold w-28 text-center cursor-not-allowed">
|
||||
In Use
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
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"
|
||||
>
|
||||
Upgrade
|
||||
</button>
|
||||
)}
|
||||
<div className="py-4 my-2">
|
||||
{isInUse() ? (
|
||||
<button className="bg-slate-400 text-slate-600 px-4 py-2 rounded-lg font-bold text-center cursor-not-allowed">
|
||||
In Use
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
onClick={() =>
|
||||
props.upgradeInventoryItem(props.inventoryItem.id)
|
||||
}
|
||||
className="bg-slate-100 text-slate-900 px-4 py-2 rounded-lg font-bold text-center"
|
||||
>
|
||||
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>
|
||||
);
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
console.log(conversionPairs);
|
||||
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>
|
||||
|
@ -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,14 +102,19 @@ const ResourceStoreItem = (props: {
|
||||
) : (
|
||||
<div className="flex-1"></div>
|
||||
)}
|
||||
<input
|
||||
type="text"
|
||||
className="bg-white px-4 py-2 mr-4 rounded-lg flex-none"
|
||||
placeholder="0"
|
||||
onChange={(e) =>
|
||||
props.handleAmountChange(e, props.resourceAccount.resourceType)
|
||||
}
|
||||
/>
|
||||
<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-2 rounded-lg h-full"
|
||||
placeholder="0"
|
||||
onChange={(e) =>
|
||||
handleAmountChange(e, props.resourceAccount.resourceType)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -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}
|
||||
|
@ -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>
|
||||
) : (
|
||||
<></>
|
||||
|
@ -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
|
||||
<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 | ${props.storeItem.price}
|
||||
</button>
|
||||
) : (
|
||||
<>
|
||||
<p className="text-lg font-bold mb-2">${props.storeItem.price}</p>
|
||||
<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
|
||||
</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>
|
||||
</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>
|
||||
<p className="font-bold mt-3">Upgrades</p>
|
||||
<div className="max-h-44">
|
||||
<Chart upgrades={props.storeItem.upgrades} />
|
||||
</div>
|
||||
</CommonCardLayout>
|
||||
);
|
||||
|
@ -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}
|
||||
|
@ -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);
|
||||
@ -77,26 +70,4 @@ export const generateRandomBase64String = (length: number) => {
|
||||
const base64String = btoa(String.fromCharCode(...byteArray));
|
||||
|
||||
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
1
typings.d.ts
vendored
@ -52,6 +52,7 @@ export interface IStoreItem {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
image: string,
|
||||
price: number;
|
||||
completionTimeInMins: number;
|
||||
claimAmount: number;
|
||||
|
Loading…
x
Reference in New Issue
Block a user