further restyle tweaks
All checks were successful
Deploy Blog / deploy (push) Successful in 3m7s

This commit is contained in:
Thomas Bishop 2026-03-13 18:40:02 +00:00
parent dbf853be9e
commit a52c80333d
9 changed files with 251 additions and 194 deletions

View file

@ -1,29 +1,35 @@
import MetricBar from "./MetricBar" import MetricBar from "./MetricBar"
const LanguagesChart = ({ chartData, error }) => { const LanguagesChart = ({ chartData, error }) => {
return ( return (
<div style={{marginTop:'1rem'}}> <div style={{ marginTop: "1rem" }}>
<div className="code-stat-label" style={{marginBottom: '.5rem'}}> <div
Programming languages className="code-stat-label"
</div> style={{
paddingBottom: ".5rem",
marginBottom: ".5rem",
}}
>
Programming languages
</div>
{error ? ( {error ? (
<div>Data could not be found!</div> <div>Data could not be found!</div>
) : !chartData?.length ? ( ) : !chartData?.length ? (
<div>No data for time period.</div> <div>No data for time period.</div>
) : ( ) : (
chartData.map((x) => ( chartData.map((x) => (
<MetricBar <MetricBar
key={x.language} key={x.language}
metric={x.language} metric={x.language}
hours={x.hours} hours={x.hours}
percentage={x.percentage} percentage={x.percentage}
color="dodgerblue" color="black"
/> />
)) ))
)} )}
</div> </div>
) )
} }
export default LanguagesChart export default LanguagesChart

View file

@ -1,36 +1,36 @@
const MetricBar = ({ metric, hours, percentage, color }) => ( const MetricBar = ({ metric, hours, percentage, color }) => (
<div style={{ marginBottom: "12px", margin: '.5rem' }}> <div style={{ marginBottom: "12px" }}>
<div <div
style={{ style={{
display: "flex", display: "flex",
justifyContent: "space-between", justifyContent: "space-between",
marginBottom: "4px", marginBottom: "4px",
fontSize: "14px", fontSize: "14px",
}} }}
> >
<span style={{}}>{metric}</span> <span style={{}}>{metric}</span>
<span style={{ color: "black" }}> <span style={{ color: "black" }}>
{hours}h ({percentage}%) {hours}h ({percentage}%)
</span> </span>
</div> </div>
<div <div
style={{ style={{
width: "100%", width: "100%",
height: "8px", height: "8px",
backgroundColor: "lightgrey", backgroundColor: "lightgrey",
overflow: "hidden", overflow: "hidden",
}} }}
> >
<div <div
style={{ style={{
width: `${percentage}%`, width: `${percentage}%`,
height: "100%", height: "100%",
backgroundColor: color, backgroundColor: color,
transition: "width 0.3s ease", transition: "width 0.3s ease",
}} }}
/> />
</div> </div>
</div> </div>
) )
export default MetricBar export default MetricBar

View file

@ -1,30 +1,38 @@
import MetricBar from "./MetricBar" import MetricBar from "./MetricBar"
const ProjectsChart = ({ chartData, error }) => { const ProjectsChart = ({ chartData, error }) => {
return ( return (
<div style={{marginTop: '1rem'}}> <div style={{ marginTop: "1rem" }}>
<div className="code-stat-label">Repos</div> <div
className="code-stat-label"
style={{
paddingBottom: ".5rem",
marginBottom: ".5rem",
}}
>
Repos
</div>
{error ? ( {error ? (
<div>Data could not be found!</div> <div>Data could not be found!</div>
) : !chartData?.length ? ( ) : !chartData?.length ? (
<div>No data for time period.</div> <div>No data for time period.</div>
) : ( ) : (
chartData.map((x) => ( chartData.map((x) => (
<MetricBar <MetricBar
key={x.project} key={x.project}
metric={x.project} metric={x.project}
hours={x.hours} hours={x.hours}
percentage={x.percentage} percentage={x.percentage}
color="dodgerblue" color="black"
/> />
)) ))
)} )}
<div className="code-stats-disclaimer"> <div className="code-stats-disclaimer">
Data excludes workplace repos. Data excludes workplace repos.
</div> </div>
</div> </div>
) )
} }
export default ProjectsChart export default ProjectsChart

View file

@ -1,4 +1,5 @@
import { useQuery } from "@tanstack/react-query" import { useQuery } from "@tanstack/react-query"
import wakapiApi from "../api/wakapi-api" import wakapiApi from "../api/wakapi-api"
import { convertDateFriendly } from "../utils/convertDate" import { convertDateFriendly } from "../utils/convertDate"
import Scorecard from "../components/Scorecard" import Scorecard from "../components/Scorecard"
@ -32,7 +33,9 @@ const CodeStats = () => {
data && data &&
data?.projects.filter( data?.projects.filter(
(project) => (project) =>
!project.key.includes("gp-") && !project.key.includes("unknown") && !project.key.includes("amber") !project.key.includes("gp-") &&
!project.key.includes("unknown") &&
!project.key.includes("amber")
) )
const personalProjectsSorted = const personalProjectsSorted =
@ -67,43 +70,52 @@ const CodeStats = () => {
.slice(0, 4) .slice(0, 4)
return ( return (
<div className=""> <div className="code-stats-sect">
<div className=""> <div className="">
<section className=""> <section className="">
<div className=""> <div className="">
<h2 className=""> <h2 className="big-title">{`Code this month`}</h2>
{`Code stats`}
</h2>
<div className="code-stat-grid">
<span className="code-stat-label" style={{marginRight: '2rem'}}>Period:</span>
<span className="code-stat-metric">{convertDateFriendly(data?.from)} -{" "}
{convertDateFriendly(data?.to)}</span>
</div>
</div>
<div className="">
<Scorecard
title="Total time:"
metric={
error ? "Error" : isLoading ? "Loading..." : grandTotalFormatted
}
/>
<Scorecard {/*
title="Main project" <table
metric={error ? "Error" : isLoading ? "Loading..." : mainProject} border="1"
/> width="100%"
style={{ borderCollapse: "collapse" }}
>
<tr>
<td style={{ paddingLeft: "4px" }}>Period:</td>
<td style={{ paddingLeft: "4px" }}>
{convertDateFriendly(data?.from)} -{" "}
{convertDateFriendly(data?.to)}
</td>
</tr>
<tr>
<td style={{ paddingLeft: "4px" }}>Total time:</td>
<td style={{ paddingLeft: "4px" }}>
{error
? "Error"
: isLoading
? "Loading..."
: grandTotalFormatted}
</td>
</tr>
<tr>
<td style={{ paddingLeft: "4px" }}>Main project:</td>
<td style={{ paddingLeft: "4px" }}>
{error ? "Error" : isLoading ? "Loading..." : mainProject}
</td>
</tr>
</table>
*/}
</div> </div>
<LanguagesChart chartData={languagesChartData} error={error} /> <LanguagesChart chartData={languagesChartData} error={error} />
<ProjectsChart chartData={projectsChartData} error={error} /> <ProjectsChart chartData={projectsChartData} error={error} />
<div className="code-stats-disclaimer"> <div className="code-stats-disclaimer">
Data sourced from my self-hosted{" "} Data sourced from my self-hosted{" "}
<a <a href="https://wakapi.dev/" target="__blank" className="">
href="https://wakapi.dev/"
target="__blank"
className=""
>
Wakapi Wakapi
</a>{" "} </a>{" "}
instance. instance.

View file

@ -4,62 +4,56 @@ import { Link } from "react-router"
import { convertDate } from "@/utils/convertDate" import { convertDate } from "@/utils/convertDate"
const PostListing = ({ posts, title, showAllButton }) => { const PostListing = ({ posts, title, showAllButton }) => {
return ( return (
<div className=""> <div className="">
<div className=""> <div className="">
<section className=""> <section className="">
<h2 className=""> <h2 className="big-title">{`${title}`}</h2>
{`${title}`} {posts.map((post) => (
</h2> <ul className="no-bullets">
{posts.map((post) => ( <li className="">
<ul className="no-bullets"> <div className="post-listing-item">
<li className=""> <span style={{ marginRight: "1rem" }}>
<div className="post-listing-item"> {convertDate(post.date)}
<span style={{ marginRight: '1rem' }}> </span>
{convertDate(post.date)} <Link to={`/posts/${post.slug}`} key={post.slug} className="">
</span> {post.title}
<Link </Link>
to={`/posts/${post.slug}`} </div>
key={post.slug} </li>
className="" </ul>
> ))}
{post.title} </section>
</Link> </div>
</div> </div>
</li> )
</ul>
))}
</section>
</div>
</div>
)
} }
export default PostListing export default PostListing
{ {
/* /*
<Link <Link
to={`/posts/${post.slug}`} to={`/posts/${post.slug}`}
key={post.slug} key={post.slug}
className="block no-underline" className="block no-underline"
> >
<Card <Card
key={post.slug} key={post.slug}
className="flex flex-col h-full hover:bg-primary/5 py-4 rounded border-none " className="flex flex-col h-full hover:bg-primary/5 py-4 rounded border-none "
> >
<CardHeader className=""> <CardHeader className="">
<CardTitle className="leading-snug font-bold "> <CardTitle className="leading-snug font-bold ">
{post.title} {post.title}
</CardTitle> </CardTitle>
<CardDescription className="text-sm text-muted-foreground"> <CardDescription className="text-sm text-muted-foreground">
<div className="flex justify-between gap-2"> <div className="flex justify-between gap-2">
<span className="text-sm">{convertDate(post.date)}</span> <span className="text-sm">{convertDate(post.date)}</span>
</div> </div>
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
</Card> </Card>
</Link> </Link>
*/ */
} }

View file

@ -15,20 +15,35 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.title-link {
letter-spacing: 0 !important;
}
} }
.post-listing-item { .post-listing-item {
display: flex; display: flex;
} }
h1.site-title { html {
font-weight: 800; font-family:
system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
Oxygen,
Ubuntu,
Cantarell,
"Open Sans",
"Helvetica Neue",
sans-serif;
} }
.header-links { .header-links {
display: flex; display: flex;
list-style: none; list-style: none;
gap: 0.5rem; gap: 1rem;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
@ -71,6 +86,10 @@ figure img {
overflow: auto; overflow: auto;
} }
.code-stats-sect {
font-family: sans-serif !important;
}
.code-stat-grid { .code-stat-grid {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -79,8 +98,8 @@ figure img {
} }
.code-stat-label { .code-stat-label {
font-weight: 500; font-weight: bold;
font-style: italic; font-family: sans-serif;
} }
.code-stats-disclaimer { .code-stats-disclaimer {
@ -92,3 +111,18 @@ figure img {
.about-li-padding { .about-li-padding {
padding-right: 1rem; padding-right: 1rem;
} }
h1.site-title,
h1.post-title {
margin-bottom: 0.75rem;
}
.big-title {
padding-bottom: 0.5rem;
margin-bottom: 0.5rem;
border-bottom: 1px solid black;
}
.blog-meta {
font-size: 14px;
}

View file

@ -7,25 +7,22 @@ import CodeStats from "../containers/CodeStats"
import { Link } from "react-router" import { Link } from "react-router"
const HomePage = () => { const HomePage = () => {
const { posts } = usePosts() const { posts } = usePosts()
return ( return (
<MainTemplate> <MainTemplate>
<p>A wizard who goes to bed early. This is <Link to="/about">my</Link> technical scrapbook <p>
and digital garden. A wizard who goes to bed early. This is <Link to="/about">my</Link>{" "}
</p> technical scrapbook and digital garden.
</p>
<PostListing title="Recent posts" posts={posts.slice(0, 5)} />
<PostListing title="Recent posts" posts={posts.slice(0, 5)} /> <PostListing
title="Highlights"
<PostListing posts={posts.filter((post) => post.tags.includes("highlight"))}
title="Highlights" />
posts={posts.filter((post) => post.tags.includes("highlight"))} </MainTemplate>
/> )
<CodeStats />
</MainTemplate>
)
} }
export { HomePage } export { HomePage }

View file

@ -17,11 +17,19 @@ const BlogTemplate = () => {
<div>Loading...</div> <div>Loading...</div>
) : ( ) : (
<article className=""> <article className="">
<header className=""> <header
<h1 className=""> className="big-title"
{post?.title} style={{ paddingBottom: "1rem", marginBottom: "2rem" }}
</h1> >
<div className=""> <h1 className="post-title">{post?.title}</h1>
<div
className="blog-meta"
style={{
display: "flex",
flexDirection: "row",
gap: "1rem",
}}
>
<time datetime={convertDate(post?.date)} className="text-sm"> <time datetime={convertDate(post?.date)} className="text-sm">
{convertDateFriendly(post?.date)} {convertDateFriendly(post?.date)}
</time> </time>
@ -29,7 +37,7 @@ const BlogTemplate = () => {
<span>Tag(s): </span> <span>Tag(s): </span>
{post?.tags?.map((tag, i) => ( {post?.tags?.map((tag, i) => (
<Link <Link
style={{ marginRight: '0.5rem' }} style={{ marginRight: "0.5rem" }}
key={i} key={i}
to={`/tags/${tag}`} to={`/tags/${tag}`}
> >
@ -40,9 +48,7 @@ const BlogTemplate = () => {
</div> </div>
</header> </header>
<div <div dangerouslySetInnerHTML={{ __html: post?.html }} />
dangerouslySetInnerHTML={{ __html: post?.html }}
/>
</article> </article>
)} )}
</div> </div>

View file

@ -6,15 +6,15 @@ const Header = () => {
<header> <header>
<nav className=""> <nav className="">
<h1 className="site-title"> <h1 className="site-title">
<Link <Link className="title-link plain-link" to="/">
className="plain-link" Systems Obscure
to="/">Systems Obscure</Link> </Link>
</h1> </h1>
<ul className="header-links"> <ul className="header-links">
<li> <li>
<Link to="/">Home</Link> <Link to="/">Home</Link>
</li> </li>
<li> <li>
<Link to="/posts">Posts</Link> <Link to="/posts">Posts</Link>
</li> </li>
@ -27,10 +27,9 @@ const Header = () => {
href="https://forgejo.systemsobscure.net/thomasabishop" href="https://forgejo.systemsobscure.net/thomasabishop"
target="blank" target="blank"
> >
Forgejo (ext.) Code
</a> </a>
</li> </li>
</ul> </ul>
</nav> </nav>
</header> </header>
@ -69,4 +68,5 @@ const MainTemplate = ({ children }) => {
} }
export default MainTemplate export default MainTemplate
//antialiased max-w-3xl mt-3 mx-auto bg-[#282828] no-scanlines wrapper //antialiased max-w-3xl mt-3 mx-auto bg-[#282828] no-scanlines wrapper
//main: flex-auto min-w-0 mt-0 flex flex-col px-2 md:px-0 //main: flex-auto min-w-0 mt-0 flex flex-col px-2 md:px-0