mirror of
https://github.com/ArthurDanjou/website-old.git
synced 2026-01-14 20:19:35 +01:00
Add new mobile menu
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
"nuxt-i18n": "^6.27.1",
|
||||
"prism-themes": "^1.7.0",
|
||||
"sass": "^1.35.1",
|
||||
"vuex": "^3.6.2",
|
||||
"windicss": "^3.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -31,7 +32,7 @@
|
||||
"@nuxt/typescript-build": "^2.1.0",
|
||||
"@nuxtjs/color-mode": "^2.0.10",
|
||||
"markdown-it-prism": "^2.1.6",
|
||||
"sass-loader": "10.1.1",
|
||||
"nuxt-windicss": "^1.1.1"
|
||||
"nuxt-windicss": "^1.1.1",
|
||||
"sass-loader": "10.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
BIN
src/assets/images/photo-rounded.png
Normal file
BIN
src/assets/images/photo-rounded.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 125 KiB |
@@ -1,23 +1,37 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="announce"
|
||||
class="h-16 bg-black text-center"
|
||||
class="h-12 flex justify-center items-center"
|
||||
:class="[getBackgroundColor, getHoverColor]"
|
||||
>
|
||||
{{ announce }}
|
||||
{{ announce.translation.code }}
|
||||
<img
|
||||
v-if="announce.file"
|
||||
:src="`https://athena.arthurdanjou.fr/files/${announce.file}`"
|
||||
alt="Announce Cover File"
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {ref, useAsync, useContext} from "@nuxtjs/composition-api";
|
||||
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
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "Announcement",
|
||||
setup() {
|
||||
const {$axios, $sentry} = useContext()
|
||||
const announce = ref("")
|
||||
const announce = ref<Announce>()
|
||||
|
||||
useAsync(async () => {
|
||||
const response = await $axios.get('/api/announce', {
|
||||
const response = await $axios.get('/api/announces', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.API_TOKEN}`
|
||||
}
|
||||
@@ -29,8 +43,26 @@ export default {
|
||||
}
|
||||
})
|
||||
|
||||
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!.color) {
|
||||
case 'gray': {
|
||||
return 'hover:bg-gray-600'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
announce
|
||||
announce,
|
||||
getBackgroundColor,
|
||||
getHoverColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<header class="dark:bg-black dark:text-white fixed z-50 top-0 left-0 bg-white w-full duration-400"
|
||||
:class="scrollPosition > 50 ? ' shadow-md dark:shadow-white h-16 lg:h-20' : 'h-20 lg:h-24'">
|
||||
<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'">
|
||||
<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"/>
|
||||
@@ -21,37 +21,6 @@
|
||||
</nuxt-link>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="w-full z-50 fixed bottom-0 left-0 md:hidden">
|
||||
<ul
|
||||
class="bg-gray-300 dark:bg-gray-700 m-4 rounded-xl 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('')"/>
|
||||
</li>
|
||||
</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>
|
||||
<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>
|
||||
<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>
|
||||
<nuxt-link to="/contact" class="w-1/5">
|
||||
<li class="font-medium flex flex-col items-center justify-center">
|
||||
<ContactIcon :active="isWindow('/contact')"/>
|
||||
</li>
|
||||
</nuxt-link>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<ul class="flex items-center">
|
||||
<li @click="changeLanguage()"
|
||||
@@ -75,14 +44,13 @@
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
computed,
|
||||
defineComponent,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
ref,
|
||||
useAsync,
|
||||
useContext,
|
||||
useRouter, watch
|
||||
useRouter
|
||||
} from "@nuxtjs/composition-api";
|
||||
|
||||
export default defineComponent({
|
||||
@@ -115,17 +83,11 @@ export default defineComponent({
|
||||
}
|
||||
})
|
||||
|
||||
const isWindow = (loc: string) => {
|
||||
if (loc === '') return $router.currentRoute.path === "/"
|
||||
else return $router.currentRoute.path.includes(loc)
|
||||
}
|
||||
|
||||
return {
|
||||
scrollPosition,
|
||||
changeColorMode,
|
||||
updateScroll,
|
||||
changeLanguage,
|
||||
isWindow
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
87
src/components/MobileNavbar.vue
Normal file
87
src/components/MobileNavbar.vue
Normal file
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<div
|
||||
class="w-full z-100 fixed bottom-0 left-0 md:hidden duration-500"
|
||||
:class="{'opened': isOpened}"
|
||||
>
|
||||
<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>
|
||||
</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>
|
||||
<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>
|
||||
<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>
|
||||
<li @click='toggleMenu' class="w-1/5 flex flex-col items-center justify-center cursor-pointer">
|
||||
<MenuIcon :type="getMenuIconType"/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {computed, defineComponent, useRouter, useStore} from "@nuxtjs/composition-api";
|
||||
import {State} from "~/types/types";
|
||||
|
||||
const PAGE_TYPE = {
|
||||
projects: 1,
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
const store = useStore<State>()
|
||||
const toggleMenu = () => {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
})
|
||||
store.commit('TOGGLE_OPENED', !store.state.opened)
|
||||
}
|
||||
|
||||
$router.afterEach(() => {
|
||||
store.commit('TOGGLE_OPENED', false)
|
||||
})
|
||||
|
||||
const isOpened = computed(() => store.state.opened)
|
||||
|
||||
return {
|
||||
isWindow,
|
||||
toggleMenu,
|
||||
isOpened,
|
||||
getMenuIconType,
|
||||
debug
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.opened {
|
||||
@apply transform translate-x-9/12 scale-90 -translate-y-10 duration-500;
|
||||
}
|
||||
</style>
|
||||
170
src/components/SideMenu.vue
Normal file
170
src/components/SideMenu.vue
Normal file
@@ -0,0 +1,170 @@
|
||||
<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="mb-8">
|
||||
<div class="flex justify-between mb-4">
|
||||
<div @click="closeMenu" class="flex justify-center items-center cursor-pointer cross text-sm">
|
||||
<CrossIcon class="duration-300" />
|
||||
<div class="ml-4">{{ $t('sidebar.close') }}</div>
|
||||
</div>
|
||||
<div class="ml-6">
|
||||
<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/>
|
||||
</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>
|
||||
<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>
|
||||
</div>
|
||||
<div class="w-auto flex">
|
||||
<div class="flex flex-col ml-4 mb-8 space-y-1.5 font-bold text-lg">
|
||||
<div class="nav-link" :class="{ 'link-active': isWindow('') }">
|
||||
<nuxt-link to="/">
|
||||
{{ $t('header.home') }}
|
||||
</nuxt-link>
|
||||
</div>
|
||||
<div class="nav-link" :class="{ 'link-active': isWindow('') }">
|
||||
<nuxt-link to="/about">
|
||||
{{ $t('header.about') }}
|
||||
</nuxt-link>
|
||||
</div>
|
||||
<div class="nav-link" :class="{ 'link-active': isWindow('blog') }">
|
||||
<nuxt-link to="/blog">
|
||||
{{ $t('header.blog') }}
|
||||
</nuxt-link>
|
||||
</div>
|
||||
<div class="nav-link" :class="{ 'link-active': isWindow('projects') }">
|
||||
<nuxt-link to="/projects">
|
||||
{{ $t('header.projects') }}
|
||||
</nuxt-link>
|
||||
</div>
|
||||
<div class="nav-link" :class="{ 'link-active': isWindow('services') }">
|
||||
<nuxt-link to="/services">
|
||||
{{ $t('header.services') }}
|
||||
</nuxt-link>
|
||||
</div>
|
||||
<div class="nav-link" :class="{ 'link-active': isWindow('env') }">
|
||||
<nuxt-link to="/env">
|
||||
{{ $t('header.env') }}
|
||||
</nuxt-link>
|
||||
</div>
|
||||
<div class="nav-link" :class="{ 'link-active': isWindow('guestbook') }">
|
||||
<nuxt-link to="/guestbook">
|
||||
{{ $t('header.guestbook') }}
|
||||
</nuxt-link>
|
||||
</div>
|
||||
<div class="nav-link" :class="{ 'link-active': isWindow('contact') }">
|
||||
<nuxt-link to="/contact">
|
||||
{{ $t('header.contact') }}
|
||||
</nuxt-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="social-links flex justify-between space-x-1">
|
||||
<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>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent, useAsync, useContext, useRouter, useStore} from "@nuxtjs/composition-api";
|
||||
import {State} from "~/types/types";
|
||||
|
||||
export default defineComponent({
|
||||
name: "SideMenu",
|
||||
setup() {
|
||||
const {$colorMode} = useContext()
|
||||
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') || $router.currentRoute.fullPath === '/') {
|
||||
window.location.reload()
|
||||
}
|
||||
})
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
return {
|
||||
isWindow,
|
||||
changeColorMode,
|
||||
changeLanguage,
|
||||
closeMenu
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.cross:hover svg {
|
||||
@apply transform scale-140;
|
||||
}
|
||||
|
||||
.profile:hover img {
|
||||
@apply transform rotate-360;
|
||||
}
|
||||
|
||||
.nav-link a, .link-active a {
|
||||
@apply duration-300 border-b-2 border-transparent;
|
||||
|
||||
&:hover {
|
||||
@apply border-indigo-600;
|
||||
}
|
||||
}
|
||||
|
||||
.social-links a {
|
||||
svg {
|
||||
@apply h-8 w-8 duration-300
|
||||
}
|
||||
|
||||
&:hover svg {
|
||||
@apply transform hover:scale-120
|
||||
}
|
||||
}
|
||||
</style>
|
||||
18
src/components/icons/CrossIcon.vue
Normal file
18
src/components/icons/CrossIcon.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<svg class="inline" width="1.5em" height="1.5em" viewBox="0 0 15 15" focusable="false">
|
||||
<g fill="none">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M11.782 4.032a.575.575 0 1 0-.813-.814L7.5 6.687L4.032 3.218a.575.575 0 0 0-.814.814L6.687 7.5l-3.469 3.468a.575.575 0 0 0 .814.814L7.5 8.313l3.469 3.469a.575.575 0 0 0 .813-.814L8.313 7.5l3.469-3.468z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "CrossIcon"
|
||||
}
|
||||
</script>
|
||||
13
src/components/icons/DiscordIcon.vue
Normal file
13
src/components/icons/DiscordIcon.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<svg class="inline" width="1.5em" height="1.5em" viewBox="0 0 24 24" focusable="false">
|
||||
<path
|
||||
d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0a12.64 12.64 0 0 0-.617-1.25a.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106a13.107 13.107 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10.2 10.2 0 0 0 .372-.292a.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127a12.299 12.299 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028a19.839 19.839 0 0 0 6.002-3.03a.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418z"
|
||||
fill="currentColor" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "DiscordIcon"
|
||||
}
|
||||
</script>
|
||||
32
src/components/icons/MenuIcon.vue
Normal file
32
src/components/icons/MenuIcon.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<div>
|
||||
<svg v-if="type === 0" class="inline" width="2.5em" height="2.5em" viewBox="0 0 24 24" focusable="false">
|
||||
<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/"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg v-else-if="type === 1" class="inline" width="2.5em" height="2.5em" viewBox="0 0 48 48" focusable="false">
|
||||
<g fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path
|
||||
clip-rule="evenodd"
|
||||
d="M44 22c0-9.941-8.954-18-20-18S4 12.059 4 22h40z" />
|
||||
<path d="M4 38h40v6H4z" />
|
||||
<path d="M4 28l5.455 4l7.272-4L24 32l7.273-4l7.272 4L44 28" />
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MenuIcon",
|
||||
props: {
|
||||
type: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
13
src/components/icons/PolyworkIcon.vue
Normal file
13
src/components/icons/PolyworkIcon.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<svg class="inline" width="1.5em" height="1.5em" viewBox="0 0 24 24" focusable="false">
|
||||
<path
|
||||
d="M19.125 0H4.875A4.865 4.865 0 0 0 0 4.875v14.25C0 21.825 2.175 24 4.875 24h6.6c2.7 0 4.875-2.175 4.875-4.875V16.65h2.775c2.7 0 4.875-2.175 4.875-4.875v-6.9C24 2.175 21.825 0 19.125 0zM16.5 1.275h2.625a3.6 3.6 0 0 1 3.6 3.6v2.7H16.5v-6.3zM15.075 9v6.45H8.85V9h6.225zM8.85 1.2h6.225v6.375H8.85V1.2zM1.275 4.8a3.6 3.6 0 0 1 3.6-3.6H7.5v6.375H1.275V4.8zM7.5 9v6.45H1.2V9h6.3zm0 13.725H4.8a3.6 3.6 0 0 1-3.6-3.6V16.8h6.3v5.925zm7.575-3.525a3.6 3.6 0 0 1-3.6 3.6H8.85v-5.925h6.225V19.2zm7.65-7.35a3.6 3.6 0 0 1-3.6 3.6H16.5V9h6.225v2.85z"
|
||||
fill="currentColor" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "PolyworkIcon"
|
||||
}
|
||||
</script>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<svg class="inline" width="1em" height="1em" viewBox="0 0 24 24" focusable="false">
|
||||
<svg class="inline" width="1.5em" height="1.5em" 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"
|
||||
|
||||
@@ -1,7 +1,52 @@
|
||||
<template>
|
||||
<div>
|
||||
<Header />
|
||||
<Nuxt class="z-10 pt-16 lg:pt-24 content"/>
|
||||
<Footer />
|
||||
<SideMenu />
|
||||
<div
|
||||
class="z-50 relative top-0 left-0 w-full duration-500 h-1/2"
|
||||
:class="{'opened': opened}"
|
||||
:style="`max-height: ${height}px`"
|
||||
>
|
||||
<div @click="closeMenu" class="z-50 bg-white dark:bg-black overflow-hidden overflow-x-hidden w-full min-w-screen" :class="{'cursor-pointer': opened}">
|
||||
<Announcement />
|
||||
<Header />
|
||||
<Nuxt class="z-10 pt-16 lg:pt-24 content"/>
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
<MobileNavbar />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {computed, onMounted, ref, useStore} from "@nuxtjs/composition-api";
|
||||
import {State} from "~/types/types";
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const store = useStore<State>()
|
||||
|
||||
const opened = computed(() => store.state.opened)
|
||||
|
||||
const closeMenu = () => {
|
||||
store.commit('TOGGLE_OPENED', false)
|
||||
}
|
||||
|
||||
const height = ref(0)
|
||||
onMounted(() => {
|
||||
height.value = window.innerHeight
|
||||
})
|
||||
|
||||
return {
|
||||
opened,
|
||||
closeMenu,
|
||||
height
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.opened {
|
||||
@apply rounded-lg overflow-hidden overflow-x-hidden transform scale-90 translate-x-9/12 transition-all duration-500;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
export default {
|
||||
header: {
|
||||
home: 'Home',
|
||||
about: 'About',
|
||||
blog: 'Blog',
|
||||
contact: 'Contact',
|
||||
projects: 'Projects',
|
||||
env: 'Tools',
|
||||
guestbook: 'Guestbook',
|
||||
newsletter: 'Newsletter'
|
||||
newsletter: 'Newsletter',
|
||||
services: 'Services'
|
||||
},
|
||||
|
||||
sidebar: {
|
||||
close: 'Close the menu'
|
||||
},
|
||||
|
||||
part: {
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
export default {
|
||||
header: {
|
||||
home: 'Accueil',
|
||||
about: 'A Propos',
|
||||
blog: 'Blog',
|
||||
contact: 'Contact',
|
||||
projects: 'Projets',
|
||||
env: 'Outils',
|
||||
guestbook: "Livre d'or",
|
||||
newsletter: 'Newsletter'
|
||||
newsletter: 'Newsletter',
|
||||
services: 'Services'
|
||||
},
|
||||
|
||||
sidebar: {
|
||||
close: 'Fermer le menu'
|
||||
},
|
||||
|
||||
part: {
|
||||
|
||||
15
src/store/index.ts
Executable file → Normal file
15
src/store/index.ts
Executable file → Normal file
@@ -0,0 +1,15 @@
|
||||
import {GetterTree, MutationTree} from "vuex";
|
||||
|
||||
export const state = () => ({
|
||||
opened: false
|
||||
})
|
||||
|
||||
export type RootState = ReturnType<typeof state>
|
||||
|
||||
export const getters: GetterTree<RootState, RootState> = {
|
||||
opened: state => state.opened,
|
||||
}
|
||||
|
||||
export const mutations: MutationTree<RootState> = {
|
||||
TOGGLE_OPENED: (state, opened: boolean) => (state.opened = opened),
|
||||
}
|
||||
|
||||
1
types/index.d.ts
vendored
1
types/index.d.ts
vendored
@@ -3,6 +3,7 @@ import VueI18n, {IVueI18n} from "vue-i18n";
|
||||
import {ColorModeInstance} from "@nuxtjs/color-mode/types/color-mode";
|
||||
import {NuxtApp} from "@nuxt/types/app";
|
||||
import {NuxtStorage} from "@nuxtjs/universal-storage";
|
||||
import {NuxtOptionsRouter} from "@nuxt/types/config/router";
|
||||
|
||||
declare module 'vue/types/vue' {
|
||||
|
||||
|
||||
@@ -69,4 +69,14 @@ interface NewsletterForm {
|
||||
email: string
|
||||
}
|
||||
|
||||
export { Form, InfoData, Skill, Experience, Formation, Post, Tag, Project, GuestbookForm, NewsletterForm }
|
||||
interface Translation {
|
||||
code: string,
|
||||
english: string,
|
||||
french: string
|
||||
}
|
||||
|
||||
interface State {
|
||||
opened: boolean
|
||||
}
|
||||
|
||||
export { Form, InfoData, Skill, Experience, Formation, Post, Tag, Project, GuestbookForm, NewsletterForm, Translation, State }
|
||||
|
||||
Reference in New Issue
Block a user