Skip to content

Commit 0120a96

Browse files
committed
updated template cards
1 parent 1a2f068 commit 0120a96

File tree

1 file changed

+78
-78
lines changed

1 file changed

+78
-78
lines changed

apps/framework-docs-v2/src/components/mdx/template-card.tsx

Lines changed: 78 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ import {
1111
CardFooter,
1212
CardHeader,
1313
} from "@/components/ui/card";
14-
import { IconBrandGithub, IconRocket } from "@tabler/icons-react";
14+
import { IconBrandGithub, IconRocket, IconBook } from "@tabler/icons-react";
1515
import { Button } from "@/components/ui/button";
16-
import { Separator } from "@/components/ui/separator";
1716
import {
1817
Snippet,
1918
SnippetCopyButton,
@@ -53,6 +52,7 @@ export function TemplateCard({ item, className }: TemplateCardProps) {
5352
const isTemplate = item.type === "template";
5453
const template = isTemplate ? (item as TemplateMetadata) : null;
5554
const app = !isTemplate ? (item as AppMetadata) : null;
55+
const [chipsExpanded, setChipsExpanded] = React.useState(false);
5656

5757
const categoryLabels = {
5858
starter: "Starter",
@@ -74,6 +74,17 @@ export function TemplateCard({ item, className }: TemplateCardProps) {
7474
const description = isTemplate ? template!.description : app!.description;
7575
const name = isTemplate ? template!.name : app!.name;
7676

77+
// Combine frameworks and features into a single array with type info
78+
const allChips = [
79+
...frameworks.map((f) => ({ value: f, type: "framework" as const })),
80+
...features.map((f) => ({ value: f, type: "feature" as const })),
81+
];
82+
83+
const MAX_VISIBLE_CHIPS = 3;
84+
const visibleChips =
85+
chipsExpanded ? allChips : allChips.slice(0, MAX_VISIBLE_CHIPS);
86+
const hiddenCount = allChips.length - MAX_VISIBLE_CHIPS;
87+
7788
return (
7889
<Card
7990
className={cn(
@@ -84,26 +95,63 @@ export function TemplateCard({ item, className }: TemplateCardProps) {
8495
<CardHeader>
8596
<div className="flex items-start justify-between gap-2">
8697
<div className="flex-1 min-w-0">
87-
<div className="flex items-center gap-2 mb-2">
88-
{language && (
89-
<Badge variant="secondary" className="text-xs">
90-
{language === "typescript" ? "TypeScript" : "Python"}
91-
</Badge>
92-
)}
93-
{isTemplate && template && (
94-
<Badge variant="outline" className="text-xs">
95-
{categoryLabels[template.category]}
96-
</Badge>
97-
)}
98-
{!isTemplate && (
99-
<Badge variant="outline" className="text-xs">
100-
Demo App
101-
</Badge>
102-
)}
98+
<div className="flex items-center gap-1 mb-2">
99+
{(() => {
100+
const labels: string[] = [];
101+
if (language) {
102+
labels.push(
103+
language === "typescript" ? "TypeScript" : "Python",
104+
);
105+
}
106+
if (isTemplate && template) {
107+
labels.push(categoryLabels[template.category]);
108+
}
109+
if (!isTemplate) {
110+
labels.push("Demo App");
111+
}
112+
return (
113+
<span className="text-xs text-muted-foreground">
114+
{labels.join(" • ")}
115+
</span>
116+
);
117+
})()}
103118
</div>
104119
<h3 className="text-xl text-foreground mb-1">
105120
{isTemplate ? formatTemplateName(name) : name}
106121
</h3>
122+
{allChips.length > 0 && (
123+
<div className="flex flex-wrap gap-1.5 justify-start w-full mt-2">
124+
{visibleChips.map((chip) => (
125+
<Badge
126+
key={`${chip.type}-${chip.value}`}
127+
variant={
128+
chip.type === "framework" ? "secondary" : "outline"
129+
}
130+
className="text-xs"
131+
>
132+
{chip.value}
133+
</Badge>
134+
))}
135+
{!chipsExpanded && hiddenCount > 0 && (
136+
<Badge
137+
variant="outline"
138+
className="text-xs cursor-pointer hover:bg-accent"
139+
onClick={() => setChipsExpanded(true)}
140+
>
141+
{hiddenCount} more
142+
</Badge>
143+
)}
144+
{chipsExpanded && (
145+
<Badge
146+
variant="outline"
147+
className="text-xs cursor-pointer hover:bg-accent"
148+
onClick={() => setChipsExpanded(false)}
149+
>
150+
Show less
151+
</Badge>
152+
)}
153+
</div>
154+
)}
107155
</div>
108156
</div>
109157
</CardHeader>
@@ -116,66 +164,6 @@ export function TemplateCard({ item, className }: TemplateCardProps) {
116164
)}
117165
</CardContent>
118166
<CardFooter className="flex flex-col gap-2 pt-4 w-full">
119-
{isTemplate && template && (
120-
<>
121-
{(frameworks.length > 0 || features.length > 0) && (
122-
<>
123-
<Separator className="my-2" />
124-
<div className="flex flex-wrap gap-1.5 justify-start w-full">
125-
{frameworks.map((framework) => (
126-
<Badge
127-
key={framework}
128-
variant="secondary"
129-
className="text-xs"
130-
>
131-
{framework}
132-
</Badge>
133-
))}
134-
{features.map((feature) => (
135-
<Badge key={feature} variant="outline" className="text-xs">
136-
{feature}
137-
</Badge>
138-
))}
139-
</div>
140-
</>
141-
)}
142-
</>
143-
)}
144-
{!isTemplate && app && (
145-
<>
146-
{app.blogPost && (
147-
<Link
148-
href={app.blogPost}
149-
target="_blank"
150-
rel="noopener noreferrer"
151-
className="text-xs text-muted-foreground hover:text-foreground flex items-center gap-1 w-full"
152-
>
153-
Read Blog Post →
154-
</Link>
155-
)}
156-
{app.blogPost && (frameworks.length > 0 || features.length > 0) && (
157-
<Separator className="my-2" />
158-
)}
159-
{(frameworks.length > 0 || features.length > 0) && (
160-
<div className="flex flex-wrap gap-1.5 justify-start w-full">
161-
{frameworks.map((framework) => (
162-
<Badge
163-
key={framework}
164-
variant="secondary"
165-
className="text-xs"
166-
>
167-
{framework}
168-
</Badge>
169-
))}
170-
{features.map((feature) => (
171-
<Badge key={feature} variant="outline" className="text-xs">
172-
{feature}
173-
</Badge>
174-
))}
175-
</div>
176-
)}
177-
</>
178-
)}
179167
<div className="flex w-full items-center justify-start gap-2 mt-auto pt-2">
180168
<Button variant="default" asChild>
181169
<Link
@@ -185,6 +173,18 @@ export function TemplateCard({ item, className }: TemplateCardProps) {
185173
Deploy
186174
</Link>
187175
</Button>
176+
{!isTemplate && app && app.blogPost && (
177+
<Button variant="outline" size="icon" asChild>
178+
<Link
179+
href={app.blogPost}
180+
target="_blank"
181+
rel="noopener noreferrer"
182+
aria-label="Read Blog Post"
183+
>
184+
<IconBook className="h-4 w-4" />
185+
</Link>
186+
</Button>
187+
)}
188188
<Button variant="outline" size="icon" asChild>
189189
<Link
190190
href={githubUrl}

0 commit comments

Comments
 (0)