Commit cbd0bf04 authored by Max Alekseenko's avatar Max Alekseenko

rework app card styles

parent 946f77de
import { Box, IconButton, Image, Link, LinkBox, Skeleton, useColorModeValue } from '@chakra-ui/react'; import { Box, IconButton, Image, Link, LinkBox, Skeleton, useColorModeValue, chakra, Flex } from '@chakra-ui/react';
import type { MouseEvent } from 'react'; import type { MouseEvent } from 'react';
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import type { MarketplaceAppPreview } from 'types/client/marketplace'; import type { MarketplaceAppPreview } from 'types/client/marketplace';
import * as mixpanel from 'lib/mixpanel/index';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import MarketplaceAppCardLink from './MarketplaceAppCardLink'; import MarketplaceAppCardLink from './MarketplaceAppCardLink';
...@@ -13,9 +12,10 @@ import MarketplaceAppIntegrationIcon from './MarketplaceAppIntegrationIcon'; ...@@ -13,9 +12,10 @@ import MarketplaceAppIntegrationIcon from './MarketplaceAppIntegrationIcon';
interface Props extends MarketplaceAppPreview { interface Props extends MarketplaceAppPreview {
onInfoClick: (id: string) => void; onInfoClick: (id: string) => void;
isFavorite: boolean; isFavorite: boolean;
onFavoriteClick: (id: string, isFavorite: boolean, source: 'Discovery view') => void; onFavoriteClick: (id: string, isFavorite: boolean) => void;
isLoading: boolean; isLoading: boolean;
onAppClick: (event: MouseEvent, id: string) => void; onAppClick: (event: MouseEvent, id: string) => void;
className?: string;
} }
const MarketplaceAppCard = ({ const MarketplaceAppCard = ({
...@@ -33,23 +33,24 @@ const MarketplaceAppCard = ({ ...@@ -33,23 +33,24 @@ const MarketplaceAppCard = ({
isLoading, isLoading,
internalWallet, internalWallet,
onAppClick, onAppClick,
className,
}: Props) => { }: Props) => {
const categoriesLabel = categories.join(', '); const categoriesLabel = categories.join(', ');
const handleInfoClick = useCallback((event: MouseEvent) => { const handleInfoClick = useCallback((event: MouseEvent) => {
event.preventDefault(); event.preventDefault();
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'More button', Info: id, Source: 'Discovery view' });
onInfoClick(id); onInfoClick(id);
}, [ onInfoClick, id ]); }, [ onInfoClick, id ]);
const handleFavoriteClick = useCallback(() => { const handleFavoriteClick = useCallback(() => {
onFavoriteClick(id, isFavorite, 'Discovery view'); onFavoriteClick(id, isFavorite);
}, [ onFavoriteClick, id, isFavorite ]); }, [ onFavoriteClick, id, isFavorite ]);
const logoUrl = useColorModeValue(logo, logoDarkMode || logo); const logoUrl = useColorModeValue(logo, logoDarkMode || logo);
return ( return (
<LinkBox <LinkBox
className={ className }
_hover={{ _hover={{
boxShadow: isLoading ? 'none' : 'md', boxShadow: isLoading ? 'none' : 'md',
}} }}
...@@ -57,103 +58,116 @@ const MarketplaceAppCard = ({ ...@@ -57,103 +58,116 @@ const MarketplaceAppCard = ({
boxShadow: isLoading ? 'none' : 'md', boxShadow: isLoading ? 'none' : 'md',
}} }}
borderRadius="md" borderRadius="md"
height="100%"
padding={{ base: 3, sm: '20px' }} padding={{ base: 3, sm: '20px' }}
border="1px" border="1px"
borderColor={ useColorModeValue('gray.200', 'gray.600') } borderColor={ useColorModeValue('gray.200', 'gray.600') }
role="group" role="group"
> >
<Box <Flex
display={{ base: 'grid', sm: 'flex' }} flexDirection={{ base: 'row', sm: 'column' }}
flexDirection="column"
gridTemplateColumns={{ base: '64px 1fr', sm: '1fr' }}
gridTemplateRows={{ base: 'none', sm: 'none' }}
gridRowGap={{ base: 2, sm: 0 }}
gridColumnGap={{ base: 4, sm: 0 }}
height="100%" height="100%"
alignContent="start" alignContent="start"
gap={{ base: 4, sm: 0 }}
> >
<Skeleton <Flex
isLoaded={ !isLoading } display={{ base: 'flex', sm: 'contents' }}
gridRow={{ base: '1 / 4', sm: 'auto' }} flexDirection="column"
marginBottom={ 4 }
w={{ base: '64px', sm: '96px' }}
h={{ base: '64px', sm: '96px' }}
display="flex"
alignItems="center" alignItems="center"
justifyContent="center" justifyContent="space-between"
> >
<Image <Skeleton
src={ isLoading ? undefined : logoUrl } isLoaded={ !isLoading }
alt={ `${ title } app icon` } marginBottom={ 4 }
borderRadius="8px" w={{ base: '64px', sm: '96px' }}
/> h={{ base: '64px', sm: '96px' }}
</Skeleton> display="flex"
alignItems="center"
justifyContent="center"
order={{ base: 'auto', sm: 1 }}
>
<Image
src={ isLoading ? undefined : logoUrl }
alt={ `${ title } app icon` }
borderRadius="8px"
/>
</Skeleton>
<Skeleton { !isLoading && (
isLoaded={ !isLoading } <Box
gridColumn={{ base: 2, sm: 'auto' }} display="flex"
as="h3" marginTop={{ base: 0, sm: 'auto' }}
marginBottom={{ base: 0, sm: 2 }} paddingTop={{ base: 0, sm: 4 }}
fontSize={{ base: 'sm', sm: 'lg' }} order={{ base: 'auto', sm: 5 }}
fontWeight="semibold" >
fontFamily="heading" <Link
display="inline-block" fontSize={{ base: 'xs', sm: 'sm' }}
> fontWeight="500"
<MarketplaceAppCardLink paddingRight={{ sm: 2 }}
id={ id } href="#"
url={ url } onClick={ handleInfoClick }
external={ external } >
title={ title } More info
onClick={ onAppClick } </Link>
/> </Box>
<MarketplaceAppIntegrationIcon external={ external } internalWallet={ internalWallet }/> ) }
</Skeleton> </Flex>
<Skeleton <Flex
isLoaded={ !isLoading } display={{ base: 'flex', sm: 'contents' }}
marginBottom={{ base: 0, sm: 2 }} flexDirection="column"
color="text_secondary" gap={ 2 }
fontSize="xs"
> >
<span>{ categoriesLabel }</span> <Skeleton
</Skeleton> isLoaded={ !isLoading }
marginBottom={{ base: 0, sm: 2 }}
fontSize={{ base: 'sm', sm: 'lg' }}
lineHeight={{ base: '20px', sm: '28px' }}
paddingRight={{ base: '25px', sm: 0 }}
fontWeight="semibold"
fontFamily="heading"
display="inline-block"
order={{ base: 'auto', sm: 2 }}
>
<MarketplaceAppCardLink
id={ id }
url={ url }
external={ external }
title={ title }
onClick={ onAppClick }
/>
<MarketplaceAppIntegrationIcon external={ external } internalWallet={ internalWallet }/>
</Skeleton>
<Skeleton <Skeleton
isLoaded={ !isLoading } isLoaded={ !isLoading }
fontSize={{ base: 'xs', sm: 'sm' }} marginBottom={{ base: 0, sm: 2 }}
lineHeight="20px" color="text_secondary"
noOfLines={ 3 } fontSize="xs"
> lineHeight="16px"
{ shortDescription } order={{ base: 'auto', sm: 3 }}
</Skeleton> >
<span>{ categoriesLabel }</span>
</Skeleton>
{ !isLoading && ( <Skeleton
<Box isLoaded={ !isLoading }
display="flex" fontSize={{ base: 'xs', sm: 'sm' }}
position={{ base: 'absolute', sm: 'relative' }} lineHeight="20px"
bottom={{ base: 3, sm: 0 }} noOfLines={ 3 }
left={{ base: 3, sm: 0 }} order={{ base: 'auto', sm: 4 }}
marginTop={{ base: 0, sm: 'auto' }}
paddingTop={{ base: 0, sm: 4 }}
> >
<Link { shortDescription }
fontSize={{ base: 'xs', sm: 'sm' }} </Skeleton>
paddingRight={{ sm: 2 }} </Flex>
href="#"
onClick={ handleInfoClick }
>
More info
</Link>
</Box>
) }
{ !isLoading && ( { !isLoading && (
<IconButton <IconButton
display="block" display="flex"
alignItems="center"
justifyContent="center"
position="absolute" position="absolute"
right={{ base: 3, sm: '10px' }} right={{ base: 1, sm: '10px' }}
top={{ base: 3, sm: '14px' }} top={{ base: 1, sm: '10px' }}
aria-label="Mark as favorite" aria-label="Mark as favorite"
title="Mark as favorite" title="Mark as favorite"
variant="ghost" variant="ghost"
...@@ -167,9 +181,9 @@ const MarketplaceAppCard = ({ ...@@ -167,9 +181,9 @@ const MarketplaceAppCard = ({
} }
/> />
) } ) }
</Box> </Flex>
</LinkBox> </LinkBox>
); );
}; };
export default React.memo(MarketplaceAppCard); export default React.memo(chakra(MarketplaceAppCard));
...@@ -42,7 +42,6 @@ const MarketplaceAppIntegrationIcon = ({ external, internalWallet }: Props) => { ...@@ -42,7 +42,6 @@ const MarketplaceAppIntegrationIcon = ({ external, internalWallet }: Props) => {
position="relative" position="relative"
cursor="pointer" cursor="pointer"
verticalAlign="middle" verticalAlign="middle"
marginBottom={ 1 }
/> />
</Tooltip> </Tooltip>
); );
......
import { Grid } from '@chakra-ui/react'; import { Grid } from '@chakra-ui/react';
import React from 'react'; import React, { useCallback } from 'react';
import type { MouseEvent } from 'react'; import type { MouseEvent } from 'react';
import type { MarketplaceAppPreview } from 'types/client/marketplace'; import type { MarketplaceAppPreview } from 'types/client/marketplace';
import * as mixpanel from 'lib/mixpanel/index';
import EmptySearchResult from './EmptySearchResult'; import EmptySearchResult from './EmptySearchResult';
import MarketplaceAppCard from './MarketplaceAppCard'; import MarketplaceAppCard from './MarketplaceAppCard';
...@@ -18,6 +20,15 @@ type Props = { ...@@ -18,6 +20,15 @@ type Props = {
} }
const MarketplaceList = ({ apps, showAppInfo, favoriteApps, onFavoriteClick, isLoading, selectedCategoryId, onAppClick }: Props) => { const MarketplaceList = ({ apps, showAppInfo, favoriteApps, onFavoriteClick, isLoading, selectedCategoryId, onAppClick }: Props) => {
const handleInfoClick = useCallback((id: string) => {
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'More button', Info: id, Source: 'Discovery view' });
showAppInfo(id);
}, [ showAppInfo ]);
const handleFavoriteClick = useCallback((id: string, isFavorite: boolean) => {
onFavoriteClick(id, isFavorite, 'Discovery view');
}, [ onFavoriteClick ]);
return apps.length > 0 ? ( return apps.length > 0 ? (
<Grid <Grid
templateColumns={{ templateColumns={{
...@@ -30,7 +41,7 @@ const MarketplaceList = ({ apps, showAppInfo, favoriteApps, onFavoriteClick, isL ...@@ -30,7 +41,7 @@ const MarketplaceList = ({ apps, showAppInfo, favoriteApps, onFavoriteClick, isL
{ apps.map((app, index) => ( { apps.map((app, index) => (
<MarketplaceAppCard <MarketplaceAppCard
key={ app.id + (isLoading ? index : '') } key={ app.id + (isLoading ? index : '') }
onInfoClick={ showAppInfo } onInfoClick={ handleInfoClick }
id={ app.id } id={ app.id }
external={ app.external } external={ app.external }
url={ app.url } url={ app.url }
...@@ -40,7 +51,7 @@ const MarketplaceList = ({ apps, showAppInfo, favoriteApps, onFavoriteClick, isL ...@@ -40,7 +51,7 @@ const MarketplaceList = ({ apps, showAppInfo, favoriteApps, onFavoriteClick, isL
shortDescription={ app.shortDescription } shortDescription={ app.shortDescription }
categories={ app.categories } categories={ app.categories }
isFavorite={ favoriteApps.includes(app.id) } isFavorite={ favoriteApps.includes(app.id) }
onFavoriteClick={ onFavoriteClick } onFavoriteClick={ handleFavoriteClick }
isLoading={ isLoading } isLoading={ isLoading }
internalWallet={ app.internalWallet } internalWallet={ app.internalWallet }
onAppClick={ onAppClick } onAppClick={ onAppClick }
......
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