Skip to content

Commit 4b828a9

Browse files
committed
update grouping
1 parent 32d7ab0 commit 4b828a9

File tree

3 files changed

+105
-8
lines changed

3 files changed

+105
-8
lines changed

components/techstack/stackitem.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,24 @@ export default function StackItem({
3333
showLogo = false,
3434
showText = true
3535
}: StackItemProps) {
36-
// Construct the full logo path using the title as subdirectory
37-
const titleLower = title ? title.toLowerCase().replace(/\s+/g, '-') : '';
38-
const fullLogoPath = showLogo && id && titleLower ? `https://camel-ai.github.io/camel_asset/logos/${titleLower}/${id}.svg` : null;
36+
// Map section titles to directory names
37+
const getLogoPath = (sectionTitle: string) => {
38+
const titleMap: { [key: string]: string } = {
39+
'Models': 'models',
40+
'Tools': 'tools',
41+
'Storage': 'storage',
42+
'Data Loaders': 'loaders',
43+
'Interpreters': 'interpreters',
44+
'Run Time': 'run-time',
45+
'Human in the Loop': 'human-in-the-loop',
46+
'Observe': 'observe'
47+
};
48+
return titleMap[sectionTitle] || sectionTitle.toLowerCase().replace(/\s+/g, '-');
49+
};
50+
51+
// Construct the full logo path using the mapped directory name
52+
const logoDir = title ? getLogoPath(title) : '';
53+
const fullLogoPath = showLogo && id && logoDir ? `https://camel-ai.github.io/camel_asset/logos/${logoDir}/${id}.svg` : null;
3954

4055
// Special styling for logo-only items
4156
const isLogoOnly = showLogo && !showText;

components/techstack/stacksection.tsx

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export interface StackItemData {
66
name: string
77
logo?: boolean
88
showText?: boolean
9+
subcategory?: string
910
onClick?: () => void
1011
}
1112

@@ -15,6 +16,7 @@ export interface StackSectionProps {
1516
items: StackItemData[]
1617
variant?: 'neon' | 'green' | 'yellow' | 'purple' | 'pink' | 'orange' | 'grey' | 'blue' | 'red' | 'bone'
1718
className?: string
19+
grouped?: boolean
1820
}
1921

2022
const backgroundColorVariants = {
@@ -43,13 +45,82 @@ const borderColorVariants = {
4345
bone: 'border-bone-700'
4446
}
4547

48+
// Group items by subcategory
49+
const groupItemsBySubcategory = (items: StackItemData[]) => {
50+
const groups: { [key: string]: StackItemData[] } = {};
51+
52+
items.forEach(item => {
53+
const subcategory = item.subcategory || 'Other';
54+
if (!groups[subcategory]) {
55+
groups[subcategory] = [];
56+
}
57+
groups[subcategory].push(item);
58+
});
59+
60+
return groups;
61+
};
62+
4663
export default function StackSection({
4764
title,
4865
subtitle,
4966
items,
5067
variant = 'neon',
51-
className = ''
68+
className = '',
69+
grouped = false
5270
}: StackSectionProps) {
71+
// If grouped is true, render grouped layout
72+
if (grouped) {
73+
const groupedItems = groupItemsBySubcategory(items);
74+
const subcategories = Object.keys(groupedItems);
75+
76+
return (
77+
<div className={`flex flex-col lg:flex-row py-4 ${className}`}>
78+
{/* Title Section */}
79+
<div className={`lg:w-1/5 flex-shrink-0 pt-4 border-t ${borderColorVariants[variant]}`}>
80+
<h3 className={`font-palatino text-2xl font-bold text-black-900 mb-2`}>
81+
{title}
82+
</h3>
83+
{subtitle && (
84+
<p className="text-black-700 text-sm font-palatino">
85+
{subtitle}
86+
</p>
87+
)}
88+
</div>
89+
90+
{/* Grouped Items Layout */}
91+
<div className="lg:w-4/5 flex-1">
92+
<div className={`border border-white rounded-tr-xl backdrop-blur-sm rounded-b-xl p-4 ${backgroundColorVariants[variant]}`}>
93+
{subcategories.map((subcategory, groupIndex) => (
94+
<div key={subcategory} className={`${groupIndex > 0 ? 'mt-6 pt-6 border-t border-white/20' : ''}`}>
95+
{/* Subcategory Title */}
96+
<h4 className="font-palatino text-lg font-bold text-black-800 mb-3">
97+
{subcategory}
98+
</h4>
99+
{/* Items in this subcategory */}
100+
<div className="flex flex-wrap gap-4">
101+
{groupedItems[subcategory].map((item) => (
102+
<StackItem
103+
key={item.id}
104+
variant={variant}
105+
onClick={item.onClick}
106+
id={item.id}
107+
title={title}
108+
showLogo={item.logo || false}
109+
showText={item.showText !== false}
110+
>
111+
{item.name}
112+
</StackItem>
113+
))}
114+
</div>
115+
</div>
116+
))}
117+
</div>
118+
</div>
119+
</div>
120+
);
121+
}
122+
123+
// Original non-grouped layout
53124
return (
54125
<div className={`flex flex-col lg:flex-row py-4 ${className}`}>
55126
{/* Title Section */}
@@ -94,6 +165,7 @@ export const createStackSection = (
94165
subtitle?: string
95166
variant?: StackSectionProps['variant']
96167
onItemClick?: (itemName: string, index: number) => void
168+
grouped?: boolean
97169
}
98170
): StackSectionProps => {
99171
const stackItems: StackItemData[] = items.map((item, index) => {
@@ -111,6 +183,7 @@ export const createStackSection = (
111183
title,
112184
subtitle: options?.subtitle,
113185
items: stackItems,
114-
variant: options?.variant || 'neon'
186+
variant: options?.variant || 'neon',
187+
grouped: options?.grouped || false
115188
}
116189
}

techstack/techstack.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ function TechStackContent() {
3535
}))
3636
};
3737

38+
const storageData = {
39+
...storage,
40+
items: storage.items.map(item => ({
41+
...item,
42+
onClick: () => handleItemClick(item)
43+
}))
44+
};
45+
3846

3947
return (
4048
<div className="flex-1 w-full max-w-[1200px] mx-auto py-8">
@@ -79,9 +87,10 @@ function TechStackContent() {
7987
/>
8088
{/* Storage Section */}
8189
<StackSection
82-
title={storage.title}
83-
items={storage.items}
84-
variant={storage.variant as "orange"}
90+
title={storageData.title}
91+
items={storageData.items}
92+
variant={storageData.variant as "orange"}
93+
grouped={true}
8594
/>
8695
{/* Data Loaders Section */}
8796
<StackSection

0 commit comments

Comments
 (0)