Import nuxt 3 and edit to script setup

This commit is contained in:
2021-11-07 22:19:18 +01:00
parent 0ed426b710
commit 83c1eca443
60 changed files with 3293 additions and 7086 deletions

View File

@@ -1,22 +1,125 @@
import head from './settings/Head'
import buildModules from './settings/BuildModules'
import modules from './settings/Modules'
import build from './settings/Build'
import arch from './settings/Arch'
import plugins from './settings/Plugins'
import css from './settings/Style'
import configs from './settings/RuntimeConfig'
import {NuxtConfig} from "@nuxt/types";
import WindicssConfig from "./settings/WindicssConfig";
import ColorModeConfig from "./settings/ColorModeConfig";
import HeadConfig from "./settings/HeadConfig";
import SentryConfig from "./settings/SentryConfig";
import AxiosConfig from "./settings/AxiosConfig";
import I18nConfig from "./settings/I18nConfig";
import StorageConfig from "./settings/StorageConfig";
import RobotsConfig from "./settings/RobotsConfig";
import EnvConfig from "./settings/EnvConfig";
import RedirectConfig from "./settings/RedirectConfig";
import SiteMapConfig from "./settings/SiteMapConfig";
import {defineNuxtConfig} from "nuxt3";
const config = {
head,
modules,
...arch,
build,
plugins,
css,
buildModules,
...configs,
} as NuxtConfig
export default defineNuxtConfig({
target: 'server',
ssr: true,
export default config
server: {
host: '0.0.0.0',
port: 3333
},
proxy: {
'/api': {
target: 'https://athena.arthurdanjou.fr',
pathRewrite: { "^/api": "" }
}
},
router: {
middleware: [
'maintenance'
]
},
srcDir: 'src',
dir: {
assets: 'assets',
layouts: 'layouts',
middleware: 'middlewares',
pages: 'pages',
static: 'static',
store: 'store',
},
components: [
'components',
'components/icons'
],
build: {
extractCSS: true,
babel: {
plugins: [
['@babel/plugin-proposal-private-methods', { loose: true }]
],
}
},
pageTransition: {
name: 'page',
mode: 'out-in',
},
buildModules: [
['nuxt-windicss', WindicssConfig],
// ['@nuxtjs/color-mode', ColorModeConfig],
],
modules: [
// ['@nuxtjs/axios', AxiosConfig],
// ['@nuxtjs/i18n', I18nConfig],
// ['@nuxt/content', content],
// ['@nuxtjs/universal-storage', StorageConfig],
// ['@nuxtjs/robots', RobotsConfig],
// ['@nuxtjs/sitemap', SiteMapConfig],
// ['@nuxtjs/redirect-module', RedirectConfig],
// ['@nuxtjs/dotenv', EnvConfig],
// ['@nuxtjs/sentry', SentryConfig]
],
head: {
meta: [
{ charset: 'utf-8' },
{ lang: 'fr-FR' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: HeadConfig.description },
/**
* Open graph
* See : https://ogp.me/
*/
{ hid: 'og:type', name: 'og:type', content: 'website' },
{ hid: 'og:url', name: 'og:url', content: HeadConfig.url },
{ hid: 'og:title', name: 'og:title', content: HeadConfig.title },
{ hid: 'og:site_name', name: 'og:site_name', content: HeadConfig.title },
{ hid: 'og:locale', name: 'og:locale', content: 'fr' },
{ hid: 'og:image', name: 'og:image', content: HeadConfig.image },
{ name: 'msapplication-TileColor', content: HeadConfig.color },
{ name: 'theme-color', content: HeadConfig.color },
],
link: [
{ rel: 'icon', type: HeadConfig.favicon.type, href: HeadConfig.favicon.href },
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
{ rel: 'preconnect', href: 'https://fonts.googleapis.com', crossOrigin: 'true' },
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Raleway:wght@500&family=Roboto:wght@900&display=swap' }
],
},
plugins: [
{
src: '~/plugins/i18n.ts'
}
],
publicRuntimeConfig: {
},
privateRuntimeConfig: {
API_TOKEN: process.env.API_TOKEN,
SENTRY_DSN: process.env.SENTRY_DSN
}
})

View File

@@ -3,15 +3,13 @@
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"dev": "nuxi dev",
"build": "nuxi build",
"start": "node .nuxt/server/index.mjs",
"analyse": "windicss-analysis"
},
"dependencies": {
"@nuxt/content": "^1.15.0",
"@nuxtjs/axios": "^5.13.6",
"@nuxtjs/composition-api": "^0.29.3",
"@nuxtjs/dotenv": "^1.4.1",
"@nuxtjs/i18n": "^7.1.0",
"@nuxtjs/proxy": "^2.1.0",
@@ -23,13 +21,12 @@
"axios": "^0.24.0",
"blobity": "^0.1.7",
"core-js": "^3.19.1",
"nuxt": "^2.15.8",
"nuxt3": "latest",
"prism-themes": "^1.9.0",
"sass": "^1.43.4"
},
"devDependencies": {
"@nuxt/types": "^2.15.8",
"@nuxt/typescript-build": "^2.1.0",
"@nuxtjs/color-mode": "^2.1.1",
"markdown-it-prism": "^2.2.1",
"nuxt-windicss": "^2.0.11",

View File

@@ -1,48 +0,0 @@
const srcDir = 'src'
const dir = {
assets: 'assets',
layouts: 'layouts',
middleware: 'middlewares',
pages: 'pages',
static: 'static',
store: 'store',
}
const build = {
extractCss: true,
}
const pageTransition = {
name: 'page',
mode: 'out-in',
}
const target = 'server'
const server = {
port: 3333,
host: '0.0.0.0'
}
const components = [
'components',
'components/icons'
]
const buildDir = '.nuxt'
const ssr = true
const proxy = {
'/api': {
target: 'https://athena.arthurdanjou.fr',
pathRewrite: { "^/api": "" }
}
}
const router = {
middleware: 'maintenance'
}
export default { router, srcDir, dir, build, pageTransition, target, server, buildDir, components, ssr, proxy }

5
settings/AxiosConfig.ts Normal file
View File

@@ -0,0 +1,5 @@
export default {
proxy: true,
credentials: true,
proxyHeaders: true
}

View File

@@ -1,15 +0,0 @@
// Build Configuration: https://go.nuxtjs.dev/config-build
export default {
babel: {
plugins: [
['@babel/plugin-proposal-private-methods', { loose: true }]
],
},
postcss: {
preset: {
features: {
"focus-within-pseudo-class": false
}
}
}
}

View File

@@ -1,40 +0,0 @@
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
import {NuxtOptionsModule} from "@nuxt/types/config/module";
const color_mode = {
preference: 'system',
fallback: 'light',
classPrefix: '',
classSuffix: '',
}
const windicss = {
scan: {
dirs: [ './' ],
exclude: [
'node_modules',
'.git',
'.nuxt/**/*',
'build/**/*',
'*.template.html',
'app.html'
],
include: []
},
transformCSS: 'pre',
preflight: {
alias: {
// add nuxt aliases
'nuxt-link': 'a',
// @nuxt/image module
'nuxt-img': 'img',
}
}
}
export default [
'@nuxt/typescript-build',
'@nuxtjs/composition-api/module',
['nuxt-windicss', windicss],
['@nuxtjs/color-mode', color_mode],
] as NuxtOptionsModule[]

View File

@@ -0,0 +1,6 @@
export default {
preference: 'system',
fallback: 'light',
classPrefix: '',
classSuffix: '',
}

3
settings/EnvConfig.ts Normal file
View File

@@ -0,0 +1,3 @@
export default {
path: process.cwd()
}

View File

@@ -1,46 +0,0 @@
// Global page headers: https://go.nuxtjs.dev/config-head
import {NuxtOptionsHead} from "@nuxt/types/config/head";
const params = {
title: 'arthurdanjou.fr - Web & Software Developer',
color: '#00a0ff',
image: '/images/memojies/Hey.png',
url: 'https://arthurdanjou.fr',
favicon: {
type: 'image/jpg',
href: '/favicon.png',
},
description:
'Web & Software Developer from Paris, France.',
}
export default {
htmlAttrs: { lang: 'fr-FR' },
title: params.title,
meta: [
{ charset: 'utf-8' },
{ lang: 'fr-FR' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: params.description },
/**
* Open graph
* See : https://ogp.me/
*/
{ hid: 'og:type', name: 'og:type', content: 'website' },
{ hid: 'og:url', name: 'og:url', content: params.url },
{ hid: 'og:title', name: 'og:title', content: params.title },
{ hid: 'og:site_name', name: 'og:site_name', content: params.title },
{ hid: 'og:locale', name: 'og:locale', content: 'fr' },
{ hid: 'og:image', name: 'og:image', content: params.image },
{ name: 'msapplication-TileColor', content: params.color },
{ name: 'theme-color', content: params.color },
],
link: [
{ rel: 'icon', type: params.favicon.type, href: params.favicon.href },
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
{ rel: 'preconnect', href: 'https://fonts.googleapis.com', crossOrigin: 'true' },
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Raleway:wght@500&family=Roboto:wght@900&display=swap' }
],
} as NuxtOptionsHead

11
settings/HeadConfig.ts Normal file
View File

@@ -0,0 +1,11 @@
export default {
title: 'arthurdanjou.fr - Web & Software Developer',
color: '#00a0ff',
image: '/images/memojies/Hey.png',
url: 'https://arthurdanjou.fr',
favicon: {
type: 'image/jpg',
href: '/favicon.png',
},
description: 'Web & Software Developer from Paris, France.',
}

24
settings/I18nConfig.ts Normal file
View File

@@ -0,0 +1,24 @@
export default {
locales: [
{
code: 'en',
name: 'English',
iso: 'en-EN',
file: 'en-EN.ts',
},
{
code: 'fr',
name: 'Français',
iso: 'fr-FR',
file: 'fr-FR.ts'
},
],
strategy: 'no_prefix',
defaultLocale: 'en',
langDir: 'locales/',
lazy: true,
seo: true,
vueI18n: {
fallbackLocale: 'en',
},
}

View File

@@ -1,98 +0,0 @@
import {NuxtOptionsModule} from "@nuxt/types/config/module";
const axios = {
proxy: true,
credentials: true,
proxyHeaders: true
}
const i18n = {
locales: [
{
code: 'en',
name: 'English',
iso: 'en-EN',
file: 'en-EN.ts',
},
{
code: 'fr',
name: 'Français',
iso: 'fr-FR',
file: 'fr-FR.ts'
},
],
strategy: 'no_prefix',
defaultLocale: 'en',
langDir: 'locales/',
lazy: true,
seo: true,
vueI18n: {
fallbackLocale: 'en',
},
}
const content = {
nestedProperties: ['skills.slug'],
markdown: {
prism: {
theme: 'prism-themes/themes/prism-darcula.css'
},
remarkPlugins: [
'remark-squeeze-paragraphs',
'remark-slug',
'remark-autolink-headings',
'remark-external-links',
'remark-footnotes',
],
}
}
const storage = {
cookie: {
prefix: 'arthurdanjou.fr/',
options: {
path: '/'
}
},
}
const sitemap = {
path: '/sitemap.xml',
hostname: 'https://arthurdanjou.fr',
cacheTime: 720000,
gzip: true,
generate: false,
}
const robots = {
UserAgent: '*',
Sitemap: 'https://arthurdanjou.fr/sitemap.xml',
Allow: '*'
}
const redirect = [
{ from: '/source', to: 'https://github.com/arthurdanjou/ares' },
{ from: '/shelf', to: '/blog' },
{ from: '/posts', to: '/blog' },
{ from: '/resume', to: '/cv' }
]
const env = {
path: process.cwd()
}
const sentry = {
dsn: process.env.SENTRY_DSN
}
export default [
['@nuxtjs/axios', axios],
['@nuxtjs/i18n', i18n],
['@nuxt/content', content],
['@nuxtjs/universal-storage', storage],
['@nuxtjs/robots', robots],
['@nuxtjs/sitemap', sitemap],
['@nuxtjs/redirect-module', redirect],
['@nuxtjs/dotenv', env],
['@nuxtjs/sentry', sentry]
] as NuxtOptionsModule[]

View File

@@ -1,6 +0,0 @@
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
export default [
{
src: '~/plugins/i18n.ts'
}
]

View File

@@ -0,0 +1,6 @@
export default [
{ from: '/source', to: 'https://github.com/arthurdanjou/ares' },
{ from: '/shelf', to: '/blog' },
{ from: '/posts', to: '/blog' },
{ from: '/resume', to: '/cv' }
]

5
settings/RobotsConfig.ts Normal file
View File

@@ -0,0 +1,5 @@
export default {
UserAgent: '*',
Sitemap: 'https://arthurdanjou.fr/sitemap.xml',
Allow: '*'
}

View File

@@ -1,9 +0,0 @@
const publicRuntimeConfig = {
}
const privateRuntimeConfig = {
API_TOKEN: process.env.API_TOKEN,
SENTRY_DSN: process.env.SENTRY_DSN
}
export default { publicRuntimeConfig, privateRuntimeConfig}

3
settings/SentryConfig.ts Normal file
View File

@@ -0,0 +1,3 @@
export default {
dsn: process.env.SENTRY_DSN
}

View File

@@ -0,0 +1,7 @@
export default {
path: '/sitemap.xml',
hostname: 'https://arthurdanjou.fr',
cacheTime: 720000,
gzip: true,
generate: false,
}

View File

@@ -0,0 +1,8 @@
export default {
cookie: {
prefix: 'arthurdanjou.fr/',
options: {
path: '/'
}
},
}

View File

@@ -1,4 +0,0 @@
// Global CSS: https://go.nuxtjs.dev/config-css
export default [
'@/assets/css/style.scss'
]

View File

@@ -0,0 +1,23 @@
export default {
scan: {
dirs: [ './' ],
exclude: [
'node_modules',
'.git',
'.nuxt/**/*',
'build/**/*',
'*.template.html',
'app.html'
],
include: []
},
transformCSS: 'pre',
preflight: {
alias: {
// add nuxt aliases
'nuxt-link': 'a',
// @nuxt/image module
'nuxt-img': 'img',
}
}
}

9
src/app.vue Normal file
View File

@@ -0,0 +1,9 @@
<template>
<main>
<NuxtPage />
</main>
</template>
<style>
@import '@/assets/css/style.scss';
</style>

View File

@@ -19,31 +19,21 @@
</section>
</template>
<script lang="ts">
import {defineComponent, useAsync, useContext} from "@nuxtjs/composition-api";
<script setup lang="ts">
import {useAsyncData, useNuxtApp} from "nuxt3";
export default defineComponent({
name: "AboutHome",
setup() {
const {$axios, $sentry, app} = useContext()
const age = useAsync(async () => {
const response = await $axios.get('/api/informations', {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (response.status === 200) {
return response.data.informations.age
} else {
$sentry.captureEvent(response.data)
app.error({statusCode: 500})
}
}, 'infos')
return {
age
const { $axios, $sentry, app } = useNuxtApp()
const age = useAsyncData('infos', async () => {
const response = await $axios.get('/api/informations', {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (response.status === 200) {
return response.data.informations.age
} else {
$sentry.captureEvent(response.data)
app.error({statusCode: 500})
}
})
</script>

View File

@@ -4,36 +4,23 @@
</div>
</template>
<script lang="ts">
import {computed, defineComponent} from "@nuxtjs/composition-api";
<script setup lang="ts">
import { computed } from 'vue'
interface AdProps {
color: string
}
export default defineComponent({
name: "Ad",
props: {
color: {
type: String,
default: 'red'
}
},
setup(props: AdProps) {
const getColor = computed(() => {
switch (props.color) {
case 'red':
return 'bg-red-400'
case 'blue':
return 'bg-blue-400'
case 'green':
return 'bg-green-400'
}
})
return {
getColor
}
const props = defineProps({
color: {
type: String,
default: 'red'
}
})
const getColor = computed(() => {
switch (props.color) {
case 'red':
return 'bg-red-400'
case 'blue':
return 'bg-blue-400'
case 'green':
return 'bg-green-400'
}
})
</script>

View File

@@ -16,48 +16,37 @@
</div>
</template>
<script lang="ts">
import {computed, defineComponent, useAsync, useContext} from "@nuxtjs/composition-api";
<script setup lang="ts">
import {useAsyncData, useNuxtApp} from "nuxt3";
import {computed} from "vue";
export default defineComponent({
name: "Announce",
setup() {
const {$axios, $sentry, app} = useContext()
const {$axios, $sentry, app} = useNuxtApp()
const announce = await useAsyncData('announce', async () => {
const response = await $axios.get('/api/announce', {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (response.status === 200) {
return response.data.announce
} else {
$sentry.captureEvent(response.data)
app.error({statusCode: 500})
}
})
const announce = useAsync(async () => {
const response = await $axios.get('/api/announce', {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (response.status === 200) {
return response.data.announce
} else {
$sentry.captureEvent(response.data)
app.error({statusCode: 500})
}
}, 'announce')
const getBackgroundColor = computed(() => {
switch (announce.data.value.color) {
case 'black': {
return 'bg-black text-white dark:(bg-white text-black)'
}
}
})
const getBackgroundColor = computed(() => {
switch (announce.value.color) {
case 'black': {
return 'bg-black text-white dark:(bg-white text-black)'
}
}
})
const getHoverColor = computed(() => {
switch (announce.value.hover_color) {
case 'gray': {
return 'hover:bg-gray-800 dark:hover:bg-gray-300'
}
}
})
return {
announce,
getBackgroundColor,
getHoverColor,
const getHoverColor = computed(() => {
switch (announce.data.value.hover_color) {
case 'gray': {
return 'hover:bg-gray-800 dark:hover:bg-gray-300'
}
}
})

View File

@@ -17,9 +17,8 @@
</section>
</template>
<script lang="ts">
import {defineComponent, onMounted, onUnmounted} from "@nuxtjs/composition-api";
<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue'
interface Color {
name: string,
color: string
@@ -31,27 +30,22 @@ const COLORS: Color[] = [
{ name: 'improve', color: 'green' }
]
export default defineComponent({
name: "Banner",
setup() {
let task
let task
onMounted(() => {
let CURRENT = 0
task = setInterval(() => {
const color = COLORS[CURRENT]
const new_color = COLORS[CURRENT === COLORS.length -1 ? 0 : CURRENT + 1]
document.getElementById(new_color.name)!.classList.toggle(new_color.color)
document.getElementById(new_color.name)!.classList.toggle('z-index-3')
setTimeout(() => document.getElementById(color.name)!.classList.toggle(color.color), 0)
setTimeout(() => document.getElementById(color.name)!.classList.toggle('z-index-3'), 0)
CURRENT === COLORS.length - 1 ? CURRENT = 0 : CURRENT++
}, 2000)
})
onUnmounted(() => clearInterval(task))
}
onMounted(() => {
let CURRENT = 0
task = setInterval(() => {
const color = COLORS[CURRENT]
const new_color = COLORS[CURRENT === COLORS.length -1 ? 0 : CURRENT + 1]
document.getElementById(new_color.name)!.classList.toggle(new_color.color)
document.getElementById(new_color.name)!.classList.toggle('z-index-3')
setTimeout(() => document.getElementById(color.name)!.classList.toggle(color.color), 0)
setTimeout(() => document.getElementById(color.name)!.classList.toggle('z-index-3'), 0)
CURRENT === COLORS.length - 1 ? CURRENT = 0 : CURRENT++
}, 2000)
})
onUnmounted(() => clearInterval(task))
</script>
<style scoped lang="scss">

View File

@@ -1,23 +1,21 @@
<template>
<nuxt-link data-blobity-radius="16" :to="link" class="z-index-3">
<nuxt-link data-blobity-radius="16" :to="props.link" class="z-index-3">
<div class="text-lg px-8 py-4 rounded-xl bg-white dark:bg-black border-2 border-red-500 dark:border-amber-400 text-red-500 dark:text-amber-400 duration-300">
{{ $t(content) }}
{{ $t(props.content) }}
</div>
</nuxt-link>
</template>
<script lang="ts">
export default {
name: "Button",
props: {
content: {
type: String,
default: 'Content'
},
link: {
type: String,
default: '/'
}
<script setup lang="ts">
const props = defineProps({
content: {
type: String,
default: 'Content'
},
link: {
type: String,
default: '/'
}
}
})
</script>

View File

@@ -73,63 +73,51 @@
</section>
</template>
<script lang="ts">
import {computed, defineComponent, ref, useContext} from "@nuxtjs/composition-api";
<script setup lang="ts">
import {ref, computed} from 'vue'
import {Form} from "~/types/types";
import {useNuxtApp} from "nuxt3";
export default defineComponent({
name: "ContactForm",
setup() {
const error = ref(false)
const success = ref(false)
const error = ref(false)
const success = ref(false)
const {$axios, $sentry} = useContext()
const form = ref<Form>({} as Form)
const handleForm = async () => {
const response = await $axios.post('/api/form',
{
email: form.value.email,
name: form.value.name,
content: form.value.content,
subject: form.value.subject
}, {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (response.status === 200) {
success.value = true
setTimeout(() => {
success.value = false
form.value = {} as Form
}, 5000)
} else {
$sentry.captureEvent(response.data)
error.value = true
setTimeout(() => {
error.value = false
}, 5000)
const {$axios, $sentry} = useNuxtApp()
const form = ref<Form>({} as Form)
const handleForm = async () => {
const response = await $axios.post('/api/form',
{
email: form.value.email,
name: form.value.name,
content: form.value.content,
subject: form.value.subject
}, {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
}
const isSendable = computed(() => {
const {email, name, content, subject} = form.value
return isNotEmpty(email) && isNotEmpty(name) && isNotEmpty(content) && isNotEmpty(subject)
})
const isNotEmpty = (object: string | undefined) => {
return object !== undefined && object.length > 0 && object !== "" && object !== ''
}
return {
error,
success,
isSendable,
form,
handleForm
}
if (response.status === 200) {
success.value = true
setTimeout(() => {
success.value = false
form.value = {} as Form
}, 5000)
} else {
$sentry.captureEvent(response.data)
error.value = true
setTimeout(() => {
error.value = false
}, 5000)
}
}
const isSendable = computed(() => {
const {email, name, content, subject} = form.value
return isNotEmpty(email) && isNotEmpty(name) && isNotEmpty(content) && isNotEmpty(subject)
})
const isNotEmpty = (object: string | undefined) => {
return object !== undefined && object.length > 0 && object !== "" && object !== ''
}
</script>
<style scoped lang="scss">

View File

@@ -1,28 +1,25 @@
<template>
<li>
{{ $t(title) }}:
{{ $t(props.title) }}:
<div class="z-index-3 inline">
<a data-blobity-magnetic="false" class="text-red-500 dark:text-amber-400 font-medium" v-if="link" :href="link" target="_blank">{{ content }}</a>
<span v-else>{{ content }}</span>
<a data-blobity-magnetic="false" class="text-red-500 dark:text-amber-400 font-medium" v-if="props.link" :href="props.link" target="_blank">{{ props.content }}</a>
<span v-else>{{ props.content }}</span>
</div>
</li>
</template>
<script>
export default {
name: "EnvListItem",
props:{
title: {
default: 'Title',
type: String
},
link: {
type: String
},
content: {
default: 'content',
type: String
},
}
}
<script setup lang="ts">
const props = defineProps({
title: {
default: 'Title',
type: String
},
link: {
type: String
},
content: {
default: 'content',
type: String
},
})
</script>

View File

@@ -19,8 +19,10 @@
</div>
</template>
<script lang="ts">
import {computed, defineComponent, useContext} from "@nuxtjs/composition-api";
<script setup lang="ts">
import {useNuxtApp} from "nuxt3";
import {computed} from "vue";
interface ExperienceProps {
title: string,
@@ -30,50 +32,40 @@ interface ExperienceProps {
end: string
}
export default defineComponent({
name: "Experience",
props: {
title: {
type: String,
default: "Title"
},
company: {
type: String,
default: "ArtDanjProduction"
},
location: {
type: String,
default: "France"
},
begin: {
type: String,
default: "Now"
},
end: {
type: String,
default: "Never"
}
const props = defineProps({
title: {
type: String,
default: "Title"
},
setup(props: ExperienceProps) {
const {i18n} = useContext()
const getBeginDate = computed(() => {
const dateFormat = props.begin.split('-')
return i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
})
const getEndDate = computed(() => {
const dateFormat = props.end.split('-')
return props.end === 'Today' ? i18n.t('date.today') : i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
})
const isSameDate = () => {
return props.begin === props.end
}
return {
getBeginDate,
getEndDate,
isSameDate
}
company: {
type: String,
default: "ArtDanjProduction"
},
location: {
type: String,
default: "France"
},
begin: {
type: String,
default: "Now"
},
end: {
type: String,
default: "Never"
}
})
const {i18n} = useNuxtApp()
const getBeginDate = computed(() => {
const dateFormat = props.begin.split('-')
return i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
})
const getEndDate = computed(() => {
const dateFormat = props.end.split('-')
return props.end === 'Today' ? i18n.t('date.today') : i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
})
const isSameDate = () => {
return props.begin === props.end
}
</script>

View File

@@ -15,33 +15,23 @@
</section>
</template>
<script lang="ts">
import {defineComponent, useAsync, useContext} from "@nuxtjs/composition-api";
<script setup lang="ts">
import {useAsyncData, useNuxtApp} from "nuxt3";
export default defineComponent({
name: "ExperiencesAbout",
setup() {
const {$axios, $sentry, app} = useContext()
const experiences = useAsync(async () => {
const response = await $axios.get('/api/experiences', {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (response.status === 200) {
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)
}
}, 'experiences')
return {
experiences
const {$axios, $sentry, app} = useNuxtApp()
const experiences = await useAsyncData('experiences', async () => {
const response = await $axios.get('/api/experiences', {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (response.status === 200) {
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)
}
})
</script>

View File

@@ -91,45 +91,34 @@
</footer>
</template>
<script lang="ts">
import {computed, defineComponent, ref, useAsync, useContext, useStore} from "@nuxtjs/composition-api";
import {State} from "~/types/types";
<script setup lang="ts">
import {useAsyncData, useNuxtApp} from "nuxt3";
import {computed, ref} from "vue";
export default defineComponent({
name: "Footer",
setup() {
const {$axios, $sentry, app} = useContext()
const {$axios, $sentry, app} = useNuxtApp()
const getDate = ref(new Date().getFullYear())
const getDate = ref(new Date().getFullYear())
const hiring_message = useAsync(async () => {
const request = await $axios.get('/api/informations', {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (request.status === 200) {
return request.data.informations.translation.code
} else {
app.error({statusCode: 500})
$sentry.captureEvent(request.data)
}
}, 'hiring_message')
const store = useStore<State>()
const route = computed(() => store.state.route)
const isWindow = (loc: string) => {
if (loc === '') return route.value === "/"
else return route.value.includes(loc)
}
return {
getDate,
hiring_message,
isWindow
const hiring_message = useAsyncData('hiring_message', async () => {
const request = await $axios.get('/api/informations', {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (request.status === 200) {
return request.data.informations.translation.code
} else {
app.error({statusCode: 500})
$sentry.captureEvent(request.data)
}
})
const { $store } = useNuxtApp()
const route = computed(() => $store.state.route)
const isWindow = (loc: string) => {
if (loc === '') return route.value === "/"
else return route.value.includes(loc)
}
</script>
<style scoped lang="scss">

View File

@@ -3,23 +3,24 @@
<div class="self-center flex h-3 w-3 mr-3 relative">
<span
class="relative inline h-3 w-3 rounded-full opacity-75"
:class="end === 'Today' ? 'animate-ping bg-red-500 dark:bg-amber-400' : 'bg-gray-400'"
:class="props.end === 'Today' ? 'animate-ping bg-red-500 dark:bg-amber-400' : 'bg-gray-400'"
/>
<span
class="inline absolute rounded-full h-3 w-3"
:class="end === 'Today' ? 'bg-red-500 dark:bg-amber-400' : 'bg-gray-500'"
:class="props.end === 'Today' ? 'bg-red-500 dark:bg-amber-400' : 'bg-gray-500'"
/>
</div>
<div class="leading-7">
<p class="text-base dark:text-dark-100 text-gray-800 leading-6">{{ getBeginDate }} - {{ getEndDate }} <span class="px-3">|</span> {{location}}</p>
<h1 class="text-2xl font-bold">{{ $t(title) }}</h1>
<h2 class="text-xl text-gray-700 dark:text-gray-400">{{ $t(description) }}</h2>
<p class="text-base dark:text-dark-100 text-gray-800 leading-6">{{ getBeginDate }} - {{ getEndDate }} <span class="px-3">|</span> {{props.location}}</p>
<h1 class="text-2xl font-bold">{{ $t(props.title) }}</h1>
<h2 class="text-xl text-gray-700 dark:text-gray-400">{{ $t(props.description) }}</h2>
</div>
</div>
</template>
<script lang="ts">
import {computed, defineComponent, useContext} from "@nuxtjs/composition-api";
<script setup lang="ts">
import {useNuxtApp} from "nuxt3";
import {computed} from "vue";
interface FormationProps {
title: string,
@@ -29,45 +30,36 @@ interface FormationProps {
end: string
}
export default defineComponent({
name: "Formation",
props: {
title: {
type: String,
default: "Title"
},
description: {
type: String,
default: "Description"
},
location: {
type: String,
default: "Location"
},
begin: {
type: String,
default: "Now"
},
end: {
type: String,
default: "Never"
}
const props = defineProps({
title: {
type: String,
default: "Title"
},
setup(props: FormationProps) {
const {i18n} = useContext()
const getBeginDate = computed(() => {
const dateFormat = props.begin.split('-')
return i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
})
const getEndDate = computed(() => {
const dateFormat = props.end.split('-')
return props.end === 'Today' ? i18n.t('date.today') : i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
})
return {
getBeginDate,
getEndDate
}
description: {
type: String,
default: "Description"
},
location: {
type: String,
default: "Location"
},
begin: {
type: String,
default: "Now"
},
end: {
type: String,
default: "Never"
}
})
const {i18n} = useNuxtApp()
const getBeginDate = computed(() => {
const dateFormat = props.begin.split('-')
return i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
})
const getEndDate = computed(() => {
const dateFormat = props.end.split('-')
return props.end === 'Today' ? i18n.t('date.today') : i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
})
</script>

View File

@@ -15,33 +15,24 @@
</section>
</template>
<script lang="ts">
import {defineComponent, useAsync, useContext} from "@nuxtjs/composition-api";
<script setup lang="ts">
import {useAsyncData, useNuxtApp} from "nuxt3";
export default defineComponent({
name: "FormationsHome",
setup() {
const {$axios, $sentry, app} = useContext()
const {$axios, $sentry, app} = useNuxtApp()
const formations = useAsync(async () => {
const response = await $axios.get('/api/formations', {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (response.status === 200) {
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)
}
}, 'formations')
return {
formations
const formations = await useAsyncData('formations', async () => {
const response = await $axios.get('/api/formations', {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (response.status === 200) {
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)
}
})
</script>

View File

@@ -49,51 +49,33 @@
</header>
</template>
<script lang="ts">
import {
computed,
defineComponent,
useAsync,
useContext,
useRouter,
useStore
} from "@nuxtjs/composition-api";
import {State} from "~/types/types";
<script setup lang="ts">
import {useNuxtApp, useRouter} from "nuxt3";
import {computed} from "vue";
export default defineComponent({
name: "Header",
setup() {
const {$colorMode} = useContext()
const changeColorMode = () => {
$colorMode.preference = $colorMode.value === 'light' ? 'dark' : 'light'
}
const {$colorMode} = useNuxtApp()
const changeColorMode = () => {
$colorMode.preference = $colorMode.value === 'light' ? 'dark' : 'light'
}
const {i18n, } = useContext()
const $router = useRouter()
const changeLanguage = () => useAsync(() => {
i18n.setLocale(i18n.locale === 'fr' ? 'en' : 'fr')
if ($router.currentRoute.fullPath.includes('blog')) {
window.location.reload()
}
})
const isFrench = computed(() => i18n.locale === 'fr')
const store = useStore<State>()
const route = computed(() => store.state.route)
const isWindow = (loc: string) => {
if (loc === '') return route.value === "/"
else return route.value.includes(loc)
}
return {
changeColorMode,
changeLanguage,
isWindow,
isFrench
}
const {i18n} = useNuxtApp()
const $router = useRouter()
const changeLanguage = () => useAsync(() => {
i18n.setLocale(i18n.locale === 'fr' ? 'en' : 'fr')
if ($router.currentRoute.fullPath.includes('blog')) {
window.location.reload()
}
})
}, 'language')
const isFrench = computed(() => i18n.locale === 'fr')
const { $store } = useNuxtApp()
const route = computed(() => $store.state.route)
const isWindow = (loc: string) => {
if (loc === '') return route.value === "/"
else return route.value.includes(loc)
}
</script>
<style scoped lang="scss">

View File

@@ -24,9 +24,9 @@
</div>
</template>
<script lang="ts">
import {computed, defineComponent, useRouter, useStore} from "@nuxtjs/composition-api";
import {State} from "~/types/types";
<script setup lang="ts">
import {useNuxtApp, useRouter} from "nuxt3";
import {computed} from "vue";
const PAGE_TYPE = {
projects: 1,
@@ -36,46 +36,36 @@ const PAGE_TYPE = {
newsletter: 5
}
export default defineComponent({
name: "MobileNavbar",
setup () {
const store = useStore<State>()
const route = computed(() => store.state.route)
const isWindow = (loc: string) => {
if (loc === '') return route.value === "/"
else return route.value.includes(loc)
}
const { $store } = useNuxtApp()
const route = computed(() => $store.state.route)
const isWindow = (loc: string) => {
if (loc === '') return route.value === "/"
else return route.value.includes(loc)
}
const getMenuIconType = computed(() => PAGE_TYPE[route.value.split('/')[1]] || 0)
const getMenuIconType = computed(() => PAGE_TYPE[route.value.split('/')[1]] || 0)
const toggleMenu = () => {
store.commit('TOGGLE_OPENED', !store.state.opened)
if (store.state.opened) {
document.getElementById('slider')!.style.maxHeight = window.innerHeight + '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'
}, 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'
}, 600)
})
return {
isWindow,
toggleMenu,
opened: computed(() => store.state.opened),
getMenuIconType
}
const toggleMenu = () => {
$store.commit('TOGGLE_OPENED', !$store.state.opened)
if ($store.state.opened) {
document.getElementById('slider')!.style.maxHeight = window.innerHeight + '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'
}, 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'
}, 600)
})
const opened = computed(() => $store.state.opened)
</script>

View File

@@ -4,88 +4,70 @@
data-blobity-magnetic="false"
data-blobity-offset-x="4"
data-blobity-offset-y="4"
:to="`/blog/${slug}`"
:to="`/blog/${props.slug}`"
>
<div class="group post w-full text-justify bg-white p-2 rounded-md dark:bg-black">
<h1 class="font-black text-3xl duration-300" :class="getHoverColor">{{ $t(title) }}</h1>
<h2 class="my-4 text-2xl text-gray-600 dark:text-gray-400">{{ $t(description) }}</h2>
<h1 class="font-black text-3xl duration-300" :class="getHoverColor">{{ $t(props.title) }}</h1>
<h2 class="my-4 text-2xl text-gray-600 dark:text-gray-400">{{ $t(props.description) }}</h2>
<div class="text-gray-700 dark:text-gray-300">
<span>{{ formatDate }}</span>, <span>{{ reading_time }}</span> min.
<span>{{ formatDate }}</span>, <span>{{ props.reading_time }}</span> min.
</div>
</div>
</nuxt-link>
</template>
<script lang="ts">
import {computed, defineComponent, useContext} from "@nuxtjs/composition-api";
<script setup lang="ts">
interface PostProps {
title: string,
description: string,
date: string,
cover: string,
slug: string,
tags: Array<string>,
reading_time: number,
color: string
}
import {useNuxtApp} from "nuxt3";
import {computed} from "vue";
export default defineComponent({
name: "Post",
props: {
title: {
type: String,
default: "Title"
},
description: {
type: String,
default: "Description"
},
date: {
type: String,
default: "Date"
},
slug: {
type: String,
default: "slug"
},
reading_time: {
type: Number,
default: 0
},
color: {
type: String,
default: 'blue'
}
const props = defineProps({
title: {
type: String,
default: "Title"
},
setup(props: PostProps) {
const { i18n } = useContext()
const formatDate = computed(() => {
const [first, second, third]: any = props.date.split('-')
return `${first} ${i18n.t(`month.${second}`)} ${third}`
})
description: {
type: String,
default: "Description"
},
date: {
type: String,
default: "Date"
},
slug: {
type: String,
default: "slug"
},
reading_time: {
type: Number,
default: 0
},
color: {
type: String,
default: 'blue'
}
})
const getHoverColor = computed(() => {
switch (props.color) {
case 'blue':
return 'group-hover:text-blue-400'
case 'red':
return 'group-hover:text-red-400'
case 'green':
return 'group-hover:text-green-400'
case 'yellow':
return 'group-hover:text-yellow-400'
case 'purple':
return 'group-hover:text-purple-400'
default:
return 'group-hover:text-blue-400'
}
})
const { i18n } = useNuxtApp()
const formatDate = computed(() => {
const [first, second, third]: any = props.date.split('-')
return `${first} ${i18n.t(`month.${second}`)} ${third}`
})
return {
formatDate,
getHoverColor
}
const getHoverColor = computed(() => {
switch (props.color) {
case 'blue':
return 'group-hover:text-blue-400'
case 'red':
return 'group-hover:text-red-400'
case 'green':
return 'group-hover:text-green-400'
case 'yellow':
return 'group-hover:text-yellow-400'
case 'purple':
return 'group-hover:text-purple-400'
default:
return 'group-hover:text-blue-400'
}
})
</script>

View File

@@ -28,31 +28,21 @@
</section>
</template>
<script lang="ts">
import {defineComponent, useAsync, useContext} from "@nuxtjs/composition-api";
<script setup lang="ts">
import {useAsyncData, useNuxtApp} from "nuxt3";
export default defineComponent({
name: "PostsHome",
setup() {
const { $axios, app, $sentry } = useContext()
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
const { $axios, app, $sentry } = useNuxtApp()
const posts = await useAsyncData('posts_home', 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)
}
})
</script>

View File

@@ -1,56 +1,51 @@
<template>
<a
data-blobity-magnetic="false"
:href="url"
:href="props.url"
target="_blank"
rel="noreferrer noopener"
class="z-index-3"
>
<div class="h-full rounded-lg w-full bg-gray-100 dark:bg-gray-800">
<div class="max-w-full rounded-t-lg border-l-2 border-r-2 border-t-2 border-transparent dark:border-gray-900">
<img class="w-full rounded-t-lg" :src="`https://athena.arthurdanjou.fr/files/${cover}`" alt="Project Cover" />
<img class="w-full rounded-t-lg" :src="`https://athena.arthurdanjou.fr/files/${props.cover}`" alt="Project Cover" />
</div>
<div class="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">
<div v-for="tag in props.tags">
<Tag :content="tag.label.code" :pill="false"/>
</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">{{ $t(description) }}</p>
<h1 class="text-2xl font-bold">{{ props.title }}</h1>
<p class="text-base mt-3 text-gray-700 dark:text-gray-400 text-justify">{{ $t(props.description) }}</p>
</div>
</div>
</div>
</a>
</template>
<script lang="ts">
import {defineComponent} from "@nuxtjs/composition-api";
export default defineComponent({
name: "Project",
props: {
title: {
type: String,
default: "Title"
},
cover: {
type: String,
default: "athena.png"
},
description: {
type: String,
default: "Description"
},
tags: {
type: Array,
default: () => ['tags.web', 'tags.software']
},
url: {
type: String,
default: 'https://arthurdanjou.fr'
}
<script setup lang="ts">
const props = defineProps({
title: {
type: String,
default: "Title"
},
cover: {
type: String,
default: "athena.png"
},
description: {
type: String,
default: "Description"
},
tags: {
type: Array,
default: () => ['tags.web', 'tags.software']
},
url: {
type: String,
default: 'https://arthurdanjou.fr'
}
})
</script>

View File

@@ -27,31 +27,21 @@
</section>
</template>
<script lang="ts">
import {defineComponent, useAsync, useContext} from "@nuxtjs/composition-api";
<script setup lang="ts">
import {useAsyncData, useNuxtApp} from "nuxt3";
export default defineComponent({
name: "ProjectsHome",
setup() {
const { $axios, app, $sentry } = useContext()
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
const { $axios, app, $sentry } = useNuxtApp()
const projects = await useAsyncData('projects_home', 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})
}
})
</script>

View File

@@ -13,35 +13,25 @@
</transition>
</template>
<script lang="ts">
import {defineComponent, onMounted, onUnmounted, ref, useRouter} from "@nuxtjs/composition-api";
<script setup lang="ts">
import {onMounted, onUnmounted, ref} from "vue";
export default defineComponent({
name: "Scroller",
setup() {
const scrollPosition = ref(0)
const scrollPosition = ref(0)
const scrollToTop = () => {
window.scrollTo({top: 0, behavior: 'smooth'});
}
const scrollToTop = () => {
window.scrollTo({top: 0, behavior: 'smooth'});
}
const updateScroll = () => {
scrollPosition.value = window.scrollY
}
const updateScroll = () => {
scrollPosition.value = window.scrollY
}
onMounted(() => {
window.addEventListener('scroll', updateScroll);
})
onMounted(() => {
window.addEventListener('scroll', updateScroll);
})
onUnmounted(() => {
window.removeEventListener('scroll', updateScroll)
})
return {
scrollPosition,
scrollToTop
}
}
onUnmounted(() => {
window.removeEventListener('scroll', updateScroll)
})
</script>

View File

@@ -5,21 +5,18 @@
</div>
<div class="sm:mt-8">
<h1 class="font-bold tracking-wider text-3xl mb-4">
{{ $t(title) }}
{{ $t(props.title) }}
</h1>
<slot name="content"/>
</div>
</div>
</template>
<script>
export default {
name: "ServicePart",
props: {
title: {
type: String,
default: 'services.1.title'
}
<script setup lang="ts">
const props = defineProps({
title: {
type: String,
default: 'services.1.title'
}
}
})
</script>

View File

@@ -83,54 +83,42 @@
</div>
</template>
<script lang="ts">
import {computed, defineComponent, useAsync, useContext, useRouter, useStore} from "@nuxtjs/composition-api";
import {State} from "~/types/types";
<script setup lang="ts">
import {useNuxtApp, useRouter} from "nuxt3";
import {computed} from "vue";
export default defineComponent({
name: "SideMenu",
setup() {
const {$colorMode} = useContext()
const changeColorMode = () => {
$colorMode.preference = $colorMode.value === 'light' ? 'dark' : 'light'
}
const {$colorMode} = useNuxtApp()
const changeColorMode = () => {
$colorMode.preference = $colorMode.value === 'light' ? 'dark' : 'light'
}
const {i18n} = useContext()
const $router = useRouter()
const changeLanguage = () => useAsync(() => {
i18n.setLocale(i18n.locale === 'fr' ? 'en' : 'fr')
if ($router.currentRoute.fullPath.includes('blog')) {
window.location.reload()
}
})
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'
}, 500)
}
const route = computed(() => store.state.route)
const isWindow = (loc: string) => {
if (loc === '') return route.value === "/"
else return route.value.includes(loc)
}
return {
changeColorMode,
changeLanguage,
closeMenu,
opened: computed(() => store.state.opened),
isWindow,
isFrench
}
const {i18n} = useNuxtApp()
const $router = useRouter()
const changeLanguage = () => useAsync(() => {
i18n.setLocale(i18n.locale === 'fr' ? 'en' : 'fr')
if ($router.currentRoute.fullPath.includes('blog')) {
window.location.reload()
}
})
const isFrench = computed(() => i18n.locale === 'fr')
const { $store } = useNuxtApp()
const closeMenu = () => {
$store.commit('TOGGLE_OPENED', false)
document.getElementById('nav')!.classList.remove('z-50')
setTimeout(() => {
document.getElementById('slider')!.style.maxHeight = 'none'
}, 500)
}
const opened = computed(() => $store.state.opened)
const route = computed(() => $store.state.route)
const isWindow = (loc: string) => {
if (loc === '') return route.value === "/"
else return route.value.includes(loc)
}
</script>
<style scoped lang="scss">

View File

@@ -1,77 +1,63 @@
<template>
<div
:id="name.toLowerCase()"
:id="props.name.toLowerCase()"
class="p-1 flex items-center group group"
>
<img
class="rounded-sm h-8 mr-2"
:alt="`Skill ${name} Image`"
:src="`https://athena.arthurdanjou.fr/files/${cover}`"
:alt="`Skill ${props.name} Image`"
:src="`https://athena.arthurdanjou.fr/files/${props.cover}`"
/>
<h1 :class="getColor" class="duration-300 md:font-lg font-md font-bold text-center text-gray-700 dark:text-gray-400">{{ name }}</h1>
<h1 :class="getColor" class="duration-300 md:font-lg font-md font-bold text-center text-gray-700 dark:text-gray-400">{{ props.name }}</h1>
</div>
</template>
<script lang="ts">
import {computed, defineComponent} from '@nuxtjs/composition-api'
<script setup lang="ts">
import {computed} from "vue";
interface SkillProps {
name: string,
color: string,
cover: string
}
export default defineComponent({
name: "Skill",
props: {
name: {
type: String,
default: "Rien"
},
color: {
type: String,
default: "red"
},
cover: {
type: String,
default: "logo.jpg"
}
const props = defineProps({
name: {
type: String,
default: "Rien"
},
setup(props: SkillProps) {
const getColor = computed(() => {
switch (props.color) {
case 'blueGray':
return 'group-hover:text-blueGray-400'
case 'cyan':
return 'group-hover:text-cyan-400'
case 'yellow':
return 'group-hover:text-yellow-400'
case 'emerald':
return 'group-hover:text-emerald-400'
case 'purple':
return 'group-hover:text-purple-400'
case 'orange':
return 'group-hover:text-orange-700'
case 'sky':
return 'group-hover:text-sky-400'
case 'lime':
return 'group-hover:text-lime-400'
case 'teal':
return 'group-hover:text-teal-400'
case 'blue':
return 'group-hover:text-blue-400'
case 'red':
return 'group-hover:text-red-400'
case 'rose':
return 'group-hover:text-rose-400'
case 'amber':
return 'group-hover:text-amber-400'
}
})
color: {
type: String,
default: "red"
},
cover: {
type: String,
default: "logo.jpg"
}
})
return {
getColor
}
const getColor = computed(() => {
switch (props.color) {
case 'blueGray':
return 'group-hover:text-blueGray-400'
case 'cyan':
return 'group-hover:text-cyan-400'
case 'yellow':
return 'group-hover:text-yellow-400'
case 'emerald':
return 'group-hover:text-emerald-400'
case 'purple':
return 'group-hover:text-purple-400'
case 'orange':
return 'group-hover:text-orange-700'
case 'sky':
return 'group-hover:text-sky-400'
case 'lime':
return 'group-hover:text-lime-400'
case 'teal':
return 'group-hover:text-teal-400'
case 'blue':
return 'group-hover:text-blue-400'
case 'red':
return 'group-hover:text-red-400'
case 'rose':
return 'group-hover:text-rose-400'
case 'amber':
return 'group-hover:text-amber-400'
}
})
</script>

View File

@@ -16,31 +16,21 @@
</section>
</template>
<script lang="ts">
import {defineComponent, useAsync, useContext} from "@nuxtjs/composition-api";
<script setup lang="ts">
import {useAsyncData, useNuxtApp} from "nuxt3";
export default defineComponent({
name: "SkillsAbout",
setup() {
const {$axios, $sentry, app} = useContext()
const skills = useAsync(async () => {
const response = await $axios.get('/api/skills', {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (response.status === 200) {
return response.data.skills
} else {
app.error({statusCode: 500})
$sentry.captureEvent(response.data)
}
}, 'skills')
return {
skills
const {$axios, $sentry, app} = useNuxtApp()
const skills = await useAsyncData('skills', async () => {
const response = await $axios.get('/api/skills', {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (response.status === 200) {
return response.data.skills
} else {
app.error({statusCode: 500})
$sentry.captureEvent(response.data)
}
})
</script>

View File

@@ -1,26 +1,21 @@
<template>
<div
class="px-2 py-0.5 rounded-full bg-gray-200 text-sm text-gray-800 dark:(bg-gray-700 text-gray-300)"
:class="pill === true ? 'px-2 py-0.5 rounded-full' : 'px-2 py-1 rounded-md'"
:class="props.pill === true ? 'px-2 py-0.5 rounded-full' : 'px-2 py-1 rounded-md'"
>
{{ $t(content) }}
{{ $t(props.content) }}
</div>
</template>
<script lang="ts">
import {defineComponent} from "@nuxtjs/composition-api";
export default defineComponent({
name: "TagPreview",
props: {
content: {
type: String,
default: "Content"
},
pill: {
type: Boolean,
default: true
}
<script setup lang="ts">
const props = defineProps({
content: {
type: String,
default: "Content"
},
pill: {
type: Boolean,
default: true
}
})
</script>

View File

@@ -8,7 +8,7 @@
</template>
<script lang="ts">
import {computed, defineComponent, useContext} from "@nuxtjs/composition-api";
import {computed, defineComponent, useContext} from "@nuxt/bridge/dist/runtime/capi.legacy";
export default defineComponent({
name: "GithubIcon",

View File

@@ -8,7 +8,7 @@
</template>
<script lang="ts">
import {computed, defineComponent, useContext} from "@nuxtjs/composition-api";
import {computed, defineComponent, useContext} from "@nuxt/bridge/dist/runtime/capi.legacy";
export default defineComponent({
name: "GithubIcon",

View File

@@ -8,7 +8,7 @@
</template>
<script lang="ts">
import {computed, defineComponent, useContext} from "@nuxtjs/composition-api";
import {computed, defineComponent, useContext} from "@nuxt/bridge/dist/runtime/capi.legacy";
export default defineComponent({
name: "GithubIcon",

View File

@@ -16,7 +16,7 @@
</template>
<script lang="ts">
import {computed, defineComponent, useContext} from "@nuxtjs/composition-api";
import {computed, defineComponent, useContext} from "@nuxt/bridge/dist/runtime/capi.legacy";
export default defineComponent({
name: "TwitterIcon",

View File

@@ -8,7 +8,7 @@
</template>
<script lang="ts">
import {computed, defineComponent, useContext} from "@nuxtjs/composition-api";
import {computed, defineComponent, useContext} from "@nuxt/bridge/dist/runtime/capi.legacy";
export default defineComponent({
name: "TwitterIcon",

View File

@@ -25,13 +25,12 @@
</template>
<script lang="ts">
import {computed, useRouter, useStore} from "@nuxtjs/composition-api";
import {State} from "~/types/types";
import {computed, useRouter, useStore} from "@nuxt/bridge/dist/runtime/capi.legacy";
import {options, useBlobity} from "@/plugins/Blobity";
export default {
setup() {
const store = useStore<State>()
const store = useStore()
const $router = useRouter()
$router.afterEach(() => {

View File

@@ -39,7 +39,7 @@
</template>
<script lang="ts">
import {defineComponent, useRouter} from "@nuxtjs/composition-api";
import {defineComponent, useRouter} from "@nuxt/bridge/dist/runtime/capi.legacy";
export default defineComponent({
name: "error",

View File

@@ -28,7 +28,7 @@
</template>
<script lang="ts">
import {defineComponent, useAsync, useContext} from "@nuxtjs/composition-api";
import {defineComponent, useAsync, useContext} from "@nuxt/bridge/dist/runtime/capi.legacy";
export default defineComponent({
name: "blog",

View File

@@ -51,7 +51,7 @@
</template>
<script lang="ts">
import {computed, defineComponent, useAsync, useContext} from "@nuxtjs/composition-api";
import {computed, defineComponent, useAsync, useContext} from "@nuxt/bridge/dist/runtime/capi.legacy";
export default defineComponent({
name: "maintenance",

View File

@@ -51,7 +51,7 @@
</template>
<script lang="ts">
import {defineComponent, ref, useAsync, useContext} from "@nuxtjs/composition-api";
import {defineComponent, ref, useAsync, useContext} from "@nuxt/bridge/dist/runtime/capi.legacy";
import {NewsletterForm} from "~/types/types";
export default defineComponent({

View File

@@ -21,7 +21,7 @@
</template>
<script lang="ts">
import {defineComponent, useAsync, useContext} from "@nuxtjs/composition-api";
import {defineComponent, useAsync, useContext} from "@nuxt/bridge/dist/runtime/capi.legacy";
export default defineComponent({
name: "index",

View File

@@ -1,6 +1,6 @@
import Blobity from "blobity";
import {Options} from "blobity/lib/Blobity";
import {onMounted, ref} from "@nuxtjs/composition-api";
import {onMounted, ref} from "@nuxt/bridge/dist/runtime/capi.legacy";
export const options: Partial<Options> = {
color: 'rgb(125, 125, 125)',

View File

@@ -1,4 +1,5 @@
{
"extends": "./.nuxt/tsconfig.json",
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
@@ -58,11 +59,9 @@
// "typeRoots": [], /* List of folders to include type definitions from. */
"types": [
"@types/node",
"@nuxt/content",
"@nuxt/types",
"@nuxtjs/axios",
"@nuxtjs/sentry",
"@nuxtjs/composition-api",
"@nuxtjs/i18n",
"@nuxtjs/color-mode",
"@nuxtjs/universal-storage"

8491
yarn.lock

File diff suppressed because it is too large Load Diff