simon-einzinger.de/docs/.vitepress/theme/layout/CVProjectCard.vue
2025-01-29 22:02:53 +01:00

91 lines
1.8 KiB
Vue

<script setup lang="ts">
interface ProjectLink {
label: string;
url: string;
}
interface ProjectItemData {
title?: string;
excerpt?: string;
links?: ProjectLink[];
technologies?: string[];
}
const props = defineProps<{ item: ProjectItemData }>();
</script>
<template>
<div class="card card-lift card-gradient-border">
<div class="card-content">
<!-- Header row: Title on left, Links on right -->
<div class="card-header project-header">
<h3 class="card-title">
{{ props.item.title || "Untitled Project" }}
</h3>
<div
class="project-links"
v-if="props.item.links && props.item.links.length"
>
<a
v-for="link in props.item.links"
:key="link.url"
:href="link.url"
target="_blank"
rel="noopener"
>
{{ link.label }}
</a>
</div>
</div>
<p
v-if="props.item.excerpt"
class="card-excerpt project-excerpt"
v-html="props.item.excerpt"
></p>
<div
class="project-technologies"
v-if="props.item.technologies && props.item.technologies.length"
>
{{ props.item.technologies.join(" · ") }}
</div>
</div>
</div>
</template>
<style scoped>
.project-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.project-links {
display: flex;
flex-wrap: wrap;
gap: 1em;
}
.project-links a {
color: var(--highlight-color);
text-decoration: none;
font-weight: var(--font-weight-bold);
transition: color 0.3s;
}
.project-links a:hover {
color: var(--primary-color);
}
.project-excerpt {
color: var(--text-color);
}
.project-technologies {
margin-top: 1em;
font-size: 0.9em;
color: var(--secondary-text-color);
text-align: center;
}
</style>