Commit 2fff1760 authored by tom's avatar tom

marketplace app page

parent 6aba61a4
...@@ -16,7 +16,7 @@ import config from 'configs/app'; ...@@ -16,7 +16,7 @@ import config from 'configs/app';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import LayoutApp from 'ui/shared/layout/LayoutApp'; import LayoutApp from 'ui/shared/layout/LayoutApp';
// const MarketplaceApp = dynamic(() => import('ui/pages/MarketplaceApp'), { ssr: false }); const MarketplaceApp = dynamic(() => import('ui/pages/MarketplaceApp'), { ssr: false });
const pathname: Route['pathname'] = '/apps/[id]'; const pathname: Route['pathname'] = '/apps/[id]';
const feature = config.features.marketplace; const feature = config.features.marketplace;
...@@ -24,7 +24,7 @@ const feature = config.features.marketplace; ...@@ -24,7 +24,7 @@ const feature = config.features.marketplace;
const Page: NextPageWithLayout<Props<typeof pathname>> = (props: Props<typeof pathname>) => { const Page: NextPageWithLayout<Props<typeof pathname>> = (props: Props<typeof pathname>) => {
return ( return (
<PageNextJs pathname={ pathname } query={ props.query } apiData={ props.apiData }> <PageNextJs pathname={ pathname } query={ props.query } apiData={ props.apiData }>
{ /* <MarketplaceApp/> */ } <MarketplaceApp/>
</PageNextJs> </PageNextJs>
); );
}; };
......
import { LinkBox, Flex, LinkOverlay } from '@chakra-ui/react'; import { LinkBox, Flex, LinkOverlay, Text } from '@chakra-ui/react';
import type { MouseEvent } from 'react'; import type { MouseEvent } from 'react';
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
...@@ -143,15 +143,11 @@ const FeaturedApp = ({ ...@@ -143,15 +143,11 @@ const FeaturedApp = ({
<Skeleton <Skeleton
loading={ isLoading } loading={ isLoading }
textStyle="sm" asChild
WebkitLineClamp={ 2 }
style={{
WebkitBoxOrient: 'vertical',
}}
display="-webkit-box"
overflow="hidden"
> >
<Text lineClamp={ 2 } textStyle="sm">
{ shortDescription } { shortDescription }
</Text>
</Skeleton> </Skeleton>
</Flex> </Flex>
</Flex> </Flex>
......
import { LinkBox, Flex } from '@chakra-ui/react'; import { LinkBox, Flex, Text } from '@chakra-ui/react';
import type { MouseEvent } from 'react'; import type { MouseEvent } from 'react';
import React from 'react'; import React from 'react';
...@@ -125,15 +125,11 @@ const FeaturedAppMobile = ({ ...@@ -125,15 +125,11 @@ const FeaturedAppMobile = ({
<Skeleton <Skeleton
loading={ isLoading } loading={ isLoading }
textStyle="xs" asChild
WebkitLineClamp={ 3 }
style={{
WebkitBoxOrient: 'vertical',
}}
display="-webkit-box"
overflow="hidden"
> >
<Text lineClamp={ 3 } textStyle="xs">
{ shortDescription } { shortDescription }
</Text>
</Skeleton> </Skeleton>
</Flex> </Flex>
......
import { LinkBox, chakra, Flex } from '@chakra-ui/react'; import { LinkBox, chakra, Flex, Text } from '@chakra-ui/react';
import type { MouseEvent } from 'react'; import type { MouseEvent } from 'react';
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
...@@ -161,15 +161,11 @@ const MarketplaceAppCard = ({ ...@@ -161,15 +161,11 @@ const MarketplaceAppCard = ({
<Skeleton <Skeleton
loading={ isLoading } loading={ isLoading }
textStyle="sm" asChild
WebkitLineClamp={{ base: 2, md: 3 }}
style={{
WebkitBoxOrient: 'vertical',
}}
display="-webkit-box"
overflow="hidden"
> >
<Text lineClamp={{ base: 2, md: 3 }} textStyle="sm">
{ shortDescription } { shortDescription }
</Text>
</Skeleton> </Skeleton>
{ !isLoading && ( { !isLoading && (
......
...@@ -18,8 +18,9 @@ const MarketplaceAppCardLink = ({ url, external, id, title, onClick, className } ...@@ -18,8 +18,9 @@ const MarketplaceAppCardLink = ({ url, external, id, title, onClick, className }
onClick?.(event, id); onClick?.(event, id);
}, [ onClick, id ]); }, [ onClick, id ]);
// TODO @tom2drum create LinkOverlay component
return external ? ( return external ? (
<LinkOverlay href={ url } marginRight={ 2 } className={ className }> <LinkOverlay href={ url } marginRight={ 2 } className={ className } target="_blank">
{ title } { title }
</LinkOverlay> </LinkOverlay>
) : ( ) : (
......
...@@ -8,11 +8,12 @@ import Content from './MarketplaceAppInfo/Content'; ...@@ -8,11 +8,12 @@ import Content from './MarketplaceAppInfo/Content';
interface Props { interface Props {
data: MarketplaceAppOverview | undefined; data: MarketplaceAppOverview | undefined;
isLoading?: boolean;
} }
const MarketplaceAppInfo = ({ data }: Props) => { const MarketplaceAppInfo = ({ data, isLoading }: Props) => {
return ( return (
<InfoButton> <InfoButton isLoading={ isLoading }>
<Content data={ data }/> <Content data={ data }/>
</InfoButton> </InfoButton>
); );
......
...@@ -34,13 +34,13 @@ const Content = ({ data }: Props) => { ...@@ -34,13 +34,13 @@ const Content = ({ data }: Props) => {
return ( return (
<Flex fontSize="sm" flexDir="column" rowGap={ 5 }> <Flex fontSize="sm" flexDir="column" rowGap={ 5 }>
<div> <div>
<Text variant="secondary" fontSize="xs">Project info</Text> <Text color="text.secondary" textStyle="xs">Project info</Text>
<Text fontSize="sm" mt={ 3 }>{ data?.shortDescription }</Text> <Text fontSize="sm" mt={ 3 }>{ data?.shortDescription }</Text>
<WebsiteLink url={ data?.site }/> <WebsiteLink url={ data?.site }/>
</div> </div>
{ socialLinks.length > 0 && ( { socialLinks.length > 0 && (
<div> <div>
<Text variant="secondary" fontSize="xs">Links</Text> <Text color="text.secondary" textStyle="xs">Links</Text>
<Grid templateColumns={{ base: 'repeat(2, 1fr)', lg: 'repeat(3, 1fr)' }} columnGap={ 4 } rowGap={ 3 } mt={ 3 }> <Grid templateColumns={{ base: 'repeat(2, 1fr)', lg: 'repeat(3, 1fr)' }} columnGap={ 4 } rowGap={ 3 } mt={ 3 }>
{ socialLinks.map((link, index) => <SocialLink key={ index } { ...link }/>) } { socialLinks.map((link, index) => <SocialLink key={ index } { ...link }/>) }
</Grid> </Grid>
......
import { Link } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import makePrettyLink from 'lib/makePrettyLink';
import { Link } from 'toolkit/chakra/link';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
interface Props { interface Props {
...@@ -12,23 +13,18 @@ const WebsiteLink = ({ url }: Props) => { ...@@ -12,23 +13,18 @@ const WebsiteLink = ({ url }: Props) => {
return null; return null;
} }
function getHostname(url: string) {
try {
return new URL(url).hostname;
} catch (err) {}
}
return ( return (
<Link <Link
external
noIcon
href={ url } href={ url }
target="_blank"
display="inline-flex" display="inline-flex"
alignItems="center" alignItems="center"
columnGap={ 1 } columnGap={ 1 }
mt={ 3 } mt={ 3 }
> >
<IconSvg name="link" boxSize={ 5 } color="text_secondary"/> <IconSvg name="link" boxSize={ 5 } color="text.secondary"/>
<span>{ getHostname(url) }</span> <span>{ makePrettyLink(url)?.domain }</span>
</Link> </Link>
); );
}; };
......
...@@ -10,6 +10,7 @@ import config from 'configs/app'; ...@@ -10,6 +10,7 @@ import config from 'configs/app';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import { nbsp } from 'lib/html-entities'; import { nbsp } from 'lib/html-entities';
import isBrowser from 'lib/isBrowser'; import isBrowser from 'lib/isBrowser';
import makePrettyLink from 'lib/makePrettyLink';
import * as mixpanel from 'lib/mixpanel/index'; import * as mixpanel from 'lib/mixpanel/index';
import { Badge } from 'toolkit/chakra/badge'; import { Badge } from 'toolkit/chakra/badge';
import { Button } from 'toolkit/chakra/button'; import { Button } from 'toolkit/chakra/button';
...@@ -129,12 +130,6 @@ const MarketplaceAppModal = ({ ...@@ -129,12 +130,6 @@ const MarketplaceAppModal = ({
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const logoUrl = useColorModeValue(logo, logoDarkMode || logo); const logoUrl = useColorModeValue(logo, logoDarkMode || logo);
function getHostname(url: string | undefined) {
try {
return new URL(url || '').hostname;
} catch (err) {}
}
const iconColor = { _light: 'blue.600', _dark: 'gray.400' }; const iconColor = { _light: 'blue.600', _dark: 'gray.400' };
return ( return (
...@@ -323,7 +318,7 @@ const MarketplaceAppModal = ({ ...@@ -323,7 +318,7 @@ const MarketplaceAppModal = ({
overflow="hidden" overflow="hidden"
textOverflow="ellipsis" textOverflow="ellipsis"
> >
{ getHostname(site) } { makePrettyLink(site)?.domain }
</Text> </Text>
</Link> </Link>
) } ) }
......
import { chakra, Flex, Tooltip } from '@chakra-ui/react'; import { chakra, Flex } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { MarketplaceAppOverview, MarketplaceAppSecurityReport, ContractListTypes } from 'types/client/marketplace'; import type { MarketplaceAppOverview, MarketplaceAppSecurityReport, ContractListTypes } from 'types/client/marketplace';
...@@ -8,11 +8,10 @@ import { route } from 'nextjs-routes'; ...@@ -8,11 +8,10 @@ import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import { useAppContext } from 'lib/contexts/app'; import { useAppContext } from 'lib/contexts/app';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import makePrettyLink from 'lib/makePrettyLink';
import { Link } from 'toolkit/chakra/link';
import RewardsButton from 'ui/rewards/RewardsButton'; import RewardsButton from 'ui/rewards/RewardsButton';
import Skeleton from 'ui/shared/chakra/Skeleton'; import ButtonBackTo from 'ui/shared/buttons/ButtonBackTo';
import IconSvg from 'ui/shared/IconSvg';
import LinkExternal from 'ui/shared/links/LinkExternal';
import LinkInternal from 'ui/shared/links/LinkInternal';
import NetworkLogo from 'ui/snippets/networkMenu/NetworkLogo'; import NetworkLogo from 'ui/snippets/networkMenu/NetworkLogo';
import UserProfileDesktop from 'ui/snippets/user/profile/UserProfileDesktop'; import UserProfileDesktop from 'ui/snippets/user/profile/UserProfileDesktop';
import UserWalletDesktop from 'ui/snippets/user/wallet/UserWalletDesktop'; import UserWalletDesktop from 'ui/snippets/user/wallet/UserWalletDesktop';
...@@ -44,41 +43,34 @@ const MarketplaceAppTopBar = ({ appId, data, isLoading, securityReport }: Props) ...@@ -44,41 +43,34 @@ const MarketplaceAppTopBar = ({ appId, data, isLoading, securityReport }: Props)
return route({ pathname: '/apps' }); return route({ pathname: '/apps' });
}, [ appProps.referrer ]); }, [ appProps.referrer ]);
function getHostname(url: string | undefined) {
try {
return new URL(url || '').hostname;
} catch (err) {}
}
const showContractList = React.useCallback((id: string, type: ContractListTypes) => setContractListType(type), []); const showContractList = React.useCallback((id: string, type: ContractListTypes) => setContractListType(type), []);
const hideContractList = React.useCallback(() => setContractListType(undefined), []); const hideContractList = React.useCallback(() => setContractListType(undefined), []);
return ( return (
<> <>
<Flex alignItems="center" mb={{ base: 3, md: 2 }} rowGap={ 3 } columnGap={ 2 }> <Flex alignItems="center" mb={{ base: 3, md: 2 }} rowGap={ 3 } columnGap={ 2 }>
{ !isMobile && <NetworkLogo isCollapsed/> } { !isMobile && <NetworkLogo isCollapsed mr={ 4 }/> }
<Tooltip label="Back to dApps list"> <ButtonBackTo
<LinkInternal display="inline-flex" href={ goBackUrl } h="32px" isLoading={ isLoading } ml={ isMobile ? 0 : 4 }> href={ goBackUrl }
<IconSvg name="arrows/east" boxSize={ 6 } transform="rotate(180deg)" margin="auto" color="gray.400"/> hint="Back to dApps list"
</LinkInternal> size="sm"
</Tooltip> loading={ isLoading }
<LinkExternal />
<Link
external
href={ data?.url } href={ data?.url }
variant="subtle" variant="underlaid"
fontSize="sm" textStyle="sm"
lineHeight={ 5 }
minW={ 0 } minW={ 0 }
maxW={{ base: 'calc(100% - 114px)', md: 'auto' }} maxW={{ base: 'calc(100% - 114px)', md: 'auto' }}
display="flex" display="flex"
isLoading={ isLoading } loading={ isLoading }
> >
<chakra.span isTruncated> <chakra.span truncate>
{ getHostname(data?.url) } { makePrettyLink(data?.url)?.domain }
</chakra.span> </chakra.span>
</LinkExternal> </Link>
<Skeleton isLoaded={ !isLoading }> <MarketplaceAppInfo data={ data } isLoading={ isLoading }/>
<MarketplaceAppInfo data={ data }/>
</Skeleton>
{ (securityReport || isLoading) && ( { (securityReport || isLoading) && (
<AppSecurityReport <AppSecurityReport
id={ data?.id || '' } id={ data?.id || '' }
......
import { Box, Center, useColorMode, Flex } from '@chakra-ui/react'; import { Center, chakra, Flex } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { DappscoutIframeProvider, useDappscoutIframe } from 'dappscout-iframe'; import { DappscoutIframeProvider, useDappscoutIframe } from 'dappscout-iframe';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
...@@ -16,6 +16,7 @@ import throwOnResourceLoadError from 'lib/errors/throwOnResourceLoadError'; ...@@ -16,6 +16,7 @@ import throwOnResourceLoadError from 'lib/errors/throwOnResourceLoadError';
import useFetch from 'lib/hooks/useFetch'; import useFetch from 'lib/hooks/useFetch';
import * as metadata from 'lib/metadata'; import * as metadata from 'lib/metadata';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import { useColorMode } from 'toolkit/chakra/color-mode';
import ContentLoader from 'ui/shared/ContentLoader'; import ContentLoader from 'ui/shared/ContentLoader';
import MarketplaceAppTopBar from '../marketplace/MarketplaceAppTopBar'; import MarketplaceAppTopBar from '../marketplace/MarketplaceAppTopBar';
...@@ -82,12 +83,11 @@ const MarketplaceAppContent = ({ address, data, isPending, appUrl }: Props) => { ...@@ -82,12 +83,11 @@ const MarketplaceAppContent = ({ address, data, isPending, appUrl }: Props) => {
) } ) }
{ (data && isReady) && ( { (data && isReady) && (
<Box <chakra.iframe
key={ iframeKey } key={ iframeKey }
allow={ IFRAME_ALLOW_ATTRIBUTE } allow={ IFRAME_ALLOW_ATTRIBUTE }
ref={ iframeRef } ref={ iframeRef }
sandbox={ IFRAME_SANDBOX_ATTRIBUTE } sandbox={ IFRAME_SANDBOX_ATTRIBUTE }
as="iframe"
h="100%" h="100%"
w="100%" w="100%"
display={ isFrameLoading ? 'none' : 'block' } display={ isFrameLoading ? 'none' : 'block' }
......
...@@ -346,15 +346,7 @@ const SearchResultListItem = ({ data, searchTerm, isLoading, addressFormat }: Pr ...@@ -346,15 +346,7 @@ const SearchResultListItem = ({ data, searchTerm, isLoading, addressFormat }: Pr
} }
case 'app': { case 'app': {
return ( return (
<Text <Text lineClamp={ 3 }>
overflow="hidden"
textOverflow="ellipsis"
style={{
WebkitLineClamp: 3,
WebkitBoxOrient: 'vertical',
display: '-webkit-box',
}}
>
{ data.app.description } { data.app.description }
</Text> </Text>
); );
......
...@@ -8,9 +8,10 @@ import IconSvg from 'ui/shared/IconSvg'; ...@@ -8,9 +8,10 @@ import IconSvg from 'ui/shared/IconSvg';
interface Props { interface Props {
children: React.ReactNode; children: React.ReactNode;
isLoading?: boolean;
} }
const InfoButton = ({ children }: Props) => { const InfoButton = ({ children, isLoading }: Props) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const triggerButton = ( const triggerButton = (
...@@ -22,6 +23,7 @@ const InfoButton = ({ children }: Props) => { ...@@ -22,6 +23,7 @@ const InfoButton = ({ children }: Props) => {
fontWeight={ 500 } fontWeight={ 500 }
pl={ 1 } pl={ 1 }
pr={ isMobile ? 1 : 2 } pr={ isMobile ? 1 : 2 }
loadingSkeleton={ isLoading }
> >
<IconSvg name="info" boxSize={ 6 } mr={ isMobile ? 0 : 1 }/> <IconSvg name="info" boxSize={ 6 } mr={ isMobile ? 0 : 1 }/>
{ !isMobile && <span>Info</span> } { !isMobile && <span>Info</span> }
......
...@@ -49,13 +49,7 @@ const SearchBarSuggestApp = ({ data, isMobile, searchTerm, onClick }: Props) => ...@@ -49,13 +49,7 @@ const SearchBarSuggestApp = ({ data, isMobile, searchTerm, onClick }: Props) =>
</Flex> </Flex>
<Text <Text
color="text.secondary" color="text.secondary"
overflow="hidden" lineClamp={ 3 }
textOverflow="ellipsis"
style={{
WebkitLineClamp: 3,
WebkitBoxOrient: 'vertical',
display: '-webkit-box',
}}
> >
{ data.description } { data.description }
</Text> </Text>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment