Initial Commit

This commit is contained in:
2021-12-12 17:39:25 +00:00
commit 472a53c2e0
139 changed files with 11404 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
<template>
<header class="rounded-md flex flex-col-reverse bg-gray-100 my-16 py-10 px-8 justify-between md:flex-row md:items-center dark:bg-gray-800">
<div class="sm:w-8/12">
<div class="space-y-px">
<div class="text-2xl font-semibold text-gray-900 sm:text-3xl md:text-4xl dark:text-gray-100">
<h1>Michael Thomas</h1>
<h1><span class="text-blue-600 dark:text-blue-600">Full-stack</span> web developer</h1>
</div>
<p class="text-gray-800 dark:text-gray-200">
Hi there! I'm Michael Thomas, a web developer and systems engineer from Columbia, South Carolina.
I build complex web apps using <a target="_blank" href="https://vuejs.org/">Vue.js</a>,
<a target="_blank" href="https://nuxtjs.org/">Nuxt.js</a> and <a target="_blank" href="https://tailwindcss.com/">TailwindCSS</a>.
</p>
</div>
</div>
</header>
</template>

View File

@@ -0,0 +1,43 @@
<template>
<div class="project-card md:flex mt-10">
<div class="img max-w-lg md:max-w-sm mx-auto m-2">
<nuxt-link :to="`/posts/${post.slug}`">
<img :alt="post.title" :src="`${post.thumbnail[0].url}`" class="rounded-xl"/>
</nuxt-link>
</div>
<div class="flex flex-col justify-between max-w-lg mx-auto">
<div class="txt md:px-5 lg:px-0">
<nuxt-link :to="`/posts/${post.slug}`">
<h2 class="text-xl font-semibold text-gray-800 dark:text-gray-100">{{ post.title }}</h2>
</nuxt-link>
<p class="font-semibold text-gray-600 dark:text-gray-300 text-sm">{{ formatDate(post.created_at) }}</p>
<div class="flex flex-col justify-between max-w-lg mx-auto">
</div>
<BlogTags :tags="post.tags" />
<p class="text-base text-gray-700 dark:text-gray-200 my-1">{{ post.description }}</p>
<nuxt-link
:to="`/posts/${post.slug}`"
class="text-base font-semibold text-gray-700 dark:text-gray-200 my-3 hover:underline">
Read more
</nuxt-link>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
post: {
type: Object,
default: null
}
},
methods: {
formatDate(date) {
const options = {year: 'numeric', month: 'long', day: 'numeric'}
return new Date(date).toLocaleDateString('en', options)
}
},
}
</script>

22
components/Blog/Tags.vue Normal file
View File

@@ -0,0 +1,22 @@
<template>
<div class="post-tags">
<span
v-for="tag of tags"
:key="tag"
class="font-semibold text-gray-600 bg-opacity-25 dark:bg-opacity-40 dark:text-gray-300 text-sm rounded bg-gray-200 dark:bg-primary mr-1 px-1"
>
#{{ tag }}
</span>
</div>
</template>
<script>
export default {
props: {
tags: {
type: Array,
default() {return []}
},
},
}
</script>

63
components/Blogs.vue Normal file
View File

@@ -0,0 +1,63 @@
<template>
<div class="mt-16">
<div class="flex justify-center items-center text-base font-semibold text-gray-600 dark:text-gray-300">
<h2 class="text-center">{{ title }}</h2>
<IconDoubleDown class="h-4 w-4"/>
</div>
<div class="wrapper-small my-5">
<div v-for="post of posts" :key="post.slug" class="project-card md:flex mt-10">
<div class="img max-w-lg md:max-w-sm mx-auto m-2">
<nuxt-link :to="`/posts/${post.slug}`">
<img :alt="post.title" :src="`${post.thumbnail[0].url}`" class="rounded-xl"/>
</nuxt-link>
</div>
<div class="flex flex-col justify-between max-w-lg mx-auto">
<div class="txt md:px-5 lg:px-0">
<nuxt-link :to="`/posts/${post.slug}`">
<h2 class="text-xl font-semibold text-gray-800 dark:text-gray-100">{{ post.title }}</h2>
</nuxt-link>
<p class="font-semibold text-gray-600 dark:text-gray-300 text-sm">{{ formatDate(post.created_at) }}</p>
<div class="flex flex-col justify-between max-w-lg mx-auto">
</div>
<span
v-for="tag of post.tags" :key="tag"
class="font-semibold text-gray-600 bg-opacity-25 dark:bg-opacity-40 dark:text-gray-300 text-sm rounded bg-gray-200 dark:bg-primary mr-1 px-1">
#{{ tag }}
</span>
<p class="text-base text-gray-700 dark:text-gray-200 my-1">{{ post.description }}</p>
<nuxt-link
:to="`/posts/${post.slug}`"
class="text-base font-semibold text-gray-700 dark:text-gray-200 my-3 hover:underline">
Read more >
</nuxt-link>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
default: "Blogs",
},
posts: {
type: Array,
default() {return []}
},
},
methods: {
formatDate(date) {
const options = {year: 'numeric', month: 'long', day: 'numeric'}
return new Date(date).toLocaleDateString('en', options)
}
},
}
</script>

View File

@@ -0,0 +1,34 @@
<template>
<div
class="rounded-full cursor-pointer ml-5 bg-gray-100 p-2 text-gray-900 dark:bg-gray-800 dark:text-gray-100 focus:outline-none"
@click="switchTheme"
>
<IconSun v-if="getSelectedTheme === 'light'" class="h-5 w-5"/>
<IconMoon v-else class="h-5 w-5"/>
</div>
</template>
<script>
export default {
computed: {
/**
* Returns the selected color mode value.
* @returns {string} The color mode as "light" or "dark".
*/
getSelectedTheme() {
return this.$colorMode.value
},
},
methods: {
/**
* Updates the color mode value.
*/
switchTheme() {
this.$colorMode.preference =
this.getSelectedTheme === "dark" ? "light" : "dark"
},
},
}
</script>

30
components/Footer.vue Normal file
View File

@@ -0,0 +1,30 @@
<template>
<footer class="bg-gray-50 dark:bg-gray-800">
<div class="wrapper mx-auto mt-24 px-5">
<div class="md:py-5">
<div class="flex flex-col items-center justify-between mt-6 md:mt-0 md:flex-row">
<div class="logo flex items-center">
<div class="text-sm text-gray-700 dark:text-gray-200 mx-1">
<p>© 2021 Michael Thomas</p>
<p>
Built with &#128151; and
<a
aria-label="AymaneMx.com"
class="text-sm underline text-gray-700 dark:text-gray-200"
href="https://github.com/aymaneMx/nuxt-portfolio-dev"
>
available on Github
</a>
</p>
</div>
</div>
<div>
<Social/>
</div>
</div>
</div>
</div>
</footer>
</template>

46
components/Header.vue Normal file
View File

@@ -0,0 +1,46 @@
<template>
<div>
<nav class="wrapper py-6">
<div class="px-10 flex justify-between items-center">
<div class="logo">
<nuxt-link to="/">
<h1 class="text-2xl font-semibold text-gray-700 dark:text-gray-200">{{ $config.devLogo }}</h1>
</nuxt-link>
</div>
<div class="flex flex-row">
<nuxt-link class="nav-link" to="/posts">Blog</nuxt-link>
<nuxt-link class="nav-link" to="/about">About</nuxt-link>
<ColorSwitcher/>
</div>
</div>
</nav>
</div>
</template>
<script>
export default {
data() {
return {
isOpen: false
}
},
methods: {
toggle() {
this.isOpen = !this.isOpen
},
}
}
</script>
<style>
.mobile-link {
@apply block px-3 py-2 text-lg text-gray-900 rounded-md text-white font-medium text-center;
}
.nav-link {
@apply ml-5 font-medium text-center text-lg text-gray-700 dark:text-gray-200 dark:hover:text-primary hover:text-primary m-auto;
}
</style>

14
components/Hero.vue Normal file
View File

@@ -0,0 +1,14 @@
<template>
<div class="flex h-full text-center text-gray-700 dark:text-gray-200 m-8">
<div class="m-auto">
<h2 class="text-xl md:text-2xl lg:text-3xl font-semibold">
<span class="font-normal dark:text-gray-300"> Hey, I am </span>{{ $config.devName}}</h2>
<h3 class="font-bold text-primary dark:text-primary text-2xl md:text-3xl lg:text-4xl">a {{ $config.devRole}}</h3>
<p class="text-lg lg:text-xl font-semibold">{{ $config.devDescription}}</p>
<div class="mt-5">
<TechStack/>
</div>
</div>
</div>
</template>

44
components/Icon.vue Normal file
View File

@@ -0,0 +1,44 @@
<template>
<!-- eslint-disable vue/no-v-html -->
<div v-if="!name"></div>
<div v-else-if="!icon"></div>
<div
v-else-if="typeof classes === 'string'"
:class="`svg-icon ${classes}`"
>
<img :src="icon" />
</div>
<div
v-else-if="typeof classes === 'object'"
:class="`svg-icon ${classes}`"
>
<img :src="icon" />
</div>
<div v-else class="svg-icon">
<img :src="icon" />
</div>
</template>
<script>
export default {
props: {
name: {
type: String,
required: true,
},
classes: {
type: [String, Array],
required: false,
default: () => [],
},
},
data() {
return {
icon: this.name ? require(`~/assets/icons/${this.name}.svg`) : null,
}
},
}
</script>

3
components/Icon/Aws.vue Normal file
View File

@@ -0,0 +1,3 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--fa-brands" width="40" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 512"><path d="M180.41 203.01c-.72 22.65 10.6 32.68 10.88 39.05a8.164 8.164 0 0 1-4.1 6.27l-12.8 8.96a10.66 10.66 0 0 1-5.63 1.92c-.43-.02-8.19 1.83-20.48-25.61a78.608 78.608 0 0 1-62.61 29.45c-16.28.89-60.4-9.24-58.13-56.21c-1.59-38.28 34.06-62.06 70.93-60.05c7.1.02 21.6.37 46.99 6.27v-15.62c2.69-26.46-14.7-46.99-44.81-43.91c-2.4.01-19.4-.5-45.84 10.11c-7.36 3.38-8.3 2.82-10.75 2.82c-7.41 0-4.36-21.48-2.94-24.2c5.21-6.4 35.86-18.35 65.94-18.18a76.857 76.857 0 0 1 55.69 17.28a70.285 70.285 0 0 1 17.67 52.36l-.01 69.29zM93.99 235.4c32.43-.47 46.16-19.97 49.29-30.47c2.46-10.05 2.05-16.41 2.05-27.4c-9.67-2.32-23.59-4.85-39.56-4.87c-15.15-1.14-42.82 5.63-41.74 32.26c-1.24 16.79 11.12 31.4 29.96 30.48zm170.92 23.05c-7.86.72-11.52-4.86-12.68-10.37l-49.8-164.65c-.97-2.78-1.61-5.65-1.92-8.58a4.61 4.61 0 0 1 3.86-5.25c.24-.04-2.13 0 22.25 0c8.78-.88 11.64 6.03 12.55 10.37l35.72 140.83l33.16-140.83c.53-3.22 2.94-11.07 12.8-10.24h17.16c2.17-.18 11.11-.5 12.68 10.37l33.42 142.63L420.98 80.1c.48-2.18 2.72-11.37 12.68-10.37h19.72c.85-.13 6.15-.81 5.25 8.58c-.43 1.85 3.41-10.66-52.75 169.9c-1.15 5.51-4.82 11.09-12.68 10.37h-18.69c-10.94 1.15-12.51-9.66-12.68-10.75L328.67 110.7l-32.78 136.99c-.16 1.09-1.73 11.9-12.68 10.75h-18.3zm273.48 5.63c-5.88.01-33.92-.3-57.36-12.29a12.802 12.802 0 0 1-7.81-11.91v-10.75c0-8.45 6.2-6.9 8.83-5.89c10.04 4.06 16.48 7.14 28.81 9.6c36.65 7.53 52.77-2.3 56.72-4.48c13.15-7.81 14.19-25.68 5.25-34.95c-10.48-8.79-15.48-9.12-53.13-21c-4.64-1.29-43.7-13.61-43.79-52.36c-.61-28.24 25.05-56.18 69.52-55.95c12.67-.01 46.43 4.13 55.57 15.62c1.35 2.09 2.02 4.55 1.92 7.04v10.11c0 4.44-1.62 6.66-4.87 6.66c-7.71-.86-21.39-11.17-49.16-10.75c-6.89-.36-39.89.91-38.41 24.97c-.43 18.96 26.61 26.07 29.7 26.89c36.46 10.97 48.65 12.79 63.12 29.58c17.14 22.25 7.9 48.3 4.35 55.44c-19.08 37.49-68.42 34.44-69.26 34.42zm40.2 104.86c-70.03 51.72-171.69 79.25-258.49 79.25A469.127 469.127 0 0 1 2.83 327.46c-6.53-5.89-.77-13.96 7.17-9.47a637.37 637.37 0 0 0 316.88 84.12a630.22 630.22 0 0 0 241.59-49.55c11.78-5 21.77 7.8 10.12 16.38zm29.19-33.29c-8.96-11.52-59.28-5.38-81.81-2.69c-6.79.77-7.94-5.12-1.79-9.47c40.07-28.17 105.88-20.1 113.44-10.63c7.55 9.47-2.05 75.41-39.56 106.91c-5.76 4.87-11.27 2.3-8.71-4.1c8.44-21.25 27.39-68.49 18.43-80.02z" fill="currentColor"></path></svg>
</template>

View File

@@ -0,0 +1,3 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--bx" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M7.533 12.249c-.011 1.985 1.445 3.168 3.768 2.63V9.618c-2.352-.716-3.758.733-3.768 2.631m3.839-10.238h3.199v15.143c-3.066.501-6.004.819-8.104-.355c-2.705-1.513-2.923-6.319-.782-8.46c1.085-1.085 3.271-1.85 5.616-1.351V2.225c-.006-.101-.012-.202.071-.214m8.389 3.342h-3.199V2.011h3.199v3.342z" fill="currentColor"></path><path d="M19.761 7.044c-.003 2.356-.003 4.048-.003 6.911c-.136 2.813-.104 5.052-1.135 6.398c-.203.266-.634.652-.995.924c-.303.228-.881.691-1.208.711c-.331.021-1.18-.459-1.564-.64c-.505-.237-.971-.553-1.493-.71c1.218-.754 2.372-1.32 2.844-2.844c.41-1.326.355-3.247.355-5.119c0-1.849.009-3.998.009-5.63l3.19-.001z" fill="currentColor"></path></svg>
</template>

View File

@@ -0,0 +1,10 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24">
<path
d="M16.59 5.59L18 7l-6 6l-6-6l1.41-1.41L12 10.17l4.59-4.58m0 6L18 13l-6 6l-6-6l1.41-1.41L12 16.17l4.59-4.58z"
fill="currentColor"></path>
</svg>
</template>

9
components/Icon/Fork.vue Normal file
View File

@@ -0,0 +1,9 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
class="iconify iconify--fe" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24">
<path
d="M9 7.83V12h3a3 3 0 0 0 3-3V7.83a3.001 3.001 0 1 1 2 0V9a5 5 0 0 1-5 5H9v2.17a3.001 3.001 0 1 1-2 0V7.83a3.001 3.001 0 1 1 2 0zM8 20a1 1 0 1 0 0-2a1 1 0 0 0 0 2zm8-14a1 1 0 1 0 0-2a1 1 0 0 0 0 2zM8 6a1 1 0 1 0 0-2a1 1 0 0 0 0 2z"
fill="currentColor" fill-rule="evenodd"></path>
</svg>
</template>

View File

@@ -0,0 +1,9 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24">
<path
d="M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5c.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34c-.46-1.16-1.11-1.47-1.11-1.47c-.91-.62.07-.6.07-.6c1 .07 1.53 1.03 1.53 1.03c.87 1.52 2.34 1.07 2.91.83c.09-.65.35-1.09.63-1.34c-2.22-.25-4.55-1.11-4.55-4.92c0-1.11.38-2 1.03-2.71c-.1-.25-.45-1.29.1-2.64c0 0 .84-.27 2.75 1.02c.79-.22 1.65-.33 2.5-.33c.85 0 1.71.11 2.5.33c1.91-1.29 2.75-1.02 2.75-1.02c.55 1.35.2 2.39.1 2.64c.65.71 1.03 1.6 1.03 2.71c0 3.82-2.34 4.66-4.57 4.91c.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2z"
fill="currentColor"></path>
</svg>
</template>

View File

@@ -0,0 +1,10 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
class="iconify iconify--grommet-icons" width="32" height="32" preserveAspectRatio="xMidYMid meet"
viewBox="0 0 24 24">
<path
fill="currentColor" fill-rule="evenodd"
d="M20.443 0H3.162A2.162 2.162 0 0 0 1 2.162V21.84C1 23.034 1.97 24 3.162 24h17.28a2.159 2.159 0 0 0 2.16-2.16V2.162A2.16 2.16 0 0 0 20.442 0zm.958 21.84c0 .53-.429.96-.958.96H3.162a.961.961 0 0 1-.962-.96V2.162c0-.532.432-.962.962-.962h17.28c.53 0 .96.43.96.962V21.84zm-15-1.439l2.701-2.4L6.4 15.6V20.4zm9.757-9.729c-.486-.488-1.373-1.071-2.856-1.071c-1.627 0-3.303.424-4.5.812V3.6H6.4V14.01l1.697-.769c.028-.013 2.763-1.239 5.205-1.239c1.218 0 1.488.67 1.501 1.231v7.17h2.398v-7.2c.003-.155-.012-1.486-1.043-2.53M13 7.5h2.401c1.085-1.228 1.637-2.536 1.8-3.899h-2.399c-.267 1.36-.858 2.66-1.802 3.9"></path>
</svg>
</template>

View File

@@ -0,0 +1,10 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
class="iconify iconify--simple-icons" width="32" height="32" preserveAspectRatio="xMidYMid meet"
viewBox="0 0 24 24">
<path
d="M0 0h24v24H0V0zm22.034 18.276c-.175-1.095-.888-2.015-3.003-2.873c-.736-.345-1.554-.585-1.797-1.14c-.091-.33-.105-.51-.046-.705c.15-.646.915-.84 1.515-.66c.39.12.75.42.976.9c1.034-.676 1.034-.676 1.755-1.125c-.27-.42-.404-.601-.586-.78c-.63-.705-1.469-1.065-2.834-1.034l-.705.089c-.676.165-1.32.525-1.71 1.005c-1.14 1.291-.811 3.541.569 4.471c1.365 1.02 3.361 1.244 3.616 2.205c.24 1.17-.87 1.545-1.966 1.41c-.811-.18-1.26-.586-1.755-1.336l-1.83 1.051c.21.48.45.689.81 1.109c1.74 1.756 6.09 1.666 6.871-1.004c.029-.09.24-.705.074-1.65l.046.067zm-8.983-7.245h-2.248c0 1.938-.009 3.864-.009 5.805c0 1.232.063 2.363-.138 2.711c-.33.689-1.18.601-1.566.48c-.396-.196-.597-.466-.83-.855c-.063-.105-.11-.196-.127-.196l-1.825 1.125c.305.63.75 1.172 1.324 1.517c.855.51 2.004.675 3.207.405c.783-.226 1.458-.691 1.811-1.411c.51-.93.402-2.07.397-3.346c.012-2.054 0-4.109 0-6.179l.004-.056z"
fill="currentColor"></path>
</svg>
</template>

View File

@@ -0,0 +1,10 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24">
<path
d="M19 3a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14m-.5 15.5v-5.3a3.26 3.26 0 0 0-3.26-3.26c-.85 0-1.84.52-2.32 1.3v-1.11h-2.79v8.37h2.79v-4.93c0-.77.62-1.4 1.39-1.4a1.4 1.4 0 0 1 1.4 1.4v4.93h2.79M6.88 8.56a1.68 1.68 0 0 0 1.68-1.68c0-.93-.75-1.69-1.68-1.69a1.69 1.69 0 0 0-1.69 1.69c0 .93.76 1.68 1.69 1.68m1.39 9.94v-8.37H5.5v8.37h2.77z"
fill="currentColor"></path>
</svg>
</template>

View File

@@ -0,0 +1,9 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
class="iconify iconify--bx" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24">
<path
d="M4.285 7.269a.733.733 0 0 0-.24-.619l-1.77-2.133v-.32h5.498l4.25 9.32l3.736-9.32H21v.319l-1.515 1.451a.45.45 0 0 0-.168.425v10.666a.448.448 0 0 0 .168.425l1.479 1.451v.319h-7.436v-.319l1.529-1.487c.152-.15.152-.195.152-.424V8.401L10.95 19.218h-.575L5.417 8.401v7.249c-.041.305.06.612.275.833L7.684 18.9v.319H2.036V18.9l1.992-2.417a.971.971 0 0 0 .257-.833V7.269z"
fill="currentColor"></path>
</svg>
</template>

15
components/Icon/Moon.vue Normal file
View File

@@ -0,0 +1,15 @@
<template>
<svg
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="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"
/>
</svg>
</template>

9
components/Icon/Nuxt.vue Normal file
View File

@@ -0,0 +1,9 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24">
<path
d="M21.8 18.36L16.03 8.08c-.1-.08-.4-.65-1-.65c-.25 0-.6.1-.96.65l-.74 1.18l-2.02-3.61c-.05-.1-.4-.65-1-.65c-.25 0-.65.1-.95.65L2.18 18.31c-.05.1-.35.69-.05 1.19c.1.25.4.5 1.06.5h17.66c.1 0 .75 0 1.05-.5c.1-.24.2-.64-.1-1.14m-13.7-.05l-.15.55H3.24l7.12-12.52l2.3 4.13l-4.56 7.84m1.11.55l4.11-7.2l4.18 7.2H9.21m9.53 0l-.2-.55L14 10.46l1.03-1.73l5.72 10.13h-2.01z"
fill="currentColor"></path>
</svg>
</template>

View File

@@ -0,0 +1,9 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24">
<path
d="M19.14 7.5A2.86 2.86 0 0 1 22 10.36v3.78A2.86 2.86 0 0 1 19.14 17H12c0 .39.32.96.71.96H17v1.68a2.86 2.86 0 0 1-2.86 2.86H9.86A2.86 2.86 0 0 1 7 19.64v-3.75a2.85 2.85 0 0 1 2.86-2.85h5.25a2.85 2.85 0 0 0 2.85-2.86V7.5h1.18m-4.28 11.79c-.4 0-.72.3-.72.89c0 .59.32.71.72.71a.71.71 0 0 0 .71-.71c0-.59-.32-.89-.71-.89m-10-1.79A2.86 2.86 0 0 1 2 14.64v-3.78A2.86 2.86 0 0 1 4.86 8H12c0-.39-.32-.96-.71-.96H7V5.36A2.86 2.86 0 0 1 9.86 2.5h4.28A2.86 2.86 0 0 1 17 5.36v3.75a2.85 2.85 0 0 1-2.86 2.85H8.89a2.85 2.85 0 0 0-2.85 2.86v2.68H4.86M9.14 5.71c.4 0 .72-.3.72-.89c0-.59-.32-.71-.72-.71c-.39 0-.71.12-.71.71s.32.89.71.89z"
fill="currentColor"></path>
</svg>
</template>

9
components/Icon/Star.vue Normal file
View File

@@ -0,0 +1,9 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
class="iconify iconify--carbon" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32">
<path
d="M16 6.52l2.76 5.58l.46 1l1 .15l6.16.89l-4.38 4.3l-.75.73l.18 1l1.05 6.13l-5.51-2.89L16 23l-.93.49l-5.51 2.85l1-6.13l.18-1l-.74-.77l-4.42-4.35l6.16-.89l1-.15l.46-1L16 6.52M16 2l-4.55 9.22l-10.17 1.47l7.36 7.18L6.9 30l9.1-4.78L25.1 30l-1.74-10.13l7.36-7.17l-10.17-1.48z"
fill="currentColor"></path>
</svg>
</template>

15
components/Icon/Sun.vue Normal file
View File

@@ -0,0 +1,15 @@
<template>
<svg
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="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"
/>
</svg>
</template>

View File

@@ -0,0 +1,15 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
class="iconify iconify--teenyicons" width="32" height="32" preserveAspectRatio="xMidYMid meet"
viewBox="0 0 15 15">
<g fill="none">
<path
d="M7.5 2.5c-1.026 0-1.908.277-2.6.87c-.688.59-1.137 1.447-1.387 2.516a.5.5 0 0 0 .897.4c.316-.452.632-.723.936-.863c.294-.135.611-.162.975-.065c.366.098.65.386 1.095.87l.015.016c.336.365.745.81 1.305 1.156c.582.359 1.305.6 2.264.6c1.026 0 1.908-.277 2.6-.87c.688-.59 1.138-1.447 1.387-2.516a.5.5 0 0 0-.897-.4c-.316.452-.632.723-.936.863c-.294.135-.611.162-.975.065c-.366-.098-.65-.386-1.095-.87l-.015-.016c-.336-.365-.745-.81-1.305-1.156c-.582-.359-1.305-.6-2.264-.6z"
fill="currentColor"></path>
<path
d="M4 7c-1.026 0-1.908.277-2.6.87C.712 8.46.263 9.317.013 10.386a.5.5 0 0 0 .897.4c.316-.452.632-.723.936-.863c.294-.135.611-.162.975-.065c.366.098.65.386 1.095.87l.015.016c.336.365.745.81 1.305 1.156c.582.359 1.305.6 2.264.6c1.026 0 1.908-.277 2.6-.87c.688-.59 1.138-1.447 1.387-2.516a.5.5 0 0 0-.897-.4c-.316.452-.632.723-.936.863c-.294.135-.611.162-.975.065c-.366-.098-.65-.386-1.095-.87l-.015-.016c-.335-.365-.745-.81-1.305-1.156C5.682 7.24 4.959 7 4 7z"
fill="currentColor"></path>
</g>
</svg>
</template>

View File

@@ -0,0 +1,9 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24">
<path
d="M22.46 6c-.77.35-1.6.58-2.46.69c.88-.53 1.56-1.37 1.88-2.38c-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29c0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15c0 1.49.75 2.81 1.91 3.56c-.71 0-1.37-.2-1.95-.5v.03c0 2.08 1.48 3.82 3.44 4.21a4.22 4.22 0 0 1-1.93.07a4.28 4.28 0 0 0 4 2.98a8.521 8.521 0 0 1-5.33 1.84c-.34 0-.68-.02-1.02-.06C3.44 20.29 5.7 21 8.12 21C16 21 20.33 14.46 20.33 8.79c0-.19 0-.37-.01-.56c.84-.6 1.56-1.36 2.14-2.23z"
fill="currentColor"></path>
</svg>
</template>

View File

@@ -0,0 +1,7 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img"
class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24">
<path d="M2 3h3.5L12 15l6.5-12H22L12 21L2 3m4.5 0h3L12 7.58L14.5 3h3L12 13.08L6.5 3z" fill="currentColor"></path>
</svg>
</template>

View File

View File

View File

@@ -0,0 +1,55 @@
<template>
<div class="wrapper-small my-5">
<div class='grid grid-cols-1 md:grid-cols-2 gap-6'>
<a
v-for='(project, index) in projects'
:key='index'
:href='project.html_url'
class='block bg-gray-50 dark:bg-gray-800 p-6 shadow rounded-lg mt-2 lg:mt-0'
rel="noreferrer"
target='_blank'
>
<div>
<h3 class='text-lg font-medium text-gray-800 dark:text-gray-100'>
{{ project.name }}
</h3>
<p class='my-2 text-base text-gray-500 dark:text-gray-400'>
{{ project.description }}
</p>
<ul class='flex items-center space-x-4 text-black dark:text-gray-200'>
<li class='inline-flex items-center'>
<IconStar class="h-4 w-4 mr-1"/>
<span>{{ project.stargazers_count }}</span>
</li>
<li v-if='project.forks' class='inline-flex items-center'>
<IconFork class="h-4 w-4 mr-1"/>
<span>{{ project.forks }}</span>
</li>
</ul>
</div>
</a>
<div class='flex items-center justify-center'>
<a
class='bg-black w-full md:w-auto flex items-center justify-center px-10 md:px-24 py-3 shadow-md hover:bg-gray-800 rounded-lg text-white'
href='https://github.com/aymaneMx'
rel="noreferrer"
target='_blank'
>
<IconGithub class="text-white h-6 w-6 mr-3"/>
See More Projects
</a>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
projects: {
type: Array,
default() {return []}
}
}
}
</script>

View File

@@ -0,0 +1,32 @@
<template>
<div class="grid grid-cols-2 gap-2 mt-4 sm:grid-cols-3 md:grid-cols-4">
<ResumeTechnologyCard
v-for="(technology, index) in technologies"
:key="`skill-${index}`"
:title="technology"
/>
</div>
</template>
<script>
export default {
data() {
return {
technologies: [
"JavaScript",
"HTML5",
"Nuxt.js",
"Vue.js",
"Tailwind CSS",
"Node.js",
"TypeScript",
"Sass",
"Figma",
"WordPress",
"PHP",
"React.js",
]
}
}
}
</script>

View File

@@ -0,0 +1,38 @@
<template>
<div
class="flex items-center space-x-2 overflow-hidden text-gray-900 dark:text-gray-100"
>
<icon :name="getIconName" class="flex-shrink-0 w-7 h-7" />
<span class="truncate">{{ title }}</span>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
required: true,
default: "",
},
icon: {
type: String,
required: false,
default: null,
},
},
computed: {
/**
* Returns possible icon name if icon prop is not passed.
* @returns {string}
*/
getIconName() {
if (this.icon) return this.icon
else
return (
this.title?.toLowerCase()?.replace(/[^a-zA-Z]/g, "") || "arrow-right"
)
},
},
}
</script>

21
components/Social.vue Normal file
View File

@@ -0,0 +1,21 @@
<template>
<div class="wrapper flex flex-wrap text-base text-center m-3 text-gray-800 dark:text-gray-200">
<a
aria-label="Github"
class="social-link hover:text-primary mx-3" :href=$config.devGithubLink>
<IconGithub class="h-6 w-6"/>
</a>
<a
aria-label="Twitter"
class="social-link hover:text-primary mx-3" :href=$config.devTwitterLink>
<IconTwitter class="h-6 w-6"/>
</a>
<a
aria-label="LinkedIn"
class="social-link hover:text-primary mx-3" :href=$config.devLinkedinLink>
<IconLinkedin class="h-6 w-6"/>
</a>
</div>
</template>

20
components/TechStack.vue Normal file
View File

@@ -0,0 +1,20 @@
<template>
<div class="mt-16 md:mt-24">
<div class="flex justify-center items-center text-base font-semibold text-gray-600 dark:text-gray-300">
<h2 class="text-center">Tech stack I use </h2>
<IconDoubleDown class="h-4 w-4"/>
</div>
<div class="flex flex-wrap justify-center items-center text-4xl mt-5">
<IconPython class="m-2 md:m-4"/>
<IconDjango class="m-2 md:m-4"/>
<IconAws class="m-2 md:m-4"/>
<IconHeroku class="m-2 md:m-4"/>
<IconJavascript class="m-2 md:m-4"/>
<IconTailwind class="m-2 md:m-4"/>
<IconVuejs class="m-2 md:m-4"/>
<IconNuxt class="m-2 md:m-4"/>
</div>
</div>
</template>