Skip to content

Commit

Permalink
Merge pull request #762 from amitamrutiya/catalogcard
Browse files Browse the repository at this point in the history
Add new image and catalog empty card
  • Loading branch information
aabidsofi19 authored Oct 18, 2024
2 parents 21bed8a + 4bc1b00 commit bf8f47b
Show file tree
Hide file tree
Showing 18 changed files with 338 additions and 119 deletions.
7 changes: 2 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"access": "public"
},
"dependencies": {
"js-yaml": "^4.1.0",
"lodash": "^4.17.21"
}
}
95 changes: 95 additions & 0 deletions src/custom/CustomCatalog/CatalogCardDesignLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React, { useState } from 'react';
import { Dialog } from '../../base';
import { DesignIcon, MesheryFilterIcon } from '../../icons';

interface CatalogCardDesignLogoProps {
zoomEffect?: boolean;
imgURL?: string[];
type: { type: string };
width: string;
height: string;
style?: React.CSSProperties;
}

const CatalogCardDesignLogo: React.FC<CatalogCardDesignLogoProps> = ({
zoomEffect = false,
imgURL,
type,
width,
height,
style = {}
}) => {
const [imgError, setImgError] = useState(false);
const [isZoomed, setIsZoomed] = useState(false);

const handleZoomClick = () => {
if (zoomEffect) {
setIsZoomed(true);
}
};

const handleZoomClose = () => {
setIsZoomed(false);
};

const SvgComponent: React.FC<{ type: { type: string } }> = ({ type }) => {
return type.type === 'filter' ? (
<MesheryFilterIcon width={width} height={height} style={style} />
) : (
<DesignIcon width={width} height={height} style={style} />
);
};

return (
<>
{imgURL && imgURL.length > 0 ? (
<div style={{ width: '100%', height: '7.5rem', position: 'relative' }}>
{!imgError ? (
<>
<img
src={imgURL[0]}
alt="Design SnapShot"
loading="lazy"
onClick={handleZoomClick}
onError={() => setImgError(true)}
style={{
cursor: 'pointer',
width: '100%',
height: '100%',
objectFit: 'cover'
}}
/>
<Dialog
open={isZoomed}
onClose={handleZoomClose}
style={{
backgroundColor: 'rgba(0, 0, 0, 0.8)'
}}
PaperProps={{
style: {
background: 'transparent',
boxShadow: 'none',
overflow: 'hidden',
maxWidth: '60vw'
}
}}
>
<img
src={imgURL[0]}
alt="Zoomed Design SnapShot"
style={{ objectFit: 'contain', maxWidth: '100%', maxHeight: '100%' }}
/>
</Dialog>
</>
) : (
<SvgComponent type={type} />
)}
</div>
) : (
<SvgComponent type={type} />
)}
</>
);
};

export default CatalogCardDesignLogo;
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import { CloneIcon, CommunityClassIcon, OfficialClassIcon, OpenIcon, ShareIcon }
import VerificationClassIcon from '../../icons/ContentClassIcons/VerificationClassIcon';
import DeploymentsIcon from '../../icons/Deployments/DeploymentsIcon';
import { DownloadIcon } from '../../icons/Download';
import { DARK_TEAL, useTheme } from '../../theme';
import { SNOW_WHITE } from '../../theme/colors/colors';
import { CustomTooltip } from '../CustomTooltip';
import { getVersion, handleImage } from './Helper';
import {
CardBack,
CardFront,
Expand Down Expand Up @@ -35,7 +38,10 @@ export const DesignCardUrl = styled('a')(() => ({
textDecoration: 'none'
}));

interface Pattern {
export interface Pattern {
id: string;
user_id: string;
pattern_file: string;
name: string;
download_count: number;
clone_count: number;
Expand All @@ -51,8 +57,10 @@ interface Pattern {
};
catalog_data?: {
content_class?: string;
imageURL?: string;
imageURL?: string[];
compatibility?: string[];
published_version?: string;
type?: string;
};
visibility: string;
updated_at: Date;
Expand All @@ -61,21 +69,15 @@ interface Pattern {
type CatalogCardProps = {
pattern: Pattern;
patternType: string;
cardLink: string;
cardHeight: string;
cardWidth: string;
cardStyles: React.CSSProperties;
version?: string;
avatarUrl: string;
shouldFlip?: boolean;
cardTechnologies?: boolean;
isDetailed?: boolean;
cardAvatarUrl?: boolean;
date?: boolean;
cardVersion?: boolean;
UserName?: string;
children?: React.ReactNode; // catalogImage
TechnologyComponent?: React.ReactNode;
basePath?: string; // path of meshmodel img stored
subBasePath?: string; // path of meshmodel img stored
getHostUrl?: () => string;
Expand Down Expand Up @@ -109,7 +111,6 @@ const CustomCatalogCard: React.FC<CatalogCardProps> = ({
shouldFlip,
isDetailed,
cardTechnologies,
cardVersion,
avatarUrl,
UserName,
children,
Expand All @@ -123,45 +124,15 @@ const CustomCatalogCard: React.FC<CatalogCardProps> = ({
width: cardWidth,
...cardStyles
};
const theme = useTheme();

const technologies = pattern.catalog_data?.compatibility || []; // an array
const technologies = pattern.catalog_data?.compatibility || [];
const techlimit = 5;
const [availableTechnologies, setAvailableTechnologies] = useState<string[]>([]);
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);
};
const version = getVersion(pattern);

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()}/${subBasePath}/${technology.toLowerCase()}-color.svg`;
const isSvgPathValid = await checkImageUrlValidity(svgIconPath as string);
if (isSvgPathValid) {
validSvgPaths.push(technology);
}
}

setAvailableTechnologies(validSvgPaths);
};
useEffect(() => {
handleImage();
handleImage(technologies, basePath, subBasePath, setAvailableTechnologies);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

Expand Down Expand Up @@ -196,7 +167,8 @@ const CustomCatalogCard: React.FC<CatalogCardProps> = ({
<DesignDetailsDiv>
<div
style={{
background: 'rgba(231, 239, 243, 0.40)',
background:
theme.palette.mode === 'light' ? 'rgba(231, 239, 243, 0.4)' : 'transparent',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
Expand All @@ -210,26 +182,22 @@ const CustomCatalogCard: React.FC<CatalogCardProps> = ({
</DesignDetailsDiv>
{isDetailed && (
<MetricsContainerFront isDetailed={isDetailed}>
<MetricsDiv>
<DownloadIcon width={18} height={18} />
<MetricsCount>{pattern.download_count}</MetricsCount>
</MetricsDiv>
<MetricsDiv>
<CloneIcon width={18} height={18} fill={'#51636B'} />
<MetricsCount>{pattern.clone_count}</MetricsCount>
</MetricsDiv>
<MetricsDiv>
<OpenIcon width={18} height={18} fill={'#51636B'} />
<MetricsCount>{pattern.view_count}</MetricsCount>
</MetricsDiv>
<MetricsDiv>
<DeploymentsIcon width={18} height={18} />
<MetricsCount>{pattern.deployment_count}</MetricsCount>
</MetricsDiv>
<MetricsDiv>
<ShareIcon width={18} height={18} fill={'#51636B'} />
<MetricsCount>{pattern.share_count}</MetricsCount>
</MetricsDiv>
{[
{ Icon: DownloadIcon, count: pattern.download_count },
{ Icon: CloneIcon, count: pattern.clone_count },
{ Icon: OpenIcon, count: pattern.view_count },
{ Icon: DeploymentsIcon, count: pattern.deployment_count },
{ Icon: ShareIcon, count: pattern.share_count }
].map(({ Icon, count }, index) => (
<MetricsDiv key={index}>
<Icon
width={18}
height={18}
fill={theme.palette.mode === 'light' ? DARK_TEAL : SNOW_WHITE}
/>
<MetricsCount>{count}</MetricsCount>
</MetricsDiv>
))}
</MetricsContainerFront>
)}
</CardFront>
Expand Down Expand Up @@ -335,9 +303,9 @@ const CustomCatalogCard: React.FC<CatalogCardProps> = ({
</Grid>
</DesignDetailsDiv>
)}
{cardVersion && (
{version && (
<VersionDiv>
<VersionText>v{cardVersion}</VersionText>
<VersionText>v{version}</VersionText>
</VersionDiv>
)}
</CardBack>
Expand Down
16 changes: 16 additions & 0 deletions src/custom/CustomCatalog/EmptyStateCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { FC } from 'react';
import { EmptyStyleIcon } from '../../icons/EmptyStyle';
import { useTheme } from '../../theme';
import { CatalogEmptyStateDiv } from './style';

const EmptyStateCard: FC = () => {
const theme = useTheme();
return (
<CatalogEmptyStateDiv>
<EmptyStyleIcon fill={theme.palette.text.default} width="100px" height="100px" />
<h3 style={{ color: theme.palette.text.default }}>No match found</h3>
</CatalogEmptyStateDiv>
);
};

export default EmptyStateCard;
Loading

0 comments on commit bf8f47b

Please sign in to comment.