Adding project to github
This commit is contained in:
67
pages/blog/[post].vue
Normal file
67
pages/blog/[post].vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="sticky top-0 py-2 px-4 bg-white opacity-90 shadow-md">
|
||||
<div
|
||||
class="m-auto w-full max-w-3xl flex items-center justify-between"
|
||||
>
|
||||
<NuxtLink class="text-2xl text-zinc-600" to="/blog"
|
||||
>Project Overview</NuxtLink
|
||||
>
|
||||
<NuxtLink to="/">Back to Resume</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-4"></div>
|
||||
<div class="mx-auto max-w-3xl px-4 blog">
|
||||
<h1>{{ page.title }}</h1>
|
||||
<h2 class="text-zinc-500 pb-3">Posted on: {{ page.date }}</h2>
|
||||
<!-- <ContentDoc /> -->
|
||||
<ContentRenderer :key="page._id" :value="page" />
|
||||
</div>
|
||||
<div class="w-full h-2 bg-blue-400 my-4"></div>
|
||||
<div v-if="data && page" class="mx-auto max-w-3xl px-4">
|
||||
<p>Other Projects</p>
|
||||
<a
|
||||
v-for="post in data"
|
||||
:href="post._path"
|
||||
class="text-blue-700 w-full px-2"
|
||||
>
|
||||
<h3 class="text-xl">{{ post.title }}</h3>
|
||||
<p class="text-zinc-500">{{ post.description }}</p>
|
||||
<!-- <p>{{ post }}</p> -->
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// Find other pages and list them
|
||||
const { data } = await useAsyncData("blog", () => queryContent("/").find());
|
||||
// Find current page content
|
||||
const { page } = useContent();
|
||||
// console.log(page.value);
|
||||
// console.log(data.value);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.blog {
|
||||
@apply leading-9 text-base;
|
||||
}
|
||||
.blog a {
|
||||
@apply text-blue-700;
|
||||
}
|
||||
.blog h1 {
|
||||
@apply pt-5 text-3xl border-zinc-300;
|
||||
}
|
||||
.blog h3 {
|
||||
@apply pt-5 mb-2 text-xl border-b border-zinc-300;
|
||||
}
|
||||
.blog img {
|
||||
@apply my-3 shadow-sm;
|
||||
}
|
||||
.blog p + P {
|
||||
@apply pt-4;
|
||||
}
|
||||
.blog ul {
|
||||
@apply list-disc ml-10;
|
||||
}
|
||||
</style>
|
50
pages/blog/index.vue
Normal file
50
pages/blog/index.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<div class="">
|
||||
<div class="sticky top-0 py-2 bg-white opacity-90 shadow-md">
|
||||
<div
|
||||
class="m-auto w-full max-w-3xl flex items-center justify-between"
|
||||
>
|
||||
<NuxtLink class="text-xl" to="/blog">Max's Blog</NuxtLink>
|
||||
<NuxtLink class="" to="/">Home</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full h-2 bg-blue-400"></div>
|
||||
<div v-if="data" class="mx-auto max-w-3xl">
|
||||
<a
|
||||
v-for="post in data"
|
||||
:href="post._path"
|
||||
class="text-blue-700 w-full px-2"
|
||||
>
|
||||
<h3>{{ post.title }}</h3>
|
||||
<p class="text-zinc-500">{{ post.description }}</p>
|
||||
<!-- <p>{{ post }}</p> -->
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// Find other pages and list them
|
||||
const { data } = await useAsyncData("blog", () => queryContent("/").find());
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.blog {
|
||||
@apply leading-9 text-base;
|
||||
}
|
||||
.blog a {
|
||||
@apply text-blue-700;
|
||||
}
|
||||
.blog h1 {
|
||||
@apply pt-5 text-3xl border-zinc-300;
|
||||
}
|
||||
.blog h3 {
|
||||
@apply pt-5 mb-2 text-xl border-b border-zinc-300;
|
||||
}
|
||||
.blog img {
|
||||
@apply my-3 shadow-sm;
|
||||
}
|
||||
.blog p + P {
|
||||
@apply pt-4;
|
||||
}
|
||||
</style>
|
780
pages/homepage.html.vue
Normal file
780
pages/homepage.html.vue
Normal file
@@ -0,0 +1,780 @@
|
||||
<template>
|
||||
<div class="max-links">
|
||||
<div class="text-box">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Type some shit 😘🔎"
|
||||
class="glass"
|
||||
v-model="inputText"
|
||||
v-on:keydown="filterKeydown"
|
||||
v-on:keyup="filterLinks"
|
||||
v-on:keyup.enter="webSearch"
|
||||
ref="search"
|
||||
/>
|
||||
|
||||
<div class="suggestions" v-if="suggestions.length > 0">
|
||||
<div
|
||||
class="suggestion"
|
||||
v-for="(suggestion, index) in suggestions"
|
||||
:class="{ active: suggestionIndex == index }"
|
||||
>
|
||||
{{ suggestion }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-for="column in columns" class="column">
|
||||
<h2>{{ column }}</h2>
|
||||
<div
|
||||
v-for="link in sortedLinks(links, column)"
|
||||
v-if="link?.title"
|
||||
class="flex-child"
|
||||
>
|
||||
<a
|
||||
:href="setupUrl(link.url)"
|
||||
class="max-link"
|
||||
target="_blank"
|
||||
v-on:click="linkClick"
|
||||
v-if="link.column == column"
|
||||
>
|
||||
<span class="visual-aid">
|
||||
{{ link.emoji }}
|
||||
</span>
|
||||
{{ link?.title }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="lip one"></div> -->
|
||||
|
||||
<span
|
||||
v-on:click="clicks++"
|
||||
class="small message"
|
||||
v-html="generateMessage(2)"
|
||||
></span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
let seed = ref(0);
|
||||
let clicks = ref(0);
|
||||
let inputText = ref("");
|
||||
let suggestions = ref([]);
|
||||
let suggestionIndex = ref(0);
|
||||
let autocomplete = ref(["google.com", "gmail.com", "graxday.com"]);
|
||||
let columns = ref(["web", "apps", "local", "dumb"]);
|
||||
let links = ref([
|
||||
{
|
||||
column: "local",
|
||||
url: "192.168.1.6",
|
||||
title: "Tower",
|
||||
emoji: "🖥️",
|
||||
},
|
||||
{
|
||||
column: "local",
|
||||
url: "192.168.1.242/admin",
|
||||
title: "Pi-Hole",
|
||||
emoji: "🌌",
|
||||
},
|
||||
{
|
||||
column: "local",
|
||||
url: "192.168.1.6:8112",
|
||||
title: "Deluge",
|
||||
emoji: "💦",
|
||||
},
|
||||
{
|
||||
column: "local",
|
||||
url: "192.168.1.164",
|
||||
title: "Marvin",
|
||||
emoji: "🧪",
|
||||
},
|
||||
{
|
||||
column: "local",
|
||||
url: "https://192.168.1.1",
|
||||
title: "Router",
|
||||
emoji: "📶",
|
||||
},
|
||||
|
||||
{
|
||||
column: "apps",
|
||||
url: "192.168.1.164:9999/admin",
|
||||
title: "Blog Editing",
|
||||
emoji: "✏️",
|
||||
},
|
||||
|
||||
{
|
||||
column: "apps",
|
||||
url: "www.solidscribe.com",
|
||||
title: "Solid Scribe",
|
||||
emoji: "🔏",
|
||||
},
|
||||
{
|
||||
column: "web",
|
||||
url: "www.wunderground.com/weather/us/az/flagstaff/KAZFLAGS335",
|
||||
title: "Weather",
|
||||
emoji: "🌦️",
|
||||
},
|
||||
|
||||
{
|
||||
column: "web",
|
||||
url: "https://mail.protonmail.com/u/0/inbox",
|
||||
title: "Proton Mail",
|
||||
emoji: "📧",
|
||||
},
|
||||
{
|
||||
column: "web",
|
||||
url: "www.amazon.com",
|
||||
title: "Amazon",
|
||||
emoji: "🛒",
|
||||
},
|
||||
{
|
||||
column: "web",
|
||||
url: "www.camelcamelcamel.com",
|
||||
title: "Camel Camel Camel",
|
||||
emoji: "🐫",
|
||||
},
|
||||
|
||||
{
|
||||
column: "apps",
|
||||
url: "spotify.com",
|
||||
title: "Spotify",
|
||||
emoji: "🎶",
|
||||
},
|
||||
{
|
||||
column: "web",
|
||||
url: "butcherbox.com",
|
||||
title: "Butcher Box",
|
||||
emoji: "📦",
|
||||
},
|
||||
{ column: "web", url: "gmail.com", title: "Gmail", emoji: "✉" },
|
||||
{
|
||||
column: "apps",
|
||||
url: "schwab.com",
|
||||
title: "Schwab",
|
||||
emoji: "🤑",
|
||||
},
|
||||
{
|
||||
column: "local",
|
||||
url: "graxday.com",
|
||||
title: "Grax Day",
|
||||
emoji: "😘",
|
||||
},
|
||||
{
|
||||
column: "web",
|
||||
url: "https://drive.google.com/drive/u/0/folders/10hsNBu0o8at687PLc5mcfDtJkhjDcwk9?ths=true",
|
||||
title: "Grax Day Docs",
|
||||
emoji: "📄",
|
||||
},
|
||||
|
||||
// {'column':'apps','url':'x.maxg.cc/code/?folder=/home/mab/ss', 'title':'Code Server', 'emoji':'🦿'},
|
||||
{
|
||||
column: "apps",
|
||||
url: "pix.maxg.cc/library/import",
|
||||
title: "PhotoPrism Import",
|
||||
emoji: "📷",
|
||||
},
|
||||
|
||||
{
|
||||
column: "apps",
|
||||
url: "http://git.maxg.cc",
|
||||
title: "Gitea",
|
||||
emoji: "🍵",
|
||||
},
|
||||
{
|
||||
column: "web",
|
||||
url: "https://forum.xda-developers.com/t/rom-13-op7pro-crdroid-v9-0-18-12-2022.4511589/page-12",
|
||||
title: "OnePlus7 ISO",
|
||||
emoji: "📱",
|
||||
},
|
||||
{
|
||||
column: "local",
|
||||
url: "https://localhost:47990/",
|
||||
title: "Sunshine",
|
||||
emoji: "☀️",
|
||||
},
|
||||
|
||||
// dumb
|
||||
{
|
||||
column: "dumb",
|
||||
url: "www.youtube.com",
|
||||
title: "Youtube",
|
||||
emoji: "📺",
|
||||
},
|
||||
{
|
||||
column: "dumb",
|
||||
url: "arstechnica.com",
|
||||
title: "ArsTechnica",
|
||||
emoji: "📰",
|
||||
},
|
||||
{
|
||||
column: "dumb",
|
||||
url: "phoronix.com",
|
||||
title: "Phoronix",
|
||||
emoji: "📰",
|
||||
},
|
||||
|
||||
{
|
||||
column: "dumb",
|
||||
url: "slashdot.org/",
|
||||
title: "Slashdot",
|
||||
emoji: "📃",
|
||||
},
|
||||
{
|
||||
column: "dumb",
|
||||
url: "imgur.com",
|
||||
title: "Imgur",
|
||||
emoji: "😺",
|
||||
},
|
||||
{
|
||||
column: "dumb",
|
||||
url: "hackaday.com",
|
||||
title: "Hack a Day",
|
||||
emoji: "☠",
|
||||
},
|
||||
{
|
||||
column: "dumb",
|
||||
url: "duckduckgo.com",
|
||||
title: "Duck Duck Go",
|
||||
emoji: "🦆",
|
||||
},
|
||||
{ column: "dumb", url: "bing.com", title: "Bing", emoji: "🦑" },
|
||||
{
|
||||
column: "dumb",
|
||||
url: "google.com",
|
||||
title: "Google",
|
||||
emoji: "🐚",
|
||||
},
|
||||
{
|
||||
column: "dumb",
|
||||
url: "https://www.etsy.com/shop/PowerfulSpell",
|
||||
title: "Powerful Spell",
|
||||
emoji: "🧚🏻",
|
||||
},
|
||||
{
|
||||
column: "dumb",
|
||||
url: "https://kbd.news/",
|
||||
title: "KBD",
|
||||
emoji: "⌨️",
|
||||
},
|
||||
{
|
||||
column: "web",
|
||||
url: "https://store.epicgames.com/en-US/free-games",
|
||||
title: "Free Game!",
|
||||
emoji: "🎮",
|
||||
},
|
||||
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
{ url: "", title: "" },
|
||||
]);
|
||||
|
||||
onMounted(() => {
|
||||
// setup autocomplete
|
||||
Object.keys(this.links).forEach((key) => {
|
||||
const link = this.links[key].url;
|
||||
if (link) {
|
||||
this.autocomplete.push(link);
|
||||
}
|
||||
});
|
||||
// remove duplicates
|
||||
// this.autocomplete = [...new Set(this.autocomplete)]
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$refs.search.focus();
|
||||
});
|
||||
});
|
||||
|
||||
function sortedLinks(inLinks, category) {
|
||||
let sortList = [];
|
||||
inLinks.forEach((link) => {
|
||||
const lowText = this.inputText.toLowerCase();
|
||||
const searchTitle = link.title.toLowerCase().includes(lowText);
|
||||
const searchUrl = link.url.toLowerCase().includes(lowText);
|
||||
const searchFilter =
|
||||
this.inputText == "" || searchTitle || searchUrl;
|
||||
|
||||
if (link.column == category && searchFilter) {
|
||||
sortList.push(link);
|
||||
}
|
||||
});
|
||||
|
||||
return sortList.sort((a, b) => {
|
||||
return a.title.localeCompare(b.title);
|
||||
});
|
||||
}
|
||||
function setupIcon(title) {
|
||||
title = title.toLowerCase().trim();
|
||||
|
||||
return icons[finalRandomIndex];
|
||||
}
|
||||
function setupUrl(inUrl) {
|
||||
if (inUrl.indexOf("http") === -1) {
|
||||
inUrl = "http://" + inUrl;
|
||||
}
|
||||
|
||||
return inUrl.trim();
|
||||
}
|
||||
function filterKeydown(e) {
|
||||
if (e.code != "Tab") {
|
||||
return;
|
||||
}
|
||||
if (e.code == "Tab") {
|
||||
e.preventDefault();
|
||||
this.suggestionIndex++;
|
||||
if (this.suggestionIndex > this.suggestions.length - 1) {
|
||||
this.suggestionIndex = 0;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
function filterLinks(e) {
|
||||
// if(e.code == 'Escape'){
|
||||
// e.preventDefault()
|
||||
// this.suggestions = []
|
||||
// this.inputText = ''
|
||||
// return
|
||||
// }
|
||||
// if(e.code == 'ArrowUp'){
|
||||
// e.preventDefault()
|
||||
// this.suggestionIndex--
|
||||
// if(this.suggestionIndex <= -1){
|
||||
// this.suggestionIndex = this.suggestions.length -1
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
// if(e.code == 'ArrowDown'){
|
||||
// e.preventDefault()
|
||||
// this.suggestionIndex++
|
||||
// if(this.suggestionIndex > this.suggestions.length-1){
|
||||
// this.suggestionIndex = 0
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
if (e.code == "Tab" || e.code == "Enter") {
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
this.suggestionIndex = -1;
|
||||
this.suggestions = [];
|
||||
|
||||
const searchString = String(e.target.value)
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace("www.", "");
|
||||
|
||||
if (searchString.length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.autocomplete.forEach((entry) => {
|
||||
const test = entry.toLowerCase().indexOf(searchString);
|
||||
if (test >= 0) {
|
||||
this.suggestions.push(entry);
|
||||
}
|
||||
});
|
||||
|
||||
this.suggestions = this.suggestions.splice(0, 2);
|
||||
}
|
||||
function webSearch(e) {
|
||||
// go to suggestion
|
||||
if (this.suggestions.length >= 1) {
|
||||
window.location.href = `https://${this.suggestions[0]}`;
|
||||
return;
|
||||
}
|
||||
|
||||
// go straight to URLs
|
||||
const urlCheck = String(e.target.value).trim();
|
||||
if (urlCheck.indexOf(".") > -1 && urlCheck.indexOf(" ") == -1) {
|
||||
let goodUrl = urlCheck.replace("http://", "").replace("www.", "");
|
||||
window.location.href = `https://www.${goodUrl}`;
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip empty strings
|
||||
if (e.target.value == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
// duck duck go search
|
||||
let webString = String(e.target.value).replaceAll(" ", "+");
|
||||
window.location.href = `https://duckduckgo.com/?hps=1&q=${webString}`;
|
||||
return;
|
||||
}
|
||||
function generateMessage(index) {
|
||||
let message = "";
|
||||
let m = [];
|
||||
|
||||
var now = new Date();
|
||||
var days = [
|
||||
"Sunday",
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday",
|
||||
];
|
||||
var months = [
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December",
|
||||
];
|
||||
|
||||
var day = days[now.getDay()];
|
||||
var month = months[now.getMonth()];
|
||||
|
||||
this.seed =
|
||||
parseInt(`${now.getMonth()}${now.getHours()}${now.getDay()}`) +
|
||||
this.clicks;
|
||||
|
||||
let weekday =
|
||||
day + ", " + month + " " + now.getDate() + "<sup>th</sup>";
|
||||
|
||||
if (index == 1) {
|
||||
m = [
|
||||
[
|
||||
"Continue",
|
||||
"Keep on",
|
||||
"Don't stop",
|
||||
"Persist",
|
||||
"Never stop",
|
||||
"Without falter keep",
|
||||
],
|
||||
[
|
||||
"Slaying",
|
||||
"Rocking",
|
||||
"Fighting",
|
||||
"murdering",
|
||||
"betraying",
|
||||
"stabbing",
|
||||
"killing",
|
||||
"dancing",
|
||||
],
|
||||
[weekday],
|
||||
];
|
||||
}
|
||||
if (index == 2 && this.seed % 2 == 0) {
|
||||
m = [
|
||||
["You", "The world", "The universe", "Your life"],
|
||||
[
|
||||
"really",
|
||||
"could be",
|
||||
"might be",
|
||||
"certainly",
|
||||
"will turn out to be",
|
||||
"will be",
|
||||
],
|
||||
[
|
||||
"tough",
|
||||
"strong",
|
||||
"a champ",
|
||||
"a bitch",
|
||||
"stronger than a bull",
|
||||
"another day",
|
||||
"a fine one",
|
||||
"sick nasty",
|
||||
],
|
||||
["."],
|
||||
["\nAll your"],
|
||||
[
|
||||
"exploits",
|
||||
"missions",
|
||||
"endeavors",
|
||||
"journeys",
|
||||
"limbs",
|
||||
"friendships",
|
||||
"meetings",
|
||||
"destinations",
|
||||
"plants",
|
||||
"thoughts",
|
||||
"dreams",
|
||||
"projects",
|
||||
],
|
||||
[
|
||||
"will",
|
||||
"could",
|
||||
"may",
|
||||
"certainly will",
|
||||
"are going to",
|
||||
"are about to",
|
||||
"will",
|
||||
"will",
|
||||
],
|
||||
[
|
||||
"succeed",
|
||||
"avail",
|
||||
"pass",
|
||||
"make good",
|
||||
"grow famous",
|
||||
"work",
|
||||
"profit",
|
||||
"reap success",
|
||||
"conquer",
|
||||
"avail",
|
||||
"thrive",
|
||||
"flourish",
|
||||
"triumph",
|
||||
],
|
||||
["."],
|
||||
];
|
||||
}
|
||||
if (index == 2 && this.seed % 2 == 1) {
|
||||
m = [
|
||||
["Things", "Stuff", "Its", "Everything"],
|
||||
["are not", "ain't", "is not"],
|
||||
["so", "that"],
|
||||
["bad", "grim", "brutal", "hard", "stuffy", "saddening"],
|
||||
[".", ".", ".", ".", ".", ".", ".", "?"],
|
||||
["\nGet", "\nRun", "\nSprint", "\nShamble"],
|
||||
["out there", "in there", "on over", "along now", "on over"],
|
||||
["and"],
|
||||
["seize", "grab", "embrace", "hug", "curb stomp", "smash"],
|
||||
["the", "those", "thine"],
|
||||
["tasty", "special", "spicy", "magical", "wicked", "powerful"],
|
||||
[
|
||||
"day",
|
||||
"goals",
|
||||
"missions",
|
||||
"pants",
|
||||
"trees",
|
||||
"dreams",
|
||||
"pants",
|
||||
"goats",
|
||||
"grundus",
|
||||
],
|
||||
["."],
|
||||
];
|
||||
}
|
||||
|
||||
m.forEach((part) => {
|
||||
// const p = part[Math.floor(Math.random() * part.length)]
|
||||
const p = part[this.seed % part.length];
|
||||
let space = " ";
|
||||
if (p == "." || p == "?") {
|
||||
space = "";
|
||||
}
|
||||
message += space + p;
|
||||
});
|
||||
|
||||
return "<span>" + message + "</span>";
|
||||
}
|
||||
function linkClick() {
|
||||
setTimeout(() => {
|
||||
console.log("Close a boy");
|
||||
window.open("", "_self").close();
|
||||
}, 250);
|
||||
}
|
||||
function onCluck() {
|
||||
console.log("hi");
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
html {
|
||||
font-family: Roboto, Helvetica Neue, Arial, Helvetica, sans-serif;
|
||||
}
|
||||
body {
|
||||
background-image: none;
|
||||
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='49' viewBox='0 0 28 49'%3E%3Cg fill-rule='evenodd'%3E%3Cg id='hexagons' fill='%239C92AC' fill-opacity='0.25' fill-rule='nonzero'%3E%3Cpath d='M13.99 9.25l13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"),
|
||||
linear-gradient(
|
||||
135deg,
|
||||
rgba(0, 0, 0, 0) 1%,
|
||||
rgba(0, 8, 70, 0.56) 60%
|
||||
),
|
||||
radial-gradient(
|
||||
circle at left bottom,
|
||||
rgb(179, 0, 193) 0%,
|
||||
rgb(0, 0, 0) 50%
|
||||
);
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
input {
|
||||
width: calc(100% - 20px);
|
||||
margin: 0 10px 15px;
|
||||
font-size: 1.4em;
|
||||
border-radius: 4px;
|
||||
outline: none;
|
||||
padding: 10px 15px;
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.message {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
color: white;
|
||||
font-size: 1.5em;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid white;
|
||||
padding: 0 0 5px 0;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.large.message {
|
||||
padding: 0 0 5px 0;
|
||||
font-size: 2em;
|
||||
border-bottom: none;
|
||||
}
|
||||
.small.message {
|
||||
padding: 5px 0 15px 0;
|
||||
font-size: 1em;
|
||||
border-bottom: none;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.center-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 80vh;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.column {
|
||||
width: 25%;
|
||||
display: inline-block;
|
||||
}
|
||||
h2 {
|
||||
text-align: center;
|
||||
color: white;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
.max-links {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
align-items: flex-start;
|
||||
align-content: space-evenly;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.flex-child {
|
||||
width: calc(100% - 10px);
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
.glass {
|
||||
background-color: rgba(255, 255, 255, 0.25);
|
||||
border-radius: 4px;
|
||||
backdrop-filter: blur(3px);
|
||||
border: 2px solid rgba(255, 255, 255, 0.1);
|
||||
color: white;
|
||||
}
|
||||
.max-link {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
background-color: rgba(255, 255, 255, 0.25);
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
font-size: 0.8em;
|
||||
padding: 10px 10px;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
word-break: break-word;
|
||||
backdrop-filter: blur(2px);
|
||||
/* border: 2px solid rgba(255,255,255,0.1);*/
|
||||
font-size: 1.1em;
|
||||
}
|
||||
.max-link:hover {
|
||||
transition: all 0.4s ease-out;
|
||||
/* background-color: #35004d;*/
|
||||
backdrop-filter: blur(7px);
|
||||
}
|
||||
.visual-aid {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
margin: 0 5px 0 0;
|
||||
}
|
||||
|
||||
.text-box {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
.suggestions {
|
||||
display: inline-block;
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
top: 49px;
|
||||
left: 0px;
|
||||
right: 0;
|
||||
z-index: 2;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
margin: 0 10px 0;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0px 4px 3px 0px gray;
|
||||
|
||||
background-color: rgba(255, 255, 255, 0.25);
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
.suggestion {
|
||||
display: inline-block;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
color: white;
|
||||
}
|
||||
.suggestion.active {
|
||||
background-color: purple;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nose,
|
||||
.lip,
|
||||
.eye {
|
||||
display: inline-block;
|
||||
background-color: rgba(255, 255, 255, 0.18);
|
||||
border-radius: 4px;
|
||||
padding: 5px 10px;
|
||||
backdrop-filter: blur(3px);
|
||||
border: 2px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.lip {
|
||||
width: calc(100% - 35px);
|
||||
}
|
||||
.lip.one {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
.max-links {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 992px) {
|
||||
.max-links {
|
||||
width: 70%;
|
||||
}
|
||||
}
|
||||
</style>
|
709
pages/index.vue
Normal file
709
pages/index.vue
Normal file
@@ -0,0 +1,709 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- resume box -->
|
||||
<div
|
||||
class="container mx-auto flex flex-row flex-wrap max-w-none md:max-w-5xl bg-white paper my-5"
|
||||
>
|
||||
<div
|
||||
class="w-full md:w-7/12 flex flex-col items-center justify-center fade-in"
|
||||
>
|
||||
<div class="p-6 pb-1 md:text-center text-sm md:text-base">
|
||||
<p class="text-5xl md:text-6xl">Max Gialanella</p>
|
||||
<p class="py-3">
|
||||
Full stack engineer with a decade of professional
|
||||
experience.
|
||||
<br />Passionate about web technologies & creative
|
||||
problem solving.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="w-full md:w-5/12 flex flex-row justify-around items-center pt-6 fade-in"
|
||||
>
|
||||
<div class="pl-1 pr-3 bg-zinc-50 rounded-md shadow-sm">
|
||||
<img
|
||||
src="/maxhead.png"
|
||||
alt="Max head photo"
|
||||
class="object-cover h-auto w-[150px]"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col justify-start gap-2 text-sm md:text-base"
|
||||
>
|
||||
<div>
|
||||
<EnvelopeIcon class="h-4 w-4 inline subtle" />
|
||||
<a target="_blank" href="mailto:maxjobhunt@pm.me">
|
||||
MaxJobHunt@pm.me
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<PhoneIcon class="h-4 w-4 inline subtle" />
|
||||
<a target="_blank" href="tel:480-788-5217">
|
||||
(480) 788-5217
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<MapPinIcon class="h-4 w-4 inline subtle" />
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://goo.gl/maps/smMV1RZ3pZrS6C1y7"
|
||||
>
|
||||
Flagstaff, AZ
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w-full md:w-7/12 fade-in d1">
|
||||
<!-- astound -->
|
||||
<div class="p-6 pb-1">
|
||||
<div class="w-full flex justify-between border-b accent">
|
||||
<div>Astound Commerce</div>
|
||||
<div class="text-s text-zinc-600">2021-2023</div>
|
||||
</div>
|
||||
<p class="font-bold py-2">
|
||||
Software Engineer - Salesforce Commerce Cloud
|
||||
</p>
|
||||
<p>
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Launched a new SFCC, online storefront for
|
||||
<a href="https://www.rag-bone.com" target="_blank"
|
||||
>Rag & Bone</a
|
||||
>
|
||||
using Typescript, Node.JS and other JS technologies.
|
||||
Updated & streamlined, domestic and international
|
||||
payments before a big sale which facilitated millions in
|
||||
new revenue.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- rws -->
|
||||
<div class="p-6 pb-1">
|
||||
<div class="w-full flex justify-between border-b accent">
|
||||
<div>RWS - IP Services</div>
|
||||
<div class="text-s text-zinc-600">2018 - 2021</div>
|
||||
</div>
|
||||
<p class="font-bold pt-2">Senior Software Engineer</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />Worked
|
||||
with partners to build a suite of internal tools.
|
||||
Including custom systems for time tracking, invoicing, a
|
||||
live cardwall, dashboards, forms with intelligent
|
||||
validation, extensive reporting and tools allowing for
|
||||
mass data import and export.
|
||||
</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Worked with managers to create a sophisticated, dynamic
|
||||
form-building system that enabled clients to input
|
||||
custom data with intelligent auto-complete rules per
|
||||
client, removing the need for Marketing and
|
||||
Administrative interaction.
|
||||
</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Fully rebuilt nine legacy, Single Page Applications.
|
||||
Worked directly with managers and QA to scope out all
|
||||
existing functionality, then wrote scalable
|
||||
replacements.
|
||||
</p>
|
||||
|
||||
<p class="font-bold pt-2">Lead Software Engineer</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Lead a team of developers in system design and releases.
|
||||
Pushed for improved standards in communication &
|
||||
quality.
|
||||
</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Leveraged Azure Pipelines and Bash to stand up a DevOps
|
||||
suite that automated builds, package management, version
|
||||
control, source compression and dev, stage & prod
|
||||
releases.
|
||||
</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Created a highly performant, browser-based PDF
|
||||
annotation & highlighting system with Vue. Annotations
|
||||
were converted to images and OCR'd for searching,
|
||||
allowing for cataloging of highlighted data across
|
||||
thousands of documents.
|
||||
</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Created an email invite tool to orchestrate sending
|
||||
thousands of emails, inviting specific users based on
|
||||
various attributes, reporting stats, tracking user
|
||||
engagement and managing email queues. Which resulted in
|
||||
increased product engagement.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- article one -->
|
||||
<div class="p-6 pb-1">
|
||||
<div class="w-full flex justify-between border-b accent">
|
||||
<div>Article One Partners</div>
|
||||
<div class="text-s text-zinc-600">2013 - 2018</div>
|
||||
</div>
|
||||
<p class="font-bold pt-2">Software Engineer</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Rewrote outdated jQuery UI font end in Vue.
|
||||
</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Worked to migrate system from PHP 5 to 7.
|
||||
</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Migrated legacy file system to Azure cloud. Integrated
|
||||
new packages from PHP to Node.
|
||||
</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Updated systems to be GDPR compliant with intelligent
|
||||
data purging and greater respect for user privacy and
|
||||
control.
|
||||
</p>
|
||||
<p class="font-bold pt-2">JR Software Engineer</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Update old system to use dynamic template engine and
|
||||
Doctrine ORM.
|
||||
</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Integrated system with external APIs.
|
||||
</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Updated front-end with new CSS styles and libraries for
|
||||
modern and responsive web.
|
||||
</p>
|
||||
<p class="py-2">
|
||||
<ChevronRightIcon class="w-3 h-3 accent inline" />
|
||||
Learned to apply GIT, Agile, bash, and modern web
|
||||
standards.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- skills column -->
|
||||
<div class="w-full md:w-5/12 skills p-6 fade-in d2">
|
||||
<p class="w-full border-b accent">Primary Skills</p>
|
||||
<p>
|
||||
Javascript ES6, Node.js, NPM
|
||||
<span class="years">10</span>
|
||||
</p>
|
||||
<p>
|
||||
Vue, UI, UX
|
||||
<span class="years">14</span>
|
||||
</p>
|
||||
<p>
|
||||
HTML5, CCS3
|
||||
<span class="years">15</span>
|
||||
</p>
|
||||
<p>
|
||||
Linux, Bash
|
||||
<span class="years">10</span>
|
||||
</p>
|
||||
<p>
|
||||
GIT, SVN
|
||||
<span class="years">8</span>
|
||||
</p>
|
||||
<p>
|
||||
MySQL
|
||||
<span class="years">10</span>
|
||||
</p>
|
||||
<p>
|
||||
Agile, SCRUM
|
||||
<span class="years">8</span>
|
||||
</p>
|
||||
<p>
|
||||
OO Design, Architecture, MVC
|
||||
<span class="years">10</span>
|
||||
</p>
|
||||
<p>
|
||||
RESTful, SOAP APIs, SaaS
|
||||
<span class="years">8</span>
|
||||
</p>
|
||||
<p>
|
||||
Azure DevOps, CI/CD
|
||||
<span class="years">4</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
PHP, Zend 2, Composer
|
||||
<span class="years">6</span>
|
||||
</p>
|
||||
|
||||
<p class="w-full border-b accent">Secondary Skills</p>
|
||||
<p>
|
||||
Python, Java
|
||||
<span class="years">8</span>
|
||||
</p>
|
||||
<p>
|
||||
React, Angular, jQuery
|
||||
<span class="years">7</span>
|
||||
</p>
|
||||
<p>Salesforce Commerce Cloud</p>
|
||||
|
||||
<p class="w-full border-b accent">Certifications</p>
|
||||
<p>Salesforce Javascript Developer</p>
|
||||
<p>Salesforce B2C Commerce Developer</p>
|
||||
<!-- <a href="https://trailblazer.me/id/mgialanella" target="_blank">View Certifications</a> -->
|
||||
|
||||
<p class="w-full border-b accent">Education</p>
|
||||
<p>
|
||||
BS - Computer Science<br />University of Massachusets
|
||||
Amherset
|
||||
</p>
|
||||
|
||||
<p class="w-full border-b accent">Passions</p>
|
||||
<p>
|
||||
Building
|
||||
<a
|
||||
href="http://blog.maxg.cc/2023/02/22/pc-builds/"
|
||||
target="_blank"
|
||||
>PCs</a
|
||||
>
|
||||
&
|
||||
<a
|
||||
href="http://blog.maxg.cc/2023/01/11/Build-a-Keyboard-Links/#My-Builds"
|
||||
>Keyboards</a
|
||||
>
|
||||
</p>
|
||||
<p>Cooking, Diet, Nutrition</p>
|
||||
<p>Brazilian Jiu-Jitsu, Ultimate Frisbee</p>
|
||||
<p>Coffee Snobbery</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- pagebreak for pdf -->
|
||||
<div class="pagebreak"></div>
|
||||
|
||||
<div class="w-fill p-4 pb-10 flex justify-center">
|
||||
<a
|
||||
href="/resume.pdf"
|
||||
class="flex flex-row border border-zinc-200 shadow-lg rounded-md px-4 py-2 bg-white"
|
||||
>
|
||||
<div class="flex items-center pr-4">
|
||||
<FolderArrowDownIcon class="w-8 h-8 accent inline" />
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-base">Download Resume</p>
|
||||
<p class="text-zinc-500 text-xs">.PDF Format</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div v-if="false">
|
||||
TODO
|
||||
<p>Change Resume Mode - General, Frontend, Backend</p>
|
||||
<p>Finish Blog Articles</p>
|
||||
<p>Optimize for mobile</p>
|
||||
<p>Dark Mode</p>
|
||||
</div>
|
||||
|
||||
<!-- headshot and overview -->
|
||||
<div class="w-full bg-gradient-to-tr from-slate-100 to-teal-50">
|
||||
<div class="w-full md:max-w-5xl m-auto flex flex-row flex-wrap">
|
||||
<!-- info and downloads -->
|
||||
<div class="w-6/12 flex flex-col justify-center">
|
||||
<div class="border-l-4 border-l-zinc-400">
|
||||
<h1 class="text-2xl md:text-4xl pl-5">
|
||||
Software is a
|
||||
<span class="text-blue-600">passion</span>.
|
||||
</h1>
|
||||
<h2 class="text-2xl md:text-3xl pl-5">
|
||||
I'll never stop building cool things.
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="p-4"></div>
|
||||
|
||||
<div class="pl-4">
|
||||
<p>Dig Deeper</p>
|
||||
<p>
|
||||
Connect with me on Linkedin
|
||||
<a
|
||||
href="https://www.linkedin.com/in/max-g-856a2555"
|
||||
>
|
||||
<CursorArrowRippleIcon
|
||||
class="w-8 h-8 accent inline"
|
||||
/>
|
||||
Linkedin
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<!-- <p>Learn More about my Frontend work</p>
|
||||
<p>Link to frontend</p>
|
||||
<p>Learn More about my backed work</p>
|
||||
<p>Link to backend</p> -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- headshot -->
|
||||
<div class="w-6/12 flex justify-center">
|
||||
<div class="imgcropper">
|
||||
<img
|
||||
src="/maxheadcolor.png"
|
||||
alt="Max Gialanella"
|
||||
class="object-cover max-w-[300px] h-auto"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- marketing box -->
|
||||
<div class="w-full bg-slate-200">
|
||||
<div class="p-4 w-full md:max-w-5xl m-auto pt-10">
|
||||
<h1 class="text-3xl">Personal Projects</h1>
|
||||
<p class="text-zinc-500">
|
||||
Recent Examples of Professional software and passion
|
||||
projects.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-row flex-wrap">
|
||||
<div class="w-full bg-slate-200 pb-10">
|
||||
<div
|
||||
class="flex flex-row flex-wrap items-stretch justify-around max-w-none md:max-w-5xl m-auto"
|
||||
>
|
||||
<NuxtLink
|
||||
v-for="(p, index) in projects"
|
||||
class="w-full md:w-4/12 p-4 cursor-pointer"
|
||||
:to="p[3]"
|
||||
>
|
||||
<div
|
||||
class="border border-zinc-200 rounded-lg overflow-hidden shadow-md bg-slate-100"
|
||||
>
|
||||
<!-- {{ p[2] }} -->
|
||||
<div
|
||||
class="min-h-[80px] overflow-hidden flex justify-center items-center"
|
||||
:class="`bg${index + 1}`"
|
||||
>
|
||||
<img
|
||||
:src="p[2]"
|
||||
alt="cover"
|
||||
class="object-cover w-auto h-[150px] bigskew"
|
||||
/>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<p class="text-zinc-900 text-lg">{{ p[0] }}</p>
|
||||
<p
|
||||
class="pt-2 text-sm min-h-[80px] text-zinc-600"
|
||||
>
|
||||
<ChevronRightIcon
|
||||
class="w-3 h-3 accent inline"
|
||||
/>
|
||||
{{ p[1] }}
|
||||
</p>
|
||||
<p
|
||||
class="text-sm w-full text-right accent pt-2"
|
||||
>
|
||||
Explore
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w-full overflow-hidden relative bg-black">
|
||||
<div
|
||||
class="w-full md:max-w-5xl m-auto flex flex-row flex-wrap z-20"
|
||||
>
|
||||
<!-- info and downloads -->
|
||||
<div
|
||||
class="w-4/12 md:w-6/12 flex justify-center items-end overflow-hidden h-[280px]"
|
||||
>
|
||||
<img
|
||||
src="/callme.png"
|
||||
alt="Max head photo"
|
||||
class="object-cover w-auto h-[340px] imgcropper-right"
|
||||
/>
|
||||
</div>
|
||||
<!-- headshot -->
|
||||
<div
|
||||
class="w-8/12 md:w-6/12 flex flex-col justify-center items-start text-white pl-5"
|
||||
>
|
||||
<p class="text-xl md:text-3xl font-bold pb-5">
|
||||
Lets Chat. Anytime. Anywhere.
|
||||
</p>
|
||||
<div class="border-l-4 border-l-zinc-600 pl-4">
|
||||
<p>Call me</p>
|
||||
<PhoneIcon class="h-4 w-4 inline" />
|
||||
<a
|
||||
target="_blank"
|
||||
href="tel:480-788-5217"
|
||||
class="text-white"
|
||||
>
|
||||
(480) 788-5217
|
||||
</a>
|
||||
</div>
|
||||
<div class="p-4"></div>
|
||||
<div class="border-l-4 border-l-zinc-600 pl-4">
|
||||
<p>Email me and schedule a meeting</p>
|
||||
<EnvelopeIcon class="h-4 w-4 inline" />
|
||||
<a
|
||||
target="_blank"
|
||||
href="mailto:maxjobhunt@pm.me"
|
||||
class="text-white"
|
||||
>
|
||||
MaxJobHunt@pm.me
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space1"></div>
|
||||
<div class="space2"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
BeakerIcon,
|
||||
MapPinIcon,
|
||||
EnvelopeIcon,
|
||||
PhoneIcon,
|
||||
PaperClipIcon,
|
||||
ChevronRightIcon,
|
||||
FolderArrowDownIcon,
|
||||
CursorArrowRippleIcon,
|
||||
} from "@heroicons/vue/24/outline";
|
||||
|
||||
const projects = [
|
||||
[
|
||||
"Ravenwulf Consulting",
|
||||
"Marketing site I built for a consulting firm. I designed the logo and identity. Built using Tailwind, Nuxt.js and hosted on Cloudflare.",
|
||||
"/covers/ravenwulficon.png",
|
||||
"/blog/creation-of-ravenwulf",
|
||||
],
|
||||
[
|
||||
"Solid Scribe",
|
||||
"Encrypted note taking application I designed and built. Uses applied cryptography and web-sockets for a convenient and secure experience.",
|
||||
"/covers/solidscribeicon.svg",
|
||||
"/blog/building-solid-scribe",
|
||||
],
|
||||
[
|
||||
"Chat GPT Autocomplete",
|
||||
"Scripts to access chatGPT for instantly generated code snippets. Allowing for rapid prototyping and development.",
|
||||
"/covers/gpticon.png",
|
||||
"https://git.maxg.cc/max/ChatGPTAutocomplete",
|
||||
],
|
||||
[
|
||||
"Atreyu Custom Keyboard",
|
||||
"Affordable and sleek ergonomic keyboard with custom firmware",
|
||||
"/covers/atreyuicon.png",
|
||||
"/blog/atreyu-keyboard",
|
||||
],
|
||||
[
|
||||
"Personal Git Repo",
|
||||
"Examine more of my work on my self hosted git repository.",
|
||||
"/covers/giticon.png",
|
||||
"https://git.maxg.cc/max",
|
||||
],
|
||||
[
|
||||
"Personal Blog",
|
||||
"Personal Blog where I post about tech topics.",
|
||||
"/covers/blogicon.png",
|
||||
"https://blog.maxg.cc/",
|
||||
],
|
||||
];
|
||||
|
||||
onMounted(() => {
|
||||
// generate stars
|
||||
function randomNumber(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
const STAR_COUNT = 180;
|
||||
const shades = ["#e0e0e0", "#e0e0e0", "#bdbdbd", "#bdbdbd", "#484848"];
|
||||
|
||||
for (var j = 1; j < 3; j++) {
|
||||
let result = "";
|
||||
for (let i = 0; i < STAR_COUNT; i++) {
|
||||
const shade = shades[Math.floor(Math.random() * shades.length)];
|
||||
result += `${randomNumber(-50, 50)}vw ${randomNumber(
|
||||
-50,
|
||||
50
|
||||
)}vh ${randomNumber(0, 1)}px ${randomNumber(0, 1)}px ${shade},`;
|
||||
}
|
||||
document.documentElement.style.setProperty(
|
||||
"--random-stars" + j,
|
||||
result.substring(0, result.length - 1)
|
||||
);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #d0b24d;
|
||||
--color-hint: #515151;
|
||||
--border: #ccc;
|
||||
|
||||
--duration: 30;
|
||||
--rp1: 20;
|
||||
--rp2: 72;
|
||||
--rp3: 1;
|
||||
--rp4: 2;
|
||||
--rp5: 3;
|
||||
--rp6: 4;
|
||||
|
||||
--ray-rotate: 26deg;
|
||||
|
||||
--shift: 3;
|
||||
--x: 0;
|
||||
--y: 0;
|
||||
--random-stars1: 0;
|
||||
--random-stars2: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
@apply text-blue-600 border-zinc-300;
|
||||
}
|
||||
.accent {
|
||||
@apply text-blue-600 border-zinc-300;
|
||||
}
|
||||
.subtle {
|
||||
@apply text-zinc-600;
|
||||
}
|
||||
.years {
|
||||
display: none;
|
||||
}
|
||||
.skills p + p {
|
||||
padding: 7px 0 0 0;
|
||||
}
|
||||
.space1,
|
||||
.space2 {
|
||||
/* position: fixed; */
|
||||
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
right: -1px;
|
||||
bottom: -1px;
|
||||
z-index: 1;
|
||||
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
border-radius: 100%;
|
||||
|
||||
--shift: -2;
|
||||
--shift-px: calc(var(--shift) * 1px);
|
||||
transform: translateX(calc((100vw - var(--x) * var(--shift-px)) / 90))
|
||||
translateY(calc((100vh - var(--y) * var(--shift-px)) / 90));
|
||||
|
||||
/* background: radial-gradient(circle, rgba(0,0,0,1) 20%, rgba(47,47,47,1) 100%);*/
|
||||
box-shadow: var(--random-stars1);
|
||||
}
|
||||
.space2 {
|
||||
box-shadow: var(--random-stars2);
|
||||
animation: zoom 50s alternate infinite;
|
||||
}
|
||||
|
||||
@keyframes zoom {
|
||||
0% {
|
||||
transform: scale(0.6);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
.bg1 {
|
||||
@apply bg-gradient-to-tr from-slate-900 to-teal-500;
|
||||
}
|
||||
.bg2 {
|
||||
@apply bg-gradient-to-tr from-slate-900 to-cyan-500;
|
||||
}
|
||||
.bg3 {
|
||||
@apply bg-gradient-to-tr from-slate-900 to-blue-500;
|
||||
}
|
||||
.bg4 {
|
||||
@apply bg-gradient-to-tr from-slate-900 to-violet-500;
|
||||
}
|
||||
.bg5 {
|
||||
@apply bg-gradient-to-tr from-slate-900 to-fuchsia-500;
|
||||
}
|
||||
.bg6 {
|
||||
@apply bg-gradient-to-tr from-slate-900 to-pink-500;
|
||||
}
|
||||
|
||||
.bigskew {
|
||||
transform: scale(0.85);
|
||||
transition: all 1s ease;
|
||||
|
||||
filter: drop-shadow(1px 1px 0.2px rgba(255, 255, 255, 0.503))
|
||||
drop-shadow(-1px 1px 0.2px rgba(255, 255, 255, 0.503))
|
||||
drop-shadow(1px -1px 0.2px rgba(255, 255, 255, 0.503))
|
||||
drop-shadow(-1px -1px 0.2px rgba(255, 255, 255, 0.503));
|
||||
}
|
||||
a:hover .bigskew {
|
||||
transform: scale(1);
|
||||
transition: all 1s ease;
|
||||
}
|
||||
|
||||
.paper {
|
||||
background: #fff;
|
||||
box-shadow: 0 -1px 1px rgba(0, 0, 0, 0.15), 0 -10px 0 -5px #eee,
|
||||
0 -10px 1px -4px rgba(0, 0, 0, 0.15), 0 -20px 0 -10px #eee,
|
||||
0 -20px 1px -9px rgba(0, 0, 0, 0.15);
|
||||
padding-bottom: 30px;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
.imgcropper {
|
||||
overflow: hidden;
|
||||
border-radius: 20px 0 100px;
|
||||
}
|
||||
.imgcropper-right {
|
||||
overflow: hidden;
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation-duration: 0.6s;
|
||||
animation-name: fadeIn;
|
||||
animation-timing-function: ease-in-out;
|
||||
animation-fill-mode: forwards;
|
||||
opacity: 0;
|
||||
}
|
||||
@keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translate3d(0, 20px, 0);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.d1 {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
.d2 {
|
||||
animation-delay: 0.8s;
|
||||
}
|
||||
|
||||
/* styles for printing as pdf */
|
||||
@media print {
|
||||
.pagebreak {
|
||||
page-break-before: always;
|
||||
}
|
||||
.paper {
|
||||
box-shadow: none;
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user