feat: refactor
This commit is contained in:
parent
b83f17d087
commit
8666e5a169
57 changed files with 5734 additions and 5313 deletions
183
src/pages/index.astro
Normal file
183
src/pages/index.astro
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
---
|
||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
const title = "Barrett Ruth";
|
||||
|
||||
const allPosts = await getCollection("posts");
|
||||
const postsByCategory = allPosts.reduce((acc, post) => {
|
||||
const category = post.id.split('/')[0];
|
||||
if (!acc[category]) acc[category] = [];
|
||||
acc[category].push(post);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
Object.keys(postsByCategory).forEach(category => {
|
||||
postsByCategory[category].sort((a, b) => {
|
||||
const dateA = a.data.date ? new Date(a.data.date) : new Date(0);
|
||||
const dateB = b.data.date ? new Date(b.data.date) : new Date(0);
|
||||
return dateB.getTime() - dateA.getTime();
|
||||
});
|
||||
});
|
||||
---
|
||||
|
||||
<BaseLayout title={title}>
|
||||
<slot name="head" slot="head">
|
||||
<link rel="stylesheet" href="/styles/index.css" />
|
||||
</slot>
|
||||
<div class="content">
|
||||
<ul class="topics">
|
||||
<li class="topic algorithms">
|
||||
<a href="#algorithms" data-topic="algorithms">algorithms</a>
|
||||
</li>
|
||||
<li class="topic software">
|
||||
<a href="#software" data-topic="software">software</a>
|
||||
</li>
|
||||
<li class="topic meditations">
|
||||
<a href="#meditations" data-topic="meditations">meditations</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="posts" id="posts"></div>
|
||||
</div>
|
||||
|
||||
<script slot="scripts" define:vars={{ postsByCategory }}>
|
||||
function getTopicColor(topicName) {
|
||||
switch (topicName) {
|
||||
case "software":
|
||||
return "#0073e6";
|
||||
case "operating-systems":
|
||||
return "#009975";
|
||||
case "algorithms":
|
||||
return "#d50032";
|
||||
case "meditations":
|
||||
return "#6a0dad";
|
||||
default:
|
||||
return "#000000";
|
||||
}
|
||||
}
|
||||
|
||||
const TERMINAL_PROMPT = "barrett@ruth:~$ ";
|
||||
let typing = false;
|
||||
let clearing = false;
|
||||
|
||||
function clearPrompt(delay, callback) {
|
||||
if (clearing) return;
|
||||
clearing = true;
|
||||
|
||||
const terminalPrompt = document.querySelector(".terminal-prompt");
|
||||
if (!terminalPrompt) {
|
||||
clearing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const topicLength = terminalPrompt.innerHTML.length - TERMINAL_PROMPT.length;
|
||||
let i = 0;
|
||||
|
||||
function removeChar() {
|
||||
if (i++ < topicLength) {
|
||||
terminalPrompt.textContent = terminalPrompt.textContent.slice(0, -1);
|
||||
setTimeout(removeChar, delay / topicLength);
|
||||
} else {
|
||||
i = 0;
|
||||
clearing = false;
|
||||
callback && callback();
|
||||
}
|
||||
}
|
||||
|
||||
removeChar();
|
||||
}
|
||||
|
||||
function typechars(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const topicElement = e.target;
|
||||
if (topicElement.classList.contains("active")) return;
|
||||
if (typing) return;
|
||||
typing = true;
|
||||
|
||||
const topic = topicElement.dataset.topic;
|
||||
const terminalText = ` /${topic.toLowerCase()}`;
|
||||
const terminalPrompt = document.querySelector(".terminal-prompt");
|
||||
const delay =
|
||||
terminalPrompt.innerHTML.length > TERMINAL_PROMPT.length ? 250 : 500;
|
||||
|
||||
const topics = document.querySelectorAll(".topic a");
|
||||
topics.forEach((t) => {
|
||||
t.classList.remove("active");
|
||||
t.style.color = "";
|
||||
});
|
||||
|
||||
topicElement.classList.add("active");
|
||||
topicElement.style.color = getTopicColor(topic);
|
||||
|
||||
clearPrompt(delay, () => {
|
||||
let i = 0;
|
||||
function typechar() {
|
||||
if (i < terminalText.length) {
|
||||
terminalPrompt.innerHTML += terminalText.charAt(i++);
|
||||
setTimeout(typechar, delay / terminalText.length);
|
||||
} else {
|
||||
renderPosts(topic);
|
||||
typing = false;
|
||||
}
|
||||
}
|
||||
typechar();
|
||||
});
|
||||
}
|
||||
|
||||
function renderPosts(topic) {
|
||||
const posts = document.getElementById("posts");
|
||||
posts.innerHTML = "";
|
||||
|
||||
const categoryPosts = postsByCategory[topic];
|
||||
|
||||
if (!categoryPosts) {
|
||||
console.error(`No posts found for topic: ${topic}`);
|
||||
return;
|
||||
}
|
||||
|
||||
categoryPosts.forEach((post) => {
|
||||
const postDiv = document.createElement("div");
|
||||
postDiv.classList.add("post");
|
||||
|
||||
const link = document.createElement("a");
|
||||
const slug = post.id.split('/').pop().replace(/\.mdx?$/, '');
|
||||
|
||||
link.href = `/posts/${topic}/${slug}`;
|
||||
link.textContent = post.data.title;
|
||||
link.style.textDecoration = "underline";
|
||||
|
||||
postDiv.appendChild(link);
|
||||
posts.appendChild(postDiv);
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const topics = document.querySelectorAll('.topic a');
|
||||
|
||||
topics.forEach(topic => {
|
||||
topic.addEventListener('click', typechars);
|
||||
|
||||
const topicName = topic.dataset.topic;
|
||||
|
||||
topic.addEventListener('mouseenter', () => {
|
||||
const color = getTopicColor(topicName);
|
||||
topic.style.color = color;
|
||||
});
|
||||
|
||||
topic.addEventListener('mouseleave', () => {
|
||||
if (!topic.classList.contains('active')) {
|
||||
topic.style.color = "";
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
window.addEventListener('beforeunload', () => {
|
||||
const terminalPrompt = document.querySelector('.terminal-prompt');
|
||||
if (terminalPrompt) {
|
||||
terminalPrompt.innerHTML = TERMINAL_PROMPT;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</BaseLayout>
|
||||
Loading…
Add table
Add a link
Reference in a new issue