Major Redesign.... Again
All checks were successful
Build Site / Build-Site (18.x) (push) Successful in 50s
All checks were successful
Build Site / Build-Site (18.x) (push) Successful in 50s
This commit is contained in:
parent
8fa85ed6ac
commit
cc848bf06f
@ -22,5 +22,8 @@
|
||||
"svelte": "^3.55.0",
|
||||
"tailwindcss": "^3.3.1",
|
||||
"theme-change": "^2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.5.9"
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,12 @@
|
||||
<footer class="p-4">
|
||||
<p class="text-sm text-center">© 2023 Thomas Cole.</p>
|
||||
---
|
||||
import SocialLinks from "./nav/SocialLinks.astro";
|
||||
|
||||
---
|
||||
|
||||
<footer class="text-gray-600 dark:text-gray-400 body-font">
|
||||
<div class="container flex flex-col items-center px-5 py-8 mx-auto place-content-center sm:flex-row">
|
||||
<p class="mt-4 text-sm text-gray-500 align-middle dark:text-gray-400">© 2023
|
||||
Thomas Cole</p>
|
||||
<SocialLinks />
|
||||
</div>
|
||||
</footer>
|
@ -1,23 +1,33 @@
|
||||
---
|
||||
export interface Props {
|
||||
title: string;
|
||||
subtitle: string;
|
||||
image: string;
|
||||
link: string;
|
||||
}
|
||||
export interface Props {
|
||||
title: string;
|
||||
subtitle: string;
|
||||
image: string;
|
||||
link: string;
|
||||
category: string;
|
||||
date: string;
|
||||
}
|
||||
|
||||
const { title, subtitle, image, link } = Astro.props;
|
||||
const { title, subtitle, image, link, category, date } = Astro.props;
|
||||
---
|
||||
|
||||
|
||||
<div class="rounded-lg ">
|
||||
<a href={link}>
|
||||
<div class="flex flex-col w-11/12 mx-auto my-2 sm:flex-col md:flex-col lg:flex-row xl:flex-row 2xl:flex-row">
|
||||
<img class="object-cover my-2 rounded-lg h-44 lg:h-28 xl:h-28 aspect-video" src={image} alt="" loading="lazy">
|
||||
<div class="lg:ml-4 xl:ml-4 2xl:ml-4 grow">
|
||||
<p class="py-2 mt-2 text-2xl font-semibold sm:text-2xl md:text-2xl lg:text-3xl xl:text-3xl 2xl:text-3xl">{title}</p>
|
||||
<p>{subtitle}</p>
|
||||
<div class="p-4 md:w-1/3">
|
||||
<div class="h-full overflow-hidden border-2 border-gray-200 rounded-lg dark:border-gray-800 dark:bg-gray-800 border-opacity-60">
|
||||
<img class="object-cover object-center w-full lg:h-48 md:h-36" src={image} alt="blog" draggable="false">
|
||||
<div class="p-6">
|
||||
<h2 class="mb-1 text-xs font-medium tracking-widest text-gray-400 dark:text-gray-500 title-font">{category}</h2>
|
||||
<h1 class="mb-3 text-lg font-medium text-gray-900 title-font dark:text-white">{title}</h1>
|
||||
<p class="mb-3 leading-relaxed">{subtitle}</p>
|
||||
<div class="flex flex-wrap items-center ">
|
||||
<a href={link} class="inline-flex items-center text-indigo-500 md:mb-2 lg:mb-0">Read
|
||||
<svg class="w-4 h-4 ml-2" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M5 12h14"></path>
|
||||
<path d="M12 5l7 7-7 7"></path>
|
||||
</svg>
|
||||
</a>
|
||||
<span class="text-sm leading-none text-right text-gray-400 grow">{date}</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
@ -1,19 +1,29 @@
|
||||
<!-- Could be remade as svelte component.
|
||||
For the 3 lines of javascript needed I think its okay to use a script tag -->
|
||||
<script>
|
||||
let theme = localStorage.getItem("theme");
|
||||
if (theme == "business") {
|
||||
document.getElementById("themetoggle").checked = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<label class="transition ease-in-out swap swap-rotate hover:scale-125">
|
||||
<!-- this hidden checkbox controls the state -->
|
||||
<input id="themetoggle" type="checkbox" data-toggle-theme="business,corporate" />
|
||||
<span class="mx-2 swap-off material-symbols-outlined">
|
||||
light_mode
|
||||
</span>
|
||||
<span class="mx-2 swap-on material-symbols-outlined">
|
||||
<input id="themetoggle" type="checkbox" onchange="updateTheme()" />
|
||||
<span class="swap-off material-symbols-outlined">
|
||||
dark_mode
|
||||
</span>
|
||||
</label>
|
||||
<span class="swap-on material-symbols-outlined">
|
||||
light_mode
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<script is:inline>
|
||||
let toggle = document.getElementById("themetoggle");
|
||||
|
||||
if (localStorage.theme === 'light') {
|
||||
toggle.checked = true;
|
||||
}
|
||||
|
||||
function updateTheme() {
|
||||
if (toggle.checked) {
|
||||
document.documentElement.classList.remove('dark')
|
||||
localStorage.setItem("theme", "light");
|
||||
} else {
|
||||
document.documentElement.classList.add('dark')
|
||||
localStorage.setItem("theme", "dark");
|
||||
};
|
||||
window.dispatchEvent(new Event("themeupdate"));
|
||||
}
|
||||
</script>
|
@ -1,96 +1,30 @@
|
||||
---
|
||||
export interface Props {
|
||||
pageName?: string;
|
||||
}
|
||||
export interface Props {
|
||||
pageName?: string;
|
||||
}
|
||||
|
||||
import Divider from "../misc/Divider.astro";
|
||||
import SocialLinks from "./SocialLinks.astro";
|
||||
import ThemeToggle from "../misc/ThemeToggle.astro";
|
||||
|
||||
const { pageName } = Astro.props;
|
||||
let displayedName = "";
|
||||
if (pageName) {
|
||||
displayedName = pageName.replace("|", "").trim();
|
||||
}
|
||||
const { pageName } = Astro.props;
|
||||
let displayedName = "";
|
||||
if (pageName) {
|
||||
displayedName = pageName.replace("|", "").trim();
|
||||
}
|
||||
---
|
||||
|
||||
<style>
|
||||
[data-shown="true"] {
|
||||
transform: translateX(0);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="menu" data-shown=""
|
||||
class="fixed top-0 left-0 z-50 flex flex-col h-screen p-4 transition-all duration-100 -translate-x-full w-72 bg-base-200 lg:translate-x-0 xl:translate-x-0">
|
||||
|
||||
<button id="menu-close" class="absolute top-0 right-0 p-2 lg:hidden">
|
||||
<span class="material-symbols-outlined">
|
||||
close
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<a href="/">
|
||||
<div class="block w-1/2 mx-auto mt-2 mb-2 transition ease-in-out hover:scale-105">
|
||||
<img class="object-cover w-full rounded-full aspect-square" src="/img/profile.jpg" alt="">
|
||||
</div>
|
||||
<header class="text-gray-600 dark:text-gray-400 body-font">
|
||||
<div class="container flex flex-col flex-wrap items-center p-5 mx-auto md:flex-row">
|
||||
<a href="/" class="flex items-center mb-4 font-medium text-gray-900 title-font dark:text-white md:mb-0">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-10 h-10 p-2 text-white bg-indigo-500 rounded-full" viewBox="0 0 24 24">
|
||||
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path>
|
||||
</svg>
|
||||
<span class="ml-3 text-xl">thomaspcole.com</span>
|
||||
</a>
|
||||
|
||||
<SocialLinks />
|
||||
<Divider />
|
||||
|
||||
<ul>
|
||||
<li class="flex flex-col">
|
||||
<a href="/" class="w-full duration-200 ease-in-out rounded hover:bg-base-100 transation">
|
||||
<button class="p-2">Home</button>
|
||||
</a>
|
||||
</li>
|
||||
<li class="flex">
|
||||
<a href="/projects/1" class="w-full duration-200 ease-in-out rounded hover:bg-base-100 transation">
|
||||
<button class="p-2">Projects</button>
|
||||
</a>
|
||||
</li>
|
||||
<li class="flex">
|
||||
<a href="/resume" class="w-full duration-200 ease-in-out rounded hover:bg-base-100 transation">
|
||||
<button class="p-2">Resume/CV</button>
|
||||
</a>
|
||||
</li>
|
||||
<li class="flex">
|
||||
<a href="/contact" class="w-full duration-200 ease-in-out rounded hover:bg-base-100 transation">
|
||||
<button class="p-2">Contact</button>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<Divider />
|
||||
<div class="grow"></div>
|
||||
</div>
|
||||
|
||||
<div class="flex w-full h-12 text-left transition-all duration-100 lg:hidden xl:hidden bg-base-200">
|
||||
<button id="menubtn" class="w-12 h-12">
|
||||
<span class="mt-1 material-symbols-outlined">
|
||||
menu
|
||||
</span>
|
||||
</button>
|
||||
<p class="mx-auto my-auto text-xl font-semibold -translate-x-1/2">{displayedName}</p>
|
||||
</div>
|
||||
|
||||
<div id="draweroverlay" class="hidden fixed top-0 left-0 w-full h-[100vh] z-10 bg-black/50" />
|
||||
|
||||
<script is:inline>
|
||||
const btn = document.getElementById("menubtn");
|
||||
const menu = document.getElementById("menu");
|
||||
const closebtn = document.getElementById("menu-close")
|
||||
const draweroverlay = document.getElementById("draweroverlay")
|
||||
|
||||
btn.addEventListener('click', () => {
|
||||
menu.dataset.shown = "true";
|
||||
draweroverlay.classList.remove("hidden");
|
||||
});
|
||||
|
||||
closebtn.addEventListener('click', closeMenu);
|
||||
draweroverlay.addEventListener('click', closeMenu);
|
||||
|
||||
function closeMenu() {
|
||||
menu.dataset.shown = "false";
|
||||
draweroverlay.classList.add("hidden");
|
||||
}
|
||||
</script>
|
||||
<nav class="flex flex-wrap items-center justify-center text-base md:ml-auto">
|
||||
<a href="/projects/1" class="mr-5 hover:text-gray-900 dark:hover:text-white">Projects</a>
|
||||
<a href="/about" class="mr-5 hover:text-gray-900 dark:hover:text-white">About</a>
|
||||
<a href="/contact" class="mr-5 hover:text-gray-900 dark:hover:text-white">Contact</a>
|
||||
<ThemeToggle/>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
@ -1,11 +1,6 @@
|
||||
---
|
||||
import ThemeToggle from "../misc/ThemeToggle.astro";
|
||||
---
|
||||
|
||||
<div class="flex mt-4 place-content-center">
|
||||
<a class="mx-2" href="https://git.thomaspcole.com/thomascole">
|
||||
<svg class="inline-block transition ease-in-out w-7 h-7 hover:scale-125" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
version="1.1" id="main_outline" viewBox="0 0 640 640" xml:space="preserve">
|
||||
<span class="inline-flex justify-center mt-4 sm:justify-start sm:ml-auto">
|
||||
<a class="ml-3 text-gray-500 dark:text-gray-400" href="https://git.thomaspcole.com/thomascole">
|
||||
<svg class="w-5 h-5" id="main_outline" viewBox="0 0 640 550" xml:space="preserve" stroke="currentColor">
|
||||
<g>
|
||||
<path id="teabag" class="fill-none"
|
||||
d="M395.9,484.2l-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5,21.2-17.9,33.8-11.8 c17.2,8.3,27.1,13,27.1,13l-0.1-109.2l16.7-0.1l0.1,117.1c0,0,57.4,24.2,83.1,40.1c3.7,2.3,10.2,6.8,12.9,14.4 c2.1,6.1,2,13.1-1,19.3l-61,126.9C423.6,484.9,408.4,490.3,395.9,484.2z" />
|
||||
@ -20,23 +15,19 @@ import ThemeToggle from "../misc/ThemeToggle.astro";
|
||||
</g>
|
||||
</svg>
|
||||
</a>
|
||||
<a class="mx-2" href="https://github.com/thomaspcole">
|
||||
<svg class="inline-block w-6 h-6 transition ease-in-out fill-current hover:scale-125" viewBox="0 0 96 98" xmlns="http://www.w3.org/2000/svg">
|
||||
<a class="ml-3 text-gray-500 dark:text-gray-400" href="https://github.com/thomaspcole">
|
||||
<svg class="w-5 h-5" viewBox="0 0 98 96" fill="currentColor" stroke="currentColor" stroke-linecap="round"
|
||||
stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" />
|
||||
</svg>
|
||||
</a>
|
||||
<a class="mx-2" href="https://www.linkedin.com/in/thomaspcole">
|
||||
<svg class="inline-block w-6 h-6 transition ease-in-out fill-current hover:scale-125" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 455 455"
|
||||
style="enable-background:new 0 0 455 455;" xml:space="preserve">
|
||||
<g>
|
||||
<path style="fill-rule:evenodd;clip-rule:evenodd;"
|
||||
d="M246.4,204.35v-0.665c-0.136,0.223-0.324,0.446-0.442,0.665H246.4z" />
|
||||
<path style="fill-rule:evenodd;clip-rule:evenodd;"
|
||||
d="M0,0v455h455V0H0z M141.522,378.002H74.016V174.906h67.506V378.002z M107.769,147.186h-0.446C84.678,147.186,70,131.585,70,112.085c0-19.928,15.107-35.087,38.211-35.087 c23.109,0,37.31,15.159,37.752,35.087C145.963,131.585,131.32,147.186,107.769,147.186z M385,378.002h-67.524V269.345 c0-27.291-9.756-45.92-34.195-45.92c-18.664,0-29.755,12.543-34.641,24.693c-1.776,4.34-2.24,10.373-2.24,16.459v113.426h-67.537 c0,0,0.905-184.043,0-203.096H246.4v28.779c8.973-13.807,24.986-33.547,60.856-33.547c44.437,0,77.744,29.02,77.744,91.398V378.002 z" />
|
||||
</g>
|
||||
<a class="ml-3 text-gray-500 dark:text-gray-400" href="https://www.linkedin.com/in/thomaspcole">
|
||||
<svg fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="0"
|
||||
class="w-5 h-5" viewBox="0 0 24 24">
|
||||
<path stroke="none"
|
||||
d="M16 8a6 6 0 016 6v7h-4v-7a2 2 0 00-2-2 2 2 0 00-2 2v7h-4v-7a6 6 0 016-6zM2 9h4v12H2z"></path>
|
||||
<circle cx="4" cy="4" r="2" stroke="none"></circle>
|
||||
</svg>
|
||||
</a>
|
||||
<ThemeToggle/>
|
||||
</div>
|
||||
</span>
|
@ -9,8 +9,8 @@ const { title, subtitle } = Astro.props;
|
||||
|
||||
<div class="flex">
|
||||
<div>
|
||||
<span class="block w-4 h-4 mt-2 rounded-full bg-primary"></span>
|
||||
<span class="bg-primary block h-full w-[2px] translate-x-[7px]"></span>
|
||||
<span class="block w-4 h-4 mt-2 bg-indigo-500 rounded-full"></span>
|
||||
<span class="bg-indigo-500 block h-full w-[2px] translate-x-[7px]"></span>
|
||||
</div>
|
||||
<div class="px-5">
|
||||
<p class="text-xl font-semibold">{title}</p>
|
||||
|
@ -1,22 +0,0 @@
|
||||
---
|
||||
import Divider from "../components/misc/Divider.astro";
|
||||
import Layout from "./Layout.astro";
|
||||
|
||||
const { frontmatter } = Astro.props;
|
||||
---
|
||||
|
||||
<Layout>
|
||||
<main
|
||||
class="flex flex-col justify-center w-1/2 mx-auto mt-4 mb-6 sm:w-5/6 md:w-4/5 lg:w-4/5 xl:w-4/5 2xl:w-1/2">
|
||||
<div class="relative mb-4">
|
||||
<img class="object-cover aspect-video" src={frontmatter.image} alt="" loading="lazy"/>
|
||||
<a href={frontmatter.imageattr} class="absolute bottom-0 right-0 h-[24px]">
|
||||
<span class="material-symbols-outlined opacity-25 mr-[4px]">link</span>
|
||||
</a>
|
||||
</div>
|
||||
<p class="my-2 text-5xl font-bold">{frontmatter.title}</p>
|
||||
<p>{frontmatter.date}</p>
|
||||
<Divider />
|
||||
<slot />
|
||||
</main>
|
||||
</Layout>
|
@ -7,13 +7,14 @@
|
||||
<Layout>
|
||||
<main class="flex flex-col justify-center w-5/6 mx-auto mt-4 mb-6 sm:w-5/6 md:w-4/5 lg:w-4/5 xl:w-4/5 2xl:w-1/2">
|
||||
<div class="relative mb-4">
|
||||
<img class="object-cover aspect-video rounded-xl" src={frontmatter.image} alt="" />
|
||||
<img class="object-cover aspect-video rounded-xl max-h-[20%Z]" src={frontmatter.image} alt=""
|
||||
draggable="false" />
|
||||
<a href={frontmatter.imageattr} class="absolute bottom-0 right-0 h-[24px]">
|
||||
<span class="material-symbols-outlined opacity-25 mr-[4px]">link</span>
|
||||
</a>
|
||||
</div>
|
||||
<p class="my-2 text-5xl font-bold">{frontmatter.title}</p>
|
||||
<p>{frontmatter.date}</p>
|
||||
<p class="my-2 text-5xl font-bold text-gray-800 dark:text-white">{frontmatter.title}</p>
|
||||
<p class="text-gray-600 dark:text-gray-400">{frontmatter.date}</p>
|
||||
<Divider />
|
||||
<!-- Render our markdown with the normal header styling and some extra padding. -->
|
||||
<style is:inline>
|
||||
@ -22,44 +23,45 @@
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p,
|
||||
table,
|
||||
hr {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3rem;
|
||||
line-height: 1;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 2.25rem;
|
||||
line-height: 2.5rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.875rem;
|
||||
line-height: 2.25rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
img {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
/* Silly :root .prose. Why must you be difficult */
|
||||
.prose-light {
|
||||
--tw-prose-body: #374151 !important;
|
||||
--tw-prose-headings: #111827 !important;
|
||||
--tw-prose-lead: #4b5563 !important;
|
||||
--tw-prose-links: #111827 !important;
|
||||
--tw-prose-bold: #111827 !important;
|
||||
--tw-prose-counters: #6b7280 !important;
|
||||
--tw-prose-bullets: #d1d5db !important;
|
||||
--tw-prose-hr: #e5e7eb !important;
|
||||
--tw-prose-quotes: #111827 !important;
|
||||
--tw-prose-quote-borders: #e5e7eb !important;
|
||||
--tw-prose-captions: #6b7280 !important;
|
||||
--tw-prose-code: #111827 !important;
|
||||
--tw-prose-pre-code: #e5e7eb !important;
|
||||
--tw-prose-pre-bg: #1f2937 !important;
|
||||
--tw-prose-th-borders: #d1d5db !important;
|
||||
--tw-prose-td-borders: #e5e7eb !important;
|
||||
}
|
||||
</style>
|
||||
<slot />
|
||||
<article id="article" class="max-w-full prose dark:prose-invert prose-light">
|
||||
<slot />
|
||||
</article>
|
||||
<script is:inline>
|
||||
let article = document.getElementById("article");
|
||||
//Should this be in a function? yes. Does that break everyting? Also yes.
|
||||
if (localStorage.theme === 'light') {
|
||||
article.classList.add("prose-light");
|
||||
} else {
|
||||
article.classList.remove("prose-light");
|
||||
}
|
||||
|
||||
window.addEventListener("themeupdate", (event) => {
|
||||
if (localStorage.theme === 'light') {
|
||||
article.classList.add("prose-light");
|
||||
} else {
|
||||
article.classList.remove("prose-light");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</main>
|
||||
</Layout>
|
@ -10,7 +10,7 @@
|
||||
---
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" class="">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
@ -36,25 +36,23 @@
|
||||
}
|
||||
</style>
|
||||
<script is:inline>
|
||||
if (localStorage.getItem("theme") === null) {
|
||||
document.documentElement.setAttribute("data-theme", "business");
|
||||
} else {
|
||||
document.documentElement.setAttribute("data-theme", localStorage.getItem("theme"));
|
||||
if(!('theme' in localStorage)){
|
||||
localStorage.setItem("theme", "light")
|
||||
}
|
||||
|
||||
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
||||
document.documentElement.classList.add('dark')
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark')
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
import { themeChange } from 'theme-change';
|
||||
themeChange();
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body class="">
|
||||
<body class="flex flex-col w-full h-full min-h-screen bg-white dark:bg-gray-900">
|
||||
<Nav pageName={title} />
|
||||
<div class="ml-0 sm:ml-0 md:ml-0 lg:ml-72 xl:ml-72 2xl:ml-72 flex flex-col min-h-[calc(100vh-48px)] lg:min-h-screen xl:min-h-screen">
|
||||
<slot />
|
||||
<div class="grow"></div>
|
||||
<Footer/>
|
||||
</div>
|
||||
<slot />
|
||||
<div class="grow"></div>
|
||||
<Footer />
|
||||
</body>
|
||||
|
||||
</html>
|
83
src/pages/about.astro
Normal file
83
src/pages/about.astro
Normal file
@ -0,0 +1,83 @@
|
||||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import Timeline from "../components/resume/Timeline.astro";
|
||||
|
||||
const resumeRaw = await fetch('https://git.thomaspcole.com/thomascole/Resume/raw/branch/master/resume.json');
|
||||
const resume = await resumeRaw.json();
|
||||
|
||||
function parseDate(date: string) {
|
||||
const retVal = new Date(date).toLocaleString('default', { month: 'long', year: "numeric" })
|
||||
if (retVal === "Invalid Date") {
|
||||
return "Present";
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
---
|
||||
|
||||
<Layout title={" | Resume"}>
|
||||
|
||||
<style is:inline>
|
||||
.time-line-container>div:last-child>div:nth-child(1)>span:nth-child(2) {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<main class="w-5/6 mx-auto text-gray-900 dark:text-white sm:w-5/6 md:w-4/5 lg:w-4/5 xl:w-4/5 2xl:w-1/2">
|
||||
<section class="text-gray-600 body-font">
|
||||
|
||||
</section>
|
||||
|
||||
<section class="body-font">
|
||||
<div class="container pt-6 pb-6 mx-auto sm:pb-0">
|
||||
<div class="flex flex-col-reverse items-start mx-auto sm:flex-row sm:items-center">
|
||||
<p class="py-0 mr-auto text-2xl font-bold sm:py-6">About Me</p>
|
||||
<a href="https://git.thomaspcole.com/attachments/9027185b-9841-4687-addd-0e5ba5eb0d1f" target="_blank" download
|
||||
class="flex items-center px-6 py-1 mb-6 ml-auto mr-auto text-lg text-white bg-indigo-500 border-0 rounded sm:mr-0 sm:mb-0 place-content-center sm:w-auto focus:outline-none hover:bg-indigo-600">Download
|
||||
as PDF <span class="ml-2 material-symbols-outlined">
|
||||
download
|
||||
</span></a>
|
||||
</div>
|
||||
</div>
|
||||
<p>{resume.basics.summary}</p>
|
||||
|
||||
<div class="divider" />
|
||||
<p class="pb-6 text-2xl font-bold">Work Experience</p>
|
||||
<div class="time-line-container">
|
||||
{resume.work.map((item:any)=>
|
||||
<Timeline title={item.position} subtitle={item.name + " | " + parseDate(item.startDate) + " - " +
|
||||
parseDate(item.endDate)}>
|
||||
<ul class="text-sm ml-3.5 list-disc mt-2 mb-4">
|
||||
{item.highlights.map((highlight:any)=>
|
||||
<li>{highlight}</li>
|
||||
)}
|
||||
</ul>
|
||||
</Timeline>
|
||||
)}
|
||||
</div>
|
||||
<p class="py-6 text-2xl font-bold">Education</p>
|
||||
<div class="time-line-container">
|
||||
{resume.education.map((item:any)=>
|
||||
<Timeline title={item.institution} subtitle={item.area + " | " + parseDate(item.endDate)} />
|
||||
)}
|
||||
</div>
|
||||
<p class="py-6 text-2xl font-bold">Professional Certificates</p>
|
||||
<div class="time-line-container">
|
||||
{resume.certificates.map((item:any)=>
|
||||
<Timeline title={item.name} subtitle={item.issuer + " | " + parseDate(item.date)} />
|
||||
)}
|
||||
</div>
|
||||
<p class="py-6 text-2xl font-bold">Skills</p>
|
||||
{resume.skills.map((item:any)=>
|
||||
<div class="divider">{item.name}</div>
|
||||
<div class="flex flex-wrap gap-2 pb-4 mx-auto my-2">
|
||||
{item.keywords.map((skill:any)=>
|
||||
<div
|
||||
class="text-gray-600 bg-white border-gray-200 badge badge-lg dark:bg-gray-800 dark:border-gray-800 dark:text-gray-400">
|
||||
{skill}</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</main>
|
||||
</Layout>
|
@ -3,15 +3,40 @@
|
||||
---
|
||||
|
||||
<Layout title={" | Contact"}>
|
||||
<div class="flex flex-col w-5/6 mx-auto my-2 sm:flex-col md:flex-col lg:flex-row xl:flex-row 2xl:flex-row">
|
||||
<div class="w-full text-center lg:w-1/2">
|
||||
<p>Picture here</p>
|
||||
<section class="relative text-gray-600 body-font">
|
||||
<div class="container px-5 py-24 mx-auto">
|
||||
<div class="flex flex-col w-full text-center">
|
||||
<h1 class="mb-4 text-2xl font-medium text-gray-900 sm:text-3xl title-font">Contact Me</h1>
|
||||
</div>
|
||||
<div class="mx-auto lg:w-1/2 md:w-2/3">
|
||||
<div class="flex flex-wrap -m-2">
|
||||
<div class="w-1/2 p-2">
|
||||
<div class="relative">
|
||||
<label for="name" class="text-sm leading-7 text-gray-600 dark:text-gray-400">Name</label>
|
||||
<input type="text" id="name" name="name"
|
||||
class="w-full px-3 py-1 text-base leading-8 text-gray-700 transition-colors duration-200 ease-in-out bg-gray-100 bg-opacity-50 border border-gray-300 rounded outline-none dark:border-gray-700 dark:bg-gray-800 dark:focus:border-indigo-500 focus:border-indigo-500 focus:bg-white focus:ring-2 focus:ring-indigo-200 dark:focus:ring-indigo-500 dark:focus:bg-gray-900">
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/2 p-2">
|
||||
<div class="relative">
|
||||
<label for="email" class="text-sm leading-7 text-gray-600 dark:text-gray-400">Email</label>
|
||||
<input type="email" id="email" name="email"
|
||||
class="w-full px-3 py-1 text-base leading-8 text-gray-700 transition-colors duration-200 ease-in-out bg-gray-100 bg-opacity-50 border border-gray-300 rounded outline-none focus:border-indigo-500 dark:border-gray-700 dark:focus:border-indigo-500 dark:bg-gray-800 focus:bg-white focus:ring-2 focus:ring-indigo-200 dark:focus:ring-indigo-500 dark:focus:bg-gray-900">
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full p-2">
|
||||
<div class="relative">
|
||||
<label for="message" class="text-sm leading-7 text-gray-600 dark:text-gray-400">Message</label>
|
||||
<textarea id="message" name="message"
|
||||
class="w-full h-32 px-3 py-1 text-base leading-6 text-gray-700 transition-colors duration-200 ease-in-out bg-gray-100 bg-opacity-50 border border-gray-300 rounded outline-none resize-none dark:border-gray-700 dark:focus:border-indigo-500 dark:bg-gray-800 focus:border-indigo-500 focus:bg-white focus:ring-2 focus:ring-indigo-200 dark:focus:ring-indigo-500 dark:focus:bg-gray-900"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full p-2">
|
||||
<button
|
||||
class="flex px-8 py-2 mx-auto text-lg text-white bg-indigo-500 border-0 rounded focus:outline-none hover:bg-indigo-600">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col w-full gap-4 text-center lg:w-1/2">
|
||||
<input type="text" placeholder="Name" class="w-full input input-bordered" />
|
||||
<input type="text" placeholder="Email" class="w-full input input-bordered" />
|
||||
<textarea class="w-full textarea textarea-bordered" placeholder="Message" style="resize:none"></textarea>
|
||||
<button class="w-full btn">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Layout>
|
@ -1,38 +1,27 @@
|
||||
---
|
||||
import BlogProjectCard from "../components/misc/BlogProjectCard.astro";
|
||||
import Divider from "../components/misc/Divider.astro";
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
|
||||
const projects = (await Astro.glob("./projects/**/*.{md,mdx}")).sort(
|
||||
(a,b) =>
|
||||
new Date(b.frontmatter.date).valueOf()-
|
||||
new Date(a.frontmatter.date).valueOf()
|
||||
).slice(0,5);
|
||||
const projects = (await Astro.glob("./projects/**/*.{md,mdx}")).sort(
|
||||
(a, b) =>
|
||||
new Date(b.frontmatter.date).valueOf() -
|
||||
new Date(a.frontmatter.date).valueOf()
|
||||
).slice(0, 5);
|
||||
---
|
||||
|
||||
<Layout>
|
||||
<main class="flex flex-col w-5/6 m-6 mx-auto sm:w-5/6 md:w-4/5 lg:w-4/5 xl:w-4/5 2xl:w-1/2">
|
||||
<section>
|
||||
<div class="flex flex-row">
|
||||
<p class="text-5xl sm:text-5xl md:text-5xl lg:text-6xl py-1 font-extrabold text-transparent bg-clip-text bg-gradient-to-br from-[#1f89db] to-[#f42a8b]">Hello World!</p>
|
||||
<main class="flex flex-col w-full m-6 mx-auto md:w-4/5 lg:w-4/5 xl:w-4/5 2xl:w-1/2">
|
||||
<section class="text-gray-600 dark:text-gray-400 body-font mt-[15%]">
|
||||
<div class="container flex flex-col items-center justify-center px-5 py-10 mx-auto">
|
||||
<img class="object-cover object-center w-4/6 mb-10 rounded-full lg:w-2/6 md:w-3/6 aspect-square"
|
||||
alt="hero" src="/img/profile.jpg">
|
||||
<div class="w-full text-center lg:w-5/6">
|
||||
<h1
|
||||
class="w-full mb-4 text-4xl font-extrabold text-transparent title-font md:text-7xl lg:text-8xl whitespace-nowrap bg-clip-text bg-gradient-to-br from-blue-300 via-purple-600 to-red-600 animate-text">
|
||||
Hello World!</h1>
|
||||
<h1 class="mb-4 text-3xl font-medium text-gray-900 title-font sm:text-4xl dark:text-white">I'm Thomas Cole</h1>
|
||||
<p class="mb-8 leading-relaxed">Web Developer, System Administrator, Network Engineer</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-3xl font-semibold">I'm Thomas Cole</p>
|
||||
<p class="font-thin">Web Developer, System Administrator, Network Engineer</p>
|
||||
</section>
|
||||
<div class="divider"/>
|
||||
<section>
|
||||
<p class="py-2 text-2xl font-bold sm:text-2xl md:text-2xl lg:text-4xl xl:text-4xl 2xl:text-4xl">Latest Projects</p>
|
||||
{
|
||||
projects.map((post) => (
|
||||
<BlogProjectCard
|
||||
title={post.frontmatter.title}
|
||||
subtitle={post.frontmatter.tagline}
|
||||
image={post.frontmatter.image}
|
||||
link={post.url}
|
||||
/>
|
||||
<div class="divider"/>
|
||||
))
|
||||
}
|
||||
</section>
|
||||
</main>
|
||||
</Layout>
|
||||
|
@ -18,15 +18,21 @@
|
||||
|
||||
<Layout title=" | Projects">
|
||||
<main class="w-full mx-auto mt-4 md:w-5/6 lg:w-4/5 xl:w-4/5">
|
||||
<div class="flex flex-col">
|
||||
{
|
||||
page.data.map((post: any) => (
|
||||
<BlogProjectCard title={post.frontmatter.title} subtitle={post.frontmatter.tagline}
|
||||
image={post.frontmatter.image} link={post.url}/>
|
||||
<Divider />
|
||||
))
|
||||
}
|
||||
</div>
|
||||
<section class="text-gray-600 dark:text-gray-400 body-font">
|
||||
<p class="px-5 text-2xl font-bold sm:text-2xl md:text-2xl lg:text-4xl xl:text-4xl 2xl:text-4xl">Latest
|
||||
Projects</p>
|
||||
<div class="container px-5 py-6 mx-auto">
|
||||
<div class="flex flex-wrap -m-4">
|
||||
{
|
||||
page.data.map((post: any) => (
|
||||
<BlogProjectCard title={post.frontmatter.title} subtitle={post.frontmatter.tagline}
|
||||
image={post.frontmatter.image} link={post.url} category={post.frontmatter.category} date={post.frontmatter.date}/>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="flex justify-between w-1/2 mx-auto">
|
||||
{
|
||||
page.url.prev ? (
|
||||
|
@ -1,8 +1,9 @@
|
||||
---
|
||||
layout: "../../layouts/InteractiveDemoLayout.astro"
|
||||
title: "Set and Forget Digital Signage"
|
||||
title: "Adventures in Digital Signage"
|
||||
tagline: "Using slideshow.digital for cheap reliable signs"
|
||||
date: "April 17, 2023"
|
||||
category: "Software"
|
||||
image: "https://images.unsplash.com/photo-1496442226666-8d4d0e62e6e9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80"
|
||||
imageattr: "https://unsplash.com/photos/TaCk3NspYe0"
|
||||
---
|
||||
|
@ -3,6 +3,7 @@ layout: "../../../layouts/InteractiveDemoLayout.astro"
|
||||
title: "Pedal-pi"
|
||||
tagline: "A custom effects processor using MODEP"
|
||||
date: "May 15, 2023"
|
||||
category: "Hardware"
|
||||
image: "https://images.unsplash.com/photo-1511203438670-49f8ea8441c6?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80"
|
||||
imageattr: "https://unsplash.com/photos/lEwyj4FiHHU"
|
||||
---
|
||||
|
@ -3,6 +3,7 @@ layout: "../../../layouts/InteractiveDemoLayout.astro"
|
||||
title: "Quicksort Demo"
|
||||
tagline: "A simple visualization of the quicksort algorithm using p5.js"
|
||||
date: "December 23, 2022"
|
||||
category: "Software"
|
||||
image: "https://images.unsplash.com/photo-1669399213378-2853e748f217?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1632&q=80"
|
||||
imageattr: "https://unsplash.com/photos/5dgXQJ7ezuU"
|
||||
---
|
||||
|
@ -3,6 +3,7 @@ layout: "../../../layouts/InteractiveDemoLayout.astro"
|
||||
title: "Visual Sitemap"
|
||||
tagline: "Using Cytoscape.js to visualize all the pages of a website"
|
||||
date: "January 6, 2023"
|
||||
category: "Software"
|
||||
image: "https://images.unsplash.com/photo-1639322537228-f710d846310a?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1632&q=80"
|
||||
imageattr: "https://unsplash.com/photos/T9rKvI3N0NM"
|
||||
---
|
||||
|
@ -1,68 +0,0 @@
|
||||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import Timeline from "../components/resume/Timeline.astro";
|
||||
|
||||
const resumeRaw = await fetch('https://git.thomaspcole.com/thomascole/Resume/raw/branch/master/resume.json');
|
||||
const resume = await resumeRaw.json();
|
||||
|
||||
function parseDate(date:string){
|
||||
const retVal = new Date(date).toLocaleString('default', { month: 'long', year: "numeric" })
|
||||
if(retVal === "Invalid Date"){
|
||||
return "Present";
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
---
|
||||
|
||||
<Layout title={" | Resume"}>
|
||||
|
||||
<style is:inline>
|
||||
.time-line-container > div:last-child > div:nth-child(1) > span:nth-child(2){
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<main class="w-5/6 mx-auto sm:w-5/6 md:w-4/5 lg:w-4/5 xl:w-4/5 2xl:w-1/2">
|
||||
<p class="py-6 text-2xl font-bold">About Me</p>
|
||||
<p>{resume.basics.summary}</p>
|
||||
|
||||
<div class="divider"/>
|
||||
<p class="pb-6 text-2xl font-bold">Work Experience</p>
|
||||
<div class="time-line-container">
|
||||
{resume.work.map((item:any)=>
|
||||
<Timeline title={item.position} subtitle={item.name + " | " + parseDate(item.startDate) + " - " + parseDate(item.endDate)}>
|
||||
<ul class="text-sm ml-3.5 list-disc mt-2 mb-4">
|
||||
{item.highlights.map((highlight:any)=>
|
||||
<li>{highlight}</li>
|
||||
)}
|
||||
</ul>
|
||||
</Timeline>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<p class="py-6 text-2xl font-bold">Education</p>
|
||||
<div class="time-line-container">
|
||||
{resume.education.map((item:any)=>
|
||||
<Timeline title={item.institution} subtitle={item.area + " | " + parseDate(item.endDate)}/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<p class="py-6 text-2xl font-bold">Professional Certificates</p>
|
||||
<div class="time-line-container">
|
||||
{resume.certificates.map((item:any)=>
|
||||
<Timeline title={item.name} subtitle={item.issuer + " | " + parseDate(item.date)}/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<p class="py-6 text-2xl font-bold">Skills</p>
|
||||
{resume.skills.map((item:any)=>
|
||||
<div class="divider">{item.name}</div>
|
||||
<div class="flex flex-wrap gap-2 pb-4 mx-auto my-2">
|
||||
{item.keywords.map((skill:any)=>
|
||||
<div class="badge badge-lg">{skill}</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
</Layout>
|
@ -3,7 +3,7 @@ const defaultTheme = require('tailwindcss/defaultTheme');
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
|
||||
darkMode: ["class", "[data-theme]=business"],
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
@ -14,20 +14,26 @@ module.exports = {
|
||||
'0%, 100%': { transform: 'rotate(-5deg)' },
|
||||
'50%': { transform: 'rotate(5deg)' },
|
||||
},
|
||||
'bg-animate':{
|
||||
'0%,100%': {'background-position': '25% 50%'},
|
||||
'50%': {'background-position': '75% 50%'},
|
||||
}
|
||||
text: {
|
||||
'0%, 100%': {
|
||||
'background-size': '200% 200%',
|
||||
'background-position': 'left center',
|
||||
},
|
||||
'50%': {
|
||||
'background-size': '200% 200%',
|
||||
'background-position': 'right center',
|
||||
},
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
'wiggle-infinite': 'wiggle 1s ease-in-out infinite',
|
||||
wiggle: 'wiggle 1s ease-in-out',
|
||||
'bg-animate': 'bg-animate 5s ease-in-out infinite',
|
||||
'text': 'text 15s ease infinite'
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: [require("daisyui")],
|
||||
daisyui: {
|
||||
themes: ["corporate", "business"],
|
||||
},
|
||||
plugins: [
|
||||
require("daisyui"),
|
||||
require('@tailwindcss/typography')
|
||||
],
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user