This commit is contained in:
2023-08-18 01:32:23 +02:00
parent a988391944
commit 6dc6002061
12 changed files with 142 additions and 180 deletions

View File

@@ -14,6 +14,9 @@ export default defineAppConfig({
},
dropdown: {
background: 'bg-white dark:bg-zinc-800',
item: {
base: 'duration-300 group flex items-center gap-2 w-full',
},
},
button: {
base: 'duration-300 focus:outline-none focus-visible:outline-0 disabled:cursor-not-allowed disabled:opacity-75 flex-shrink-0',

View File

@@ -4,7 +4,7 @@
@layer components {
.w-container {
@apply mx-auto max-w-7xl lg:px-24 sm:px-4;
@apply mx-auto max-w-7xl lg:px-24 md:px-12 sm:px-4;
}
.text-subtitle {

View File

@@ -1,130 +0,0 @@
<script setup lang="ts">
const isOpen = ref(false)
const commandPaletteRef = ref()
const router = useRouter()
const color = useColorMode()
const quickLinks = [
{ id: 'twitter', label: 'Twitter', icon: 'i-ph-twitter-logo-bold' },
{ id: 'github', label: 'GitHub', icon: 'i-ph-github-logo-bold' },
]
const navigations = [
{ id: 'home', label: 'Home', icon: 'i-ph-house-bold', to: '/', shortcuts: ['H'] },
{ id: 'about', label: 'About', icon: 'i-ph-user-bold', to: '/about', shortcuts: ['A'] },
{ id: 'blog', label: 'Blog', icon: 'i-ph-book-bold', to: '/blog', shortcuts: ['B'] },
{ id: 'work', label: 'Work', icon: 'i-ph-wrench-bold', to: '/work', shortcuts: ['W'] },
]
const toast = useToast()
const isDark = computed(() => color.preference === 'dark')
const controls = [
{
id: 'color',
label: 'Toggle Color Mode',
icon: isDark ? 'i-ph-moon-bold' : 'i-ph-sun-bold',
click: () => {
color.preference = color.value === 'dark' ? 'light' : 'dark'
toast.add({
color: 'primary',
title: 'Color mode switched!',
icon: isDark.value ? 'i-ph-moon-bold' : 'i-ph-sun-bold',
})
},
shortcuts: ['C'],
},
]
const groups = [{
key: 'navigation',
label: 'Navigation',
inactive: 'Navigation',
commands: navigations,
}, {
key: 'quickLinks',
label: 'Quick Links',
inactive: 'Quick Links',
commands: quickLinks,
}, {
key: 'controls',
label: 'Controls',
inactive: 'Controls',
commands: controls,
}]
const { usingInput } = useShortcuts()
const canToggleModal = computed(() => isOpen.value || !usingInput.value)
defineShortcuts({
meta_k: {
usingInput: true,
whenever: [canToggleModal],
handler: () => {
isOpen.value = !isOpen.value
},
},
escape: {
usingInput: true,
whenever: [isOpen],
handler: () => { isOpen.value = false },
},
})
function onSelect(option: any) {
if (option.click) {
option.click()
isOpen.value = false
}
else if (option.to) { router.push(option.to) }
else if (option.href) { window.open(option.href, '_blank') }
}
onKeyStroke(true, (event: KeyboardEvent) => {
if (!isOpen.value && !usingInput.value) {
switch (event.key) {
case 'A':
case 'a':
router.push('/about')
break
case 'H':
case 'h':
router.push('/')
break
case 'W':
case 'w':
router.push('/work')
break
case 'B':
case 'b':
router.push('/blog')
break
case 'C':
case 'c':
color.preference = color.value === 'dark' ? 'light' : 'dark'
toast.add({
color: 'primary',
title: 'Color mode switched!',
icon: isDark.value ? 'i-ph-moon-bold' : 'i-ph-sun-bold',
})
break
}
}
})
</script>
<template>
<UModal v-model="isOpen">
<UCommandPalette
ref="commandPaletteRef"
:groups="groups"
icon=""
:autoselect="false"
placeholder="Search for apps and commands"
@update:model-value="onSelect"
/>
</UModal>
</template>

View File

@@ -22,27 +22,27 @@ const items = [
<template>
<nav class="hidden md:block pointer-events-auto z-50">
<div class="flex items-center h-10 rounded-md p-1 gap-1 relative bg-black/5 text-sm font-medium text-zinc-700 dark:bg-zinc-800/90 dark:text-zinc-300">
<UButton to="/" size="sm" variant="ghost" color="white">
<UButton to="/" size="sm" variant="ghost" color="white" :class="{ 'router-link-exact-active': route.path === '/' }">
Home
</UButton>
<UButton to="/about" size="sm" variant="ghost" color="white">
<UButton to="/about" size="sm" variant="ghost" color="white" :class="{ 'router-link-exact-active': route.path.includes('/about') }">
About
</UButton>
<UButton to="/writing" size="sm" variant="ghost" color="white" :class="{ 'router-link-exact-active': route.path.includes('/writing') }">
Articles
</UButton>
<UButton to="/work" size="sm" variant="ghost" color="white">
<UButton to="/work" size="sm" variant="ghost" color="white" :class="{ 'router-link-exact-active': route.path.includes('/work') }">
Projects
</UButton>
<UButton to="/uses" size="sm" variant="ghost" color="white">
<UButton to="/uses" size="sm" variant="ghost" color="white" :class="{ 'router-link-exact-active': route.path.includes('/uses') }">
Uses
</UButton>
<UDropdown mode="hover" :items="items" :popper="{ placement: 'bottom' }">
<UButton size="sm" variant="ghost" color="white">
<UButton size="sm" variant="ghost" color="white" class="duration-300">
Other
</UButton>
</UDropdown>
<UButton to="/contact" size="sm" variant="ghost" color="white">
<UButton to="/contact" size="sm" variant="ghost" color="white" :class="{ 'router-link-exact-active': route.path.includes('/contact') }">
Contact
</UButton>
</div>

View File

@@ -1,78 +1,78 @@
::uses-section{title="Computers"}
::grid-section{title="Computers"}
:::uses-slot{title="MacBook Pro 13'"}
:::grid-slot{title="MacBook Pro 13'"}
I use this for code
:::
:::uses-slot{title="Specs..."}
:::grid-slot{title="Specs..."}
I use this for valorant
:::
::
::uses-section{title="Peripherals"}
::grid-section{title="Peripherals"}
:::uses-slot{title="MacBook Pro 13'"}
:::grid-slot{title="MacBook Pro 13'"}
I use this for code
:::
:::uses-slot{title="My gaming computer"}
:::grid-slot{title="My gaming computer"}
Windows 11, Intel Core i5-10400F, 16Go DDR4, RTX 2060
:::
:::uses-slot{title="Phone, Sound & Other"}
:::grid-slot{title="Phone, Sound & Other"}
Iphone 14 Pro, Ipad Air, AirPods Pro, Beats Studio 3
:::
::
::uses-section{title="Editors"}
::grid-section{title="Editors"}
:::uses-slot{title="Visual Studio Code"}
:::grid-slot{title="Visual Studio Code"}
I use this for code
:::
:::uses-slot{title="JetBrains Mono"}
:::grid-slot{title="JetBrains Mono"}
I use this for valorant
:::
::
::uses-section{title="Software and Applications"}
::grid-section{title="Software and Applications"}
:::uses-slot{title="Warp"}
:::grid-slot{title="Warp"}
I use this for code
:::
:::uses-slot{title="Apple Apps"}
:::grid-slot{title="Apple Apps"}
Music, mail, reminders, calendar
:::
:::uses-slot{title="Notion"}
:::grid-slot{title="Notion"}
I use this for valorant
:::
:::uses-slot{title="Google Chrome & Arc"}
:::grid-slot{title="Google Chrome & Arc"}
I use this for valorant
:::
:::uses-slot{title="Discord"}
:::grid-slot{title="Discord"}
I use this for valorant
:::
:::uses-slot{title="RayCast"}
:::grid-slot{title="RayCast"}
I use this for valorant
:::
::
::uses-section{title="Favorite Stack"}
::grid-section{title="Favorite Stack"}
:::uses-slot{title="FrontEnd"}
:::grid-slot{title="FrontEnd"}
TS, Vue 3 with Nuxt 3, TailwindCss, Nuxt UI
:::
:::uses-slot{title="BackEnd"}
:::grid-slot{title="BackEnd"}
Prisma, AdonisJs, Supabase, TRPC.io
:::

48
src/error.vue Normal file
View File

@@ -0,0 +1,48 @@
<script setup lang="ts">
const error = useError()
const appConfig = useAppConfig()
const getColor = computed(() => appConfig.ui.primary)
definePageMeta({
layout: 'default',
})
</script>
<template>
<NuxtLoadingIndicator :color="getColor" />
<section class="fixed inset-0 flex justify-center sm:px-8">
<div class="flex w-full max-w-7xl">
<div class="w-full bg-white ring-1 ring-zinc-100 dark:bg-zinc-900 dark:ring-zinc-300/20" />
</div>
</section>
<div class="relative z-50">
<Header />
<UContainer class="my-32 w-container flex flex-col items-center gap-8">
<div class="flex flex-col items-center gap-4">
<h1 class="font-medium text-[8rem] md:text-[16rem] leading-none bg-error bg-clip-text tracking-wider font-error" :class="`text-${getColor}-500`">
{{ error.statusCode }}
</h1>
<p class="text-lg md:text-2xl text-subtitle text-center">
Sorry, {{ error.statusCode === 404
? "the page you are looking for doesn't exist or as been moved."
: "you have encountered a problem."
}}
<br>
Let's find a better place for you to go.
</p>
</div>
<div>
<UButton to="/" size="md" variant="soft" color="primary">
Go back to the main page
</UButton>
</div>
</UContainer>
<Footer />
</div>
</template>
<style scoped>
.bg-error {
@apply text-transparent bg-clip-text bg-origin-content bg-gradient-to-b from-gray-100 to-gray-300 dark:from-zinc-600 to-55% dark:to-zinc-800;
}
</style>

View File

@@ -1,6 +1,10 @@
<script setup lang="ts">
const appConfig = useAppConfig()
const getColor = computed(() => appConfig.ui.primary)
</script>
<template>
<CommandPalette />
<NuxtLoadingIndicator />
<NuxtLoadingIndicator :color="getColor" />
<section class="fixed inset-0 flex justify-center sm:px-8">
<div class="flex w-full max-w-7xl">
<div class="w-full bg-white ring-1 ring-zinc-100 dark:bg-zinc-900 dark:ring-zinc-300/20" />
@@ -13,6 +17,4 @@
</UContainer>
<Footer />
</div>
<UNotifications />
</template>

View File

@@ -3,7 +3,36 @@
</script>
<template>
<div>
ABOUT
</div>
<section>
<div class="w-container lg:my-32 mt-16">
<div class="max-w-2xl space-y-8 mb-16">
<h1 class="text-4xl font-bold tracking-tight text-zinc-800 dark:text-zinc-100 sm:text-5xl !leading-tight">
I'm Arthur, I live and study in France where I learn new things.
</h1>
<p class="leading-relaxed text-subtitle">
As a software engineer with a passion for AI and the cloud, I have a deep understanding of emerging technologies that are transforming the way businesses and organizations operate. I am at the heart of an ever-changing and rapidly growing field. My background in mathematics also gives me an edge in understanding the mathematical concepts and theories behind these technologies as well as how to design them.
</p>
<p class="leading-relaxed text-subtitle">
I enjoy sharing my knowledge and learning new theorems and technologies. I am a curious person and eager to continue learning and growing throughout your life. My passion and commitment to these subjects are admirable qualities and will help me succeed in my career and education.
</p>
</div>
<GridSection title="Interests">
<GridSlot title="Development">
Development is the passion that appeared the earliest in my life. I started developing on Minecraft and then I migrated to the broad field of the web.
</GridSlot>
<GridSlot title="Mathematics">
During my studies, I loved mathematics very quickly. That's why today I continue my studies in this fabulous field.
</GridSlot>
<GridSlot title="Artificial Intelligence">
We hear more and more about artificial intelligence with the evolution of our society. So I quickly got interested by doing my own research and I quickly discovered that this field is closely related to mathematics, hence my interest.
</GridSlot>
<GridSlot title="Cloud and infrastructure">
When you're doing development and deploying projects online, you discover and are forced to touch the cloud, infrastructure, and network. It's a totally different field than the others but just as interesting.
</GridSlot>
<GridSlot title="Fitness">
In addition to my studies and programming, I go to the gym every day to relax and stay in shape. Sport allows me to recharge my batteries and move on to other things.
</GridSlot>
</GridSection>
</div>
</section>
</template>

View File

@@ -1,18 +1,23 @@
<script lang="ts" setup>
import type { Post } from '../../../types'
import type { Post } from '~~/types'
const route = useRoute()
const { data: postContent } = await useAsyncData<Post>(`writing:${route.params.slug}`, async () => await queryContent<Post>(`/writing/${route.params.slug}`).findOne())
const { post, view, like, likes, views } = await usePost(route.params.slug.toString())
if (!postContent.value) {
throw createError({
statusMessage: 'The post you are looking for was not found.',
statusCode: 404,
})
}
onMounted(() => {
view()
})
const { post, view, like, likes, views } = await usePost(route.params.slug.toString())
view()
useHead({
title: `${postContent.value?.title} — Arthur Danjou's shelf`,
})
function top() {
window.scrollTo({
top: 0,
@@ -25,8 +30,6 @@ const { copy, copied } = useClipboard({
source: `https://arthurdanjou.fr/writing/${route.params.slug}`,
copiedDuring: 4000,
})
const router = useRouter()
</script>
<template>
@@ -41,7 +44,7 @@ const router = useRouter()
size="lg"
:ui="{ rounded: 'rounded-full' }"
class="lg:absolute left-0 mb-8"
@click.prevent="router.back()"
@click.prevent="useRouter().back()"
/>
<article>
<header class="flex flex-col space-y-6">
@@ -54,7 +57,7 @@ const router = useRouter()
<span></span>
<div>{{ postContent.readingMins }} min</div>
<span></span>
<div>{{ views }} views</div>
<div>{{ views }} {{ views > 1 ? 'views' : 'view' }}</div>
</div>
</time>
<h1 class="text-4xl font-bold tracking-tight text-zinc-800 dark:text-zinc-100 sm:text-5xl">
@@ -67,18 +70,25 @@ const router = useRouter()
<div class="w-full rounded-md my-8">
{{ postContent.cover }}
</div>
<ContentRenderer
class="mt-12 prose leading-6 prose-table:w-full md:prose-table:w-3/4 lg:prose-table:w-2/5 max-w-none
<ClientOnly>
<ContentRenderer
class="mt-12 prose leading-6 prose-table:w-full md:prose-table:w-3/4 lg:prose-table:w-2/5 max-w-none
dark:prose dark:prose-invert dark:leading-6 dark:max-w-none dark:prose-table:w-full dark:md:prose-table:w-3/4 dark:lg:prose-table:w-2/5"
:value="postContent || undefined"
/>
:value="postContent"
/>
<template #fallback>
<p class="my-16 text-subtitle">
The content of the page is loading...
</p>
</template>
</ClientOnly>
<footer class="my-8 space-y-8">
<p class="text-subtitle">
Thanks for reading this post! If you liked it, please consider sharing it with your friends. <strong>Don't forget to leave a like!</strong>
</p>
<div class="flex gap-4 flex-wrap">
<UButton
:label="`${likes} likes`"
:label="`${likes} ${likes > 1 ? 'likes' : 'like'}`"
icon="i-ph-heart-bold"
size="lg"
variant="soft"

View File

@@ -26,7 +26,7 @@ const { data: posts } = await usePosts()
<div class="mt-16 md:mt-20">
<div class="md:border-l md:border-zinc-100 md:pl-6 md:dark:border-zinc-700/40">
<div class="flex max-w-3xl flex-col space-y-16">
<article v-for="post in posts" :key="post.slug" class="md:grid md:grid-cols-4 md:items-baseline">
<article v-for="post in posts" :key="post.slug" class="group md:grid md:grid-cols-4 md:items-baseline">
<div class="md:col-span-3 group relative flex flex-col items-start">
<h2 class="text-base font-semibold tracking-tight text-zinc-800 dark:text-zinc-100">
<div class="absolute -inset-y-6 -inset-x-4 z-0 scale-95 bg-zinc-50 opacity-0 transition group-hover:scale-100 group-hover:opacity-100 dark:bg-zinc-800/50 sm:-inset-x-6 sm:rounded-2xl" />
@@ -48,7 +48,7 @@ const { data: posts } = await usePosts()
</p>
<div class="relative z-10 mt-4 flex items-center gap-2 justify-center text-sm font-medium" :class="getColor()">
<p>Read article</p>
<UIcon name="i-ph-arrow-circle-right-bold" />
<UIcon name="i-ph-arrow-circle-right-bold" class="duration-300 group-hover:ml-2"/>
</div>
</div>
<time class="mt-1 md:block relative z-10 order-first mb-3 hidden text-sm text-zinc-400 dark:text-zinc-500">