mirror of
https://github.com/ArthurDanjou/website-old.git
synced 2026-01-20 23:11:43 +01:00
💻 | Working so hard on the design review
This commit is contained in:
43
src/components/AboutPreview.vue
Normal file
43
src/components/AboutPreview.vue
Normal file
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<section v-if="info && info.age" class="w-full flex items-center justify-center my-12">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="w-1/2 flex justify-center">
|
||||
<img src="@/assets/images/Logo.jpg" alt="Logo Image" class="w-1/2 rounded-2xl border-2 border-gray-100 dark:border-transparent">
|
||||
</div>
|
||||
<div class="w-1/2 text-justify">
|
||||
<h2 class="text-4xl font-bold">
|
||||
Who am I ?
|
||||
</h2>
|
||||
<p class="text-xl my-6 text-gray-700 dark:text-gray-400">
|
||||
{{ $t('home.banner.description', {age: info.age}) }}
|
||||
</p>
|
||||
<div class="flex">
|
||||
<Button content="Decouvrir mon profil" link="about"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {useAsync, useContext} from "@nuxtjs/composition-api";
|
||||
import {InfoData} from "../../@types/types";
|
||||
|
||||
export default {
|
||||
name: "AboutPreview",
|
||||
setup() {
|
||||
const {$content} = useContext()
|
||||
const info = useAsync(() => {
|
||||
return $content('infos').fetch<InfoData>()
|
||||
})
|
||||
|
||||
return {
|
||||
info
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
41
src/components/Ad.vue
Normal file
41
src/components/Ad.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="rounded-3xl p-12 text-center shadow-md" :class="getColor">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {computed} from "@nuxtjs/composition-api";
|
||||
|
||||
interface AdProps {
|
||||
color: string
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "Ad",
|
||||
props: {
|
||||
color: {
|
||||
type: String,
|
||||
default: 'red'
|
||||
}
|
||||
},
|
||||
setup(props: AdProps) {
|
||||
const getColor = computed(() => {
|
||||
switch (props.color) {
|
||||
case 'red':
|
||||
return 'bg-red-300'
|
||||
case 'blue':
|
||||
return 'bg-blue-300'
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
getColor
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
46
src/components/AdPreview.vue
Normal file
46
src/components/AdPreview.vue
Normal file
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div class="w-full my-12">
|
||||
<div class="space-x-12 flex items-center justify-center">
|
||||
<nuxt-link to="/uses" class="h-84 w-1/2">
|
||||
<Ad class="h-full w-full flex flex-col justify-between">
|
||||
<div>
|
||||
ILLUSTRATION
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="font-bold text-black text-3xl">
|
||||
Usages
|
||||
</h1>
|
||||
<p class="text-lg text-gray-700 mt-4">
|
||||
Venez decouvrir mon environnement de developpement
|
||||
</p>
|
||||
</div>
|
||||
</Ad>
|
||||
</nuxt-link>
|
||||
<nuxt-link to="/contact" class="h-84 w-1/2">
|
||||
<Ad color="blue" class="h-full w-full flex flex-col justify-between">
|
||||
<div>
|
||||
ILLUSTRATION
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="font-bold text-black text-4xl">
|
||||
Vous avez un projet ?
|
||||
</h1>
|
||||
<p class="text-lg text-gray-700 mt-4">
|
||||
Contactez moi en detaillant votre projet pour debuter notre collaboration.
|
||||
</p>
|
||||
</div>
|
||||
</Ad>
|
||||
</nuxt-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "AdPreview"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
29
src/components/Banner.vue
Normal file
29
src/components/Banner.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<section class="my-32 w-full flex items-center justify-center">
|
||||
<div class="text-center">
|
||||
<h1 class="text-6xl font-bold text-gray-700 dark:text-gray-400">
|
||||
Hello I am <span class="text-black dark:text-white">Arthur Danjou</span>
|
||||
</h1>
|
||||
<h3 class="my-6 text-2xl font-medium text-gray-700 dark:text-gray-400">
|
||||
Developer and Student
|
||||
</h3>
|
||||
<p class="text-lg text-gray-800 mb-10 dark:text-gray-300">You can follow me on <span class="link">Twitter</span>,
|
||||
<span class="link">Twitch</span>
|
||||
and <span class="link">Github</span>.
|
||||
Here is my <nuxt-link to="/contact" class="link">Contact</nuxt-link> page.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "Banner"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.link {
|
||||
@apply font-medium cursor-pointer border-b-2 border-gray-200 text-teal-400 hover:border-teal-400 duration-200 dark:(font-white border-gray-700) hover:dark:border-teal-400
|
||||
}
|
||||
</style>
|
||||
27
src/components/Button.vue
Normal file
27
src/components/Button.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<nuxt-link :to="link">
|
||||
<div class="text-lg cursor-pointer px-8 py-4 rounded-xl border-2 border-gray-600 hover:(bg-gray-700 text-white) text-gray-700 duration-300 dark:(border-gray-400 text-gray-400) dark:hover:bg-gray-400 dark:hover:text-black">
|
||||
{{ content }}
|
||||
</div>
|
||||
</nuxt-link>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "Button",
|
||||
props: {
|
||||
content: {
|
||||
type: String,
|
||||
default: 'Content'
|
||||
},
|
||||
link: {
|
||||
type: String,
|
||||
default: '/'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -51,14 +51,14 @@ export default {
|
||||
}
|
||||
},
|
||||
setup(props: ExperienceProps) {
|
||||
const {$i18n} = useContext()
|
||||
const {i18n} = useContext()
|
||||
const getBeginDate = computed(() => {
|
||||
const dateFormat = props.begin.split('-')
|
||||
return $i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
|
||||
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 props.end === 'Today' ? i18n.t('date.today') : i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
|
||||
})
|
||||
|
||||
const isSameDate = () => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<footer class="footer w-full border-t-2 border-solid border-black dark:border-white mb-20 md:mb-0">
|
||||
<footer class="footer w-full border-t-2 border-solid border-gray-200 dark:border-gray-800 mb-20 md:mb-0">
|
||||
<div>
|
||||
<div class="flex flex-col items-center py-4 text-center ">
|
||||
<div class="mb-3">
|
||||
@@ -67,7 +67,7 @@ export default {
|
||||
}
|
||||
|
||||
.link {
|
||||
@apply duration-300;
|
||||
@apply duration-100;
|
||||
|
||||
&:hover {
|
||||
@apply border-b-2 border-opacity-0 dark:border-opacity-0 dark:hover:border-opacity-100 hover:border-opacity-100 border-black dark:border-white border-solid;
|
||||
|
||||
@@ -50,18 +50,14 @@ export default {
|
||||
}
|
||||
},
|
||||
setup(props: FormationProps) {
|
||||
const {$i18n} = useContext()
|
||||
const {i18n} = useContext()
|
||||
const getBeginDate = computed(() => {
|
||||
const dateFormat = props.begin.split('-')
|
||||
console.log('1')
|
||||
console.log($i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1])
|
||||
return $i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
|
||||
return i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
|
||||
})
|
||||
const getEndDate = computed(() => {
|
||||
const dateFormat = props.end.split('-')
|
||||
console.log('2')
|
||||
console.log(props.end === 'Today' ? $i18n.t('date.today') : $i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1])
|
||||
return props.end === 'Today' ? $i18n.t('date.today') : $i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
|
||||
return props.end === 'Today' ? i18n.t('date.today') : i18n.t('month.' + dateFormat[0]) + " " + dateFormat[1]
|
||||
})
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<header class="dark:bg-black dark:text-white fixed z-50 top-0 left-0 bg-white header w-full h-16 lg:h-24 duration-500" :class="scrollPosition > 50 ? ' shadow-md dark:shadow-white' : ''">
|
||||
<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-10 lg:h-18' : 'h-16 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" />
|
||||
@@ -80,11 +80,11 @@
|
||||
</nav>
|
||||
<div>
|
||||
<ul class="flex items-center">
|
||||
<li 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-850">
|
||||
<div v-if="this.$i18n.locale === 'en'" @click="changeLanguage('fr')">
|
||||
:fr:
|
||||
<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-850">
|
||||
<div v-if="this.$i18n.locale === 'en'">
|
||||
Fr
|
||||
</div>
|
||||
<div v-else @click="changeLanguage('en')">
|
||||
<div v-else>
|
||||
🇬🇧
|
||||
</div>
|
||||
</li>
|
||||
@@ -114,7 +114,6 @@ export default {
|
||||
setup() {
|
||||
const {$colorMode} = useContext()
|
||||
const changeColorMode = () => {
|
||||
console.log("changed !")
|
||||
$colorMode.preference = $colorMode.value === 'light' ? 'dark' : 'light'
|
||||
}
|
||||
|
||||
@@ -131,13 +130,12 @@ export default {
|
||||
window.removeEventListener('scroll', updateScroll)
|
||||
})
|
||||
|
||||
const {app, $i18n} = useContext()
|
||||
const {i18n} = useContext()
|
||||
const $router = useRouter()
|
||||
const changeLanguage = (lang: 'fr' | 'en') => useAsync(() => {
|
||||
console.log("i18n changed")
|
||||
$i18n.setLocale(lang)
|
||||
if ($router.currentRoute.fullPath.includes('blog')) {
|
||||
app.refresh()
|
||||
const changeLanguage = () => useAsync(() => {
|
||||
i18n.setLocale(i18n.locale === 'fr' ? 'en' : 'fr')
|
||||
if ($router.currentRoute.fullPath.includes('blog') || $router.currentRoute.fullPath === '/') {
|
||||
window.location.reload()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -152,25 +150,19 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.header {
|
||||
.nav-link {
|
||||
@apply text-gray-500 dark:text-gray-400 hover:dark:text-white font-medium hover:text-black mx-4 cursor-pointer duration-300
|
||||
}
|
||||
|
||||
.header-container {
|
||||
.nav-link-mobile {
|
||||
@apply text-gray-500 dark:text-gray-400 hover:dark:text-white hover:text-black duration-300
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
@apply text-gray-500 dark:text-gray-400 hover:dark:text-white font-medium hover:text-black mx-4 cursor-pointer duration-300
|
||||
}
|
||||
nav .nuxt-link-exact-active {
|
||||
@apply text-black dark:text-white;
|
||||
}
|
||||
|
||||
.nav-link-mobile {
|
||||
@apply text-gray-500 dark:text-gray-400 hover:dark:text-white hover:text-black duration-300
|
||||
}
|
||||
|
||||
nav .nuxt-link-exact-active {
|
||||
@apply text-black dark:text-white;
|
||||
}
|
||||
|
||||
.navbar-bottom-items li {
|
||||
transition: all .2s ease-in-out;
|
||||
}
|
||||
}
|
||||
.navbar-bottom-items li {
|
||||
transition: all .2s ease-in-out;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
<template>
|
||||
<nuxt-link :to="link">
|
||||
<div
|
||||
class="mb-8 md:mb-0 home-link h-full duration-500 cursor-pointer flex flex-row justify-between py-3 w-full md:w-96 items-center"
|
||||
:class="getColor"
|
||||
>
|
||||
<div class="ml-4">
|
||||
<h1 class="text-2xl md:text-3xl font-bold my-2">
|
||||
{{ $t(title) }}
|
||||
<slot />
|
||||
</h1>
|
||||
<p class="w-5/6 text-gray-900 dark:text-dark-100 text-justify duration-300">{{ $t(description) }}</p>
|
||||
</div>
|
||||
<div class="mr-10 arrow duration-300">
|
||||
<svg class="inline icon" height="25" width="25" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</nuxt-link>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import {computed} from "@nuxtjs/composition-api";
|
||||
|
||||
interface HomeLinkProps {
|
||||
title: string,
|
||||
description: string,
|
||||
color: string,
|
||||
link: string
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "HomeLink",
|
||||
props: {
|
||||
title: {
|
||||
default: "Title",
|
||||
type: String
|
||||
},
|
||||
description: {
|
||||
default: "Description",
|
||||
type: String
|
||||
},
|
||||
color: {
|
||||
default: "red",
|
||||
type: String
|
||||
},
|
||||
link: {
|
||||
default: "/",
|
||||
type: String
|
||||
}
|
||||
},
|
||||
setup(props: HomeLinkProps) {
|
||||
/**const getColor = computed(() => {
|
||||
return 'hover:bg-color-400 dark:hover:bg-color-600 active:bg-color-400 dark:active:bg-color-600'.replaceAll('color', props.color)
|
||||
})*/
|
||||
const getColor = computed(() => {
|
||||
switch (props.color) {
|
||||
case 'orange':
|
||||
return 'hover:bg-orange-400 dark:hover:bg-orange-600 active:bg-orange-400 dark:active:bg-orange-600'
|
||||
case 'purple':
|
||||
return 'hover:bg-purple-400 dark:hover:bg-purple-600 active:bg-purple-400 dark:active:bg-purple-600'
|
||||
case 'blue':
|
||||
return 'hover:bg-blue-400 dark:hover:bg-blue-600 active:bg-blue-400 dark:active:bg-blue-600'
|
||||
case 'green':
|
||||
return 'hover:bg-green-400 dark:hover:bg-green-600 active:bg-green-400 dark:active:bg-green-600'
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
getColor,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.home-link:hover {
|
||||
p {
|
||||
@apply dark:text-white
|
||||
}
|
||||
.arrow {
|
||||
transform: translateX(15px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<h1
|
||||
class="mt-16 md:mt-32 font-bold text-2xl md:text-4xl mr-2 inline mb-4 border-b-2 border-solid"
|
||||
:class="getColor"
|
||||
class="mt-16 md:mt-32 font-bold text-2xl md:text-4xl mr-2 inline mb-4 border-b-2 border-solid border-gray-200 dark:border-gray-800"
|
||||
>
|
||||
{{ this.$t(title) }}
|
||||
<slot />
|
||||
@@ -9,31 +8,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import {computed} from "@nuxtjs/composition-api";
|
||||
|
||||
interface TitleProps {
|
||||
title: string,
|
||||
color: string
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "PageTitle",
|
||||
props: {
|
||||
title: {
|
||||
default: 'Title',
|
||||
type: String
|
||||
},
|
||||
color: {
|
||||
default: 'red',
|
||||
type: String
|
||||
}
|
||||
},
|
||||
setup(props: TitleProps) {
|
||||
const getColor = computed(() => `border-${props.color}-400`)
|
||||
|
||||
return {
|
||||
getColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,104 +1,85 @@
|
||||
<template>
|
||||
<article
|
||||
class="post border-2 border-black border-solid rounded-xl w-full h-blog p-2 flex flex-col justify-between my-5 duration-200 transform hover:scale-95"
|
||||
:style="{ backgroundImage: `url(${getBackGroundCover})` }"
|
||||
>
|
||||
<div>
|
||||
<p
|
||||
class="text-2xl md:text-3xl font-bold md:text-justify leading-7 mb-3"
|
||||
:class="lightBg ? 'text-black':'text-white'"
|
||||
>{{ title }}</p>
|
||||
<p
|
||||
class="text-lg italic text-justify leading-5"
|
||||
:class="lightBg ? 'text-gray-900':'text-dark-100'"
|
||||
>{{ description }}</p>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between mt-8 items-end"
|
||||
:class="lightBg ? 'text-gray-900':'text-dark-100'"
|
||||
>
|
||||
<div>
|
||||
<div>{{getDate}}</div>
|
||||
<div>{{reading_time}} min</div>
|
||||
<nuxt-link :to="`/blog/${slug}`">
|
||||
<div class="rounded-lg shadow-lg h-116 w-100 text-left dark:bg-gray-800 transform hover:scale-103 duration-300">
|
||||
<div class="h-2/5 post rounded-t-lg"
|
||||
:style="{ backgroundImage: `url(${getBackgroundCover})` }">
|
||||
</div>
|
||||
<div class="self-end flex flex-wrap flex-col md:flex-row">
|
||||
<div v-for="tag in tags"
|
||||
class="my-1 md:my-0 ml-2 py-1 px-2 rounded font-semibold"
|
||||
:class="lightBg ? 'bg-black text-white':'bg-white text-black'"
|
||||
>
|
||||
#{{ $t(tag) }}
|
||||
<div class="h-3/5 p-4 flex flex-col justify-between">
|
||||
<div>
|
||||
<div class="flex space-x-2 mb-2">
|
||||
<div v-for="tag in tags">
|
||||
<TagPreview :content="tag" :pill="true"/>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="text-2xl font-bold">{{ title }}</h1>
|
||||
<p class="text-base mt-3 text-gray-700 dark:text-gray-400 text-justify">{{ description }}</p>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<h5 class="text-base text-gray-700 dark:text-gray-400">{{ date }}</h5>
|
||||
<h5 class="text-base text-gray-700 dark:text-gray-400">{{ reading_time }} min.</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</nuxt-link>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {computed, useContext} from "@nuxtjs/composition-api";
|
||||
import {computed} from "@nuxtjs/composition-api";
|
||||
|
||||
interface PostProps {
|
||||
interface PostHomeProps {
|
||||
title: string,
|
||||
description: string,
|
||||
reading_time: number,
|
||||
date: string,
|
||||
tags: [],
|
||||
cover: string,
|
||||
background_is_light: boolean
|
||||
slug: string,
|
||||
tags: Array<string>,
|
||||
reading_time: number
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "Post",
|
||||
name: "PostHome",
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: "New Post's title "
|
||||
default: "Title"
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
default: "New Post's description"
|
||||
},
|
||||
reading_time: {
|
||||
type: Number,
|
||||
default: 0
|
||||
default: "Description"
|
||||
},
|
||||
date: {
|
||||
type: String,
|
||||
default: "Today"
|
||||
default: "Date"
|
||||
},
|
||||
cover: {
|
||||
type: String,
|
||||
default: "string"
|
||||
},
|
||||
slug: {
|
||||
type: String,
|
||||
default: "slug"
|
||||
},
|
||||
tags: {
|
||||
type: Array,
|
||||
default: () => ["Tag1", "Tag2", "Tag3"],
|
||||
},
|
||||
cover: {
|
||||
type: String,
|
||||
default: "default.png"
|
||||
reading_time: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
lightBg: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
setup(props: PostProps) {
|
||||
const {$i18n} = useContext()
|
||||
|
||||
const getDate = computed(() => {
|
||||
const dateFormat = props.date.split('-')
|
||||
return dateFormat[0] + " " + $i18n.t('month.' + dateFormat[1]) + " " + dateFormat[2]
|
||||
})
|
||||
|
||||
const getBackGroundCover = computed(() => require(`~/assets/images/posts/${props.cover}.png`))
|
||||
setup(props: PostHomeProps) {
|
||||
const getBackgroundCover = computed(() => require(`@/assets/images/posts/${props.cover}`))
|
||||
|
||||
return {
|
||||
getDate,
|
||||
getBackGroundCover
|
||||
getBackgroundCover
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.h-blog {
|
||||
min-height: 20rem;
|
||||
.post {
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
@apply bg-opacity-50;
|
||||
|
||||
57
src/components/PostsPreview.vue
Normal file
57
src/components/PostsPreview.vue
Normal file
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<section v-if="posts" class="w-full flex items-center justify-center my-20">
|
||||
<div class="flex flex-col items-center text-center">
|
||||
<div class="flex flex-col items-center">
|
||||
<h2 class="font-bold text-3xl">
|
||||
Derniers articles
|
||||
</h2>
|
||||
<p class="text-gray-700 dark:text-gray-400 text-xl w-2/3 mt-4">
|
||||
Je redige des articles concernant ma vie, le developpement et mes passions.
|
||||
</p>
|
||||
</div>
|
||||
<div class="my-8 flex w-full space-x-6">
|
||||
<div v-for="post in posts">
|
||||
<Post
|
||||
:title="post.title"
|
||||
:cover="post.cover"
|
||||
:description="post.description"
|
||||
:date="post.date"
|
||||
:slug="post.slug"
|
||||
:tags="post.tags"
|
||||
:reading_time="post.reading_time"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<Button content="Voir plus d'articles" link="blog"/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {useAsync, useContext} from "@nuxtjs/composition-api";
|
||||
import {Post} from "../../@types/types";
|
||||
|
||||
export default {
|
||||
name: "PostsPreview",
|
||||
setup() {
|
||||
const { $content, i18n } = useContext()
|
||||
|
||||
const posts = useAsync(() => {
|
||||
return $content(`articles/${i18n.locale}`)
|
||||
.sortBy("date", "asc")
|
||||
.limit(3)
|
||||
.fetch<Post>()
|
||||
})
|
||||
|
||||
return {
|
||||
posts
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
74
src/components/Project.vue
Normal file
74
src/components/Project.vue
Normal file
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<nuxt-link :to="`/projects/${slug}`">
|
||||
<div class="rounded-lg shadow-lg w-72 text-left dark:bg-gray-800 transform hover:scale-103 duration-300">
|
||||
<div class="h-40 post rounded-t-lg"
|
||||
:style="{ backgroundImage: `url(${getBackgroundCover})` }">
|
||||
</div>
|
||||
<div class="p-4 flex flex-col justify-between">
|
||||
<h1 class="text-xl font-bold">
|
||||
{{ title }}
|
||||
</h1>
|
||||
<div class="flex space-x-2 mt-2">
|
||||
<div v-for="tag in tags">
|
||||
<TagPreview :content="tag" :pill="false"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nuxt-link>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import {computed} from "@nuxtjs/composition-api";
|
||||
|
||||
interface ProjectProp {
|
||||
title: string,
|
||||
description: string,
|
||||
cover: string,
|
||||
slug: string,
|
||||
color: string,
|
||||
url: string
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "Project",
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: "Title"
|
||||
},
|
||||
cover: {
|
||||
type: String,
|
||||
default: "artapi.png"
|
||||
},
|
||||
slug: {
|
||||
type: String,
|
||||
default: "slug"
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: "red"
|
||||
},
|
||||
tags: {
|
||||
type: Array,
|
||||
default: () => ['tags.web', 'tags.software']
|
||||
}
|
||||
},
|
||||
setup(props: ProjectProp) {
|
||||
const getBackgroundCover = computed(() => require(`@/assets/images/works/artapi.png`))
|
||||
|
||||
return {
|
||||
getBackgroundCover
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.project {
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
@apply bg-opacity-50;
|
||||
}
|
||||
</style>
|
||||
53
src/components/ProjectsPreview.vue
Normal file
53
src/components/ProjectsPreview.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<section v-if="projects" class="w-full flex items-center justify-center my-20">
|
||||
<div class="flex flex-col items-center text-center">
|
||||
<div class="flex flex-col items-center">
|
||||
<h2 class="font-bold text-3xl">
|
||||
Derniers projets
|
||||
</h2>
|
||||
<p class="text-gray-700 dark:text-gray-400 text-xl w-2/3 mt-4">
|
||||
Quelques projets que j'ai realise dans ma vie de developpeur.
|
||||
</p>
|
||||
</div>
|
||||
<div class="my-8 flex w-full space-x-8">
|
||||
<div v-for="project in projects">
|
||||
<Project
|
||||
:title="project.title"
|
||||
:description="project.description"
|
||||
:color="project.color"
|
||||
:cover="project.cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<Button content="Voir plus de projets" link="projects"/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {useAsync, useContext} from "@nuxtjs/composition-api";
|
||||
import {Project} from "../../@types/types";
|
||||
|
||||
export default {
|
||||
name: "ProjectsPreview",
|
||||
setup() {
|
||||
const { $content } = useContext()
|
||||
|
||||
const projects = useAsync(() => {
|
||||
return $content(`projects`)
|
||||
.limit(3)
|
||||
.fetch<Project>()
|
||||
})
|
||||
|
||||
return {
|
||||
projects
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -35,7 +35,34 @@ export default {
|
||||
}
|
||||
},
|
||||
setup(props: SkillProps) {
|
||||
const getColor = computed(() => `hover:bg-${props.color}-400`)
|
||||
const getColor = computed(() => {
|
||||
switch (props.color) {
|
||||
case 'blueGray':
|
||||
return 'hover:bg-blueGray-400'
|
||||
case 'cyan':
|
||||
return 'hover:bg-cyan-400'
|
||||
case 'yellow':
|
||||
return 'hover:bg-yellow-400'
|
||||
case 'emerald':
|
||||
return 'hover:bg-emerald-400'
|
||||
case 'black':
|
||||
return 'hover:bg-black dark:hover:bg-gray-500'
|
||||
case 'orange':
|
||||
return 'hover:bg-orange-400'
|
||||
case 'lightBlue':
|
||||
return 'hover:bg-lightBlue-400'
|
||||
case 'lime':
|
||||
return 'hover:bg-lime-400'
|
||||
case 'teal':
|
||||
return 'hover:bg-teal-400'
|
||||
case 'blue':
|
||||
return 'hover:bg-blue-400'
|
||||
case 'red':
|
||||
return 'hover:bg-red-400'
|
||||
case 'rose':
|
||||
return 'hover:bg-rose-400'
|
||||
}
|
||||
})
|
||||
const getCoverLink = computed(() => require(`@/assets/images/skills/${props.cover}.png`))
|
||||
|
||||
return {
|
||||
|
||||
38
src/components/StrategyPart.vue
Normal file
38
src/components/StrategyPart.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1 class="font-bold text-2xl">
|
||||
{{ title }}
|
||||
</h1>
|
||||
<p class="text-gray-700 dark:text-gray-400 text-base text-justify">
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
interface StrategyPartProp {
|
||||
title: string,
|
||||
description: string
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "StrategyPart",
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: 'Title'
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
default: 'Description'
|
||||
}
|
||||
},
|
||||
setup(props: StrategyPartProp) {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
49
src/components/StrategyPreview.vue
Normal file
49
src/components/StrategyPreview.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<section class="w-full flex items-center justify-center my-12">
|
||||
<div class="flex flex-col items-center w-full">
|
||||
<div class="flex flex-col items-center">
|
||||
<h2 class="font-bold text-3xl">
|
||||
Workflow
|
||||
</h2>
|
||||
<p class="text-gray-700 dark:text-gray-400 text-xl w-2/3 mt-4">
|
||||
Je suis ce processus afin d'etre le plus productif et de donner le resultat le plus qualitatif possible.
|
||||
</p>
|
||||
</div>
|
||||
<div class="my-8 flex flex-row-reverse w-full justify-between items-center">
|
||||
<div class="w-1/2 flex justify-center items-center">
|
||||
La belle image
|
||||
</div>
|
||||
<div class="flex justify-center 1/2">
|
||||
<div class="flex flex-col space-y-6 w-full">
|
||||
<StrategyPart
|
||||
title="#1. Brainstorming"
|
||||
description="Je realise blablabla Je realise blablabla Je realise blablabla Je realise blablabla"
|
||||
/>
|
||||
<StrategyPart
|
||||
title="#2. Conception"
|
||||
description="Je realise blablabla"
|
||||
/>
|
||||
<StrategyPart
|
||||
title="#3. Developpement"
|
||||
description="Je realise blablabla"
|
||||
/>
|
||||
<StrategyPart
|
||||
title="#4. Livraison"
|
||||
description="Je realise blablabla"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "StrategyPreview",
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
28
src/components/TagPreview.vue
Normal file
28
src/components/TagPreview.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<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'"
|
||||
>
|
||||
{{ $t(content) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "TagPreview",
|
||||
props: {
|
||||
content: {
|
||||
type: String,
|
||||
default: "Content"
|
||||
},
|
||||
pill: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user