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