Feature/homepage (#2)
* Basic UI for resources * Style upgrades etc. * Add template for drill * Add moons and drill templates * Add mining timer * Delete comment * Modify some styling to cards and resources * Enhance styling on difference components --------- Co-authored-by: Nico Li <nilindenau@gmail.com>
This commit is contained in:
parent
988920afc0
commit
0c1f15464f
52
src/app/Components/MiningItem.tsx
Normal file
52
src/app/Components/MiningItem.tsx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Drill } from "typings";
|
||||||
|
import CardLayout from "../Layouts/CardLayout";
|
||||||
|
|
||||||
|
const MiningItem = (props: { drill: Drill }) => {
|
||||||
|
return (
|
||||||
|
<CardLayout>
|
||||||
|
<h3 className="text-xl font-bold mb-2">{props.drill.name}</h3>
|
||||||
|
<p className="text-sm">{props.drill.description}</p>
|
||||||
|
<div className="flex gap-4">
|
||||||
|
<div className="flex-1">
|
||||||
|
<p className="font-bold mt-4">Base Yield</p>
|
||||||
|
<ul className="list-none">
|
||||||
|
{props.drill.yield.map(
|
||||||
|
(x, id) =>
|
||||||
|
x.resource && (
|
||||||
|
<li key={id}>
|
||||||
|
<span>{x.baseYield}</span>{" "}
|
||||||
|
<span className="text-teal-500 font-bold">
|
||||||
|
{x.resource.name}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
<p className="font-bold mt-4">Upgrades</p>
|
||||||
|
<ul className="list-none">
|
||||||
|
<li>
|
||||||
|
<span className="">SkyMiner MK-III</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div className="flex-1">
|
||||||
|
<p className="font-bold mt-4">Status</p>
|
||||||
|
<ul className="list-none">
|
||||||
|
<li>
|
||||||
|
<span className="">Active Mining on Moon 1</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p className="font-bold mt-4">Moon</p>
|
||||||
|
<select className="block bg-white px-4 py-2 pr-8 rounded shadow text-black cursor-pointer">
|
||||||
|
<option>Moon 1</option>
|
||||||
|
<option>Moon 2</option>
|
||||||
|
<option>Moon 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MiningItem;
|
16
src/app/Components/MiningView.tsx
Normal file
16
src/app/Components/MiningView.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Drill } from "typings";
|
||||||
|
import MiningItem from "./MiningItem";
|
||||||
|
|
||||||
|
const MiningView = (props: { drills: Drill[] }) => {
|
||||||
|
return (
|
||||||
|
<div className="bg-slate-800 text-white p-4 rounded-lg">
|
||||||
|
<h2 className="text-2xl font-bold mb-4">Drills</h2>
|
||||||
|
{props.drills.map((drill, id) => (
|
||||||
|
<MiningItem key={id} drill={drill} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MiningView;
|
57
src/app/Components/MoonItem.tsx
Normal file
57
src/app/Components/MoonItem.tsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Moon } from "typings";
|
||||||
|
import CardLayout from "../Layouts/CardLayout";
|
||||||
|
|
||||||
|
const MoonItem = (props: { moon: Moon }) => {
|
||||||
|
return (
|
||||||
|
<CardLayout>
|
||||||
|
<h3 className="text-xl font-bold mb-2">{props.moon.name}</h3>
|
||||||
|
<p className="text-sm">{props.moon.description}</p>
|
||||||
|
<div className="flex gap-4">
|
||||||
|
<div className="flex-1">
|
||||||
|
<p className="font-bold mt-4">Mineral Composition</p>
|
||||||
|
<ul className="list-none">
|
||||||
|
{props.moon.resources.map((resource, id) => (
|
||||||
|
<li key={id}>
|
||||||
|
<span>{resource.name}</span>{" "}
|
||||||
|
<span className="text-teal-500 font-bold">80%</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div className="flex-1">
|
||||||
|
<p className="font-bold mt-4">Status</p>
|
||||||
|
<ul className="list-none">
|
||||||
|
<li className="flex">
|
||||||
|
<span className="text-green-600 mr-1">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
className="w-6 h-6"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
Operational
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p className="font-bold mt-4">Drill</p>
|
||||||
|
<ul className="list-none">
|
||||||
|
<li>
|
||||||
|
<span className="">Eclipse Drill</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MoonItem;
|
76
src/app/Components/MoonsView.tsx
Normal file
76
src/app/Components/MoonsView.tsx
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
"use client";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { Moon } from "typings";
|
||||||
|
import MoonItem from "./MoonItem";
|
||||||
|
|
||||||
|
const MoonsView = (props: { moons: Moon[] }) => {
|
||||||
|
const [isMining, setIsMining] = useState(false);
|
||||||
|
const [miningTime, setMiningTime] = useState(3);
|
||||||
|
const [farmedResources, setFarmedResources] = useState<string[]>([]);
|
||||||
|
|
||||||
|
const resources = ["Moonstone", "Lunarite", "Selenite", "Heliogem"];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isMining) {
|
||||||
|
const intervalId = setInterval(() => {
|
||||||
|
setMiningTime((prev) => prev - 1);
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
if (miningTime === 0) {
|
||||||
|
setIsMining(false);
|
||||||
|
setFarmedResources((prev) => [
|
||||||
|
...prev,
|
||||||
|
resources[Math.floor(Math.random() * (resources.length - 1 - 1))],
|
||||||
|
]);
|
||||||
|
clearInterval(intervalId);
|
||||||
|
setMiningTime(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, [isMining, miningTime]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-slate-800 p-4 rounded-lg text-white">
|
||||||
|
<h2 className="text-2xl mb-4 font-bold">Moons</h2>
|
||||||
|
{props.moons.map((moon, id) => (
|
||||||
|
<MoonItem key={id} moon={moon} />
|
||||||
|
))}
|
||||||
|
<div className="flex mt-5">
|
||||||
|
<button
|
||||||
|
className="bg-slate-100 text-slate-900 p-1 rounded-lg"
|
||||||
|
onClick={() => setIsMining(true)}
|
||||||
|
>
|
||||||
|
Start mining
|
||||||
|
</button>
|
||||||
|
{isMining && <div className="p-1 ml-5">Mining time: {miningTime}</div>}
|
||||||
|
</div>
|
||||||
|
<div className="mt-5"> Here you will see your mined resources</div>
|
||||||
|
{farmedResources.length <= 0 ? (
|
||||||
|
<div>Start mining to get resources</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{farmedResources.map((farmedResource, index) => (
|
||||||
|
<div className="my-2" key={index}>
|
||||||
|
{farmedResource}
|
||||||
|
<button
|
||||||
|
className="bg-slate-100 text-slate-900 p-1 mx-2 rounded-lg"
|
||||||
|
onClick={() =>
|
||||||
|
setFarmedResources((prev) =>
|
||||||
|
prev.filter((_, idx) => idx !== index)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Claim
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MoonsView;
|
51
src/app/Components/ResourceItem.tsx
Normal file
51
src/app/Components/ResourceItem.tsx
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
"use client";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { IResourceCardProps } from "typings";
|
||||||
|
|
||||||
|
const ResourceItem = (props: { resourceCardProps: IResourceCardProps }) => {
|
||||||
|
const [totalYield, settotalYield] = useState(100);
|
||||||
|
const [isMining, setIsMining] = useState(props.resourceCardProps.isMining);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isMining) {
|
||||||
|
const intervalId = setInterval(() => {
|
||||||
|
settotalYield((prev) => prev + props.resourceCardProps.yieldPerSecond);
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, [totalYield]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
props.resourceCardProps.resource.bgColorClass +
|
||||||
|
" bg-gradient-to-br hover:bg-gradient-to-tr rounded-lg p-3"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className="text-white">
|
||||||
|
<span
|
||||||
|
className={
|
||||||
|
props.resourceCardProps.resource.fontColorClass + " font-bold"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{props.resourceCardProps.resource.name}
|
||||||
|
</span>
|
||||||
|
<h3 className="text-2xl font-bold">
|
||||||
|
{totalYield.toLocaleString("en-US", {
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2,
|
||||||
|
})}{" "}
|
||||||
|
kg
|
||||||
|
</h3>
|
||||||
|
<span className="text-sm">
|
||||||
|
{props.resourceCardProps.yieldPerSecond * 3600} / hour
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ResourceItem;
|
34
src/app/Components/ResourceView.tsx
Normal file
34
src/app/Components/ResourceView.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
"use client";
|
||||||
|
import React from "react";
|
||||||
|
import { Resource } from "typings";
|
||||||
|
import ResourceItem from "./ResourceItem";
|
||||||
|
|
||||||
|
const ResourceView = (props: { resources: Resource[] }) => {
|
||||||
|
return (
|
||||||
|
<div className="p-4">
|
||||||
|
<div className="grid grid-cols-5 gap-8">
|
||||||
|
<div className="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>
|
||||||
|
<button className="px-2 text-sm mt-1 rounded-lg font-bold bg-green-400 text-green-800">
|
||||||
|
Sell Resources
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{props.resources.map((resource, id) => {
|
||||||
|
const resourceCardProps = {
|
||||||
|
resource: resource,
|
||||||
|
isMining: true,
|
||||||
|
yieldPerSecond: 0.15,
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<ResourceItem key={id} resourceCardProps={resourceCardProps} />
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ResourceView;
|
57
src/app/Components/UpgradeItem.tsx
Normal file
57
src/app/Components/UpgradeItem.tsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Upgrade } from "typings";
|
||||||
|
import CardLayout from "../Layouts/CardLayout";
|
||||||
|
import RareCardLayout from "../Layouts/RareCardLayout";
|
||||||
|
import EpicCardLayout from "../Layouts/EpicCardLayout";
|
||||||
|
import PrestineCardLayout from "../Layouts/PrestineCardLayout";
|
||||||
|
import CommonCardLayout from "../Layouts/CommonCardLayout";
|
||||||
|
|
||||||
|
const UpgradeItem = (props: { upgrade: Upgrade }) => {
|
||||||
|
return (
|
||||||
|
<CommonCardLayout>
|
||||||
|
<div className="flex gap-4">
|
||||||
|
<div className="flex-1">
|
||||||
|
{props.upgrade.owned && (
|
||||||
|
<span className="text-green-600 font-bold">Owned</span>
|
||||||
|
)}
|
||||||
|
<h3 className="text-xl font-bold mb-2">{props.upgrade.name}</h3>
|
||||||
|
<p className="text-sm mb-3">{props.upgrade.description}</p>
|
||||||
|
{!props.upgrade.owned && (
|
||||||
|
<p className="text-lg font-bold">${props.upgrade.price}</p>
|
||||||
|
)}
|
||||||
|
<p className="font-bold mt-3">Modifies</p>
|
||||||
|
<ul className="list-none">
|
||||||
|
{props.upgrade.modifiers.map((modifier, id) => (
|
||||||
|
<li key={id}>
|
||||||
|
<span>{modifier.yield}</span>{" "}
|
||||||
|
<span
|
||||||
|
className={modifier.resource?.fontColorClass + " font-bold"}
|
||||||
|
>
|
||||||
|
{modifier.resource && modifier.resource.name}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{!props.upgrade.owned ? (
|
||||||
|
<div className="flex items-center h-100">
|
||||||
|
<button 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-none items-center h-100">
|
||||||
|
<p className="font-bold mt-4">Drill</p>
|
||||||
|
<select className="block bg-white px-4 py-2 pr-8 rounded shadow text-black cursor-pointer">
|
||||||
|
<option>Drill 1</option>
|
||||||
|
<option>Drill 2</option>
|
||||||
|
<option>Drill 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</CommonCardLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default UpgradeItem;
|
16
src/app/Components/UpgradeView.tsx
Normal file
16
src/app/Components/UpgradeView.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Upgrade } from "typings";
|
||||||
|
import UpgradeItem from "./UpgradeItem";
|
||||||
|
|
||||||
|
const UpgradeView = (props: { upgrades: Upgrade[] }) => {
|
||||||
|
return (
|
||||||
|
<div className="bg-slate-800 p-4 rounded-lg">
|
||||||
|
<h2 className="text-2xl font-bold mb-4 text-white">Upgrades</h2>
|
||||||
|
{props.upgrades.map((upgrade, id) => (
|
||||||
|
<UpgradeItem key={id} upgrade={upgrade} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default UpgradeView;
|
11
src/app/Layouts/CardLayout.tsx
Normal file
11
src/app/Layouts/CardLayout.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export default function CardLayout({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="rounded-lg border border-black/25 bg-slate-700 shadow-xl shadow-black/5 p-4 mb-4 text-slate-100">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
13
src/app/Layouts/CommonCardLayout.tsx
Normal file
13
src/app/Layouts/CommonCardLayout.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export default function CommonCardLayout({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="rounded-lg border border-black/25 bg-gradient-to-br from-slate-700 via-slate-600 to-slate-800 shadow-xl shadow-black/5 p-4 mb-4 text-slate-100">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rounded-lg border border-black/25 bg-gradient-to-br from-slate-700 via-slate-600 to-slate-800 shadow-xl shadow-black/5 p-4 mb-4 text-slate-100
|
11
src/app/Layouts/EpicCardLayout.tsx
Normal file
11
src/app/Layouts/EpicCardLayout.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export default function EpicCardLayout({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="rounded-lg border border-black/25 bg-gradient-to-br from-slate-800 via-purple-900 to-slate-900 shadow-xl shadow-black/5 p-4 mb-4 text-slate-100">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
11
src/app/Layouts/PrestineCardLayout.tsx
Normal file
11
src/app/Layouts/PrestineCardLayout.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export default function PrestineCardLayout({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="rounded-lg border border-black/25 bg-gradient-to-br from-yellow-700 via-yellow-600 to-yellow-800 shadow-xl shadow-black/5 p-4 mb-4 text-slate-100">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
11
src/app/Layouts/RareCardLayout.tsx
Normal file
11
src/app/Layouts/RareCardLayout.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export default function RareCardLayout({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="rounded-lg border border-black/25 bg-gradient-to-br from-slate-700 via-slate-600 to-slate-800 shadow-xl shadow-black/5 p-4 mb-4 text-slate-100">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -8,7 +8,7 @@ export default function RootLayout({
|
|||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head />
|
<head />
|
||||||
<body>{children}</body>
|
<body className="bg-slate-900">{children}</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,98 @@
|
|||||||
|
import MiningView from "./Components/MiningView";
|
||||||
|
import MoonsView from "./Components/MoonsView";
|
||||||
|
import ResourceView from "./Components/ResourceView";
|
||||||
|
import UpgradeView from "./Components/UpgradeView";
|
||||||
|
import { Resource, Upgrade, Drill, Moon } from "typings";
|
||||||
|
|
||||||
|
import getObjectFromArray from "@/utils/helpers";
|
||||||
|
|
||||||
|
const resources: Resource[] = [
|
||||||
|
{
|
||||||
|
name: "Moonstone",
|
||||||
|
fontColorClass: "text-teal-400",
|
||||||
|
bgColorClass: "from-teal-800 to-teal-900",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Lunarite",
|
||||||
|
fontColorClass: "text-cyan-400",
|
||||||
|
bgColorClass: "from-cyan-800 to-cyan-900",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Selenite",
|
||||||
|
fontColorClass: "text-purple-300",
|
||||||
|
bgColorClass: "from-purple-800 to-purple-900",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Heliogem",
|
||||||
|
fontColorClass: "text-rose-300",
|
||||||
|
bgColorClass: "from-rose-800 to-rose-900",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const upgrades: Upgrade[] = [
|
||||||
|
{
|
||||||
|
name: "SkyMiner MK-III",
|
||||||
|
description:
|
||||||
|
"A cutting-edge mining robot equipped with advanced sensors, capable of identifying and extracting even the rarest minerals on the moon's surface.",
|
||||||
|
price: 500,
|
||||||
|
modifiers: [
|
||||||
|
{
|
||||||
|
resource: getObjectFromArray(resources, "name", "Moonstone"),
|
||||||
|
yield: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
owned: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Astro-Excavator 5000",
|
||||||
|
description:
|
||||||
|
"A state-of-the-art excavation machine, capable of digging deeper and faster than any other equipment on the market.",
|
||||||
|
price: 250,
|
||||||
|
modifiers: [
|
||||||
|
{
|
||||||
|
resource: getObjectFromArray(resources, "name", "Selenite"),
|
||||||
|
yield: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
owned: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const drills: Drill[] = [
|
||||||
|
{
|
||||||
|
name: "Eclipse Drill",
|
||||||
|
description:
|
||||||
|
"A compact and lightweight drill designed for use in tight and narrow mining tunnels.",
|
||||||
|
price: 1500,
|
||||||
|
yield: [
|
||||||
|
{
|
||||||
|
resource: getObjectFromArray(resources, "name", "Lunarite"),
|
||||||
|
baseYield: 250,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
upgrades: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const moons: Moon[] = [
|
||||||
|
{
|
||||||
|
name: "Selene's Eye",
|
||||||
|
description:
|
||||||
|
"Selene's Eye is a large and mysterious moon, named for its distinctive appearance - a bright, glowing eye that seems to stare out from the void of space",
|
||||||
|
resources: resources,
|
||||||
|
drill: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<div className="h-screen flex justify-center items-center">
|
<>
|
||||||
<h1 className="text-red-500 text-9xl">To the moon!</h1>;
|
<ResourceView resources={resources} />
|
||||||
</div>
|
<div className="grid grid-cols-3 gap-8 p-4">
|
||||||
|
<MoonsView moons={moons} />
|
||||||
|
<MiningView drills={drills} />
|
||||||
|
<UpgradeView upgrades={upgrades} />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
3
src/utils/helpers.ts
Normal file
3
src/utils/helpers.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default function getObjectFromArray<T>(array: T[], key: keyof T, value: any): T | undefined {
|
||||||
|
return array.find(obj => obj[key] === value);
|
||||||
|
}
|
45
typings.d.ts
vendored
Normal file
45
typings.d.ts
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
export type Resource = {
|
||||||
|
name: string,
|
||||||
|
fontColorClass: string,
|
||||||
|
bgColorClass: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IResourceCardProps {
|
||||||
|
resource: Resource,
|
||||||
|
isMining: boolean,
|
||||||
|
yieldPerSecond: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Modifier = {
|
||||||
|
resource: Resource | undefined,
|
||||||
|
yield: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Yield = {
|
||||||
|
resource: Resource | undefined,
|
||||||
|
baseYield: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Moon = {
|
||||||
|
name: string,
|
||||||
|
description: string,
|
||||||
|
resources: Resource[]
|
||||||
|
drill: Drill | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Drill = {
|
||||||
|
name: string,
|
||||||
|
description: string,
|
||||||
|
price: number,
|
||||||
|
yield: Yield[]
|
||||||
|
upgrades: Upgrade[] | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Upgrade = {
|
||||||
|
name: string,
|
||||||
|
description: string,
|
||||||
|
price: number,
|
||||||
|
modifiers: Modifier[]
|
||||||
|
owned: boolean
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user