From 1f5663a772a5da809329886fa0676dc6c33feb6e Mon Sep 17 00:00:00 2001 From: Ankita Sahu <71656941+SAHU-01@users.noreply.github.com> Date: Mon, 5 Aug 2024 11:56:25 +0530 Subject: [PATCH] feat(UI): Catalog Card flip enabled Signed-off-by: Ankita Sahu <71656941+SAHU-01@users.noreply.github.com> --- src/custom/CatalogCard/CatalogCard.tsx | 272 ++++++++++++++++++++----- 1 file changed, 220 insertions(+), 52 deletions(-) diff --git a/src/custom/CatalogCard/CatalogCard.tsx b/src/custom/CatalogCard/CatalogCard.tsx index 01804ff7..9c185a05 100644 --- a/src/custom/CatalogCard/CatalogCard.tsx +++ b/src/custom/CatalogCard/CatalogCard.tsx @@ -1,4 +1,5 @@ -import { styled } from '@mui/material'; +import CalendarMonthIcon from '@mui/icons-material/CalendarMonth'; +import { Avatar, Box, Typography, styled } from '@mui/material'; import React from 'react'; import { CloneIcon, @@ -29,9 +30,28 @@ 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; + }; +} + type CatalogCardProps = { // eslint-disable-next-line @typescript-eslint/no-explicit-any - pattern: any; + pattern: Pattern; patternType: string; cardLink: string; cardHeight: string; @@ -39,18 +59,22 @@ type CatalogCardProps = { cardStyles: React.CSSProperties; type: string; version?: string; + avatarUrl: string; + userName: string; + technologies: string[]; + updatedAt: string; }; export const VersionTag = styled('div')(({ theme }) => ({ - position: 'absolute', - bottom: '65px', - left: '18px', - backgroundColor: theme.palette.grey[500], - color: theme.palette.grey[900], - padding: '1px 10px', + display: 'inline-block', + backgroundColor: theme.palette.background.secondary, + color: theme.palette.text.secondary, borderRadius: '4px', fontSize: '0.75rem', - fontWeight: 'bold' + fontWeight: 'bold', + margin: '5px 0', + padding: '2px 5px', + maxWidth: 'fit-content' })); export const ClassToIconMap = { @@ -70,6 +94,82 @@ const ClassWrap = ({ catalogClassName }: { catalogClassName: string }) => { ); }; + +const FlipCard = styled('div')(() => ({ + perspective: '1000px', + '&:hover .flipper': { + transform: 'rotateY(-180deg)' + } +})); + +const Flipper = styled('div')(() => ({ + transition: '0.6s', + transformStyle: 'preserve-3d', + position: 'relative' +})); + +const Face = styled('div')(() => ({ + backfaceVisibility: 'hidden', + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%' +})); + +const FrontFace = styled(Face)(() => ({ + zIndex: 2, + transform: 'rotateY(0deg)' +})); + +const BackFace = styled(Box)(() => ({ + transform: 'rotateY(-180deg)', + color: '#fff', + display: 'inline-flex', + flexDirection: 'column', + padding: '16px', + height: '100%', + width: '100%', + position: 'relative', + bottom: 0, + left: 0, + backfaceVisibility: 'hidden' +})); + +const BackFaceContent = styled(Box)(({ 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' +})); + +const ProfileSection = styled(Box)({ + display: 'flex', + alignItems: 'center', + marginBottom: '16px' +}); + +const TechnologiesSection = styled(Box)(({ theme }) => ({ + backgroundColor: 'rgba(255, 255, 255, 0.25)', + padding: theme.spacing(1), + borderRadius: theme.shape.borderRadius, + marginBottom: '16px' +})); + +const UpdatedSection = styled(Box)({ + display: 'flex', + alignItems: 'center', + color: '#fff', + margin: '20px 0' +}); + const CatalogCard: React.FC = ({ pattern, patternType, @@ -77,57 +177,125 @@ const CatalogCard: React.FC = ({ cardWidth, cardStyles, cardLink, - version + version, + avatarUrl, + userName, + updatedAt, + technologies }) => { const outerStyles = { height: cardHeight, width: cardWidth, ...cardStyles }; + + const cardVersion = version || pattern?.userData?.version; + const cardAvatarUrl = avatarUrl || pattern?.userData?.avatarUrl; + const cardName = userName || pattern?.userData?.userName; + const cardTechnologies = technologies || pattern?.userData?.technologies; + const cardUpdatedAt = updatedAt || pattern?.userData?.updatedAt; + const date = cardUpdatedAt ? new Date(cardUpdatedAt) : null; + const options: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long', day: 'numeric' }; + const formattedDate = date ? date.toLocaleDateString('en-US', options) : 'N/A'; + return ( - - - - {version && v{version}} - {patternType} - - - {pattern.name} - - - - - - - - - {pattern.download_count} - - - - {pattern.clone_count} - - - - {pattern.view_count} - - - - {pattern.deployment_count} - - - - {pattern.share_count} - - - - + + + + + + + {/* {cardVersion && v{cardVersion}} */} + {patternType} + + + {pattern.name} + + + + + + + + + {pattern.download_count} + + + + {pattern.clone_count} + + + + {pattern.view_count} + + + + {pattern.deployment_count} + + + + {pattern.share_count} + + + + + + + + {cardAvatarUrl && ( + + + + {cardName} + + + )} + + {cardTechnologies && ( + + + Technologies + + + Kubernetes + + + )} + + {date && ( + + + + Updated At + + + {formattedDate} + + + )} + + {cardVersion && ( + + v{cardVersion} + + )} + + + + ); };