Working
@@ -10,20 +10,20 @@
|
||||
"dependencies": {
|
||||
"@nuxt/content": "^1.14.0",
|
||||
"@nuxtjs/axios": "^5.13.6",
|
||||
"@nuxtjs/composition-api": "^0.26.0",
|
||||
"@nuxtjs/composition-api": "^0.27.0",
|
||||
"@nuxtjs/dotenv": "^1.4.1",
|
||||
"@nuxtjs/i18n": "^7.0.2",
|
||||
"@nuxtjs/proxy": "^2.1.0",
|
||||
"@nuxtjs/redirect-module": "^0.3.1",
|
||||
"@nuxtjs/robots": "^2.5.0",
|
||||
"@nuxtjs/sentry": "^5.1.0",
|
||||
"@nuxtjs/sentry": "^5.1.2",
|
||||
"@nuxtjs/sitemap": "^2.4.0",
|
||||
"@nuxtjs/universal-storage": "^0.5.9",
|
||||
"axios": "^0.21.1",
|
||||
"core-js": "^3.16.1",
|
||||
"core-js": "^3.16.2",
|
||||
"nuxt": "^2.15.8",
|
||||
"prism-themes": "^1.8.0",
|
||||
"sass": "^1.37.5"
|
||||
"sass": "^1.38.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt/types": "^2.15.8",
|
||||
|
||||
@@ -41,4 +41,8 @@ const proxy = {
|
||||
}
|
||||
}
|
||||
|
||||
export default { srcDir, dir, build, pageTransition, target, server, buildDir, components, ssr, proxy }
|
||||
const router = {
|
||||
middleware: 'maintenance'
|
||||
}
|
||||
|
||||
export default { router, srcDir, dir, build, pageTransition, target, server, buildDir, components, ssr, proxy }
|
||||
|
||||
BIN
src/assets/images/maintenance.png
Normal file
|
After Width: | Height: | Size: 340 KiB |
|
Before Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 457 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 18 KiB |
@@ -26,7 +26,7 @@ export default {
|
||||
const {$axios, $sentry, app} = useContext()
|
||||
|
||||
const announce = useAsync(async () => {
|
||||
const response = await $axios.get('/api/announces', {
|
||||
const response = await $axios.get('/api/announce', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||
}
|
||||
|
||||
@@ -31,7 +31,9 @@ export default defineComponent({
|
||||
}
|
||||
})
|
||||
if (response.status === 200) {
|
||||
return response.data.experiences
|
||||
return response.data.experiences.sort((a, b) => {
|
||||
return a.end_date === 'Today' ? -1 : a.end_date.split('-')[1] > b.end_date.split('-')[1] ? -1 : a.end_date.split('-')[0] > b.end_date.split('-')[0] ? 0 : 1
|
||||
})
|
||||
} else {
|
||||
app.error({statusCode: 500})
|
||||
$sentry.captureEvent(response.data)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<a target="_blank" href="https://www.twitch.tv/arthurdanjou" rel="noopener noreferrer">
|
||||
<TwitchIcon />
|
||||
</a>
|
||||
<a target="_blank" href="https://discord.gg/RQhjE5UkxD" rel="noopener noreferrer">
|
||||
<a target="_blank" href="https://discord.gg/ENG6cFQhPS" rel="noopener noreferrer">
|
||||
<DiscordIcon />
|
||||
</a>
|
||||
<a target="_blank" href="mailto:contact@arthurdanjou.fr" rel="noopener noreferrer">
|
||||
|
||||
@@ -31,7 +31,9 @@ export default defineComponent({
|
||||
}
|
||||
})
|
||||
if (response.status === 200) {
|
||||
return response.data.formations
|
||||
return response.data.formations.sort((a, b) => {
|
||||
return a.end_date === 'Today' ? -1 : a.end_date.split('-')[1] > b.end_date.split('-')[1] ? -1 : a.end_date.split('-')[0] > b.end_date.split('-')[0] ? 0 : 1
|
||||
})
|
||||
} else {
|
||||
app.error({statusCode: 500})
|
||||
$sentry.captureEvent(response.data)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<ul class="flex items-center">
|
||||
<li @click="changeLanguage()"
|
||||
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-400">
|
||||
<TranslateIcon/>
|
||||
<TranslateIcon :french="isFrench"/>
|
||||
</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-400 duration-200">
|
||||
@@ -83,6 +83,7 @@ export default defineComponent({
|
||||
window.location.reload()
|
||||
}
|
||||
})
|
||||
const isFrench = computed(() => i18n.locale === 'fr')
|
||||
|
||||
const store = useStore<State>()
|
||||
const route = computed(() => store.state.route)
|
||||
@@ -97,7 +98,8 @@ export default defineComponent({
|
||||
changeColorMode,
|
||||
updateScroll,
|
||||
changeLanguage,
|
||||
isWindow
|
||||
isWindow,
|
||||
isFrench
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<section class="w-full mb-10">
|
||||
<h3 class="font-bold text-2xl md:text-4xl">
|
||||
{{ $t('about.title.languages') }}
|
||||
<TranslateIcon />
|
||||
<LanguageIcon />
|
||||
</h3>
|
||||
<div>
|
||||
<table class="text-base text-xl text-gray-700 dark:text-gray-400">
|
||||
@@ -21,6 +21,6 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "LanguagesAbout"
|
||||
name: "LanguagesAbout",
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -51,22 +51,22 @@ export default defineComponent({
|
||||
const toggleMenu = () => {
|
||||
store.commit('TOGGLE_OPENED', !store.state.opened)
|
||||
if (store.state.opened) {
|
||||
document.getElementById('slider')!.style.maxHeight = window.screen.height + 'px'
|
||||
setTimeout(() => document.getElementById('nav')!.classList.add('z-50'), 300)
|
||||
} else {
|
||||
document.getElementById('nav')!.classList.remove('z-50')
|
||||
setTimeout(() => {
|
||||
document.getElementById('slider')!.style.maxHeight = 'none'
|
||||
}, 100)
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
|
||||
const $router = useRouter()
|
||||
$router.afterEach(() => {
|
||||
store.commit('TOGGLE_OPENED', false)
|
||||
document.getElementById('nav')!.classList.remove('z-50')
|
||||
setTimeout(() => {
|
||||
document.getElementById('slider')!.style.maxHeight = 'none'
|
||||
}, 100)
|
||||
}, 600)
|
||||
})
|
||||
|
||||
return {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<nuxt-link :to="`/blog/${slug}`">
|
||||
<div class="rounded-lg dark:shadow-white shadow-xl h-116 w-full lg:w-100 text-left bg-gray-100 dark:bg-gray-800 transform hover:scale-103 duration-300 mb-8 lg:mb-0">
|
||||
<div class="h-2/5 post rounded-t-lg"
|
||||
:style="{ backgroundImage: `url(${getCover})` }">
|
||||
:style="{ backgroundImage: `url(https://athena.arthurdanjou.fr/files/${cover})` }">
|
||||
</div>
|
||||
<div class="h-3/5 p-4 flex flex-col justify-between">
|
||||
<div>
|
||||
@@ -11,8 +11,8 @@
|
||||
<Tag :content="tag" :pill="true"/>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="text-2xl font-bold">{{ title }}</h1>
|
||||
<p class="text-base mt-3 text-gray-700 dark:text-gray-400 text-justify">{{ description }}</p>
|
||||
<h1 class="text-2xl font-bold">{{ $t(title) }}</h1>
|
||||
<p class="text-base mt-3 text-gray-700 dark:text-gray-400 text-justify">{{ $t(description) }}</p>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<h5 class="text-base text-gray-700 dark:text-gray-400">{{ formatDate }}</h5>
|
||||
@@ -69,8 +69,6 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
setup(props: PostProps) {
|
||||
const getCover = computed(() => require(`~/assets/images/posts/${props.cover}`))
|
||||
|
||||
const { i18n } = useContext()
|
||||
const formatDate = computed(() => {
|
||||
const [first, second, third]: any = props.date.split('-')
|
||||
@@ -78,7 +76,6 @@ export default defineComponent({
|
||||
})
|
||||
|
||||
return {
|
||||
getCover,
|
||||
formatDate
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
<div class="my-8 lg:flex w-full lg:space-x-6">
|
||||
<div v-for="post in posts">
|
||||
<Post
|
||||
:title="post.title"
|
||||
:cover="post.cover"
|
||||
:description="post.description"
|
||||
:title="post.title.code"
|
||||
:cover="post.cover.file_name"
|
||||
:description="post.description.code"
|
||||
:date="post.date"
|
||||
:slug="post.slug"
|
||||
:tags="post.tags"
|
||||
@@ -36,17 +36,21 @@ import {Post} from "~/types/types";
|
||||
export default defineComponent({
|
||||
name: "PostsHome",
|
||||
setup() {
|
||||
const { $content, i18n, $sentry } = useContext()
|
||||
const { $axios, app, $sentry } = useContext()
|
||||
|
||||
const posts = useAsync(() => {
|
||||
return $content(`articles/${i18n.locale}`)
|
||||
.sortBy('date', 'asc')
|
||||
.limit(3)
|
||||
.fetch<Post>()
|
||||
.catch((error) => {
|
||||
$sentry.captureEvent(error)
|
||||
})
|
||||
}, 'posts')
|
||||
const posts = useAsync(async () => {
|
||||
const response = await $axios.get('/api/posts', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||
}
|
||||
})
|
||||
if (response.status === 200) {
|
||||
return response.data.posts
|
||||
} else {
|
||||
app.error({statusCode: 500})
|
||||
$sentry.captureEvent(response.data)
|
||||
}
|
||||
}, 'posts_home')
|
||||
|
||||
return {
|
||||
posts
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<img class="rounded-full my-5" src="~/assets/images/memojies/Hey.png" alt="A picture of myself" />
|
||||
</div>
|
||||
<div class="text-lg leading-6 text-justify dark:text-gray-400 text-gray-700">
|
||||
<p>{{ $t('about.banner.hello') }} <span class="text-indigo-600 font-bold">Arthur DANJOU</span> 👋.</p> <br/>
|
||||
<div>{{ $t('about.banner.hello') }} <span class="text-indigo-600 font-bold">Arthur DANJOU</span> 👋.</div> <br/>
|
||||
<p>{{ $t('about.banner.1')}}</p> <br/>
|
||||
<p>{{ $t('about.banner.2') }}</p> <br/>
|
||||
<p>{{ $t('about.banner.3') }}</p> <br />
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<a :href="url" target="_blank">
|
||||
<div class="rounded-lg dark:shadow-white shadow-xl h-92 w-full lg:w-84 text-left bg-gray-100 dark:bg-gray-800 transform hover:scale-103 duration-300 mb-8 lg:mb-0">
|
||||
<div class="h-1/2 w-full h-2/5 project rounded-t-lg"
|
||||
:style="{ backgroundImage: `url(${getCover})` }">
|
||||
<div class="rounded-lg dark:shadow-white shadow-xl lg:h-92 w-full lg:w-84 text-left bg-gray-100 dark:bg-gray-800 transform hover:scale-103 duration-300 mb-8 lg:mb-0">
|
||||
<div class="h-64 lg:h-1/2 w-full project rounded-t-lg"
|
||||
:style="{ backgroundImage: `url(https://athena.arthurdanjou.fr/files/${cover})` }">
|
||||
</div>
|
||||
<div class="h-1/2 p-4 flex flex-col justify-between">
|
||||
<div class="lg:h-1/2 py-8 px-4 lg:p-4 flex flex-col justify-between">
|
||||
<div>
|
||||
<div class="flex space-x-2 mb-2">
|
||||
<div v-for="tag in tags">
|
||||
<Tag :content="tag" :pill="false"/>
|
||||
<Tag :content="tag.label.code" :pill="false"/>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="text-2xl font-bold">{{ title }}</h1>
|
||||
@@ -20,15 +20,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {computed, defineComponent} from "@nuxtjs/composition-api";
|
||||
|
||||
interface ProjectProp {
|
||||
title: string,
|
||||
cover: string,
|
||||
tags: Array<String>,
|
||||
description: string,
|
||||
url: string,
|
||||
}
|
||||
import {defineComponent} from "@nuxtjs/composition-api";
|
||||
|
||||
export default defineComponent({
|
||||
name: "Project",
|
||||
@@ -53,13 +45,6 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: 'https://arthurdanjou.fr'
|
||||
}
|
||||
},
|
||||
setup(props: ProjectProp) {
|
||||
const getCover = computed(() => require(`@/assets/images/projects/${props.cover}`))
|
||||
|
||||
return {
|
||||
getCover
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
{{ $t('projects.description') }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="my-8 lg:flex w-full lg:space-x-8 flex flex-wrap justify-center">
|
||||
<div class="my-8 w-full lg:space-x-8 lg:flex justify-center">
|
||||
<div v-for="project in projects" class="mb-4">
|
||||
<Project
|
||||
:title="project.title"
|
||||
:cover="project.cover"
|
||||
:description="project.description"
|
||||
:title="project.name"
|
||||
:cover="project.cover.file_name"
|
||||
:description="project.description.code"
|
||||
:tags="project.tags"
|
||||
:url="project.url"
|
||||
/>
|
||||
@@ -34,16 +34,21 @@ import {Project} from "~/types/types";
|
||||
export default defineComponent({
|
||||
name: "ProjectsHome",
|
||||
setup() {
|
||||
const { $content, $sentry } = useContext()
|
||||
const { $axios, app, $sentry } = useContext()
|
||||
|
||||
const projects = useAsync(() => {
|
||||
return $content(`projects`)
|
||||
.limit(3)
|
||||
.fetch<Project>()
|
||||
.catch((error) => {
|
||||
$sentry.captureEvent(error)
|
||||
})
|
||||
}, 'projects')
|
||||
const projects = useAsync(async () => {
|
||||
const response = await $axios.get('/api/projects', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||
}
|
||||
})
|
||||
if (response.status === 200) {
|
||||
return response.data.projects.slice(0, 3)
|
||||
} else {
|
||||
$sentry.captureEvent(response.data)
|
||||
app.error({statusCode: 500})
|
||||
}
|
||||
}, 'projects_home')
|
||||
|
||||
return {
|
||||
projects
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<ul class="flex items-center">
|
||||
<li @click="changeLanguage()"
|
||||
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-400">
|
||||
<TranslateIcon/>
|
||||
<TranslateIcon :french="isFrench" />
|
||||
</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-400 duration-200">
|
||||
@@ -90,7 +90,7 @@
|
||||
<a target="_blank" href="https://www.twitch.tv/arthurdanjou" rel="noopener noreferrer">
|
||||
<TwitchIcon />
|
||||
</a>
|
||||
<a target="_blank" href="https://discord.gg/RQhjE5UkxD" rel="noopener noreferrer">
|
||||
<a target="_blank" href="https://discord.gg/ENG6cFQhPS" rel="noopener noreferrer">
|
||||
<DiscordIcon />
|
||||
</a>
|
||||
<a target="_blank" href="mailto:contact@arthurdanjou.fr" rel="noopener noreferrer">
|
||||
@@ -130,13 +130,15 @@ export default defineComponent({
|
||||
}
|
||||
})
|
||||
|
||||
const isFrench = computed(() => i18n.locale === 'fr')
|
||||
|
||||
const store = useStore<State>()
|
||||
const closeMenu = () => {
|
||||
store.commit('TOGGLE_OPENED', false)
|
||||
document.getElementById('nav')!.classList.remove('z-50')
|
||||
setTimeout(() => {
|
||||
document.getElementById('slider')!.style.maxHeight = 'none'
|
||||
}, 100)
|
||||
}, 500)
|
||||
}
|
||||
|
||||
const route = computed(() => store.state.route)
|
||||
@@ -150,7 +152,8 @@ export default defineComponent({
|
||||
changeLanguage,
|
||||
closeMenu,
|
||||
opened: computed(() => store.state.opened),
|
||||
isWindow
|
||||
isWindow,
|
||||
isFrench
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
14
src/components/icons/LanguageIcon.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<svg class="inline" width="1em" height="1em" viewBox="0 0 24 24" focusable="false">
|
||||
<path
|
||||
d="M12.87 15.07l-2.54-2.51l.03-.03A17.52 17.52 0 0 0 14.07 6H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35C8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5l3.11 3.11l.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "LanguageIcon"
|
||||
}
|
||||
</script>
|
||||
@@ -1,14 +1,40 @@
|
||||
<template>
|
||||
<svg class="inline" width="1.5em" height="1.5em" viewBox="0 0 24 24" focusable="false">
|
||||
<svg v-if="french" class="inline" width="1.5em" height="1.5em" viewBox="0 0 36 36" focusable="false">
|
||||
<path
|
||||
d="M12.87 15.07l-2.54-2.51l.03-.03A17.52 17.52 0 0 0 14.07 6H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35C8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5l3.11 3.11l.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
fill="#00247D"
|
||||
d="M0 9.059V13h5.628zM4.664 31H13v-5.837zM23 25.164V31h8.335zM0 23v3.941L5.63 23zM31.337 5H23v5.837zM36 26.942V23h-5.631zM36 13V9.059L30.371 13zM13 5H4.664L13 10.837z" />
|
||||
<path
|
||||
fill="#CF1B2B"
|
||||
d="M25.14 23l9.712 6.801a3.977 3.977 0 0 0 .99-1.749L28.627 23H25.14zM13 23h-2.141l-9.711 6.8c.521.53 1.189.909 1.938 1.085L13 23.943V23zm10-10h2.141l9.711-6.8a3.988 3.988 0 0 0-1.937-1.085L23 12.057V13zm-12.141 0L1.148 6.2a3.994 3.994 0 0 0-.991 1.749L7.372 13h3.487z" />
|
||||
<path
|
||||
fill="#EEE"
|
||||
d="M36 21H21v10h2v-5.836L31.335 31H32a3.99 3.99 0 0 0 2.852-1.199L25.14 23h3.487l7.215 5.052c.093-.337.158-.686.158-1.052v-.058L30.369 23H36v-2zM0 21v2h5.63L0 26.941V27c0 1.091.439 2.078 1.148 2.8l9.711-6.8H13v.943l-9.914 6.941c.294.07.598.116.914.116h.664L13 25.163V31h2V21H0zM36 9a3.983 3.983 0 0 0-1.148-2.8L25.141 13H23v-.943l9.915-6.942A4.001 4.001 0 0 0 32 5h-.663L23 10.837V5h-2v10h15v-2h-5.629L36 9.059V9zM13 5v5.837L4.664 5H4a3.985 3.985 0 0 0-2.852 1.2l9.711 6.8H7.372L.157 7.949A3.968 3.968 0 0 0 0 9v.059L5.628 13H0v2h15V5h-2z" />
|
||||
<path
|
||||
fill="#CF1B2B"
|
||||
d="M21 15V5h-6v10H0v6h15v10h6V21h15v-6z" />
|
||||
</svg>
|
||||
<svg v-else class="inline" width="1.5em" height="1.5em" viewBox="0 0 36 36" focusable="false">
|
||||
<path
|
||||
fill="#ED2939"
|
||||
d="M36 27a4 4 0 0 1-4 4h-8V5h8a4 4 0 0 1 4 4v18z" />
|
||||
<path
|
||||
fill="#002495"
|
||||
d="M4 5a4 4 0 0 0-4 4v18a4 4 0 0 0 4 4h8V5H4z" />
|
||||
<path
|
||||
fill="#EEE"
|
||||
d="M12 5h12v26H12z" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "TranslateIcon"
|
||||
name: "TranslateIcon",
|
||||
props: {
|
||||
french: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
---
|
||||
slug: how-i-start
|
||||
title: How did I start development?
|
||||
description: How did I start development? What am I capable of mastering? What will my future be?
|
||||
reading_time: 5
|
||||
tags: ["tags.life"]
|
||||
cover: post-2.png
|
||||
date: 07-01-2021
|
||||
---
|
||||
|
||||
## Presentation
|
||||
@@ -1,11 +1,5 @@
|
||||
---
|
||||
slug: new-version-new-website
|
||||
title: Opening of the new version of my site!
|
||||
description: After long months of development, here is version 2 of my site!
|
||||
reading_time: 2
|
||||
tags: ["tags.dev"]
|
||||
cover: post-1.png
|
||||
date: 13-12-2020
|
||||
---
|
||||
|
||||
## Presentation
|
||||
@@ -1,11 +1,5 @@
|
||||
---
|
||||
slug: how-i-start
|
||||
title: Comment ai-je commencé le développement ?
|
||||
description: Comment ai-je commencé le développement ? Que suis-je capable de maitriser ? Quel sera mon futur ?
|
||||
reading_time: 5
|
||||
tags: ["tags.life"]
|
||||
cover: post-2.png
|
||||
date: 07-01-2021
|
||||
---
|
||||
|
||||
## Présentation
|
||||
@@ -1,11 +1,5 @@
|
||||
---
|
||||
slug: new-version-new-website
|
||||
title: Ouverture de la nouvelle version de mon site !
|
||||
description: Après de long mois de développement, voici la version 2 de mon site !
|
||||
reading_time: 2
|
||||
tags: ["tags.dev"]
|
||||
cover: post-1.png
|
||||
date: 13-12-2020
|
||||
---
|
||||
|
||||
## Présentation
|
||||
@@ -1,34 +0,0 @@
|
||||
[
|
||||
{
|
||||
"slug": "erisium",
|
||||
"title": "Erisium",
|
||||
"description": "works.erisium",
|
||||
"url": "https://erisium.com",
|
||||
"cover": "erisium.png",
|
||||
"tags": ["tags.mc"]
|
||||
},
|
||||
{
|
||||
"slug": "ares",
|
||||
"title": "Ares",
|
||||
"description": "works.ares",
|
||||
"url": "https://arthurdanjou.fr",
|
||||
"cover": "ares.png",
|
||||
"tags": ["tags.web"]
|
||||
},
|
||||
{
|
||||
"slug": "athena",
|
||||
"title": "Athena",
|
||||
"description": "works.athena",
|
||||
"url": "https://athena.arthurdanjou.fr",
|
||||
"cover": "athena.png",
|
||||
"tags": ["tags.api"]
|
||||
},
|
||||
{
|
||||
"slug": "linkyjs",
|
||||
"title": "LinkyJs",
|
||||
"description": "works.linkyjs",
|
||||
"url": "https://github.com/linkyjs/",
|
||||
"cover": "linkyjs.png",
|
||||
"tags": ["tags.software", "tags.opensource"]
|
||||
}
|
||||
]
|
||||
@@ -1,11 +0,0 @@
|
||||
[
|
||||
{
|
||||
"slug": "tags.dev"
|
||||
},
|
||||
{
|
||||
"slug": "tags.tech"
|
||||
},
|
||||
{
|
||||
"slug": "tags.life"
|
||||
}
|
||||
]
|
||||
@@ -6,7 +6,6 @@
|
||||
id="slider"
|
||||
class="xl:static shadow-2xl transition-all duration-500 overflow-hidden xl:overflow-visible"
|
||||
:class="{'transform scale-90 md:scale-70 lg:scale-60 xl:scale-100 rounded-lg xl:rounded-none translate-x-10/12 sm:translate-x-4/12 lg:translate-x-3/12 xl:translate-x-0': opened}"
|
||||
:style="`max-height: ${height}px`"
|
||||
:tabindex="opened ? -1 : 0"
|
||||
>
|
||||
<div
|
||||
@@ -41,17 +40,14 @@ export default {
|
||||
const closeMenu = () => {
|
||||
store.commit('TOGGLE_OPENED', false)
|
||||
document.getElementById('nav')!.classList.remove('z-50')
|
||||
setTimeout(() => {
|
||||
document.getElementById('slider')!.style.maxHeight = 'none'
|
||||
}, 500)
|
||||
}
|
||||
|
||||
const height = ref(0)
|
||||
onMounted(() => {
|
||||
height.value = window.screen.height
|
||||
})
|
||||
|
||||
return {
|
||||
opened: computed(() => store.state.opened),
|
||||
closeMenu,
|
||||
height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
src/layouts/maintenance.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<Nuxt />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "maintenance"
|
||||
}
|
||||
</script>
|
||||
@@ -47,7 +47,7 @@ const translations = {
|
||||
},
|
||||
|
||||
footer: {
|
||||
description: 'Développeur Web et Logiciel, mais également étudiant en Mathématiques et en Physique. Je développe des sites internet',
|
||||
description: "Web and Software Developer, but also student in Mathematics and Physics 🎓. I live in Paris 🇫🇷. I love to create more or less useful applications and software 🛍. I use modern technologies to get the best possible result ✨ I also adore contributing to all types of Open-Source projects 🧪",
|
||||
links: 'Quick links',
|
||||
credits: 'Developed with',
|
||||
credits_separator: 'and',
|
||||
@@ -115,7 +115,7 @@ const translations = {
|
||||
1: 'I am a young creative developer who loves to tinker and touch everything! I am very interested in new technologies, development and IT.',
|
||||
2: 'I love sharing my knowledge and helping others through lives on Twitchs, technical articles on my blog, open-source projects or by reviewing community code. As long as I share my passions, I will continue to do this.',
|
||||
3: 'I am able to quickly learn new technologies to meet the needs of different projects. I often identify the need for new systems or tools to improve workflow efficiency. I am always motivated by a challenge and like to be well organized to produce consistent results.',
|
||||
4: 'En parallèle du développement, je suis étudiant en Mathématiques et en Physique dans la faculté des Sciences Paris-Saclay. De plus, je suis un grand fan de moto.'
|
||||
4: 'In parallel with the development, I am a student in Mathematics and Physics in the Paris-Saclay Faculty of Sciences. In addition, I am a big fan of motorcycles.'
|
||||
},
|
||||
title: {
|
||||
skills: 'Skills',
|
||||
@@ -252,7 +252,14 @@ const translations = {
|
||||
linkyjs: 'LinkyJS is my custom and Open-Source url shortener'
|
||||
},
|
||||
|
||||
loading: 'Loading...'
|
||||
loading: 'Loading...',
|
||||
|
||||
maintenance: {
|
||||
back_soon: "We'll be back soon...",
|
||||
title: 'Website under maintenance !',
|
||||
progress: "To follow the progress: ",
|
||||
separator: 'or'
|
||||
}
|
||||
}
|
||||
|
||||
export default async function () {
|
||||
|
||||
@@ -47,7 +47,7 @@ const translations = {
|
||||
},
|
||||
|
||||
footer: {
|
||||
description: 'Développeur Web et Logiciel, mais également étudiant en Mathématiques et en Physique. Je développe des sites internet',
|
||||
description: "Développeur Web et Logiciel, mais aussi étudiant en Mathématiques et Physique 🎓. J'habite à Paris 🇫🇷. J'adore créer des applications et des logiciels plus ou moins utiles 🛍. J'utilise les technologies modernes pour obtenir le meilleur résultat possible ✨ J'adore également contribuer à tous types de projets Open-Source 🧪",
|
||||
links: 'Liens rapides',
|
||||
credits: 'Développé avec',
|
||||
credits_separator: 'et',
|
||||
@@ -252,7 +252,14 @@ const translations = {
|
||||
linkyjs: "LinkyJS est mon raccourcisseur d'url personnalisé et Open-Source."
|
||||
},
|
||||
|
||||
loading: 'Chargement...'
|
||||
loading: 'Chargement...',
|
||||
|
||||
maintenance: {
|
||||
back_soon: "Nous serons de retour bientôt...",
|
||||
title: 'Site en maintenance !',
|
||||
progress: "Pour suivre l'avancée : ",
|
||||
separator: 'ou'
|
||||
}
|
||||
}
|
||||
|
||||
export default async function () {
|
||||
|
||||
19
src/middlewares/maintenance.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import {Context} from "@nuxt/types";
|
||||
|
||||
export default async function ({redirect, route, $axios}: Context) {
|
||||
let isMaintenance = true
|
||||
const response = await $axios.get('/api/maintenance', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||
}
|
||||
})
|
||||
if (response.status === 200) {
|
||||
isMaintenance = response.data.maintenance.active === 1
|
||||
}
|
||||
if(isMaintenance){
|
||||
return redirect('/maintenance')
|
||||
}
|
||||
if(!isMaintenance && route.path === '/maintenance'){
|
||||
return redirect('/')
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<main v-if="post" class="blog flex flex-col items-center px-4 xl:px-72 mb-16 md:mb-32">
|
||||
<main v-if="post && postData" class="blog flex flex-col items-center px-4 xl:px-72 mb-16 md:mb-32">
|
||||
<div class="mt-8 md:mt-32 flex flex-col justify-around py-8 w-full">
|
||||
{{ slug }}
|
||||
<div>
|
||||
<div class="mb-4 flex">
|
||||
<nuxt-link to="/blog" class="back-arrow flex">
|
||||
@@ -14,10 +15,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="text-3xl md:text-5xl font-bold">
|
||||
{{ post.title }}
|
||||
{{ $t(postData.title.code) }}
|
||||
</h1>
|
||||
<h3 class="text-xl text-gray-800 dark:text-gray-300 my-4 md:mt-8">
|
||||
{{ post.description }}
|
||||
{{ $t(postData.description.code) }}
|
||||
</h3>
|
||||
<div class="flex flex-row justify-between w-full md:w-2/3 mb-12">
|
||||
<div>
|
||||
@@ -26,16 +27,16 @@
|
||||
</div>
|
||||
<div>
|
||||
<p class="uppercase text-sm font-bold text-gray-800 dark:text-gray-400">{{ $t('blog.read.time') }}</p>
|
||||
<p>{{ post.reading_time }} min</p>
|
||||
<p>{{ postData.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-gray-400">Tags</p>
|
||||
<p :class="postData.tags.length === 0 ? 'opacity-0': 'opacity-100'" class="uppercase text-sm font-bold text-gray-800 dark:text-gray-400">Tags</p>
|
||||
<p>{{ formatTags }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<div class="flex justify-center w-full">
|
||||
<img class="w-full" :src="require(`@/assets/images/posts/${post.cover}`)" alt="Cover Img" />
|
||||
<img class="w-full" :src="`https://athena.arthurdanjou.fr/files/${postData.cover.file_name}`" alt="Cover Img" />
|
||||
</div>
|
||||
</div>
|
||||
<nuxt-content
|
||||
@@ -55,7 +56,7 @@
|
||||
: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 leading-3">
|
||||
{{ likes }}
|
||||
{{ getLikes }}
|
||||
</div>
|
||||
<div class="inline leading-6" :class="{'animate-pulse heartbeat': liked}">
|
||||
<HeartIcon :liked="liked"/>
|
||||
@@ -63,7 +64,7 @@
|
||||
</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"
|
||||
:href="'https://twitter.com/intent/tweet?url=https%3A%2F%2Farthurdanjou.fr%2Fblog%2F' + postData.slug + '&text=' + $t('blog.tweet') + ' ' + $i18n.t('title')"
|
||||
class="mr-2 icon-hover cursor-pointer duration-300 text-2xl p-1 border-solid border border-gray-300 dark:border-dark-200 hover:border-cyan-500 dark:hover:border-cyan-400 flex justify-center items-center"
|
||||
>
|
||||
<TwitterBlogIcon />
|
||||
@@ -119,7 +120,7 @@ export default defineComponent({
|
||||
const slug = computed(() => route.value.params.slug)
|
||||
|
||||
const post = useStatic((slug) => {
|
||||
return $content(`articles/${i18n.locale}`, slug)
|
||||
return $content(i18n.locale, slug)
|
||||
.fetch<Post>()
|
||||
.catch((error) => {
|
||||
app.error({statusCode: 404, message: "Post not found"})
|
||||
@@ -127,31 +128,34 @@ export default defineComponent({
|
||||
}) as Promise<Post>
|
||||
}, slug, 'post')
|
||||
|
||||
title.value = post.value?.title ? `Blog - Arthur Danjou - ${post.value!.title}` : 'Loading title...'
|
||||
|
||||
watch(post, () => {
|
||||
title.value = post.value?.title ? `Blog - Arthur Danjou - ${post.value!.title}` : 'Loading title...'
|
||||
})
|
||||
|
||||
const liked = ref($storage.getCookie(`${slug.value}`) !== undefined)
|
||||
const likes = ref(0)
|
||||
const getLikes = computed(() => likes.value)
|
||||
|
||||
const likes = useAsync(async () => {
|
||||
const response = await $axios.get(`/api/posts/${slug.value}`, {
|
||||
const postData = useAsync(async () => {
|
||||
const response = await $axios.get(`/api/posts/${slug.value}/data`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||
}
|
||||
})
|
||||
if (response.status === 200) {
|
||||
return response.data.likes
|
||||
likes.value = response.data.post.likes
|
||||
title.value = `Blog - Arthur Danjou - ${i18n.t(response.data.post.title.code)}`
|
||||
return response.data.post
|
||||
} else {
|
||||
$sentry.captureEvent(response.data)
|
||||
app.error({statusCode: 500})
|
||||
}
|
||||
}, 'likes')
|
||||
}, 'postData')
|
||||
|
||||
watch(postData, () => {
|
||||
title.value = `Blog - Arthur Danjou - ${i18n.t(postData.value.title.code)}`
|
||||
likes.value = postData.value.likes
|
||||
})
|
||||
|
||||
const handleLike = async () => {
|
||||
if (liked.value) {
|
||||
const response = await $axios.post(`/api/posts/${post.value?.slug}/unlike`, {}, {
|
||||
const response = await $axios.post(`/api/posts/${postData.value.slug}/unlike`, {}, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||
}
|
||||
@@ -165,7 +169,7 @@ export default defineComponent({
|
||||
app.error({statusCode: 500})
|
||||
}
|
||||
} else {
|
||||
const response = await $axios.post(`/api/posts/${post.value?.slug}/like`, {}, {
|
||||
const response = await $axios.post(`/api/posts/${postData.value.slug}/like`, {}, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||
}
|
||||
@@ -185,7 +189,7 @@ export default defineComponent({
|
||||
|
||||
const isCopied = ref(false)
|
||||
const copyToClipboard = () => {
|
||||
navigator.clipboard.writeText('https://arthurdanjou.fr/blog/' + post.value?.slug)
|
||||
navigator.clipboard.writeText('https://arthurdanjou.fr/blog/' + postData.value.slug)
|
||||
isCopied.value = true
|
||||
setTimeout(() => {
|
||||
isCopied.value = false
|
||||
@@ -200,13 +204,13 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
const formatDate = computed(() => {
|
||||
const [first, second, third]: any = post.value?.date.split('-')
|
||||
const [first, second, third]: any = postData.value.date.split('-')
|
||||
return `${first} ${i18n.t(`month.${second}`)} ${third}`
|
||||
})
|
||||
|
||||
const formatTags = computed(() => {
|
||||
let tags = ""
|
||||
post.value?.tags.map(tag => {
|
||||
postData.value.tags.map(tag => {
|
||||
tags += i18n.t(String(tag)) + ", "
|
||||
})
|
||||
return tags.substring(0, tags.length - 2)
|
||||
@@ -214,14 +218,16 @@ export default defineComponent({
|
||||
|
||||
return {
|
||||
post,
|
||||
likes,
|
||||
getLikes,
|
||||
liked,
|
||||
handleLike,
|
||||
isCopied,
|
||||
copyToClipboard,
|
||||
scrollToTop,
|
||||
formatDate,
|
||||
formatTags
|
||||
formatTags,
|
||||
postData,
|
||||
slug
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
<div class="flex py-8 w-full flex-wrap">
|
||||
<div class="md:mx-8 my-4 w-full lg:w-auto" v-for="post in posts">
|
||||
<Post
|
||||
:title="post.title"
|
||||
:cover="post.cover"
|
||||
:description="post.description"
|
||||
:title="post.title.code"
|
||||
:cover="post.cover.file_name"
|
||||
:description="post.description.code"
|
||||
:date="post.date"
|
||||
:slug="post.slug"
|
||||
:tags="post.tags"
|
||||
@@ -41,20 +41,25 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
const { $content, i18n, $sentry } = useContext()
|
||||
const { $sentry, $axios, app } = useContext()
|
||||
|
||||
const posts = useAsync(() => {
|
||||
return $content(`articles/${i18n.locale}`)
|
||||
.sortBy('date', 'asc')
|
||||
.limit(10)
|
||||
.fetch<Post>()
|
||||
.catch((error) => {
|
||||
$sentry.captureEvent(error)
|
||||
})
|
||||
const posts = useAsync(async () => {
|
||||
const response = await $axios.get('/api/posts', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||
}
|
||||
})
|
||||
if (response.status === 200) {
|
||||
console.log(response.data.posts)
|
||||
return response.data.posts
|
||||
} else {
|
||||
app.error({statusCode: 500})
|
||||
$sentry.captureEvent(response.data)
|
||||
}
|
||||
}, 'posts')
|
||||
|
||||
return {
|
||||
posts,
|
||||
posts
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
107
src/pages/maintenance.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<div v-if="maintenance" class="w-screen h-screen flex items-center">
|
||||
<div class="absolute right-4 top-4">
|
||||
<ul class="flex items-center">
|
||||
<li @click="changeLanguage()"
|
||||
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-400">
|
||||
<TranslateIcon :french="isFrench"/>
|
||||
</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-400 duration-200">
|
||||
<div v-if="this.$colorMode.preference === 'light'">
|
||||
<MoonIcon/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<SunIcon/>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="w-full flex flex-col items-center">
|
||||
<div class="self-center">
|
||||
<div class="flex justify-center mb-8">
|
||||
<img class="w-full lg:w-3/4 xl:w-1/3" src="@/assets/images/maintenance.png" alt="Maintenance Image" />
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<h3 class="text-xl lg:text-2xl">
|
||||
{{ $t('maintenance.back_soon') }}
|
||||
</h3>
|
||||
<h1 class="font-black text-3xl lg:text-5xl my-4">
|
||||
{{ $t('maintenance.title') }}
|
||||
</h1>
|
||||
<p class="text-gray-600 dark:text-gray-400 text-md lg:text-xl">
|
||||
{{ $t(maintenance.reason.code) }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lg:w-2/3 p-4 lg:p-8 mt-auto w-full ">
|
||||
<div class="py-4 text-center border-t-2 border-gray-200 dark:border-gray-800 social-links">
|
||||
{{ $t('maintenance.progress') }} <br class="lg:hidden"/>
|
||||
<a target="_blank" href="https://twitter.com/ArthurDanj" rel="noopener noreferrer">
|
||||
<TwitterIcon />
|
||||
</a>
|
||||
<div class="mx-2 inline">{{ $t('maintenance.separator') }}</div>
|
||||
<a target="_blank" href="https://discord.gg/ENG6cFQhPS" rel="noopener noreferrer">
|
||||
<DiscordIcon />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {computed, defineComponent, useAsync, useContext} from "@nuxtjs/composition-api";
|
||||
|
||||
export default defineComponent({
|
||||
name: "maintenance",
|
||||
layout: 'maintenance',
|
||||
setup() {
|
||||
const {$axios, $sentry, app} = useContext()
|
||||
|
||||
const maintenance = useAsync(async () => {
|
||||
const response = await $axios.get('/api/maintenance', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||
}
|
||||
})
|
||||
if (response.status === 200) {
|
||||
return response.data.maintenance
|
||||
} else {
|
||||
$sentry.captureEvent(response.data)
|
||||
app.error({statusCode: 500})
|
||||
}
|
||||
}, 'maintenance')
|
||||
|
||||
const {i18n} = useContext()
|
||||
const changeLanguage = () => useAsync(() => {
|
||||
i18n.setLocale(i18n.locale === 'fr' ? 'en' : 'fr')
|
||||
})
|
||||
const isFrench = computed(() => i18n.locale === 'fr')
|
||||
|
||||
const {$colorMode} = useContext()
|
||||
const changeColorMode = () => {
|
||||
$colorMode.preference = $colorMode.value === 'light' ? 'dark' : 'light'
|
||||
}
|
||||
|
||||
return {
|
||||
maintenance,
|
||||
changeLanguage,
|
||||
isFrench,
|
||||
changeColorMode
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.social-links a {
|
||||
svg {
|
||||
@apply h-6 w-6 duration-300
|
||||
}
|
||||
|
||||
&:hover svg {
|
||||
@apply transform hover:scale-120
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -5,12 +5,12 @@
|
||||
<div v-else class="flex flex-col justify-around items-center py-10 w-full">
|
||||
<h1 class="text-gray-700 dark:text-gray-400 text-xl mt-4">{{ $t('projects.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 class="flex py-4 w-full flex-wrap justify-center">
|
||||
<div class="md:mx-4 my-4 w-full lg:w-auto" v-for="project in projects">
|
||||
<div class="lg:flex py-4 w-full flex-wrap justify-center">
|
||||
<div class="m-4" v-for="project in projects">
|
||||
<Project
|
||||
:title="project.title"
|
||||
:cover="project.cover"
|
||||
:description="project.description"
|
||||
:title="project.name"
|
||||
:cover="project.cover.file_name"
|
||||
:description="project.description.code"
|
||||
:tags="project.tags"
|
||||
:url="project.url"
|
||||
/>
|
||||
@@ -33,14 +33,20 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
const { $content, $sentry } = useContext()
|
||||
const { $axios, app, $sentry } = useContext()
|
||||
|
||||
const projects = useAsync(() => {
|
||||
return $content('projects')
|
||||
.fetch<Project>()
|
||||
.catch((error) => {
|
||||
$sentry.captureEvent(error)
|
||||
})
|
||||
const projects = useAsync(async () => {
|
||||
const response = await $axios.get('/api/projects', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||
}
|
||||
})
|
||||
if (response.status === 200) {
|
||||
return response.data.projects
|
||||
} else {
|
||||
$sentry.captureEvent(response.data)
|
||||
app.error({statusCode: 500})
|
||||
}
|
||||
}, 'projects')
|
||||
|
||||
return {
|
||||
|
||||
56
yarn.lock
@@ -1414,17 +1414,17 @@
|
||||
defu "^5.0.0"
|
||||
lodash.template "^4.5.0"
|
||||
|
||||
"@nuxtjs/composition-api@^0.26.0":
|
||||
version "0.26.0"
|
||||
resolved "https://registry.yarnpkg.com/@nuxtjs/composition-api/-/composition-api-0.26.0.tgz#0fbda4fc942ca1e346b7c6d55a1fb331ff931a2a"
|
||||
integrity sha512-+4L9YDEN5h/vBY6xbBKPMIhgxbPv7psE4IVgKlF+QIekou6oN8m0T+QR2JLE0dHKwzicUbZLCr1v2Qw5T7L48A==
|
||||
"@nuxtjs/composition-api@^0.27.0":
|
||||
version "0.27.0"
|
||||
resolved "https://registry.yarnpkg.com/@nuxtjs/composition-api/-/composition-api-0.27.0.tgz#cbe4df6a7306e4a34770fbad5b1ad79717f8fdb7"
|
||||
integrity sha512-YtQ1KX+ls13zbukII8/vhKskoI1FrngDxegGVW31576qlaiEQUQGpOATF0cGrZ1W7Wgmz3rsAz1CNdSd5FFXOA==
|
||||
dependencies:
|
||||
"@vue/composition-api" "^1.0.4"
|
||||
"@vue/composition-api" "^1.1.1"
|
||||
defu "^5.0.0"
|
||||
estree-walker "^2.0.2"
|
||||
fs-extra "^9.1.0"
|
||||
magic-string "^0.25.7"
|
||||
ufo "^0.7.7"
|
||||
ufo "^0.7.9"
|
||||
upath "^2.0.1"
|
||||
|
||||
"@nuxtjs/dotenv@^1.4.1":
|
||||
@@ -1470,17 +1470,17 @@
|
||||
resolved "https://registry.yarnpkg.com/@nuxtjs/robots/-/robots-2.5.0.tgz#a42b25e3bc58181cb2a8fbd30d6b0fee6c36bc60"
|
||||
integrity sha512-z1F3HXb05NiZga8Cuq6k5bbowfJOScPtbSOakip0nege+1aI9pGoajzap8eR5s1qwLXAk9Ts+NcgetoUn5lwrQ==
|
||||
|
||||
"@nuxtjs/sentry@^5.1.0":
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@nuxtjs/sentry/-/sentry-5.1.1.tgz#329606bf93f804d18769cf26befd6786b86e0480"
|
||||
integrity sha512-tJq4I0r3M46WMO8oPIRVZ05VjXJrzuWCPYNRmhg2q2jcKgHaetK60RnJwGcnsDz6x92MLFVhdzA5kiJEIe9/7Q==
|
||||
"@nuxtjs/sentry@^5.1.2":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@nuxtjs/sentry/-/sentry-5.1.2.tgz#ba856e4b35676f5be9adfbe73cfa5b785fb0051c"
|
||||
integrity sha512-WdEa22ynTkFr2FQo3FZEEr5derBu2ckBvAYE5897kJvYp5dI65PK0dKRilPbHikrfb0hUWaPp2dH6Ke1VvGElw==
|
||||
dependencies:
|
||||
"@sentry/browser" "^6.11.0"
|
||||
"@sentry/integrations" "^6.11.0"
|
||||
"@sentry/node" "^6.11.0"
|
||||
"@sentry/webpack-plugin" "^1.17.1"
|
||||
consola "^2.15.3"
|
||||
lodash.merge "^4.6.2"
|
||||
lodash.mergewith "^4.6.2"
|
||||
|
||||
"@nuxtjs/sitemap@^2.4.0":
|
||||
version "2.4.0"
|
||||
@@ -2106,10 +2106,10 @@
|
||||
optionalDependencies:
|
||||
prettier "^1.18.2"
|
||||
|
||||
"@vue/composition-api@^1.0.4":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@vue/composition-api/-/composition-api-1.1.0.tgz#484e7e3bbc516ad6a9b0a9967d316325c239539e"
|
||||
integrity sha512-9TMJliVFByhfEJjqM+Ymu9ImVrUnrT/Y2S7Fz8EsQ1MbggbE0o8Ohvk9XqK2UIOp8w68f7goVX+6h6O78iRsJQ==
|
||||
"@vue/composition-api@^1.1.1":
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@vue/composition-api/-/composition-api-1.1.3.tgz#8fa528c5f68fec47363340fdae7c7fe047ba5e10"
|
||||
integrity sha512-gFcLkHD7SkaoE+i4OhMtv6c/gQeSYxEDDGk4yzF4tZ8h8+7oFNBX8lPUWf9McHGBTcztZNzsIZuwkDVmc0WZlQ==
|
||||
dependencies:
|
||||
tslib "^2.3.0"
|
||||
|
||||
@@ -3392,10 +3392,10 @@ core-js@^2.6.5:
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
||||
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
||||
|
||||
core-js@^3.16.1:
|
||||
version "3.16.1"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.16.1.tgz#f4485ce5c9f3c6a7cb18fa80488e08d362097249"
|
||||
integrity sha512-AAkP8i35EbefU+JddyWi12AWE9f2N/qr/pwnDtWz4nyUIBGMJPX99ANFFRSw6FefM374lDujdtLDyhN2A/btHw==
|
||||
core-js@^3.16.2:
|
||||
version "3.16.2"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.16.2.tgz#3f485822889c7fc48ef463e35be5cc2a4a01a1f4"
|
||||
integrity sha512-P0KPukO6OjMpjBtHSceAZEWlDD1M2Cpzpg6dBbrjFqFhBHe/BwhxaP820xKOjRn/lZRQirrCusIpLS/n2sgXLQ==
|
||||
|
||||
core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
@@ -5773,6 +5773,11 @@ lodash.merge@^4.6.2:
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||
|
||||
lodash.mergewith@^4.6.2:
|
||||
version "4.6.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55"
|
||||
integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==
|
||||
|
||||
lodash.template@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
|
||||
@@ -8275,10 +8280,10 @@ sass-loader@10.1.1:
|
||||
schema-utils "^3.0.0"
|
||||
semver "^7.3.2"
|
||||
|
||||
sass@^1.37.5:
|
||||
version "1.37.5"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.37.5.tgz#f6838351f7cc814c4fcfe1d9a20e0cabbd1e7b3c"
|
||||
integrity sha512-Cx3ewxz9QB/ErnVIiWg2cH0kiYZ0FPvheDTVC6BsiEGBTZKKZJ1Gq5Kq6jy3PKtL6+EJ8NIoaBW/RSd2R6cZOA==
|
||||
sass@^1.38.0:
|
||||
version "1.38.0"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.38.0.tgz#2f3e60a1efdcdc910586fa79dc89d3399a145b4f"
|
||||
integrity sha512-WBccZeMigAGKoI+NgD7Adh0ab1HUq+6BmyBUEaGxtErbUtWUevEbdgo5EZiJQofLUGcKtlNaO2IdN73AHEua5g==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
|
||||
@@ -9178,6 +9183,11 @@ ufo@^0.7.4, ufo@^0.7.5, ufo@^0.7.7:
|
||||
resolved "https://registry.yarnpkg.com/ufo/-/ufo-0.7.7.tgz#0062f9e5e790819b0fb23ca24d7c63a4011c036a"
|
||||
integrity sha512-N25aY3HBkJBnahm+2l4JRBBrX5I+JPakF/tDHYDTjd3wUR7iFLdyiPhj8mBwBz21v728BKwM9L9tgBfCntgdlw==
|
||||
|
||||
ufo@^0.7.9:
|
||||
version "0.7.9"
|
||||
resolved "https://registry.yarnpkg.com/ufo/-/ufo-0.7.9.tgz#0268e3734b413c9ed6f3510201f42372821b875c"
|
||||
integrity sha512-6t9LrLk3FhqTS+GW3IqlITtfRB5JAVr5MMNjpBECfK827W+Vh5Ilw/LhTcHWrt6b3hkeBvcbjx4Ti7QVFzmcww==
|
||||
|
||||
uglify-js@^3.5.1:
|
||||
version "3.14.1"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.1.tgz#e2cb9fe34db9cb4cf7e35d1d26dfea28e09a7d06"
|
||||
|
||||