Compare commits
10 Commits
b9390c18ab
...
a7c03a2703
Author | SHA1 | Date | |
---|---|---|---|
|
a7c03a2703 | ||
b965371fe5 | |||
6c1ac1838f | |||
|
a7e7c4dbe9 | ||
|
87ac3c373b | ||
01cc1d78ef | |||
|
d0bcdde4c8 | ||
9f01712230 | |||
40060686a0 | |||
d040970e97 |
@ -6,8 +6,11 @@ COPY package*.json ./
|
|||||||
|
|
||||||
RUN npm install
|
RUN npm install
|
||||||
|
|
||||||
|
# RUN npm run build
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# CMD ["npm", "run", "start"]
|
||||||
CMD ["npm", "run", "dev"]
|
CMD ["npm", "run", "dev"]
|
||||||
|
@ -26,5 +26,5 @@ DB_DATABASE=
|
|||||||
|
|
||||||
## API Endpoints
|
## API Endpoints
|
||||||
|
|
||||||
Refer to ~test-endpoints.restclient~ for an up-to-date list of endpoints. If you want to use this to
|
Refer to `test-endpoints.restclient` for an up-to-date list of endpoints. If you want to use this to
|
||||||
actually query the endpoints, it's not too hard to setup with Emacs.
|
actually query the endpoints, it's not too hard to setup with Emacs.
|
||||||
|
@ -6,19 +6,19 @@ begin
|
|||||||
name text not null,
|
name text not null,
|
||||||
description text not null,
|
description text not null,
|
||||||
image text not null,
|
image text not null,
|
||||||
claimAmount integer not null,
|
claimAmount float8 not null,
|
||||||
completionTimeInMins integer not null,
|
completionTimeInMins integer not null,
|
||||||
basePrice integer not null,
|
basePrice float8 not null,
|
||||||
tier_1_price integer not null,
|
tier_1_price float8 not null,
|
||||||
tier_1_claimboost integer not null,
|
tier_1_claimboost float8 not null,
|
||||||
tier_2_price integer not null,
|
tier_2_price float8 not null,
|
||||||
tier_2_claimboost integer not null,
|
tier_2_claimboost float8 not null,
|
||||||
tier_3_price integer not null,
|
tier_3_price float8 not null,
|
||||||
tier_3_claimboost integer not null,
|
tier_3_claimboost float8 not null,
|
||||||
tier_4_price integer not null,
|
tier_4_price float8 not null,
|
||||||
tier_4_claimboost integer not null,
|
tier_4_claimboost float8 not null,
|
||||||
tier_5_price integer not null,
|
tier_5_price float8 not null,
|
||||||
tier_5_claimboost integer not null
|
tier_5_claimboost float8 not null
|
||||||
) on commit drop;
|
) on commit drop;
|
||||||
create temporary table if not exists stakingSources(
|
create temporary table if not exists stakingSources(
|
||||||
id integer primary key,
|
id integer primary key,
|
||||||
@ -130,6 +130,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
$$ language plpgsql;
|
$$ language plpgsql;
|
||||||
|
|
||||||
|
-- Needed to load the python3 extension
|
||||||
|
create or replace trusted language plpython3u;
|
||||||
|
-- If you don't grant this permission then devs will not be able to update this function
|
||||||
|
-- It's dangerous though, I guess
|
||||||
|
update pg_language set lanpltrusted = true where lanname = 'plpython3u';
|
||||||
|
|
||||||
create or replace function download_sheets()
|
create or replace function download_sheets()
|
||||||
returns void as $$
|
returns void as $$
|
||||||
import requests
|
import requests
|
||||||
|
@ -8,6 +8,7 @@ as $$
|
|||||||
declare
|
declare
|
||||||
new_uuid uuid;
|
new_uuid uuid;
|
||||||
res_id integer;
|
res_id integer;
|
||||||
|
currency_start_amount float8;
|
||||||
begin
|
begin
|
||||||
if p_user_id is null then
|
if p_user_id is null then
|
||||||
insert into users(name, wallet) values (p_name, p_wallet)
|
insert into users(name, wallet) values (p_name, p_wallet)
|
||||||
@ -17,7 +18,11 @@ begin
|
|||||||
insert into users(id, name, wallet) values (p_user_id, p_name, p_wallet);
|
insert into users(id, name, wallet) values (p_user_id, p_name, p_wallet);
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
insert into bank_account(user_id, balance) values (new_uuid, 500);
|
select value into currency_start_amount
|
||||||
|
from game_constants
|
||||||
|
where key = 'MoonbucksStartAmount';
|
||||||
|
|
||||||
|
insert into bank_account(user_id, balance) values (new_uuid, currency_start_amount);
|
||||||
|
|
||||||
insert into resource_account (resource_id, user_id, balance)
|
insert into resource_account (resource_id, user_id, balance)
|
||||||
select resource.id, new_uuid, 50
|
select resource.id, new_uuid, 50
|
||||||
@ -31,7 +36,7 @@ $$ language plpgsql;
|
|||||||
create or replace function get_accounts(user_id uuid)
|
create or replace function get_accounts(user_id uuid)
|
||||||
returns table (
|
returns table (
|
||||||
id uuid,
|
id uuid,
|
||||||
"primaryBalance" integer,
|
"primaryBalance" float8,
|
||||||
"resourceAccounts" json
|
"resourceAccounts" json
|
||||||
)
|
)
|
||||||
as $$
|
as $$
|
||||||
@ -61,23 +66,23 @@ create or replace function sell_resources(
|
|||||||
)
|
)
|
||||||
returns table (
|
returns table (
|
||||||
"resourceName" text,
|
"resourceName" text,
|
||||||
"resourceAmount" integer,
|
"resourceAmount" float8,
|
||||||
"returnAmount" integer,
|
"returnAmount" float8,
|
||||||
"saleResult" text
|
"saleResult" text
|
||||||
)
|
)
|
||||||
as $$
|
as $$
|
||||||
declare
|
declare
|
||||||
resource jsonb;
|
resource jsonb;
|
||||||
resource_name text;
|
resource_name text;
|
||||||
resource_amount integer;
|
resource_amount float8;
|
||||||
return_amount integer;
|
return_amount float8;
|
||||||
resource_sell_factor real;
|
resource_sell_factor real;
|
||||||
sale_result text;
|
sale_result text;
|
||||||
begin
|
begin
|
||||||
for resource in select * from jsonb_array_elements(p_resources)
|
for resource in select * from jsonb_array_elements(p_resources)
|
||||||
loop
|
loop
|
||||||
resource_name := resource ->> 'resourceType';
|
resource_name := resource ->> 'resourceType';
|
||||||
resource_amount := (resource ->> 'resourceAmount')::integer;
|
resource_amount := (resource ->> 'resourceAmount')::float8;
|
||||||
sale_result := null;
|
sale_result := null;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -98,9 +103,9 @@ begin
|
|||||||
where key = resource_name || 'ToMoonbucks';
|
where key = resource_name || 'ToMoonbucks';
|
||||||
|
|
||||||
update bank_account
|
update bank_account
|
||||||
set balance = balance + resource_amount * resource_sell_factor
|
set balance = balance + resource_amount / resource_sell_factor
|
||||||
where user_id = p_user_id
|
where user_id = p_user_id
|
||||||
returning resource_amount * resource_sell_factor into return_amount;
|
returning resource_amount / resource_sell_factor into return_amount;
|
||||||
|
|
||||||
sale_result := 'Success';
|
sale_result := 'Success';
|
||||||
end if;
|
end if;
|
||||||
@ -218,9 +223,9 @@ declare
|
|||||||
new_source_id uuid;
|
new_source_id uuid;
|
||||||
res_id integer;
|
res_id integer;
|
||||||
address varchar;
|
address varchar;
|
||||||
price integer;
|
price float8;
|
||||||
min_res integer;
|
min_res float8;
|
||||||
max_res integer;
|
max_res float8;
|
||||||
begin
|
begin
|
||||||
select value into price from game_constants where key = 'price';
|
select value into price from game_constants where key = 'price';
|
||||||
|
|
||||||
@ -262,7 +267,7 @@ returns table (
|
|||||||
id uuid,
|
id uuid,
|
||||||
name varchar,
|
name varchar,
|
||||||
wallet varchar,
|
wallet varchar,
|
||||||
balance integer
|
balance float8
|
||||||
)
|
)
|
||||||
as $$
|
as $$
|
||||||
begin
|
begin
|
||||||
@ -275,7 +280,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
$$ language plpgsql;
|
$$ language plpgsql;
|
||||||
|
|
||||||
|
|
||||||
create or replace function purchase_item(
|
create or replace function purchase_item(
|
||||||
p_user_id uuid,
|
p_user_id uuid,
|
||||||
p_store_item_id integer
|
p_store_item_id integer
|
||||||
@ -283,7 +287,7 @@ create or replace function purchase_item(
|
|||||||
as $$
|
as $$
|
||||||
declare
|
declare
|
||||||
new_item_id uuid;
|
new_item_id uuid;
|
||||||
item_price integer;
|
item_price float8;
|
||||||
begin
|
begin
|
||||||
select price into item_price from store_item where store_item.id = p_store_item_id;
|
select price into item_price from store_item where store_item.id = p_store_item_id;
|
||||||
|
|
||||||
@ -314,7 +318,7 @@ as $$
|
|||||||
declare
|
declare
|
||||||
upgrade_event_id uuid;
|
upgrade_event_id uuid;
|
||||||
item_insert_id uuid;
|
item_insert_id uuid;
|
||||||
upgrade_price integer;
|
upgrade_price float8;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
select upgrade_item.price into upgrade_price
|
select upgrade_item.price into upgrade_price
|
||||||
@ -361,7 +365,7 @@ declare
|
|||||||
inv_id uuid;
|
inv_id uuid;
|
||||||
stake_id uuid;
|
stake_id uuid;
|
||||||
stake_created_at timestamp;
|
stake_created_at timestamp;
|
||||||
total_stake_amount integer;
|
total_stake_amount float8;
|
||||||
found_resource_well_id uuid;
|
found_resource_well_id uuid;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
@ -392,7 +396,7 @@ begin
|
|||||||
raise exception 'Unable to find an inventory item that is owned and not actively staked';
|
raise exception 'Unable to find an inventory item that is owned and not actively staked';
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
select claim_amount
|
select claim_amount + coalesce(claim_boost, 0)
|
||||||
into total_stake_amount
|
into total_stake_amount
|
||||||
from inventory_item
|
from inventory_item
|
||||||
join store_item on inventory_item.store_item_id = store_item.id
|
join store_item on inventory_item.store_item_id = store_item.id
|
||||||
@ -425,7 +429,7 @@ returns table (
|
|||||||
"wellId" uuid,
|
"wellId" uuid,
|
||||||
"inventoryItemId" uuid,
|
"inventoryItemId" uuid,
|
||||||
"resourceType" varchar,
|
"resourceType" varchar,
|
||||||
"stakeAmount" integer,
|
"stakeAmount" float8,
|
||||||
"stakeTime" timestamp with time zone,
|
"stakeTime" timestamp with time zone,
|
||||||
"durationInMins" integer,
|
"durationInMins" integer,
|
||||||
unclaimed bool
|
unclaimed bool
|
||||||
@ -459,8 +463,8 @@ declare
|
|||||||
stake record;
|
stake record;
|
||||||
claim_event_id uuid;
|
claim_event_id uuid;
|
||||||
stake_end_time timestamp;
|
stake_end_time timestamp;
|
||||||
resource_supply integer;
|
resource_supply float8;
|
||||||
final_supply integer;
|
final_supply float8;
|
||||||
begin
|
begin
|
||||||
select
|
select
|
||||||
staking_event.id,
|
staking_event.id,
|
||||||
|
@ -18,9 +18,9 @@ create table store_item(
|
|||||||
id integer primary key,
|
id integer primary key,
|
||||||
name text not null,
|
name text not null,
|
||||||
description text not null,
|
description text not null,
|
||||||
price integer not null,
|
price float8 not null,
|
||||||
image_name text not null,
|
image_name text not null,
|
||||||
claim_amount integer not null,
|
claim_amount float8 not null,
|
||||||
completion_time_in_mins integer not null
|
completion_time_in_mins integer not null
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ create table upgrade_item(
|
|||||||
tier integer not null,
|
tier integer not null,
|
||||||
store_item_id integer not null,
|
store_item_id integer not null,
|
||||||
price text not null,
|
price text not null,
|
||||||
claim_boost integer not null,
|
claim_boost float8 not null,
|
||||||
constraint fk_store_item_upgrade_item foreign key(store_item_id)
|
constraint fk_store_item_upgrade_item foreign key(store_item_id)
|
||||||
references store_item(id) on delete cascade,
|
references store_item(id) on delete cascade,
|
||||||
primary key (store_item_id, tier)
|
primary key (store_item_id, tier)
|
||||||
@ -57,7 +57,7 @@ create table resource_well (
|
|||||||
id uuid primary key default gen_random_uuid(),
|
id uuid primary key default gen_random_uuid(),
|
||||||
resource_id integer not null,
|
resource_id integer not null,
|
||||||
source_id uuid not null,
|
source_id uuid not null,
|
||||||
supply integer not null,
|
supply float8 not null,
|
||||||
constraint fk_sid_resource_well foreign key(source_id)
|
constraint fk_sid_resource_well foreign key(source_id)
|
||||||
references staking_source(id) on delete cascade,
|
references staking_source(id) on delete cascade,
|
||||||
constraint fk_rid_resource_well foreign key(resource_id)
|
constraint fk_rid_resource_well foreign key(resource_id)
|
||||||
@ -91,12 +91,12 @@ create table staking_event (
|
|||||||
well_id uuid not null,
|
well_id uuid not null,
|
||||||
inventory_item_id uuid not null,
|
inventory_item_id uuid not null,
|
||||||
duration_in_mins integer not null,
|
duration_in_mins integer not null,
|
||||||
stake_amount integer not null,
|
stake_amount float8 not null,
|
||||||
created_at timestamp with time zone default timezone('utc', now()),
|
created_at timestamp with time zone default timezone('utc', now()),
|
||||||
constraint fk_user_staking_event foreign key(user_id)
|
constraint fk_user_staking_event foreign key(user_id)
|
||||||
references users(id) on delete cascade,
|
references users(id) on delete cascade,
|
||||||
constraint fk_wid_staking_event foreign key(well_id)
|
constraint fk_wid_staking_event foreign key(well_id)
|
||||||
references resource_well(id),
|
references resource_well(id) on delete cascade,
|
||||||
constraint fk_iiid_staking_event foreign key(inventory_item_id)
|
constraint fk_iiid_staking_event foreign key(inventory_item_id)
|
||||||
references inventory_item(id) on delete cascade
|
references inventory_item(id) on delete cascade
|
||||||
);
|
);
|
||||||
@ -104,7 +104,7 @@ create table staking_event (
|
|||||||
create table claim_event (
|
create table claim_event (
|
||||||
id uuid primary key default gen_random_uuid(),
|
id uuid primary key default gen_random_uuid(),
|
||||||
staking_event_id uuid not null,
|
staking_event_id uuid not null,
|
||||||
claim_amount integer not null,
|
claim_amount float8 not null,
|
||||||
created_at timestamp with time zone default timezone('utc', now()),
|
created_at timestamp with time zone default timezone('utc', now()),
|
||||||
constraint fk_se_claim_event foreign key(staking_event_id)
|
constraint fk_se_claim_event foreign key(staking_event_id)
|
||||||
references staking_event(id) on delete cascade
|
references staking_event(id) on delete cascade
|
||||||
@ -113,7 +113,7 @@ create table claim_event (
|
|||||||
create table bank_account (
|
create table bank_account (
|
||||||
id uuid primary key default gen_random_uuid(),
|
id uuid primary key default gen_random_uuid(),
|
||||||
user_id uuid not null,
|
user_id uuid not null,
|
||||||
balance integer not null default 0 check (balance >= 0),
|
balance float8 not null default 0 check (balance >= 0),
|
||||||
constraint fk_user_bank_account foreign key(user_id)
|
constraint fk_user_bank_account foreign key(user_id)
|
||||||
references users(id) on delete cascade
|
references users(id) on delete cascade
|
||||||
);
|
);
|
||||||
@ -122,7 +122,7 @@ create table resource_account (
|
|||||||
id uuid primary key default gen_random_uuid(),
|
id uuid primary key default gen_random_uuid(),
|
||||||
resource_id integer not null,
|
resource_id integer not null,
|
||||||
user_id uuid not null,
|
user_id uuid not null,
|
||||||
balance integer not null default 0 check (balance >= 0),
|
balance float8 not null default 0 check (balance >= 0),
|
||||||
constraint fk_user_resource_account foreign key(user_id)
|
constraint fk_user_resource_account foreign key(user_id)
|
||||||
references users(id) on delete cascade,
|
references users(id) on delete cascade,
|
||||||
constraint fk_rid_resource_account foreign key(resource_id)
|
constraint fk_rid_resource_account foreign key(resource_id)
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { IResourceAccount, IConversionPair, IGameConfig } from "typings";
|
import { IResourceAccount, IConversionPair, IGameConfig } from "typings";
|
||||||
import { resourceToFc } from "../../../utils/helpers";
|
import { resourceToFc, resourceToBg } from "../../../utils/helpers";
|
||||||
import ResourceModal from "./ResourceModal";
|
import ResourceModal from "./ResourceModal";
|
||||||
|
import { BiLoaderAlt } from "react-icons/bi";
|
||||||
|
|
||||||
const ResourceAccount = (props: {
|
const ResourceAccount = (props: {
|
||||||
account: IResourceAccount;
|
account: IResourceAccount;
|
||||||
@ -13,13 +14,14 @@ const ResourceAccount = (props: {
|
|||||||
const [conversionPair, setConversionPair] = useState<
|
const [conversionPair, setConversionPair] = useState<
|
||||||
IConversionPair | undefined
|
IConversionPair | undefined
|
||||||
>(undefined);
|
>(undefined);
|
||||||
const [conversionRate, setConversionRate] = useState<number>(0.1);
|
const [conversionRate, setConversionRate] = useState<number>(0);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const handleConversionPair = (amount: number, resourceType: string) => {
|
const handleConversionPair = (amount: number, resourceType: string) => {
|
||||||
const updatedPair = {
|
const updatedPair = {
|
||||||
resourceType: resourceType,
|
resourceType: resourceType,
|
||||||
resourceAmount: amount,
|
resourceAmount: amount,
|
||||||
moneyAmount: amount * conversionRate,
|
moneyAmount: amount / conversionRate,
|
||||||
};
|
};
|
||||||
setConversionPair(updatedPair);
|
setConversionPair(updatedPair);
|
||||||
};
|
};
|
||||||
@ -31,6 +33,22 @@ const ResourceAccount = (props: {
|
|||||||
return rate;
|
return rate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSellResource = async () => {
|
||||||
|
if (conversionPair) {
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
await props.sellResource([conversionPair]);
|
||||||
|
} catch (error) {
|
||||||
|
// Show error here
|
||||||
|
} finally {
|
||||||
|
setShowModal(false);
|
||||||
|
}
|
||||||
|
conversionPair && props.sellResource([conversionPair]);
|
||||||
|
setIsLoading(false);
|
||||||
|
setShowModal(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const rate = getConversionRate(props.account);
|
const rate = getConversionRate(props.account);
|
||||||
setConversionRate(rate);
|
setConversionRate(rate);
|
||||||
@ -62,7 +80,12 @@ const ResourceAccount = (props: {
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<div className="md:h-auto max-w-md max-h-full overflow-y-auto">
|
<div className="relative md:h-auto max-w-md max-h-full overflow-y-auto">
|
||||||
|
{isLoading && (
|
||||||
|
<div className="absolute bg-white/75 text-white w-full h-full grid justify-center items-center rounded-xl">
|
||||||
|
<BiLoaderAlt className="animate-spin w-6 h-6" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<ResourceModal
|
<ResourceModal
|
||||||
resourceAccount={props.account}
|
resourceAccount={props.account}
|
||||||
conversionPair={conversionPair}
|
conversionPair={conversionPair}
|
||||||
@ -84,7 +107,7 @@ const ResourceAccount = (props: {
|
|||||||
</p>
|
</p>
|
||||||
{conversionPair && (
|
{conversionPair && (
|
||||||
<button
|
<button
|
||||||
onClick={() => props.sellResource([conversionPair])}
|
onClick={() => handleSellResource()}
|
||||||
className="bg-green-700 py-2 text-slate-900 rounded-lg font-bold w-28 text-center text-white"
|
className="bg-green-700 py-2 text-slate-900 rounded-lg font-bold w-28 text-center text-white"
|
||||||
>
|
>
|
||||||
Sell Now
|
Sell Now
|
||||||
@ -96,8 +119,14 @@ const ResourceAccount = (props: {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="flex-1 md:mb-0 mb-2 bg-gradient-to-tr from-purple-600 via-blue-600 to-indigo-700 h-auto p-1 rounded-xl">
|
<div className="flex-1 md:mb-0 mb-2 h-auto p-1 rounded-xl">
|
||||||
<div className="relative bg-slate-900 text-white px-8 py-4 rounded-xl">
|
<div
|
||||||
|
className={
|
||||||
|
"bg-gradient-to-br hover:bg-gradient-to-tr " +
|
||||||
|
resourceToBg(props.account.resourceType) +
|
||||||
|
" relative text-white px-8 py-4 rounded-xl"
|
||||||
|
}
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
className={resourceToFc(props.account.resourceType) + " font-bold"}
|
className={resourceToFc(props.account.resourceType) + " font-bold"}
|
||||||
>
|
>
|
||||||
@ -110,16 +139,21 @@ const ResourceAccount = (props: {
|
|||||||
})}{" "}
|
})}{" "}
|
||||||
kg
|
kg
|
||||||
</h3>
|
</h3>
|
||||||
|
<div className="absolute right-0 top-0 mt-4 mr-4 hover:cursor-pointer">
|
||||||
|
<div
|
||||||
|
className="flex"
|
||||||
|
onClick={() => {
|
||||||
|
setShowModal(!showModal);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="mr-2">Sell</span>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
strokeWidth={1.5}
|
strokeWidth={1.5}
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
className="w-6 h-6 absolute right-0 top-0 mt-4 mr-4 hover:cursor-pointer"
|
className="w-6 h-6"
|
||||||
onClick={() => {
|
|
||||||
setShowModal(!showModal);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
@ -129,6 +163,8 @@ const ResourceAccount = (props: {
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React, { useState, useEffect } from "react";
|
import React from "react";
|
||||||
import {
|
import { IBankAccount, IConversionPair, IGameConfig } from "typings";
|
||||||
IBankAccount,
|
|
||||||
IConversionPair,
|
|
||||||
IGameConfig,
|
|
||||||
IResourceAccount,
|
|
||||||
} from "typings";
|
|
||||||
import Account from "./Account";
|
import Account from "./Account";
|
||||||
import { BiLoaderAlt } from "react-icons/bi";
|
import { BiLoaderAlt } from "react-icons/bi";
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@ import React, { useState, useEffect } from "react";
|
|||||||
import { IInventoryItem, IStake, IUpgrade } from "typings";
|
import { IInventoryItem, IStake, IUpgrade } from "typings";
|
||||||
import CardLayout from "../../Layouts/CardLayout";
|
import CardLayout from "../../Layouts/CardLayout";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import { BiLoaderAlt } from "react-icons/bi";
|
||||||
|
|
||||||
const InventoryItem = (props: {
|
const InventoryItem = (props: {
|
||||||
inventoryItem: IInventoryItem;
|
inventoryItem: IInventoryItem;
|
||||||
stakes: IStake[] | null;
|
stakes: IStake[] | null;
|
||||||
@ -19,63 +21,48 @@ const InventoryItem = (props: {
|
|||||||
setCurrentUpgrade(currentUpdade);
|
setCurrentUpgrade(currentUpdade);
|
||||||
}, [props.inventoryItem]);
|
}, [props.inventoryItem]);
|
||||||
|
|
||||||
const isInUse = () => {
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
if (!props.stakes) return false;
|
|
||||||
return props.stakes.some((stake) => {
|
const handleUpgradeInventoryItem = async () => {
|
||||||
stake.inventoryItemId === props.inventoryItem.id;
|
setIsLoading(true);
|
||||||
});
|
try {
|
||||||
|
// Create the source
|
||||||
|
await props.upgradeInventoryItem(
|
||||||
|
props.inventoryItem.id,
|
||||||
|
props.inventoryItem.storeItem.id
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
// Handle error if needed (e.g., show a notification or log the error)
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getNextUpgradePrice = () => {
|
const renderUpgradeButton = () => {
|
||||||
|
// If no staking source
|
||||||
|
if (!props.stakes) return "No staking source";
|
||||||
|
|
||||||
|
// If item is in use
|
||||||
|
if (
|
||||||
|
props.stakes.some((stake) => {
|
||||||
|
stake.inventoryItemId === props.inventoryItem.id;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return "In use";
|
||||||
|
|
||||||
|
// If item is maxxed
|
||||||
if (currentTierIndex === 4) return "Maxed";
|
if (currentTierIndex === 4) return "Maxed";
|
||||||
return `$${
|
|
||||||
props.inventoryItem.storeItem.upgrades[currentTierIndex + 1].price
|
// Show price
|
||||||
}`;
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<CardLayout>
|
<>
|
||||||
<div className="md:flex gap-4">
|
{isLoading ? (
|
||||||
<div className="flex-1">
|
<button className="bg-green-600 rounded-full p-1">
|
||||||
<h3 className="text-2xl font-bold mb-2">
|
<BiLoaderAlt className="animate-spin w-6 h-6" />
|
||||||
{props.inventoryItem.storeItem.name}
|
|
||||||
</h3>
|
|
||||||
<p className="text-sm mb-3">
|
|
||||||
{props.inventoryItem.storeItem.description}
|
|
||||||
</p>
|
|
||||||
<p className="font-bold mt-4">Base Yield</p>
|
|
||||||
<p>{props.inventoryItem.storeItem.claimAmount}</p>
|
|
||||||
<p className="font-bold mb-1 mt-4">Tier</p>
|
|
||||||
<div className="flex items-center">
|
|
||||||
{currentUpgrade &&
|
|
||||||
props.inventoryItem.storeItem.upgrades.map((upgrade, id) => {
|
|
||||||
if (upgrade.tier <= currentUpgrade.tier) {
|
|
||||||
return (
|
|
||||||
<span key={id} className="bg-green-600 px-4 py-2"></span>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<span key={id} className="bg-slate-200 px-4 py-2"></span>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
<p className="font-bold ml-1">
|
|
||||||
(+{currentUpgrade && currentUpgrade.claimBoost})
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<p className="font-bold mb-1 mt-4">Upgrade</p>
|
|
||||||
<div className="flex items-center">
|
|
||||||
{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>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
onClick={() =>
|
onClick={() => handleUpgradeInventoryItem()}
|
||||||
props.upgradeInventoryItem(
|
|
||||||
props.inventoryItem.id,
|
|
||||||
props.inventoryItem.storeItem.id
|
|
||||||
)
|
|
||||||
}
|
|
||||||
className="bg-green-600 rounded-full p-1"
|
className="bg-green-600 rounded-full p-1"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@ -94,7 +81,61 @@ const InventoryItem = (props: {
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<span className="ml-1">({getNextUpgradePrice()})</span>
|
<span className="ml-1">
|
||||||
|
{`$${
|
||||||
|
props.inventoryItem.storeItem.upgrades[currentTierIndex + 1].price
|
||||||
|
}`}
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CardLayout>
|
||||||
|
<div className="md:flex gap-4">
|
||||||
|
<div className="flex-1">
|
||||||
|
<h3 className="text-2xl font-bold mb-2">
|
||||||
|
{props.inventoryItem.storeItem.name}
|
||||||
|
</h3>
|
||||||
|
<p className="text-sm mb-3">
|
||||||
|
{props.inventoryItem.storeItem.description}
|
||||||
|
</p>
|
||||||
|
<div className="grid grid-cols-4 gap-4">
|
||||||
|
<div className="col-span-1">
|
||||||
|
<p className="font-bold mt-4">Yield</p>
|
||||||
|
<p>
|
||||||
|
{props.inventoryItem.storeItem.claimAmount} (+
|
||||||
|
{currentUpgrade && currentUpgrade.claimBoost})
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-span-3">
|
||||||
|
<p className="font-bold mb-1 mt-4">Tier</p>
|
||||||
|
<div className="flex">
|
||||||
|
<div className="flex items-center mr-2">
|
||||||
|
{currentUpgrade &&
|
||||||
|
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>
|
||||||
|
<div className="flex items-center">{renderUpgradeButton()}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative object-contain w-48 h-48 mt-4 md:mt-0">
|
<div className="relative object-contain w-48 h-48 mt-4 md:mt-0">
|
||||||
|
@ -23,14 +23,14 @@ const NavbarVertical: React.FC<NavbarProps> = ({
|
|||||||
return (
|
return (
|
||||||
<div className="w-full col-span-5 md:col-span-1">
|
<div className="w-full col-span-5 md:col-span-1">
|
||||||
<nav className="bg-gradient-to-tr from-purple-600 via-blue-600 to-indigo-700 h-auto p-1 rounded-xl">
|
<nav className="bg-gradient-to-tr from-purple-600 via-blue-600 to-indigo-700 h-auto p-1 rounded-xl">
|
||||||
<ul className="bg-slate-900 p-8 rounded-xl">
|
<ul className="bg-slate-900 rounded-xl p-2">
|
||||||
{menuItems.map((item) => (
|
{menuItems.map((item) => (
|
||||||
<li
|
<li
|
||||||
key={item.componentKey}
|
key={item.componentKey}
|
||||||
className={`text-white cursor-pointer mb-1 ${
|
className={`cursor-pointer mb-1 px-4 ${
|
||||||
item.componentKey === activeItem
|
item.componentKey === activeItem
|
||||||
? "text-3xl font-bold"
|
? "text-white bg-gradient-to-tr from-purple-600 via-blue-600 to-indigo-700 text-3xl font-bold rounded-xl py-2 "
|
||||||
: "text-2xl"
|
: "text-white text-2xl"
|
||||||
}`}
|
}`}
|
||||||
onClick={() => onMenuItemClick(item.componentKey)}
|
onClick={() => onMenuItemClick(item.componentKey)}
|
||||||
>
|
>
|
||||||
|
@ -23,7 +23,10 @@ const SelectDropdown: React.FC<ISelectDropdownProps> = (props) => {
|
|||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
className="text-black flex-1 p-2 border border-gray-300 rounded-lg hover:cursor-pointer"
|
className="text-black flex-1 p-2 border border-gray-300 rounded-lg hover:cursor-pointer"
|
||||||
>
|
>
|
||||||
<option value="">Select</option>
|
<option value="" className="font-bold">
|
||||||
|
Select resource to mine
|
||||||
|
</option>
|
||||||
|
<hr />
|
||||||
{props.options.map((option, index) => (
|
{props.options.map((option, index) => (
|
||||||
<option key={index} value={option.value}>
|
<option key={index} value={option.value}>
|
||||||
{option.label}
|
{option.label}
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
} from "../../../utils/helpers";
|
} from "../../../utils/helpers";
|
||||||
import SelectDropdown from "../SelectDropdown";
|
import SelectDropdown from "../SelectDropdown";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import { BiLoaderAlt } from "react-icons/bi";
|
||||||
|
|
||||||
const StakingSource = (props: {
|
const StakingSource = (props: {
|
||||||
stakingSource: IStakingSource;
|
stakingSource: IStakingSource;
|
||||||
@ -25,7 +26,7 @@ const StakingSource = (props: {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
const [selectedWellId, setSelectedWellId] = useState<string | null>(null);
|
const [selectedWellId, setSelectedWellId] = useState<string | null>(null);
|
||||||
const [showInfo, setShowInfo] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
// Check if claimable every second
|
// Check if claimable every second
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -54,18 +55,33 @@ const StakingSource = (props: {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleStartMining = () => {
|
const handleStartMining = async () => {
|
||||||
if (selectedInventoryItemId && selectedWellId && selectedStoreItemId) {
|
if (selectedInventoryItemId && selectedWellId && selectedStoreItemId) {
|
||||||
props.startStake(
|
setIsLoading(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await props.startStake(
|
||||||
selectedInventoryItemId,
|
selectedInventoryItemId,
|
||||||
selectedStoreItemId,
|
selectedStoreItemId,
|
||||||
selectedWellId
|
selectedWellId
|
||||||
);
|
);
|
||||||
|
} catch (error) {
|
||||||
|
// Handle error if needed (e.g., show a notification or log the error)
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClaim = (stakingEventId: number) => {
|
const handleClaim = async (stakingEventId: number) => {
|
||||||
props.claimStake(stakingEventId);
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
await props.claimStake(stakingEventId);
|
||||||
|
} catch (error) {
|
||||||
|
// Handle error if needed (e.g., show a notification or log the error)
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectChange = (
|
const handleSelectChange = (
|
||||||
@ -102,7 +118,7 @@ const StakingSource = (props: {
|
|||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
onClick={() => handleClaim(props.stake.id)}
|
onClick={() => handleClaim(props.stake.id)}
|
||||||
className="bg-slate-100 text-slate-900 px-4 py-2 rounded-lg font-bold text-center"
|
className="bg-green-600 text-white px-4 py-2 rounded-lg font-bold text-center"
|
||||||
>
|
>
|
||||||
Claim
|
Claim
|
||||||
</button>
|
</button>
|
||||||
@ -119,56 +135,45 @@ const StakingSource = (props: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-center items-center">
|
<div className="flex">
|
||||||
<div className="relative group">
|
|
||||||
<Image
|
<Image
|
||||||
src={"/assets/moons/" + props.stakingSource.image}
|
src={"/assets/moons/" + props.stakingSource.image}
|
||||||
alt="Moon"
|
alt="Moon"
|
||||||
width={props.stakingSource.size}
|
width={300}
|
||||||
height={props.stakingSource.size}
|
height={300}
|
||||||
onClick={() => setShowInfo(!showInfo)}
|
style={{ objectFit: "contain" }}
|
||||||
className="hover:cursor-pointer"
|
className="mr-4"
|
||||||
/>
|
/>
|
||||||
{showInfo && (
|
<div className="max-w-md text-white bg-gradient-to-tr from-purple-600 via-blue-600 to-indigo-700 md:rounded-xl p-1">
|
||||||
<div className="z-10 fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center">
|
<div className="relative bg-slate-900 md:rounded-xl h-full">
|
||||||
<div className="w-full h-full md:h-auto max-w-md max-h-full overflow-y-auto">
|
{isLoading && (
|
||||||
<div className="relative h-full md:h-auto text-white bg-gradient-to-tr from-purple-600 via-blue-600 to-indigo-700 h-auto md:rounded-xl h-auto p-1">
|
<div className="absolute bg-slate-900 w-full h-full grid justify-center items-center rounded-xl">
|
||||||
<div className="h-full md:h-auto bg-slate-900 md:rounded-xl p-4">
|
<BiLoaderAlt className="animate-spin w-6 h-6" />
|
||||||
<button
|
</div>
|
||||||
onClick={() => {
|
)}
|
||||||
setShowInfo(!showInfo);
|
<div className="p-4">
|
||||||
}}
|
|
||||||
className="text-white absolute -right-0 mr-4"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
strokeWidth={2}
|
|
||||||
stroke="currentColor"
|
|
||||||
className="w-6 h-6"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
d="M6 18L18 6M6 6l12 12"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<h3 className="text-3xl font-bold mb-2">
|
<h3 className="text-3xl font-bold mb-2">
|
||||||
{props.stakingSource.name}
|
{props.stakingSource.name}{" "}
|
||||||
|
<span>
|
||||||
|
(
|
||||||
|
{props.stakingSource.resourceWells.reduce(
|
||||||
|
(x, y) => x + y.supply,
|
||||||
|
0
|
||||||
|
)}
|
||||||
|
)
|
||||||
|
</span>
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-sm">{props.stakingSource.description}</p>
|
<p className="text-sm">{props.stakingSource.description}</p>
|
||||||
<div className="flex-1">
|
</div>
|
||||||
<p className="font-bold mt-4 mb-2">Active Drills</p>
|
<div className="p-4">
|
||||||
{activeStakes &&
|
{activeStakes.length > 0 && (
|
||||||
activeStakes.map((stake, id) => (
|
<>
|
||||||
|
{activeStakes.map((stake, id) => (
|
||||||
<div
|
<div
|
||||||
key={id}
|
key={id}
|
||||||
className="border border-white rounded-xl p-3 mb-2 bg-black/20"
|
className="border border-white rounded-xl p-3 mb-2 bg-black/20"
|
||||||
>
|
>
|
||||||
<p>
|
<p className="font-bold text-xl mb-2">
|
||||||
<span className="font-bold">Drill: </span>
|
|
||||||
{props.inventoryItems &&
|
{props.inventoryItems &&
|
||||||
getObjectFromArray(
|
getObjectFromArray(
|
||||||
props.inventoryItems,
|
props.inventoryItems,
|
||||||
@ -187,24 +192,26 @@ const StakingSource = (props: {
|
|||||||
<RenderButtonOrCountdown stake={stake} />
|
<RenderButtonOrCountdown stake={stake} />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</>
|
||||||
<p className="font-bold mt-4 mb-2">Inactive Drills</p>
|
)}
|
||||||
{props.inventoryItems &&
|
{props.inventoryItems && (
|
||||||
props.inventoryItems.map(
|
<div className="">
|
||||||
|
{props.inventoryItems.map(
|
||||||
(item, id) =>
|
(item, id) =>
|
||||||
!isActive(item) && (
|
!isActive(item) && (
|
||||||
<div
|
<div
|
||||||
key={id}
|
key={id}
|
||||||
className="border border-white rounded-xl p-3 mb-2 bg-black/20"
|
className="border border-white rounded-xl p-3 mb-2 bg-black/20"
|
||||||
>
|
>
|
||||||
<p className="font-bold">{item.storeItem.name}</p>
|
<p className="font-bold text-xl mb-2">
|
||||||
<p className="mt-2">Select Resource</p>
|
{item.storeItem.name}
|
||||||
|
</p>
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<SelectDropdown
|
<SelectDropdown
|
||||||
options={props.stakingSource.resourceWells.map(
|
options={props.stakingSource.resourceWells.map(
|
||||||
(well): IOption => ({
|
(well): IOption => ({
|
||||||
value: well.id,
|
value: well.id,
|
||||||
label: well.resourceType,
|
label: well.resourceType + ` (${well.supply})`,
|
||||||
})
|
})
|
||||||
)}
|
)}
|
||||||
onChange={(value) =>
|
onChange={(value) =>
|
||||||
@ -231,12 +238,11 @@ const StakingSource = (props: {
|
|||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,42 +1,8 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { IInventoryItem, IStakingSource } from "typings";
|
import { IInventoryItem, IStakingSource } from "typings";
|
||||||
import StakingSource from "./StakingSource";
|
import StakingSource from "./StakingSource";
|
||||||
|
import { BiLoaderAlt } from "react-icons/bi";
|
||||||
interface RowProps {
|
|
||||||
stakingSources: IStakingSource[];
|
|
||||||
inventoryItems: IInventoryItem[] | undefined | null;
|
|
||||||
claimStake: (stakingEventId: number) => void;
|
|
||||||
startStake: (
|
|
||||||
inventoryItemId: string,
|
|
||||||
storeItemId: number,
|
|
||||||
wellId: string
|
|
||||||
) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Row: React.FC<RowProps> = ({
|
|
||||||
stakingSources,
|
|
||||||
inventoryItems,
|
|
||||||
claimStake,
|
|
||||||
startStake,
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<div className="md:flex md:justify-between md:items-center w-full mb-8 mt-8">
|
|
||||||
{stakingSources.map((stakingSource, index) => (
|
|
||||||
<div key={index} className="w-full">
|
|
||||||
<StakingSource
|
|
||||||
stakingSource={stakingSource}
|
|
||||||
inventoryItems={inventoryItems}
|
|
||||||
claimStake={claimStake}
|
|
||||||
startStake={startStake}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const moonSizes = [250, 375, 300, 225, 175, 300, 200, 150, 300, 225];
|
|
||||||
|
|
||||||
const StakingSourcesView = (props: {
|
const StakingSourcesView = (props: {
|
||||||
stakingSources: IStakingSource[] | null;
|
stakingSources: IStakingSource[] | null;
|
||||||
@ -49,42 +15,33 @@ const StakingSourcesView = (props: {
|
|||||||
) => void;
|
) => void;
|
||||||
createStakingSource: () => void;
|
createStakingSource: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
// Generate rows of stakingSources
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const handleRows = () => {
|
|
||||||
let rows = [];
|
|
||||||
let currentRow: IStakingSource[] = [];
|
|
||||||
let rowSize = 3;
|
|
||||||
if (props.stakingSources) {
|
|
||||||
props.stakingSources.forEach((stakingSource, index) => {
|
|
||||||
currentRow.push({ ...stakingSource, size: moonSizes[index] });
|
|
||||||
|
|
||||||
if (currentRow.length === rowSize) {
|
const handleCreateStakingSource = async () => {
|
||||||
rows.push(currentRow);
|
setIsLoading(true);
|
||||||
currentRow = [];
|
try {
|
||||||
rowSize = rowSize === 3 ? 4 : 3;
|
// Create the source
|
||||||
}
|
await props.createStakingSource();
|
||||||
});
|
} catch (error) {
|
||||||
|
// Handle error if needed (e.g., show a notification or log the error)
|
||||||
if (currentRow.length) {
|
} finally {
|
||||||
rows.push(currentRow);
|
setIsLoading(false);
|
||||||
}
|
|
||||||
|
|
||||||
return rows;
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const rows = handleRows();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-gradient-to-tr from-purple-600 via-blue-600 to-indigo-700 h-auto p-1 rounded-xl h-auto p-1 rounded-xl col-span-5">
|
<div className="bg-gradient-to-tr from-purple-600 via-blue-600 to-indigo-700 h-auto p-1 rounded-xl h-auto p-1 rounded-xl col-span-5">
|
||||||
<div className="bg-slate-900 p-8 rounded-xl h-full">
|
<div className="bg-slate-900 p-8 rounded-xl h-full">
|
||||||
<div className="flex items-center mb-4">
|
<div className="flex items-center mb-4">
|
||||||
<h2 className="text-3xl text-white font-bold">Your Moons</h2>
|
<h2 className="text-3xl text-white font-bold">Your Moons</h2>
|
||||||
|
{isLoading ? (
|
||||||
|
<button className="bg-green-600 text-white rounded-full ml-2 p-1 inline">
|
||||||
|
<BiLoaderAlt className="animate-spin w-6 h-6" />
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
<button
|
<button
|
||||||
className="bg-green-600 rounded-full ml-2 p-1 inline"
|
className="bg-green-600 text-white rounded-full ml-2 p-1 inline"
|
||||||
onClick={() => props.createStakingSource()}
|
onClick={() => handleCreateStakingSource()}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@ -101,22 +58,26 @@ const StakingSourcesView = (props: {
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{rows.length > 0 ? (
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
rows.map((stakingSources, index) => (
|
{props.stakingSources ? (
|
||||||
<Row
|
props.stakingSources.map((stakingSource, index) => (
|
||||||
key={index}
|
<div key={index} className="mb-4">
|
||||||
stakingSources={stakingSources}
|
<StakingSource
|
||||||
|
stakingSource={stakingSource}
|
||||||
inventoryItems={props.inventoryItems}
|
inventoryItems={props.inventoryItems}
|
||||||
claimStake={props.claimStake}
|
claimStake={props.claimStake}
|
||||||
startStake={props.startStake}
|
startStake={props.startStake}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<p className="text-white text-2xl">You don't have any moons</p>
|
<p className="text-white text-2xl">You don't have any moons</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
"use client";
|
|
||||||
import React from "react";
|
|
||||||
import { IInventoryItem, IStakingSource } from "typings";
|
|
||||||
import StakingSource from "./StakingSource";
|
|
||||||
|
|
||||||
const StakingSourcesView = (props: {
|
|
||||||
stakingSources: IStakingSource[] | null;
|
|
||||||
inventoryItems: IInventoryItem[] | null | undefined;
|
|
||||||
claimStake: (stakingEventId: number) => void;
|
|
||||||
startStake: (
|
|
||||||
inventoryItemId: number,
|
|
||||||
storeItemId: string,
|
|
||||||
wellId: number
|
|
||||||
) => void;
|
|
||||||
createStakingSource: () => void;
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<div className="bg-slate-800 p-4 rounded-lg text-white col-span-5">
|
|
||||||
<div className="flex items-center mb-4">
|
|
||||||
<h2 className="text-3xl font-bold">Your Moons</h2>
|
|
||||||
<button
|
|
||||||
className="bg-green-600 rounded-full ml-2 p-1 inline"
|
|
||||||
onClick={() => props.createStakingSource()}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
strokeWidth={2}
|
|
||||||
stroke="currentColor"
|
|
||||||
className="w-6 h-6"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
d="M12 4.5v15m7.5-7.5h-15"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div className="grid grid-cols-3 gap-4">
|
|
||||||
{props.stakingSources &&
|
|
||||||
props.stakingSources.length > 0 &&
|
|
||||||
props.stakingSources.map((stakingSource, id) => (
|
|
||||||
<StakingSource
|
|
||||||
key={id}
|
|
||||||
stakingSource={stakingSource}
|
|
||||||
inventoryItems={props.inventoryItems}
|
|
||||||
claimStake={props.claimStake}
|
|
||||||
startStake={props.startStake}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default StakingSourcesView;
|
|
@ -1,13 +1,28 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { IStoreItem } from "typings";
|
import { IStoreItem } from "typings";
|
||||||
import CardLayout from "../../Layouts/CardLayout";
|
import CardLayout from "../../Layouts/CardLayout";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import { BiLoaderAlt } from "react-icons/bi";
|
||||||
|
|
||||||
const StoreItem = (props: {
|
const StoreItem = (props: {
|
||||||
storeItem: IStoreItem;
|
storeItem: IStoreItem;
|
||||||
buyStoreItem: (storeItemId: number) => void;
|
buyStoreItem: (storeItemId: number) => void;
|
||||||
}) => {
|
}) => {
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
|
const handleBuyStoreItem = async () => {
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
// Create the source
|
||||||
|
await props.buyStoreItem(props.storeItem.id);
|
||||||
|
} catch (error) {
|
||||||
|
// Handle error if needed (e.g., show a notification or log the error)
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CardLayout>
|
<CardLayout>
|
||||||
<div className="md:flex">
|
<div className="md:flex">
|
||||||
@ -15,26 +30,18 @@ const StoreItem = (props: {
|
|||||||
<h3 className="text-2xl font-bold mb-2">{props.storeItem.name}</h3>
|
<h3 className="text-2xl font-bold mb-2">{props.storeItem.name}</h3>
|
||||||
<p className="text-sm mb-3">{props.storeItem.description}</p>
|
<p className="text-sm mb-3">{props.storeItem.description}</p>
|
||||||
<div className="py-4 my-2">
|
<div className="py-4 my-2">
|
||||||
|
{isLoading ? (
|
||||||
|
<button className="bg-green-600 text-white px-4 py-2 rounded-lg font-bold w-auto text-center">
|
||||||
|
<BiLoaderAlt className="animate-spin w-6 h-6" />
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
<button
|
<button
|
||||||
onClick={() => props.buyStoreItem(props.storeItem.id)}
|
onClick={() => handleBuyStoreItem()}
|
||||||
className="bg-slate-100 text-slate-900 px-4 py-2 rounded-lg font-bold w-auto text-center"
|
className="bg-green-600 text-white px-4 py-2 rounded-lg font-bold w-auto text-center"
|
||||||
>
|
>
|
||||||
Buy | ${props.storeItem.price}
|
Buy | ${props.storeItem.price}
|
||||||
</button>
|
</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>
|
</div>
|
||||||
<div className="relative object-contain w-48 h-48">
|
<div className="relative object-contain w-48 h-48">
|
||||||
@ -46,6 +53,42 @@ const StoreItem = (props: {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex flex-grow mt-4">
|
||||||
|
<div className="mr-3 flex-grow">
|
||||||
|
<p className="font-bold">Yield</p>
|
||||||
|
<p className="">{props.storeItem.claimAmount}</p>
|
||||||
|
</div>
|
||||||
|
<div className="mr-3 flex-grow">
|
||||||
|
<p className="font-bold">Completion Time</p>
|
||||||
|
<p className="">{props.storeItem.completionTimeInMins} min</p>
|
||||||
|
</div>
|
||||||
|
<div className="mr-3 flex-grow">
|
||||||
|
<p className="font-bold">Yield / Hr.</p>
|
||||||
|
<p className="">
|
||||||
|
{(
|
||||||
|
(props.storeItem.claimAmount /
|
||||||
|
props.storeItem.completionTimeInMins) *
|
||||||
|
60
|
||||||
|
).toFixed(0)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="font-bold mt-4 ">Tiers</p>
|
||||||
|
<div className="mt-4 flex f-full">
|
||||||
|
{props.storeItem.upgrades.map((upgrade, id) => (
|
||||||
|
<table key={id} className="table-auto flex-grow">
|
||||||
|
<tr className="border">
|
||||||
|
<td colSpan={2} className="p-2 text-center">
|
||||||
|
{upgrade.tier}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="p-2 border">${upgrade.price}</td>
|
||||||
|
<td className="p-2 border">+{upgrade.claimBoost}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</CardLayout>
|
</CardLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -32,7 +32,7 @@ export default function Home() {
|
|||||||
const [notificationTime, setNotificationTime] = useState(30);
|
const [notificationTime, setNotificationTime] = useState(30);
|
||||||
const [storeItems, setStoreItems] = useState<IStoreItem[] | null>(null);
|
const [storeItems, setStoreItems] = useState<IStoreItem[] | null>(null);
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [activeComponent, setActiveComponent] = useState("inventoryitemview");
|
const [activeComponent, setActiveComponent] = useState("stakingsourcesview");
|
||||||
const [gameConfig, setGameConfig] = useState<IGameConfig>();
|
const [gameConfig, setGameConfig] = useState<IGameConfig>();
|
||||||
|
|
||||||
const isOwned = (storeItemId: number) => {
|
const isOwned = (storeItemId: number) => {
|
||||||
@ -204,7 +204,13 @@ export default function Home() {
|
|||||||
if (response.status == 200) {
|
if (response.status == 200) {
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
setNotification({
|
setNotification({
|
||||||
message: `You've received ${data[0].returnAmount} $MoonBucks`,
|
message: `You've received ${data[0].returnAmount.toLocaleString(
|
||||||
|
"en-US",
|
||||||
|
{
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2,
|
||||||
|
}
|
||||||
|
)} $MoonBucks`,
|
||||||
type: "Success",
|
type: "Success",
|
||||||
});
|
});
|
||||||
fetchBankAccount();
|
fetchBankAccount();
|
||||||
@ -332,7 +338,11 @@ export default function Home() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Navbar setUserId={setUserId} />
|
<Navbar setUserId={setUserId} />
|
||||||
<p>Please login</p>
|
<div className="grid justify-center items-center h-96">
|
||||||
|
<h1 className="text-3xl text-white">
|
||||||
|
Connect Your Wallet to Continue
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -10,9 +10,11 @@ export default function Utils() {
|
|||||||
const [userId, setUserId] = useState<string>("");
|
const [userId, setUserId] = useState<string>("");
|
||||||
|
|
||||||
const clearUserData = async () => {
|
const clearUserData = async () => {
|
||||||
await fetch(`/api/user/${userId}/clear-data`, {
|
console.log("Clearing data..");
|
||||||
|
const response = await fetch(`/api/user/${userId}/clear-data`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
});
|
});
|
||||||
|
console.log(response);
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadConfig = async () => {
|
const loadConfig = async () => {
|
||||||
|
@ -18,6 +18,6 @@ export default async function handler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json(error);
|
res.status(500).json(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
#
|
#
|
||||||
:user_id = 595ab570-fa74-4c6c-980e-4c80d1064dd1
|
:user_id = 595ab570-fa74-4c6c-980e-4c80d1064dd1
|
||||||
|
:host = https://moonminers.app/api
|
||||||
|
|
||||||
# Seed the SQLite database (deprecated)
|
# Seed the SQLite database (deprecated)
|
||||||
GET http://localhost:3000/api/seed
|
GET http://localhost:3000/api/seed
|
||||||
@ -11,8 +12,12 @@ GET http://localhost:3000/api/seed
|
|||||||
POST http://localhost:3000/api/import-config
|
POST http://localhost:3000/api/import-config
|
||||||
:headers
|
:headers
|
||||||
|
|
||||||
|
# Get leaderboards
|
||||||
|
GET :host/leaderboards
|
||||||
|
:headers
|
||||||
|
|
||||||
# Get Inventory Items
|
# Get Inventory Items
|
||||||
POST http://localhost:3000/api/user/login
|
POST :host/user/login
|
||||||
:headers
|
:headers
|
||||||
{ "wallet" : "Wallet12345678" }
|
{ "wallet" : "Wallet12345678" }
|
||||||
|
|
||||||
@ -40,10 +45,6 @@ PUT http://localhost:3000/api/user/:user_id/account
|
|||||||
POST http://localhost:3000/api/user/:user_id/clear-data
|
POST http://localhost:3000/api/user/:user_id/clear-data
|
||||||
:headers
|
:headers
|
||||||
|
|
||||||
# Get leaderboards
|
|
||||||
GET http://localhost:3000/api/leaderboards
|
|
||||||
:headers
|
|
||||||
|
|
||||||
# Get game config
|
# Get game config
|
||||||
GET http://localhost:3000/api/get-game-config
|
GET http://localhost:3000/api/get-game-config
|
||||||
:headers
|
:headers
|
||||||
@ -77,8 +78,8 @@ GET http://localhost:3000/api/user/:user_id/stakes/
|
|||||||
# Start a stake
|
# Start a stake
|
||||||
POST http://localhost:3000/api/user/:user_id/stakes/start
|
POST http://localhost:3000/api/user/:user_id/stakes/start
|
||||||
:headers
|
:headers
|
||||||
{ "inventoryItemId": "2bd5f846-ce1d-45be-998e-26d2e97b7f68"
|
{ "inventoryItemId": "1db181dd-320f-4525-a00d-933e5d72d690"
|
||||||
, "wellId": "588ad177-83ca-4a5f-9672-bf97783ea42f" }
|
, "wellId": "0a7fd54d-02cf-4c08-b106-6f812ad4b1ca" }
|
||||||
|
|
||||||
# Claim a stake
|
# Claim a stake
|
||||||
POST http://localhost:3000/api/user/:user_id/stakes/claim
|
POST http://localhost:3000/api/user/:user_id/stakes/claim
|
||||||
|
1
typings.d.ts
vendored
1
typings.d.ts
vendored
@ -39,7 +39,6 @@ export interface IStakingSource {
|
|||||||
resourceChance: number | null
|
resourceChance: number | null
|
||||||
resourceMinStartAmount: number | null
|
resourceMinStartAmount: number | null
|
||||||
resourceMaxStartAmount: number | null
|
resourceMaxStartAmount: number | null
|
||||||
size: number | undefined
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IInventoryItem {
|
export interface IInventoryItem {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user