From 0c1f15464f5025c1671fd190e7f3c490bed274d8 Mon Sep 17 00:00:00 2001 From: Emil Andreas Nielsen <72539155+freakspace@users.noreply.github.com> Date: Sun, 12 Feb 2023 12:40:35 +0700 Subject: [PATCH] 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 --- src/app/Components/MiningItem.tsx | 52 ++++++++++++++ src/app/Components/MiningView.tsx | 16 +++++ src/app/Components/MoonItem.tsx | 57 +++++++++++++++ src/app/Components/MoonsView.tsx | 76 ++++++++++++++++++++ src/app/Components/ResourceItem.tsx | 51 ++++++++++++++ src/app/Components/ResourceView.tsx | 34 +++++++++ src/app/Components/UpgradeItem.tsx | 57 +++++++++++++++ src/app/Components/UpgradeView.tsx | 16 +++++ src/app/Layouts/CardLayout.tsx | 11 +++ src/app/Layouts/CommonCardLayout.tsx | 13 ++++ src/app/Layouts/EpicCardLayout.tsx | 11 +++ src/app/Layouts/PrestineCardLayout.tsx | 11 +++ src/app/Layouts/RareCardLayout.tsx | 11 +++ src/app/layout.tsx | 2 +- src/app/page.tsx | 97 +++++++++++++++++++++++++- src/utils/helpers.ts | 3 + typings.d.ts | 45 ++++++++++++ 17 files changed, 559 insertions(+), 4 deletions(-) create mode 100644 src/app/Components/MiningItem.tsx create mode 100644 src/app/Components/MiningView.tsx create mode 100644 src/app/Components/MoonItem.tsx create mode 100644 src/app/Components/MoonsView.tsx create mode 100644 src/app/Components/ResourceItem.tsx create mode 100644 src/app/Components/ResourceView.tsx create mode 100644 src/app/Components/UpgradeItem.tsx create mode 100644 src/app/Components/UpgradeView.tsx create mode 100644 src/app/Layouts/CardLayout.tsx create mode 100644 src/app/Layouts/CommonCardLayout.tsx create mode 100644 src/app/Layouts/EpicCardLayout.tsx create mode 100644 src/app/Layouts/PrestineCardLayout.tsx create mode 100644 src/app/Layouts/RareCardLayout.tsx create mode 100644 src/utils/helpers.ts create mode 100644 typings.d.ts diff --git a/src/app/Components/MiningItem.tsx b/src/app/Components/MiningItem.tsx new file mode 100644 index 0000000..7064085 --- /dev/null +++ b/src/app/Components/MiningItem.tsx @@ -0,0 +1,52 @@ +import React from "react"; +import { Drill } from "typings"; +import CardLayout from "../Layouts/CardLayout"; + +const MiningItem = (props: { drill: Drill }) => { + return ( + +

{props.drill.name}

+

{props.drill.description}

+
+
+

Base Yield

+
    + {props.drill.yield.map( + (x, id) => + x.resource && ( +
  • + {x.baseYield}{" "} + + {x.resource.name} + +
  • + ) + )} +
+

Upgrades

+
    +
  • + SkyMiner MK-III +
  • +
+
+
+

Status

+
    +
  • + Active Mining on Moon 1 +
  • +
+

Moon

+ +
+
+
+ ); +}; + +export default MiningItem; diff --git a/src/app/Components/MiningView.tsx b/src/app/Components/MiningView.tsx new file mode 100644 index 0000000..e533ad8 --- /dev/null +++ b/src/app/Components/MiningView.tsx @@ -0,0 +1,16 @@ +import React from "react"; +import { Drill } from "typings"; +import MiningItem from "./MiningItem"; + +const MiningView = (props: { drills: Drill[] }) => { + return ( +
+

Drills

+ {props.drills.map((drill, id) => ( + + ))} +
+ ); +}; + +export default MiningView; diff --git a/src/app/Components/MoonItem.tsx b/src/app/Components/MoonItem.tsx new file mode 100644 index 0000000..539bcfd --- /dev/null +++ b/src/app/Components/MoonItem.tsx @@ -0,0 +1,57 @@ +import React from "react"; +import { Moon } from "typings"; +import CardLayout from "../Layouts/CardLayout"; + +const MoonItem = (props: { moon: Moon }) => { + return ( + +

{props.moon.name}

+

{props.moon.description}

+
+
+

Mineral Composition

+
    + {props.moon.resources.map((resource, id) => ( +
  • + {resource.name}{" "} + 80% +
  • + ))} +
+
+
+

Status

+
    +
  • + + + + + + Operational +
  • +
+

Drill

+
    +
  • + Eclipse Drill +
  • +
+
+
+
+ ); +}; + +export default MoonItem; diff --git a/src/app/Components/MoonsView.tsx b/src/app/Components/MoonsView.tsx new file mode 100644 index 0000000..b9f9037 --- /dev/null +++ b/src/app/Components/MoonsView.tsx @@ -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([]); + + 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 ( +
+

Moons

+ {props.moons.map((moon, id) => ( + + ))} +
+ + {isMining &&
Mining time: {miningTime}
} +
+
Here you will see your mined resources
+ {farmedResources.length <= 0 ? ( +
Start mining to get resources
+ ) : ( + <> + {farmedResources.map((farmedResource, index) => ( +
+ {farmedResource} + +
+ ))} + + )} +
+ ); +}; + +export default MoonsView; diff --git a/src/app/Components/ResourceItem.tsx b/src/app/Components/ResourceItem.tsx new file mode 100644 index 0000000..acb39af --- /dev/null +++ b/src/app/Components/ResourceItem.tsx @@ -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 ( +
+
+ + {props.resourceCardProps.resource.name} + +

+ {totalYield.toLocaleString("en-US", { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })}{" "} + kg +

+ + {props.resourceCardProps.yieldPerSecond * 3600} / hour + +
+
+ ); +}; + +export default ResourceItem; diff --git a/src/app/Components/ResourceView.tsx b/src/app/Components/ResourceView.tsx new file mode 100644 index 0000000..b9fcbd9 --- /dev/null +++ b/src/app/Components/ResourceView.tsx @@ -0,0 +1,34 @@ +"use client"; +import React from "react"; +import { Resource } from "typings"; +import ResourceItem from "./ResourceItem"; + +const ResourceView = (props: { resources: Resource[] }) => { + return ( +
+
+
+
+ Moonbucks +

$5,342.23

+ +
+
+ {props.resources.map((resource, id) => { + const resourceCardProps = { + resource: resource, + isMining: true, + yieldPerSecond: 0.15, + }; + return ( + + ); + })} +
+
+ ); +}; + +export default ResourceView; diff --git a/src/app/Components/UpgradeItem.tsx b/src/app/Components/UpgradeItem.tsx new file mode 100644 index 0000000..a262c88 --- /dev/null +++ b/src/app/Components/UpgradeItem.tsx @@ -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 ( + +
+
+ {props.upgrade.owned && ( + Owned + )} +

{props.upgrade.name}

+

{props.upgrade.description}

+ {!props.upgrade.owned && ( +

${props.upgrade.price}

+ )} +

Modifies

+
    + {props.upgrade.modifiers.map((modifier, id) => ( +
  • + {modifier.yield}{" "} + + {modifier.resource && modifier.resource.name} + +
  • + ))} +
+
+ {!props.upgrade.owned ? ( +
+ +
+ ) : ( +
+

Drill

+ +
+ )} +
+
+ ); +}; + +export default UpgradeItem; diff --git a/src/app/Components/UpgradeView.tsx b/src/app/Components/UpgradeView.tsx new file mode 100644 index 0000000..815aac8 --- /dev/null +++ b/src/app/Components/UpgradeView.tsx @@ -0,0 +1,16 @@ +import React from "react"; +import { Upgrade } from "typings"; +import UpgradeItem from "./UpgradeItem"; + +const UpgradeView = (props: { upgrades: Upgrade[] }) => { + return ( +
+

Upgrades

+ {props.upgrades.map((upgrade, id) => ( + + ))} +
+ ); +}; + +export default UpgradeView; diff --git a/src/app/Layouts/CardLayout.tsx b/src/app/Layouts/CardLayout.tsx new file mode 100644 index 0000000..348238f --- /dev/null +++ b/src/app/Layouts/CardLayout.tsx @@ -0,0 +1,11 @@ +export default function CardLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( +
+ {children} +
+ ); +} diff --git a/src/app/Layouts/CommonCardLayout.tsx b/src/app/Layouts/CommonCardLayout.tsx new file mode 100644 index 0000000..d04ff1d --- /dev/null +++ b/src/app/Layouts/CommonCardLayout.tsx @@ -0,0 +1,13 @@ +export default function CommonCardLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( +
+ {children} +
+ ); +} + +// 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 diff --git a/src/app/Layouts/EpicCardLayout.tsx b/src/app/Layouts/EpicCardLayout.tsx new file mode 100644 index 0000000..aedda8d --- /dev/null +++ b/src/app/Layouts/EpicCardLayout.tsx @@ -0,0 +1,11 @@ +export default function EpicCardLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( +
+ {children} +
+ ); +} diff --git a/src/app/Layouts/PrestineCardLayout.tsx b/src/app/Layouts/PrestineCardLayout.tsx new file mode 100644 index 0000000..bbc11d4 --- /dev/null +++ b/src/app/Layouts/PrestineCardLayout.tsx @@ -0,0 +1,11 @@ +export default function PrestineCardLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( +
+ {children} +
+ ); +} diff --git a/src/app/Layouts/RareCardLayout.tsx b/src/app/Layouts/RareCardLayout.tsx new file mode 100644 index 0000000..a0154c3 --- /dev/null +++ b/src/app/Layouts/RareCardLayout.tsx @@ -0,0 +1,11 @@ +export default function RareCardLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( +
+ {children} +
+ ); +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 6901b0c..6e5a2cb 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -8,7 +8,7 @@ export default function RootLayout({ return ( - {children} + {children} ); } diff --git a/src/app/page.tsx b/src/app/page.tsx index 333a95c..ed02308 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -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() { return ( -
-

To the moon!

; -
+ <> + +
+ + + +
+ ); } diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts new file mode 100644 index 0000000..7de1cd2 --- /dev/null +++ b/src/utils/helpers.ts @@ -0,0 +1,3 @@ +export default function getObjectFromArray(array: T[], key: keyof T, value: any): T | undefined { + return array.find(obj => obj[key] === value); + } \ No newline at end of file diff --git a/typings.d.ts b/typings.d.ts new file mode 100644 index 0000000..c1ee1ba --- /dev/null +++ b/typings.d.ts @@ -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 +} \ No newline at end of file