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,31 +58,32 @@ const MarketplaceAppCard = ({ ...@@ -57,31 +58,32 @@ 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 }}
>
<Flex
display={{ base: 'flex', sm: 'contents' }}
flexDirection="column"
alignItems="center"
justifyContent="space-between"
> >
<Skeleton <Skeleton
isLoaded={ !isLoading } isLoaded={ !isLoading }
gridRow={{ base: '1 / 4', sm: 'auto' }}
marginBottom={ 4 } marginBottom={ 4 }
w={{ base: '64px', sm: '96px' }} w={{ base: '64px', sm: '96px' }}
h={{ base: '64px', sm: '96px' }} h={{ base: '64px', sm: '96px' }}
display="flex" display="flex"
alignItems="center" alignItems="center"
justifyContent="center" justifyContent="center"
order={{ base: 'auto', sm: 1 }}
> >
<Image <Image
src={ isLoading ? undefined : logoUrl } src={ isLoading ? undefined : logoUrl }
...@@ -90,15 +92,41 @@ const MarketplaceAppCard = ({ ...@@ -90,15 +92,41 @@ const MarketplaceAppCard = ({
/> />
</Skeleton> </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>
<Flex
display={{ base: 'flex', sm: 'contents' }}
flexDirection="column"
gap={ 2 }
>
<Skeleton <Skeleton
isLoaded={ !isLoading } isLoaded={ !isLoading }
gridColumn={{ base: 2, sm: 'auto' }}
as="h3"
marginBottom={{ base: 0, sm: 2 }} marginBottom={{ base: 0, sm: 2 }}
fontSize={{ base: 'sm', sm: 'lg' }} fontSize={{ base: 'sm', sm: 'lg' }}
lineHeight={{ base: '20px', sm: '28px' }}
paddingRight={{ base: '25px', sm: 0 }}
fontWeight="semibold" fontWeight="semibold"
fontFamily="heading" fontFamily="heading"
display="inline-block" display="inline-block"
order={{ base: 'auto', sm: 2 }}
> >
<MarketplaceAppCardLink <MarketplaceAppCardLink
id={ id } id={ id }
...@@ -115,6 +143,8 @@ const MarketplaceAppCard = ({ ...@@ -115,6 +143,8 @@ const MarketplaceAppCard = ({
marginBottom={{ base: 0, sm: 2 }} marginBottom={{ base: 0, sm: 2 }}
color="text_secondary" color="text_secondary"
fontSize="xs" fontSize="xs"
lineHeight="16px"
order={{ base: 'auto', sm: 3 }}
> >
<span>{ categoriesLabel }</span> <span>{ categoriesLabel }</span>
</Skeleton> </Skeleton>
...@@ -124,36 +154,20 @@ const MarketplaceAppCard = ({ ...@@ -124,36 +154,20 @@ const MarketplaceAppCard = ({
fontSize={{ base: 'xs', sm: 'sm' }} fontSize={{ base: 'xs', sm: 'sm' }}
lineHeight="20px" lineHeight="20px"
noOfLines={ 3 } noOfLines={ 3 }
order={{ base: 'auto', sm: 4 }}
> >
{ shortDescription } { shortDescription }
</Skeleton> </Skeleton>
</Flex>
{ !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 }}
>
<Link
fontSize={{ base: 'xs', sm: 'sm' }}
paddingRight={{ sm: 2 }}
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