Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Improve Works section with categories #81

Merged
merged 7 commits into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# Generated by Shelve CLI
NUXT_PUBLIC_STUDIO_TOKENS=your_value
NUXT_PUBLIC_MEETING_LINK=your_value
NUXT_PRIVATE_RESEND_API_KEY=your_value
NUXT_PRIVATE_GITHUB_TOKEN=your_value
NUXT_PRIVATE_NOTES_PASSWORD=your_value
NUXT_PRIVATE_NOTES_PASSWORD=your_value
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
run_install: false

- name: 📦 Install dependencies
run: pnpm install --frozen-lockfile
run: pnpm install

- name: 🛠️ Build
run: pnpm run build
12 changes: 5 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@ FROM node:22.13.1-alpine AS build
ARG NUXT_PRIVATE_GITHUB_TOKEN
ENV NUXT_PRIVATE_GITHUB_TOKEN=$NUXT_PRIVATE_GITHUB_TOKEN

RUN apk add --no-cache python3 make g++
RUN corepack enable && corepack prepare pnpm@latest --activate

WORKDIR /app

COPY pnpm-lock.yaml package.json ./
RUN corepack enable

COPY . .
COPY package.json pnpm-lock.yaml .npmrc ./

RUN corepack enable
RUN pnpm install --frozen-lockfile --prod
RUN pnpm install

COPY . .

RUN pnpm run build

Expand Down
5 changes: 4 additions & 1 deletion app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
export default defineAppConfig({
global: {
meetingLink: 'https://cal.com/hugorcd/15min',
},
profile: {
name: 'Hugo Richard',
job: 'Frontend Architect and Designer',
job: '[Frontend Engineer at [Nuxtlabs](https://nuxtlabs.com)]{.text-accent}',
email: 'contact@hrcd.fr',
phone: '(+33) 6 21 56 22 18',
picture: 'https://avatars.githubusercontent.com/u/71938701?v=4'
Expand Down
33 changes: 6 additions & 27 deletions app/components/List.vue
Original file line number Diff line number Diff line change
@@ -1,36 +1,15 @@
<script setup lang="ts">
type Post = {
title: string
date: string
description: string
path: string
}
import type { Collections } from '@nuxt/content'

type ListProps = {
data: Post[]
sort?: 'asc' | 'desc'
}

const { data, sort = 'desc' } = defineProps<ListProps>()

const sortedPosts = computed(() => {
return [...data]
.sort((a, b) => {
const dateA = new Date(a.date.split('/').reverse().join('-'))
const dateB = new Date(b.date.split('/').reverse().join('-'))

return sort === 'desc'
? dateB.getTime() - dateA.getTime()
: dateA.getTime() - dateB.getTime()
})
.map((post, index) => ({ post, index }))
})
defineProps<{
posts: Collections['writing'][]
}>()
</script>

<template>
<div class="mt-6 flex flex-col gap-8">
<NuxtLink
v-for="{ post, index } in sortedPosts"
v-for="(post, index) in posts"
:key="post.title"
:to="post.path"
class="group relative max-w-prose"
Expand All @@ -39,7 +18,7 @@ const sortedPosts = computed(() => {
:aria-label="`Read ${post.title}`"
>
<div class="font-newsreader text-lg italic opacity-50">
{{ post.date }}
{{ new Date(post.date).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }) }}
</div>
<h3 class="text-2xl font-newsreader font-medium italic decoration-accent group-hover:underline text-font-primary/80">
{{ post.title }}
Expand Down
2 changes: 1 addition & 1 deletion app/components/ThemeSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const switchTheme = () => {
colorMode.preference = colorMode.value
}

const startViewTransition = (theme) => {
const startViewTransition = (theme: string) => {
if (theme === colorMode.value) return
if (reduceMotion.value) {
switchTheme()
Expand Down
4 changes: 1 addition & 3 deletions app/components/content/Hero.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ const { profile } = useAppConfig()
<h3 class="font-newsreader text-xl italic text-secondary">
{{ profile.name }}
</h3>
<h1 class="font-newsreader text-2xl font-medium italic text-accent sm:text-3xl">
{{ profile.job }}
</h1>
<MDC :value="profile.job!" class="font-newsreader text-2xl font-medium italic sm:text-3xl mt-1" />
<p class="max-w-[600px] text-pretty text-tertiary text-sm font-extralight sm:text-base">
<slot mdc-unwrap="p" />
</p>
Expand Down
2 changes: 1 addition & 1 deletion app/components/content/Notes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ async function verifyPassword() {
<input v-model="password" type="password" placeholder="Password" class="input">
<MButton class="flex items-center cursor-pointer justify-center gap-2 bg-accent hover:bg-accent/90 px-2 text-white" type="submit" rounded="none" label="Verify" :loading />
</form>
<List v-if="isAuthorized && notes" :data="notes" />
<List v-if="isAuthorized && notes" :posts="notes" />
</div>
</template>
15 changes: 13 additions & 2 deletions app/components/content/Works.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
<script setup lang="ts">
const { data: works, error } = await useAsyncData('works', () => queryCollection('works').order('date', 'DESC').all())
const { category } = defineProps<{
category?: string
}>()

const { data: works, error } = await useAsyncData(`works-${category}`, () => {
return queryCollection('works')
.where('category', '=', category)
.order('date', 'DESC')
.all()
})

if (!works.value || !error.value) createError({ statusCode: 404 })
</script>

Expand All @@ -9,6 +19,7 @@ if (!works.value || !error.value) createError({ statusCode: 404 })
v-for="(work, index) in works"
:key="work.name"
:to="work.link"
target="_blank"
class="group relative"
data-animate
:aria-label="`Open ${work.name}`"
Expand All @@ -17,7 +28,7 @@ if (!works.value || !error.value) createError({ statusCode: 404 })
<div class="absolute right-0 top-0 font-newsreader text-5xl italic opacity-15 sm:text-3xl">
{{ work.release }}
</div>
<h3 class="font-newsreader italic text-secondary text-2xl italic decoration-accent group-hover:underline">
<h3 class="font-newsreader italic text-secondary text-2xl decoration-accent group-hover:underline">
{{ work.name }}<span class="text-accent">.</span>
</h3>
<p class="text-tertiary text-sm font-extralight sm:text-base">
Expand Down
6 changes: 3 additions & 3 deletions app/components/content/Writing.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ async function submit() {
}
}

const { data, error } = await useAsyncData('writings', () => queryCollection('writing').order('date', 'DESC').all())
const { data: posts, error } = await useAsyncData('writings', () => queryCollection('writing').order('date', 'DESC').all())

if (!data.value || !error.value) createError({ statusCode: 404 })
if (!posts.value || !error.value) createError({ statusCode: 404 })
</script>

<template>
<div class="flex font-normal flex-col gap-8">
<List v-if="data" :data />
<List v-if="posts" :posts />
<div class="mt-10 flex flex-col gap-1">
<p class="mb-1 text-sm">
Subscribe to get notified about new articles
Expand Down
21 changes: 7 additions & 14 deletions app/components/content/WritingList.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
<script setup lang="ts">
const { data, error } = await useAsyncData('feed', () => queryCollection('writing').order('date', 'DESC').limit(4).all())
const { data, error } = await useAsyncData('feed', () =>
queryCollection('writing')
.order('date', 'DESC')
.limit(4)
.all()
)
if (!data.value || !error.value) createError({ statusCode: 404 })

const sortedPosts = computed(() => {
if (!data.value) return []
return [...data.value]
.sort((a, b) => {
const dateA = new Date(a.date.split('/').reverse().join('-'))
const dateB = new Date(b.date.split('/').reverse().join('-'))

return dateB.getTime() - dateA.getTime()
})
.map((post, index) => ({ post, index }))
})
</script>

<template>
<div class="flex flex-col gap-3">
<NuxtLink
v-for="{ post, index } in sortedPosts"
v-for="(post, index) in data"
:key="post.title"
:to="post.path"
class="link text-secondary text-lg decoration-accent hover:underline font-extralight"
Expand Down
2 changes: 1 addition & 1 deletion app/pages/[...slug].vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const mdcVars = ref({ ...seo, ...profile, ...socials })
const isWriting = computed(() => route.path.includes('/writing/') || route.path.includes('/notes/'))

const contentClasses = {
writing: 'mb-4 mt-8',
writing: 'enter-content mb-4 mt-8',
default: 'mb-4 mt-8 flex flex-1 flex-col justify-around gap-8 sm:gap-12'
}
</script>
Expand Down
25 changes: 11 additions & 14 deletions content.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,16 @@ export const collections = {
})
})
),
works: defineCollection(
asSeoCollection({
type: 'data',
source: '1.works/*.json',
schema: z.object({
name: z.string().nonempty(),
logo: z.string().nonempty(),
description: z.string().nonempty(),
image: z.string().url(),
link: z.string().url(),
release: z.string().nonempty(),
date: z.string().nonempty(),
})
works: defineCollection({
type: 'data',
source: '1.works/*.json',
schema: z.object({
name: z.string().nonempty(),
description: z.string().nonempty(),
category: z.string().nonempty(),
link: z.string().url(),
release: z.string().optional(),
date: z.string().nonempty(),
})
)
}),
}
5 changes: 2 additions & 3 deletions content/1.works/canvas.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{
"name": "Canvas",
"logo": "SvgoCanvas",
"image": "/projects/canvas.webp",
"category": "featured",
"description": "A premium portfolio template, with a minimal and clean design",
"link": "https://canvas.hrcd.fr/",
"release": "2024",
"date": "2024"
"date": "2024-01-10"
}
5 changes: 2 additions & 3 deletions content/1.works/currencia.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{
"name": "Currencia",
"logo": "SvgoCurrencia",
"image": "/projects/currencia.webp",
"category": "personal",
"description": "Simple yet beautiful crypto tracker template",
"link": "https://currencia.hrcd.fr/",
"release": "2023",
"date": "2023"
"date": "2023-11-20"
}
8 changes: 8 additions & 0 deletions content/1.works/eslint-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@hrcd/eslint-config",
"category": "personal",
"description": "My personal ESLint Flat Config, crafted for TS, Vue, and Nuxt development.",
"link": "https://github.com/HugoRCD/eslint-config",
"release": "2024",
"date": "2024-03-23"
}
5 changes: 2 additions & 3 deletions content/1.works/helpr.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{
"name": "Helpr",
"logo": "SvgoHelpr",
"image": "/projects/helpr.webp",
"category": "personal",
"description": "Automation tools connecting various applications to create powerful workflows",
"link": "https://helpr.hrcd.fr/",
"release": "2023",
"date": "2023"
"date": "2023-03-23"
}
8 changes: 8 additions & 0 deletions content/1.works/inkly.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "Inkly",
"category": "personal",
"description": "The most simple open-source email signature generator",
"link": "https://inkly.hrcd.fr/",
"release": "2024",
"date": "2024-06-20"
}
5 changes: 2 additions & 3 deletions content/1.works/maison-hochard.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{
"name": "Maison Hochard",
"logo": "SvgoMaisonHochard",
"image": "/projects/maison-hochard.webp",
"category": "personal",
"description": "Luxury graphic design and web development communication agency",
"link": "https://mh.hrcd.fr/",
"release": "2022",
"date": "2022"
"date": "2022-11-20"
}
7 changes: 4 additions & 3 deletions content/1.works/mockline.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"name": "Mockline",
"logo": "SvgoMockline",
"logo": "custom:mockline",
"category": "personal",
"image": "/projects/mockline.webp",
"description": "A components library to breathe new life and meaning into the web",
"description": "The most customizable opinionated UI library for Nuxt and Vue",
"link": "https://mockline.dev/",
"release": "Soon",
"date": "2025"
"date": "Soon"
}
8 changes: 8 additions & 0 deletions content/1.works/nuppets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "Nuppets",
"category": "personal",
"description": "A universal hub for Nuxt and Vue snippets - Available for Raycast, VS Code, and more",
"link": "https://nuppets.dev",
"release": "2025",
"date": "2025-02-08"
}
7 changes: 7 additions & 0 deletions content/1.works/nuxt-ui-pro.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "Nuxt UI Pro",
"category": "ecosystem",
"description": "The most complete Nuxt / Vue UI library",
"link": "https://ui3.nuxt.dev/getting-started",
"date": "2025-01-06"
}
7 changes: 7 additions & 0 deletions content/1.works/nuxt-ui.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "Nuxt UI",
"category": "ecosystem",
"description": "The most complete Nuxt / Vue UI library",
"link": "https://ui3.nuxt.dev/getting-started",
"date": "2025-01-06"
}
8 changes: 8 additions & 0 deletions content/1.works/nuxt-visitors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "Nuxt Visitors",
"category": "personal",
"description": "Add real-time visitor tracking to your Nuxt app with one line of code. WebSocket made easy",
"link": "https://nuxt-visitors.nuxt.dev/",
"release": "2025",
"date": "2025-01-28"
}
5 changes: 2 additions & 3 deletions content/1.works/nuxtlog.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{
"name": "Nuxtlog",
"logo": "SvgoNuxtlog",
"image": "/projects/nuxtlog.webp",
"category": "personal",
"description": "A changelog, newsletter and blog template made for Nuxt",
"link": "https://nuxtlog.hrcd.fr/",
"release": "2024",
"date": "2024"
"date": "2024-01-18"
}
5 changes: 2 additions & 3 deletions content/1.works/shelve.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{
"name": "Shelve",
"logo": "SvgoShelve",
"image": "/projects/shelve.webp",
"category": "featured",
"description": "Easily kick off and oversee team projects with just a few clicks!",
"link": "https://shelve.cloud/",
"release": "2024",
"date": "2025"
"date": "2024-02-29"
}
Loading
Loading