Add latest article section to homepage and back to articles link
This commit is contained in:
41
components/home/latest-article.vue
Normal file
41
components/home/latest-article.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<script setup lang="ts">
|
||||
const { data: article } = await useAsyncData("latest-article", async () => {
|
||||
return queryCollection("articles").order("date", "DESC").first();
|
||||
});
|
||||
|
||||
const date = useDateFormat(new Date(article.value?.date ?? ""), "Do of MMMM YYYY");
|
||||
|
||||
const excerpt = computed(() => {
|
||||
if (!article.value) return "";
|
||||
const text = article.value.description ?? article.value.body ?? "";
|
||||
return text.slice(0, 150) + (text.length > 150 ? "..." : "");
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UContainer
|
||||
v-if="article"
|
||||
class="p-4 sm:p-6 lg:p-8 max-w-3xl"
|
||||
as="section"
|
||||
>
|
||||
<span class="text-sm text-gray-500 flex flex-row gap-1 items-center">
|
||||
Latest article
|
||||
</span>
|
||||
|
||||
<ULink :to="article.path" class="block mt-4">
|
||||
<div class="flex gap-6 items-start flex-row-reverse">
|
||||
<NuxtImg
|
||||
v-if="article.coverImage?.url"
|
||||
class="w-24 h-24 object-cover rounded-lg shrink-0"
|
||||
:src="article.coverImage.url.replace('w=1287&h=600', 'w=300&h=300')"
|
||||
:alt="article.title"
|
||||
/>
|
||||
<div class="flex flex-col gap-2">
|
||||
<h3 class="font-semibold text-lg">{{ article.title }}</h3>
|
||||
<p class="text-sm text-slate-600 dark:text-slate-400 line-clamp-3">{{ excerpt }}</p>
|
||||
<time class="text-xs text-slate-500">{{ date }}</time>
|
||||
</div>
|
||||
</div>
|
||||
</ULink>
|
||||
</UContainer>
|
||||
</template>
|
||||
@@ -1,15 +1,19 @@
|
||||
<template>
|
||||
<UContainer class="flex flex-col gap-5 p-4 sm:p-6 lg:p-8 max-w-3xl" as="section">
|
||||
<UContainer
|
||||
class="flex flex-col gap-5 p-4 sm:p-6 lg:p-8 max-w-3xl"
|
||||
as="section"
|
||||
>
|
||||
<div class="text-sm text-gray-500">Personal projects</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-5 md:grid-cols-3">
|
||||
<Project
|
||||
title="Ghostwriter"
|
||||
image="https://www.ghostwriter.rocks/ghostwriter-logo.png"
|
||||
image="https://app.ghostwriter.rocks/_ipx/_/ghostwriter-logo.png"
|
||||
url="https://ghostwriter.rocks"
|
||||
>
|
||||
<template v-slot:description>
|
||||
Creative post-generation for Strava activities with a lightweight, playful product feel.
|
||||
Creative post-generation for Strava activities with a lightweight,
|
||||
playful product feel.
|
||||
</template>
|
||||
<template v-slot:subtitle> Compatible with Strava </template>
|
||||
</Project>
|
||||
@@ -20,11 +24,10 @@
|
||||
url="https://getplaces.co"
|
||||
>
|
||||
<template v-slot:description>
|
||||
Location-aware lead capture designed to connect digital conversations to real-world businesses.
|
||||
</template>
|
||||
<template v-slot:subtitle>
|
||||
Built for Zendesk marketplace
|
||||
Location-aware lead capture designed to connect digital conversations
|
||||
to real-world businesses.
|
||||
</template>
|
||||
<template v-slot:subtitle> Built for Zendesk marketplace </template>
|
||||
</Project>
|
||||
|
||||
<Project
|
||||
@@ -34,11 +37,10 @@
|
||||
marketplace="LiveChat"
|
||||
>
|
||||
<template v-slot:description
|
||||
>Turn plain links into richer, more informative chat experiences</template
|
||||
>Turn plain links into richer, more informative chat
|
||||
experiences</template
|
||||
>
|
||||
<template v-slot:subtitle>
|
||||
Built for LiveChat marketplace
|
||||
</template>
|
||||
<template v-slot:subtitle> Built for LiveChat marketplace </template>
|
||||
</Project>
|
||||
</div>
|
||||
</UContainer>
|
||||
|
||||
@@ -20,7 +20,14 @@ const { data: article } = useAsyncData(path, async () => {
|
||||
class="flex flex-col gap-3 prose max-w-3xl dark:prose-invert p-4 sm:p-6 lg:p-8"
|
||||
as="article"
|
||||
>
|
||||
<div class="text-sm text-slate-500">
|
||||
<ULink
|
||||
class="text-sm text-gray-500 flex flex-row gap-1 items-center group w-fit"
|
||||
to="/articles"
|
||||
>
|
||||
<UIcon class="opacity-100 group-hover:-translate-x-1 transition-transform" name="i-heroicons-arrow-left" />
|
||||
Back to articles
|
||||
</ULink>
|
||||
<div class="text-sm text-slate-500 mt-6">
|
||||
{{ formatDate(new Date(article.date), "Do of MMMM YYYY") }}
|
||||
</div>
|
||||
<h1 class="text-3xl md:text-4xl font-bold">{{ article.title }}</h1>
|
||||
|
||||
@@ -12,6 +12,7 @@ useSeoMeta({
|
||||
|
||||
<template>
|
||||
<HomeIntroduction v-motion-fade />
|
||||
<HomeLatestArticle v-motion-fade :delay="500" />
|
||||
<HomeBeenWorkingWith v-motion-fade :delay="500" />
|
||||
<HomePersonalProjects v-motion-fade :delay="500" />
|
||||
<HomeConnect v-motion-fade :delay="500" />
|
||||
|
||||
BIN
public/ghostwriter-logo.png
Normal file
BIN
public/ghostwriter-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
Reference in New Issue
Block a user