chore: remove junk
This commit is contained in:
parent
f6dcc302d4
commit
8f6872f739
96 changed files with 1002 additions and 2485 deletions
|
@ -1,13 +1,13 @@
|
|||
---
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
import type { CollectionEntry } from 'astro:content'
|
||||
|
||||
type Props = {
|
||||
entry: CollectionEntry<"blog">;
|
||||
};
|
||||
entry: CollectionEntry<'blog'>
|
||||
}
|
||||
|
||||
const { entry } = Astro.props as {
|
||||
entry: CollectionEntry<"blog">;
|
||||
};
|
||||
entry: CollectionEntry<'blog'>
|
||||
}
|
||||
---
|
||||
|
||||
<a
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
---
|
||||
type Props = {
|
||||
href: string;
|
||||
};
|
||||
href: string
|
||||
}
|
||||
|
||||
const { href } = Astro.props;
|
||||
const { href } = Astro.props
|
||||
---
|
||||
|
||||
<a
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
---
|
||||
export interface Props {
|
||||
institution: string;
|
||||
time: string;
|
||||
job_title: string;
|
||||
location: string;
|
||||
description: string
|
||||
}
|
||||
|
||||
const { institution, time, job_title, location, description } = Astro.props;
|
||||
institution: string
|
||||
time: string
|
||||
job_title: string
|
||||
location: string
|
||||
description: string
|
||||
}
|
||||
|
||||
const { institution, time, job_title, location, description } = Astro.props
|
||||
---
|
||||
|
||||
<div class="py-5 px-8">
|
||||
<div class="flex justify-between text-sm font-bold md:text-lg">
|
||||
<div>{institution}</div>
|
||||
<div>{location}</div>
|
||||
</div>
|
||||
<div class="flex justify-between text-xs md:text-base">
|
||||
<div class="italic">{job_title}</div>
|
||||
<div>{time}</div>
|
||||
</div>
|
||||
<p class="text-xs mt-2">{description}</p>
|
||||
</div>
|
||||
<div class="px-8 py-5">
|
||||
<div class="flex justify-between text-sm font-bold md:text-lg">
|
||||
<div>{institution}</div>
|
||||
<div>{location}</div>
|
||||
</div>
|
||||
<div class="flex justify-between text-xs md:text-base">
|
||||
<div class="italic">{job_title}</div>
|
||||
<div>{time}</div>
|
||||
</div>
|
||||
<p class="mt-2 text-xs">{description}</p>
|
||||
</div>
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
---
|
||||
interface Component {
|
||||
type: "default" | "info" | "warning" | "error";
|
||||
type: 'default' | 'info' | 'warning' | 'error'
|
||||
}
|
||||
|
||||
const { type = "default" } = Astro.props;
|
||||
const { type = 'default' } = Astro.props
|
||||
|
||||
let emoji = "💡";
|
||||
let emoji = '💡'
|
||||
|
||||
if (type === "info") {
|
||||
emoji = "ℹ️";
|
||||
} else if (type === "warning") {
|
||||
emoji = "⚠️";
|
||||
} else if (type === "error") {
|
||||
emoji = "🚨";
|
||||
if (type === 'info') {
|
||||
emoji = 'ℹ️'
|
||||
} else if (type === 'warning') {
|
||||
emoji = '⚠️'
|
||||
} else if (type === 'error') {
|
||||
emoji = '🚨'
|
||||
}
|
||||
---
|
||||
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
---
|
||||
import Container from "@components/Container.astro";
|
||||
import { SITE } from "@consts";
|
||||
import BackToTop from "@components/BackToTop.astro";
|
||||
import SocialIcons from "./SocialIcons.astro";
|
||||
import Container from '@components/Container.astro'
|
||||
import { SITE } from '@consts'
|
||||
import BackToTop from '@components/BackToTop.astro'
|
||||
import SocialIcons from './SocialIcons.astro'
|
||||
---
|
||||
|
||||
<footer class="animate">
|
||||
<Container>
|
||||
<div class="flex justify-between my-2">
|
||||
<div class="my-2 flex justify-between">
|
||||
<SocialIcons icon_size={'text-xl'} />
|
||||
<BackToTop />
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div>© {new Date().getFullYear()} • {SITE.TITLE} 👀<br>
|
||||
Built with Astro
|
||||
<div>
|
||||
© {new Date().getFullYear()} • {SITE.TITLE} 👀<br />
|
||||
Built with Astro
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-1.5">
|
||||
<button
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
---
|
||||
interface Props {
|
||||
date: Date;
|
||||
date: Date
|
||||
}
|
||||
|
||||
const { date } = Astro.props;
|
||||
const { date } = Astro.props
|
||||
---
|
||||
|
||||
<time datetime={date.toISOString()}>
|
||||
{
|
||||
date.toLocaleDateString("en-US", {
|
||||
month: "long",
|
||||
day: "2-digit",
|
||||
year: "numeric",
|
||||
date.toLocaleDateString('en-US', {
|
||||
month: 'long',
|
||||
day: '2-digit',
|
||||
year: 'numeric',
|
||||
})
|
||||
}
|
||||
</time>
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
---
|
||||
import "../styles/global.css";
|
||||
import { ViewTransitions } from "astro:transitions";
|
||||
import '../styles/global.css'
|
||||
import { ViewTransitions } from 'astro:transitions'
|
||||
|
||||
import "@fontsource/geist-sans";
|
||||
import "@fontsource/geist-mono";
|
||||
import '@fontsource/geist-sans'
|
||||
import '@fontsource/geist-mono'
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
description: string;
|
||||
image?: string;
|
||||
title: string
|
||||
description: string
|
||||
image?: string
|
||||
}
|
||||
|
||||
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
|
||||
const canonicalURL = new URL(Astro.url.pathname, Astro.site)
|
||||
|
||||
const { title, description, image = "/blog-placeholder-1.jpg" } = Astro.props;
|
||||
const { title, description, image = '/blog-placeholder-1.jpg' } = Astro.props
|
||||
---
|
||||
|
||||
<!-- Global Metadata -->
|
||||
|
@ -48,116 +48,112 @@ const { title, description, image = "/blog-placeholder-1.jpg" } = Astro.props;
|
|||
<meta property="twitter:description" content={description} />
|
||||
<meta property="twitter:image" content={new URL(image, Astro.url)} />
|
||||
|
||||
<!-- PageFind -->
|
||||
<link href="/pagefind/pagefind-ui.css" rel="stylesheet" />
|
||||
<script is:inline src="/pagefind/pagefind-ui.js"></script>
|
||||
|
||||
<ViewTransitions />
|
||||
|
||||
<script is:inline>
|
||||
function init() {
|
||||
preloadTheme();
|
||||
onScroll();
|
||||
animate();
|
||||
updateThemeButtons();
|
||||
addCopyCodeButtons();
|
||||
setGiscusTheme();
|
||||
preloadTheme()
|
||||
onScroll()
|
||||
animate()
|
||||
updateThemeButtons()
|
||||
addCopyCodeButtons()
|
||||
setGiscusTheme()
|
||||
|
||||
const backToTop = document.getElementById("back-to-top");
|
||||
backToTop?.addEventListener("click", (event) => scrollToTop(event));
|
||||
const backToTop = document.getElementById('back-to-top')
|
||||
backToTop?.addEventListener('click', (event) => scrollToTop(event))
|
||||
|
||||
const backToPrev = document.getElementById("back-to-prev");
|
||||
backToPrev?.addEventListener("click", () => window.history.back());
|
||||
const backToPrev = document.getElementById('back-to-prev')
|
||||
backToPrev?.addEventListener('click', () => window.history.back())
|
||||
|
||||
const lightThemeButton = document.getElementById("light-theme-button");
|
||||
lightThemeButton?.addEventListener("click", () => {
|
||||
localStorage.setItem("theme", "light");
|
||||
toggleTheme(false);
|
||||
updateThemeButtons();
|
||||
});
|
||||
const lightThemeButton = document.getElementById('light-theme-button')
|
||||
lightThemeButton?.addEventListener('click', () => {
|
||||
localStorage.setItem('theme', 'light')
|
||||
toggleTheme(false)
|
||||
updateThemeButtons()
|
||||
})
|
||||
|
||||
const darkThemeButton = document.getElementById("dark-theme-button");
|
||||
darkThemeButton?.addEventListener("click", () => {
|
||||
localStorage.setItem("theme", "dark");
|
||||
toggleTheme(true);
|
||||
updateThemeButtons();
|
||||
});
|
||||
const darkThemeButton = document.getElementById('dark-theme-button')
|
||||
darkThemeButton?.addEventListener('click', () => {
|
||||
localStorage.setItem('theme', 'dark')
|
||||
toggleTheme(true)
|
||||
updateThemeButtons()
|
||||
})
|
||||
|
||||
const systemThemeButton = document.getElementById("system-theme-button");
|
||||
systemThemeButton?.addEventListener("click", () => {
|
||||
localStorage.setItem("theme", "system");
|
||||
toggleTheme(window.matchMedia("(prefers-color-scheme: dark)").matches);
|
||||
updateThemeButtons();
|
||||
});
|
||||
const systemThemeButton = document.getElementById('system-theme-button')
|
||||
systemThemeButton?.addEventListener('click', () => {
|
||||
localStorage.setItem('theme', 'system')
|
||||
toggleTheme(window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||
updateThemeButtons()
|
||||
})
|
||||
|
||||
window
|
||||
.matchMedia("(prefers-color-scheme: dark)")
|
||||
.addEventListener("change", (event) => {
|
||||
if (localStorage.theme === "system") {
|
||||
toggleTheme(event.matches);
|
||||
.matchMedia('(prefers-color-scheme: dark)')
|
||||
.addEventListener('change', (event) => {
|
||||
if (localStorage.theme === 'system') {
|
||||
toggleTheme(event.matches)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
document.addEventListener("scroll", onScroll);
|
||||
document.addEventListener('scroll', onScroll)
|
||||
}
|
||||
|
||||
function updateThemeButtons() {
|
||||
const theme = localStorage.getItem("theme");
|
||||
const lightThemeButton = document.getElementById("light-theme-button");
|
||||
const darkThemeButton = document.getElementById("dark-theme-button");
|
||||
const systemThemeButton = document.getElementById("system-theme-button");
|
||||
const theme = localStorage.getItem('theme')
|
||||
const lightThemeButton = document.getElementById('light-theme-button')
|
||||
const darkThemeButton = document.getElementById('dark-theme-button')
|
||||
const systemThemeButton = document.getElementById('system-theme-button')
|
||||
|
||||
function removeActiveButtonTheme(button) {
|
||||
button?.classList.remove("bg-black/5");
|
||||
button?.classList.remove("dark:bg-white/5");
|
||||
button?.classList.remove('bg-black/5')
|
||||
button?.classList.remove('dark:bg-white/5')
|
||||
}
|
||||
|
||||
function addActiveButtonTheme(button) {
|
||||
button?.classList.add("bg-black/5");
|
||||
button?.classList.add("dark:bg-white/5");
|
||||
button?.classList.add('bg-black/5')
|
||||
button?.classList.add('dark:bg-white/5')
|
||||
}
|
||||
|
||||
removeActiveButtonTheme(lightThemeButton);
|
||||
removeActiveButtonTheme(darkThemeButton);
|
||||
removeActiveButtonTheme(systemThemeButton);
|
||||
removeActiveButtonTheme(lightThemeButton)
|
||||
removeActiveButtonTheme(darkThemeButton)
|
||||
removeActiveButtonTheme(systemThemeButton)
|
||||
|
||||
if (theme === "light") {
|
||||
addActiveButtonTheme(lightThemeButton);
|
||||
} else if (theme === "dark") {
|
||||
addActiveButtonTheme(darkThemeButton);
|
||||
if (theme === 'light') {
|
||||
addActiveButtonTheme(lightThemeButton)
|
||||
} else if (theme === 'dark') {
|
||||
addActiveButtonTheme(darkThemeButton)
|
||||
} else {
|
||||
addActiveButtonTheme(systemThemeButton);
|
||||
addActiveButtonTheme(systemThemeButton)
|
||||
}
|
||||
}
|
||||
|
||||
function animate() {
|
||||
const animateElements = document.querySelectorAll(".animate");
|
||||
const animateElements = document.querySelectorAll('.animate')
|
||||
|
||||
animateElements.forEach((element, index) => {
|
||||
setTimeout(() => {
|
||||
element.classList.add("show");
|
||||
}, index * 100);
|
||||
});
|
||||
element.classList.add('show')
|
||||
}, index * 100)
|
||||
})
|
||||
}
|
||||
|
||||
function onScroll() {
|
||||
if (window.scrollY > 0) {
|
||||
document.documentElement.classList.add("scrolled");
|
||||
document.documentElement.classList.add('scrolled')
|
||||
} else {
|
||||
document.documentElement.classList.remove("scrolled");
|
||||
document.documentElement.classList.remove('scrolled')
|
||||
}
|
||||
}
|
||||
|
||||
function scrollToTop(event) {
|
||||
event.preventDefault();
|
||||
event.preventDefault()
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: "smooth",
|
||||
});
|
||||
behavior: 'smooth',
|
||||
})
|
||||
}
|
||||
|
||||
function toggleTheme(dark) {
|
||||
const css = document.createElement("style");
|
||||
const css = document.createElement('style')
|
||||
|
||||
css.appendChild(
|
||||
document.createTextNode(
|
||||
|
@ -168,84 +164,84 @@ const { title, description, image = "/blog-placeholder-1.jpg" } = Astro.props;
|
|||
-ms-transition: none !important;
|
||||
transition: none !important;
|
||||
}
|
||||
`
|
||||
)
|
||||
);
|
||||
`,
|
||||
),
|
||||
)
|
||||
|
||||
document.head.appendChild(css);
|
||||
document.head.appendChild(css)
|
||||
|
||||
if (dark) {
|
||||
document.documentElement.classList.add("dark");
|
||||
document.documentElement.classList.add('dark')
|
||||
} else {
|
||||
document.documentElement.classList.remove("dark");
|
||||
document.documentElement.classList.remove('dark')
|
||||
}
|
||||
|
||||
window.getComputedStyle(css).opacity;
|
||||
document.head.removeChild(css);
|
||||
window.getComputedStyle(css).opacity
|
||||
document.head.removeChild(css)
|
||||
|
||||
setGiscusTheme();
|
||||
setGiscusTheme()
|
||||
}
|
||||
|
||||
function preloadTheme() {
|
||||
const userTheme = localStorage.theme;
|
||||
const userTheme = localStorage.theme
|
||||
|
||||
if (userTheme === "light" || userTheme === "dark") {
|
||||
toggleTheme(true); // set default to dark theme
|
||||
if (userTheme === 'light' || userTheme === 'dark') {
|
||||
toggleTheme(true) // set default to dark theme
|
||||
} else {
|
||||
toggleTheme(window.matchMedia("(prefers-color-scheme: dark)").matches);
|
||||
toggleTheme(window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||
}
|
||||
}
|
||||
|
||||
function addCopyCodeButtons() {
|
||||
let copyButtonLabel = "📋";
|
||||
let codeBlocks = Array.from(document.querySelectorAll("pre"));
|
||||
let copyButtonLabel = '📋'
|
||||
let codeBlocks = Array.from(document.querySelectorAll('pre'))
|
||||
|
||||
async function copyCode(codeBlock, copyButton) {
|
||||
const codeText = codeBlock.innerText;
|
||||
const buttonText = copyButton.innerText;
|
||||
const textToCopy = codeText.replace(buttonText, "");
|
||||
const codeText = codeBlock.innerText
|
||||
const buttonText = copyButton.innerText
|
||||
const textToCopy = codeText.replace(buttonText, '')
|
||||
|
||||
await navigator.clipboard.writeText(textToCopy);
|
||||
copyButton.innerText = "✅";
|
||||
await navigator.clipboard.writeText(textToCopy)
|
||||
copyButton.innerText = '✅'
|
||||
|
||||
setTimeout(() => {
|
||||
copyButton.innerText = copyButtonLabel;
|
||||
}, 2000);
|
||||
copyButton.innerText = copyButtonLabel
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
for (let codeBlock of codeBlocks) {
|
||||
const wrapper = document.createElement("div");
|
||||
wrapper.style.position = "relative";
|
||||
const wrapper = document.createElement('div')
|
||||
wrapper.style.position = 'relative'
|
||||
|
||||
const copyButton = document.createElement("button");
|
||||
copyButton.innerText = copyButtonLabel;
|
||||
copyButton.classList = "copy-code";
|
||||
const copyButton = document.createElement('button')
|
||||
copyButton.innerText = copyButtonLabel
|
||||
copyButton.classList = 'copy-code'
|
||||
|
||||
codeBlock.setAttribute("tabindex", "0");
|
||||
codeBlock.appendChild(copyButton);
|
||||
codeBlock.setAttribute('tabindex', '0')
|
||||
codeBlock.appendChild(copyButton)
|
||||
|
||||
codeBlock.parentNode.insertBefore(wrapper, codeBlock);
|
||||
wrapper.appendChild(codeBlock);
|
||||
codeBlock.parentNode.insertBefore(wrapper, codeBlock)
|
||||
wrapper.appendChild(codeBlock)
|
||||
|
||||
copyButton?.addEventListener("click", async () => {
|
||||
await copyCode(codeBlock, copyButton);
|
||||
});
|
||||
copyButton?.addEventListener('click', async () => {
|
||||
await copyCode(codeBlock, copyButton)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const setGiscusTheme = () => {
|
||||
const giscus = document.querySelector(".giscus-frame");
|
||||
const giscus = document.querySelector('.giscus-frame')
|
||||
|
||||
const isDark = document.documentElement.classList.contains("dark");
|
||||
const isDark = document.documentElement.classList.contains('dark')
|
||||
|
||||
if (giscus) {
|
||||
const url = new URL(giscus.src);
|
||||
url.searchParams.set("theme", isDark ? "dark" : "light");
|
||||
giscus.src = url.toString();
|
||||
const url = new URL(giscus.src)
|
||||
url.searchParams.set('theme', isDark ? 'dark' : 'light')
|
||||
giscus.src = url.toString()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => init());
|
||||
document.addEventListener("astro:after-swap", () => init());
|
||||
preloadTheme();
|
||||
document.addEventListener('DOMContentLoaded', () => init())
|
||||
document.addEventListener('astro:after-swap', () => init())
|
||||
preloadTheme()
|
||||
</script>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
import Container from "@components/Container.astro";
|
||||
import Link from "@components/Link.astro";
|
||||
import { SITE } from "@consts";
|
||||
import ProgressBar from "./ProgressBar.astro";
|
||||
import Container from '@components/Container.astro'
|
||||
import Link from '@components/Link.astro'
|
||||
import { SITE } from '@consts'
|
||||
import ProgressBar from './ProgressBar.astro'
|
||||
---
|
||||
|
||||
<header transition:persist>
|
||||
|
|
|
@ -1,29 +1,23 @@
|
|||
---
|
||||
import { cn } from "@lib/utils";
|
||||
import { cn } from '@lib/utils'
|
||||
|
||||
type Props = {
|
||||
href: string;
|
||||
external?: boolean;
|
||||
underline?: boolean;
|
||||
group?: boolean;
|
||||
};
|
||||
href: string
|
||||
external?: boolean
|
||||
underline?: boolean
|
||||
group?: boolean
|
||||
}
|
||||
|
||||
const {
|
||||
href,
|
||||
external,
|
||||
underline = true,
|
||||
group = false,
|
||||
...rest
|
||||
} = Astro.props;
|
||||
const { href, external, underline = true, group = false, ...rest } = Astro.props
|
||||
---
|
||||
|
||||
<a
|
||||
href={href}
|
||||
target={external ? "_blank" : "_self"}
|
||||
target={external ? '_blank' : '_self'}
|
||||
class={cn(
|
||||
"inline-block decoration-black/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:decoration-white/30 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 hover:text-cyan-500 focus-visible:text-black dark:hover:text-orange-500 dark:focus-visible:text-white transition-colors duration-300 ease-in-out",
|
||||
underline && "underline underline-offset-[3px]",
|
||||
group && "group"
|
||||
'inline-block decoration-black/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:decoration-white/30 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 hover:text-cyan-500 focus-visible:text-black dark:hover:text-orange-500 dark:focus-visible:text-white transition-colors duration-300 ease-in-out',
|
||||
underline && 'underline underline-offset-[3px]',
|
||||
group && 'group',
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
---
|
||||
import Search from "astro-pagefind/components/Search";
|
||||
---
|
||||
|
||||
<aside data-pagefind-ignore>
|
||||
<div
|
||||
transition:persist
|
||||
id="backdrop"
|
||||
class="bg-[rgba(0, 0, 0, 0.5] invisible fixed left-0 top-0 z-50 flex h-screen w-full justify-center p-6 backdrop-blur-sm"
|
||||
>
|
||||
<div
|
||||
id="pagefind-container"
|
||||
class="m-0 flex h-fit max-h-[80%] w-full max-w-screen-sm flex-col overflow-auto rounded border border-black/15 bg-neutral-100 p-2 px-4 py-3 shadow-lg dark:border-white/20 dark:bg-neutral-900"
|
||||
>
|
||||
<Search
|
||||
id="search"
|
||||
className="pagefind-ui"
|
||||
uiOptions={{
|
||||
showImages: false,
|
||||
excerptLength: 15,
|
||||
resetStyles: false,
|
||||
}}
|
||||
/>
|
||||
<div class="mr-2 pb-1 pt-4 text-right text-xs dark:prose-invert">
|
||||
Press <span class="prose text-xs dark:prose-invert"
|
||||
><kbd class="">Esc</kbd></span
|
||||
> or click anywhere to close
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script is:inline>
|
||||
const magnifyingGlass = document.getElementById("magnifying-glass");
|
||||
const backdrop = document.getElementById("backdrop");
|
||||
|
||||
function openPagefind() {
|
||||
const searchDiv = document.getElementById("search");
|
||||
const search = searchDiv.querySelector("input");
|
||||
setTimeout(() => {
|
||||
search.focus();
|
||||
}, 0);
|
||||
backdrop?.classList.remove("invisible");
|
||||
backdrop?.classList.add("visible");
|
||||
}
|
||||
|
||||
function closePagefind() {
|
||||
const search = document.getElementById("search");
|
||||
search.value = "";
|
||||
backdrop?.classList.remove("visible");
|
||||
backdrop?.classList.add("invisible");
|
||||
}
|
||||
|
||||
// open pagefind
|
||||
magnifyingGlass?.addEventListener("click", () => {
|
||||
openPagefind();
|
||||
});
|
||||
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (e.key === "/") {
|
||||
e.preventDefault();
|
||||
openPagefind();
|
||||
} else if ((e.metaKey || e.ctrlKey) && e.key === "k") {
|
||||
e.preventDefault();
|
||||
openPagefind();
|
||||
}
|
||||
});
|
||||
|
||||
// close pagefind
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Escape" || e.keyCode === 27) {
|
||||
closePagefind();
|
||||
}
|
||||
});
|
||||
|
||||
// close pagefind when searched result(link) clicked
|
||||
document.addEventListener("click", (event) => {
|
||||
if (event.target.classList.contains("pagefind-ui__result-link")) {
|
||||
closePagefind();
|
||||
}
|
||||
});
|
||||
|
||||
backdrop?.addEventListener("click", (event) => {
|
||||
if (!event.target.closest("#pagefind-container")) {
|
||||
closePagefind();
|
||||
}
|
||||
});
|
||||
|
||||
// prevent form submission
|
||||
const form = document.getElementById("form");
|
||||
form?.addEventListener("submit", (event) => {
|
||||
event.preventDefault();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style is:global>
|
||||
:root {
|
||||
--pagefind-ui-scale: 0.75;
|
||||
--pagefind-ui-border-width: 1px;
|
||||
--pagefind-ui-border-radius: 3px;
|
||||
--pagefind-ui-font: "Geist", sans-serif;
|
||||
--pagefind-ui-primary: #3d3d3d;
|
||||
--pagefind-ui-text: #3d3d3d;
|
||||
--pagefind-ui-background: #ffffff;
|
||||
--pagefind-ui-border: #d0d0d0;
|
||||
--pagefind-ui-tag: #f5f5f5;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--pagefind-ui-primary: #d4d4d4;
|
||||
--pagefind-ui-text: #d4d4d4;
|
||||
--pagefind-ui-background: #171717;
|
||||
--pagefind-ui-border: #404040;
|
||||
}
|
||||
|
||||
#search input {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#search p {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#search .pagefind-ui__result-title {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#search .pagefind-ui__message {
|
||||
padding: 0;
|
||||
padding-bottom: 0.75rem;
|
||||
}
|
||||
</style>
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
const { prevPost, nextPost } = Astro.props;
|
||||
const { prevPost, nextPost } = Astro.props
|
||||
---
|
||||
|
||||
<div class="grid grid-cols-2 gap-1.5 sm:gap-3">
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
<div class="fixed w-full h-[2px] bg-neutral-300 dark:bg-slate-900 z-50">
|
||||
<div class="bg-cyan-500 dark:bg-orange-500 h-full"></div>
|
||||
<div class="fixed z-50 h-[2px] w-full bg-neutral-300 dark:bg-slate-900">
|
||||
<div class="h-full bg-cyan-500 dark:bg-orange-500"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
import { initializeProgressBar } from '../scripts/progress-bar.js';
|
||||
initializeProgressBar();
|
||||
import { initializeProgressBar } from '../scripts/progress-bar.js'
|
||||
initializeProgressBar()
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,74 +1,118 @@
|
|||
---
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
import { Image } from "astro:assets";
|
||||
import { HIGHLIGHTAUTHOR } from "@consts";
|
||||
import type { CollectionEntry } from 'astro:content'
|
||||
import { Image } from 'astro:assets'
|
||||
import { HIGHLIGHTAUTHOR } from '@consts'
|
||||
|
||||
type Props = {
|
||||
entry: CollectionEntry<"publications">;
|
||||
};
|
||||
entry: CollectionEntry<'publications'>
|
||||
}
|
||||
|
||||
const { entry } = Astro.props as {
|
||||
entry: CollectionEntry<"publications">;
|
||||
};
|
||||
entry: CollectionEntry<'publications'>
|
||||
}
|
||||
|
||||
const splitStr = (authors: string | undefined, targetAuthor: string) => {
|
||||
if (!authors) return [];
|
||||
const parts = authors.split(new RegExp(`(${targetAuthor})`, 'g'));
|
||||
return parts;
|
||||
};
|
||||
if (!authors) return []
|
||||
const parts = authors.split(new RegExp(`(${targetAuthor})`, 'g'))
|
||||
return parts
|
||||
}
|
||||
const decomposeURL = (URL: string | undefined) => {
|
||||
if (!URL) return { text: '', url: '' };
|
||||
const parts = URL.split(": ");
|
||||
return { text: parts[0], url: parts[1] };
|
||||
};
|
||||
|
||||
const dataLink = decomposeURL(entry.data.dataURL);
|
||||
const paperLink = decomposeURL(entry.data.paperURL);
|
||||
const codeLink = decomposeURL(entry.data.codeURL);
|
||||
const webLink = decomposeURL(entry.data.webURL);
|
||||
const authorsParts = splitStr(entry.data.authors, HIGHLIGHTAUTHOR);
|
||||
if (!URL) return { text: '', url: '' }
|
||||
const parts = URL.split(': ')
|
||||
return { text: parts[0], url: parts[1] }
|
||||
}
|
||||
|
||||
const dataLink = decomposeURL(entry.data.dataURL)
|
||||
const paperLink = decomposeURL(entry.data.paperURL)
|
||||
const codeLink = decomposeURL(entry.data.codeURL)
|
||||
const webLink = decomposeURL(entry.data.webURL)
|
||||
const authorsParts = splitStr(entry.data.authors, HIGHLIGHTAUTHOR)
|
||||
---
|
||||
|
||||
<div
|
||||
class="w-full not-prose group relative grid grid-cols-auto md:grid-cols-[204px_auto] gap-4 rounded-lg items-center border border-black/15 px-4 py-3 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"
|
||||
class="not-prose grid-cols-auto group relative grid w-full items-center gap-4 rounded-lg border border-black/15 px-4 py-3 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white md:grid-cols-[204px_auto]"
|
||||
>
|
||||
<Image
|
||||
src={entry.data.img ?? ''}
|
||||
alt={entry.data.imgAlt ?? ''}
|
||||
width={640}
|
||||
height={480}
|
||||
class="sm:w-[240px] sm:h-[135px] shadow-sm rounded-md sm:mr-6 hover:opacity-80 transition hidden md:flex"
|
||||
loading="eager"
|
||||
src={entry.data.img ?? ''}
|
||||
alt={entry.data.imgAlt ?? ''}
|
||||
width={640}
|
||||
height={480}
|
||||
class="hidden rounded-md shadow-sm transition hover:opacity-80 sm:mr-6 sm:h-[135px] sm:w-[240px] md:flex"
|
||||
loading="eager"
|
||||
/>
|
||||
|
||||
|
||||
<div class="flex items-center h-full">
|
||||
<div class="flex h-full items-center">
|
||||
<div class="flex flex-col">
|
||||
<div class="w-full">
|
||||
<div class="text-md font-semibold w-full">
|
||||
<div class="text-md w-full font-semibold">
|
||||
{entry.data.title}
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
{authorsParts.map((part:any) =>
|
||||
part === HIGHLIGHTAUTHOR ? <u><strong>{part}</strong></u> : part
|
||||
)}
|
||||
<div class="w-full text-sm">
|
||||
{
|
||||
authorsParts.map((part: any) =>
|
||||
part === HIGHLIGHTAUTHOR ? (
|
||||
<u>
|
||||
<strong>{part}</strong>
|
||||
</u>
|
||||
) : (
|
||||
part
|
||||
),
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
{paperLink.url!="" && <a class="underline hover:text-cyan-500 text-orange-500 dark:hover:text-cyan-500 transition-colors duration-300 ease-in-out visited:text-indigo-400" target="_blank" href={paperLink.url}>{paperLink.text}</a>}
|
||||
{codeLink.url!="" && <a class="underline hover:text-cyan-500 text-orange-500 dark:hover:text-cyan-500 transition-colors duration-300 ease-in-out visited:text-indigo-400" target="_blank" href={codeLink.url}>{codeLink.text}</a>}
|
||||
{webLink.url!="" && <a class="underline hover:text-cyan-500 text-orange-500 dark:hover:text-cyan-500 transition-colors duration-300 ease-in-out visited:text-indigo-400" target="_blank" href={webLink.url}>{webLink.text}</a>}
|
||||
{dataLink.url!="" && <a class="underline hover:text-cyan-500 text-orange-500 dark:hover:text-cyan-500 transition-colors duration-300 ease-in-out visited:text-indigo-400" target="_blank" href={dataLink.url}>{dataLink.text}</a>}
|
||||
<div class="w-full text-sm">
|
||||
{
|
||||
paperLink.url != '' && (
|
||||
<a
|
||||
class="text-orange-500 underline transition-colors duration-300 ease-in-out visited:text-indigo-400 hover:text-cyan-500 dark:hover:text-cyan-500"
|
||||
target="_blank"
|
||||
href={paperLink.url}
|
||||
>
|
||||
{paperLink.text}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
{
|
||||
codeLink.url != '' && (
|
||||
<a
|
||||
class="text-orange-500 underline transition-colors duration-300 ease-in-out visited:text-indigo-400 hover:text-cyan-500 dark:hover:text-cyan-500"
|
||||
target="_blank"
|
||||
href={codeLink.url}
|
||||
>
|
||||
{codeLink.text}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
{
|
||||
webLink.url != '' && (
|
||||
<a
|
||||
class="text-orange-500 underline transition-colors duration-300 ease-in-out visited:text-indigo-400 hover:text-cyan-500 dark:hover:text-cyan-500"
|
||||
target="_blank"
|
||||
href={webLink.url}
|
||||
>
|
||||
{webLink.text}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
{
|
||||
dataLink.url != '' && (
|
||||
<a
|
||||
class="text-orange-500 underline transition-colors duration-300 ease-in-out visited:text-indigo-400 hover:text-cyan-500 dark:hover:text-cyan-500"
|
||||
target="_blank"
|
||||
href={dataLink.url}
|
||||
>
|
||||
{dataLink.text}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div class="text-sm">
|
||||
In <div class="inline italic">{entry.data.pub}</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm mt-2 break-words">
|
||||
<p class="mt-2 break-words text-sm">
|
||||
{entry.data.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
---
|
||||
import 'bootstrap-icons/font/bootstrap-icons.css';
|
||||
import 'bootstrap-icons/font/bootstrap-icons.css'
|
||||
|
||||
export interface Props {
|
||||
URL: string;
|
||||
icon: string;
|
||||
icon_size: string
|
||||
URL: string
|
||||
icon: string
|
||||
icon_size: string
|
||||
}
|
||||
|
||||
const { URL, icon, icon_size } = Astro.props;
|
||||
|
||||
const { URL, icon, icon_size } = Astro.props
|
||||
---
|
||||
|
||||
<a
|
||||
href={URL}
|
||||
target={"_blank"}
|
||||
class={
|
||||
`inline-block ${icon_size} decoration-black/30 dark:decoration-white/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 text-current hover:text-cyan-500 focus-visible:text-black dark:hover:text-orange-500 dark:focus-visible:text-white transition-colors duration-300 ease-in-out`}>
|
||||
<i class={`bi bi-${icon}`}></i>
|
||||
</a>
|
||||
href={URL}
|
||||
target={'_blank'}
|
||||
class={`inline-block ${icon_size} decoration-black/30 dark:decoration-white/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 text-current hover:text-cyan-500 focus-visible:text-black dark:hover:text-orange-500 dark:focus-visible:text-white transition-colors duration-300 ease-in-out`}
|
||||
>
|
||||
<i class={`bi bi-${icon}`}></i>
|
||||
</a>
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
---
|
||||
import SocialIcon from "@components/SocialIcon.astro";
|
||||
import { SITE } from "@consts";
|
||||
import SocialIcon from '@components/SocialIcon.astro'
|
||||
import { SITE } from '@consts'
|
||||
|
||||
export interface Props {
|
||||
icon_size: string
|
||||
icon_size: string
|
||||
}
|
||||
|
||||
const { icon_size } = Astro.props;
|
||||
|
||||
const { icon_size } = Astro.props
|
||||
---
|
||||
|
||||
<ul class="not-prose flex flex-wrap gap-2">
|
||||
<SocialIcon icon_size={icon_size} URL="#" icon="twitter-x"/>
|
||||
<SocialIcon icon_size={icon_size} URL="#" icon="github"/>
|
||||
<SocialIcon icon_size={icon_size} URL="#" icon="linkedin"/>
|
||||
<SocialIcon icon_size={icon_size} URL="#" icon="envelope-fill"/>
|
||||
<SocialIcon icon_size={icon_size} URL="#" icon="mortarboard-fill"/>
|
||||
<SocialIcon icon_size={icon_size} URL={`${SITE.SITEURL}/rss.xml`} icon="rss-fill"/>
|
||||
</ul>
|
||||
<SocialIcon icon_size={icon_size} URL="#" icon="twitter-x" />
|
||||
<SocialIcon icon_size={icon_size} URL="#" icon="github" />
|
||||
<SocialIcon icon_size={icon_size} URL="#" icon="linkedin" />
|
||||
<SocialIcon icon_size={icon_size} URL="#" icon="envelope-fill" />
|
||||
<SocialIcon icon_size={icon_size} URL="#" icon="mortarboard-fill" />
|
||||
<SocialIcon
|
||||
icon_size={icon_size}
|
||||
URL={`${SITE.SITEURL}/rss.xml`}
|
||||
icon="rss-fill"
|
||||
/>
|
||||
</ul>
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
---
|
||||
import TableOfContentsHeading from "./TableOfContentsHeading.astro";
|
||||
import TableOfContentsHeading from './TableOfContentsHeading.astro'
|
||||
|
||||
// https://kld.dev/building-table-of-contents/
|
||||
const { headings } = Astro.props;
|
||||
const toc = buildToc(headings);
|
||||
const { headings } = Astro.props
|
||||
const toc = buildToc(headings)
|
||||
|
||||
export interface Heading {
|
||||
depth: number;
|
||||
slug: string;
|
||||
text: string;
|
||||
depth: number
|
||||
slug: string
|
||||
text: string
|
||||
}
|
||||
|
||||
function buildToc(headings: Heading[]) {
|
||||
const toc: Heading[] = [];
|
||||
const parentHeadings = new Map();
|
||||
const toc: Heading[] = []
|
||||
const parentHeadings = new Map()
|
||||
headings.forEach((h) => {
|
||||
const heading = { ...h, subheadings: [] };
|
||||
parentHeadings.set(heading.depth, heading);
|
||||
const heading = { ...h, subheadings: [] }
|
||||
parentHeadings.set(heading.depth, heading)
|
||||
if (heading.depth === 2) {
|
||||
toc.push(heading);
|
||||
toc.push(heading)
|
||||
} else {
|
||||
parentHeadings.get(heading.depth - 1).subheadings.push(heading);
|
||||
parentHeadings.get(heading.depth - 1).subheadings.push(heading)
|
||||
}
|
||||
});
|
||||
return toc;
|
||||
})
|
||||
return toc
|
||||
}
|
||||
---
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
---
|
||||
import type { Heading } from "./TableOfContents.astro";
|
||||
import Link from "./Link.astro";
|
||||
import type { Heading } from './TableOfContents.astro'
|
||||
import Link from './Link.astro'
|
||||
|
||||
// https://kld.dev/building-table-of-contents/
|
||||
|
||||
const { heading } = Astro.props;
|
||||
const { heading } = Astro.props
|
||||
---
|
||||
|
||||
<li class="list-inside list-disc px-6 py-1.5 text-sm">
|
||||
<Link href={"#" + heading.slug} underline>
|
||||
<Link href={'#' + heading.slug} underline>
|
||||
{heading.text}
|
||||
</Link>
|
||||
{
|
||||
|
|
|
@ -1,46 +1,43 @@
|
|||
import type { Metadata, Site } from "@types";
|
||||
import type { Metadata, Site } from '@types'
|
||||
|
||||
export const SITE: Site = {
|
||||
TITLE: "Astro Micro Academics",
|
||||
DESCRIPTION: "Astro Micro Academics is for academic user.",
|
||||
EMAIL: "youremial@gmail.com",
|
||||
TITLE: 'Astro Micro Academics',
|
||||
DESCRIPTION: 'Astro Micro Academics is for academic user.',
|
||||
EMAIL: 'youremial@gmail.com',
|
||||
NUM_POSTS_ON_HOMEPAGE: 2,
|
||||
NUM_PUBLICATIONS_ON_HOMEPAGE: 3,
|
||||
SITEURL: 'https://astro-micro-academic.vercel.app' // Update here to link the RSS icon to your website rss
|
||||
};
|
||||
SITEURL: 'https://astro-micro-academic.vercel.app', // Update here to link the RSS icon to your website rss
|
||||
}
|
||||
|
||||
export const HIGHLIGHTAUTHOR = "John B"
|
||||
export const HIGHLIGHTAUTHOR = 'John B'
|
||||
|
||||
export const HOME: Metadata = {
|
||||
TITLE: "Home",
|
||||
DESCRIPTION: "Astro Micro is an accessible theme for Astro.",
|
||||
};
|
||||
TITLE: 'Home',
|
||||
DESCRIPTION: 'Astro Micro is an accessible theme for Astro.',
|
||||
}
|
||||
|
||||
export const BLOG: Metadata = {
|
||||
TITLE: "Blog",
|
||||
DESCRIPTION: "A collection of articles on topics I am passionate about.",
|
||||
};
|
||||
TITLE: 'Blog',
|
||||
DESCRIPTION: 'A collection of articles on topics I am passionate about.',
|
||||
}
|
||||
|
||||
export const RESEARCH: Metadata = {
|
||||
TITLE: "Publications",
|
||||
TITLE: 'Publications',
|
||||
DESCRIPTION:
|
||||
"A collection of my publications with links to paper, repositories and live demos.",
|
||||
};
|
||||
'A collection of my publications with links to paper, repositories and live demos.',
|
||||
}
|
||||
|
||||
export const CV: Metadata = {
|
||||
TITLE: "CV",
|
||||
DESCRIPTION:
|
||||
"your cv",
|
||||
};
|
||||
TITLE: 'CV',
|
||||
DESCRIPTION: 'your cv',
|
||||
}
|
||||
|
||||
export const TAGS: Metadata = {
|
||||
TITLE: "TAGS",
|
||||
DESCRIPTION:
|
||||
"blog tag filter",
|
||||
};
|
||||
TITLE: 'TAGS',
|
||||
DESCRIPTION: 'blog tag filter',
|
||||
}
|
||||
|
||||
export const ABOUT: Metadata = {
|
||||
TITLE: "ABOUT",
|
||||
DESCRIPTION:
|
||||
"A self-intro",
|
||||
};
|
||||
TITLE: 'ABOUT',
|
||||
DESCRIPTION: 'A self-intro',
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
---
|
||||
title: "[Logs] What is new in Astro Micro Academic"
|
||||
description: "Features, enhancements, and changes."
|
||||
date: "2024-07-25"
|
||||
title: '[Logs] What is new in Astro Micro Academic'
|
||||
description: 'Features, enhancements, and changes.'
|
||||
date: '2024-07-25'
|
||||
tags: ['log', 'rss-feed']
|
||||
---
|
||||
|
||||
:exclamation: Also refer to [Old] posts to see examples and changes. Some changes are removed in this version, which are marked.
|
||||
:exclamation: Also refer to [Old] posts to see examples and changes. Some changes are removed in this version, which are marked.
|
||||
|
||||
## What is New
|
||||
|
||||
|
@ -13,18 +13,18 @@ tags: ['log', 'rss-feed']
|
|||
- Add News, Research, Publication, CV sections
|
||||
- add icon to connect section
|
||||
- Add tag function to the blog
|
||||
- add RSS Feed icon
|
||||
- add RSS Feed icon
|
||||
- add tags to post slug and enable tag based search
|
||||
- add function to RSS feed only posts with rss-feed tags
|
||||
- add function to RSS feed only posts with rss-feed tags
|
||||
- Change SOCIALS
|
||||
- add highlight author
|
||||
- redo the news section height
|
||||
- support markdown emoji :blush: :exclamation:
|
||||
- Clear and rearrange all the posts
|
||||
- [x] rewrite astro-micro-academics
|
||||
- [x] astro micro
|
||||
- [x] get started with astro micro
|
||||
- [x] blog collection example
|
||||
- Clear and rearrange all the posts
|
||||
- [x] rewrite astro-micro-academics
|
||||
- [x] astro micro
|
||||
- [x] get started with astro micro
|
||||
- [x] blog collection example
|
||||
|
||||
---
|
||||
|
||||
|
@ -32,9 +32,9 @@ tags: ['log', 'rss-feed']
|
|||
|
||||
- Add Group Page
|
||||
- Add Opening Section
|
||||
- Add Award Page
|
||||
- Write a complete personal website setup guide
|
||||
- screenshot and submit theme to astro
|
||||
- Add Award Page
|
||||
- Write a complete personal website setup guide
|
||||
- screenshot and submit theme to astro
|
||||
- add progress bar on the top
|
||||
- show tags on allowcard
|
||||
- fix news section scroll bar
|
||||
|
@ -48,4 +48,5 @@ a = \sum_{n=1}^{22} \sqrt{a+b_n}
|
|||
$$
|
||||
|
||||
## 中文测试
|
||||
这里是中文测试
|
||||
|
||||
这里是中文测试
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
---
|
||||
title: "[Tutorial] Getting started with Astro-Micro-Academics"
|
||||
description: "Hit the ground running."
|
||||
date: "2024-07-26"
|
||||
title: '[Tutorial] Getting started with Astro-Micro-Academics'
|
||||
description: 'Hit the ground running.'
|
||||
date: '2024-07-26'
|
||||
tags: ['guide', 'tutorial']
|
||||
---
|
||||
|
||||
:exclamation: Also refer to [Old] posts to see examples and changes. Some changes are removed in this version, which are marked.
|
||||
:exclamation: Also refer to [Old] posts to see examples and changes. Some changes are removed in this version, which are marked.
|
||||
|
||||
## Install Astro-Micro-Academics
|
||||
## Install Astro-Micro-Academics
|
||||
|
||||
Clone the [repository](https://github.com/jingwu2121/astro-micro-academic).
|
||||
|
||||
|
@ -24,6 +24,7 @@ npm i
|
|||
```
|
||||
|
||||
Run local server
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
@ -32,55 +33,72 @@ npm run dev
|
|||
|
||||
Update your home page in `src/pages/index.astro`.
|
||||
|
||||
|
||||
## CV & About
|
||||
|
||||
Update your CV and About page in `src/pages/cv.astro` and `src/pages/about.astro`.
|
||||
|
||||
```ts
|
||||
const works = [
|
||||
{company:"Company A", time: "2022-Present", job_title: "Research Scientist", location: "London, UK", description: "Your Notes about the job"},
|
||||
{company:"Company A", time: "2022-Present", job_title: "Research Scientist", location: "London, UK", description: "Your Notes about the job"},
|
||||
{
|
||||
company: 'Company A',
|
||||
time: '2022-Present',
|
||||
job_title: 'Research Scientist',
|
||||
location: 'London, UK',
|
||||
description: 'Your Notes about the job',
|
||||
},
|
||||
{
|
||||
company: 'Company A',
|
||||
time: '2022-Present',
|
||||
job_title: 'Research Scientist',
|
||||
location: 'London, UK',
|
||||
description: 'Your Notes about the job',
|
||||
},
|
||||
]
|
||||
const educations = [
|
||||
{school:"University 1", time: "2022-Present", job_title: "BEng in Electronic Information Engineering", location: "London, UK", description: "Your Notes about the study"},
|
||||
{
|
||||
school: 'University 1',
|
||||
time: '2022-Present',
|
||||
job_title: 'BEng in Electronic Information Engineering',
|
||||
location: 'London, UK',
|
||||
description: 'Your Notes about the study',
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
## Social Links
|
||||
|
||||
Update the social links in `src/components/SocialIcons.astro`, simply replace the `URL`.
|
||||
Update the social links in `src/components/SocialIcons.astro`, simply replace the `URL`.
|
||||
|
||||
## Publications metadata
|
||||
|
||||
Metadata is required for each post. Add a new `publication.md` to automartically add a publication on the website. Publications are sorted by date.
|
||||
Metadata is required for each post. Add a new `publication.md` to automartically add a publication on the website. Publications are sorted by date.
|
||||
|
||||
```astro
|
||||
---
|
||||
title: "Diffusion Models Beat GANs on Image Synthesis"
|
||||
description: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias earum quod quo repellat blanditiis est iste eos dolorem! Voluptatibus corporis totam sed unde est iusto neque iure natus adipisci omnis."
|
||||
date: "2024-07-26"
|
||||
authors: "John B*, Jon A*, Frank C, John B, Jon A, Frank C"
|
||||
paperURL: "Paper: https://astro-sphere-demo.vercel.app"
|
||||
codeURL: "Code: "
|
||||
webURL: "Web: https://github.com/markhorn-dev/astro-sphere"
|
||||
dataURL: "Data: https://github.com/markhorn-dev/astro-sphere"
|
||||
img: "/rupert-cat.gif"
|
||||
imgAlt: "Paper Teaser"
|
||||
pub: "ECCV2024"
|
||||
title: 'Diffusion Models Beat GANs on Image Synthesis'
|
||||
description: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias earum quod quo repellat blanditiis est iste eos dolorem! Voluptatibus corporis totam sed unde est iusto neque iure natus adipisci omnis.'
|
||||
date: '2024-07-26'
|
||||
authors: 'John B*, Jon A*, Frank C, John B, Jon A, Frank C'
|
||||
paperURL: 'Paper: https://astro-sphere-demo.vercel.app'
|
||||
codeURL: 'Code: '
|
||||
webURL: 'Web: https://github.com/markhorn-dev/astro-sphere'
|
||||
dataURL: 'Data: https://github.com/markhorn-dev/astro-sphere'
|
||||
img: '/rupert-cat.gif'
|
||||
imgAlt: 'Paper Teaser'
|
||||
pub: 'ECCV2024'
|
||||
---
|
||||
```
|
||||
|
||||
| Field | Req | Type | Remarks |
|
||||
| :---------- | :-- | :------ | :----------------------------------------------- |
|
||||
| title | Yes | string | Title of the content. Used in SEO and RSS. |
|
||||
| description | Yes | string | Description of the content. Used in SEO and RSS. |
|
||||
| date | Yes | string | Must be a valid date string (able to be parsed). |
|
||||
| authors | Yes | string | A string seperated by comma. |
|
||||
| paperURL, codeURL, webURL, dataURL | Yes | string | A string seperated by ": ". If you don't have a link to add, leave the link part blank, e.g. `codeURL: "Code: "` |
|
||||
| img | Yes | string | Path to teaser image. |
|
||||
| imgAlt | Yes | string | Description of the image. |
|
||||
| pub | Yes | string | The conference or journal |
|
||||
| Field | Req | Type | Remarks |
|
||||
| :--------------------------------- | :-- | :----- | :--------------------------------------------------------------------------------------------------------------- |
|
||||
| title | Yes | string | Title of the content. Used in SEO and RSS. |
|
||||
| description | Yes | string | Description of the content. Used in SEO and RSS. |
|
||||
| date | Yes | string | Must be a valid date string (able to be parsed). |
|
||||
| authors | Yes | string | A string seperated by comma. |
|
||||
| paperURL, codeURL, webURL, dataURL | Yes | string | A string seperated by ": ". If you don't have a link to add, leave the link part blank, e.g. `codeURL: "Code: "` |
|
||||
| img | Yes | string | Path to teaser image. |
|
||||
| imgAlt | Yes | string | Description of the image. |
|
||||
| pub | Yes | string | The conference or journal |
|
||||
|
||||
## Blog metadata
|
||||
|
||||
|
@ -88,11 +106,11 @@ Metadata is required for each post.
|
|||
|
||||
```astro
|
||||
---
|
||||
title: "Blog Collection";
|
||||
description: "How to add posts to the blog.";
|
||||
date: "2024-03-21";
|
||||
title: 'Blog Collection'
|
||||
description: 'How to add posts to the blog.'
|
||||
date: '2024-03-21'
|
||||
tags: ['guide', 'tutorial']
|
||||
draft: false;
|
||||
draft: false
|
||||
---
|
||||
```
|
||||
|
||||
|
@ -101,10 +119,10 @@ draft: false;
|
|||
| title | Yes | string | Title of the content. Used in SEO and RSS. |
|
||||
| description | Yes | string | Description of the content. Used in SEO and RSS. |
|
||||
| date | Yes | string | Must be a valid date string (able to be parsed). |
|
||||
| tags | Yes | list | A list of strings |
|
||||
| tags | Yes | list | A list of strings |
|
||||
| draft | No | boolean | If draft: true, content will not be published. |
|
||||
|
||||
## Customize the website metadata and set up RSS
|
||||
## Customize the website metadata and set up RSS
|
||||
|
||||
To change the website metadata, edit `src/consts.ts`.
|
||||
|
||||
|
@ -112,27 +130,27 @@ To change the website metadata, edit `src/consts.ts`.
|
|||
// src/consts.ts
|
||||
|
||||
export const SITE: Site = {
|
||||
TITLE: "Astro Micro Academics",
|
||||
DESCRIPTION: "Astro Micro Academics is for academic user.",
|
||||
EMAIL: "youremial@gmail.com",
|
||||
TITLE: 'Astro Micro Academics',
|
||||
DESCRIPTION: 'Astro Micro Academics is for academic user.',
|
||||
EMAIL: 'youremial@gmail.com',
|
||||
NUM_POSTS_ON_HOMEPAGE: 2,
|
||||
NUM_PUBLICATIONS_ON_HOMEPAGE: 3,
|
||||
SITEURL: 'https://astro-micro-academic.vercel.app' // Update here to link the RSS icon to your website RSS
|
||||
};
|
||||
SITEURL: 'https://astro-micro-academic.vercel.app', // Update here to link the RSS icon to your website RSS
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Req | Description |
|
||||
| :----------- | :-- | :--------------------------------------------------- |
|
||||
| TITLE | Yes | Displayed in header and footer. Used in SEO and RSS. |
|
||||
| DESCRIPTION | Yes | Used in SEO and RSS. |
|
||||
| EMAIL | Yes | Displayed in contact section. |
|
||||
| NUM_POSTS | Yes | Limit number of posts on home page. |
|
||||
| Field | Req | Description |
|
||||
| :--------------- | :-- | :--------------------------------------------------- |
|
||||
| TITLE | Yes | Displayed in header and footer. Used in SEO and RSS. |
|
||||
| DESCRIPTION | Yes | Used in SEO and RSS. |
|
||||
| EMAIL | Yes | Displayed in contact section. |
|
||||
| NUM_POSTS | Yes | Limit number of posts on home page. |
|
||||
| NUM_PUBLICATIONS | Yes | Limit number of research on home page. |
|
||||
| SITEURL | Yes | Your website URL |
|
||||
| SITEURL | Yes | Your website URL |
|
||||
|
||||
### RSS Post
|
||||
|
||||
Please tag the post of RSS feed with tag `"rss-feed"`, other posts are not included in the RSS.
|
||||
Please tag the post of RSS feed with tag `"rss-feed"`, other posts are not included in the RSS.
|
||||
|
||||
---
|
||||
|
||||
|
@ -141,7 +159,7 @@ Please tag the post of RSS feed with tag `"rss-feed"`, other posts are not inclu
|
|||
```ts
|
||||
// src/consts.ts
|
||||
|
||||
export const HIGHLIGHTAUTHOR = "John B"
|
||||
export const HIGHLIGHTAUTHOR = 'John B'
|
||||
```
|
||||
|
||||
## Customize metadata for individual pages
|
||||
|
@ -150,38 +168,35 @@ export const HIGHLIGHTAUTHOR = "John B"
|
|||
// src/consts.ts
|
||||
|
||||
export const HOME: Metadata = {
|
||||
TITLE: "Home",
|
||||
DESCRIPTION: "Astro Micro is an accessible theme for Astro.",
|
||||
};
|
||||
TITLE: 'Home',
|
||||
DESCRIPTION: 'Astro Micro is an accessible theme for Astro.',
|
||||
}
|
||||
|
||||
export const BLOG: Metadata = {
|
||||
TITLE: "Blog",
|
||||
DESCRIPTION: "A collection of articles on topics I am passionate about.",
|
||||
};
|
||||
TITLE: 'Blog',
|
||||
DESCRIPTION: 'A collection of articles on topics I am passionate about.',
|
||||
}
|
||||
|
||||
export const RESEARCH: Metadata = {
|
||||
TITLE: "Publications",
|
||||
TITLE: 'Publications',
|
||||
DESCRIPTION:
|
||||
"A collection of my publications with links to paper, repositories and live demos.",
|
||||
};
|
||||
'A collection of my publications with links to paper, repositories and live demos.',
|
||||
}
|
||||
|
||||
export const CV: Metadata = {
|
||||
TITLE: "CV",
|
||||
DESCRIPTION:
|
||||
"your cv",
|
||||
};
|
||||
TITLE: 'CV',
|
||||
DESCRIPTION: 'your cv',
|
||||
}
|
||||
|
||||
export const TAGS: Metadata = {
|
||||
TITLE: "TAGS",
|
||||
DESCRIPTION:
|
||||
"blog tag filter",
|
||||
};
|
||||
TITLE: 'TAGS',
|
||||
DESCRIPTION: 'blog tag filter',
|
||||
}
|
||||
|
||||
export const ABOUT: Metadata = {
|
||||
TITLE: "ABOUT",
|
||||
DESCRIPTION:
|
||||
"A self-intro",
|
||||
};
|
||||
TITLE: 'ABOUT',
|
||||
DESCRIPTION: 'A self-intro',
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Req | Description |
|
||||
|
@ -206,12 +221,11 @@ To set up RSS and Giscus, it's easier if the site is deployed and has a URL for
|
|||
|
||||
To deploy manually see [Astro's docs](https://docs.astro.build/en/guides/deploy/).
|
||||
|
||||
To deploy to Github, see [here](https://docs.astro.build/en/guides/deploy/github/).
|
||||
|
||||
To deploy to Github, see [here](https://docs.astro.build/en/guides/deploy/github/).
|
||||
|
||||
## Set up Giscus (from Astro Micro)
|
||||
|
||||
Follow the steps at [giscus.app](https://giscus.app). Once you get your custom Giscus script from that site, go to `Giscus.astro` and replace that script with your own.
|
||||
Follow the steps at [giscus.app](https://giscus.app). Once you get your custom Giscus script from that site, go to `Giscus.astro` and replace that script with your own.
|
||||
|
||||
```js
|
||||
// src/components/Giscus.astro
|
||||
|
@ -232,8 +246,8 @@ Follow the steps at [giscus.app](https://giscus.app). Once you get your custom
|
|||
data-lang="en"
|
||||
data-loading="lazy"
|
||||
crossorigin="anonymous"
|
||||
async></script>
|
||||
|
||||
async
|
||||
></script>
|
||||
```
|
||||
|
||||
To change the Giscus themes used, edit the `setGiscusTheme` function in `Head.astro`.
|
||||
|
@ -242,15 +256,15 @@ To change the Giscus themes used, edit the `setGiscusTheme` function in `Head.as
|
|||
// src/components/Head.astro
|
||||
|
||||
const setGiscusTheme = () => {
|
||||
const giscus = document.querySelector(".giscus-frame");
|
||||
const giscus = document.querySelector('.giscus-frame')
|
||||
|
||||
const isDark = document.documentElement.classList.contains("dark");
|
||||
const isDark = document.documentElement.classList.contains('dark')
|
||||
|
||||
if (giscus) {
|
||||
const url = new URL(giscus.src);
|
||||
const url = new URL(giscus.src)
|
||||
// Change "dark" and "light" to other Giscus themes
|
||||
url.searchParams.set("theme", isDark ? "dark" : "light");
|
||||
giscus.src = url.toString();
|
||||
url.searchParams.set('theme', isDark ? 'dark' : 'light')
|
||||
giscus.src = url.toString()
|
||||
}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
---
|
||||
title: "[Old] Everything new in Astro Micro"
|
||||
description: "Features, enhancements, and changes."
|
||||
date: "2024-05-09"
|
||||
title: '[Old] Everything new in Astro Micro'
|
||||
description: 'Features, enhancements, and changes.'
|
||||
date: '2024-05-09'
|
||||
tags: ['astro-micro']
|
||||
---
|
||||
|
||||
import Callout from "@/components/Callout.astro";
|
||||
import Callout from '@/components/Callout.astro'
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "[Old] Getting started with Astro-Micro"
|
||||
description: "Hit the ground running."
|
||||
date: "2024-03-22"
|
||||
title: '[Old] Getting started with Astro-Micro'
|
||||
description: 'Hit the ground running.'
|
||||
date: '2024-03-22'
|
||||
tags: ['guide', 'start']
|
||||
---
|
||||
|
||||
|
@ -39,20 +39,20 @@ To change the website metadata, edit `src/consts.ts`.
|
|||
// src/consts.ts
|
||||
|
||||
export const SITE: Site = {
|
||||
NAME: "Astro Micro",
|
||||
DESCRIPTION: "Astro Micro is an accessible theme for Astro.",
|
||||
EMAIL: "trevortylerlee@gmail.com",
|
||||
NAME: 'Astro Micro',
|
||||
DESCRIPTION: 'Astro Micro is an accessible theme for Astro.',
|
||||
EMAIL: 'trevortylerlee@gmail.com',
|
||||
NUM_POSTS_ON_HOMEPAGE: 3,
|
||||
NUM_PUBLICATIONS_ON_HOMEPAGE: 3,
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Req | Description |
|
||||
| :----------- | :-- | :--------------------------------------------------- |
|
||||
| TITLE | Yes | Displayed in header and footer. Used in SEO and RSS. |
|
||||
| DESCRIPTION | Yes | Used in SEO and RSS. |
|
||||
| EMAIL | Yes | Displayed in contact section. |
|
||||
| NUM_POSTS | Yes | Limit number of posts on home page. |
|
||||
| Field | Req | Description |
|
||||
| :--------------- | :-- | :--------------------------------------------------- |
|
||||
| TITLE | Yes | Displayed in header and footer. Used in SEO and RSS. |
|
||||
| DESCRIPTION | Yes | Used in SEO and RSS. |
|
||||
| EMAIL | Yes | Displayed in contact section. |
|
||||
| NUM_POSTS | Yes | Limit number of posts on home page. |
|
||||
| NUM_PUBLICATIONS | Yes | Limit number of research on home page. |
|
||||
|
||||
---
|
||||
|
@ -63,9 +63,9 @@ export const SITE: Site = {
|
|||
// src/consts.ts
|
||||
|
||||
export const ABOUT: Metadata = {
|
||||
TITLE: "About",
|
||||
DESCRIPTION: "Astro Micro is a fork of Astro Nano.",
|
||||
};
|
||||
TITLE: 'About',
|
||||
DESCRIPTION: 'Astro Micro is a fork of Astro Nano.',
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Req | Description |
|
||||
|
@ -82,18 +82,18 @@ export const ABOUT: Metadata = {
|
|||
|
||||
export const SOCIALS: Socials = [
|
||||
{
|
||||
NAME: "twitter-x",
|
||||
HREF: "https://twitter.com/boogerbuttcheeks",
|
||||
NAME: 'twitter-x',
|
||||
HREF: 'https://twitter.com/boogerbuttcheeks',
|
||||
},
|
||||
{
|
||||
NAME: "github",
|
||||
HREF: "https://github.com/trevortylerlee",
|
||||
NAME: 'github',
|
||||
HREF: 'https://github.com/trevortylerlee',
|
||||
},
|
||||
{
|
||||
NAME: "linkedin",
|
||||
HREF: "https://www.linkedin.com/in/trevortylerlee",
|
||||
NAME: 'linkedin',
|
||||
HREF: 'https://www.linkedin.com/in/trevortylerlee',
|
||||
},
|
||||
];
|
||||
]
|
||||
```
|
||||
|
||||
| Field | Req | Description |
|
||||
|
@ -124,19 +124,19 @@ Change the `site` option to the deployed site's URL.
|
|||
// astro.config.mjs
|
||||
|
||||
export default defineConfig({
|
||||
site: "https://astro-micro.vercel.app",
|
||||
site: 'https://astro-micro.vercel.app',
|
||||
integrations: [tailwind(), sitemap(), mdx(), pagefind()],
|
||||
markdown: {
|
||||
shikiConfig: {
|
||||
theme: "css-variables",
|
||||
theme: 'css-variables',
|
||||
},
|
||||
},
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
## Set up Giscus
|
||||
|
||||
Follow the steps at [giscus.app](https://giscus.app). Once you get your custom Giscus script from that site, go to `Giscus.astro` and replace that script with your own.
|
||||
Follow the steps at [giscus.app](https://giscus.app). Once you get your custom Giscus script from that site, go to `Giscus.astro` and replace that script with your own.
|
||||
|
||||
```js
|
||||
// src/components/Giscus.astro
|
||||
|
@ -157,8 +157,8 @@ Follow the steps at [giscus.app](https://giscus.app). Once you get your custom
|
|||
data-lang="en"
|
||||
data-loading="lazy"
|
||||
crossorigin="anonymous"
|
||||
async></script>
|
||||
|
||||
async
|
||||
></script>
|
||||
```
|
||||
|
||||
To change the Giscus themes used, edit the `setGiscusTheme` function in `Head.astro`.
|
||||
|
@ -167,15 +167,15 @@ To change the Giscus themes used, edit the `setGiscusTheme` function in `Head.as
|
|||
// src/components/Head.astro
|
||||
|
||||
const setGiscusTheme = () => {
|
||||
const giscus = document.querySelector(".giscus-frame");
|
||||
const giscus = document.querySelector('.giscus-frame')
|
||||
|
||||
const isDark = document.documentElement.classList.contains("dark");
|
||||
const isDark = document.documentElement.classList.contains('dark')
|
||||
|
||||
if (giscus) {
|
||||
const url = new URL(giscus.src);
|
||||
const url = new URL(giscus.src)
|
||||
// Change "dark" and "light" to other Giscus themes
|
||||
url.searchParams.set("theme", isDark ? "dark" : "light");
|
||||
giscus.src = url.toString();
|
||||
url.searchParams.set('theme', isDark ? 'dark' : 'light')
|
||||
giscus.src = url.toString()
|
||||
}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "[Old] Blog Collection"
|
||||
description: "How to add posts to the blog."
|
||||
date: "2024-03-21"
|
||||
title: '[Old] Blog Collection'
|
||||
description: 'How to add posts to the blog.'
|
||||
date: '2024-03-21'
|
||||
tags: ['aa']
|
||||
---
|
||||
|
||||
|
@ -32,10 +32,10 @@ Metadata is required for each post.
|
|||
|
||||
```astro
|
||||
---
|
||||
title: "Blog Collection";
|
||||
description: "How to add posts to the blog.";
|
||||
date: "2024-03-21";
|
||||
draft: false;
|
||||
title: 'Blog Collection'
|
||||
description: 'How to add posts to the blog.'
|
||||
date: '2024-03-21'
|
||||
draft: false
|
||||
---
|
||||
```
|
||||
|
||||
|
@ -52,10 +52,10 @@ All that's left to do is write the content under the metadata.
|
|||
|
||||
```astro
|
||||
---
|
||||
title: "Blog Collection";
|
||||
description: "How to add posts to the blog.";
|
||||
date: "2024-03-21";
|
||||
draft: false;
|
||||
title: 'Blog Collection'
|
||||
description: 'How to add posts to the blog.'
|
||||
date: '2024-03-21'
|
||||
draft: false
|
||||
---
|
||||
|
||||
## Working with the blog collection
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
---
|
||||
title: "[Old] Markdown syntax guide"
|
||||
description: "Get started writing content in Markdown."
|
||||
date: "2024-03-17"
|
||||
title: '[Old] Markdown syntax guide'
|
||||
description: 'Get started writing content in Markdown.'
|
||||
date: '2024-03-17'
|
||||
---
|
||||
|
||||
import Callout from "@/components/Callout.astro";
|
||||
import Callout from '@/components/Callout.astro'
|
||||
|
||||
---
|
||||
|
||||
|
@ -385,7 +385,7 @@ Denote a code block by wrapping a section of valid code in triple backticks (`).
|
|||
|
||||
```js
|
||||
function hello() {
|
||||
console.log("hello world");
|
||||
console.log('hello world')
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
---
|
||||
title: "[Old] MDX syntax guide"
|
||||
description: "Use interactive components in Markdown."
|
||||
date: "2024-03-16"
|
||||
title: '[Old] MDX syntax guide'
|
||||
description: 'Use interactive components in Markdown.'
|
||||
date: '2024-03-16'
|
||||
---
|
||||
|
||||
import Callout from "@/components/Callout.astro";
|
||||
import Callout from '@/components/Callout.astro'
|
||||
|
||||
---
|
||||
|
||||
|
@ -25,7 +25,7 @@ import DateComp from "../../../components/FormattedDate.astro";
|
|||
<DateComp date={new Date()} />
|
||||
```
|
||||
|
||||
import FormattedDate from "../../../components/FormattedDate.astro";
|
||||
import FormattedDate from '../../../components/FormattedDate.astro'
|
||||
|
||||
<FormattedDate date={new Date()} />
|
||||
|
||||
|
@ -43,7 +43,7 @@ import RelativeComponent from "./component.astro";
|
|||
<RelativeComponent />
|
||||
```
|
||||
|
||||
import RelativeComponent from "./component.astro";
|
||||
import RelativeComponent from './component.astro'
|
||||
|
||||
<RelativeComponent />
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "[Old] Year sorting example"
|
||||
description: "Nano groups posts by year."
|
||||
date: "2023-12-31"
|
||||
title: '[Old] Year sorting example'
|
||||
description: 'Nano groups posts by year.'
|
||||
date: '2023-12-31'
|
||||
---
|
||||
|
||||
This post is to demonstrate the year sorting capabilities.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "[Old] Draft example"
|
||||
description: "Setting draft flag to true to hide this post."
|
||||
date: "2022-12-31"
|
||||
title: '[Old] Draft example'
|
||||
description: 'Setting draft flag to true to hide this post.'
|
||||
date: '2022-12-31'
|
||||
draft: false
|
||||
---
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: "[Old] Chronological pagination example"
|
||||
description: "Pagination works regardless of folder name."
|
||||
date: "2024-03-21"
|
||||
title: '[Old] Chronological pagination example'
|
||||
description: 'Pagination works regardless of folder name.'
|
||||
date: '2024-03-21'
|
||||
draft: false
|
||||
---
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { defineCollection, z } from "astro:content";
|
||||
import { defineCollection, z } from 'astro:content'
|
||||
|
||||
const blog = defineCollection({
|
||||
type: "content",
|
||||
type: 'content',
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
|
@ -10,10 +10,10 @@ const blog = defineCollection({
|
|||
|
||||
tags: z.array(z.string()).optional(),
|
||||
}),
|
||||
});
|
||||
})
|
||||
|
||||
const publications = defineCollection({
|
||||
type: "content",
|
||||
type: 'content',
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
|
@ -27,6 +27,6 @@ const publications = defineCollection({
|
|||
imgAlt: z.string().optional(),
|
||||
pub: z.string().optional(),
|
||||
}),
|
||||
});
|
||||
})
|
||||
|
||||
export const collections = { blog, publications };
|
||||
export const collections = { blog, publications }
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
---
|
||||
title: "Paper Title1"
|
||||
description: "Your Paper Abstract"
|
||||
date: "2024-03-26"
|
||||
authors: "John B*, Jon A*, Frank C, "
|
||||
paperURL: "Paper: https://astro-sphere-demo.vercel.app"
|
||||
codeURL: "Code: https://astro-sphere-demo.vercel.app"
|
||||
webURL: "Web: https://github.com/markhorn-dev/astro-sphere"
|
||||
img: "/rupert-cat.gif"
|
||||
imgAlt: "Paper Teaser"
|
||||
pub: "ECCV2024"
|
||||
dataURL: "Data: "
|
||||
title: 'Paper Title1'
|
||||
description: 'Your Paper Abstract'
|
||||
date: '2024-03-26'
|
||||
authors: 'John B*, Jon A*, Frank C, '
|
||||
paperURL: 'Paper: https://astro-sphere-demo.vercel.app'
|
||||
codeURL: 'Code: https://astro-sphere-demo.vercel.app'
|
||||
webURL: 'Web: https://github.com/markhorn-dev/astro-sphere'
|
||||
img: '/rupert-cat.gif'
|
||||
imgAlt: 'Paper Teaser'
|
||||
pub: 'ECCV2024'
|
||||
dataURL: 'Data: '
|
||||
---
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
---
|
||||
title: "Paper Title1"
|
||||
description: "Lorem ipsum dolor sit amet consectetur adipisicing elit. "
|
||||
date: "2024-07-26"
|
||||
authors: "John B*, Jon A*, Frank C, John B, Jon A, Frank C, "
|
||||
paperURL: "Paper: https://astro-sphere-demo.vercel.app"
|
||||
codeURL: "Code: https://astro-sphere-demo.vercel.app"
|
||||
webURL: "Web: https://github.com/markhorn-dev/astro-sphere"
|
||||
img: "/rupert-cat.gif"
|
||||
imgAlt: "Paper Teaser"
|
||||
pub: "ECCV2024"
|
||||
dataURL: "Data: https://github.com/markhorn-dev/astro-sphere"
|
||||
title: 'Paper Title1'
|
||||
description: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. '
|
||||
date: '2024-07-26'
|
||||
authors: 'John B*, Jon A*, Frank C, John B, Jon A, Frank C, '
|
||||
paperURL: 'Paper: https://astro-sphere-demo.vercel.app'
|
||||
codeURL: 'Code: https://astro-sphere-demo.vercel.app'
|
||||
webURL: 'Web: https://github.com/markhorn-dev/astro-sphere'
|
||||
img: '/rupert-cat.gif'
|
||||
imgAlt: 'Paper Teaser'
|
||||
pub: 'ECCV2024'
|
||||
dataURL: 'Data: https://github.com/markhorn-dev/astro-sphere'
|
||||
---
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
---
|
||||
title: "Paper Title1"
|
||||
description: "Your Paper Abstract"
|
||||
date: "2024-03-26"
|
||||
authors: "John B*, Jon A*, Frank C, "
|
||||
paperURL: "Paper: https://astro-sphere-demo.vercel.app"
|
||||
codeURL: "Code: https://astro-sphere-demo.vercel.app"
|
||||
webURL: "Web: https://github.com/markhorn-dev/astro-sphere"
|
||||
img: "/rupert-cat.gif"
|
||||
imgAlt: "Paper Teaser"
|
||||
pub: "ECCV2024"
|
||||
dataURL: "Data: "
|
||||
title: 'Paper Title1'
|
||||
description: 'Your Paper Abstract'
|
||||
date: '2024-03-26'
|
||||
authors: 'John B*, Jon A*, Frank C, '
|
||||
paperURL: 'Paper: https://astro-sphere-demo.vercel.app'
|
||||
codeURL: 'Code: https://astro-sphere-demo.vercel.app'
|
||||
webURL: 'Web: https://github.com/markhorn-dev/astro-sphere'
|
||||
img: '/rupert-cat.gif'
|
||||
imgAlt: 'Paper Teaser'
|
||||
pub: 'ECCV2024'
|
||||
dataURL: 'Data: '
|
||||
---
|
||||
|
||||
|
|
|
@ -1,33 +1,29 @@
|
|||
---
|
||||
import Head from "@components/Head.astro";
|
||||
import Header from "@components/Header.astro";
|
||||
import Footer from "@components/Footer.astro";
|
||||
import PageFind from "@components/PageFind.astro";
|
||||
import { SITE } from "@consts";
|
||||
import '../styles/katex.css';
|
||||
import ProgressBar from "@components/ProgressBar.astro";
|
||||
import Head from '@components/Head.astro'
|
||||
import Header from '@components/Header.astro'
|
||||
import Footer from '@components/Footer.astro'
|
||||
import { SITE } from '@consts'
|
||||
import '../styles/katex.css'
|
||||
|
||||
type Props = {
|
||||
title: string;
|
||||
description: string;
|
||||
};
|
||||
title: string
|
||||
description: string
|
||||
}
|
||||
|
||||
const { title, description } = Astro.props;
|
||||
const { title, description } = Astro.props
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<Head title={`${title} | ${SITE.TITLE}`} description={description} />
|
||||
<link rel="stylesheet" href="/path/to/your/global.css">
|
||||
<link rel="stylesheet" href="/path/to/your/global.css" />
|
||||
</head>
|
||||
<body>
|
||||
<Header />
|
||||
<!-- <ProgressBar /> -->
|
||||
<main>
|
||||
<slot />
|
||||
</main>
|
||||
<Footer />
|
||||
<PageFind />
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
import { clsx, type ClassValue } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { clsx, type ClassValue } from 'clsx'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
|
||||
export function formatDate(date: Date) {
|
||||
return Intl.DateTimeFormat("en-US", {
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
}).format(date);
|
||||
return Intl.DateTimeFormat('en-US', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
}).format(date)
|
||||
}
|
||||
|
||||
export function readingTime(html: string) {
|
||||
const textOnly = html.replace(/<[^>]+>/g, "");
|
||||
const wordCount = textOnly.split(/\s+/).length;
|
||||
const readingTimeMinutes = (wordCount / 200 + 1).toFixed();
|
||||
return `${readingTimeMinutes} min read`;
|
||||
const textOnly = html.replace(/<[^>]+>/g, '')
|
||||
const wordCount = textOnly.split(/\s+/).length
|
||||
const readingTimeMinutes = (wordCount / 200 + 1).toFixed()
|
||||
return `${readingTimeMinutes} min read`
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
---
|
||||
import Layout from "@layouts/Layout.astro";
|
||||
import Container from "@components/Container.astro";
|
||||
import Link from "@components/Link.astro";
|
||||
import BackToPrevious from "@components/BackToPrevious.astro";
|
||||
import { SITE } from "@consts";
|
||||
import Layout from '@layouts/Layout.astro'
|
||||
import Container from '@components/Container.astro'
|
||||
import Link from '@components/Link.astro'
|
||||
import BackToPrevious from '@components/BackToPrevious.astro'
|
||||
import { SITE } from '@consts'
|
||||
---
|
||||
|
||||
<Layout title="404" description={SITE.DESCRIPTION}>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import Layout from "@layouts/Layout.astro";
|
||||
import Container from "@components/Container.astro";
|
||||
import { ABOUT } from "@consts";
|
||||
import Image from "astro/components/Image.astro";
|
||||
import { getCollection } from 'astro:content'
|
||||
import Layout from '@layouts/Layout.astro'
|
||||
import Container from '@components/Container.astro'
|
||||
import { ABOUT } from '@consts'
|
||||
import { Image } from 'astro:assets'
|
||||
---
|
||||
|
||||
<Layout title={ABOUT.TITLE} description={ABOUT.DESCRIPTION}>
|
||||
|
@ -14,37 +14,51 @@ import Image from "astro/components/Image.astro";
|
|||
About
|
||||
</div>
|
||||
<section class="animate not-prose flex flex-col gap-4 text-justify">
|
||||
<p class="text-justify">Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolores porro hic minima incidunt explicabo obcaecati consectetur consequuntur at quisquam commodi.
|
||||
</p>
|
||||
|
||||
<p class="text-justify">Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolores porro hic minima incidunt explicabo obcaecati consectetur consequuntur at quisquam commodi.
|
||||
<p class="text-justify">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolores
|
||||
porro hic minima incidunt explicabo obcaecati consectetur
|
||||
consequuntur at quisquam commodi.
|
||||
</p>
|
||||
|
||||
<p class="text-justify">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolores
|
||||
porro hic minima incidunt explicabo obcaecati consectetur
|
||||
consequuntur at quisquam commodi.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div class="flex flex-col md:flex-row justify-center">
|
||||
<div class="flex flex-col justify-center md:flex-row">
|
||||
<div class="my-10 text-center">
|
||||
<div class="bg-neutral-300 w-[350px] h-[250px] object-cover rounded-xl -rotate-6 overflow-hidden">
|
||||
<div
|
||||
class="h-[250px] w-[350px] -rotate-6 overflow-hidden rounded-xl bg-neutral-300 object-cover"
|
||||
>
|
||||
<Image
|
||||
src={'/astro-nano.png'}
|
||||
alt={'life2'}
|
||||
width={350}
|
||||
height={250}
|
||||
class="w-[350px] h-[250px] object-cover rounded-xl overflow-hidden"
|
||||
class="h-[250px] w-[350px] overflow-hidden rounded-xl object-cover"
|
||||
/>
|
||||
</div>
|
||||
<p class="mt-4 text-sm">Lorem ipsum dolor sit amet, consectetur adipisicing elit. </p>
|
||||
<p class="mt-4 text-sm">
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
|
||||
</p>
|
||||
</div>
|
||||
<div class="mx-10 my-10 text-center">
|
||||
<div class="bg-neutral-300 w-[150px] h-[250px] object-cover rounded-xl rotate-6 mx-auto sm:ml-auto">
|
||||
<div
|
||||
class="mx-auto h-[250px] w-[150px] rotate-6 rounded-xl bg-neutral-300 object-cover sm:ml-auto"
|
||||
>
|
||||
<Image
|
||||
src={'/astro-micro.jpg'}
|
||||
alt={'life2'}
|
||||
width={150}
|
||||
height={250}
|
||||
class="w-[150px] h-[250px] object-cover rounded-xl "
|
||||
class="h-[250px] w-[150px] rounded-xl object-cover"
|
||||
/>
|
||||
</div>
|
||||
<p class="mt-4 text-sm">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
|
||||
<p class="mt-4 text-sm">
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,49 +1,51 @@
|
|||
---
|
||||
import { type CollectionEntry, getCollection } from "astro:content";
|
||||
import Layout from "@layouts/Layout.astro";
|
||||
import Container from "@components/Container.astro";
|
||||
import FormattedDate from "@components/FormattedDate.astro";
|
||||
import { readingTime } from "@lib/utils";
|
||||
import BackToPrevious from "@components/BackToPrevious.astro";
|
||||
import PostNavigation from "@components/PostNavigation.astro";
|
||||
import TableOfContents from "@components/TableOfContents.astro";
|
||||
import Giscus from "@components/Giscus.astro";
|
||||
import { type CollectionEntry, getCollection } from 'astro:content'
|
||||
import Layout from '@layouts/Layout.astro'
|
||||
import Container from '@components/Container.astro'
|
||||
import FormattedDate from '@components/FormattedDate.astro'
|
||||
import { readingTime } from '@lib/utils'
|
||||
import BackToPrevious from '@components/BackToPrevious.astro'
|
||||
import PostNavigation from '@components/PostNavigation.astro'
|
||||
import TableOfContents from '@components/TableOfContents.astro'
|
||||
import Giscus from '@components/Giscus.astro'
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = (await getCollection("blog"))
|
||||
const posts = (await getCollection('blog'))
|
||||
.filter((post) => !post.data.draft)
|
||||
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
|
||||
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
||||
return posts.map((post) => ({
|
||||
params: { slug: post.slug },
|
||||
props: post,
|
||||
}));
|
||||
}))
|
||||
}
|
||||
type Props = CollectionEntry<"blog">;
|
||||
type Props = CollectionEntry<'blog'>
|
||||
|
||||
const posts = (await getCollection("blog"))
|
||||
const posts = (await getCollection('blog'))
|
||||
.filter((post) => !post.data.draft)
|
||||
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
|
||||
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
||||
|
||||
function getPostIndex(slug: string): number {
|
||||
return posts.findIndex((post) => post.slug === slug);
|
||||
return posts.findIndex((post) => post.slug === slug)
|
||||
}
|
||||
|
||||
function getNextPost(slug: string): Props | null {
|
||||
const postIndex = getPostIndex(slug);
|
||||
return postIndex !== -1 && postIndex < posts.length - 1 ? posts[postIndex + 1] : null;
|
||||
const postIndex = getPostIndex(slug)
|
||||
return postIndex !== -1 && postIndex < posts.length - 1
|
||||
? posts[postIndex + 1]
|
||||
: null
|
||||
}
|
||||
|
||||
function getPrevPost(slug: string): Props | null {
|
||||
const postIndex = getPostIndex(slug);
|
||||
return postIndex > 0 ? posts[postIndex - 1] : null;
|
||||
const postIndex = getPostIndex(slug)
|
||||
return postIndex > 0 ? posts[postIndex - 1] : null
|
||||
}
|
||||
|
||||
const currentPostSlug = Astro.params.slug;
|
||||
const nextPost = getNextPost(currentPostSlug);
|
||||
const prevPost = getPrevPost(currentPostSlug);
|
||||
const currentPostSlug = Astro.params.slug
|
||||
const nextPost = getNextPost(currentPostSlug)
|
||||
const prevPost = getPrevPost(currentPostSlug)
|
||||
|
||||
const post = Astro.props;
|
||||
const { Content, headings } = await post.render();
|
||||
const post = Astro.props
|
||||
const { Content, headings } = await post.render()
|
||||
---
|
||||
|
||||
<Layout title={post.data.title} description={post.data.description}>
|
||||
|
@ -64,21 +66,23 @@ const { Content, headings } = await post.render();
|
|||
<h1 class="animate text-4xl font-semibold text-black dark:text-white">
|
||||
{post.data.title}
|
||||
</h1>
|
||||
<div class="font-base text-sm ">
|
||||
{post.data.tags && post.data.tags.length > 0 ? (
|
||||
post.data.tags.map((tag) => (
|
||||
<div class="inline-block my-1">
|
||||
<a
|
||||
href={`/tags/${tag}`}
|
||||
class="mx-1 rounded-full px-2 py-1 bg-orange-300 hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500 transition-colors duration-300 ease-in-out"
|
||||
>
|
||||
#{tag}
|
||||
</a>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<span>No tags available</span>
|
||||
)}
|
||||
<div class="font-base text-sm">
|
||||
{
|
||||
post.data.tags && post.data.tags.length > 0 ? (
|
||||
post.data.tags.map((tag) => (
|
||||
<div class="my-1 inline-block">
|
||||
<a
|
||||
href={`/tags/${tag}`}
|
||||
class="mx-1 rounded-full bg-orange-300 px-2 py-1 transition-colors duration-300 ease-in-out hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500"
|
||||
>
|
||||
#{tag}
|
||||
</a>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<span>No tags available</span>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
{headings.length > 0 && <TableOfContents headings={headings} />}
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
---
|
||||
import { type CollectionEntry, getCollection } from "astro:content";
|
||||
import Layout from "@layouts/Layout.astro";
|
||||
import Container from "@components/Container.astro";
|
||||
import ArrowCard from "@components/ArrowCard.astro";
|
||||
import { BLOG } from "@consts";
|
||||
import { type CollectionEntry, getCollection } from 'astro:content'
|
||||
import Layout from '@layouts/Layout.astro'
|
||||
import Container from '@components/Container.astro'
|
||||
import ArrowCard from '@components/ArrowCard.astro'
|
||||
import { BLOG } from '@consts'
|
||||
|
||||
const data = (await getCollection("blog"))
|
||||
const data = (await getCollection('blog'))
|
||||
.filter((post) => !post.data.draft)
|
||||
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
|
||||
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
||||
|
||||
type Acc = {
|
||||
[year: string]: CollectionEntry<"blog">[];
|
||||
};
|
||||
[year: string]: CollectionEntry<'blog'>[]
|
||||
}
|
||||
|
||||
const posts = data.reduce((acc: Acc, post) => {
|
||||
const year = post.data.date.getFullYear().toString();
|
||||
const year = post.data.date.getFullYear().toString()
|
||||
if (!acc[year]) {
|
||||
acc[year] = [];
|
||||
acc[year] = []
|
||||
}
|
||||
acc[year].push(post);
|
||||
return acc;
|
||||
}, {});
|
||||
acc[year].push(post)
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
const years = Object.keys(posts).sort((a, b) => parseInt(b) - parseInt(a));
|
||||
const years = Object.keys(posts).sort((a, b) => parseInt(b) - parseInt(a))
|
||||
---
|
||||
|
||||
<Layout title={BLOG.TITLE} description={BLOG.DESCRIPTION}>
|
||||
|
|
|
@ -1,17 +1,35 @@
|
|||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import Layout from "@layouts/Layout.astro";
|
||||
import Container from "@components/Container.astro";
|
||||
import { CV } from "@consts";
|
||||
import CVCard from "@components/CVCard.astro";
|
||||
import { getCollection } from 'astro:content'
|
||||
import Layout from '@layouts/Layout.astro'
|
||||
import Container from '@components/Container.astro'
|
||||
import { CV } from '@consts'
|
||||
import CVCard from '@components/CVCard.astro'
|
||||
|
||||
// TO Modify
|
||||
const works = [
|
||||
{company:"Company A", time: "2022-Present", job_title: "Research Scientist", location: "London, UK", description: "Your Notes about the job"},
|
||||
{company:"Company A", time: "2022-Present", job_title: "Research Scientist", location: "London, UK", description: "Your Notes about the job"},
|
||||
{
|
||||
company: 'Company A',
|
||||
time: '2022-Present',
|
||||
job_title: 'Research Scientist',
|
||||
location: 'London, UK',
|
||||
description: 'Your Notes about the job',
|
||||
},
|
||||
{
|
||||
company: 'Company A',
|
||||
time: '2022-Present',
|
||||
job_title: 'Research Scientist',
|
||||
location: 'London, UK',
|
||||
description: 'Your Notes about the job',
|
||||
},
|
||||
]
|
||||
const educations = [
|
||||
{school:"University 1", time: "2022-Present", job_title: "BEng in Electronic Information Engineering", location: "London, UK", description: "Your Notes about the study"},
|
||||
{
|
||||
school: 'University 1',
|
||||
time: '2022-Present',
|
||||
job_title: 'BEng in Electronic Information Engineering',
|
||||
location: 'London, UK',
|
||||
description: 'Your Notes about the study',
|
||||
},
|
||||
]
|
||||
---
|
||||
|
||||
|
@ -23,17 +41,33 @@ const educations = [
|
|||
Work Experience
|
||||
</div>
|
||||
<ul class="animate not-prose flex flex-col gap-4">
|
||||
{works.map((work) => (
|
||||
<CVCard institution={work.company} time={work.time} job_title={work.job_title} location={work.location} description={work.description} />)
|
||||
)}
|
||||
{
|
||||
works.map((work) => (
|
||||
<CVCard
|
||||
institution={work.company}
|
||||
time={work.time}
|
||||
job_title={work.job_title}
|
||||
location={work.location}
|
||||
description={work.description}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
<div class="animate font-semibold text-black dark:text-white">
|
||||
Education
|
||||
</div>
|
||||
<ul class="animate not-prose flex flex-col gap-4">
|
||||
{educations.map((education) => (
|
||||
<CVCard institution={education.school} time={education.time} job_title={education.job_title} location={education.location} description={education.description} />)
|
||||
)}
|
||||
{
|
||||
educations.map((education) => (
|
||||
<CVCard
|
||||
institution={education.school}
|
||||
time={education.time}
|
||||
job_title={education.job_title}
|
||||
location={education.location}
|
||||
description={education.description}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
---
|
||||
import Layout from "@layouts/Layout.astro";
|
||||
import Container from "@components/Container.astro";
|
||||
import { SITE, HOME } from "@consts";
|
||||
import ArrowCard from "@components/ArrowCard.astro";
|
||||
import Link from "@components/Link.astro";
|
||||
import { getCollection } from "astro:content";
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
import PublicationCard from "@components/PublicationCard.astro";
|
||||
import SocialIcons from "@components/SocialIcons.astro";
|
||||
import Layout from '@layouts/Layout.astro'
|
||||
import Container from '@components/Container.astro'
|
||||
import { SITE, HOME } from '@consts'
|
||||
import ArrowCard from '@components/ArrowCard.astro'
|
||||
import Link from '@components/Link.astro'
|
||||
import { getCollection } from 'astro:content'
|
||||
import type { CollectionEntry } from 'astro:content'
|
||||
import PublicationCard from '@components/PublicationCard.astro'
|
||||
import SocialIcons from '@components/SocialIcons.astro'
|
||||
|
||||
const blog = (await getCollection("blog"))
|
||||
const blog = (await getCollection('blog'))
|
||||
.filter((post) => !post.data.draft)
|
||||
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
||||
.slice(0, SITE.NUM_POSTS_ON_HOMEPAGE);
|
||||
.slice(0, SITE.NUM_POSTS_ON_HOMEPAGE)
|
||||
|
||||
const publications: CollectionEntry<"publications">[] = (
|
||||
await getCollection("publications")
|
||||
const publications: CollectionEntry<'publications'>[] = (
|
||||
await getCollection('publications')
|
||||
)
|
||||
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
||||
.slice(0, SITE.NUM_PUBLICATIONS_ON_HOMEPAGE);
|
||||
.slice(0, SITE.NUM_PUBLICATIONS_ON_HOMEPAGE)
|
||||
---
|
||||
|
||||
<Layout title={HOME.TITLE} description={HOME.DESCRIPTION}>
|
||||
|
@ -34,16 +34,21 @@ const publications: CollectionEntry<"publications">[] = (
|
|||
<p>
|
||||
Astro Micro Academics is a theme for <Link
|
||||
href="https://astro.build/">Astro</Link
|
||||
> and tailored for academic users and researchers. It's built on <Link href="https://astro.build/themes/details/astro-micro/">Astro Micro</Link> and
|
||||
> and tailored for academic users and researchers. It's built on
|
||||
<Link href="https://astro.build/themes/details/astro-micro/"
|
||||
>Astro Micro</Link
|
||||
> and
|
||||
<Link href="https://github.com/markhorn-dev">
|
||||
Mark Horn's
|
||||
</Link> popular theme <Link
|
||||
href="https://astro.build/themes/details/astronano/"
|
||||
>Astro Nano</Link
|
||||
>.
|
||||
>.
|
||||
</p>
|
||||
<p>
|
||||
Micro Academics adds features like <span class="text-red-500">tags, and blog math support</span> and also inherits <Link href="https://pagefind.app/"
|
||||
Micro Academics adds features like <span class="text-red-500"
|
||||
>tags, and blog math support</span
|
||||
> and also inherits <Link href="https://pagefind.app/"
|
||||
>Pagefind</Link
|
||||
> for search, <Link href="https://giscus.app">Giscus</Link> for comments,
|
||||
from Astro Micro. See full changes this <Link
|
||||
|
@ -53,10 +58,10 @@ const publications: CollectionEntry<"publications">[] = (
|
|||
</span>
|
||||
<span class="animate">
|
||||
<p>
|
||||
Micro Academics still comes with everything great about Micro and Nano — full type
|
||||
safety, a sitemap, an RSS feed, and Markdown + MDX support.
|
||||
Styled with TailwindCSS and preconfigured with system, light,
|
||||
and dark themes.
|
||||
Micro Academics still comes with everything great about Micro
|
||||
and Nano — full type safety, a sitemap, an RSS feed, and
|
||||
Markdown + MDX support. Styled with TailwindCSS and
|
||||
preconfigured with system, light, and dark themes.
|
||||
</p>
|
||||
<p>
|
||||
Visit
|
||||
|
@ -66,11 +71,12 @@ const publications: CollectionEntry<"publications">[] = (
|
|||
to fork the repository to get started.
|
||||
</p>
|
||||
</span>
|
||||
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="animate space-y-2 border-2 border-red-800 text-red-800 dark:border-red-400 border-dashed p-2 dark:text-red-400">
|
||||
<section
|
||||
class="animate space-y-2 border-2 border-dashed border-red-800 p-2 text-red-800 dark:border-red-400 dark:text-red-400"
|
||||
>
|
||||
📢📢 Your important Information (Open for job/Recruiting students)
|
||||
</section>
|
||||
|
||||
|
@ -81,8 +87,8 @@ const publications: CollectionEntry<"publications">[] = (
|
|||
</h4>
|
||||
<article>
|
||||
<p>
|
||||
If you want to get in touch with me about something or just to say
|
||||
hi, reach out on social media or send me an email.
|
||||
If you want to get in touch with me about something or just to
|
||||
say hi, reach out on social media or send me an email.
|
||||
</p>
|
||||
</article>
|
||||
<SocialIcons icon_size={'text-3xl'} />
|
||||
|
@ -100,14 +106,14 @@ const publications: CollectionEntry<"publications">[] = (
|
|||
<li>AIGC</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="animate space-y-6">
|
||||
<div class="flex flex-wrap items-center justify-between gap-y-2">
|
||||
<h2 class="font-semibold text-black dark:text-white">
|
||||
News
|
||||
</h2>
|
||||
<h2 class="font-semibold text-black dark:text-white">News</h2>
|
||||
</div>
|
||||
<ul class="not-prose flex flex-col gap-4 overflow-y-auto max-h-[150px] scroll_bar">
|
||||
<ul
|
||||
class="not-prose scroll_bar flex max-h-[150px] flex-col gap-4 overflow-y-auto"
|
||||
>
|
||||
<li>[06/2024]: Your News1</li>
|
||||
<li>[06/2024]: Your <span class="text-red-600">News2</span></li>
|
||||
<li>[06/2024]: Your <span class="text-red-600">News2</span></li>
|
||||
|
@ -151,7 +157,6 @@ const publications: CollectionEntry<"publications">[] = (
|
|||
}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</aside>
|
||||
</Container>
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import Layout from "@layouts/Layout.astro";
|
||||
import Container from "@components/Container.astro";
|
||||
import { RESEARCH } from "@consts";
|
||||
import PublicationCard from "@components/PublicationCard.astro";
|
||||
import { getCollection } from 'astro:content'
|
||||
import Layout from '@layouts/Layout.astro'
|
||||
import Container from '@components/Container.astro'
|
||||
import { RESEARCH } from '@consts'
|
||||
import PublicationCard from '@components/PublicationCard.astro'
|
||||
// import PublicationCard from "@components/PublicationCard";
|
||||
|
||||
const publications = (await getCollection("publications"))
|
||||
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
|
||||
const publications = (await getCollection('publications')).sort(
|
||||
(a, b) => b.data.date.valueOf() - a.data.date.valueOf(),
|
||||
)
|
||||
---
|
||||
|
||||
<Layout title={RESEARCH.TITLE} description={RESEARCH.DESCRIPTION}>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import rss from "@astrojs/rss";
|
||||
import { SITE } from "@consts";
|
||||
import { getCollection } from "astro:content";
|
||||
import rss from '@astrojs/rss'
|
||||
import { SITE } from '@consts'
|
||||
import { getCollection } from 'astro:content'
|
||||
|
||||
export async function GET(context) {
|
||||
// const publications = (await getCollection("publications")).filter(
|
||||
|
@ -11,15 +11,20 @@ export async function GET(context) {
|
|||
// (a, b) => new Date(b.data.date).valueOf() - new Date(a.data.date).valueOf(),
|
||||
// );
|
||||
try {
|
||||
const blog = (await getCollection("blog")).filter((post) => !post.data.draft);
|
||||
const blog = (await getCollection('blog')).filter(
|
||||
(post) => !post.data.draft,
|
||||
)
|
||||
|
||||
// Filter posts by tag 'rss-feed'
|
||||
const filteredBlogs = blog.filter(post => post.data.tags && post.data.tags.includes('rss-feed'));
|
||||
const filteredBlogs = blog.filter(
|
||||
(post) => post.data.tags && post.data.tags.includes('rss-feed'),
|
||||
)
|
||||
|
||||
// Sort posts by date
|
||||
const items = [...filteredBlogs].sort(
|
||||
(a, b) => new Date(b.data.date).valueOf() - new Date(a.data.date).valueOf()
|
||||
);
|
||||
(a, b) =>
|
||||
new Date(b.data.date).valueOf() - new Date(a.data.date).valueOf(),
|
||||
)
|
||||
|
||||
// Return RSS feed
|
||||
return rss({
|
||||
|
@ -32,9 +37,9 @@ export async function GET(context) {
|
|||
pubDate: item.data.date,
|
||||
link: `/${item.collection}/${item.slug}/`,
|
||||
})),
|
||||
});
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error generating RSS feed:', error);
|
||||
return new Response('Error generating RSS feed', { status: 500 });
|
||||
console.error('Error generating RSS feed:', error)
|
||||
return new Response('Error generating RSS feed', { status: 500 })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +1,48 @@
|
|||
---
|
||||
import { type CollectionEntry, getCollection } from "astro:content";
|
||||
import Layout from "@layouts/Layout.astro";
|
||||
import Container from "@components/Container.astro";
|
||||
import ArrowCard from "@components/ArrowCard.astro";
|
||||
import { TAGS } from "@consts";
|
||||
import { type CollectionEntry, getCollection } from 'astro:content'
|
||||
import Layout from '@layouts/Layout.astro'
|
||||
import Container from '@components/Container.astro'
|
||||
import ArrowCard from '@components/ArrowCard.astro'
|
||||
import { TAGS } from '@consts'
|
||||
|
||||
type BlogPost = CollectionEntry<'blog'>;
|
||||
type BlogPost = CollectionEntry<'blog'>
|
||||
|
||||
type Props = {
|
||||
tag: string;
|
||||
posts: BlogPost[];
|
||||
};
|
||||
tag: string
|
||||
posts: BlogPost[]
|
||||
}
|
||||
|
||||
const { tag, posts } = Astro.props;
|
||||
const { tag, posts } = Astro.props
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getCollection('blog');
|
||||
const tags = posts.flatMap((post) => post.data.tags || []);
|
||||
const uniqueTags = Array.from(new Set(tags.filter((tag): tag is string => typeof tag === 'string')));
|
||||
const posts = await getCollection('blog')
|
||||
const tags = posts.flatMap((post) => post.data.tags || [])
|
||||
const uniqueTags = Array.from(
|
||||
new Set(tags.filter((tag): tag is string => typeof tag === 'string')),
|
||||
)
|
||||
|
||||
return uniqueTags.map((tag) => ({
|
||||
params: { slug: tag },
|
||||
props: { tag, posts: posts.filter((post) => post.data.tags?.includes(tag)) },
|
||||
}));
|
||||
props: {
|
||||
tag,
|
||||
posts: posts.filter((post) => post.data.tags?.includes(tag)),
|
||||
},
|
||||
}))
|
||||
}
|
||||
---
|
||||
|
||||
<Layout title={`Posts tagged with "${tag}"`} description={`A collection of posts tagged with ${tag}.`}>
|
||||
<Layout
|
||||
title={`Posts tagged with "${tag}"`}
|
||||
description={`A collection of posts tagged with ${tag}.`}
|
||||
>
|
||||
<Container>
|
||||
<aside data-pagefind-ignore>
|
||||
<div class="space-y-10">
|
||||
<div class="animate font-semibold text-black dark:text-white">
|
||||
Tag: <span class="px-3 py-2 rounded-full mx-2 bg-orange-300 hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500 transition-colors duration-300 ease-in-out">#{tag}</span>
|
||||
Tag: <span
|
||||
class="mx-2 rounded-full bg-orange-300 px-3 py-2 transition-colors duration-300 ease-in-out hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500"
|
||||
>#{tag}</span
|
||||
>
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
{
|
||||
|
@ -39,9 +50,9 @@ export async function getStaticPaths() {
|
|||
<section class="animate space-y-4">
|
||||
<div>
|
||||
<ul class="not-prose flex flex-col gap-4">
|
||||
<li>
|
||||
<ArrowCard entry={post} />
|
||||
</li>
|
||||
<li>
|
||||
<ArrowCard entry={post} />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
@ -1,31 +1,35 @@
|
|||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import Layout from "@layouts/Layout.astro";
|
||||
import Container from "@components/Container.astro";
|
||||
import { TAGS } from "@consts";
|
||||
import Image from "astro/components/Image.astro";
|
||||
import { getCollection } from 'astro:content'
|
||||
import Layout from '@layouts/Layout.astro'
|
||||
import Container from '@components/Container.astro'
|
||||
import { TAGS } from '@consts'
|
||||
import Image from 'astro/components/Image.astro'
|
||||
|
||||
const blog = (await getCollection("blog"))
|
||||
.filter((post) => !post.data.draft);
|
||||
const blog = (await getCollection('blog')).filter((post) => !post.data.draft)
|
||||
|
||||
const tags = blog.flatMap(post => post.data.tags).filter((tag, index, self) => self.indexOf(tag) === index);
|
||||
const tags = blog
|
||||
.flatMap((post) => post.data.tags)
|
||||
.filter((tag, index, self) => self.indexOf(tag) === index)
|
||||
---
|
||||
|
||||
<Layout title={TAGS.TITLE} description={TAGS.DESCRIPTION}>
|
||||
<Container>
|
||||
<aside data-pagefind-ignore>
|
||||
<div class="space-y-10">
|
||||
<div class="animate font-semibold text-black dark:text-white">
|
||||
Tags
|
||||
</div>
|
||||
<ul class="flex flex-wrap ">
|
||||
{tags.map(tag => (
|
||||
<div class="animate font-semibold text-black dark:text-white">Tags</div>
|
||||
<ul class="flex flex-wrap">
|
||||
{
|
||||
tags.map((tag) => (
|
||||
<li class="my-3">
|
||||
<a href={`/tags/${tag}`} class="px-3 py-2 rounded-full mx-2 bg-orange-300 hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500 transition-colors duration-300 ease-in-out">
|
||||
#{tag}
|
||||
<a
|
||||
href={`/tags/${tag}`}
|
||||
class="mx-2 rounded-full bg-orange-300 px-3 py-2 transition-colors duration-300 ease-in-out hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500"
|
||||
>
|
||||
#{tag}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
// src/scripts/progress-bar.js
|
||||
|
||||
export function initializeProgressBar() {
|
||||
function updateProgressBar() {
|
||||
const scrollTop = window.scrollY;
|
||||
const docHeight = document.documentElement.scrollHeight;
|
||||
const winHeight = window.innerHeight;
|
||||
const scrollPercent = (scrollTop / (docHeight - winHeight)) * 100;
|
||||
document.getElementById('progress-bar').style.width = `${scrollPercent}%`;
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', updateProgressBar);
|
||||
window.addEventListener('resize', updateProgressBar);
|
||||
|
||||
// Initialize the progress bar on page load
|
||||
updateProgressBar();
|
||||
}
|
||||
|
|
@ -57,8 +57,8 @@ article {
|
|||
}
|
||||
|
||||
.scroll_bar {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #1e293b #0f172a ;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #1e293b #0f172a;
|
||||
}
|
||||
|
||||
.animate {
|
||||
|
|
|
@ -1 +1 @@
|
|||
@import 'https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css';
|
||||
@import 'https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css';
|
||||
|
|
20
src/types.ts
20
src/types.ts
|
@ -1,13 +1,13 @@
|
|||
export type Site = {
|
||||
TITLE: string;
|
||||
DESCRIPTION: string;
|
||||
EMAIL: string;
|
||||
NUM_POSTS_ON_HOMEPAGE: number;
|
||||
NUM_PUBLICATIONS_ON_HOMEPAGE: number;
|
||||
SITEURL: string,
|
||||
};
|
||||
TITLE: string
|
||||
DESCRIPTION: string
|
||||
EMAIL: string
|
||||
NUM_POSTS_ON_HOMEPAGE: number
|
||||
NUM_PUBLICATIONS_ON_HOMEPAGE: number
|
||||
SITEURL: string
|
||||
}
|
||||
|
||||
export type Metadata = {
|
||||
TITLE: string;
|
||||
DESCRIPTION: string;
|
||||
};
|
||||
TITLE: string
|
||||
DESCRIPTION: string
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue