diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/RadarChart.astro | 147 | ||||
| -rw-r--r-- | src/layouts/Terminal.astro (renamed from src/layouts/Layout.astro) | 4 | ||||
| -rw-r--r-- | src/pages/404.astro | 15 | ||||
| -rw-r--r-- | src/pages/blogs.astro (renamed from src/pages/blogs/index.astro) | 32 | ||||
| -rw-r--r-- | src/pages/blogs/[...slug].astro | 3 | ||||
| -rw-r--r-- | src/pages/index.astro | 36 | ||||
| -rw-r--r-- | src/pages/skills.astro | 6 | ||||
| -rw-r--r-- | src/styles/terminal.css | 1 |
8 files changed, 205 insertions, 39 deletions
diff --git a/src/components/RadarChart.astro b/src/components/RadarChart.astro new file mode 100644 index 0000000..60f2cf7 --- /dev/null +++ b/src/components/RadarChart.astro @@ -0,0 +1,147 @@ +--- + +// const { data } = Astro.props; + +const data = [ + { name: 'React', total: 9 }, + { name: 'GraphQL', total: 2 }, + { name: 'JavaScript', total: 5 }, + { name: 'SVG', total: 5 }, + { name: 'TypeScript', total: 7 }, + { name: 'Tailwind', total: 7 }, + { name: 'React Query', total: 2 }, + { name: 'Next.js', total: 3 }, + { name: 'Hmm', total: 5 }, +] + +const chartSize = 400; +const chartCenter = chartSize / 2; + +const colors = ['#58e6d9', '#ff6090', '#4871e3', '#ffc107', '#8bc34a', '#00FF00']; +const chartData = data.sort((a, b) => b.total - a.total).slice(0, colors.length); +const pointPadding = 10; +const max = chartData.reduce((max, current) => (current.total > max ? current.total : max), 0); +const rings = [...Array(6).keys()]; + +const getX = (angle, value) => Math.cos(angle - Math.PI / 2) * value; +const getY = (angle, value) => Math.sin(angle - Math.PI / 2) * value; + +const axes = chartData.map((_, index) => { + const angle = (Math.PI * 2 * index) / chartData.length; + const x = getX(angle, chartSize / 2); + const y = getY(angle, chartSize / 2); + const points = [ + [0, 0], + [x, y], + ] + .map((point) => point[0] + ',' + point[1]) + .join(' '); + return { + points: points, + }; +}); + +const properties = chartData.map((item, index) => { + const { name, total } = item; + const clamp = Number(total / (max + pointPadding)); + const angle = (Math.PI * 2 * index) / chartData.length; + const x = getX(angle, (clamp * chartSize) / 2); + const y = getY(angle, (clamp * chartSize) / 2); + return { name: name, total: total, x: x, y: y }; +}); + +const shape = + properties.reduce((items, item, index) => { + const { x, y } = item; + const string = `${index === 0 ? 'M' : 'L'}${x},${y}`; + return items + string; + }, '') + 'z'; + +const bgColor = "bg-blue-500" +const borderColor = "border-gray-100" +const strokeColor = 'stroke-gray-200' +const shapeClass = 'stroke-gray-900 fill-gray-900/[0.5]' +--- + +<div class=`m-0 p-0 ${bgColor} border rounded ${borderColor} shadow-lg`> + <div class='grid md:grid-cols-2 items-center gap-16 p-16'> + <svg xmlns='http://www.w3.org/2000/svg' viewBox={`0 0 ${chartSize} ${chartSize}`} role='presentation'> + <g transform={`translate(${chartCenter},${chartCenter})`}> + { + rings.map((_, index) => { + return ( + <circle + cx={0} + cy={0} + r={((index / rings.length) * chartSize) / Number((Math.PI / 2 + 0.1).toFixed(2))} + class={strokeColor} + fill='none' + stroke-width={1} + /> + ); + }) + } + { + axes.map((axis) => { + const { points } = axis; + return <polyline points={points} class={strokeColor} fill='none' stroke-width={1} />; + }) + } + <path d={shape} class=`${shapeClass}` stroke-width={1.5}></path> + { + properties.map((property, index) => { + const { x, y } = property; + + return ( + <g transform={`translate(${x},${y})`}> + <circle cx={0} cy={0} r={8} fill={colors[index]} /> + + </g> + <g transform={`translate(${x},${y})`}> + <text + x={0} + y={0} + fill={colors[index]} + font-size="16px" + text-anchor="middle" + dominant-baseline="middle" + > + Hello + </text> + </g> + ); + }) + } + </g> + </svg> + <div> + <h2 class='text-4xl font-black uppercase'>Top 6 Tags</h2> + <p class='mb-6'>Calculated using Astro Content Collections.</p> + <ul class='list-none m-0 p-0'> + { + properties.map((property, index) => { + const { name, total } = property; + + return ( + <li class='m-0 p-0 flex items-center justify-between border-b border-b-transparent [&:not(:last-child)]:border-b-gray-100 leading-10'> + <div class='flex items-center gap-1'> + <svg + xmlns='http://www.w3.org/2000/svg' + viewBox='0 0 24 24' + width={24} + height={24} + role='presentation' + > + <circle cx={12} cy={12} r={6} fill={colors[index]} /> + </svg> + <strong>{name}</strong> + </div> + <strong>{`x${total}`}</strong> + </li> + ); + }) + } + </ul> + </div> + </div> +</div> diff --git a/src/layouts/Layout.astro b/src/layouts/Terminal.astro index 26a8e13..ca2eac0 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Terminal.astro @@ -3,10 +3,10 @@ import "../styles/terminal.css"; import Nav from "../components/Nav.astro"; interface Props { - dir: string; + path: string; } -const { dir: title } = Astro.props; +const { path: title } = Astro.props; --- <!doctype html> diff --git a/src/pages/404.astro b/src/pages/404.astro new file mode 100644 index 0000000..f5db977 --- /dev/null +++ b/src/pages/404.astro @@ -0,0 +1,15 @@ +--- +import TerminalBorder from "../components/TerminalBorder.astro" +import Terminal from "../layouts/Terminal.astro" + +const url = new URL(Astro.request.url).pathname.substring(1); +--- +<Terminal path="404"> + <TerminalBorder header="Shell" margin="0.5rem 0"> + <span> + <p>$ cd ~/{url}</p> + <p class="pt-3">"{url}": No such file or directory (os error 2)</p> + </span> + </TerminalBorder> +</Terminal> + diff --git a/src/pages/blogs/index.astro b/src/pages/blogs.astro index e91e580..c571090 100644 --- a/src/pages/blogs/index.astro +++ b/src/pages/blogs.astro @@ -1,12 +1,12 @@ --- -import Layout from "../../layouts/Layout.astro"; -import TerminalBorder from "../../components/TerminalBorder.astro"; -import BlogItem from "../../components/BlogItem.astro"; +import Terminal from "../layouts/Terminal.astro"; +import TerminalBorder from "../components/TerminalBorder.astro"; +import BlogItem from "../components/BlogItem.astro"; import { getCollection } from "astro:content"; -function formatDate(date) { +function formatDate(date: Date) { const day = date.getDate(); - const month = date.toLocaleString("default", { month: "long" }); // Get full month name + const month = date.toLocaleString("default", { month: "long" }); const year = date.getFullYear(); let suffix = "th"; @@ -21,17 +21,19 @@ function formatDate(date) { return `${month} ${day}${suffix} ${year}`; } -const blogs = (await getCollection("blogs")).map((blog) => ({ - title: blog.data.title, - description: blog.data.description, - date: formatDate(blog.data.date), - href: "/blogs/" + blog.slug, -})); +const blogs = (await getCollection("blogs")) + .sort((a, b) => +new Date(b.data.date) - +new Date(a.data.date)) + .map((blog) => ({ + title: blog.data.title, + description: blog.data.description, + date: formatDate(blog.data.date), + href: "/blogs/" + blog.slug, + })); --- -<Layout dir="blogs/"> +<Terminal path="blogs/"> <TerminalBorder header="Shell" margin="0.5rem 0 20px"> - <p>ls ~/blogs {blogs.length}</p> + <p>$ ls -lah -t --color=auto ~/blogs</p> </TerminalBorder> <div class="max-h-[18.5rem] overflow-y-auto"> { @@ -39,7 +41,7 @@ const blogs = (await getCollection("blogs")).map((blog) => ({ <> <BlogItem title={blog.title} - description={blog.description} + description={blog.description ? blog.description : ""} date={blog.date} href={blog.href} /> @@ -47,4 +49,4 @@ const blogs = (await getCollection("blogs")).map((blog) => ({ )) } </div> -</Layout> +</Terminal> diff --git a/src/pages/blogs/[...slug].astro b/src/pages/blogs/[...slug].astro index 37e6f53..3e42575 100644 --- a/src/pages/blogs/[...slug].astro +++ b/src/pages/blogs/[...slug].astro @@ -1,5 +1,6 @@ --- import Blog from "../../layouts/Blog.astro"; +import RadarChart from "../../components/RadarChart.astro" import { getCollection } from "astro:content"; export async function getStaticPaths() { @@ -15,5 +16,7 @@ const { Content } = await entry.render(); --- <Blog title=`/home/kyren/blogs/${entry.slug}`> + <h1>Test</h1> + <RadarChart></RadarChart> <Content /> </Blog> diff --git a/src/pages/index.astro b/src/pages/index.astro index d6cff92..243838f 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,9 +1,9 @@ --- -import Terminal from "../layouts/Layout.astro"; +import Terminal from "../layouts/Terminal.astro"; import TerminalBorder from "../components/TerminalBorder.astro"; import Link from "../components/Link.astro"; -const sshKey = `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAsrdN6e4XbkJfV/FbH3GY8ujWgxSCSbYiwzQ4rKyren`; +const sshKey = `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO7P9K9D5RkBk+JCRRS6AtHuTAc6cRpXfRfRMg/Kyren`; const fingerprint = ` +--[ED25519 256]--+ |+o.+oE*B%* o | @@ -25,7 +25,7 @@ And when I am not coding I am most likely playing video games, watching Anime or solving Rubik's cubes fast.`.trimStart(); --- -<Terminal dir=""> +<Terminal path=""> <div id="content"> <div id="left" class="column"> <TerminalBorder header="Profile"> @@ -36,8 +36,7 @@ watching Anime or solving Rubik's cubes fast.`.trimStart(); class="h-[100%] object-cover" /> <pre - id="sshKeyCopy" - class="text-[75%] flex-1">{fingerprint}</pre> + class="copySshKey text-[75%] flex-1 hover:text-[var(--secondary)]">{fingerprint}</pre> </div> </TerminalBorder> <TerminalBorder header="Name"> @@ -47,26 +46,22 @@ watching Anime or solving Rubik's cubes fast.`.trimStart(); <span>Kyren223@proton.me</span> </TerminalBorder> <TerminalBorder header="Timezone"> - <span>UTC+2</span> - </TerminalBorder> - <div class="w-[334%]"> - <TerminalBorder header="SSH Key"> - <div - class="w-[100%] flex items-center space-x-2 hover:text-[var(--alt)]" - > + <span>UTC+2</span> </TerminalBorder> <div class="w-[334%]"> <TerminalBorder header="SSH Key"> + <div class="w-[100%] flex items-center space-x-2 group"> <span id="sshKey" - class="hover:text-[var(--alt)] cursor-pointer truncate flex-1" + class="hover:text-[var(--alt)] cursor-pointer truncate flex-1 group-hover:text-[var(--alt)]" >{sshKey}</span > <button id="sshKeyCopy" - class="flex items-center justify-center ml-auto hover:text-[var(--alt)]" + type="button" + class="group-hover:text-[var(--alt)]" > <svg width="100%" height="100%" - viewBox="0 -3 24 24" + viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="none" > @@ -113,19 +108,18 @@ watching Anime or solving Rubik's cubes fast.`.trimStart(); navigator.clipboard .writeText(sshKey ? sshKey : "") .then(() => { + console.log("Clicked"); // TODO: show some feedback for copying }) .catch((_err) => { + console.log("Error copying!"); // TODO: show same feedback but with err }); } - document - .getElementById("sshKey") - ?.addEventListener("click", copySshKeyToClipboard); - document - .getElementById("sshKeyCopy") - ?.addEventListener("click", copySshKeyToClipboard); + document.querySelectorAll("copySshKey").forEach((elem) => { + elem.addEventListener("click", copySshKeyToClipboard); + }); </script> <style> diff --git a/src/pages/skills.astro b/src/pages/skills.astro new file mode 100644 index 0000000..550ac1d --- /dev/null +++ b/src/pages/skills.astro @@ -0,0 +1,6 @@ +--- +import Terminal from "../layouts/Terminal.astro"; +--- + +<Terminal path="skills"> +</Terminal> diff --git a/src/styles/terminal.css b/src/styles/terminal.css index 517eac7..3d8e51b 100644 --- a/src/styles/terminal.css +++ b/src/styles/terminal.css @@ -61,7 +61,6 @@ main { width: 55rem; max-width: 75%; max-height: 75%; - padding-top: 1.25rem; overflow: hidden; } |
