Working
@@ -10,20 +10,20 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxt/content": "^1.14.0",
|
"@nuxt/content": "^1.14.0",
|
||||||
"@nuxtjs/axios": "^5.13.6",
|
"@nuxtjs/axios": "^5.13.6",
|
||||||
"@nuxtjs/composition-api": "^0.26.0",
|
"@nuxtjs/composition-api": "^0.27.0",
|
||||||
"@nuxtjs/dotenv": "^1.4.1",
|
"@nuxtjs/dotenv": "^1.4.1",
|
||||||
"@nuxtjs/i18n": "^7.0.2",
|
"@nuxtjs/i18n": "^7.0.2",
|
||||||
"@nuxtjs/proxy": "^2.1.0",
|
"@nuxtjs/proxy": "^2.1.0",
|
||||||
"@nuxtjs/redirect-module": "^0.3.1",
|
"@nuxtjs/redirect-module": "^0.3.1",
|
||||||
"@nuxtjs/robots": "^2.5.0",
|
"@nuxtjs/robots": "^2.5.0",
|
||||||
"@nuxtjs/sentry": "^5.1.0",
|
"@nuxtjs/sentry": "^5.1.2",
|
||||||
"@nuxtjs/sitemap": "^2.4.0",
|
"@nuxtjs/sitemap": "^2.4.0",
|
||||||
"@nuxtjs/universal-storage": "^0.5.9",
|
"@nuxtjs/universal-storage": "^0.5.9",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"core-js": "^3.16.1",
|
"core-js": "^3.16.2",
|
||||||
"nuxt": "^2.15.8",
|
"nuxt": "^2.15.8",
|
||||||
"prism-themes": "^1.8.0",
|
"prism-themes": "^1.8.0",
|
||||||
"sass": "^1.37.5"
|
"sass": "^1.38.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/types": "^2.15.8",
|
"@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 {$axios, $sentry, app} = useContext()
|
||||||
|
|
||||||
const announce = useAsync(async () => {
|
const announce = useAsync(async () => {
|
||||||
const response = await $axios.get('/api/announces', {
|
const response = await $axios.get('/api/announce', {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (response.status === 200) {
|
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 {
|
} else {
|
||||||
app.error({statusCode: 500})
|
app.error({statusCode: 500})
|
||||||
$sentry.captureEvent(response.data)
|
$sentry.captureEvent(response.data)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
<a target="_blank" href="https://www.twitch.tv/arthurdanjou" rel="noopener noreferrer">
|
<a target="_blank" href="https://www.twitch.tv/arthurdanjou" rel="noopener noreferrer">
|
||||||
<TwitchIcon />
|
<TwitchIcon />
|
||||||
</a>
|
</a>
|
||||||
<a target="_blank" href="https://discord.gg/RQhjE5UkxD" rel="noopener noreferrer">
|
<a target="_blank" href="https://discord.gg/ENG6cFQhPS" rel="noopener noreferrer">
|
||||||
<DiscordIcon />
|
<DiscordIcon />
|
||||||
</a>
|
</a>
|
||||||
<a target="_blank" href="mailto:contact@arthurdanjou.fr" rel="noopener noreferrer">
|
<a target="_blank" href="mailto:contact@arthurdanjou.fr" rel="noopener noreferrer">
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (response.status === 200) {
|
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 {
|
} else {
|
||||||
app.error({statusCode: 500})
|
app.error({statusCode: 500})
|
||||||
$sentry.captureEvent(response.data)
|
$sentry.captureEvent(response.data)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<ul class="flex items-center">
|
<ul class="flex items-center">
|
||||||
<li @click="changeLanguage()"
|
<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">
|
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>
|
||||||
<li @click="changeColorMode()"
|
<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">
|
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()
|
window.location.reload()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const isFrench = computed(() => i18n.locale === 'fr')
|
||||||
|
|
||||||
const store = useStore<State>()
|
const store = useStore<State>()
|
||||||
const route = computed(() => store.state.route)
|
const route = computed(() => store.state.route)
|
||||||
@@ -97,7 +98,8 @@ export default defineComponent({
|
|||||||
changeColorMode,
|
changeColorMode,
|
||||||
updateScroll,
|
updateScroll,
|
||||||
changeLanguage,
|
changeLanguage,
|
||||||
isWindow
|
isWindow,
|
||||||
|
isFrench
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<section class="w-full mb-10">
|
<section class="w-full mb-10">
|
||||||
<h3 class="font-bold text-2xl md:text-4xl">
|
<h3 class="font-bold text-2xl md:text-4xl">
|
||||||
{{ $t('about.title.languages') }}
|
{{ $t('about.title.languages') }}
|
||||||
<TranslateIcon />
|
<LanguageIcon />
|
||||||
</h3>
|
</h3>
|
||||||
<div>
|
<div>
|
||||||
<table class="text-base text-xl text-gray-700 dark:text-gray-400">
|
<table class="text-base text-xl text-gray-700 dark:text-gray-400">
|
||||||
@@ -21,6 +21,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "LanguagesAbout"
|
name: "LanguagesAbout",
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -51,22 +51,22 @@ export default defineComponent({
|
|||||||
const toggleMenu = () => {
|
const toggleMenu = () => {
|
||||||
store.commit('TOGGLE_OPENED', !store.state.opened)
|
store.commit('TOGGLE_OPENED', !store.state.opened)
|
||||||
if (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)
|
setTimeout(() => document.getElementById('nav')!.classList.add('z-50'), 300)
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('nav')!.classList.remove('z-50')
|
document.getElementById('nav')!.classList.remove('z-50')
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.getElementById('slider')!.style.maxHeight = 'none'
|
document.getElementById('slider')!.style.maxHeight = 'none'
|
||||||
}, 100)
|
}, 500)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const $router = useRouter()
|
const $router = useRouter()
|
||||||
$router.afterEach(() => {
|
$router.afterEach(() => {
|
||||||
store.commit('TOGGLE_OPENED', false)
|
store.commit('TOGGLE_OPENED', false)
|
||||||
document.getElementById('nav')!.classList.remove('z-50')
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.getElementById('slider')!.style.maxHeight = 'none'
|
document.getElementById('slider')!.style.maxHeight = 'none'
|
||||||
}, 100)
|
}, 600)
|
||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<nuxt-link :to="`/blog/${slug}`">
|
<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="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"
|
<div class="h-2/5 post rounded-t-lg"
|
||||||
:style="{ backgroundImage: `url(${getCover})` }">
|
:style="{ backgroundImage: `url(https://athena.arthurdanjou.fr/files/${cover})` }">
|
||||||
</div>
|
</div>
|
||||||
<div class="h-3/5 p-4 flex flex-col justify-between">
|
<div class="h-3/5 p-4 flex flex-col justify-between">
|
||||||
<div>
|
<div>
|
||||||
@@ -11,8 +11,8 @@
|
|||||||
<Tag :content="tag" :pill="true"/>
|
<Tag :content="tag" :pill="true"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-2xl font-bold">{{ title }}</h1>
|
<h1 class="text-2xl font-bold">{{ $t(title) }}</h1>
|
||||||
<p class="text-base mt-3 text-gray-700 dark:text-gray-400 text-justify">{{ description }}</p>
|
<p class="text-base mt-3 text-gray-700 dark:text-gray-400 text-justify">{{ $t(description) }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<h5 class="text-base text-gray-700 dark:text-gray-400">{{ formatDate }}</h5>
|
<h5 class="text-base text-gray-700 dark:text-gray-400">{{ formatDate }}</h5>
|
||||||
@@ -69,8 +69,6 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup(props: PostProps) {
|
setup(props: PostProps) {
|
||||||
const getCover = computed(() => require(`~/assets/images/posts/${props.cover}`))
|
|
||||||
|
|
||||||
const { i18n } = useContext()
|
const { i18n } = useContext()
|
||||||
const formatDate = computed(() => {
|
const formatDate = computed(() => {
|
||||||
const [first, second, third]: any = props.date.split('-')
|
const [first, second, third]: any = props.date.split('-')
|
||||||
@@ -78,7 +76,6 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getCover,
|
|
||||||
formatDate
|
formatDate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,9 @@
|
|||||||
<div class="my-8 lg:flex w-full lg:space-x-6">
|
<div class="my-8 lg:flex w-full lg:space-x-6">
|
||||||
<div v-for="post in posts">
|
<div v-for="post in posts">
|
||||||
<Post
|
<Post
|
||||||
:title="post.title"
|
:title="post.title.code"
|
||||||
:cover="post.cover"
|
:cover="post.cover.file_name"
|
||||||
:description="post.description"
|
:description="post.description.code"
|
||||||
:date="post.date"
|
:date="post.date"
|
||||||
:slug="post.slug"
|
:slug="post.slug"
|
||||||
:tags="post.tags"
|
:tags="post.tags"
|
||||||
@@ -36,17 +36,21 @@ import {Post} from "~/types/types";
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "PostsHome",
|
name: "PostsHome",
|
||||||
setup() {
|
setup() {
|
||||||
const { $content, i18n, $sentry } = useContext()
|
const { $axios, app, $sentry } = useContext()
|
||||||
|
|
||||||
const posts = useAsync(() => {
|
const posts = useAsync(async () => {
|
||||||
return $content(`articles/${i18n.locale}`)
|
const response = await $axios.get('/api/posts', {
|
||||||
.sortBy('date', 'asc')
|
headers: {
|
||||||
.limit(3)
|
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||||
.fetch<Post>()
|
}
|
||||||
.catch((error) => {
|
})
|
||||||
$sentry.captureEvent(error)
|
if (response.status === 200) {
|
||||||
})
|
return response.data.posts
|
||||||
}, 'posts')
|
} else {
|
||||||
|
app.error({statusCode: 500})
|
||||||
|
$sentry.captureEvent(response.data)
|
||||||
|
}
|
||||||
|
}, 'posts_home')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
posts
|
posts
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<img class="rounded-full my-5" src="~/assets/images/memojies/Hey.png" alt="A picture of myself" />
|
<img class="rounded-full my-5" src="~/assets/images/memojies/Hey.png" alt="A picture of myself" />
|
||||||
</div>
|
</div>
|
||||||
<div class="text-lg leading-6 text-justify dark:text-gray-400 text-gray-700">
|
<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.1')}}</p> <br/>
|
||||||
<p>{{ $t('about.banner.2') }}</p> <br/>
|
<p>{{ $t('about.banner.2') }}</p> <br/>
|
||||||
<p>{{ $t('about.banner.3') }}</p> <br />
|
<p>{{ $t('about.banner.3') }}</p> <br />
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<a :href="url" target="_blank">
|
<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="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-1/2 w-full h-2/5 project rounded-t-lg"
|
<div class="h-64 lg:h-1/2 w-full project rounded-t-lg"
|
||||||
:style="{ backgroundImage: `url(${getCover})` }">
|
:style="{ backgroundImage: `url(https://athena.arthurdanjou.fr/files/${cover})` }">
|
||||||
</div>
|
</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>
|
||||||
<div class="flex space-x-2 mb-2">
|
<div class="flex space-x-2 mb-2">
|
||||||
<div v-for="tag in tags">
|
<div v-for="tag in tags">
|
||||||
<Tag :content="tag" :pill="false"/>
|
<Tag :content="tag.label.code" :pill="false"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-2xl font-bold">{{ title }}</h1>
|
<h1 class="text-2xl font-bold">{{ title }}</h1>
|
||||||
@@ -20,15 +20,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {computed, defineComponent} from "@nuxtjs/composition-api";
|
import {defineComponent} from "@nuxtjs/composition-api";
|
||||||
|
|
||||||
interface ProjectProp {
|
|
||||||
title: string,
|
|
||||||
cover: string,
|
|
||||||
tags: Array<String>,
|
|
||||||
description: string,
|
|
||||||
url: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "Project",
|
name: "Project",
|
||||||
@@ -53,13 +45,6 @@ export default defineComponent({
|
|||||||
type: String,
|
type: String,
|
||||||
default: 'https://arthurdanjou.fr'
|
default: 'https://arthurdanjou.fr'
|
||||||
}
|
}
|
||||||
},
|
|
||||||
setup(props: ProjectProp) {
|
|
||||||
const getCover = computed(() => require(`@/assets/images/projects/${props.cover}`))
|
|
||||||
|
|
||||||
return {
|
|
||||||
getCover
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -9,12 +9,12 @@
|
|||||||
{{ $t('projects.description') }}
|
{{ $t('projects.description') }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</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">
|
<div v-for="project in projects" class="mb-4">
|
||||||
<Project
|
<Project
|
||||||
:title="project.title"
|
:title="project.name"
|
||||||
:cover="project.cover"
|
:cover="project.cover.file_name"
|
||||||
:description="project.description"
|
:description="project.description.code"
|
||||||
:tags="project.tags"
|
:tags="project.tags"
|
||||||
:url="project.url"
|
:url="project.url"
|
||||||
/>
|
/>
|
||||||
@@ -34,16 +34,21 @@ import {Project} from "~/types/types";
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "ProjectsHome",
|
name: "ProjectsHome",
|
||||||
setup() {
|
setup() {
|
||||||
const { $content, $sentry } = useContext()
|
const { $axios, app, $sentry } = useContext()
|
||||||
|
|
||||||
const projects = useAsync(() => {
|
const projects = useAsync(async () => {
|
||||||
return $content(`projects`)
|
const response = await $axios.get('/api/projects', {
|
||||||
.limit(3)
|
headers: {
|
||||||
.fetch<Project>()
|
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||||
.catch((error) => {
|
}
|
||||||
$sentry.captureEvent(error)
|
})
|
||||||
})
|
if (response.status === 200) {
|
||||||
}, 'projects')
|
return response.data.projects.slice(0, 3)
|
||||||
|
} else {
|
||||||
|
$sentry.captureEvent(response.data)
|
||||||
|
app.error({statusCode: 500})
|
||||||
|
}
|
||||||
|
}, 'projects_home')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
projects
|
projects
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<ul class="flex items-center">
|
<ul class="flex items-center">
|
||||||
<li @click="changeLanguage()"
|
<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">
|
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>
|
||||||
<li @click="changeColorMode()"
|
<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">
|
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">
|
<a target="_blank" href="https://www.twitch.tv/arthurdanjou" rel="noopener noreferrer">
|
||||||
<TwitchIcon />
|
<TwitchIcon />
|
||||||
</a>
|
</a>
|
||||||
<a target="_blank" href="https://discord.gg/RQhjE5UkxD" rel="noopener noreferrer">
|
<a target="_blank" href="https://discord.gg/ENG6cFQhPS" rel="noopener noreferrer">
|
||||||
<DiscordIcon />
|
<DiscordIcon />
|
||||||
</a>
|
</a>
|
||||||
<a target="_blank" href="mailto:contact@arthurdanjou.fr" rel="noopener noreferrer">
|
<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 store = useStore<State>()
|
||||||
const closeMenu = () => {
|
const closeMenu = () => {
|
||||||
store.commit('TOGGLE_OPENED', false)
|
store.commit('TOGGLE_OPENED', false)
|
||||||
document.getElementById('nav')!.classList.remove('z-50')
|
document.getElementById('nav')!.classList.remove('z-50')
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.getElementById('slider')!.style.maxHeight = 'none'
|
document.getElementById('slider')!.style.maxHeight = 'none'
|
||||||
}, 100)
|
}, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
const route = computed(() => store.state.route)
|
const route = computed(() => store.state.route)
|
||||||
@@ -150,7 +152,8 @@ export default defineComponent({
|
|||||||
changeLanguage,
|
changeLanguage,
|
||||||
closeMenu,
|
closeMenu,
|
||||||
opened: computed(() => store.state.opened),
|
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>
|
<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
|
<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="#00247D"
|
||||||
fill="currentColor"
|
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>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "TranslateIcon"
|
name: "TranslateIcon",
|
||||||
|
props: {
|
||||||
|
french: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
---
|
---
|
||||||
slug: how-i-start
|
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
|
## Presentation
|
||||||
@@ -1,11 +1,5 @@
|
|||||||
---
|
---
|
||||||
slug: new-version-new-website
|
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
|
## Presentation
|
||||||
@@ -1,11 +1,5 @@
|
|||||||
---
|
---
|
||||||
slug: how-i-start
|
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
|
## Présentation
|
||||||
@@ -1,11 +1,5 @@
|
|||||||
---
|
---
|
||||||
slug: new-version-new-website
|
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
|
## 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"
|
id="slider"
|
||||||
class="xl:static shadow-2xl transition-all duration-500 overflow-hidden xl:overflow-visible"
|
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}"
|
: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"
|
:tabindex="opened ? -1 : 0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@@ -41,17 +40,14 @@ export default {
|
|||||||
const closeMenu = () => {
|
const closeMenu = () => {
|
||||||
store.commit('TOGGLE_OPENED', false)
|
store.commit('TOGGLE_OPENED', false)
|
||||||
document.getElementById('nav')!.classList.remove('z-50')
|
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 {
|
return {
|
||||||
opened: computed(() => store.state.opened),
|
opened: computed(() => store.state.opened),
|
||||||
closeMenu,
|
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: {
|
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',
|
links: 'Quick links',
|
||||||
credits: 'Developed with',
|
credits: 'Developed with',
|
||||||
credits_separator: 'and',
|
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.',
|
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.',
|
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.',
|
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: {
|
title: {
|
||||||
skills: 'Skills',
|
skills: 'Skills',
|
||||||
@@ -252,7 +252,14 @@ const translations = {
|
|||||||
linkyjs: 'LinkyJS is my custom and Open-Source url shortener'
|
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 () {
|
export default async function () {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ const translations = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
footer: {
|
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',
|
links: 'Liens rapides',
|
||||||
credits: 'Développé avec',
|
credits: 'Développé avec',
|
||||||
credits_separator: 'et',
|
credits_separator: 'et',
|
||||||
@@ -252,7 +252,14 @@ const translations = {
|
|||||||
linkyjs: "LinkyJS est mon raccourcisseur d'url personnalisé et Open-Source."
|
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 () {
|
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>
|
<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">
|
<div class="mt-8 md:mt-32 flex flex-col justify-around py-8 w-full">
|
||||||
|
{{ slug }}
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-4 flex">
|
<div class="mb-4 flex">
|
||||||
<nuxt-link to="/blog" class="back-arrow flex">
|
<nuxt-link to="/blog" class="back-arrow flex">
|
||||||
@@ -14,10 +15,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-3xl md:text-5xl font-bold">
|
<h1 class="text-3xl md:text-5xl font-bold">
|
||||||
{{ post.title }}
|
{{ $t(postData.title.code) }}
|
||||||
</h1>
|
</h1>
|
||||||
<h3 class="text-xl text-gray-800 dark:text-gray-300 my-4 md:mt-8">
|
<h3 class="text-xl text-gray-800 dark:text-gray-300 my-4 md:mt-8">
|
||||||
{{ post.description }}
|
{{ $t(postData.description.code) }}
|
||||||
</h3>
|
</h3>
|
||||||
<div class="flex flex-row justify-between w-full md:w-2/3 mb-12">
|
<div class="flex flex-row justify-between w-full md:w-2/3 mb-12">
|
||||||
<div>
|
<div>
|
||||||
@@ -26,16 +27,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="uppercase text-sm font-bold text-gray-800 dark:text-gray-400">{{ $t('blog.read.time') }}</p>
|
<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>
|
||||||
<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>
|
<p>{{ formatTags }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<div class="flex justify-center 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>
|
||||||
</div>
|
</div>
|
||||||
<nuxt-content
|
<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'"
|
: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">
|
<div class="mr-2 lining-nums leading-3">
|
||||||
{{ likes }}
|
{{ getLikes }}
|
||||||
</div>
|
</div>
|
||||||
<div class="inline leading-6" :class="{'animate-pulse heartbeat': liked}">
|
<div class="inline leading-6" :class="{'animate-pulse heartbeat': liked}">
|
||||||
<HeartIcon :liked="liked"/>
|
<HeartIcon :liked="liked"/>
|
||||||
@@ -63,7 +64,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
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"
|
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 />
|
<TwitterBlogIcon />
|
||||||
@@ -119,7 +120,7 @@ export default defineComponent({
|
|||||||
const slug = computed(() => route.value.params.slug)
|
const slug = computed(() => route.value.params.slug)
|
||||||
|
|
||||||
const post = useStatic((slug) => {
|
const post = useStatic((slug) => {
|
||||||
return $content(`articles/${i18n.locale}`, slug)
|
return $content(i18n.locale, slug)
|
||||||
.fetch<Post>()
|
.fetch<Post>()
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
app.error({statusCode: 404, message: "Post not found"})
|
app.error({statusCode: 404, message: "Post not found"})
|
||||||
@@ -127,31 +128,34 @@ export default defineComponent({
|
|||||||
}) as Promise<Post>
|
}) as Promise<Post>
|
||||||
}, slug, '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 liked = ref($storage.getCookie(`${slug.value}`) !== undefined)
|
||||||
|
const likes = ref(0)
|
||||||
|
const getLikes = computed(() => likes.value)
|
||||||
|
|
||||||
const likes = useAsync(async () => {
|
const postData = useAsync(async () => {
|
||||||
const response = await $axios.get(`/api/posts/${slug.value}`, {
|
const response = await $axios.get(`/api/posts/${slug.value}/data`, {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (response.status === 200) {
|
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 {
|
} else {
|
||||||
$sentry.captureEvent(response.data)
|
$sentry.captureEvent(response.data)
|
||||||
app.error({statusCode: 500})
|
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 () => {
|
const handleLike = async () => {
|
||||||
if (liked.value) {
|
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: {
|
headers: {
|
||||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||||
}
|
}
|
||||||
@@ -165,7 +169,7 @@ export default defineComponent({
|
|||||||
app.error({statusCode: 500})
|
app.error({statusCode: 500})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const response = await $axios.post(`/api/posts/${post.value?.slug}/like`, {}, {
|
const response = await $axios.post(`/api/posts/${postData.value.slug}/like`, {}, {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||||
}
|
}
|
||||||
@@ -185,7 +189,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
const isCopied = ref(false)
|
const isCopied = ref(false)
|
||||||
const copyToClipboard = () => {
|
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
|
isCopied.value = true
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
isCopied.value = false
|
isCopied.value = false
|
||||||
@@ -200,13 +204,13 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const formatDate = computed(() => {
|
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}`
|
return `${first} ${i18n.t(`month.${second}`)} ${third}`
|
||||||
})
|
})
|
||||||
|
|
||||||
const formatTags = computed(() => {
|
const formatTags = computed(() => {
|
||||||
let tags = ""
|
let tags = ""
|
||||||
post.value?.tags.map(tag => {
|
postData.value.tags.map(tag => {
|
||||||
tags += i18n.t(String(tag)) + ", "
|
tags += i18n.t(String(tag)) + ", "
|
||||||
})
|
})
|
||||||
return tags.substring(0, tags.length - 2)
|
return tags.substring(0, tags.length - 2)
|
||||||
@@ -214,14 +218,16 @@ export default defineComponent({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
post,
|
post,
|
||||||
likes,
|
getLikes,
|
||||||
liked,
|
liked,
|
||||||
handleLike,
|
handleLike,
|
||||||
isCopied,
|
isCopied,
|
||||||
copyToClipboard,
|
copyToClipboard,
|
||||||
scrollToTop,
|
scrollToTop,
|
||||||
formatDate,
|
formatDate,
|
||||||
formatTags
|
formatTags,
|
||||||
|
postData,
|
||||||
|
slug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
<div class="flex py-8 w-full flex-wrap">
|
<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">
|
<div class="md:mx-8 my-4 w-full lg:w-auto" v-for="post in posts">
|
||||||
<Post
|
<Post
|
||||||
:title="post.title"
|
:title="post.title.code"
|
||||||
:cover="post.cover"
|
:cover="post.cover.file_name"
|
||||||
:description="post.description"
|
:description="post.description.code"
|
||||||
:date="post.date"
|
:date="post.date"
|
||||||
:slug="post.slug"
|
:slug="post.slug"
|
||||||
:tags="post.tags"
|
:tags="post.tags"
|
||||||
@@ -41,20 +41,25 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const { $content, i18n, $sentry } = useContext()
|
const { $sentry, $axios, app } = useContext()
|
||||||
|
|
||||||
const posts = useAsync(() => {
|
const posts = useAsync(async () => {
|
||||||
return $content(`articles/${i18n.locale}`)
|
const response = await $axios.get('/api/posts', {
|
||||||
.sortBy('date', 'asc')
|
headers: {
|
||||||
.limit(10)
|
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||||
.fetch<Post>()
|
}
|
||||||
.catch((error) => {
|
})
|
||||||
$sentry.captureEvent(error)
|
if (response.status === 200) {
|
||||||
})
|
console.log(response.data.posts)
|
||||||
|
return response.data.posts
|
||||||
|
} else {
|
||||||
|
app.error({statusCode: 500})
|
||||||
|
$sentry.captureEvent(response.data)
|
||||||
|
}
|
||||||
}, 'posts')
|
}, 'posts')
|
||||||
|
|
||||||
return {
|
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">
|
<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>
|
<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 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="lg: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="m-4" v-for="project in projects">
|
||||||
<Project
|
<Project
|
||||||
:title="project.title"
|
:title="project.name"
|
||||||
:cover="project.cover"
|
:cover="project.cover.file_name"
|
||||||
:description="project.description"
|
:description="project.description.code"
|
||||||
:tags="project.tags"
|
:tags="project.tags"
|
||||||
:url="project.url"
|
:url="project.url"
|
||||||
/>
|
/>
|
||||||
@@ -33,14 +33,20 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const { $content, $sentry } = useContext()
|
const { $axios, app, $sentry } = useContext()
|
||||||
|
|
||||||
const projects = useAsync(() => {
|
const projects = useAsync(async () => {
|
||||||
return $content('projects')
|
const response = await $axios.get('/api/projects', {
|
||||||
.fetch<Project>()
|
headers: {
|
||||||
.catch((error) => {
|
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||||
$sentry.captureEvent(error)
|
}
|
||||||
})
|
})
|
||||||
|
if (response.status === 200) {
|
||||||
|
return response.data.projects
|
||||||
|
} else {
|
||||||
|
$sentry.captureEvent(response.data)
|
||||||
|
app.error({statusCode: 500})
|
||||||
|
}
|
||||||
}, 'projects')
|
}, 'projects')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
56
yarn.lock
@@ -1414,17 +1414,17 @@
|
|||||||
defu "^5.0.0"
|
defu "^5.0.0"
|
||||||
lodash.template "^4.5.0"
|
lodash.template "^4.5.0"
|
||||||
|
|
||||||
"@nuxtjs/composition-api@^0.26.0":
|
"@nuxtjs/composition-api@^0.27.0":
|
||||||
version "0.26.0"
|
version "0.27.0"
|
||||||
resolved "https://registry.yarnpkg.com/@nuxtjs/composition-api/-/composition-api-0.26.0.tgz#0fbda4fc942ca1e346b7c6d55a1fb331ff931a2a"
|
resolved "https://registry.yarnpkg.com/@nuxtjs/composition-api/-/composition-api-0.27.0.tgz#cbe4df6a7306e4a34770fbad5b1ad79717f8fdb7"
|
||||||
integrity sha512-+4L9YDEN5h/vBY6xbBKPMIhgxbPv7psE4IVgKlF+QIekou6oN8m0T+QR2JLE0dHKwzicUbZLCr1v2Qw5T7L48A==
|
integrity sha512-YtQ1KX+ls13zbukII8/vhKskoI1FrngDxegGVW31576qlaiEQUQGpOATF0cGrZ1W7Wgmz3rsAz1CNdSd5FFXOA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/composition-api" "^1.0.4"
|
"@vue/composition-api" "^1.1.1"
|
||||||
defu "^5.0.0"
|
defu "^5.0.0"
|
||||||
estree-walker "^2.0.2"
|
estree-walker "^2.0.2"
|
||||||
fs-extra "^9.1.0"
|
fs-extra "^9.1.0"
|
||||||
magic-string "^0.25.7"
|
magic-string "^0.25.7"
|
||||||
ufo "^0.7.7"
|
ufo "^0.7.9"
|
||||||
upath "^2.0.1"
|
upath "^2.0.1"
|
||||||
|
|
||||||
"@nuxtjs/dotenv@^1.4.1":
|
"@nuxtjs/dotenv@^1.4.1":
|
||||||
@@ -1470,17 +1470,17 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@nuxtjs/robots/-/robots-2.5.0.tgz#a42b25e3bc58181cb2a8fbd30d6b0fee6c36bc60"
|
resolved "https://registry.yarnpkg.com/@nuxtjs/robots/-/robots-2.5.0.tgz#a42b25e3bc58181cb2a8fbd30d6b0fee6c36bc60"
|
||||||
integrity sha512-z1F3HXb05NiZga8Cuq6k5bbowfJOScPtbSOakip0nege+1aI9pGoajzap8eR5s1qwLXAk9Ts+NcgetoUn5lwrQ==
|
integrity sha512-z1F3HXb05NiZga8Cuq6k5bbowfJOScPtbSOakip0nege+1aI9pGoajzap8eR5s1qwLXAk9Ts+NcgetoUn5lwrQ==
|
||||||
|
|
||||||
"@nuxtjs/sentry@^5.1.0":
|
"@nuxtjs/sentry@^5.1.2":
|
||||||
version "5.1.1"
|
version "5.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@nuxtjs/sentry/-/sentry-5.1.1.tgz#329606bf93f804d18769cf26befd6786b86e0480"
|
resolved "https://registry.yarnpkg.com/@nuxtjs/sentry/-/sentry-5.1.2.tgz#ba856e4b35676f5be9adfbe73cfa5b785fb0051c"
|
||||||
integrity sha512-tJq4I0r3M46WMO8oPIRVZ05VjXJrzuWCPYNRmhg2q2jcKgHaetK60RnJwGcnsDz6x92MLFVhdzA5kiJEIe9/7Q==
|
integrity sha512-WdEa22ynTkFr2FQo3FZEEr5derBu2ckBvAYE5897kJvYp5dI65PK0dKRilPbHikrfb0hUWaPp2dH6Ke1VvGElw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@sentry/browser" "^6.11.0"
|
"@sentry/browser" "^6.11.0"
|
||||||
"@sentry/integrations" "^6.11.0"
|
"@sentry/integrations" "^6.11.0"
|
||||||
"@sentry/node" "^6.11.0"
|
"@sentry/node" "^6.11.0"
|
||||||
"@sentry/webpack-plugin" "^1.17.1"
|
"@sentry/webpack-plugin" "^1.17.1"
|
||||||
consola "^2.15.3"
|
consola "^2.15.3"
|
||||||
lodash.merge "^4.6.2"
|
lodash.mergewith "^4.6.2"
|
||||||
|
|
||||||
"@nuxtjs/sitemap@^2.4.0":
|
"@nuxtjs/sitemap@^2.4.0":
|
||||||
version "2.4.0"
|
version "2.4.0"
|
||||||
@@ -2106,10 +2106,10 @@
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
prettier "^1.18.2"
|
prettier "^1.18.2"
|
||||||
|
|
||||||
"@vue/composition-api@^1.0.4":
|
"@vue/composition-api@^1.1.1":
|
||||||
version "1.1.0"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/composition-api/-/composition-api-1.1.0.tgz#484e7e3bbc516ad6a9b0a9967d316325c239539e"
|
resolved "https://registry.yarnpkg.com/@vue/composition-api/-/composition-api-1.1.3.tgz#8fa528c5f68fec47363340fdae7c7fe047ba5e10"
|
||||||
integrity sha512-9TMJliVFByhfEJjqM+Ymu9ImVrUnrT/Y2S7Fz8EsQ1MbggbE0o8Ohvk9XqK2UIOp8w68f7goVX+6h6O78iRsJQ==
|
integrity sha512-gFcLkHD7SkaoE+i4OhMtv6c/gQeSYxEDDGk4yzF4tZ8h8+7oFNBX8lPUWf9McHGBTcztZNzsIZuwkDVmc0WZlQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^2.3.0"
|
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"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
||||||
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
||||||
|
|
||||||
core-js@^3.16.1:
|
core-js@^3.16.2:
|
||||||
version "3.16.1"
|
version "3.16.2"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.16.1.tgz#f4485ce5c9f3c6a7cb18fa80488e08d362097249"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.16.2.tgz#3f485822889c7fc48ef463e35be5cc2a4a01a1f4"
|
||||||
integrity sha512-AAkP8i35EbefU+JddyWi12AWE9f2N/qr/pwnDtWz4nyUIBGMJPX99ANFFRSw6FefM374lDujdtLDyhN2A/btHw==
|
integrity sha512-P0KPukO6OjMpjBtHSceAZEWlDD1M2Cpzpg6dBbrjFqFhBHe/BwhxaP820xKOjRn/lZRQirrCusIpLS/n2sgXLQ==
|
||||||
|
|
||||||
core-util-is@~1.0.0:
|
core-util-is@~1.0.0:
|
||||||
version "1.0.2"
|
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"
|
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
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:
|
lodash.template@^4.5.0:
|
||||||
version "4.5.0"
|
version "4.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
|
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"
|
schema-utils "^3.0.0"
|
||||||
semver "^7.3.2"
|
semver "^7.3.2"
|
||||||
|
|
||||||
sass@^1.37.5:
|
sass@^1.38.0:
|
||||||
version "1.37.5"
|
version "1.38.0"
|
||||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.37.5.tgz#f6838351f7cc814c4fcfe1d9a20e0cabbd1e7b3c"
|
resolved "https://registry.yarnpkg.com/sass/-/sass-1.38.0.tgz#2f3e60a1efdcdc910586fa79dc89d3399a145b4f"
|
||||||
integrity sha512-Cx3ewxz9QB/ErnVIiWg2cH0kiYZ0FPvheDTVC6BsiEGBTZKKZJ1Gq5Kq6jy3PKtL6+EJ8NIoaBW/RSd2R6cZOA==
|
integrity sha512-WBccZeMigAGKoI+NgD7Adh0ab1HUq+6BmyBUEaGxtErbUtWUevEbdgo5EZiJQofLUGcKtlNaO2IdN73AHEua5g==
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar ">=3.0.0 <4.0.0"
|
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"
|
resolved "https://registry.yarnpkg.com/ufo/-/ufo-0.7.7.tgz#0062f9e5e790819b0fb23ca24d7c63a4011c036a"
|
||||||
integrity sha512-N25aY3HBkJBnahm+2l4JRBBrX5I+JPakF/tDHYDTjd3wUR7iFLdyiPhj8mBwBz21v728BKwM9L9tgBfCntgdlw==
|
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:
|
uglify-js@^3.5.1:
|
||||||
version "3.14.1"
|
version "3.14.1"
|
||||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.1.tgz#e2cb9fe34db9cb4cf7e35d1d26dfea28e09a7d06"
|
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.1.tgz#e2cb9fe34db9cb4cf7e35d1d26dfea28e09a7d06"
|
||||||
|
|||||||