diff --git a/packages/web/components/MegaMenu/MegaMenu.tsx b/packages/web/components/MegaMenu/MegaMenu.tsx new file mode 100644 index 00000000..9a73ffef --- /dev/null +++ b/packages/web/components/MegaMenu/MegaMenu.tsx @@ -0,0 +1,565 @@ +import { + Avatar, + Box, + BoxedNextImage as Image, + Button, + ChevronDownIcon, + ChevronUpIcon, + CloseIcon, + Dashboard, + Flex, + HamburgerIcon, + Icon, + Link, + LogOut, + Menu, + MenuButton, + MenuItem, + MenuList, + MetaButton, + Profile, + SimpleGrid, + Spinner, + Stack, + Text, + useBreakpointValue, + useDisclosure, +} from '@metafam/ds'; +import Alliances from 'assets/menuIcon/alliances.svg'; +import Asketh from 'assets/menuIcon/asketh.svg'; +import BecomeAPatron from 'assets/menuIcon/becomeapatron.svg'; +import Contribute from 'assets/menuIcon/contribute.svg'; +import Discord from 'assets/menuIcon/discord.svg'; +import Events from 'assets/menuIcon/events.svg'; +import Forum from 'assets/menuIcon/forum.svg'; +import Grants from 'assets/menuIcon/grants.svg'; +import Guilds from 'assets/menuIcon/guilds.svg'; +import Invest from 'assets/menuIcon/invest.svg'; +import Learn from 'assets/menuIcon/learn.svg'; +import MetaGameWiki from 'assets/menuIcon/metagamewiki.svg'; +import MetaRadio from 'assets/menuIcon/metaradio.svg'; +import Patrons from 'assets/menuIcon/patrons.svg'; +import Playbooks from 'assets/menuIcon/playbooks.svg'; +import Players from 'assets/menuIcon/players.svg'; +import Quests from 'assets/menuIcon/quests.svg'; +import Raids from 'assets/menuIcon/raids.svg'; +import Roles from 'assets/menuIcon/roles.svg'; +import SeedEarned from 'assets/menuIcon/seedearned.svg'; +import Seeds from 'assets/menuIcon/seeds.svg'; +import TheGreatHouses from 'assets/menuIcon/thegreathouses.svg'; +import WelcomeToMetaGame from 'assets/menuIcon/welcometometagame.svg'; +import XPEarned from 'assets/menuIcon/xpearned.svg'; +import Youtube from 'assets/menuIcon/youtube.svg'; +import { MetaLink } from 'components/Link'; +import { PlayerAvatar } from 'components/Player/PlayerAvatar'; +import { Player } from 'graphql/autogen/types'; +import { useUser, useWeb3 } from 'lib/hooks'; +import { useRouter } from 'next/router'; +import players from 'pages/community/players'; +import React from 'react'; +import { distinctUntilChanged, forkJoin, Subject } from 'rxjs'; +import { debounceTime, switchMap } from 'rxjs/operators'; +import { MenuLinkItem, MenuLinkSet, MenuSectionLinks } from 'utils/menuLinks'; +import { getPlayerURL } from 'utils/playerHelpers'; + +import { getPlayersByText } from '../../graphql/getPlayers'; +import { getGuildsByText } from '../../graphql/queries/guild'; +import { XPSeedsBalance } from './XPSeedsBalance'; + +const menuIcons: { [key: string]: string } = { + alliances: Alliances, + asketh: Asketh, + contribute: Contribute, + discord: Discord, + forum: Forum, + grants: Grants, + guilds: Guilds, + invest: Invest, + learn: Learn, + metagamewiki: MetaGameWiki, + patrons: Patrons, + playbooks: Playbooks, + players: Players, + quests: Quests, + raids: Raids, + roles: Roles, + seedearned: SeedEarned, + seeds: Seeds, + thegreathouses: TheGreatHouses, + welcometometagame: WelcomeToMetaGame, + xpearned: XPEarned, + youtube: Youtube, + metaradio: MetaRadio, + events: Events, + becomeapatron: BecomeAPatron, +}; + +type LogoProps = { + link: string; +}; + +const iconSize = 60; + +// Navbar logo +const Logo = ({ link }: LogoProps) => { + const width = useBreakpointValue({ base: 36, lg: 40 }) ?? (36 as number); + const height = + useBreakpointValue({ base: 45, lg: iconSize }) ?? (45 as number); + + return ( + + + + + + ); +}; + +type MenuItemProps = { + title: string; + url: string; + explainerText: string; + icon: string; +}; +// Menu links (with icons and explanatory text) -- used in DesktopNavLinks below +const DesktopMenuItem = ({ + title, + url, + explainerText, + icon, +}: MenuItemProps) => ( + + + + + + {title} + + + {explainerText} + + + + +); + +// Nav links on desktop -- text and links from utils/menuLinks.ts +const DesktopNavLinks = () => ( + + {MenuSectionLinks.map((section: MenuLinkSet) => ( + + {({ isOpen }) => ( + <> + + {section.label} + {isOpen ? ( + + ) : ( + + )} + + + + + {isOpen ? ( + + ) : ( + + )} + 3 + ? 'repeat(2, 1fr)' + : 'repeat(1, 1fr)' + } + width={section.menuItems.length > 3 ? '948px' : '474px'} + p="2rem" + boxShadow="dark-lg" + bg="linear-gradient(180deg, rgba(42, 31, 71, 0.9) 6.18%, rgba(17, 3, 32, 0.86) 140%)" + borderRadius="0.618vmax" + border="0" + > + {section.menuItems.map((item: MenuLinkItem) => ( + + ))} + + + )} + + ))} + +); + +// const getAllSearchResults = async (queryString: string) => { +// const { players } = await getPlayersByText(queryString); +// const { guilds } = await getGuildsByText(queryString); +// return { players, guilds }; +// }; + +// Search -- not working yet +const Search = () => { + const searchInputSubjectRef = React.useRef(new Subject()); + const [query, setQuery] = React.useState(''); + const [searchResults, setSearchResults] = React.useState({ + players: [], + guilds: [], + }); + const [isLoading, setLoading] = React.useState(false); + const handleSubmit = (e: React.ChangeEvent) => { + e.preventDefault(); + // Default Show Players Matching With Query + // router.push(`/search/players?q=${inputValue}`); + }; + const handleChange = (e: any) => { + setQuery(e.target.value); + }; + + React.useEffect(() => { + setLoading(true); + searchInputSubjectRef.current.next(query); + }, [query]); + + React.useEffect(() => { + const searchSubscription = searchInputSubjectRef.current + .pipe( + debounceTime(300), + distinctUntilChanged(), + // switchMap(async (queryString: string) => { + // if (queryString !== '' && !queryString) { + // setSearchResults([]); + // return; + // } + // const { players } = await getPlayersByText(queryString); + // const { guilds } = await getGuildsByText(queryString); + // // eslint-disable-next-line consistent-return + // return { players, guilds }; + // }), + // switchMap((queryString: string) => { + // if (queryString !== '' && !queryString) { + // setSearchResults([]); + // return; + // } + + // // eslint-disable-next-line consistent-return + // return forkJoin([ + // getPlayersByText(queryString), + // getGuildsByText(queryString), + // ]); + // }), + ) + .subscribe(async (val: string) => { + if (val !== '' && !val) { + setLoading(false); + + return; + } + const { players } = await getPlayersByText(val); + const { guilds } = await getGuildsByText(val); + setSearchResults({ guilds, players }); + setLoading(false); + }); + + return searchSubscription.unsubscribe; + }, []); + return ( + +
+ +
+
+ ); +}; + +const inputStyle = { + padding: '5px', +}; + +type PlayerStatsProps = { + player: Player; +}; +// Display player XP and Seed +const PlayerStats: React.FC = ({ player }) => { + const { disconnect } = useWeb3(); + + return ( + + + + + + + + + + View Profile + + + + + + Dashboard + + + + + Disconnect + + + + + ); +}; + +export const MegaMenu: React.FC = () => { + const { connected, connect } = useWeb3(); + const router = useRouter(); + const { user, fetching } = useUser(); + const { player } = user ?? {}; + + const { isOpen, onOpen, onClose } = useDisclosure(); + const menuToggle = () => (isOpen ? onClose() : onOpen()); + + return ( + + + + {isOpen ? ( + + ) : ( + + )} + + + + + + + {fetching ? ( + + ) : ( + <> + {connected && !!player ? ( + + ) : ( + + Connect + + )} + + )} + + + + + {MenuSectionLinks.map((section) => ( + + + {section.label} + + + {section.menuItems.map(({ title, icon, url }) => ( + + + {title} + + ))} + + + ))} + + + ); +}; diff --git a/packages/web/graphql/getPlayers.ts b/packages/web/graphql/getPlayers.ts index edd471d3..c5b6f5f7 100644 --- a/packages/web/graphql/getPlayers.ts +++ b/packages/web/graphql/getPlayers.ts @@ -11,11 +11,18 @@ import { Order_By, Player, Player_Bool_Exp, + PlayerFragmentFragment, + SearchPlayersDocument, + SearchPlayersQuery, + SearchPlayersQueryVariables, } from 'graphql/autogen/types'; import { client as defaultClient } from 'graphql/client'; import { PlayerFragment, PlayerSkillFragment } from 'graphql/fragments'; import { Client } from 'urql'; +import { client as defaultClient } from './client'; +import { PlayerFragment, PlayerSkillFragment } from './fragments'; + // eslint-disable-next-line @typescript-eslint/no-unused-expressions /* GraphQL */ ` query GetPlayers( @@ -193,3 +200,36 @@ export const getPlayerFilters = async (client: Client = defaultClient) => { return data; }; + +// eslint-disable-next-line @typescript-eslint/no-unused-expressions +/* GraphQL */ ` + query SearchPlayers($search: String! ,$forLoginDisplay: Boolean! = false) { + player(where: { _or: [ + { profile: { username: { _ilike: $search } } }, + { ethereumAddress: { _ilike: $search } } + ] },limit:3) { + ...PlayerFragment +} + ${PlayerFragment} +} +`; + +export const getPlayersByText = async ( + text: string, + client: Client = defaultClient, +) => { + const { data, error } = await client + .query( + SearchPlayersDocument, + { + search: `%${text}%`, + }, + ) + .toPromise(); + + return { + players: data?.player || [], + // count: data?.player_aggregate.aggregate?.count || 0, + error, + }; +}; diff --git a/packages/web/graphql/queries/guild.ts b/packages/web/graphql/queries/guild.ts index 49703896..c5d2afd0 100644 --- a/packages/web/graphql/queries/guild.ts +++ b/packages/web/graphql/queries/guild.ts @@ -7,6 +7,9 @@ import { GetGuildPlayersQueryVariables, GetGuildQuery, GetGuildQueryVariables, + GetGuildsByTextSearchDocument, + GetGuildsByTextSearchQuery, + GetGuildsByTextSearchQueryVariables, GetGuildsQuery, GetGuildsQueryVariables, GuildFragment as GuildFragmentType, @@ -160,3 +163,29 @@ export const getGuildPlayers = async ( return guildPlayers; }; + +// eslint-disable-next-line @typescript-eslint/no-unused-expressions +/* GraphQL */ ` + query getGuildsByTextSearch($text: String) { + search_guilds(args: { search: $text }, limit: 3) { + ...GuildFragment + } + } + ${GuildFragment} +`; + +export const getGuildsByText = async (text: string) => { + const { data, error } = await client + .query( + GetGuildsByTextSearchDocument, + { + text: `%${text}%`, + }, + ) + .toPromise(); + + return { + guilds: data?.search_guilds || [], + error, + }; +}; diff --git a/packages/web/package.json b/packages/web/package.json index 1b98926e..3e704704 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -63,6 +63,7 @@ "react-resizable": "3.0.4", "react-vis": "1.11.7", "rss-to-json": "2.0.2", + "rxjs": "7.5.3", "sourcecred": "0.9.0", "swr": "1.0.1", "urql": "2.0.2",