From 2b40a2c6108f8349894effabe805063e9d8cbbb6 Mon Sep 17 00:00:00 2001 From: rishabhsharma1997 Date: Thu, 27 Jun 2024 09:39:15 +0530 Subject: [PATCH] feat: added catalog card and icons Signed-off-by: rishabhsharma1997 --- src/custom/CatalogCard/CatalogCard.tsx | 129 ++++++++++++++ src/custom/CatalogCard/index.tsx | 3 + src/custom/CatalogCard/style.tsx | 164 ++++++++++++++++++ src/custom/index.tsx | 1 + .../ContentClassIcons/CommunityClassIcon.tsx | 44 +++++ .../ContentClassIcons/OfficialClassIcon.tsx | 25 +++ .../VerificationClassIcon.tsx | 26 +++ src/icons/ContentClassIcons/index.tsx | 4 + src/icons/Deployments/DeploymentsIcon.tsx | 22 +++ src/icons/Deployments/index.tsx | 2 + src/icons/Design/DesignIcon.tsx | 54 ++++++ src/icons/Design/index.tsx | 2 + src/icons/Download/Download.tsx | 22 +++ src/icons/Download/index.tsx | 2 + src/icons/Open/OpenIcon.tsx | 25 +++ src/icons/Open/index.tsx | 2 + src/icons/Share/ShareIcon.tsx | 26 +++ src/icons/Share/index.tsx | 2 + src/icons/index.ts | 6 + src/icons/types.ts | 5 + 20 files changed, 566 insertions(+) create mode 100644 src/custom/CatalogCard/CatalogCard.tsx create mode 100644 src/custom/CatalogCard/index.tsx create mode 100644 src/custom/CatalogCard/style.tsx create mode 100644 src/icons/ContentClassIcons/CommunityClassIcon.tsx create mode 100644 src/icons/ContentClassIcons/OfficialClassIcon.tsx create mode 100644 src/icons/ContentClassIcons/VerificationClassIcon.tsx create mode 100644 src/icons/ContentClassIcons/index.tsx create mode 100644 src/icons/Deployments/DeploymentsIcon.tsx create mode 100644 src/icons/Deployments/index.tsx create mode 100644 src/icons/Design/DesignIcon.tsx create mode 100644 src/icons/Design/index.tsx create mode 100644 src/icons/Download/Download.tsx create mode 100644 src/icons/Download/index.tsx create mode 100644 src/icons/Open/OpenIcon.tsx create mode 100644 src/icons/Open/index.tsx create mode 100644 src/icons/Share/ShareIcon.tsx create mode 100644 src/icons/Share/index.tsx diff --git a/src/custom/CatalogCard/CatalogCard.tsx b/src/custom/CatalogCard/CatalogCard.tsx new file mode 100644 index 000000000..1fac9cde6 --- /dev/null +++ b/src/custom/CatalogCard/CatalogCard.tsx @@ -0,0 +1,129 @@ +import { styled } from '@mui/material'; +import React from 'react'; +import { + CloneIcon, + CommunityClassIcon, + DesignIcon, + OfficialClassIcon, + OpenIcon, + ShareIcon +} from '../../icons'; +import VerificationClassIcon from '../../icons/ContentClassIcons/VerificationClassIcon'; +import DeploymentsIcon from '../../icons/Deployments/DeploymentsIcon'; +import { DownloadIcon } from '../../icons/Download'; +import { + DesignCard, + DesignDetailsDiv, + DesignInnerCard, + DesignName, + DesignType, + MetricsContainerFront, + MetricsCount, + MetricsDiv, + StyledClassWrapper, + StyledInnerClassWrapper +} from './style'; + +export const DesignCardUrl = styled('a')(() => ({ + textDecoration: 'none' +})); + +type CatalogCardProps = { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + pattern: any; + patternType: string; + url: string; + cardHeight: string; + cardWidth: string; + cardStyles: React.CSSProperties; + type: string; +}; + +export const ClassToIconMap = { + community: , + official: , + verified: +}; + +const ClassWrap = ({ catalogClassName }: { catalogClassName: string }) => { + if (!catalogClassName) return <>; + + return ( + + + {catalogClassName} + + + ); +}; +const CatalogCard: React.FC = ({ + pattern, + patternType, + cardHeight, + cardWidth, + cardStyles, + url +}) => { + const outerStyles = { + height: cardHeight, + width: cardWidth, + ...cardStyles + }; + return ( + + + + + {patternType} + + + {pattern.name} + +
+ +
+
+ + + + {pattern.download_count} + + + + {pattern.clone_count} + + + + {pattern.view_count} + + + + {pattern.deployment_count} + + + + {pattern.share_count} + + +
+
+
+ ); +}; + +export default CatalogCard; diff --git a/src/custom/CatalogCard/index.tsx b/src/custom/CatalogCard/index.tsx new file mode 100644 index 000000000..1e3c893b2 --- /dev/null +++ b/src/custom/CatalogCard/index.tsx @@ -0,0 +1,3 @@ +import CatalogCard from './CatalogCard'; + +export { CatalogCard }; diff --git a/src/custom/CatalogCard/style.tsx b/src/custom/CatalogCard/style.tsx new file mode 100644 index 000000000..c969a80f5 --- /dev/null +++ b/src/custom/CatalogCard/style.tsx @@ -0,0 +1,164 @@ +import { styled, Typography } from '@mui/material'; + +type DesignCardProps = { + outerStyles: React.CSSProperties; +}; +type StyledInnerClassWrapperProps = { + catalogClassName: string; +}; +export const StyledClassWrapper = styled('div')(() => ({ + width: '85px', + height: '88px', + overflow: 'hidden', + position: 'absolute', + top: '-3px', + left: '-3px' +})); + +export const StyledInnerClassWrapper = styled('div')(({ + catalogClassName, + theme +}) => { + const mapToColor: Record = { + community: theme.palette.icon.secondary, + official: theme.palette.background.cta?.default || '#EBC017', + verified: theme.palette.background.brand?.default || '' + }; + return { + font: 'bold 10px sans-serif', + WebkitTransform: 'rotate(-45deg)', + textAlign: 'center', + transform: 'rotate(-45deg)', + position: 'relative', + padding: '4px 0', + top: '15px', + left: '-30px', + width: '120px', + display: 'flex', + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center', + backgroundColor: mapToColor[catalogClassName], + color: '#fff' + }; +}); + +export const DesignCard = styled('div')(({ outerStyles }) => ({ + position: 'relative', + borderRadius: '1rem', + textAlign: 'center', + transformStyle: 'preserve-3d', + transition: 'all .9s ease-out', + marginBottom: '1.25rem', + display: 'inline-flex', + perspective: '1000px', + '&:hover': { + cursor: 'pointer', + transform: 'translateY(-2%)' + }, + ['@media (max-width:1200px)']: { + height: '18.75rem' + }, + ...outerStyles +})); +export const DesignInnerCard = styled('div')(({ theme }) => ({ + position: 'relative', + width: '100%', + height: '100%', + textAlign: 'center', + transition: 'transform 0.6s', + boxShadow: + theme.palette.mode === 'dark' + ? '0 4px 8px 0 rgba(255, 255, 255, 0.1)' + : '0 4px 8px 0 rgba(0,0,0,0.2)', + borderRadius: '0.9375rem' +})); +export const DesignType = styled('span')(({ theme }) => ({ + position: 'absolute', + top: '0', + right: '0', + minWidth: '3rem', + padding: '0 0.75rem', + fontSize: '0.875rem', + textTransform: 'capitalize', + background: theme.palette.background.brand?.default, + color: theme.palette.text.inverse, + borderRadius: '0 1rem 0 2rem' +})); +export const MetricsCount = styled('p')(({ theme }) => ({ + fontSize: '1rem', + textTransform: 'capitalize', + margin: '0rem', + lineHeight: '1.5', + textAlign: 'center', + color: theme.palette.text.secondary, + fontWeight: '600' +})); +export const DesignName = styled(Typography)(({ theme }) => ({ + fontWeight: 'bold', + textTransform: 'capitalize', + color: theme.palette.text.default, + fontSize: '1.125rem', + marginTop: '2rem', + padding: '0rem 1rem', // "0rem 1.5rem" + position: 'relative', + overflow: 'hidden', + whiteSpace: 'nowrap', + textOverflow: 'ellipsis', + // textAlign: "center", + textAlign: 'left', + '& :after': { + content: "''", + textAlign: 'right', + position: 'absolute', + bottom: '0', + right: '0', + width: '70%', + background: 'linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 50%)' + } +})); +export const MetricsContainerFront = styled('div')(({ theme }) => ({ + display: 'flex', + justifyContent: 'space-around', + // borderTop: "0.851px solid #C9DBE3", + fontSize: '0.2rem', + color: theme.palette.text.secondary, + // margin: "-0.8rem 0.7rem 0", + padding: '0.9rem 0.1rem', + background: theme.palette.background.secondary, + position: 'absolute', + bottom: '0px', + marginTop: '1.2rem', + borderRadius: '0 0 0.9375rem 0.9375rem', + width: '100%' +})); +export const MetricsDiv = styled('div')(() => ({ + display: 'flex', + alignItems: 'center', + gap: '4px', + fontSize: '0.2rem', + color: 'rgba(26, 26, 26, .8)', + margin: '0rem', + padding: '0.1rem' +})); +export const DesignDetailsDiv = styled('div')(() => ({ + height: 'max-content', + display: 'flex', + marginTop: '-1rem', + flexDirection: 'column', + padding: '0rem 1rem', + justifyContent: 'start', + alignItems: 'start', + ['@media (max-width:1200px)']: { + height: 'max-content' + } +})); +export const CardFront = styled('div')(({ theme }) => ({ + boxShadow: `2px 2px 3px 0px ${theme.palette.background.brand?.default}`, + background: `linear-gradient(to left bottom, #EBEFF1,#f4f5f7, #f7f7f9, #fff, #fff, #fff,#fff,#fff, #fff, #f7f7f9, #f4f5f7, #EBEFF1)`, + width: '100%', + height: '100%', + WebkitBackfaceVisibility: 'hidden', + borderRadius: '0.9375rem', + backfaceVisibility: 'hidden' +})); diff --git a/src/custom/index.tsx b/src/custom/index.tsx index 6ce7b334e..169814b3d 100644 --- a/src/custom/index.tsx +++ b/src/custom/index.tsx @@ -37,6 +37,7 @@ import { TransferList } from './TransferModal/TransferList'; import { TransferListProps } from './TransferModal/TransferList/TransferList'; import UniversalFilter, { UniversalFilterProps } from './UniversalFilter'; +export { CatalogCard } from './CatalogCard'; export { StyledChartDialog } from './ChartDialog'; export { LearningContent } from './LearningContent'; export { SetupPreReq } from './SetupPrerequisite'; diff --git a/src/icons/ContentClassIcons/CommunityClassIcon.tsx b/src/icons/ContentClassIcons/CommunityClassIcon.tsx new file mode 100644 index 000000000..ad000fc1e --- /dev/null +++ b/src/icons/ContentClassIcons/CommunityClassIcon.tsx @@ -0,0 +1,44 @@ +import { FC } from 'react'; +import { CustomIconProps } from '../types'; +export const CommunityClassIcon: FC = ({ + width = '16', + height = '13', + secondaryFill = '#293B43', + primaryFill = '#647176', + style = {} +}) => ( + + + + + + + + +); + +export default CommunityClassIcon; diff --git a/src/icons/ContentClassIcons/OfficialClassIcon.tsx b/src/icons/ContentClassIcons/OfficialClassIcon.tsx new file mode 100644 index 000000000..62d6097ed --- /dev/null +++ b/src/icons/ContentClassIcons/OfficialClassIcon.tsx @@ -0,0 +1,25 @@ +import { FC } from 'react'; +import { IconProps } from '../types'; +export const OfficialClassIcon: FC = ({ + width = '16', + height = '13', + fill = '#293B43', + style = {} +}) => ( + + + +); + +export default OfficialClassIcon; diff --git a/src/icons/ContentClassIcons/VerificationClassIcon.tsx b/src/icons/ContentClassIcons/VerificationClassIcon.tsx new file mode 100644 index 000000000..5f59f41ec --- /dev/null +++ b/src/icons/ContentClassIcons/VerificationClassIcon.tsx @@ -0,0 +1,26 @@ +import { FC } from 'react'; +import { IconProps } from '../types'; +export const VerificationClassIcon: FC = ({ + width = '16', + height = '13', + fill = '#F6F8F8', + style = {} +}) => ( + + + +); + +export default VerificationClassIcon; diff --git a/src/icons/ContentClassIcons/index.tsx b/src/icons/ContentClassIcons/index.tsx new file mode 100644 index 000000000..da65be26a --- /dev/null +++ b/src/icons/ContentClassIcons/index.tsx @@ -0,0 +1,4 @@ +import CommunityClassIcon from './CommunityClassIcon'; +import OfficialClassIcon from './OfficialClassIcon'; +import VerificationClassIcon from './VerificationClassIcon'; +export { CommunityClassIcon, OfficialClassIcon, VerificationClassIcon }; diff --git a/src/icons/Deployments/DeploymentsIcon.tsx b/src/icons/Deployments/DeploymentsIcon.tsx new file mode 100644 index 000000000..98bee2547 --- /dev/null +++ b/src/icons/Deployments/DeploymentsIcon.tsx @@ -0,0 +1,22 @@ +import { FC } from 'react'; +import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import { IconProps } from '../types'; +export const DeploymentsIcon: FC = ({ + width = DEFAULT_WIDTH, + height = DEFAULT_HEIGHT, + fill = '#51636B', + style = {} +}) => ( + + + +); + +export default DeploymentsIcon; diff --git a/src/icons/Deployments/index.tsx b/src/icons/Deployments/index.tsx new file mode 100644 index 000000000..00e3903e9 --- /dev/null +++ b/src/icons/Deployments/index.tsx @@ -0,0 +1,2 @@ +import DeploymentsIcon from './DeploymentsIcon'; +export { DeploymentsIcon }; diff --git a/src/icons/Design/DesignIcon.tsx b/src/icons/Design/DesignIcon.tsx new file mode 100644 index 000000000..e207d8979 --- /dev/null +++ b/src/icons/Design/DesignIcon.tsx @@ -0,0 +1,54 @@ +import { FC } from 'react'; +import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import { CustomIconProps } from '../types'; +export const DesignIcon: FC = ({ + width = DEFAULT_WIDTH, + height = DEFAULT_HEIGHT, + primaryFill = '#00B39F', + secondaryFill = '#00D3A9', + style = {} +}) => ( + + + + + + + + + + +); + +export default DesignIcon; diff --git a/src/icons/Design/index.tsx b/src/icons/Design/index.tsx new file mode 100644 index 000000000..2bafdf05c --- /dev/null +++ b/src/icons/Design/index.tsx @@ -0,0 +1,2 @@ +import DesignIcon from './DesignIcon'; +export { DesignIcon }; diff --git a/src/icons/Download/Download.tsx b/src/icons/Download/Download.tsx new file mode 100644 index 000000000..b4a7715ad --- /dev/null +++ b/src/icons/Download/Download.tsx @@ -0,0 +1,22 @@ +import { FC } from 'react'; +import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import { IconProps } from '../types'; +export const DownloadIcon: FC = ({ + width = DEFAULT_WIDTH, + height = DEFAULT_HEIGHT, + fill = '#455a64', + style = {} +}) => ( + + + +); + +export default DownloadIcon; diff --git a/src/icons/Download/index.tsx b/src/icons/Download/index.tsx new file mode 100644 index 000000000..c21784e76 --- /dev/null +++ b/src/icons/Download/index.tsx @@ -0,0 +1,2 @@ +import DownloadIcon from './Download'; +export { DownloadIcon }; diff --git a/src/icons/Open/OpenIcon.tsx b/src/icons/Open/OpenIcon.tsx new file mode 100644 index 000000000..4792f79df --- /dev/null +++ b/src/icons/Open/OpenIcon.tsx @@ -0,0 +1,25 @@ +import { FC } from 'react'; +import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import { IconProps } from '../types'; +export const OpenIcon: FC = ({ + width = DEFAULT_WIDTH, + height = DEFAULT_HEIGHT, + fill = '#293B43', + style = {} +}) => ( + + + + + + +); + +export default OpenIcon; diff --git a/src/icons/Open/index.tsx b/src/icons/Open/index.tsx new file mode 100644 index 000000000..e79fc2807 --- /dev/null +++ b/src/icons/Open/index.tsx @@ -0,0 +1,2 @@ +import OpenIcon from './OpenIcon'; +export { OpenIcon }; diff --git a/src/icons/Share/ShareIcon.tsx b/src/icons/Share/ShareIcon.tsx new file mode 100644 index 000000000..758f1fa93 --- /dev/null +++ b/src/icons/Share/ShareIcon.tsx @@ -0,0 +1,26 @@ +import { FC } from 'react'; +import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../constants/constants'; +import { IconProps } from '../types'; +export const ShareIcon: FC = ({ + width = DEFAULT_WIDTH, + height = DEFAULT_HEIGHT, + fill = '#51636B', + style = {} +}) => ( + + + +); + +export default ShareIcon; diff --git a/src/icons/Share/index.tsx b/src/icons/Share/index.tsx new file mode 100644 index 000000000..182307123 --- /dev/null +++ b/src/icons/Share/index.tsx @@ -0,0 +1,2 @@ +import ShareIcon from './ShareIcon'; +export { ShareIcon }; diff --git a/src/icons/index.ts b/src/icons/index.ts index 9ac694d75..bafdc2b16 100644 --- a/src/icons/index.ts +++ b/src/icons/index.ts @@ -39,7 +39,11 @@ export * from './Mesh'; // export { default as OriginalApplicationFileIcon } from "./OriginalApplicationFileIcon"; export * from './Calender'; export * from './ChevronLeft'; +export * from './ContentClassIcons'; +export * from './Deployments'; +export * from './Design'; export * from './Done'; +export * from './Download'; export * from './Edit'; export * from './Environment'; export * from './ExternalLink'; @@ -51,6 +55,7 @@ export * from './Kubernetes'; export * from './LeftAngledArrow'; export * from './LeftArrow'; export * from './MesheryOperator'; +export * from './Open'; export * from './PanTool'; export * from './Pattern'; export * from './Pod'; @@ -68,6 +73,7 @@ export * from './Save'; export * from './Screenshot'; export * from './Search'; export * from './Settings'; +export * from './Share'; export * from './Star'; export * from './Success'; export * from './TerminalIcon'; diff --git a/src/icons/types.ts b/src/icons/types.ts index 9c08ee1a3..01083842b 100644 --- a/src/icons/types.ts +++ b/src/icons/types.ts @@ -8,3 +8,8 @@ export type IconProps = { height?: number | string; fill?: string; } & React.SVGProps; + +export type CustomIconProps = { + primaryFill?: string; + secondaryFill?: string; +} & IconProps;