diff --git a/src/config/config.cairo b/src/config/config.cairo index c268b940..6b926719 100644 --- a/src/config/config.cairo +++ b/src/config/config.cairo @@ -177,10 +177,6 @@ mod config { } } - // fn update_game_config(self: @ContractState, game_config: GameConfig) { - // self.assert_caller_is_owner(); - // self.s().save_game_config(game_config); - // } fn update_drug_config(self: @ContractState, drug_config: DrugConfig) { self.assert_caller_is_owner(); diff --git a/src/config/ryo.cairo b/src/config/ryo.cairo index 575bb29b..270f2817 100644 --- a/src/config/ryo.cairo +++ b/src/config/ryo.cairo @@ -3,6 +3,13 @@ use starknet::info::get_block_timestamp; use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; use rollyourown::{models::{season::{Season, SeasonImpl, SeasonTrait}}}; +const TWO_MIN: u16 = 120; +// +const TWENTY_MIN: u32 = 1200; +const ONE_HOUR: u32 = 3600; +const ONE_DAY: u32 = 86_400; +const ONE_WEEK: u32 = 604_800; + #[derive(Model, Copy, Drop, Serde)] struct RyoConfig { #[key] @@ -23,6 +30,21 @@ struct RyoConfig { #[generate_trait] impl RyoConfigImpl of RyoConfigTrait { + fn build_initial_ryo_config() -> RyoConfig { + RyoConfig { + key: 0, + initialized: true, + paused: false, + season_version: 1, + season_duration: TWENTY_MIN, // ONE_WEEK + season_time_limit: TWO_MIN, // ONE_HOUR + paper_fee: 1000, // in ether + paper_reward_launderer: 100, // in ether + treasury_fee_pct: 5, + treasury_balance: 0, + } + } + fn build_season(self: RyoConfig, season_version: u16) -> Season { Season { version: season_version, diff --git a/src/systems/ryo.cairo b/src/systems/ryo.cairo index fe166dc6..8a44f5dd 100644 --- a/src/systems/ryo.cairo +++ b/src/systems/ryo.cairo @@ -1,6 +1,8 @@ use starknet::ContractAddress; use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; +use rollyourown::{config::ryo::{RyoConfig}}; + #[starknet::interface] trait IRyo { // @@ -11,9 +13,8 @@ trait IRyo { laundromat_address: ContractAddress ); fn set_paused(self: @T, paused: bool); - fn set_paper_fee(self: @T, fee: u16); - fn set_treasury_fee_pct(self: @T, fee_pct: u8); - fn set_season_duration(self: @T, duration_sec: u32); + fn update_ryo_config(self: @T, ryo_config: RyoConfig); + // fn paper(self: @T) -> ContractAddress; @@ -35,20 +36,12 @@ mod ryo { use rollyourown::{ interfaces::paper::{IPaperDispatcher, IPaperDispatcherTrait}, constants::{ETHER}, - config::{ryo::{RyoConfig}, ryo_address::{RyoAddress},}, models::{season::Season,}, - utils::random::{RandomImpl}, helpers::season_manager::{SeasonManager, SeasonManagerTrait}, + config::{ryo::{RyoConfig, RyoConfigImpl}, ryo_address::{RyoAddress},}, + models::{season::Season,}, utils::random::{RandomImpl}, + helpers::season_manager::{SeasonManager, SeasonManagerTrait}, library::store::{IStoreLibraryDispatcher, IStoreDispatcherTrait}, }; - const THREE_MIN: u16 = 120; - const TEN_MIN: u16 = 600; - const TWENTY_MIN: u16 = 1200; - // - const THIRTY_MIN: u32 = 1800; - const ONE_HOUR: u32 = 3600; - const TWO_HOUR: u32 = 7200; - const ONE_DAY: u32 = 86_400; - const ONE_WEEK: u32 = 604_800; #[abi(embed_v0)] impl RyoExternalImpl of super::IRyo { @@ -64,21 +57,8 @@ mod ryo { assert(ryo_config.initialized == false, 'Already initialized'); - // consume first world uuid = 0 - let _ = self.world().uuid(); - - // RyoConfig - ryo_config.initialized = true; - ryo_config.paused = false; - - ryo_config.season_version = 1; - ryo_config.season_duration = ONE_HOUR; // ONE_WEEK - ryo_config.season_time_limit = TEN_MIN; // ONE_HOUR - - ryo_config.paper_fee = 1000; // in ether - ryo_config.treasury_fee_pct = 5; - ryo_config.paper_reward_launderer = 100; // in ether - + // initial config + ryo_config = RyoConfigImpl::build_initial_ryo_config(); // save self.s().save_ryo_config(ryo_config); @@ -86,8 +66,8 @@ mod ryo { let mut ryo_addresses = self.s().ryo_addresses(); ryo_addresses.paper = paper_address; - ryo_addresses.treasury = treasury_address; - ryo_addresses.laundromat = laundromat_address; + ryo_addresses.treasury = treasury_address; // could be removed + ryo_addresses.laundromat = laundromat_address; // could be removed // save self.s().save_ryo_addresses(ryo_addresses); @@ -99,7 +79,7 @@ mod ryo { } // - // TODO: test it + // // fn set_paused(self: @ContractState, paused: bool) { @@ -111,31 +91,17 @@ mod ryo { self.s().save_ryo_config(ryo_config); } - fn set_paper_fee(self: @ContractState, fee: u16) { - self.assert_caller_is_owner(); - - let mut ryo_config = self.s().ryo_config(); - - ryo_config.paper_fee = fee; - self.s().save_ryo_config(ryo_config); - } - - - fn set_treasury_fee_pct(self: @ContractState, fee_pct: u8) { + fn update_ryo_config(self: @ContractState, ryo_config: RyoConfig) { self.assert_caller_is_owner(); - let mut ryo_config = self.s().ryo_config(); + let mut new_ryo_config = self.s().ryo_config(); - ryo_config.treasury_fee_pct = fee_pct; - self.s().save_ryo_config(ryo_config); - } - - fn set_season_duration(self: @ContractState, duration_sec: u32) { - self.assert_caller_is_owner(); - - let mut ryo_config = self.s().ryo_config(); + new_ryo_config.season_duration = ryo_config.season_duration; + new_ryo_config.season_time_limit = ryo_config.season_time_limit; + new_ryo_config.paper_fee = ryo_config.paper_fee; + new_ryo_config.paper_reward_launderer = ryo_config.paper_reward_launderer; + new_ryo_config.treasury_fee_pct = ryo_config.treasury_fee_pct; - ryo_config.season_duration = duration_sec; self.s().save_ryo_config(ryo_config); } diff --git a/web/src/components/pages/admin/DrugTable.tsx b/web/src/components/pages/admin/DrugTable.tsx index 5c194a81..1b10d589 100644 --- a/web/src/components/pages/admin/DrugTable.tsx +++ b/web/src/components/pages/admin/DrugTable.tsx @@ -8,7 +8,7 @@ import { shortString } from "starknet"; import { editComponents } from "./tables"; const columns = [ - { key: "id" }, + // { key: "id" , title: "id", dataType: DataType.Number }, { key: "icon", width: 80 }, { key: "drugs_mode", title: "drugs_mode", dataType: DataType.String }, { key: "drug", title: "drug", dataType: DataType.String }, diff --git a/web/src/components/pages/admin/EncounterTable.tsx b/web/src/components/pages/admin/EncounterTable.tsx index 0e02fcf8..1928a9d6 100644 --- a/web/src/components/pages/admin/EncounterTable.tsx +++ b/web/src/components/pages/admin/EncounterTable.tsx @@ -2,23 +2,23 @@ import { useDojoContext, useSystems } from "@/dojo/hooks"; import { observer } from "mobx-react-lite"; import { Table, useTable } from "ka-table"; -import { ActionType, DataType, SortingMode } from "ka-table/enums"; +import { ActionType, DataType, FilteringMode, SortingMode } from "ka-table/enums"; import { useState } from "react"; import { editComponents } from "./tables"; const columns = [ // { key: "image", width: 100 }, + { key: "encounters_mode", title: "mode", dataType: DataType.String }, { key: "encounter", title: "encounter", dataType: DataType.String }, - { key: "encounters_mode", title: "encounters_mode", dataType: DataType.String }, - { key: "health_base", title: "health_base", dataType: DataType.Number }, - { key: "health_step", title: "health_step", dataType: DataType.Number }, - { key: "attack_base", title: "attack_base", dataType: DataType.Number }, - { key: "attack_step", title: "attack_step", dataType: DataType.Number }, - { key: "defense_base", title: "defense_base", dataType: DataType.Number }, - { key: "defense_step", title: "defense_step", dataType: DataType.Number }, - { key: "speed_base", title: "speed_base", dataType: DataType.Number }, - { key: "speed_step", title: "speed_step", dataType: DataType.Number }, + { key: "health_base", title: "HP base", dataType: DataType.Number }, + { key: "health_step", title: "HP step", dataType: DataType.Number }, + { key: "attack_base", title: "ATK base", dataType: DataType.Number }, + { key: "attack_step", title: "ATK step", dataType: DataType.Number }, + { key: "defense_base", title: "DEF base", dataType: DataType.Number }, + { key: "defense_step", title: "DEF step", dataType: DataType.Number }, + { key: "speed_base", title: "SPD base", dataType: DataType.Number }, + { key: "speed_step", title: "SPD step", dataType: DataType.Number }, { key: "editColumn", width: 80 }, ]; @@ -70,6 +70,7 @@ export const EncounterTable = observer(() => { data={data} rowKeyField={"id"} sortingMode={SortingMode.Single} + filteringMode={FilteringMode.HeaderFilter} childComponents={editComponents} /> ); diff --git a/web/src/components/pages/admin/HustlerItemBaseTable.tsx b/web/src/components/pages/admin/HustlerItemBaseTable.tsx index b35a1898..ee3c1004 100644 --- a/web/src/components/pages/admin/HustlerItemBaseTable.tsx +++ b/web/src/components/pages/admin/HustlerItemBaseTable.tsx @@ -2,7 +2,7 @@ import { useDojoContext } from "@/dojo/hooks"; import { observer } from "mobx-react-lite"; import { Table } from "ka-table"; -import { DataType, EditingMode } from "ka-table/enums"; +import { DataType, EditingMode, FilteringMode } from "ka-table/enums"; import { editComponents } from "./tables"; const columns = [ @@ -26,8 +26,8 @@ export const HustlerItemBaseTable = observer(() => { data={config?.items || []} rowKeyField={"name"} editingMode={EditingMode.None} + filteringMode={FilteringMode.HeaderFilter} childComponents={editComponents} /> ); }); - diff --git a/web/src/components/pages/admin/HustlerItemTiersTable.tsx b/web/src/components/pages/admin/HustlerItemTiersTable.tsx index 0ead7223..cb40c655 100644 --- a/web/src/components/pages/admin/HustlerItemTiersTable.tsx +++ b/web/src/components/pages/admin/HustlerItemTiersTable.tsx @@ -2,7 +2,7 @@ import { useDojoContext } from "@/dojo/hooks"; import { observer } from "mobx-react-lite"; import { Table } from "ka-table"; -import { DataType, EditingMode, SortingMode } from "ka-table/enums"; +import { DataType, EditingMode, FilteringMode, SortingMode } from "ka-table/enums"; const columns = [ { key: "slot", title: "slot", dataType: DataType.String }, @@ -25,6 +25,7 @@ export const HustlerItemTiersTable = observer(() => { rowKeyField={"id"} editingMode={EditingMode.None} sortingMode={SortingMode.Single} + filteringMode={FilteringMode.HeaderFilter} /> ); }); diff --git a/web/src/components/pages/home/Leaderboard.tsx b/web/src/components/pages/home/Leaderboard.tsx index 1cf16898..3699e741 100644 --- a/web/src/components/pages/home/Leaderboard.tsx +++ b/web/src/components/pages/home/Leaderboard.tsx @@ -19,6 +19,7 @@ import { Arrow, InfosIcon, PaperIcon, Skull } from "../../icons"; import { SeasonDetailsModal } from "./SeasonDetailsModal"; import { Game } from "@/generated/graphql"; import { shortString } from "starknet"; +import { Config, ConfigStoreClass } from "@/dojo/stores/config"; const renderer = ({ days, @@ -54,17 +55,16 @@ const renderer = ({ } }; -export const Leaderboard = observer(({ nameEntry, ...props }: { nameEntry?: boolean } & StyleProps & ListProps) => { +export const Leaderboard = observer(({ config }: { config: Config }) => { const { router, gameId } = useRouterContext(); const { uiStore } = useDojoContext(); const { account } = useAccount(); - const { config } = useConfigStore(); const [currentVersion, setCurrentVersion] = useState(config?.ryo.season_version || 0); - const [selectedVersion, setSelectedVersion] = useState(config?.ryo.season_version || 0); + const [selectedVersion, setSelectedVersion] = useState(config?.ryo.season_version || 0); - const { season }= useSeasonByVersion(selectedVersion) + const { season } = useSeasonByVersion(selectedVersion); const { registeredGames, @@ -72,6 +72,13 @@ export const Leaderboard = observer(({ nameEntry, ...props }: { nameEntry?: bool refetch: refetchRegisteredGames, } = useRegisteredGamesBySeason(selectedVersion); + useEffect(() => { + if (!config) return; + + setCurrentVersion(config?.ryo.season_version || 0); + refetchRegisteredGames(); + }, [config]); + const onPrev = async () => { if (selectedVersion > 1) { setSelectedVersion(selectedVersion - 1); @@ -88,7 +95,7 @@ export const Leaderboard = observer(({ nameEntry, ...props }: { nameEntry?: bool router.push(`/season/${version}`); }; - if (!registeredGames || !season ) { + if (!registeredGames || !season) { return <>; } @@ -96,7 +103,12 @@ export const Leaderboard = observer(({ nameEntry, ...props }: { nameEntry?: bool - 1 ? "1" : "0.25"} onClick={onPrev}> + 1 ? "1" : "0.25"} + onClick={onPrev} + > onDetails(selectedVersion)}> SEASON {selectedVersion} REWARDS @@ -115,10 +127,7 @@ export const Leaderboard = observer(({ nameEntry, ...props }: { nameEntry?: bool {selectedVersion === currentVersion && ( - + uiStore.openSeasonDetails()}> @@ -144,7 +153,9 @@ export const Leaderboard = observer(({ nameEntry, ...props }: { nameEntry?: bool const isOwn = game.player_id === account?.address; const color = isOwn ? colors.yellow["400"].toString() : colors.neon["200"].toString(); const avatarColor = isOwn ? "yellow" : "green"; - const displayName = game.player_name ? `${shortString.decodeShortString( game.player_name)}${isOwn ? " (you)" : ""}` : "Anonymous"; + const displayName = game.player_name + ? `${shortString.decodeShortString(game.player_name)}${isOwn ? " (you)" : ""}` + : "Anonymous"; return ( @@ -167,7 +178,7 @@ export const Leaderboard = observer(({ nameEntry, ...props }: { nameEntry?: bool {/* {game.health === 0 ? ( ) : ( */} - + {/* )} */} @@ -194,19 +205,15 @@ export const Leaderboard = observer(({ nameEntry, ...props }: { nameEntry?: bool {"."} - { - game.claimable > 0 && ( - - {game.claimable} ... + {game.claimable > 0 && ( + + {game.claimable} ... - ) - } + )} {formatCash(game.final_score)} - - ); diff --git a/web/src/dojo/hooks/useSystems.ts b/web/src/dojo/hooks/useSystems.ts index a04b42f5..89b60b17 100644 --- a/web/src/dojo/hooks/useSystems.ts +++ b/web/src/dojo/hooks/useSystems.ts @@ -1,4 +1,4 @@ -import { DrugConfig, EncounterConfig, GameConfig } from "@/generated/graphql"; +import { DrugConfig, EncounterConfig, GameConfig, RyoConfig } from "@/generated/graphql"; import { useToast } from "@/hooks/toast"; import { getEvents } from "@dojoengine/utils"; import { useAccount } from "@starknet-react/core"; @@ -29,11 +29,9 @@ export interface SystemsInterface { decide: (gameId: string, action: EncountersAction) => Promise; // ryo setPaused: (paused: boolean) => Promise; - setPaperFee: (fee: number) => Promise; - setTreasuryFeePct: (fee: number) => Promise; - setLeaderboardDuration: (duration: number) => Promise; + updateRyoConfig: (ryoConfig: RyoConfig) => Promise; + // config - updateGameConfig: (gameConfig: GameConfig) => Promise; updateDrugConfig: (drugConfig: DrugConfig) => Promise; updateEncounterConfig: (encounterConfig: EncounterConfig) => Promise; @@ -408,12 +406,14 @@ export const useSystems = (): SystemsInterface => { [executeAndReceipt], ); - const setPaperFee = useCallback( - async (paperFee: number) => { + + const updateRyoConfig = useCallback( + async (ryoConfig: RyoConfig) => { + const { hash, events, parsedEvents } = await executeAndReceipt({ contractName: "rollyourown::systems::ryo::ryo", - entrypoint: "set_paper_fee", - calldata: [paperFee], + entrypoint: "update_ryo_config", + calldata: [ryoConfig], }); return { @@ -423,50 +423,7 @@ export const useSystems = (): SystemsInterface => { [executeAndReceipt], ); - const setTreasuryFeePct = useCallback( - async (treasuryFeePct: number) => { - const { hash, events, parsedEvents } = await executeAndReceipt({ - contractName: "rollyourown::systems::ryo::ryo", - entrypoint: "set_treasury_fee_pct", - calldata: [treasuryFeePct], - }); - - return { - hash, - }; - }, - [executeAndReceipt], - ); - - const setLeaderboardDuration = useCallback( - async (duration: number) => { - const { hash, events, parsedEvents } = await executeAndReceipt({ - contractName: "rollyourown::systems::ryo::ryo", - entrypoint: "set_season_duration", - calldata: [duration], - }); - return { - hash, - }; - }, - [executeAndReceipt], - ); - - const updateGameConfig = useCallback( - async (gameConfig: GameConfig) => { - const { hash, events, parsedEvents } = await executeAndReceipt({ - contractName: "rollyourown::config::config::config", - entrypoint: "update_game_config", - calldata: [gameConfig], - }); - - return { - hash, - }; - }, - [executeAndReceipt], - ); const updateDrugConfig = useCallback( async (drugConfig: DrugConfig) => { @@ -561,11 +518,8 @@ export const useSystems = (): SystemsInterface => { launder, // setPaused, - setPaperFee, - setTreasuryFeePct, - setLeaderboardDuration, + updateRyoConfig, // - updateGameConfig, updateDrugConfig, updateEncounterConfig, // diff --git a/web/src/generated/graphql.ts b/web/src/generated/graphql.ts index f2185020..98a541f6 100644 --- a/web/src/generated/graphql.ts +++ b/web/src/generated/graphql.ts @@ -2538,6 +2538,13 @@ export type ConfigQueryVariables = Exact<{ [key: string]: never; }>; export type ConfigQuery = { __typename?: 'World__Query', ryoAddressModels?: { __typename?: 'RyoAddressConnection', edges?: Array<{ __typename?: 'RyoAddressEdge', node?: { __typename?: 'RyoAddress', key?: any | null, paper?: any | null, treasury?: any | null, laundromat?: any | null } | null } | null> | null } | null, ryoConfigModels?: { __typename?: 'RyoConfigConnection', edges?: Array<{ __typename?: 'RyoConfigEdge', node?: { __typename?: 'RyoConfig', key?: any | null, initialized?: any | null, paused?: any | null, season_version?: any | null, season_duration?: any | null, season_time_limit?: any | null, paper_fee?: any | null, paper_reward_launderer?: any | null, treasury_fee_pct?: any | null, treasury_balance?: any | null } | null } | null> | null } | null, drugConfigModels?: { __typename?: 'DrugConfigConnection', edges?: Array<{ __typename?: 'DrugConfigEdge', node?: { __typename?: 'DrugConfig', drugs_mode?: any | null, drug?: any | null, drug_id?: any | null, base?: any | null, step?: any | null, weight?: any | null, name?: any | null } | null } | null> | null } | null, locationConfigModels?: { __typename?: 'LocationConfigConnection', edges?: Array<{ __typename?: 'LocationConfigEdge', node?: { __typename?: 'LocationConfig', location?: any | null, location_id?: any | null, name?: any | null } | null } | null> | null } | null, hustlerItemBaseConfigModels?: { __typename?: 'HustlerItemBaseConfigConnection', edges?: Array<{ __typename?: 'HustlerItemBaseConfigEdge', node?: { __typename?: 'HustlerItemBaseConfig', slot?: any | null, id?: any | null, slot_id?: any | null, name?: any | null, initial_tier?: any | null } | null } | null> | null } | null, hustlerItemTiersConfigModels?: { __typename?: 'HustlerItemTiersConfigConnection', edges?: Array<{ __typename?: 'HustlerItemTiersConfigEdge', node?: { __typename?: 'HustlerItemTiersConfig', slot?: any | null, slot_id?: any | null, tier?: any | null, cost?: any | null, stat?: any | null } | null } | null> | null } | null, encounterStatsConfigModels?: { __typename?: 'EncounterStatsConfigConnection', edges?: Array<{ __typename?: 'EncounterStatsConfigEdge', node?: { __typename?: 'EncounterStatsConfig', encounters_mode?: any | null, encounter?: any | null, health_base?: any | null, health_step?: any | null, attack_base?: any | null, attack_step?: any | null, defense_base?: any | null, defense_step?: any | null, speed_base?: any | null, speed_step?: any | null } | null } | null> | null } | null }; +export type GameConfigQueryVariables = Exact<{ + version?: InputMaybe; +}>; + + +export type GameConfigQuery = { __typename?: 'World__Query', gameConfigModels?: { __typename?: 'GameConfigConnection', edges?: Array<{ __typename?: 'GameConfigEdge', node?: { __typename?: 'GameConfig', season_version?: any | null, cash?: any | null, health?: any | null, max_turns?: any | null, max_wanted_shopping?: any | null, rep_drug_step?: any | null, rep_buy_item?: any | null, rep_carry_drugs?: any | null, rep_hospitalized?: any | null, rep_jailed?: any | null } | null } | null> | null } | null }; + export type GameEventsQueryVariables = Exact<{ gameId: Scalars['String']; }>; @@ -2573,13 +2580,6 @@ export type GamesByPlayerQueryVariables = Exact<{ export type GamesByPlayerQuery = { __typename?: 'World__Query', entities?: { __typename?: 'World__EntityConnection', edges?: Array<{ __typename?: 'World__EntityEdge', node?: { __typename?: 'World__Entity', id?: string | null, keys?: Array | null, models?: Array<{ __typename: 'DrugConfig' } | { __typename: 'ERC20AllowanceModel' } | { __typename: 'ERC20BalanceModel' } | { __typename: 'ERC20MetadataModel' } | { __typename: 'EncounterConfig' } | { __typename: 'EncounterStatsConfig' } | { __typename: 'Game', game_id?: any | null, player_id?: any | null, season_version?: any | null, game_mode?: any | null, hustler_id?: any | null, player_name?: any | null, game_over?: any | null, final_score?: any | null, registered?: any | null, claimed?: any | null, claimable?: any | null, position?: any | null } | { __typename: 'GameConfig' } | { __typename: 'GameStorePacked', game_id?: any | null, player_id?: any | null, packed?: any | null } | { __typename: 'HustlerItemBaseConfig' } | { __typename: 'HustlerItemTiersConfig' } | { __typename: 'InitializableModel' } | { __typename: 'LocationConfig' } | { __typename: 'RyoAddress' } | { __typename: 'RyoConfig' } | { __typename: 'Season' } | { __typename: 'SeasonSettings' } | { __typename: 'SortedList' } | { __typename: 'SortedListItem' } | null> | null } | null } | null> | null } | null }; -export type GameConfigQueryVariables = Exact<{ - version?: InputMaybe; -}>; - - -export type GameConfigQuery = { __typename?: 'World__Query', gameConfigModels?: { __typename?: 'GameConfigConnection', edges?: Array<{ __typename?: 'GameConfigEdge', node?: { __typename?: 'GameConfig', season_version?: any | null, cash?: any | null, health?: any | null, max_turns?: any | null, max_wanted_shopping?: any | null, rep_drug_step?: any | null, rep_buy_item?: any | null, rep_carry_drugs?: any | null, rep_hospitalized?: any | null, rep_jailed?: any | null } | null } | null> | null } | null }; - export type GameStorePackedQueryVariables = Exact<{ gameId: Scalars['String']; playerId: Scalars['String']; @@ -2760,6 +2760,60 @@ export const useInfiniteConfigQuery = < useInfiniteConfigQuery.getKey = (variables?: ConfigQueryVariables) => variables === undefined ? ['Config.infinite'] : ['Config.infinite', variables]; ; +export const GameConfigDocument = ` + query GameConfig($version: u16) { + gameConfigModels(where: {season_version: $version}) { + edges { + node { + season_version + cash + health + max_turns + max_wanted_shopping + rep_drug_step + rep_buy_item + rep_carry_drugs + rep_hospitalized + rep_jailed + } + } + } +} + `; +export const useGameConfigQuery = < + TData = GameConfigQuery, + TError = unknown + >( + variables?: GameConfigQueryVariables, + options?: UseQueryOptions + ) => + useQuery( + variables === undefined ? ['GameConfig'] : ['GameConfig', variables], + useFetchData(GameConfigDocument).bind(null, variables), + options + ); + +useGameConfigQuery.getKey = (variables?: GameConfigQueryVariables) => variables === undefined ? ['GameConfig'] : ['GameConfig', variables]; +; + +export const useInfiniteGameConfigQuery = < + TData = GameConfigQuery, + TError = unknown + >( + variables?: GameConfigQueryVariables, + options?: UseInfiniteQueryOptions + ) =>{ + const query = useFetchData(GameConfigDocument) + return useInfiniteQuery( + variables === undefined ? ['GameConfig.infinite'] : ['GameConfig.infinite', variables], + (metaData) => query({...variables, ...(metaData.pageParam ?? {})}), + options + )}; + + +useInfiniteGameConfigQuery.getKey = (variables?: GameConfigQueryVariables) => variables === undefined ? ['GameConfig.infinite'] : ['GameConfig.infinite', variables]; +; + export const GameEventsDocument = ` query GameEvents($gameId: String!) { events(last: 1000, keys: ["*", $gameId]) { @@ -3001,60 +3055,6 @@ export const useInfiniteGamesByPlayerQuery = < useInfiniteGamesByPlayerQuery.getKey = (variables?: GamesByPlayerQueryVariables) => variables === undefined ? ['GamesByPlayer.infinite'] : ['GamesByPlayer.infinite', variables]; ; -export const GameConfigDocument = ` - query GameConfig($version: u16) { - gameConfigModels(where: {season_version: $version}) { - edges { - node { - season_version - cash - health - max_turns - max_wanted_shopping - rep_drug_step - rep_buy_item - rep_carry_drugs - rep_hospitalized - rep_jailed - } - } - } -} - `; -export const useGameConfigQuery = < - TData = GameConfigQuery, - TError = unknown - >( - variables?: GameConfigQueryVariables, - options?: UseQueryOptions - ) => - useQuery( - variables === undefined ? ['GameConfig'] : ['GameConfig', variables], - useFetchData(GameConfigDocument).bind(null, variables), - options - ); - -useGameConfigQuery.getKey = (variables?: GameConfigQueryVariables) => variables === undefined ? ['GameConfig'] : ['GameConfig', variables]; -; - -export const useInfiniteGameConfigQuery = < - TData = GameConfigQuery, - TError = unknown - >( - variables?: GameConfigQueryVariables, - options?: UseInfiniteQueryOptions - ) =>{ - const query = useFetchData(GameConfigDocument) - return useInfiniteQuery( - variables === undefined ? ['GameConfig.infinite'] : ['GameConfig.infinite', variables], - (metaData) => query({...variables, ...(metaData.pageParam ?? {})}), - options - )}; - - -useInfiniteGameConfigQuery.getKey = (variables?: GameConfigQueryVariables) => variables === undefined ? ['GameConfig.infinite'] : ['GameConfig.infinite', variables]; -; - export const GameStorePackedDocument = ` query GameStorePacked($gameId: String!, $playerId: String!) { entities(keys: [$gameId, $playerId]) { diff --git a/web/src/pages/admin.tsx b/web/src/pages/admin.tsx index bbf63a9e..b6063e7a 100644 --- a/web/src/pages/admin.tsx +++ b/web/src/pages/admin.tsx @@ -1,6 +1,6 @@ import { Layout } from "@/components/layout"; import { ChildrenOrConnect, TokenBalance } from "@/components/wallet"; -import { useDojoContext, useRouterContext, useSystems } from "@/dojo/hooks"; +import { useDojoContext, useRouterContext, useSeasonByVersion, useSystems } from "@/dojo/hooks"; import { Button, Card, @@ -32,7 +32,8 @@ import { PlayerLayoutTable } from "@/components/pages/admin/PlayerLayoutTable"; import { useEffect, useState } from "react"; import { Dropdown } from "@/components/common"; import { RyoConfigTable } from "@/components/pages/admin/RyoConfigTable"; -import { PaperIcon } from "@/components/icons"; +import { Bag, Clock, CopsIcon, DollarBag, PaperIcon } from "@/components/icons"; +import { formatCash } from "@/utils/ui"; const Admin = () => { const { router } = useRouterContext(); @@ -48,8 +49,10 @@ const Admin = () => { GAME DRUGS ITEMS + ITEMS TIERS ENCOUNTERS - LAYOUTS + {/* LAYOUTS */} + {/* { configStore.init(); @@ -68,64 +71,76 @@ const Admin = () => { + - - - - - Game Config - - - - Ryo Config - - - + + + + Game Config + + + + Ryo Config + + + + - + + + - - ITEM BASE - + + - - ITEM TIERS - - - - + + - + + + + + + + + + + + {/* GAME - + + + PLAYER - + + + - + */} @@ -142,24 +157,24 @@ const RyoAddressCard = observer(() => { return ( - RYO ADDRESS + RYO ADDRESS - + - PAPER - {config?.ryoAddress.paper} + PAPER + {config?.ryoAddress.paper} - TREASURY - {config?.ryoAddress.treasury} + TREASURY + {config?.ryoAddress.treasury} - LAUNDROMAT - {config?.ryoAddress.laundromat} - + LAUNDROMAT + {config?.ryoAddress.laundromat} + @@ -181,7 +196,7 @@ const TreasuryClaimCard = observer(() => { return ( - TREASURY + TREASURY @@ -220,7 +235,7 @@ const RyoPauseCard = observer(() => { return ( - RYO + RYO @@ -238,42 +253,115 @@ const RyoPauseCard = observer(() => { ); }); -const RyoLeaderboardDurationCard = observer(() => { +const RyoSeasonConfigCard = observer(() => { const { configStore } = useDojoContext(); const { config } = configStore; - const [duration, setDuration] = useState(config?.ryo.season_duration); + const [ryoConfig, setRyoConfig] = useState(config?.ryo); - const { setLeaderboardDuration, isPending } = useSystems(); + const { updateRyoConfig, isPending } = useSystems(); - const updateLeaderboardDuration = async () => { - await setLeaderboardDuration(duration); + const onUpdate = async () => { + await updateRyoConfig(ryoConfig!); await configStore.init(); }; return ( - LEADERBOARD + NEXT SEASON PARAMETERS - - - DURATION (sec) - - { - setDuration(e.target.value); - }} - /> + + Configure next season parameters + + + + + SEASON DURATION (sec) + + { + setRyoConfig({ + ...ryoConfig, + season_duration: Number(e.target.value), + }); + }} + /> + + + + + SEASON TIME LIMIT (sec) + + { + setRyoConfig({ + ...ryoConfig, + season_time_limit: Number(e.target.value), + }); + }} + /> + + + + + PAPER FEE + + { + setRyoConfig({ + ...ryoConfig, + paper_fee: Number(e.target.value), + }); + }} + /> + + + + + TREASURY FEE % + + { + setRyoConfig({ + ...ryoConfig, + treasury_fee_pct: Number(e.target.value), + }); + }} + /> + + + + + PAPER REWARD LAUNDERER + + { + setRyoConfig({ + ...ryoConfig, + paper_reward_launderer: Number(e.target.value), + }); + }} + /> + + - - + @@ -283,116 +371,58 @@ const RyoLeaderboardDurationCard = observer(() => { const RyoSuperchargeCard = observer(() => { const { configStore } = useDojoContext(); const { config } = configStore; + const { account } = useAccount(); const [value, setValue] = useState(0); + const { season, refetch } = useSeasonByVersion(config?.ryo.season_version || 0); const { superchargeJackpot, isPending } = useSystems(); const onSuperchargeJackpot = async () => { await superchargeJackpot(config?.ryo.season_version, value); await configStore.init(); + await refetch(); }; return ( - SUPERCHARGE JACKPOT + SUPERCHARGE JACKPOT - - - CURRENT SEASON : {config?.ryo.season_version} + + + Transfer some PAPER from your wallet +
to supercharge current season jackpot
- - PAPER AMOUNT - - { - setValue(Number(e.target.value)); - }} - /> - - - -
-
- -
- ); -}); - -const RyoFeeCard = observer(() => { - const { configStore } = useDojoContext(); - const { config } = configStore; - - const [paperFeeValue, setPaperFeeValue] = useState(config?.ryo.paper_fee); - const [treasuryFeePctValue, setTreasuryFeePctValue] = useState(config?.ryo.treasury_fee_pct); - - const { setPaperFee, setTreasuryFeePct, isPending } = useSystems(); - - useEffect(() => { - setPaperFeeValue(config?.ryo.paper_fee); - }, [config?.ryo.paper_fee]); - - useEffect(() => { - setTreasuryFeePctValue(config?.ryo.treasury_fee_pct); - }, [config?.ryo.treasury_fee_pct]); - - // const { setPaused, isPending } = useSystems(); - - const updatePaperFee = async () => { - await setPaperFee(paperFeeValue); - await configStore.init(); - }; - - const updateTreasuryFeePct = async () => { - await setTreasuryFeePct(treasuryFeePctValue); - await configStore.init(); - }; - - return ( - - - RYO FEES - - - - - - PAPER FEE - - { - setPaperFeeValue(e.target.value); - }} - /> - - - - - - TREASURY FEE % - - { - setTreasuryFeePctValue(e.target.value); - }} - /> - - + + CURRENT SEASON : {config?.ryo.season_version} + CURRENT JACKPOT : {formatCash(season?.paper_balance).replace("$", "")} + + + + + YOUR BALANCE : + + + + + PAPER AMOUNT + { + setValue(Number(e.target.value)); + }} + /> + + + + + diff --git a/web/src/pages/index.tsx b/web/src/pages/index.tsx index 3f727a0e..9326513b 100644 --- a/web/src/pages/index.tsx +++ b/web/src/pages/index.tsx @@ -48,7 +48,7 @@ export default function Home() { if (!sortedList || sortedList.process_max_size === 0) return; const value = (sortedList?.process_size * 100) / sortedList?.process_max_size; - setProgressPercent(value); + setProgressPercent(Math.floor(value)); }, [sortedList]); const { toast } = useToast(); @@ -143,7 +143,7 @@ export default function Home() { - + diff --git a/web/src/theme/global.tsx b/web/src/theme/global.tsx index 6097d112..f71cd89d 100644 --- a/web/src/theme/global.tsx +++ b/web/src/theme/global.tsx @@ -18,6 +18,14 @@ const GlobalStyles = () => ( margin-top: 0px; } } + + html .ka { + background-color: transparent; + } + + html .ka-thead-background { + background-color: transparent; + } // .ka-table-wrapper{ // padding: 16px; @@ -27,28 +35,55 @@ const GlobalStyles = () => ( // width: 100%; // } - // .ka-table thead{ - // text-align: left; - // text-transform: uppercase; - // font-weight: 400; - // border-bottom: solid 1px ${colors.neon["700"]}; - // } + html .ka-table thead{ + text-align: left; + text-transform: uppercase; + font-weight: 400; + border-bottom: solid 1px ${colors.neon["700"]}; + } - // .ka-row{ - // border-bottom: solid 1px ${colors.neon["700"]}; - // } + html .ka-row{ + border-top: solid 1px ${colors.neon["700"]}; + border-bottom: solid 1px ${colors.neon["700"]}; + } - // .ka-cell, .ka-thead-cell{ - // padding: 4px; - // } + html .ka-thead-cell{ + color:${colors.neon["500"]}; + } - // .ka-input { - // width: 100%; - // padding: 4px; - // min-width: 50px; - // background: ${colors.neon["800"]}; - // border-color: ${colors.neon["500"]}; - // } + html .ka-cell{ + color:${colors.neon["400"]}; + } + + html .ka-cell, html .ka-thead-cell{ + padding: 4px; + } + + html .ka-header-filter-button-icon { + left: 0; + color:${colors.neon["500"]}; + } + + html .ka-header-filter-button.ka-header-filter-button-has-value .ka-icon-filter { + color:${colors.neon["400"]}; + } + + html .ka-popup{ + background-color:${colors.neon["700"]}; + } + + html .ka-popup-content-item-value { + padding: 4px; + color:${colors.neon["400"]}; + } + + .ka-input { + width: 100%; + padding: 4px; + min-width: 50px; + background: transparent; + border-color: ${colors.neon["500"]}; + } .table-vertical {