Skip to content

Commit

Permalink
Merge pull request #933 from FaheemOnHub/fix/faheemonhub/update-meshe…
Browse files Browse the repository at this point in the history
…ry-cloud-design

feat: add similar design by type
  • Loading branch information
amitamrutiya authored Mar 4, 2025
2 parents 2e91d50 + aa248b4 commit eb85e4c
Showing 10 changed files with 192 additions and 63 deletions.
57 changes: 57 additions & 0 deletions src/custom/CatalogDetail/Carousel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { ChevronLeft, ChevronRight } from '@mui/icons-material';
import React, { ReactNode, useRef } from 'react';

interface CarouselProps {
items: ReactNode[];
title?: string;
scrollAmount?: number;
showNavButtons?: boolean;
itemClassName?: string;
}

import { CarouselButton, CarouselContainer, CarouselWrapper } from './style';

const Carousel: React.FC<CarouselProps> = ({
items,
scrollAmount = 300,
showNavButtons = true,
itemClassName = 'carousel-item'
}) => {
const carouselRef = useRef<HTMLDivElement>(null);

// Skip rendering if no items
if (!items.length) return null;

const scroll = (direction: 'left' | 'right') => {
if (carouselRef.current) {
carouselRef.current.scrollBy({
left: direction === 'left' ? -scrollAmount : scrollAmount,
behavior: 'smooth'
});
}
};

return (
<CarouselWrapper>
{showNavButtons && (
<CarouselButton onClick={() => scroll('left')}>
<ChevronLeft />
</CarouselButton>
)}
<CarouselContainer ref={carouselRef}>
{items.map((item, index) => (
<div key={`carousel-item-${index}`} className={itemClassName}>
{item}
</div>
))}
</CarouselContainer>
{showNavButtons && (
<CarouselButton onClick={() => scroll('right')}>
<ChevronRight />
</CarouselButton>
)}
</CarouselWrapper>
);
};

export default Carousel;
77 changes: 44 additions & 33 deletions src/custom/CatalogDetail/RelatedDesigns.tsx
Original file line number Diff line number Diff line change
@@ -1,72 +1,83 @@
import { CatalogCardDesignLogo } from '../CustomCatalog';
import CustomCatalogCard, { Pattern } from '../CustomCatalog/CustomCard';
import Carousel from './Carousel';
import { getHeadingText } from './helper';
import { AdditionalContainer, ContentHeading, DesignCardContainer } from './style';
import { AdditionalContainer, ContentHeading } from './style';
import { UserProfile } from './types';

export interface PatternsPerUser {
patterns: Pattern[];
}

export interface DetailsByType {
patterns: Pattern[];
}
interface RelatedDesignsProps {
details: Pattern;
type: string;
patternsPerUser: PatternsPerUser;
detailsByType?: DetailsByType;
onSuggestedPatternClick: (pattern: Pattern) => void;
userProfile?: UserProfile;
technologySVGPath: string;
technologySVGSubpath: string;
orgName: string;
fetchingOrgError: boolean;
filterByType?: boolean;
}

const RelatedDesigns: React.FC<RelatedDesignsProps> = ({
details,
type,
patternsPerUser,
detailsByType,
onSuggestedPatternClick,
userProfile,
technologySVGPath,
technologySVGSubpath,
orgName,
fetchingOrgError
fetchingOrgError,
filterByType
}) => {
const filteredPatternsPerUser = patternsPerUser?.patterns?.filter(
(pattern) => pattern.id !== details.id
);
const filteredPatterns = filterByType
? detailsByType?.patterns?.filter((pattern) => pattern.id !== details.id) || []
: patternsPerUser?.patterns?.filter((pattern) => pattern.id !== details.id) || [];

if (!filteredPatterns.length) return null;
const organizationName = filterByType
? 'Similar Designs by Type'
: fetchingOrgError || !orgName
? 'Unknown Organization'
: orgName;

if (!filteredPatternsPerUser?.length) return null;
const organizationName = fetchingOrgError || !orgName ? 'Unknown Organization' : orgName;
const carouselItems = filteredPatterns.map((pattern) => (
<CustomCatalogCard
pattern={pattern}
patternType={type}
onCardClick={() => onSuggestedPatternClick(pattern)}
UserName={`${userProfile?.first_name ?? ''} ${userProfile?.last_name ?? ''}`}
avatarUrl={userProfile?.avatar_url}
basePath={technologySVGPath}
subBasePath={technologySVGSubpath}
cardTechnologies={true}
>
<CatalogCardDesignLogo
imgURL={pattern?.catalog_data?.imageURL}
height={'5.5rem'}
width={'100%'}
zoomEffect={false}
type={{ type: type }}
/>
</CustomCatalogCard>
));
return (
<AdditionalContainer>
<ContentHeading>
<h2 style={{ margin: '0', textTransform: 'uppercase' }}>
{getHeadingText({ type, userProfile, organizationName, fetchingOrgError })}
{filterByType
? organizationName
: getHeadingText({ type, userProfile, organizationName, fetchingOrgError })}
</h2>
</ContentHeading>
<DesignCardContainer>
{filteredPatternsPerUser.map((pattern, index) => (
<CustomCatalogCard
key={`design-${index}`}
pattern={pattern}
patternType={type}
onCardClick={() => onSuggestedPatternClick(pattern)}
UserName={`${userProfile?.first_name ?? ''} ${userProfile?.last_name ?? ''}`}
avatarUrl={userProfile?.avatar_url}
basePath={technologySVGPath}
subBasePath={technologySVGSubpath}
cardTechnologies={true}
>
<CatalogCardDesignLogo
imgURL={pattern?.catalog_data?.imageURL}
height={'7.5rem'}
width={'100%'}
zoomEffect={false}
type={{ type: type }}
/>
</CustomCatalogCard>
))}
</DesignCardContainer>
<Carousel items={carouselItems} scrollAmount={300} />
</AdditionalContainer>
);
};
21 changes: 19 additions & 2 deletions src/custom/CatalogDetail/RightPanel.tsx
Original file line number Diff line number Diff line change
@@ -3,11 +3,12 @@ import { Pattern } from '../CustomCatalog/CustomCard';
import { VIEW_VISIBILITY } from '../VisibilityChipMenu/VisibilityChipMenu';
import CaveatsSection from './CaveatsSection';
import OverviewSection from './OverviewSection';
import RelatedDesigns, { PatternsPerUser } from './RelatedDesigns';
import RelatedDesigns, { DetailsByType, PatternsPerUser } from './RelatedDesigns';
import { Class } from './types';

interface RightPanelProps {
details: Pattern;
detailsByType: DetailsByType;
type: string;
cardId?: string;
title: string;
@@ -35,6 +36,7 @@ interface RightPanelProps {

const RightPanel: React.FC<RightPanelProps> = ({
details,
detailsByType,
type,
cardId = details.id,
title,
@@ -64,7 +66,7 @@ const RightPanel: React.FC<RightPanelProps> = ({
});

return (
<div style={{ fontFamily }}>
<div>
<OverviewSection
details={details}
type={cleanedType}
@@ -86,6 +88,7 @@ const RightPanel: React.FC<RightPanelProps> = ({
{showCaveats && <CaveatsSection details={details} />}
<RelatedDesigns
details={details}
detailsByType={detailsByType}
orgName={orgName}
fetchingOrgError={fetchingOrgError}
type={type}
@@ -94,6 +97,20 @@ const RightPanel: React.FC<RightPanelProps> = ({
userProfile={userProfile}
technologySVGPath={technologySVGPath}
technologySVGSubpath={technologySVGSubpath}
filterByType={false}
/>
<RelatedDesigns
details={details}
detailsByType={detailsByType}
orgName={orgName}
fetchingOrgError={fetchingOrgError}
type={type}
patternsPerUser={patternsPerUser}
onSuggestedPatternClick={onSuggestedPatternClick}
userProfile={userProfile}
technologySVGPath={technologySVGPath}
technologySVGSubpath={technologySVGSubpath}
filterByType={true}
/>
</div>
);
45 changes: 45 additions & 0 deletions src/custom/CatalogDetail/style.tsx
Original file line number Diff line number Diff line change
@@ -68,6 +68,51 @@ export const ContentHeading = styled('div')(() => ({
width: '100%',
marginBottom: '1rem'
}));
export const CarouselContainer = styled('div')({
display: 'flex',
overflowX: 'auto',
scrollBehavior: 'smooth',
scrollSnapType: 'x mandatory',
gap: '1rem',
padding: '1rem 0',
width: '100%',
'&::-webkit-scrollbar': {
display: 'none' // Hide scrollbar for a cleaner look
},
'.carousel-item': {
flex: '0 0 auto',
scrollSnapAlign: 'center',
width: 'auto' // Adjust based on your card size
}
});
export const CarouselButton = styled('button')(({ theme }) => ({
position: 'absolute',
top: '50%',
transform: 'translateY(-50%)',
zIndex: '1',
background: theme.palette.background.paper,
border: 'none',
cursor: 'pointer',
padding: '0.5rem',
borderRadius: '50%',
boxShadow: '0 2px 4px rgba(0, 0, 0, 0.2)',
'&:hover': {
background: theme.palette.primary.main,
color: '#fff'
},
'&:first-of-type': {
left: '-1.2rem'
},
'&:last-of-type': {
right: '-1.2rem'
}
}));
export const CarouselWrapper = styled('div')({
display: 'flex',
alignItems: 'center',
width: '100%',
position: 'relative'
});

export const CaveatsContainer = styled('div')(({ theme }) => ({
width: '100%',
4 changes: 2 additions & 2 deletions src/custom/CustomCatalog/CustomCard.tsx
Original file line number Diff line number Diff line change
@@ -114,7 +114,7 @@ const ClassWrap = ({ catalogClassName }: { catalogClassName: string }) => {
const CustomCatalogCard: React.FC<CatalogCardProps> = ({
pattern,
patternType,
cardHeight = '18rem',
cardHeight = '16.5rem',
cardWidth = '15rem',
cardStyles,
shouldFlip = true,
@@ -280,7 +280,7 @@ const CustomCatalogCard: React.FC<CatalogCardProps> = ({
</DesignDetailsDiv>

{isDetailed && (
<DesignDetailsDiv style={{ marginTop: '40px' }}>
<DesignDetailsDiv style={{ marginTop: '20px' }}>
<Grid container style={{ justifyContent: 'space-between', alignItems: 'center' }}>
<Grid
item
2 changes: 1 addition & 1 deletion src/custom/CustomCatalog/Helper.ts
Original file line number Diff line number Diff line change
@@ -61,7 +61,7 @@ export const handleImage = async ({
export const DEFAULT_DESIGN_VERSION = '0.0.0';

export const getVersion = (design: Pattern) => {
if (design.visibility === 'published') {
if (design.visibility === 'public') {
return design?.catalog_data?.published_version || DEFAULT_DESIGN_VERSION;
}
try {
4 changes: 2 additions & 2 deletions src/custom/CustomCatalog/style.tsx
Original file line number Diff line number Diff line change
@@ -93,7 +93,7 @@ export const DesignCard = styled('div')<DesignCardProps>(
}),
...(isDetailed && {
[theme.breakpoints.down('lg')]: {
height: '18.75rem'
height: '16.75rem'
}
}),
...outerStyles
@@ -150,7 +150,7 @@ export const DesignName = styled(Typography)(({ theme }) => ({
textOverflow: 'ellipsis',
textAlign: 'center',
width: '100%',
margin: '3rem 0 1.59rem 0',
margin: '2rem 0 1.59rem 0',
fontFamily: 'inherit'
}));

5 changes: 3 additions & 2 deletions src/custom/PerformersSection/PerformersToogleButton.tsx
Original file line number Diff line number Diff line change
@@ -21,13 +21,14 @@ const PerformersSectionButton: React.FC<PerformersSectionButtonProps> = ({ open,
onClick={handleClick}
sx={{
height: '3.7rem',
padding: '0rem'
padding: '0.3rem'
}}
style={{
backgroundColor: open ? undefined : theme.palette.background.constant?.disabled
}}
>
<TropyIcon style={{ height: '2rem', width: '2rem' }} />
<TropyIcon style={{ height: '2rem', width: '2rem', marginRight: '10px' }} />
{open ? 'Hide Performers' : 'Show Performers'}
</Button>
</span>
</CustomTooltip>
Loading
Oops, something went wrong.

0 comments on commit eb85e4c

Please sign in to comment.