first commit
This commit is contained in:
94
src/components/ProjectCard.astro
Normal file
94
src/components/ProjectCard.astro
Normal file
@@ -0,0 +1,94 @@
|
||||
---
|
||||
import type { Project } from '../content/schemas';
|
||||
|
||||
interface Props {
|
||||
project: Project;
|
||||
}
|
||||
const { project } = Astro.props;
|
||||
const isArchived = project.status === 'archived';
|
||||
const isPrivate = project.status === 'private';
|
||||
const isWIP = project.status === 'wip';
|
||||
const statusLabel =
|
||||
project.status === 'live'
|
||||
? 'Live'
|
||||
: project.status === 'archived'
|
||||
? 'Archivé'
|
||||
: project.status === 'private'
|
||||
? 'Privé'
|
||||
: 'WIP';
|
||||
|
||||
const Tag = project.url && !isArchived && !isPrivate ? 'a' : 'div';
|
||||
const tagProps = project.url && !isArchived && !isPrivate
|
||||
? { href: project.url, target: '_blank', rel: 'noopener noreferrer' }
|
||||
: {};
|
||||
---
|
||||
|
||||
<Tag
|
||||
{...tagProps}
|
||||
class:list={[
|
||||
'group card-neon block h-full overflow-hidden',
|
||||
isArchived && 'opacity-70',
|
||||
]}
|
||||
>
|
||||
<div class="relative aspect-[16/9] -mx-6 -mt-6 mb-4 overflow-hidden bg-[color:var(--color-bg)]">
|
||||
{project.image ? (
|
||||
<img
|
||||
src={project.image}
|
||||
alt={project.title}
|
||||
class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
||||
class:list={[isArchived && 'grayscale']}
|
||||
/>
|
||||
) : (
|
||||
<div class="w-full h-full flex items-center justify-center text-[color:var(--color-text-dim)] font-mono text-xs aurora-bg">
|
||||
// no preview
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div class="absolute top-3 right-3 flex gap-2">
|
||||
<span
|
||||
class:list={[
|
||||
'text-[10px] font-mono uppercase tracking-wider px-2 py-1 rounded-sm border backdrop-blur-md',
|
||||
project.status === 'live' && 'border-[color:var(--color-cyan)] text-[color:var(--color-cyan)] bg-[rgba(0,240,255,0.1)]',
|
||||
project.status === 'archived' && 'border-[color:var(--color-text-dim)] text-[color:var(--color-text-dim)] bg-[rgba(0,0,0,0.5)]',
|
||||
project.status === 'private' && 'border-[color:var(--color-magenta)] text-[color:var(--color-magenta)] bg-[rgba(255,42,109,0.1)]',
|
||||
project.status === 'wip' && 'border-[color:var(--color-violet)] text-[color:var(--color-violet)] bg-[rgba(185,103,255,0.1)]',
|
||||
]}
|
||||
>
|
||||
{statusLabel}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="font-display text-lg mb-1 text-[color:var(--color-text)] group-hover:glow-text-cyan group-hover:text-[color:var(--color-cyan)] transition-colors">
|
||||
{project.title}
|
||||
</h3>
|
||||
{project.subtitle && (
|
||||
<p class="text-xs font-mono text-[color:var(--color-text-dim)] mb-3 uppercase tracking-wider">
|
||||
{project.subtitle}
|
||||
</p>
|
||||
)}
|
||||
<p class="text-sm text-[color:var(--color-text-muted)] mb-4 line-clamp-3">
|
||||
{project.description}
|
||||
</p>
|
||||
|
||||
{project.stack.length > 0 && (
|
||||
<div class="flex flex-wrap gap-1.5 mb-4">
|
||||
{project.stack.slice(0, 5).map((tech) => (
|
||||
<span class="chip">{tech}</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{project.url && !isArchived && !isPrivate && (
|
||||
<span class="text-xs font-mono text-[color:var(--color-cyan)] group-hover:underline">
|
||||
→ Voir le projet
|
||||
</span>
|
||||
)}
|
||||
{isArchived && (
|
||||
<span class="text-xs font-mono text-[color:var(--color-text-dim)]">
|
||||
// projet fermé
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</Tag>
|
||||
Reference in New Issue
Block a user