From 358830b68a0887bd739ad4d28869f5e16a47c809 Mon Sep 17 00:00:00 2001 From: Sudhanshu Dasgupta Date: Fri, 16 Aug 2024 18:39:45 +0530 Subject: [PATCH 1/5] feat(card): fix catalog card Signed-off-by: Sudhanshu Dasgupta --- src/custom/CustomCatalog/custom-card.tsx | 267 ++++++++++++++++++ src/custom/CustomCatalog/index.tsx | 3 + src/custom/CustomCatalog/style.tsx | 342 +++++++++++++++++++++++ src/custom/index.tsx | 2 + 4 files changed, 614 insertions(+) create mode 100644 src/custom/CustomCatalog/custom-card.tsx create mode 100644 src/custom/CustomCatalog/index.tsx create mode 100644 src/custom/CustomCatalog/style.tsx diff --git a/src/custom/CustomCatalog/custom-card.tsx b/src/custom/CustomCatalog/custom-card.tsx new file mode 100644 index 000000000..a73d1b090 --- /dev/null +++ b/src/custom/CustomCatalog/custom-card.tsx @@ -0,0 +1,267 @@ +import CalendarMonthIcon from '@mui/icons-material/CalendarMonth'; +import { Avatar, Box, Typography, styled } from '@mui/material'; +import React from 'react'; +import { Grid } from '../../base'; +import { CloneIcon, CommunityClassIcon, OfficialClassIcon, OpenIcon, ShareIcon } from '../../icons'; +import VerificationClassIcon from '../../icons/ContentClassIcons/VerificationClassIcon'; +import DeploymentsIcon from '../../icons/Deployments/DeploymentsIcon'; +import { DownloadIcon } from '../../icons/Download'; +import { + CardBack, + CardFront, + DateText, + DateType, + DesignAuthorName, + DesignCard, + DesignDetailsDiv, + DesignInnerCard, + DesignName, + DesignType, + MetricsContainerFront, + MetricsCount, + MetricsDiv, + ProfileSection, + StyledClassWrapper, + StyledInnerClassWrapper, + TechnologiesSection, + VersionTag +} from './style'; + +export const DesignCardUrl = styled('a')(() => ({ + textDecoration: 'none' +})); + +interface Pattern { + name: string; + download_count: number; + clone_count: number; + view_count: number; + deployment_count: number; + share_count: number; + userData?: { + version?: string; + avatarUrl?: string; + userName?: string; + technologies?: string[]; + updatedAt?: string; + }; + catalog_data?: { + content_class?: string; + imageURL?: string; + }; + visibility: string; + updated_at: Date; +} + +type CatalogCardProps = { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + pattern: Pattern; + patternType: string; + cardLink: string; + cardHeight: string; + cardWidth: string; + cardStyles: React.CSSProperties; + type: string; + version?: string; + avatarUrl: string; + userName: string; + technologies: string[]; + updatedAt: string; + shouldFlip?: boolean; + cardTechnologies?: boolean; + isDetailed?: boolean; + cardAvatarUrl?: boolean; + date?: boolean; + cardVersion?: boolean; + UserName?: string; + children?: React.ReactNode; +}; + +export const ClassToIconMap = { + community: , + official: , + verified: +}; + +const ClassWrap = ({ catalogClassName }: { catalogClassName: string }) => { + if (!catalogClassName) return <>; + + return ( + + + {catalogClassName} + + + ); +}; + +const CustomCatalogCard: React.FC = ({ + pattern, + patternType, + cardHeight, + cardWidth, + cardStyles, + cardLink, + shouldFlip, + isDetailed, + cardAvatarUrl, + cardTechnologies, + date, + cardVersion, + avatarUrl, + UserName, + children +}) => { + const outerStyles = { + height: cardHeight, + width: cardWidth, + ...cardStyles + }; + + return ( + + + + + {isDetailed && ( + <> + + {patternType} + + + {pattern.name} + + + )} + +
+ {children} +
+
+ {isDetailed && ( + + + + {pattern.download_count} + + + + {pattern.clone_count} + + + + {pattern.view_count} + + + + {pattern.deployment_count} + + + + {pattern.share_count} + + + )} +
+ {shouldFlip && ( + + {cardAvatarUrl && ( + + + {UserName} + + )} + + + {cardTechnologies && ( + + + Technologies + + + Kubernetes + + + )} + + + {date && ( + + + +
+ + Updated At +
+ + {' '} + {new Date(pattern.updated_at.toString().slice(0, 10)).toLocaleDateString( + 'en-US', + { + day: 'numeric', + month: 'long', + year: 'numeric' + } + )} + +
+
+
+ )} + + {cardVersion && ( + + v{cardVersion} + + )} +
+ )} +
+
+
+ ); +}; + +export default CustomCatalogCard; diff --git a/src/custom/CustomCatalog/index.tsx b/src/custom/CustomCatalog/index.tsx new file mode 100644 index 000000000..09adbc5cc --- /dev/null +++ b/src/custom/CustomCatalog/index.tsx @@ -0,0 +1,3 @@ +import CustomCatalogCard from './custom-card'; + +export { CustomCatalogCard }; diff --git a/src/custom/CustomCatalog/style.tsx b/src/custom/CustomCatalog/style.tsx new file mode 100644 index 000000000..ee81ec55c --- /dev/null +++ b/src/custom/CustomCatalog/style.tsx @@ -0,0 +1,342 @@ +import { styled, Typography } from '@mui/material'; + +type DesignCardProps = { + outerStyles: React.CSSProperties; + shouldFlip?: boolean; + isDetailed?: boolean; +}; +type DesignCardDivProps = { + shouldFlip?: boolean; + isDetailed?: boolean; +}; +type MetricsProps = { + isDetailed?: boolean; +}; +type CatalogProps = { + isCatalog?: boolean; +}; +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 +}) => { + const mapToColor: Record = { + community: 'rgba(122,132,142,.8)', + official: '#EBC017', + verified: '#00B39F' + }; + 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')( + ({ shouldFlip, isDetailed, outerStyles, theme }) => ({ + position: 'relative', + borderRadius: '1rem', + textAlign: 'center', + transformStyle: 'preserve-3d', + display: 'block', + perspective: '1000px', + transition: 'all .9s ease-out', + ...(shouldFlip && { + '&:hover': { + cursor: 'pointer', + '& .innerCard': { + transform: 'rotateY(180deg)' + } + } + }), + ...(isDetailed && { + [theme.breakpoints.down('lg')]: { + height: '18.75rem' + } + }), + ...outerStyles + }) +); + +export const DesignInnerCard = styled('div')(({ shouldFlip, isDetailed }) => ({ + position: 'relative', + width: '100%', + height: '100%', + textAlign: 'center', + transition: 'transform 0.6s', + ...(shouldFlip && { + transformOrigin: '50% 50%', + transformStyle: 'preserve-3d' + }), + ...(isDetailed && { + boxShadow: '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', + width: '100%' +})); +export const MetricsContainerFront = styled('div')(({ isDetailed }) => ({ + display: 'flex', + justifyContent: 'space-around', + // borderTop: "0.851px solid #C9DBE3", + fontSize: '0.2rem', + color: 'rgba(26, 26, 26, .8)', + // margin: "-0.8rem 0.7rem 0", + padding: '0.9rem 0.1rem', + background: '#E7EFF3', + ...(isDetailed && { + position: 'absolute', + bottom: '0px' + }), + ...(!isDetailed && { + 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 ImageWrapper = styled('div')(({ theme }) => ({ + background: theme.palette.mode === 'light' ? 'rgba(231, 239, 243, 0.40)' : '#212121', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + padding: '0.5rem', + width: '100%', + borderRadius: '0.5rem' +})); + +export const VersionTag = styled('div')(({ theme }) => ({ + display: 'inline-block', + backgroundColor: theme.palette.background.supplementary, + color: theme.palette.text.constant?.white, + borderRadius: '4px', + fontSize: '0.75rem', + fontWeight: 'bold', + margin: '5px 0', + padding: '2px 5px', + maxWidth: 'fit-content' +})); + +export const FlipCard = styled('div')(() => ({ + perspective: '1000px', + '&:hover .flipper': { + transform: 'rotateY(-180deg)' + } +})); + +export const Flipper = styled('div')(() => ({ + transition: '0.6s', + transformStyle: 'preserve-3d', + position: 'relative' +})); + +export const Face = styled('div')(() => ({ + backfaceVisibility: 'hidden', + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%' +})); + +export const FrontFace = styled(Face)(() => ({ + zIndex: 2, + transform: 'rotateY(0deg)' +})); + +export const BackFace = styled('div')(() => ({ + transform: 'rotateY(-180deg)', + color: '#fff', + display: 'inline-flex', + flexDirection: 'column', + padding: '16px', + height: '100%', + width: '100%', + position: 'relative', + bottom: 0, + left: 0, + backfaceVisibility: 'hidden' +})); + +export const BackFaceContent = styled('div')(({ theme }) => ({ + position: 'absolute', + background: `linear-gradient(to bottom right, black 40%, ${theme.palette.background.brand?.default})`, + width: '100%', + top: 0, + left: 0, + display: 'flex', + flexDirection: 'column', + alignItems: 'left', + padding: '16px', + boxShadow: `2px 2px 3px 0px black`, + borderRadius: '1rem' +})); + +export const ProfileSection = styled('div')({ + display: 'flex', + alignItems: 'center', + marginBottom: '16px' +}); + +export const TechnologiesSection = styled('div')(({ theme }) => ({ + backgroundColor: 'rgba(255, 255, 255, 0.25)', + padding: theme.spacing(1), + borderRadius: theme.shape.borderRadius, + marginBottom: '16px' +})); + +export const UpdatedSection = styled('div')({ + display: 'flex', + alignItems: 'center', + color: '#fff', + margin: '20px 0' +}); + +export const CardBack = styled('div')(({ isCatalog }) => ({ + boxShadow: `2px 2px 3px 0px rgba(26, 26, 26, 1)`, + position: 'absolute', + width: '100%', + height: '100%', + WebkitBackfaceVisibility: 'hidden', + borderRadius: '0.9375rem', + backfaceVisibility: 'hidden', + color: 'white', + transform: 'rotateY(180deg)', + ...(isCatalog && { + background: + 'linear-gradient(335deg, rgba(0, 179, 159, 0.80) -13.6%, rgba(0, 0, 0, 0.68) 66.8%), radial-gradient(3970.04% 147.22% at 47.5% 100%, #000 0%, #395357 100%)' + }), + ...(!isCatalog && { + background: 'linear-gradient(250deg, #477e96 0%, #00b39f 35%, rgb(60, 73, 79) 100%)' + }) +})); + +export const CardFront = styled('div')(({ shouldFlip, isDetailed, theme }) => ({ + ...(shouldFlip && { + position: 'absolute', + boxShadow: `2px 2px 3px 0px ${theme.palette.background.brand?.default}`, + background: `linear-gradient(to left bottom, #EBEFF1, #f4f5f7, #f7f7f9, white, white, white, white, white, white, #f7f7f9, #f4f5f7, #EBEFF1);` + }), + ...(isDetailed && { + boxShadow: `2px 2px 3px 0px ${theme.palette.background.brand?.default}`, + background: `linear-gradient(to left bottom, #EBEFF1, #f4f5f7, #f7f7f9, white, white, white, white, white, white, #f7f7f9, #f4f5f7, #EBEFF1);` + }), + width: '100%', + height: '100%', + WebkitBackfaceVisibility: 'hidden', + borderRadius: '0.9375rem', + backfaceVisibility: 'hidden' +})); + +export const DateText = styled('div')(() => ({ + fontSize: '0.875rem', + textTransform: 'capitalize', + color: '#eee', + margin: '0rem', + padding: '0.1rem', + fontWeight: '400', + lineHeight: '1.5' +})); + +export const DateType = styled('p')(() => ({ + fontSize: '0.876rem', + margin: '0rem', + lineHeight: '1.5', + fontWeight: '400', + color: '#eee' +})); + +export const DesignAuthorName = styled('div')(() => ({ + height: 'max-content', + display: 'flex', + margin: '0', + flexDirection: 'column', + padding: '0rem 1rem', + justifyContent: 'start', + alignItems: 'start', + fontWeight: '400', + textAlign: 'right', + color: '#E7EFF3', + textTransform: 'capitalize', + ['@media (max-width:1200px)']: { + height: 'max-content' + } +})); diff --git a/src/custom/index.tsx b/src/custom/index.tsx index b2fd178a7..24b20882d 100644 --- a/src/custom/index.tsx +++ b/src/custom/index.tsx @@ -3,6 +3,7 @@ import { BookmarkNotification } from './BookmarkNotification'; import CatalogFilter, { CatalogFilterProps } from './CatalogFilter/CatalogFilter'; import { ChapterCard } from './ChapterCard'; import { ConnectionChip } from './ConnectionChip'; +import { CustomCatalogCard } from './CustomCatalog'; import { CustomColumn, CustomColumnVisibilityControl, @@ -57,6 +58,7 @@ export { CatalogFilter, ChapterCard, ConnectionChip, + CustomCatalogCard, CustomColumnVisibilityControl, CustomDialog, CustomImage, From c21df77e265a555db5c9eb3a3f0a27a45385b235 Mon Sep 17 00:00:00 2001 From: Sudhanshu Dasgupta Date: Wed, 9 Oct 2024 19:31:32 +0530 Subject: [PATCH 2/5] feat(revamp): card Signed-off-by: Sudhanshu Dasgupta --- src/custom/CustomCatalog/custom-card.tsx | 140 ++++++++++++++++++----- src/custom/CustomCatalog/style.tsx | 43 ++++++- 2 files changed, 147 insertions(+), 36 deletions(-) diff --git a/src/custom/CustomCatalog/custom-card.tsx b/src/custom/CustomCatalog/custom-card.tsx index a73d1b090..53ff8414e 100644 --- a/src/custom/CustomCatalog/custom-card.tsx +++ b/src/custom/CustomCatalog/custom-card.tsx @@ -1,11 +1,12 @@ import CalendarMonthIcon from '@mui/icons-material/CalendarMonth'; -import { Avatar, Box, Typography, styled } from '@mui/material'; -import React from 'react'; +import { Avatar, Typography, styled } from '@mui/material'; +import React, { useEffect, useState } from 'react'; import { Grid } from '../../base'; import { CloneIcon, CommunityClassIcon, OfficialClassIcon, OpenIcon, ShareIcon } from '../../icons'; import VerificationClassIcon from '../../icons/ContentClassIcons/VerificationClassIcon'; import DeploymentsIcon from '../../icons/Deployments/DeploymentsIcon'; import { DownloadIcon } from '../../icons/Download'; +import { CustomTooltip } from '../CustomTooltip'; import { CardBack, CardFront, @@ -20,10 +21,12 @@ import { MetricsContainerFront, MetricsCount, MetricsDiv, + NoTechnologyText, ProfileSection, StyledClassWrapper, StyledInnerClassWrapper, TechnologiesSection, + TechnologyText, VersionTag } from './style'; @@ -48,6 +51,7 @@ interface Pattern { catalog_data?: { content_class?: string; imageURL?: string; + compatibility?: string[]; }; visibility: string; updated_at: Date; @@ -64,6 +68,7 @@ type CatalogCardProps = { type: string; version?: string; avatarUrl: string; + compatibility: string[]; userName: string; technologies: string[]; updatedAt: string; @@ -74,7 +79,10 @@ type CatalogCardProps = { date?: boolean; cardVersion?: boolean; UserName?: string; - children?: React.ReactNode; + children?: React.ReactNode; // catalogImage + TechnologyComponent?: React.ReactNode; + basePath?: string; // path of meshmodel img stored + getHostUrl?: () => string; }; export const ClassToIconMap = { @@ -104,13 +112,13 @@ const CustomCatalogCard: React.FC = ({ cardLink, shouldFlip, isDetailed, - cardAvatarUrl, cardTechnologies, - date, cardVersion, avatarUrl, UserName, - children + children, + basePath, + getHostUrl }) => { const outerStyles = { height: cardHeight, @@ -118,6 +126,47 @@ const CustomCatalogCard: React.FC = ({ ...cardStyles }; + const technologies = pattern.catalog_data?.compatibility || []; // an array + const techlimit = 5; + const [availableTechnologies, setAvailableTechnologies] = useState([]); + const checkImageUrlValidity = async (url: string, appendHostUrl = true) => { + return new Promise((resolve) => { + const img = new Image(); + // Only append host if the URL does not start with "http" or "https" + if (appendHostUrl && !url.startsWith('http')) { + img.src = (getHostUrl ? getHostUrl() : '') + url; + } else { + img.src = url; + } + img.onload = () => { + // Check if the image loaded successfully + resolve(true); + }; + + img.onerror = () => { + // Handle the case where the image could not be loaded + resolve(false); + }; + }); + }; + + const handleImage = async () => { + const validSvgPaths = []; + for (const technology of technologies) { + const svgIconPath = `${basePath}/${technology.toLowerCase()}/icons/color/${technology.toLowerCase()}-color.svg`; + const isSvgPathValid = await checkImageUrlValidity(svgIconPath as string); + if (isSvgPathValid) { + validSvgPaths.push(technology); + } + } + + setAvailableTechnologies(validSvgPaths); + }; + useEffect(() => { + handleImage(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + return ( @@ -181,39 +230,70 @@ const CustomCatalogCard: React.FC = ({ {shouldFlip && ( - {cardAvatarUrl && ( - - - {UserName} - - )} + + + {UserName} + {cardTechnologies && ( - Technologies + - Technologies - - - Kubernetes - + {technologies.length < 1 || availableTechnologies.length < 1 ? ( + No technologies + ) : ( + <> + {availableTechnologies.slice(0, techlimit).map((technology, index) => { + const svgPath = + (getHostUrl ? getHostUrl() : '') + + `${basePath}/${technology.toLowerCase()}/icons/color/${technology.toLowerCase()}-color.svg`; + return ( + + + {technology.toLowerCase()} + + + ); + })} + {availableTechnologies.length > techlimit && ( + + +{availableTechnologies.length - techlimit} + + )} + + )} + )} - {date && ( - + {isDetailed && ( + ({ left: '-3px' })); +export const TechnologyText = styled('div')(() => ({ + color: '#eee', + fontSize: '0.875rem', + lineHeight: '1.5', + fontWeight: '600', + borderBottom: '1px solid rgba(231, 239, 243, 0.40)' +})); + +export const NoTechnologyText = styled('div')(() => ({ + color: '#eee', + overflow: 'hidden', + fontSize: '14px', + lineHeight: '24px', + fontWeight: '400', + marginTop: '.8rem' +})); + export const StyledInnerClassWrapper = styled('div')(({ catalogClassName }) => { @@ -251,16 +268,30 @@ export const BackFaceContent = styled('div')(({ theme }) => ({ })); export const ProfileSection = styled('div')({ + height: 'max-content', display: 'flex', + marginTop: '1.2rem', + flexDirection: 'row', + padding: '0rem 1rem', + justifyContent: 'flex-start', alignItems: 'center', - marginBottom: '16px' + ['@media (max-width:1200px)']: { + height: 'max-content' + } }); -export const TechnologiesSection = styled('div')(({ theme }) => ({ - backgroundColor: 'rgba(255, 255, 255, 0.25)', - padding: theme.spacing(1), - borderRadius: theme.shape.borderRadius, - marginBottom: '16px' +export const TechnologiesSection = styled('div')(() => ({ + marginBottom: '16px', + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + width: '100%', + gap: '1rem', + alignItems: 'flex-start', + background: 'rgba(231, 239, 243, 0.40)', + borderRadius: '0.25rem', + padding: '0.5rem 1rem', + alignSelf: 'stretch' })); export const UpdatedSection = styled('div')({ From cdb37758b866b93834ae2d38813a5cc692b4ae86 Mon Sep 17 00:00:00 2001 From: Sudhanshu Dasgupta Date: Wed, 9 Oct 2024 19:33:31 +0530 Subject: [PATCH 3/5] fix(lint): linting Signed-off-by: Sudhanshu Dasgupta --- src/custom/CustomCatalog/custom-card.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/custom/CustomCatalog/custom-card.tsx b/src/custom/CustomCatalog/custom-card.tsx index 53ff8414e..06ee8018d 100644 --- a/src/custom/CustomCatalog/custom-card.tsx +++ b/src/custom/CustomCatalog/custom-card.tsx @@ -58,7 +58,6 @@ interface Pattern { } type CatalogCardProps = { - // eslint-disable-next-line @typescript-eslint/no-explicit-any pattern: Pattern; patternType: string; cardLink: string; From 7224e57f3f56ea33b714e6b9d9a8565a1f2bb0a8 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Thu, 10 Oct 2024 23:07:07 +0530 Subject: [PATCH 4/5] fix: some of the styling in custom catalog card Signed-off-by: Amit Amrutiya --- src/custom/CustomCatalog/custom-card.tsx | 24 ++++++++++++++++------ src/custom/CustomCatalog/style.tsx | 26 +++++++++++++++++++++++- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/custom/CustomCatalog/custom-card.tsx b/src/custom/CustomCatalog/custom-card.tsx index 06ee8018d..c90d78f83 100644 --- a/src/custom/CustomCatalog/custom-card.tsx +++ b/src/custom/CustomCatalog/custom-card.tsx @@ -1,5 +1,5 @@ import CalendarMonthIcon from '@mui/icons-material/CalendarMonth'; -import { Avatar, Typography, styled } from '@mui/material'; +import { Avatar, styled } from '@mui/material'; import React, { useEffect, useState } from 'react'; import { Grid } from '../../base'; import { CloneIcon, CommunityClassIcon, OfficialClassIcon, OpenIcon, ShareIcon } from '../../icons'; @@ -27,7 +27,8 @@ import { StyledInnerClassWrapper, TechnologiesSection, TechnologyText, - VersionTag + VersionDiv, + VersionText } from './style'; export const DesignCardUrl = styled('a')(() => ({ @@ -166,6 +167,18 @@ const CustomCatalogCard: React.FC = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + if (!shouldFlip) { + return ( + + + + {children} + + + + ); + } + return ( @@ -329,11 +342,10 @@ const CustomCatalogCard: React.FC = ({ )} - {cardVersion && ( - - v{cardVersion} - + + v{cardVersion} + )} )} diff --git a/src/custom/CustomCatalog/style.tsx b/src/custom/CustomCatalog/style.tsx index d8a0ce98a..863caa418 100644 --- a/src/custom/CustomCatalog/style.tsx +++ b/src/custom/CustomCatalog/style.tsx @@ -212,6 +212,31 @@ export const VersionTag = styled('div')(({ theme }) => ({ maxWidth: 'fit-content' })); +export const VersionDiv = styled('div')(({ theme }) => ({ + display: 'flex', + alignItems: 'center', + gap: '4px', + fontSize: '0.75', + color: theme.palette.text.constant?.white, + position: 'absolute', + bottom: '16px', + left: '16px', + borderRadius: '4px', + background: theme.palette.background.supplementary, + justifyContent: 'center' +})); + +export const VersionText = styled('p')(({ theme }) => ({ + fontSize: '0.75rem', + margin: '0', + padding: '0.25rem .5rem', + lineHeight: '1.5', + textTransform: 'lowercase', + fontWeight: '600', + borderRadius: '4.05px', + color: theme.palette.text.constant?.white +})); + export const FlipCard = styled('div')(() => ({ perspective: '1000px', '&:hover .flipper': { @@ -281,7 +306,6 @@ export const ProfileSection = styled('div')({ }); export const TechnologiesSection = styled('div')(() => ({ - marginBottom: '16px', display: 'flex', flexDirection: 'column', justifyContent: 'center', From a42050630bcf83de026c4429472e61ad2302e22b Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Fri, 11 Oct 2024 00:02:42 +0530 Subject: [PATCH 5/5] feat: refactor StyledSearchBar component and add search icon Signed-off-by: Amit Amrutiya --- .../StyledSearchBar/StyledSearchBar.tsx | 73 ++++++++++--------- src/custom/StyledSearchBar/style.tsx | 21 ++++++ 2 files changed, 61 insertions(+), 33 deletions(-) create mode 100644 src/custom/StyledSearchBar/style.tsx diff --git a/src/custom/StyledSearchBar/StyledSearchBar.tsx b/src/custom/StyledSearchBar/StyledSearchBar.tsx index d543bf520..2e2799bdb 100644 --- a/src/custom/StyledSearchBar/StyledSearchBar.tsx +++ b/src/custom/StyledSearchBar/StyledSearchBar.tsx @@ -1,51 +1,58 @@ +import { SxProps, Theme, useTheme } from '@mui/material'; import React from 'react'; -import { Box } from '../../base/Box'; -import { InputAdornment } from '../../base/Input'; -import { TextField } from '../../base/TextField'; +import { InputAdornment } from '../../base'; +import { SearchIcon } from '../../icons'; +import { InputAdornmentEnd, StyledSearchInput } from './style'; interface SearchBarProps { onChange?: (event: React.ChangeEvent) => void; value?: string; width?: string; - label: string; + label?: string; + placeholder?: string; + sx?: SxProps; endAdornment?: React.ReactNode; } +/** + * StyledSearchBar component renders a search input field with customizable properties. + * + * @param {Object} props - The component props. + * @param {function} [props.onChange] - Function to handle the change event when the search input value changes. + * @param {string} [props.value] - The current value of the search input. + * @param {string} [props.label] - The label for the search input. + * @param {string} [props.placeholder] - The placeholder text for the search input. + * @param {Object} [props.sx] - The style object for the search input. + * @param {React.ReactNode} [props.endAdornment] - The element to display at the end of the search input. + * + * @returns {JSX.Element} The rendered StyledSearchBar component. + */ function StyledSearchBar({ onChange, value, - width, label, - endAdornment, - ...props + sx, + placeholder, + endAdornment }: SearchBarProps): JSX.Element { + const theme = useTheme(); + return ( - - :not(style)': { width } - }} - {...props} - > - {endAdornment} - }} - /> - - + + + + } + endAdornment={{endAdornment}} + /> ); } diff --git a/src/custom/StyledSearchBar/style.tsx b/src/custom/StyledSearchBar/style.tsx new file mode 100644 index 000000000..92ce4187b --- /dev/null +++ b/src/custom/StyledSearchBar/style.tsx @@ -0,0 +1,21 @@ +import { styled } from '@mui/material'; +import { InputAdornment, OutlinedInput } from '../../base'; + +export const StyledSearchInput = styled(OutlinedInput)(({ style }) => ({ + width: '100%', + '@media (max-width: 590px)': { + marginLeft: '0.25rem', + paddingLeft: '0.25rem' + }, + display: 'flex', + ...style +})); + +export const InputAdornmentEnd = styled(InputAdornment)(({ theme }) => ({ + borderLeft: `1px solid ${theme.palette.border.normal}`, + height: '30px', + paddingLeft: '10px', + '@media (max-width: 590px)': { + paddingLeft: '0px' + } +}));