Merge feature/resource_store

* Add two views to resource store

* Add the endpoints (#4)

* add handleAmountChange

* add template changes

* add components to resourceAccounts

* refactor the storeview layout a bit

* clean up some stuff, change grand total
This commit is contained in:
Emil Nielsen 2023-03-19 10:04:50 +07:00 committed by Joseph Ferano
parent 8b10db0de5
commit e820f1c45b
9 changed files with 273 additions and 18 deletions

BIN
database.db Normal file

Binary file not shown.

View File

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import { IInventoryItem, IStoreItem } from "typings"; import { IInventoryItem } from "typings";
import CardLayout from "../Layouts/CardLayout"; import CardLayout from "../Layouts/CardLayout";
const InventoryItem = (props: { const InventoryItem = (props: {

View File

@ -1,12 +0,0 @@
import React from "react";
import { IBankAccount } from "typings";
const LightBox = (props: { bankAccounts: IBankAccount[] }) => {
return (
<div className="flex-1">
<h1>Sell Your Resources</h1>
</div>
);
};
export default LightBox;

View File

@ -0,0 +1,35 @@
import React from "react";
const ResourceItem = (props: {
name: string;
bgColor: string;
fontColor: string;
amount: number;
unit: string;
}) => {
return (
<div
className={
props.bgColor +
" bg-gradient-to-br hover:bg-gradient-to-tr rounded-lg p-3"
}
>
<div className="text-white">
<div className="flex">
<span>
<span className={props.fontColor + " font-bold"}>{props.name}</span>
<h3 className="text-2xl font-bold">
{props.amount.toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}{" "}
{props.unit}
</h3>
</span>
</div>
</div>
</div>
);
};
export default ResourceItem;

View File

@ -0,0 +1,113 @@
import React, { useState, useEffect } from "react";
import ResourceItem from "./ResourceItem";
import ResourceStoreItem from "./ResourceStoreItem";
import { sumValues } from "../../utils/helpers";
import {
IBankAccount,
IConversionPair,
IClaimableResource,
IResourceType,
} from "typings";
const ResourceStore = (props: {
bankAccounts: IBankAccount[];
setLightBoxIsActive: () => void;
}) => {
const [conversionRate, setConversionRate] = useState<Number>(0.1);
const [amount, setAmount] = useState<IClaimableResource[]>([]);
const [conversionPairs, setConversionPairs] = useState<
IConversionPair[] | null
>(null);
useEffect(() => {
const pairs = amount.map((n) => ({
resourceType: n.resourceType,
resourceAmount: n.balance,
moneyAmount: n.balance * conversionRate.valueOf(),
}));
setConversionPairs(pairs);
}, [amount]);
const handleAmountChange = (
e: React.ChangeEvent<HTMLInputElement>,
resourceType: IResourceType
) => {
const existingObj = amount.find(
(obj) => obj.resourceType.name === resourceType.name
);
if (existingObj) {
setAmount(
amount.map((obj) =>
obj.resourceType.name === resourceType.name
? { resourceType: resourceType, balance: Number(e.target.value) }
: obj
)
);
} else {
setAmount([
...amount,
{ resourceType: resourceType, balance: Number(e.target.value) },
]);
}
};
const getConversionPair = (name: string) => {
return conversionPairs?.find((obj) => obj.resourceType.name === name);
};
return (
<div className="p-4 max-w-5xl">
<h1 className="text-white text-4xl font-extrabold">
Sell Your Resources
</h1>
<div className="flex gap-4 mt-4">
<div className="flex-1">
{props.bankAccounts.map((bankAccount) => (
<div className="flex mb-4 gap-4">
<div className="flex-1">
<ResourceStoreItem
bankAccount={bankAccount}
conversionPair={getConversionPair(
bankAccount.resourceType.name
)}
handleAmountChange={handleAmountChange}
/>
</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">
${" "}
{sumValues(conversionPairs, "moneyAmount").toLocaleString(
"en-US",
{
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}
)}
</p>
{/* <ResourceItem
name="MoonBucks"
bgColor="bg-green-800"
fontColor="text-green-400"
amount={sumValues(conversionPairs, "moneyAmount")}
unit="$"
/> */}
<button className="bg-slate-100 py-2 text-slate-900 rounded-lg font-bold w-28 text-center">
Sell Now
</button>
</div>
)}
</div>
</div>
</div>
);
};
export default ResourceStore;

View File

@ -0,0 +1,106 @@
"use client";
import React, { useEffect, useState } from "react";
import { IBankAccount, IConversionPair } from "typings";
import { IResourceType } from "typings";
const ResourceStoreItem = (props: {
bankAccount: IBankAccount;
conversionPair: IConversionPair | undefined;
handleAmountChange: (
e: React.ChangeEvent<HTMLInputElement>,
resourceType: IResourceType
) => void;
}) => {
return (
<div
className={
props.bankAccount.resourceType.bgColorClass +
" bg-gradient-to-br hover:bg-gradient-to-tr rounded-lg p-3 flex flex-row"
}
>
<div className="text-white mr-4 flex-none">
<span
className={
props.bankAccount.resourceType.fontColorClass + " font-bold"
}
>
{props.bankAccount.resourceType.name}
</span>
<h3 className="text-2xl font-bold">
{props.bankAccount.balance.toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}{" "}
kg
</h3>
</div>
{props.conversionPair ? (
<div className={"text-white flex-1 border-l border-white/25 pl-4"}>
<div className="flex">
<span>
<span
className={
props.conversionPair.resourceType.fontColorClass +
" font-bold"
}
>
{props.conversionPair.resourceType.name}
</span>
<h3 className="text-2xl font-bold">
{props.conversionPair.resourceAmount.toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}{" "}
kg.
</h3>
</span>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2.5"
stroke="currentColor"
className="w-6 h-6 mt-4 mx-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M17.25 8.25L21 12m0 0l-3.75 3.75M21 12H3"
/>
</svg>
<span>
<span
className={
props.conversionPair.resourceType.fontColorClass +
" font-bold"
}
>
Moonbucks
</span>
<h3 className="text-2xl font-bold">
$
{props.conversionPair.moneyAmount.toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}
</h3>
</span>
</div>
</div>
) : (
<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.bankAccount.resourceType)
}
/>
</div>
);
};
export default ResourceStoreItem;

View File

@ -5,7 +5,7 @@ import InventoryItemView from "./Components/InventoryItemView";
import StakingSourcesView from "./Components/StakingSourcesView"; import StakingSourcesView from "./Components/StakingSourcesView";
import BankAccountsView from "./Components/BankAccountsView"; import BankAccountsView from "./Components/BankAccountsView";
import StoreItemView from "./Components/StoreItemView"; import StoreItemView from "./Components/StoreItemView";
import LightBox from "./Components/LightBox"; import ResourceStore from "./Components/ResourceStore";
import { import {
IStoreItem, IStoreItem,
IInventoryItem, IInventoryItem,
@ -194,19 +194,22 @@ export default function Home() {
}; };
const handleSetLightBox = () => { const handleSetLightBox = () => {
console.log("Tester");
setLightBoxIsActive(!lightBoxIsActive); setLightBoxIsActive(!lightBoxIsActive);
}; };
const renderLightBox = () => {
if (lightBoxIsActive) return <LightBox bankAccounts={bankAccounts} />;
};
return ( return (
<> <>
<BankAccountsView <BankAccountsView
bankAccounts={bankAccounts} bankAccounts={bankAccounts}
setLightBoxIsActive={handleSetLightBox} setLightBoxIsActive={handleSetLightBox}
/> />
{lightBoxIsActive && (
<ResourceStore
bankAccounts={bankAccounts}
setLightBoxIsActive={handleSetLightBox}
/>
)}
<div className="grid grid-cols-3 gap-8 p-4"> <div className="grid grid-cols-3 gap-8 p-4">
<StakingSourcesView <StakingSourcesView
stakingSources={stakingSources} stakingSources={stakingSources}

View File

@ -6,4 +6,8 @@ export function pushElementToArray<T>(array: T[], element: T): T[] {
const newArray = [...array]; // create a new array const newArray = [...array]; // create a new array
newArray.push(element); // add the new element to the array newArray.push(element); // add the new element to the array
return newArray; // return the new array return newArray; // return the new array
}
export function sumValues<T extends Record<K, number>, K extends keyof T>(array: T[], key: K): number {
return array.reduce((acc, obj) => acc + obj[key], 0);
} }

6
typings.d.ts vendored
View File

@ -52,3 +52,9 @@ export interface IClaimableResource {
resourceType: IResourceType; resourceType: IResourceType;
balance: number; balance: number;
} }
export interface IConversionPair {
resourceType: IResourceType;
resourceAmount: number;
moneyAmount: number
}