91 lines
1.8 KiB
Vue
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>
|