173 lines
4.3 KiB
Vue
173 lines
4.3 KiB
Vue
<script setup lang="ts">
|
|
import FixedLayout from '~/components/layouts/FixedLayout.vue';
|
|
import TableHeader from '~/components/parts/TableHeader.vue';
|
|
import api from '~/composables/api'
|
|
|
|
const { get, post } = api();
|
|
const { locale } = useI18n();
|
|
const { t } = useI18n();
|
|
|
|
// Move useAsyncData to top level — NOT inside onMounted
|
|
const { data: markdown } = await useAsyncData(`fixed-root`, async () =>
|
|
await queryCollection(`fixed`).path(`/fixed/${locale.value}/root`).first()
|
|
,{watch: [locale]})
|
|
|
|
const { data: projects } = await useAsyncData(`projects`, async () =>
|
|
(await queryCollection(`projects`).where('path', 'LIKE', `/projects/${locale.value}/%`).all())
|
|
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()),
|
|
{ watch: [locale] })
|
|
|
|
onMounted(async () => {
|
|
try {
|
|
const response = await get('/test');
|
|
} catch (error) {
|
|
console.error('API Error:', error);
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<TableHeader></TableHeader>
|
|
|
|
<FixedLayout>
|
|
<Container>
|
|
<ContentRenderer v-if="markdown" :value="markdown"></ContentRenderer>
|
|
|
|
<section class="projects-section" v-if="projects && projects.length > 0">
|
|
<h2 class="section-title">{{ t('pages.projects_heading') }}</h2>
|
|
<div class="projects-grid">
|
|
<div
|
|
v-for="project in projects"
|
|
:key="project.slug"
|
|
class="project-card"
|
|
>
|
|
<span class="project-card-corner tl"></span>
|
|
<span class="project-card-corner tr"></span>
|
|
<span class="project-card-corner bl"></span>
|
|
<span class="project-card-corner br"></span>
|
|
|
|
<a
|
|
:href="project.link"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
class="project-title"
|
|
>{{ project.title }}</a>
|
|
<p class="project-description">{{ project.description }}</p>
|
|
<div class="project-tech">
|
|
<span v-for="tech in project.tech" :key="tech" class="tech-tag">{{ tech }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</Container>
|
|
</FixedLayout>
|
|
<Footer></Footer>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.projects-section {
|
|
margin-top: 24px;
|
|
}
|
|
|
|
.section-title {
|
|
font-family: 'Hurmit', monospace;
|
|
color: var(--color-text);
|
|
font-size: 1.3rem;
|
|
letter-spacing: 0.5px;
|
|
margin-bottom: 16px;
|
|
border-left: 3px solid var(--color-link);
|
|
padding-left: 12px;
|
|
|
|
&::after {
|
|
content: '';
|
|
display: inline-block;
|
|
width: 8px;
|
|
height: 8px;
|
|
background-color: var(--color-link);
|
|
margin-left: 6px;
|
|
vertical-align: middle;
|
|
box-shadow: 0 0 6px var(--color-link);
|
|
}
|
|
}
|
|
|
|
.projects-grid {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
}
|
|
|
|
.project-card {
|
|
position: relative;
|
|
background: var(--color-background-fore);
|
|
border: 1px solid var(--color-border-color);
|
|
box-shadow: 4px -4px 0px 0px var(--color-container-shadow);
|
|
padding: 12px 16px;
|
|
}
|
|
|
|
.project-card-corner {
|
|
position: absolute;
|
|
width: 14px;
|
|
height: 14px;
|
|
border-color: #cfcfcf;
|
|
|
|
&.tl { top: -1px; left: -1px; border-top: 2px solid; border-left: 2px solid; }
|
|
&.tr { top: -1px; right: -1px; border-top: 2px solid; border-right: 2px solid; }
|
|
&.bl { bottom: -1px; left: -1px; border-bottom: 2px solid; border-left: 2px solid; }
|
|
&.br { bottom: -1px; right: -1px; border-bottom: 2px solid; border-right: 2px solid; }
|
|
}
|
|
|
|
.project-title {
|
|
font-family: 'Hurmit', monospace;
|
|
color: var(--color-link);
|
|
text-decoration: none;
|
|
font-size: 1.05rem;
|
|
text-shadow: 0 0 6px var(--color-link);
|
|
display: block;
|
|
|
|
&:hover {
|
|
color: var(--color-link);
|
|
text-shadow: 0 0 12px var(--color-link), 0 0 4px var(--color-link);
|
|
}
|
|
}
|
|
|
|
.project-description {
|
|
font-family: 'Hurmit', monospace;
|
|
color: var(--color-text);
|
|
margin: 6px 0 10px 0;
|
|
line-height: 1.5;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.project-tech {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 6px;
|
|
}
|
|
|
|
.tech-tag {
|
|
font-family: 'Hurmit', monospace;
|
|
font-size: 0.75rem;
|
|
color: var(--color-background-fore);
|
|
background-color: var(--color-link);
|
|
padding: 2px 8px;
|
|
box-shadow: 2px -2px 0px 0px rgba(0, 0, 0, 0.3);
|
|
}
|
|
|
|
@media (max-width: 640px) {
|
|
.section-title {
|
|
font-size: 1.1rem;
|
|
}
|
|
|
|
.project-card {
|
|
padding: 8px 12px;
|
|
}
|
|
|
|
.project-title {
|
|
font-size: 0.95rem;
|
|
}
|
|
|
|
.project-description {
|
|
font-size: 0.82rem;
|
|
}
|
|
}
|
|
</style> |