Skip to content

Commit 3964d6e

Browse files
committed
feat(ProjectCard): integrate image gallery and add private project indicator
- Add ImageGallery component to display thumbnails - Make project title clickable to open gallery when images exist - Add 'Private' badge for projects without public links - Accept id prop for gallery integration - Conditionally render links section only when links exist
1 parent 95f3ed7 commit 3964d6e

1 file changed

Lines changed: 29 additions & 3 deletions

File tree

src/components/ProjectCard.astro

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
---
22
import SocialIcon from '@components/SocialIcon.astro';
3+
import ImageGallery from '@components/ImageGallery.astro';
34
45
interface Props {
56
title: string;
67
description: string;
78
category: string;
89
tech: string[];
910
image?: string;
11+
images?: string[];
1012
links?: {
1113
website?: string;
1214
github?: string;
1315
blog?: string;
1416
};
17+
id: string;
1518
}
1619
17-
const { title, description, category, tech, image, links } = Astro.props;
20+
const { title, description, category, tech, image, images, links, id } = Astro.props;
1821
1922
const categoryIcons: Record<string, string> = {
2023
Product: '🚀',
@@ -23,6 +26,9 @@ const categoryIcons: Record<string, string> = {
2326
Tool: '🛠️',
2427
Fun: '🎮',
2528
};
29+
30+
const hasLinks = links && (links.website || links.github || links.blog);
31+
const isPrivate = !hasLinks;
2632
---
2733

2834
<article class="card group">
@@ -39,16 +45,36 @@ const categoryIcons: Record<string, string> = {
3945
<div class="flex items-center gap-2 mb-3">
4046
<span class="text-2xl">{categoryIcons[category] || '📦'}</span>
4147
<span class="text-sm font-medium text-[var(--color-text-muted)]">{category}</span>
48+
{isPrivate && (
49+
<span class="ml-auto px-2 py-1 text-xs font-medium bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-400 rounded inline-flex items-center gap-1">
50+
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
51+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path>
52+
</svg>
53+
Private
54+
</span>
55+
)}
4256
</div>
4357

4458
<h3 class="text-xl font-bold mb-2 group-hover:text-primary-600 transition-colors">
45-
{title}
59+
{images && images.length > 0 ? (
60+
<button
61+
type="button"
62+
class="text-left hover:text-primary-600 transition-colors cursor-pointer"
63+
onclick={`openImageGallery('${id}', 0)`}
64+
>
65+
{title}
66+
</button>
67+
) : (
68+
title
69+
)}
4670
</h3>
4771

4872
<p class="text-[var(--color-text-muted)] mb-4">
4973
{description}
5074
</p>
5175

76+
<ImageGallery images={images || []} title={title} projectId={id} />
77+
5278
<div class="flex flex-wrap gap-2 mb-4">
5379
{tech.map((t) => (
5480
<span class="px-2 py-1 text-xs font-medium bg-slate-100 dark:bg-slate-800 text-[var(--color-text-base)] rounded">
@@ -57,7 +83,7 @@ const categoryIcons: Record<string, string> = {
5783
))}
5884
</div>
5985

60-
{links && (
86+
{hasLinks && (
6187
<div class="flex items-center gap-3">
6288
{links.website && (
6389
<a

0 commit comments

Comments
 (0)