mirror of
https://github.com/ArthurDanjou/website-old.git
synced 2026-01-21 15:31:47 +01:00
Update project
This commit is contained in:
BIN
src/assets/images/logo-header.png
Normal file
BIN
src/assets/images/logo-header.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
@@ -53,10 +53,14 @@ export default {
|
||||
const {$i18n} = useContext()
|
||||
const getBeginDate = computed(() => {
|
||||
const dateFormat = props.begin.split('-')
|
||||
console.log('1')
|
||||
console.log($i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1])
|
||||
return $i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
|
||||
})
|
||||
const getEndDate = computed(() => {
|
||||
const dateFormat = props.end.split('-')
|
||||
console.log('2')
|
||||
console.log(props.end === 'Today' ? $i18n.t('date.today') : $i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1])
|
||||
return props.end === 'Today' ? $i18n.t('date.today') : $i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
|
||||
})
|
||||
|
||||
|
||||
@@ -1,96 +1,74 @@
|
||||
<template>
|
||||
<header class="dark:bg-dark-900 dark:text-white fixed z-50 top-0 left-0 bg-white header tracking-wider w-full h-16 lg:h-24 duration-500" :class="scrollPosition > 50 ? ' shadow-md dark:shadow-white' : ''">
|
||||
<div class="header-container z-index-50 flex justify-between items-center h-full px-5 xl:px-64">
|
||||
<header class="dark:bg-black dark:text-white fixed z-50 top-0 left-0 bg-white header w-full h-16 lg:h-24 duration-500" :class="scrollPosition > 50 ? ' shadow-md dark:shadow-white' : ''">
|
||||
<div class="header-container z-index-50 flex justify-between items-center h-full px-5 xl:px-32">
|
||||
<nuxt-link to="/">
|
||||
<div class="left text-2xl font-bold cursor-pointer border-b-2 border-opacity-0 dark:border-opacity-0 dark:hover:border-opacity-100 hover:border-opacity-100 border-black dark:border-white border-solid duration-500">
|
||||
{{ $t('header.title') }}
|
||||
</div>
|
||||
<img src="@/assets/images/logo-header.png" alt="Logo Circle" class="h-10 left cursor-pointer duration-500" />
|
||||
</nuxt-link>
|
||||
<nav class="right">
|
||||
<div class="flex flex-col md:flex-row items-center">
|
||||
<ul class="flex text-xl">
|
||||
<li class="mx-2 cursor-pointer">
|
||||
<div v-if="this.$i18n.locale === 'en'" @click="changeLanguage('fr')">
|
||||
🇫🇷
|
||||
</div>
|
||||
<div v-else @click="changeLanguage('en')">
|
||||
🇬🇧
|
||||
</div>
|
||||
</li>
|
||||
<li @click="changeColorMode()" class="mx-2 cursor-pointer flex items-center">
|
||||
<div v-if="this.$colorMode.value === 'light'">
|
||||
<svg height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div v-else>
|
||||
<svg height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
<nuxt-link class="red hidden md:inline-block" to="/">
|
||||
<li class="hover:text-red-400 font-bold mx-2 cursor-pointer duration-300">
|
||||
{{ $t('header.home') }}
|
||||
</li>
|
||||
</nuxt-link>
|
||||
<nuxt-link class="orange hidden md:inline-block" to="/about">
|
||||
<li class="hover:text-orange-400 font-bold mx-2 cursor-pointer duration-300">
|
||||
<ul class="flex text-lg">
|
||||
<nuxt-link class="hidden md:inline-block" to="/about">
|
||||
<li class="nav-link">
|
||||
{{ $t('header.about') }}
|
||||
</li>
|
||||
</nuxt-link>
|
||||
<nuxt-link class="green hidden md:inline-block" to="/blog">
|
||||
<li class="hover:text-green-400 font-bold mx-2 cursor-pointer duration-300">
|
||||
<nuxt-link class="hidden md:inline-block" to="/blog">
|
||||
<li class="nav-link">
|
||||
{{ $t('header.blog') }}
|
||||
</li>
|
||||
</nuxt-link>
|
||||
<nuxt-link class="blue hidden md:inline-block" to="/work">
|
||||
<li class="hover:text-blue-400 font-bold mx-2 cursor-pointer duration-300">
|
||||
{{ $t('header.work') }}
|
||||
<nuxt-link class="hidden md:inline-block" to="/uses">
|
||||
<li class="nav-link">
|
||||
{{ $t('header.uses') }}
|
||||
</li>
|
||||
</nuxt-link>
|
||||
<nuxt-link class="purple hidden md:inline-block" to="/contact">
|
||||
<li class="hover:text-purple-400 font-bold mx-2 cursor-pointer duration-300">
|
||||
<nuxt-link class="hidden md:inline-block" to="/projects">
|
||||
<li class="nav-link">
|
||||
{{ $t('header.projects') }}
|
||||
</li>
|
||||
</nuxt-link>
|
||||
<nuxt-link class="hidden md:inline-block" to="/contact">
|
||||
<li class="nav-link">
|
||||
{{ $t('header.contact') }}
|
||||
</li>
|
||||
</nuxt-link>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="dark:text-white dark:bg-dark-900 text-sm z-50 bg-white md:hidden fixed bottom-0 left-0 w-full flex items-center justify-around h-20 border-t border-gray-200 border-solid navbar-bottom-items">
|
||||
<nuxt-link to="/" class="w-1/5 red">
|
||||
<li class="font-bold flex flex-col items-center justify-center">
|
||||
<ul class="dark:text-white dark:bg-black text-sm z-50 bg-white md:hidden fixed bottom-0 left-0 w-full flex items-center justify-around h-20 border-t border-gray-200 border-solid navbar-bottom-items">
|
||||
<nuxt-link to="/about" class="w-1/5 nav-link-mobile">
|
||||
<li class="font-medium flex flex-col items-center justify-center">
|
||||
<svg class="inline-block" height="20" width="20" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
|
||||
</svg>
|
||||
{{ $t('header.home') }}
|
||||
</li>
|
||||
</nuxt-link>
|
||||
<nuxt-link to="/about" class="w-1/5 orange">
|
||||
<li class="font-bold flex flex-col items-center justify-center">
|
||||
<svg class="inline-block" height="20" width="20" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
||||
</svg>
|
||||
{{ $t('header.about') }}
|
||||
</li>
|
||||
</nuxt-link>
|
||||
<nuxt-link to="/blog" class="w-1/5 green">
|
||||
<li class="font-bold flex flex-col items-center justify-center">
|
||||
<nuxt-link to="/blog" class="w-1/5 nav-link-mobile">
|
||||
<li class="font-medium flex flex-col items-center justify-center">
|
||||
<svg class="inline-block" height="20" width="20" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
||||
</svg>
|
||||
{{ $t('header.blog') }}
|
||||
</li>
|
||||
</nuxt-link>
|
||||
<nuxt-link to="/work" class="w-1/5 blue">
|
||||
<li class="font-bold flex flex-col items-center justify-center">
|
||||
<nuxt-link to="/uses" class="w-1/5 nav-link-mobile">
|
||||
<li class="font-medium flex flex-col items-center justify-center">
|
||||
<svg class="inline-block" height="20" width="20" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
|
||||
</svg>
|
||||
{{ $t('header.uses') }}
|
||||
</li>
|
||||
</nuxt-link>
|
||||
<nuxt-link to="/projects" class="w-1/5 nav-link-mobile">
|
||||
<li class="font-medium flex flex-col items-center justify-center">
|
||||
<svg class="inline-block" height="20" width="20" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||
</svg>
|
||||
{{ $t('header.work') }}
|
||||
{{ $t('header.projects') }}
|
||||
</li>
|
||||
</nuxt-link>
|
||||
<nuxt-link to="/contact" class="w-1/5 purple">
|
||||
<li class="font-bold flex flex-col items-center justify-center">
|
||||
<nuxt-link to="/contact" class="w-1/5 nav-link-mobile">
|
||||
<li class="font-medium flex flex-col items-center justify-center">
|
||||
<svg class="inline-block" height="20" width="20" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
@@ -100,18 +78,43 @@
|
||||
</nuxt-link>
|
||||
</ul>
|
||||
</nav>
|
||||
<div>
|
||||
<ul class="flex items-center">
|
||||
<li class="mx-1 h-9 w-9 cursor-pointer flex items-center justify-center p-1.5 rounded-xl hover:bg-gray-300 duration-200 dark:hover:bg-dark-850">
|
||||
<div v-if="this.$i18n.locale === 'en'" @click="changeLanguage('fr')">
|
||||
:fr:
|
||||
</div>
|
||||
<div v-else @click="changeLanguage('en')">
|
||||
🇬🇧
|
||||
</div>
|
||||
</li>
|
||||
<li @click="changeColorMode()" class="mx-1 h-9 w-9 cursor-pointer flex items-center p-1.5 rounded-xl hover:bg-gray-300 dark:hover:bg-dark-850 duration-200">
|
||||
<div v-if="this.$colorMode.preference === 'light'">
|
||||
<svg height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div v-else>
|
||||
<svg height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {onMounted, onUnmounted, ref, useContext, useRouter} from "@nuxtjs/composition-api";
|
||||
import {onMounted, onUnmounted, ref, useAsync, useContext, useRouter} from "@nuxtjs/composition-api";
|
||||
|
||||
export default {
|
||||
name: "Header",
|
||||
setup() {
|
||||
const {$colorMode} = useContext()
|
||||
const changeColorMode = () => {
|
||||
console.log("changed !")
|
||||
$colorMode.preference = $colorMode.value === 'light' ? 'dark' : 'light'
|
||||
}
|
||||
|
||||
@@ -130,12 +133,13 @@ export default {
|
||||
|
||||
const {app, $i18n} = useContext()
|
||||
const $router = useRouter()
|
||||
const changeLanguage = async (lang: 'fr' | 'en') => {
|
||||
await $i18n.setLocale(lang)
|
||||
const changeLanguage = (lang: 'fr' | 'en') => useAsync(() => {
|
||||
console.log("i18n changed")
|
||||
$i18n.setLocale(lang)
|
||||
if ($router.currentRoute.fullPath.includes('blog')) {
|
||||
await app.refresh()
|
||||
app.refresh()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
scrollPosition,
|
||||
@@ -152,31 +156,16 @@ export default {
|
||||
|
||||
.header-container {
|
||||
|
||||
.nuxt-link-active {
|
||||
&.green {
|
||||
@apply text-green-400;
|
||||
}
|
||||
&.blue {
|
||||
@apply text-blue-400;
|
||||
}
|
||||
.nav-link {
|
||||
@apply text-gray-500 dark:text-gray-400 hover:dark:text-white font-medium hover:text-black mx-4 cursor-pointer duration-300
|
||||
}
|
||||
|
||||
.nuxt-link-exact-active {
|
||||
&.red {
|
||||
@apply text-red-400;
|
||||
}
|
||||
&.orange {
|
||||
@apply text-orange-400;
|
||||
}
|
||||
&.green {
|
||||
@apply text-green-400;
|
||||
}
|
||||
&.blue {
|
||||
@apply text-blue-400;
|
||||
}
|
||||
&.purple {
|
||||
@apply text-purple-400;
|
||||
}
|
||||
.nav-link-mobile {
|
||||
@apply text-gray-500 dark:text-gray-400 hover:dark:text-white hover:text-black duration-300
|
||||
}
|
||||
|
||||
nav .nuxt-link-exact-active {
|
||||
@apply text-black dark:text-white;
|
||||
}
|
||||
|
||||
.navbar-bottom-items li {
|
||||
|
||||
@@ -43,7 +43,7 @@ export default {
|
||||
type: String
|
||||
},
|
||||
color: {
|
||||
default: "red-100",
|
||||
default: "red",
|
||||
type: String
|
||||
},
|
||||
link: {
|
||||
@@ -52,10 +52,24 @@ export default {
|
||||
}
|
||||
},
|
||||
setup(props: HomeLinkProps) {
|
||||
const getColor = computed(() => `hover:bg-${props.color}-400 dark:hover:bg-${props.color}-600 active:bg-${props.color}-400 dark:active:bg-${props.color}-600`)
|
||||
/**const getColor = computed(() => {
|
||||
return 'hover:bg-color-400 dark:hover:bg-color-600 active:bg-color-400 dark:active:bg-color-600'.replaceAll('color', props.color)
|
||||
})*/
|
||||
const getColor = computed(() => {
|
||||
switch (props.color) {
|
||||
case 'orange':
|
||||
return 'hover:bg-orange-400 dark:hover:bg-orange-600 active:bg-orange-400 dark:active:bg-orange-600'
|
||||
case 'purple':
|
||||
return 'hover:bg-purple-400 dark:hover:bg-purple-600 active:bg-purple-400 dark:active:bg-purple-600'
|
||||
case 'blue':
|
||||
return 'hover:bg-blue-400 dark:hover:bg-blue-600 active:bg-blue-400 dark:active:bg-blue-600'
|
||||
case 'green':
|
||||
return 'hover:bg-green-400 dark:hover:bg-green-600 active:bg-green-400 dark:active:bg-green-600'
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
getColor
|
||||
getColor,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
src/layouts/dev.vue
Normal file
13
src/layouts/dev.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<Nuxt />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "dev"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,11 +1,10 @@
|
||||
export default {
|
||||
header: {
|
||||
title: 'Arthur Danjou',
|
||||
home: 'Home',
|
||||
about: 'About',
|
||||
blog: 'Blog',
|
||||
work: 'Work',
|
||||
contact: 'Contact'
|
||||
projects: 'Projects',
|
||||
uses: 'Uses',
|
||||
},
|
||||
|
||||
footer: {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
export default {
|
||||
header: {
|
||||
title: 'Arthur Danjou',
|
||||
home: 'Accueil',
|
||||
about: 'Moi',
|
||||
blog: 'Blog',
|
||||
work: 'Travail',
|
||||
contact: 'Contact'
|
||||
contact: 'Contact',
|
||||
projects: 'Projets',
|
||||
uses: 'Usages'
|
||||
},
|
||||
|
||||
footer: {
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# PAGES
|
||||
|
||||
This directory contains your Application Views and Routes.
|
||||
The framework reads all the `*.vue` files inside this directory and creates the router of your application.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing).
|
||||
274
src/pages/about.vue
Normal file
274
src/pages/about.vue
Normal file
@@ -0,0 +1,274 @@
|
||||
<template>
|
||||
<main class="about flex flex-col items-center px-5 xl:px-64">
|
||||
<PageTitle
|
||||
title="part.about"
|
||||
color="orange"
|
||||
>
|
||||
<svg class="inline-block icon" height="40" width="40" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
||||
</svg>
|
||||
</PageTitle>
|
||||
<div class="flex flex-col md:flex-row justify-around items-center py-8">
|
||||
<div>
|
||||
<img class="logo-img rounded-full my-5" src="@/assets/images/Logo.jpg" alt="It's me !" />
|
||||
</div>
|
||||
<div class="ml-2 text-lg leading-6 md:w-2/3 text-justify">
|
||||
<p>{{ $t('about.banner.hello') }} <span class="text-orange-400 font-bold">Arthur DANJOU</span> 👋.</p> <br/>
|
||||
<p>{{ $t('about.banner.1')}}</p> <br/>
|
||||
<p>{{ $t('about.banner.2') }}</p> <br/>
|
||||
<p>{{ $t('about.banner.3') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full mb-10 mt-4">
|
||||
<h3 class="font-bold text-2xl md:text-4xl mb-3">
|
||||
{{ $t('about.title.skills') }}
|
||||
<svg class="inline icon" height="32" width="32" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
|
||||
</svg>
|
||||
</h3>
|
||||
<div class="flex flex-row w-full overflow-x-auto md:overflow-x-hidden md:flex-wrap space-x-4 md:space-x-0 md:justify-start">
|
||||
<div v-if="skills" v-for="skill in skills">
|
||||
<Skill
|
||||
:skill="skill.title"
|
||||
:color="skill.color"
|
||||
:cover="skill.cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full mb-10">
|
||||
<h3 class="font-bold text-2xl md:text-4xl">
|
||||
{{ $t('about.title.interests') }}
|
||||
<svg height="32" width="32" class="inline icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 18.657A8 8 0 016.343 7.343S7 9 9 10c0-2 .5-5 2.986-7C14 5 16.09 5.777 17.656 7.343A7.975 7.975 0 0120 13a7.975 7.975 0 01-2.343 5.657z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.879 16.121A3 3 0 1012.015 11L11 14H9c0 .768.293 1.536.879 2.121z" />
|
||||
</svg>
|
||||
</h3>
|
||||
<div>
|
||||
<ul class="text-xl">
|
||||
<li class="my-2">
|
||||
{{ $t('about.title.technologies') }}
|
||||
<svg class="inline icon" height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="my-2">
|
||||
{{ $t('about.interests.dev') }}
|
||||
<svg class="inline icon" height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="my-2">
|
||||
{{ $t('about.interests.devops') }}
|
||||
<svg class="inline icon" height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="my-2">
|
||||
{{ $t('about.interests.startups') }}
|
||||
<svg class="inline icon" height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="my-2">
|
||||
{{ $t('about.interests.sysadmin') }}
|
||||
<svg class="inline icon" height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="my-2">
|
||||
{{ $t('about.interests.trips') }}
|
||||
<svg class="inline icon" height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="my-2">
|
||||
{{ $t('about.interests.moto') }}
|
||||
<svg class="inline icon" height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636" />
|
||||
</svg>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full mb-10">
|
||||
<h3 class="font-bold text-2xl md:text-4xl">
|
||||
{{ $t('about.title.languages') }}
|
||||
<svg class="inline icon" height="32" width="32" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129" />
|
||||
</svg>
|
||||
</h3>
|
||||
<div>
|
||||
<table class="text-base text-xl">
|
||||
<tr>
|
||||
<td class="font-bold py-2 pr-4">{{ $t('about.languages.fr')}} 🇫🇷</td>
|
||||
<td class="py-2 px-4">{{ $t('about.languages.native') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-bold py-2 pr-4">{{ $t('about.languages.en')}} 🇬🇧</td>
|
||||
<td class="py-2 px-4">{{ $t('about.languages.fluent') }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full mb-10">
|
||||
<h3 class="font-bold text-2xl md:text-4xl mb-3">
|
||||
{{ $t('about.title.formations') }}
|
||||
<svg class="inline icon" height="32" width="32" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 14l9-5-9-5-9 5 9 5zm0 0l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14zm-4 6v-7.5l4-2.222" />
|
||||
</svg>
|
||||
</h3>
|
||||
<div v-if="formations" v-for="formation in formations">
|
||||
<Formation
|
||||
:title="formation.title"
|
||||
:description="formation.description"
|
||||
:location="formation.location"
|
||||
:begin="formation.begin_date"
|
||||
:end="formation.end_date" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full mb-10">
|
||||
<h3 class="font-bold text-2xl md:text-4xl mb-3">
|
||||
{{ $t('about.title.experiences') }}
|
||||
<svg class="inline icon" height="32" width="32" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 13v-1m4 1v-3m4 3V8M8 21l4-4 4 4M3 4h18M4 4h16v12a1 1 0 01-1 1H5a1 1 0 01-1-1V4z" />
|
||||
</svg>
|
||||
</h3>
|
||||
<div v-if="experiences" v-for="experience in experiences">
|
||||
<Experience
|
||||
:title="experience.title"
|
||||
:company="experience.company"
|
||||
:location="experience.location"
|
||||
:begin="experience.begin_date"
|
||||
:end="experience.end_date" />
|
||||
</div>
|
||||
</div>
|
||||
<nuxt-link to="/cv">
|
||||
<div class="flex justify-center items-center font-bold py-4 px-6 bg-orange-400 hover:bg-orange-600 cursor-pointer duration-500 rounded-full dark:text-black">
|
||||
{{ $t('about.cv') }}
|
||||
<svg class="inline icon" height="32" width="32" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V8a2 2 0 00-2-2h-5m-4 0V5a2 2 0 114 0v1m-4 0a2 2 0 104 0m-5 8a2 2 0 100-4 2 2 0 000 4zm0 0c1.306 0 2.417.835 2.83 2M9 14a3.001 3.001 0 00-2.83 2M15 11h3m-3 4h2" />
|
||||
</svg>
|
||||
</div>
|
||||
</nuxt-link>
|
||||
<div class="mt-10 border-t-2 border-black dark:border-white border-solid w-full" />
|
||||
<PageTitle
|
||||
title="about.environment"
|
||||
color="orange"
|
||||
>
|
||||
<svg class="inline icon" height="40" width="40" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 4a2 2 0 114 0v1a1 1 0 001 1h3a1 1 0 011 1v3a1 1 0 01-1 1h-1a2 2 0 100 4h1a1 1 0 011 1v3a1 1 0 01-1 1h-3a1 1 0 01-1-1v-1a2 2 0 10-4 0v1a1 1 0 01-1 1H7a1 1 0 01-1-1v-3a1 1 0 00-1-1H4a2 2 0 110-4h1a1 1 0 001-1V7a1 1 0 011-1h3a1 1 0 001-1V4z" />
|
||||
</svg>
|
||||
</PageTitle>
|
||||
<p class="text-lg leading-6 text-justify pb-8">{{ $t('about.env.description') }}</p>
|
||||
<EnvGroup>
|
||||
<EnvTitle title="about.env.ide">
|
||||
<svg class="inline icon" height="32" width="32" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" />
|
||||
</svg>
|
||||
</EnvTitle>
|
||||
<EnvList>
|
||||
<EnvListItem title="about.ide.java" content="Intellij Idea Ultimate" link="https://www.jetbrains.com/fr-fr/idea/"/>
|
||||
<EnvListItem title="about.ide.web" content="WebStorm" link="https://www.jetbrains.com/fr-fr/webstorm/"/>
|
||||
<EnvListItem title="about.ide.go" content="GoLand" link="https://www.jetbrains.com/fr-fr/go/"/>
|
||||
<EnvListItem title="about.ide.db" content="DataGrip" link="https://www.jetbrains.com/fr-fr/datagrip/"/>
|
||||
<EnvListItem title="about.ide.all" content="Jetbrains Toolbox" link="https://www.jetbrains.com/toolbox-app/"/>
|
||||
<EnvListItem title="about.police" content="Jetbrains Mono" link="https://www.jetbrains.com/lp/mono/"/>
|
||||
<EnvListItem title="about.console" content="Terminus" link="https://github.com/Eugeny/terminus"/>
|
||||
<EnvListItem title="about.wsl_2" content="Ubuntu 20.04" link="https://www.microsoft.com/en-us/p/ubuntu-2004-lts/9n6svws3rx71?activetab=pivot:overviewtab"/>
|
||||
</EnvList>
|
||||
</EnvGroup>
|
||||
<EnvGroup>
|
||||
<EnvTitle title="about.env.apps">
|
||||
<svg class="inline icon" height="32" width="32" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||
</svg>
|
||||
</EnvTitle>
|
||||
<EnvList>
|
||||
<EnvListItem title="about.email_client" content="Courrier by Microsoft" link="https://www.microsoft.com/fr-fr/p/courrier-et-calendrier/9wzdncrfhvqm?activetab=pivot:overviewtab"/>
|
||||
<EnvListItem title="about.vpn_client" content="Pritunl" link="https://pritunl.com/"/>
|
||||
<EnvListItem title="about.ftp_client" content="WinSCP" link="https://winscp.net/eng/download.php"/>
|
||||
<EnvListItem title="about.web_client" content="FireFox Developer Edition" link="https://www.mozilla.org/fr/firefox/developer/"/>
|
||||
<EnvListItem title="about.organisation_tool" content="Notion" link="https://www.notion.so/"/>
|
||||
<EnvListItem title="about.organisation_tool" content="Trello" link="https://www.trello.com/"/>
|
||||
<EnvListItem title="about.design_tool" content="Affinity Designer" link="https://affinity.serif.com/fr/designer/"/>
|
||||
<EnvListItem title="about.communication_tool" content="Slack" link="https://slack.com/intl/fr-fr/"/>
|
||||
<EnvListItem title="about.communication_tool" content="Discord" link="https://www.discord.com/"/>
|
||||
<EnvListItem title="about.communication_tool" content="Mattermost" link="https://mattermost.com/"/>
|
||||
</EnvList>
|
||||
</EnvGroup>
|
||||
<EnvGroup>
|
||||
<EnvTitle title="about.env.hosting">
|
||||
<svg class="inline icon" height="32" width="32" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01" />
|
||||
</svg>
|
||||
</EnvTitle>
|
||||
<EnvList>
|
||||
<EnvListItem title="about.hosting.vps" content="PulseHeberg" link="https://pulseheberg.com/"/>
|
||||
<EnvListItem title="about.hosting.ndd" content="OVH" link="https://ovh.com/"/>
|
||||
</EnvList>
|
||||
</EnvGroup>
|
||||
<EnvGroup>
|
||||
<EnvTitle title="about.env.setup">
|
||||
<svg class="inline icon" height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" />
|
||||
</svg>
|
||||
</EnvTitle>
|
||||
<EnvList>
|
||||
<EnvListItem title="about.setup.desk" content="Ikea"/>
|
||||
<EnvListItem title="about.setup.phone" content="Samsung Galaxy Note 8" link="https://www.samsung.com/smartphones/galaxy-note8/"/>
|
||||
<EnvListItem title="about.setup.computer" content="Asus i5, 8Go Ram, GTX 950, 1To HDD"/>
|
||||
<EnvListItem title="about.setup.screen" content="iiyama ProLite E2283HS" link="https://iiyama.com/fr/fr/produits/prolite-e2283hs-b3/"/>
|
||||
<EnvListItem title="about.setup.keyboard" content="Microsoft"/>
|
||||
<EnvListItem title="about.setup.mouse" content="Roccat Kova" link="https://fr.roccat.org/Mice/Kova-AIMO"/>
|
||||
<EnvListItem title="about.setup.headphone" content="Apple Airpods" link="https://www.apple.com/fr/airpods/"/>
|
||||
<EnvListItem title="about.setup.microphone" content="Turtle Beach px22" link="https://www.amazon.fr/Turtle-Beach-PX22-casque-gaming/dp/B00BDS415I"/>
|
||||
</EnvList>
|
||||
</EnvGroup>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {useAsync, useContext} from "@nuxtjs/composition-api";
|
||||
import {Experience, Formation, Skill} from "../../@types/types";
|
||||
|
||||
export default {
|
||||
name: "about",
|
||||
head() {
|
||||
return {
|
||||
title: 'About me - Arthur Danjou'
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
const {$content} = useContext()
|
||||
|
||||
const skills = useAsync(() => {
|
||||
return $content('skills').fetch<Skill>()
|
||||
})
|
||||
const experiences = useAsync(() => {
|
||||
return $content('experiences')
|
||||
.sortBy('end_date', 'desc')
|
||||
.fetch<Experience>()
|
||||
})
|
||||
const formations = useAsync(() => {
|
||||
return $content('formations')
|
||||
.sortBy('end_date', 'desc')
|
||||
.fetch<Formation>()
|
||||
})
|
||||
|
||||
return {
|
||||
skills,
|
||||
experiences,
|
||||
formations
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.about {
|
||||
.logo-img {
|
||||
height: 20rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
201
src/pages/blog/_slug.vue
Normal file
201
src/pages/blog/_slug.vue
Normal file
@@ -0,0 +1,201 @@
|
||||
<template>
|
||||
<main class="blog flex flex-col items-center px-5 xl:px-96 mb-16 md:mb-32">
|
||||
<div class="mt-8 md:mt-32 flex flex-col justify-around py-8 w-full">
|
||||
<div>
|
||||
<div class="mb-4 flex">
|
||||
<nuxt-link to="/blog" class="back-arrow flex">
|
||||
<div class="duration-300 arrow">
|
||||
<svg height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-2">
|
||||
{{ $t('blog.read.back') }}
|
||||
</div>
|
||||
</nuxt-link>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="text-3xl md:text-5xl font-bold">
|
||||
{{ post.title }}
|
||||
</h1>
|
||||
<h3 class="text-xl text-gray-800 dark:text-dark-100 my-4 md:mt-8">
|
||||
{{ post.description }}
|
||||
</h3>
|
||||
<div class="flex flex-row justify-between w-full md:w-2/3 mb-12">
|
||||
<div>
|
||||
<p class="uppercase text-sm font-bold text-gray-800 dark:text-dark-100">Date</p>
|
||||
<p>{{ formatDate }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="uppercase text-sm font-bold text-gray-800 dark:text-dark-100">{{ $t('blog.read.time') }}</p>
|
||||
<p>{{ post.reading_time }} min</p>
|
||||
</div>
|
||||
<div>
|
||||
<p :class="post.tags.length === 0 ? 'opacity-0': 'opacity-100'" class="uppercase text-sm font-bold text-gray-800 dark:text-dark-100">Tags</p>
|
||||
<p>{{ formatTags }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<div class="flex justify-center w-full h-auto">
|
||||
<img class="w-full h-auto" :src="require(`@/assets/images/posts/${post.cover}.png`)" alt="Cover Img" />
|
||||
</div>
|
||||
</div>
|
||||
<nuxt-content
|
||||
:document="post"
|
||||
class="my-6 md:my-12 w-full text-justify max-w-none
|
||||
prose prose-sm sm:prose lg:prose-lg lg:max-w-none sm:max-w-none
|
||||
dark:prose-dark dark:max-w-none"
|
||||
/>
|
||||
<p class="mb-3">
|
||||
{{ $t('blog.read.thanks') }}
|
||||
</p>
|
||||
<div class="flex flex-col md:flex-row">
|
||||
<div class="flex items-center mb-2 md:mb-0">
|
||||
<div
|
||||
@click="handleLike"
|
||||
class="h-16 end-blog flex flex-row justify-center items-center cursor-pointer duration-300 text-3xl p-3 border-solid border mr-2"
|
||||
:class="liked ? 'border-red-500 dark:border-red-500 hover:border-gray-400 dark:hover:border-dark-200' : 'border-gray-400 dark:border-dark-200 hover:border-red-500 dark:hover:border-red-500'"
|
||||
>
|
||||
<div class="mr-2 lining-nums">
|
||||
{{ likes }}
|
||||
</div>
|
||||
<div class="icon-hover inline">❤</div>
|
||||
</div>
|
||||
<a
|
||||
target="_blank"
|
||||
:href="'https://twitter.com/intent/tweet?url=https%3A%2F%2Farthurdanjou.fr%2Fblog%2F' + this.post.slug + '&text=' + $t('blog.tweet') + ' ' + post.title"
|
||||
class="h-16 mr-2 end-blog cursor-pointer duration-300 text-3xl p-3 border-solid border border-gray-400 dark:border-dark-200 hover:border-cyan-500 dark:hover:border-cyan-400 justify-center items-center"
|
||||
>
|
||||
<img class="inline img icon-hover" src="@/assets/images/socials/twitter.svg" alt="Twitter logo" height="40" width="40" />
|
||||
</a>
|
||||
<div @click="scrollToTop"
|
||||
class="h-16 mr-2 end-blog cursor-pointer duration-300 text-3xl p-3 border-solid border border-gray-400 dark:border-dark-200 hover:border-dark-800 dark:hover:border-white">
|
||||
<svg class="inline icon-hover" width="40" height="40" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 10l7-7m0 0l7 7m-7-7v18" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<nuxt-link to="/contact"
|
||||
class="h-16 mr-2 end-blog cursor-pointer duration-300 text-3xl p-3 border-solid border border-gray-400 dark:border-dark-200 hover:border-dark-800 dark:hover:border-white"
|
||||
>
|
||||
<svg class="inline icon-hover" width="40" height="40" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z" />
|
||||
</svg>
|
||||
</nuxt-link>
|
||||
<div
|
||||
@click="copyToClipBoard"
|
||||
class="h-16 end-blog cursor-pointer duration-300 text-3xl p-3 border-solid border border-gray-400 dark:border-dark-200 hover:border-dark-800 dark:hover:border-white"
|
||||
>
|
||||
<svg class="inline icon-hover" height="40" width="40" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2" />
|
||||
</svg>
|
||||
</div>
|
||||
<div v-if="isCopied" class="p-3 relative text-sm flex justify-center items-center text-green-500">
|
||||
{{ $t('copied') }}
|
||||
<svg class="inline icon" width="25" height="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "blog",
|
||||
head() {
|
||||
return {
|
||||
title: 'Blog - Arthur Danjou - ' + this.post.title
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
likes: 0,
|
||||
post: null,
|
||||
|
||||
isCopied: false,
|
||||
liked: false
|
||||
}
|
||||
},
|
||||
async asyncData({ params, $content, app, $axios, error }) {
|
||||
const post = await $content(`articles/${app.i18n.locale}`, params.slug)
|
||||
.fetch()
|
||||
.catch(() => {
|
||||
error({ statusCode: 404, message: "Post not found" });
|
||||
});
|
||||
const {data: likes} = await $axios.get(`posts/${params.slug}`)
|
||||
const liked = await $axios.get(`posts/is/${params.slug}`)
|
||||
return {
|
||||
post,
|
||||
likes,
|
||||
liked: liked.data !== 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
scrollToTop() {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: "smooth"
|
||||
})
|
||||
},
|
||||
copyToClipBoard() {
|
||||
navigator.clipboard.writeText('https://arthurdanjou.fr/blog/' + this.post.slug)
|
||||
this.isCopied = true
|
||||
setTimeout(() => {
|
||||
this.isCopied = false
|
||||
}, 7000)
|
||||
},
|
||||
async handleLike() {
|
||||
if (this.liked) {
|
||||
const {data} = await this.$axios.post(`posts/${this.post.slug}/unlike`)
|
||||
if (data.code === 200) {
|
||||
this.liked = false
|
||||
this.likes = data.post.likes
|
||||
}
|
||||
} else {
|
||||
const {data} = await this.$axios.post(`posts/${this.post.slug}/like`)
|
||||
if (data.code === 200) {
|
||||
this.liked = true
|
||||
this.likes = data.post.likes
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
formatDate() {
|
||||
const dateFormat = this.post.date.split('-')
|
||||
return dateFormat[0] + " " + this.$t('month.' + dateFormat[1]) + " " + dateFormat[2]
|
||||
},
|
||||
formatTags() {
|
||||
let tags = ""
|
||||
this.post.tags.map(tag => {
|
||||
tags += this.$t(tag) + ", "
|
||||
})
|
||||
return tags.substring(0, tags.length - 2)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.blog {
|
||||
.back-arrow:hover .arrow {
|
||||
transform: translate(-8px, -1px);
|
||||
}
|
||||
|
||||
.arrow {
|
||||
transform: translate(3px, -1px);
|
||||
}
|
||||
|
||||
.end-blog .icon-hover {
|
||||
@apply duration-300
|
||||
}
|
||||
|
||||
.end-blog:hover .icon-hover {
|
||||
@apply transform scale-105;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
276
src/pages/blog/index.vue
Normal file
276
src/pages/blog/index.vue
Normal file
@@ -0,0 +1,276 @@
|
||||
<template>
|
||||
<main class="blog flex flex-col items-center px-5 xl:px-64">
|
||||
<PageTitle
|
||||
title="part.blog"
|
||||
color="green"
|
||||
>
|
||||
<svg class="inline-block icon" height="40" width="40" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
|
||||
</svg>
|
||||
</PageTitle>
|
||||
<div class="flex flex-col mt-8 w-full md:w-1/2">
|
||||
<h1
|
||||
v-if="current_tag === ''"
|
||||
class="text-lg mb-2"
|
||||
>{{ $t('blog.tags.search') }}</h1>
|
||||
<div
|
||||
@click="resetPosts"
|
||||
v-if="current_tag !== ''"
|
||||
class="w-full"
|
||||
>
|
||||
<div class="w-full home-arrow flex cursor-pointer font-bold mb-3">
|
||||
<div class="arrow duration-300 mr-2">
|
||||
<svg height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||
</svg>
|
||||
</div>
|
||||
{{ $t('blog.tags.back') }}
|
||||
</div>
|
||||
<div class="w-full">
|
||||
{{ $t('blog.tags.current', { tag: $t(current_tag)}) }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="flex flex-row w-full overflow-x-scroll md:overflow-x-hidden md:flex-wrap space-x-3 md:space-x-0">
|
||||
<div v-for="tag in tags">
|
||||
<div
|
||||
class="mb-3 md:mr-4 border-b-2 border-opacity-0 hover:border-opacity-100 border-green-400 border-solid duration-300 cursor-pointer font-black"
|
||||
@click="fetchPostsByTag(tag.slug)"
|
||||
>
|
||||
{{ $t(tag.slug) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h1 v-if="posts.length === 0" class="text-xl font-bold text-center my-8 w-full">{{ $t('blog.no_posts') }}</h1>
|
||||
<div class="w-full xl:w-1/2" v-else>
|
||||
<div class="flex flex-col justify-around items-center py-8 w-full">
|
||||
<div class="w-full" v-for="post in posts">
|
||||
<nuxt-link :to="'/blog/' + post.slug">
|
||||
<Post
|
||||
:title="post.title"
|
||||
:reading_time="post.reading_time"
|
||||
:description="post.description"
|
||||
:tags="displayTags(post.tags)"
|
||||
:cover="post.cover"
|
||||
:date="post.date"
|
||||
:lightBg="post.background"
|
||||
/>
|
||||
</nuxt-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex flex-row justify-between w-full mb-4" v-if="(next || prev) && this.postsCount > 5">
|
||||
<div
|
||||
class="duration-300 flex w-1/2 px-5 py-4 justify-center items-center"
|
||||
:class="prev === null ? 'opacity-0': 'opacity-100'"
|
||||
>
|
||||
<div class="flex items-center duration-300 prev-arrow" @click="prevPage">
|
||||
<div class="arrow duration-300">
|
||||
<svg class="inline icon" height="30" width="30" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 15l-3-3m0 0l3-3m-3 3h8M3 12a9 9 0 1118 0 9 9 0 01-18 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="inline ml-4 font-bold">{{ $t('blog.pagination.prev') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="duration-300 flex w-1/2 px-5 py-4 justify-center items-center"
|
||||
:class="next === null ? 'opacity-0': 'opacity-100'"
|
||||
>
|
||||
<div class="flex items-center duration-300 suiv-arrow" @click="nextPage">
|
||||
<div class="mr-4 font-bold">{{ $t('blog.pagination.next') }}</div>
|
||||
<div class="inline arrow duration-300">
|
||||
<svg class="inline icon" height="30" width="30" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Post from "~/components/Post";
|
||||
import PageTitle from "~/components/PageTitle";
|
||||
export default {
|
||||
name: "blog",
|
||||
components: {PageTitle, Post},
|
||||
head() {
|
||||
return {
|
||||
title: 'Blog - Arthur Danjou'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
postsCount: 0,
|
||||
page: 0,
|
||||
current_tag: '',
|
||||
posts: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
displayTags(tags) {
|
||||
const tags_label = []
|
||||
if (tags.length > 0) {
|
||||
tags.map(tag => {
|
||||
tags_label.push(tag)
|
||||
})
|
||||
}
|
||||
return tags_label
|
||||
},
|
||||
async fetchPostsByTag(tag) {
|
||||
this.current_tag = tag
|
||||
this.page = 0
|
||||
await this.fetchPosts()
|
||||
if (this.posts.length !== 0) {
|
||||
await this.fetchPrevAndNext()
|
||||
} else {
|
||||
this.next = null
|
||||
this.prev = null
|
||||
}
|
||||
},
|
||||
async resetPosts() {
|
||||
this.current_tag = ''
|
||||
this.posts = await this.$content(`articles/${this.$i18n.locale}`)
|
||||
.sortBy('date', 'asc')
|
||||
.limit(5)
|
||||
.fetch()
|
||||
},
|
||||
async nextPage() {
|
||||
this.page++
|
||||
await this.fetchPosts()
|
||||
await this.fetchPrevAndNext()
|
||||
|
||||
window.scrollTo({
|
||||
top: 100,
|
||||
behavior: "smooth"
|
||||
})
|
||||
},
|
||||
async prevPage() {
|
||||
this.page--
|
||||
await this.fetchPosts()
|
||||
await this.fetchPrevAndNext()
|
||||
window.scrollTo({
|
||||
top: 100,
|
||||
behavior: "smooth"
|
||||
})
|
||||
},
|
||||
async fetchPosts() {
|
||||
let postsTemp = []
|
||||
if (this.current_tag === "") {
|
||||
postsTemp = await this.$content(`articles/${this.$i18n.locale}`)
|
||||
.sortBy('date', 'asc')
|
||||
.limit(5)
|
||||
.skip(this.page * 5)
|
||||
.fetch()
|
||||
} else {
|
||||
postsTemp = await this.$content(`articles/${this.$i18n.locale}`)
|
||||
.sortBy('date', 'asc')
|
||||
.limit(5)
|
||||
.skip(this.page * 5)
|
||||
.where({
|
||||
tags: {
|
||||
$contains: this.current_tag
|
||||
}
|
||||
})
|
||||
.fetch()
|
||||
}
|
||||
|
||||
const posts = []
|
||||
postsTemp.map(post => {
|
||||
posts.push(post)
|
||||
})
|
||||
this.posts = posts
|
||||
},
|
||||
async fetchPrevAndNext() {
|
||||
const [_, next] = await this.$content(`articles/${this.$i18n.locale}`)
|
||||
.surround(this.posts[this.posts.length - 1].slug, {
|
||||
before: 1,
|
||||
after: 1
|
||||
})
|
||||
.fetch()
|
||||
const [prev, __] = await this.$content(`articles/${this.$i18n.locale}`)
|
||||
.skip(this.page)
|
||||
.surround(this.posts[0].slug, {
|
||||
before: 1,
|
||||
after: 1
|
||||
})
|
||||
.fetch()
|
||||
|
||||
this.prev = null
|
||||
this.next = null
|
||||
if (this.posts.length === 5) {
|
||||
this.next = next
|
||||
}
|
||||
if (this.page > 0) {
|
||||
this.prev = prev
|
||||
}
|
||||
}
|
||||
},
|
||||
async asyncData ({ $content, app }) {
|
||||
const tags = await $content('tags').fetch()
|
||||
const locale = await app.i18n.locale
|
||||
|
||||
const postsTemp = await $content(`articles/${locale}`)
|
||||
.sortBy('date', 'asc')
|
||||
.limit(5)
|
||||
.fetch()
|
||||
|
||||
const posts = []
|
||||
postsTemp.map(post => {
|
||||
posts.push(post)
|
||||
})
|
||||
|
||||
let prev = null
|
||||
let next = null
|
||||
|
||||
if (posts.length > 0) {
|
||||
const [_, nextTemp] = await $content(`articles/${locale}`)
|
||||
.surround(posts[posts.length - 1].slug, {
|
||||
before: 1,
|
||||
after: 1
|
||||
})
|
||||
.fetch()
|
||||
|
||||
const [prevTemp, __] = await $content(`articles/${locale}`)
|
||||
.surround(posts[0].slug, {
|
||||
before: 1,
|
||||
after: 1
|
||||
})
|
||||
.fetch()
|
||||
|
||||
next = nextTemp
|
||||
prev = prevTemp
|
||||
}
|
||||
|
||||
return {
|
||||
posts,
|
||||
postsCount: posts.length,
|
||||
tags,
|
||||
prev,
|
||||
next
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.blog {
|
||||
.home-arrow:hover .arrow {
|
||||
transform: translateX(-15px);
|
||||
}
|
||||
|
||||
.prev-arrow:hover .arrow {
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
|
||||
.suiv-arrow:hover .arrow {
|
||||
transform: translateX(15px);
|
||||
}
|
||||
|
||||
.arrow {
|
||||
transform: translateX(-3px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
162
src/pages/contact.vue
Normal file
162
src/pages/contact.vue
Normal file
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<main class="contact flex flex-col items-center px-5 xl:px-64">
|
||||
<PageTitle
|
||||
title="part.contact"
|
||||
color="purple"
|
||||
>
|
||||
<svg class="inline-block icon" height="40" width="40" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
</PageTitle>
|
||||
<div class="w-full lg:w-3/4 mb-10 mt-4">
|
||||
<h1 class="font-bold text-gray-700 text-xl md:text-3xl my-4 dark:text-dark-200">{{ $t('contact.newsletter.title') }}</h1>
|
||||
<h3 class="text-md md:text-lg">
|
||||
{{ $t('contact.newsletter.description') }} <br>
|
||||
<span class="font-bold self-start">{{ $t('contact.newsletter.unfollow') }}</span>
|
||||
</h3>
|
||||
<form class="flex flex-col lg:flex-row mt-4 w-full">
|
||||
<div class="flex flex-col lg:flex-row">
|
||||
<div class="mb-3 lg:mr-4 w-full md:w-auto">
|
||||
<input v-model="form.name"
|
||||
class="select-text w-full placeholder-purple-700 dark:focus:bg-dark-800 dark:placeholder-purple-400 focus:bg-white duration-300 px-3 py-2 bg-purple-50 dark:bg-dark-900 border border-solid border-purple-700 rounded-lg"
|
||||
type="text"
|
||||
:placeholder="$t('contact.form.name')"
|
||||
required
|
||||
id="name"/>
|
||||
</div>
|
||||
<div class="mb-3 lg:mr-4 w-full md:w-auto">
|
||||
<input v-model="form.name"
|
||||
class="select-text w-full placeholder-purple-700 dark:focus:bg-dark-800 dark:placeholder-purple-400 focus:bg-white duration-300 px-3 py-2 bg-purple-50 dark:bg-dark-900 border border-solid border-purple-700 rounded-lg"
|
||||
type="email"
|
||||
:placeholder="$t('contact.form.mail')"
|
||||
required
|
||||
id="email"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 self-center">
|
||||
<button @click.prevent="handleForm" class="dark:text-black font-bold px-3 py-2 bg-purple-400 hover:bg-purple-500 cursor-pointer duration-300 rounded-lg btn">
|
||||
{{ $t('contact.form.submit')}}
|
||||
<svg class="inline icon" height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div v-if="error" class="flex">
|
||||
<div class="rounded-xl px-3 py-2 bg-red-300 font-bold dark:text-black">
|
||||
{{ $t('contact.form.error') }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="success" class="flex">
|
||||
<div class="rounded-xl px-3 py-2 bg-green-300 font-bold dark:text-black">
|
||||
{{ $t('contact.form.success', { email: form.email }) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full lg:w-3/4 mb-10 mt-4">
|
||||
<h1 class="font-bold text-gray-700 text-xl md:text-3xl my-4 dark:text-dark-100">
|
||||
{{ $t('contact.how_to.title') }}
|
||||
</h1>
|
||||
<h3 class="text-md md:text-lg">
|
||||
{{ $t('contact.how_to.description') }}
|
||||
</h3>
|
||||
<div class="mt-4 text-lg flex">
|
||||
<div class="flex email duration-300 text-purple-500 hover:text-purple-700 cursor-pointer">
|
||||
<a class="mr-2" href="mailto:me@arthurdanjou.fr?subject=Please enter here your project name">
|
||||
me@arthurdanjou.fr
|
||||
</a>
|
||||
<div class="arrow duration-300">
|
||||
<svg class="inline icon" height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full lg:w-3/4 mb-10 mt-4">
|
||||
<h1 class="font-bold text-gray-700 text-xl md:text-3xl my-4 dark:text-dark-100">
|
||||
{{ $t('contact.available.title') }}
|
||||
</h1>
|
||||
<h3 class="text-lg md:text-lg">
|
||||
{{ $t('contact.available.description') }}
|
||||
</h3>
|
||||
<div class="my-4 text-purple-500">
|
||||
{{ $t('contact.available.start') }}
|
||||
<span v-if="info && info.hiring.status" class="py-1 px-2 font-bold rounded-full m-0.5" :class="getColor">{{ $t('hiring.status.' + info.hiring.status) }}</span>
|
||||
{{ $t('contact.available.end') }}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {computed, ref, useAsync, useContext} from "@nuxtjs/composition-api";
|
||||
import {FormData, InfoData} from "../../@types/types";
|
||||
|
||||
export default {
|
||||
name: "contact",
|
||||
setup() {
|
||||
const {$content} = useContext()
|
||||
const info = useAsync(() => {
|
||||
return $content('infos').fetch<InfoData>()
|
||||
})
|
||||
|
||||
const hiring_color = info && info.value?.values.hiring.color
|
||||
const getColor = computed(() => `bg-${hiring_color}-200 text-${hiring_color}-500`)
|
||||
|
||||
const error = ref(false)
|
||||
const success = ref(false)
|
||||
|
||||
const {$axios} = useContext()
|
||||
const form = ref({} as FormData)
|
||||
const handleForm = useAsync(
|
||||
async () => {
|
||||
await $axios.post('subscribers',
|
||||
{
|
||||
email: form.value.email,
|
||||
name: form.value.name,
|
||||
})
|
||||
.then(() => {
|
||||
success.value = true
|
||||
setTimeout(() => {
|
||||
success.value = false
|
||||
form.value.email = ''
|
||||
form.value.name = ''
|
||||
}, 5000)
|
||||
}).catch(() => {
|
||||
error.value = true
|
||||
setTimeout(() => {
|
||||
error.value = false
|
||||
}, 5000)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
info,
|
||||
getColor,
|
||||
handleForm,
|
||||
success,
|
||||
error,
|
||||
form
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.contact {
|
||||
.email:hover .arrow {
|
||||
transform: translateX(15px);
|
||||
}
|
||||
|
||||
.link {
|
||||
@apply mr-5 duration-300;
|
||||
|
||||
&:hover {
|
||||
@apply border-b-2 border-opacity-0 dark:border-opacity-0 dark:hover:border-opacity-100 hover:border-opacity-100 border-black dark:border-white border-solid;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
14
src/pages/dev.vue
Normal file
14
src/pages/dev.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<Header />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "dev",
|
||||
layout: 'dev'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
13
src/pages/uses.vue
Normal file
13
src/pages/uses.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "uses"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
150
src/pages/work/_slug.vue
Normal file
150
src/pages/work/_slug.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<main class="px-5 xl:px-64 mb-16 md:mb-32">
|
||||
<div class="w-full flex flex-col lg:flex-row items-center md:items-start mt-8 md:mt-32">
|
||||
<div class="w-full lg:w-1/2 flex flex-col items-center">
|
||||
<div class="md:mb-24">
|
||||
<div class="mb-4 flex">
|
||||
<nuxt-link to="/work" class="back-arrow flex">
|
||||
<div class="duration-300 arrow">
|
||||
<svg height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-2">
|
||||
{{ $t('work.go_back') }}
|
||||
</div>
|
||||
</nuxt-link>
|
||||
</div>
|
||||
</div>
|
||||
<img class="w-72 rounded-xl" :src="require(`@/assets/images/works/${work.cover}.png`)" alt="Project Img" />
|
||||
<a
|
||||
class="mt-4 py-3 px-6 rounded-full cursor-pointer duration-300 mb-10 lg:mb-0"
|
||||
:class="getColor"
|
||||
:href="work.url"
|
||||
>{{work.url.replace('https://', '').replace('http://', '')}}</a>
|
||||
</div>
|
||||
<div class="w-full lg:w-1/2 ml-5 ">
|
||||
<h1 class="text-xl lg:text-3xl font-bold">
|
||||
{{ work.title }}
|
||||
</h1>
|
||||
<p class="mt-5 mb-10 text-md lg:text-lg text-gray-900 dark:text-dark-100">
|
||||
{{ $t(work.description) }}
|
||||
</p>
|
||||
<div>
|
||||
<h3 class="text-md lg:text-lg font-bold">
|
||||
{{ $t('work.tech_used') }}
|
||||
</h3>
|
||||
<div class="flex flex-row w-full overflow-x-auto md:overflow-x-hidden md:flex-wrap space-x-4 md:space-x-0 md:justify-start">
|
||||
<div v-for="skill in skills">
|
||||
<WorkSkill
|
||||
:skill="skill.title"
|
||||
:color="skill.color"
|
||||
:cover="skill.cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WorkSkill from "~/components/WorkSkill";
|
||||
|
||||
export default {
|
||||
components: {WorkSkill},
|
||||
head() {
|
||||
return {
|
||||
title: 'Work - Arthur Danjou'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
work: null
|
||||
}
|
||||
},
|
||||
async asyncData({ params, $content, error }) {
|
||||
const work = await $content('works', params.slug)
|
||||
.fetch()
|
||||
.catch(() => {
|
||||
error({
|
||||
statusCode: 404,
|
||||
message: 'Work not found',
|
||||
})
|
||||
});
|
||||
let skills = []
|
||||
if (work) {
|
||||
skills = await $content('skills').where({ slug: { $in: work.skills } }).fetch()
|
||||
}
|
||||
return {
|
||||
work,
|
||||
skills
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getColor() {
|
||||
switch (this.work.color) {
|
||||
case 'red':
|
||||
return 'bg-red-400 hover:bg-red-600'
|
||||
case 'orange':
|
||||
return 'bg-orange-400 hover:bg-orange-600'
|
||||
case 'purple':
|
||||
return 'bg-purple-400 hover:bg-purple-600'
|
||||
case 'blue':
|
||||
return 'bg-blue-400 hover:bg-blue-600'
|
||||
case 'green':
|
||||
return 'bg-green-400 hover:bg-green-600'
|
||||
case 'yellow':
|
||||
return 'bg-yellow-400 hover:bg-yellow-600'
|
||||
case 'cyan':
|
||||
return 'bg-cyan-400 hover:bg-cyan-600'
|
||||
case 'teal':
|
||||
return 'bg-teal-400 hover:bg-teal-600'
|
||||
case 'amber':
|
||||
return 'bg-amber-400 hover:bg-amber-600'
|
||||
case 'blueGray':
|
||||
return 'bg-blueGray-400 hover:bg-blueGray-600'
|
||||
case 'emerald':
|
||||
return 'bg-emerald-400 hover:bg-emerald-600'
|
||||
case 'lightBlue':
|
||||
return 'bg-lightBlue-400 hover:bg-lightBlue-600'
|
||||
case 'lime':
|
||||
return 'bg-lime-400 hover:bg-lime-600'
|
||||
case 'rose':
|
||||
return 'bg-rose-400 hover:bg-rose-600'
|
||||
case 'black':
|
||||
return 'bg-black hover:bg-black'
|
||||
case 'white':
|
||||
return 'bg-white hover:bg-white'
|
||||
case 'pink':
|
||||
return 'bg-pink-400 hover:bg-pink-600'
|
||||
case 'fuchsia':
|
||||
return 'bg-fuchsia-400 hover:bg-fuchsia-600'
|
||||
case 'violet':
|
||||
return 'bg-violet-400 hover:bg-violet-600'
|
||||
case 'indigo':
|
||||
return 'bg-indigo-400 hover:bg-indigo-600'
|
||||
case 'warmGray':
|
||||
return 'bg-warmGray-400 hover:bg-warmGray-600'
|
||||
case 'trueGray':
|
||||
return 'bg-trueGray-400 hover:bg-trueGray-600'
|
||||
case 'gray':
|
||||
return 'bg-gray-400 hover:bg-gray-600'
|
||||
case 'coolGray':
|
||||
return 'bg-coolGray-400 hover:bg-coolGray-600'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.back-arrow:hover .arrow {
|
||||
transform: translate(-8px, -1px);
|
||||
}
|
||||
|
||||
.arrow {
|
||||
transform: translate(3px, -1px);
|
||||
}
|
||||
</style>
|
||||
51
src/pages/work/index.vue
Normal file
51
src/pages/work/index.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<main class="work flex flex-col items-center px-5 xl:px-64">
|
||||
<PageTitle
|
||||
title="part.work"
|
||||
color="blue"
|
||||
>
|
||||
<svg class="inline-block icon" height="40" width="40" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||
</svg>
|
||||
</PageTitle>
|
||||
<h1 v-if="works.length === 0" class="text-xl font-bold text-center my-8 w-full">{{ $t('work.no_work') }}</h1>
|
||||
<div v-else class="flex flex-col justify-around items-center py-10 w-full">
|
||||
<h1 class="text-xl font-bold text-center mb-8">{{ $t('work.description') }}</h1>
|
||||
<div class="flex flex-col items-center md:items-start md:flex-row flex-wrap w-full space-y-3 md:space-y-0">
|
||||
<div v-for="work in works">
|
||||
<nuxt-link :to="'/work/' + work.slug">
|
||||
<Work
|
||||
:title="work.title"
|
||||
:url="work.url"
|
||||
:color="work.color"
|
||||
:cover="work.cover"
|
||||
/>
|
||||
</nuxt-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PageTitle from "~/components/PageTitle";
|
||||
import Work from "~/components/Work";
|
||||
export default {
|
||||
name: "index",
|
||||
components: {Work, PageTitle},
|
||||
head() {
|
||||
return {
|
||||
title: 'Work - Arthur Danjou'
|
||||
}
|
||||
},
|
||||
async asyncData({ $content }) {
|
||||
const works = await $content('works').fetch()
|
||||
return {
|
||||
works
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
Reference in New Issue
Block a user