Working hardly

This commit is contained in:
2021-08-17 15:32:55 +02:00
parent e8484f98d5
commit adb052d1de
33 changed files with 988 additions and 767 deletions

View File

@@ -33,7 +33,7 @@ export default defineComponent({
.catch((error) => {
$sentry.captureEvent(error)
});
})
}, 'infos')
return {
info

View File

@@ -37,6 +37,6 @@
<script lang="ts">
export default {
name: "AdPreview"
name: "AdHome"
}
</script>

View File

@@ -1,28 +1,24 @@
<template>
<div
v-if="announce"
class="h-12 flex justify-center items-center"
:class="[getBackgroundColor, getHoverColor]"
class="p-4 duration-300 flex justify-center items-center text-center"
:class="[getHoverColor, getBackgroundColor]"
>
{{ announce.translation.code }}
{{ $t(announce.message.code) }}
<img
v-if="announce.file"
:src="`https://athena.arthurdanjou.fr/files/${announce.file}`"
alt="Announce Cover File"
>
</div>
<div v-else class="p-4 duration-300 flex justify-center items-center text-center bg-black dark:bg-white text-white dark:text-black">
{{ $t('loading') }}
</div>
</template>
<script lang="ts">
import {computed, ref, useAsync, useContext} from "@nuxtjs/composition-api";
import {Translation} from "~/types/types";
interface Announce {
color: string,
hover_color: string,
translation: Translation
file: null
}
import {Announce} from "~/types/types";
export default {
name: "Announcement",
@@ -52,9 +48,9 @@ export default {
})
const getHoverColor = computed(() => {
switch (announce.value!.color) {
switch (announce.value!.hover_color) {
case 'gray': {
return 'hover:bg-gray-600'
return 'hover:bg-gray-800 dark:hover:bg-gray-300'
}
}
})
@@ -62,7 +58,7 @@ export default {
return {
announce,
getBackgroundColor,
getHoverColor
getHoverColor,
}
}
}

View File

@@ -84,7 +84,7 @@ export default defineComponent({
const {$axios, $sentry} = useContext()
const form = ref<Form>({} as Form)
const handleForm = async () => {
const response = await $axios.post('form',
const response = await $axios.post('/api/form',
{
email: form.value.email,
name: form.value.name,

View File

@@ -1,70 +1,150 @@
<template>
<footer class="footer w-full border-t-2 border-solid border-gray-200 px-4 xl:px-32 dark:border-gray-800 mb-26 md:mb-0">
<div class="flex flex-col-reverse md:flex-row justify-between pt-4 items-center">
<div class="inline flex space-x-4">
<a class="link font-semibold" href="https://twitch.com/ArthurDanjou" target="_blank" rel="noopener noreferrer">
<TwitchIcon /> <span>Twitch</span>,
</a>
<a class="link font-semibold" href="https://github.com/ArthurDanjou" target="_blank" rel="noopener noreferrer">
<GithubIcon /> <span>Github</span>,
</a>
<a class="link font-semibold" href="https://twitter.com/ArthurDanj" target="_blank" rel="noopener noreferrer">
<TwitterIcon /> <span>Twitter</span>,
</a>
<a class="link font-semibold" href="mailto:contact@arthurdanjou.fr" target="_blank" rel="noopener noreferrer">
<MailIcon /> <span>Mail</span>
</a>
<footer class="footer w-full mt-20">
<div class="p-8 pb-0">
<div class="lg:flex justify-evenly">
<div class="lg:w-1/3">
<div class="flex">
<Logo />
</div>
<div class="my-8">
<p class="text-justify">
{{ $t('footer.description') }}
</p>
<div class="mt-4">
<nuxt-link to="/contact" class="text-red-400 border-b-2 border-gray-200 dark:border-gray-700 hover:border-red-400 duration-300">
{{ $t(hiring_message) }}
</nuxt-link>
</div>
</div>
<div class="social-links flex space-x-4 mb-8">
<a target="_blank" href="https://twitter.com/ArthurDanj" rel="noopener noreferrer">
<TwitterIcon />
</a>
<a target="_blank" href="https://github.com/ArthurDanjou" rel="noopener noreferrer">
<GithubIcon />
</a>
<a target="_blank" href="https://www.polywork.com/arthurdanjou" rel="noopener noreferrer">
<PolyworkIcon />
</a>
<a target="_blank" href="https://www.twitch.tv/arthurdanjou" rel="noopener noreferrer">
<TwitchIcon />
</a>
<a target="_blank" href="https://discord.gg/RQhjE5UkxD" rel="noopener noreferrer">
<DiscordIcon />
</a>
<a target="_blank" href="mailto:contact@arthurdanjou.fr" rel="noopener noreferrer">
<MailIcon />
</a>
</div>
</div>
<div class="lg:ml-32 lg:w-1/3">
<h1 class="font-bold mb-4 text-lg underline">
{{ $t('footer.links') }}
</h1>
<div class="flex flex-col mb-8 space-y-2 lg:space-y-4 font-medium">
<div class="link">
<nuxt-link to="/">
{{ $t('header.home') }}
</nuxt-link>
</div>
<div class="link">
<nuxt-link to="/about">
{{ $t('header.about') }}
</nuxt-link>
</div>
<div class="link">
<nuxt-link to="/blog">
{{ $t('header.blog') }}
</nuxt-link>
</div>
<div class="link">
<nuxt-link to="/projects">
{{ $t('header.projects') }}
</nuxt-link>
</div>
<div class="link">
<nuxt-link to="/services">
{{ $t('header.services') }}
</nuxt-link>
</div>
<div class="link">
<nuxt-link to="/env">
{{ $t('header.env') }}
</nuxt-link>
</div>
<div class="link">
<nuxt-link to="/guestbook">
{{ $t('header.guestbook') }}
</nuxt-link>
</div>
<div class="link">
<nuxt-link to="/newsletter">
{{ $t('header.newsletter') }}
</nuxt-link>
</div>
<div class="link">
<nuxt-link to="/contact">
{{ $t('header.contact') }}
</nuxt-link>
</div>
</div>
</div>
</div>
<div class="flex space-x-4 mb-4 md:mb-0">
<nuxt-link class="link font-semibold" to="/env">
<span>{{ $t('header.env') }}</span>,
</nuxt-link>
<nuxt-link class="link font-semibold" to="/guestbook">
<span>{{ $t('header.guestbook') }}</span>,
</nuxt-link>
<nuxt-link class="link font-semibold" to="/contact">
<span>{{ $t('header.contact') }}</span>,
</nuxt-link>
<nuxt-link class="link font-semibold" to="/newsletter">
<span>{{ $t('header.newsletter') }}</span>
</nuxt-link>
<div class="text-center border-t-2 border-gray-200 dark:border-gray-800 py-8 lg:flex lg:flex-row-reverse justify-between">
<div>
{{ $t('footer.credits') }}
<a class="social font-semibold" target="_blank" href="https://nuxtjs.org" rel="noopener noreferrer">
<NuxtIcon />
<span>NuxtJS</span>
</a>
{{ $t('footer.credits_separator') }}
<a class="social font-semibold" target="_blank" href="https://adonisjs.com" rel="noopener noreferrer">
<AdonisIcon />
<span>AdonisJS</span>
</a>
</div>
<p class="mt-4 lg:mt-0">{{ $t('footer.copyrights', { date: getDate }) }}</p>
</div>
</div>
<div class="text-center my-4">
<p>
{{ $t('footer.credits') }}
<a class="link font-semibold" target="_blank" href="https://nuxtjs.org" rel="noopener noreferrer">
<NuxtIcon />
<span>NuxtJS</span>
</a>
{{ $t('footer.credits_separator_and') }}
<a class="link font-semibold" target="_blank" href="https://adonisjs.com" rel="noopener noreferrer">
<AdonisIcon />
<span>AdonisJS</span>
</a>
{{ $t('footer.credits_separator') }} <span>Arthur DANJOU</span>
</p>
<p>{{ $t('footer.copyrights', { date: getDate }) }}</p>
</div>
</footer>
</template>
<script lang="ts">
import {computed, defineComponent, ref, useContext} from "@nuxtjs/composition-api";
import {computed, defineComponent, ref, useAsync, useContext, useRouter, useStore} from "@nuxtjs/composition-api";
import {State} from "~/types/types";
export default defineComponent({
name: "Footer",
setup() {
const {$colorMode} = useContext()
const {$colorMode, $axios, $sentry, app} = useContext()
const isDarkMode = computed(() => {
return $colorMode.preference === 'dark'
})
const getDate = ref(new Date().getFullYear())
const hiring_message = ref("")
useAsync(async () => {
const request = await $axios.get('/api/informations', {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (request.status === 200) {
hiring_message.value = request.data.informations.translation.code
} else {
app.error({statusCode: 500})
$sentry.captureEvent(request.data)
}
})
const store = useStore<State>()
const route = computed(() => store.state.route)
return {
getDate,
isDarkMode
isDarkMode,
hiring_message
}
}
})
@@ -72,7 +152,7 @@ export default defineComponent({
<style scoped lang="scss">
.footer {
.link {
.social {
span {
@apply border-b-2 border-gray-200 dark:border-gray-700 duration-300;
}
@@ -80,5 +160,14 @@ export default defineComponent({
@apply border-indigo-600
}
}
.link {
a {
@apply border-b-2 border-transparent duration-300;
&:hover {
@apply border-indigo-600;
}
}
}
}
</style>

View File

@@ -98,7 +98,7 @@ export default defineComponent({
const alreadySent = ref(false)
const hasAlreadySignMessage = async (id: number) => {
const response = await $axios.get(`/guestbook/${id}`, {
const response = await $axios.get(`/api/guestbook/${id}`, {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}

View File

@@ -49,7 +49,7 @@ export default defineComponent({
const month = realMonth.toString().length == 2 ? realMonth.toString() : `0${realMonth.toString()}`
const minutes = date.getMinutes().toString().length == 2 ? date.getMinutes() : `0${date.getMinutes()}`
const hours = date.getHours().toString().length == 2 ? date.getHours() : `0${date.getHours()}`
return `${date.getDate()} ${i18n.t(`month.${month}`)} ${date.getFullYear()} at ${hours}:${minutes}`
return `${date.getDate()} ${i18n.t(`month.${month}`)} ${date.getFullYear()} ${i18n.t('guestbook.at')} ${hours}:${minutes}`
})
return {

View File

@@ -1,22 +1,20 @@
<template>
<header class="hidden md:block dark:bg-black dark:text-white sticky z-50 top-0 left-0 bg-white w-full duration-400"
:class="scrollPosition > 65 ? ' shadow-md dark:shadow-white h-16 lg:h-20' : 'h-20 lg:h-24'">
<header class="hidden xl:block dark:bg-black dark:text-white z-50 sticky top-0 left-0 bg-white w-full duration-400"
:class="scrollPosition > 65 ? 'shadow-md dark:shadow-white h-16 lg:h-20' : 'h-20 lg:h-24'">
<div class="header-container z-index-50 flex justify-between items-center h-full px-5 xl:px-32">
<nuxt-link to="/">
<img src="~/assets/images/logo-header.png" alt="Logo Circle" class="h-10 left cursor-pointer duration-500"/>
</nuxt-link>
<Logo />
<nav class="right flex flex-col md:flex-row items-center hidden md:inline-block">
<div class="flex text-lg">
<nuxt-link class="nav-link" to="/about">
<nuxt-link class="nav-link" to="/about" :class="{ 'link-active': isWindow('about') }">
{{ $t('header.about') }}
</nuxt-link>
<nuxt-link class="nav-link" to="/blog">
<nuxt-link class="nav-link" to="/blog" :class="{ 'link-active': isWindow('blog') }">
{{ $t('header.blog') }}
</nuxt-link>
<nuxt-link class="nav-link" to="/projects">
<nuxt-link class="nav-link" to="/projects" :class="{ 'link-active': isWindow('projects') }">
{{ $t('header.projects') }}
</nuxt-link>
<nuxt-link class="nav-link" to="/contact">
<nuxt-link class="nav-link" to="/contact" :class="{ 'link-active': isWindow('contact') }">
{{ $t('header.contact') }}
</nuxt-link>
</div>
@@ -44,14 +42,17 @@
<script lang="ts">
import {
computed,
defineComponent,
onMounted,
onUnmounted,
ref,
useAsync,
useContext,
useRouter
useRouter,
useStore
} from "@nuxtjs/composition-api";
import {State} from "~/types/types";
export default defineComponent({
name: "Header",
@@ -83,11 +84,20 @@ export default defineComponent({
}
})
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 {
scrollPosition,
changeColorMode,
updateScroll,
changeLanguage,
isWindow
}
}
})
@@ -95,10 +105,14 @@ export default defineComponent({
<style scoped lang="scss">
.nav-link {
@apply font-medium cursor-pointer duration-300 mx-4 border-b-2 border-transparent hover:(border-indigo-600);
@apply font-medium cursor-pointer duration-500 mx-4 border-b-2 border-transparent hover:(border-indigo-600);
}
.navbar-bottom-items li {
transition: all .2s ease-in-out;
}
.link-active {
@apply text-indigo-600
}
</style>

18
src/components/Logo.vue Normal file
View File

@@ -0,0 +1,18 @@
<template>
<nuxt-link class="profile ml-4 flex items-center" to="/">
<img class="h-12 w-12 duration-500" src="@/assets/images/photo-rounded.png" alt="Photo of me" />
<h1 class="ml-4 font-bold text-lg">Arthur Danjou</h1>
</nuxt-link>
</template>
<script>
export default {
name: "Logo"
}
</script>
<style lang="scss">
.profile:hover img {
@apply transform rotate-360;
}
</style>

View File

@@ -1,41 +1,31 @@
<template>
<div
class="w-full z-100 fixed bottom-0 left-0 md:hidden duration-500"
:class="{'opened': isOpened}"
class="xl:hidden fixed z-50 top-auto bottom-0 w-full md:w-2/3 md:left-1/2 p-4 transition-all duration-500 transform md:-translate-x-1/2"
:class="{'-translate-y-8 translate-x-9/12 sm:translate-x-1/2 xl:translate-x-0': opened}"
>
<ul
class="bg-gray-200 dark:bg-gray-800 m-4 rounded-3xl dark:text-white text-sm flex items-center justify-around h-20 navbar-bottom-items"
>
<nuxt-link to="/" class="w-1/5">
<li class="h-full w-full font-medium flex flex-col items-center justify-center">
<HomeIcon :active="isWindow('')"/>
{{ debug }}
</li>
<nav class="flex justify-evenly py-4 bg-gray-200 dark:bg-gray-700 rounded-3xl dark:text-white text-sm overflow-hidden">
<nuxt-link to="/" class="relative font-medium">
<HomeIcon :active="isWindow('')"/>
</nuxt-link>
<nuxt-link to="/about" class="w-1/5">
<li class="font-medium flex flex-col items-center justify-center">
<UserIcon :active="isWindow('/about')"/>
</li>
<nuxt-link to="/about" class="relative font-medium">
<UserIcon :active="isWindow('/about')"/>
</nuxt-link>
<nuxt-link to="/blog" class="w-1/5">
<li class="font-medium flex flex-col items-center justify-center">
<BookIcon :active="isWindow('/blog')"/>
</li>
<nuxt-link to="/blog" class="relative font-medium">
<BookIcon :active="isWindow('/blog')"/>
</nuxt-link>
<nuxt-link to="/projects" class="w-1/5">
<li class="font-medium flex flex-col items-center justify-center">
<LightbulbIcon :active="isWindow('/projects')"/>
</li>
<nuxt-link to="/projects" class="relative font-medium">
<LightbulbIcon :active="isWindow('/projects')"/>
</nuxt-link>
<li @click='toggleMenu' class="w-1/5 flex flex-col items-center justify-center cursor-pointer">
<MenuIcon :type="getMenuIconType"/>
</li>
</ul>
<button @click.prevent='toggleMenu' class="font-medium cursor-pointer">
<CrossIcon v-if="opened" />
<MenuIcon v-else :type="getMenuIconType"/>
</button>
</nav>
</div>
</template>
<script lang="ts">
import {computed, defineComponent, useRouter, useStore} from "@nuxtjs/composition-api";
import {computed, defineComponent, ref, useRouter, useStore, watch} from "@nuxtjs/composition-api";
import {State} from "~/types/types";
const PAGE_TYPE = {
@@ -44,44 +34,43 @@ const PAGE_TYPE = {
export default defineComponent({
name: "MobileNavbar",
setup() {
const $router = useRouter()
const debug = computed(() => $router.currentRoute.path)
const isWindow = (loc: string) => {
if (loc === '') return $router.currentRoute.path === "/"
else return $router.currentRoute.path.includes(loc)
}
const getMenuIconType = computed(() => PAGE_TYPE[$router.currentRoute.path.split('/')[1]] || 0)
setup () {
const store = useStore<State>()
const toggleMenu = () => {
window.scrollTo({
top: 0,
})
store.commit('TOGGLE_OPENED', !store.state.opened)
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 toggleMenu = () => {
store.commit('TOGGLE_OPENED', !store.state.opened)
if (store.state.opened) {
setTimeout(() => document.getElementById('nav')!.classList.add('z-50'), 300)
} else {
document.getElementById('nav')!.classList.remove('z-50')
setTimeout(() => {
document.getElementById('slider')!.style.maxHeight = 'none'
}, 100)
}
}
const $router = useRouter()
$router.afterEach(() => {
store.commit('TOGGLE_OPENED', false)
document.getElementById('nav')!.classList.remove('z-50')
setTimeout(() => {
document.getElementById('slider')!.style.maxHeight = 'none'
}, 100)
})
const isOpened = computed(() => store.state.opened)
return {
isWindow,
toggleMenu,
isOpened,
getMenuIconType,
debug
opened: computed(() => store.state.opened),
getMenuIconType
}
}
})
</script>
<style scoped lang="scss">
.opened {
@apply transform translate-x-9/12 scale-90 -translate-y-10 duration-500;
}
</style>

View File

@@ -1,5 +1,5 @@
<template>
<nuxt-link :to="`/blog/${slug}`" rel="noreferrer noopener">
<nuxt-link :to="`/blog/${slug}`">
<div class="rounded-lg dark:shadow-white shadow-xl h-116 w-full lg:w-100 text-left bg-gray-100 dark:bg-gray-800 transform hover:scale-103 duration-300 mb-8 lg:mb-0">
<div class="h-2/5 post rounded-t-lg"
:style="{ backgroundImage: `url(${getCover})` }">

View File

@@ -1,5 +1,5 @@
<template>
<a :href="url" target="_blank" rel="noopener noreferrer">
<a :href="url" target="_blank">
<div class="rounded-lg dark:shadow-white shadow-xl h-92 w-full lg:w-84 text-left bg-gray-100 dark:bg-gray-800 transform hover:scale-103 duration-300 mb-8 lg:mb-0">
<div class="h-1/2 w-full h-2/5 project rounded-t-lg"
:style="{ backgroundImage: `url(${getCover})` }">

View File

@@ -10,7 +10,7 @@
</p>
</div>
<div class="my-8 lg:flex w-full lg:space-x-8 flex flex-wrap justify-center">
<div v-for="project in projects">
<div v-for="project in projects" class="mb-4">
<Project
:title="project.title"
:cover="project.cover"

View File

@@ -1,7 +1,12 @@
<template>
<div class="md:hidden w-full min-w-screen">
<div class="bg-gray-100 dark:bg-gray-900 min-h-screen duration-500 absolute top-0 left-0 right-0 py-4 pr-20 pl-4 flex items-center">
<nav class="w-auto">
<div class="relative w-full min-w-screen xl:overflow-auto">
<div
class="min-h-screen bg-gray-100 dark:bg-gray-900 xl:hidden pl-4 pr-20 py-4 transition-all duration-500 duration-500 absolute top-0 left-0 right-0 flex items-center"
>
<nav
id="nav"
class="w-auto"
>
<div class="mb-8">
<div class="flex justify-between mb-4">
<div @click="closeMenu" class="flex justify-center items-center cursor-pointer cross text-sm">
@@ -26,10 +31,7 @@
</ul>
</div>
</div>
<nuxt-link class="profile ml-4 flex items-center" to="/">
<img class="h-12 w-12 duration-500" src="@/assets/images/photo-rounded.png" alt="Photo of me" />
<h1 class="ml-4 font-bold text-lg">Arthur Danjou</h1>
</nuxt-link>
<Logo />
</div>
<div class="w-auto flex">
<div class="flex flex-col ml-4 mb-8 space-y-1.5 font-bold text-lg">
@@ -38,7 +40,7 @@
{{ $t('header.home') }}
</nuxt-link>
</div>
<div class="nav-link" :class="{ 'link-active': isWindow('') }">
<div class="nav-link" :class="{ 'link-active': isWindow('about') }">
<nuxt-link to="/about">
{{ $t('header.about') }}
</nuxt-link>
@@ -68,6 +70,11 @@
{{ $t('header.guestbook') }}
</nuxt-link>
</div>
<div class="nav-link" :class="{ 'link-active': isWindow('newsletter') }">
<nuxt-link to="/newsletter">
{{ $t('header.newsletter') }}
</nuxt-link>
</div>
<div class="nav-link" :class="{ 'link-active': isWindow('contact') }">
<nuxt-link to="/contact">
{{ $t('header.contact') }}
@@ -75,7 +82,7 @@
</div>
</div>
</div>
<div class="social-links flex justify-between space-x-1">
<div class="social-links flex justify-between space-x-0.5">
<a target="_blank" href="https://twitter.com/ArthurDanj" rel="noopener noreferrer">
<TwitterIcon />
</a>
@@ -101,7 +108,14 @@
</template>
<script lang="ts">
import {defineComponent, useAsync, useContext, useRouter, useStore} from "@nuxtjs/composition-api";
import {
computed,
defineComponent,
useAsync,
useContext,
useRouter,
useStore
} from "@nuxtjs/composition-api";
import {State} from "~/types/types";
export default defineComponent({
@@ -121,21 +135,27 @@ export default defineComponent({
}
})
const isWindow = (loc: string) => {
if (loc === '') return $router.currentRoute.path === "/"
else return $router.currentRoute.path.includes(loc)
}
const store = useStore<State>()
const closeMenu = () => {
store.commit('TOGGLE_OPENED', false)
document.getElementById('nav')!.classList.remove('z-50')
setTimeout(() => {
document.getElementById('slider')!.style.maxHeight = 'none'
}, 100)
}
const route = computed(() => store.state.route)
const isWindow = (loc: string) => {
if (loc === '') return route.value === "/"
else return route.value.includes(loc)
}
return {
isWindow,
changeColorMode,
changeLanguage,
closeMenu
closeMenu,
opened: computed(() => store.state.opened),
isWindow
}
}
})
@@ -146,11 +166,7 @@ export default defineComponent({
@apply transform scale-140;
}
.profile:hover img {
@apply transform rotate-360;
}
.nav-link a, .link-active a {
.nav-link a {
@apply duration-300 border-b-2 border-transparent;
&:hover {
@@ -158,9 +174,13 @@ export default defineComponent({
}
}
.link-active a {
@apply text-indigo-600;
}
.social-links a {
svg {
@apply h-8 w-8 duration-300
@apply h-6 w-6 duration-300
}
&:hover svg {

View File

@@ -4,7 +4,7 @@
<g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 12h18"/>
<path d="M3 6h18"/>
<path d="M3 18h18/"/>
<path d="M3 18h18"/>
</g>
</svg>
<svg v-else-if="type === 1" class="inline" width="2.5em" height="2.5em" viewBox="0 0 48 48" focusable="false">