chore: stylistic changes
This commit is contained in:
parent
051e466b6d
commit
f705c07d55
8 changed files with 128 additions and 43 deletions
|
@ -12,7 +12,7 @@ const { name, avatar, bio } = author.data
|
||||||
---
|
---
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="rounded-lg border p-4 transition-colors duration-300 ease-in-out hover:bg-secondary/50"
|
class="rounded-xl border p-4 transition-colors duration-300 ease-in-out hover:bg-secondary/50"
|
||||||
>
|
>
|
||||||
<Link href={`/authors/${author.slug}`} class="flex flex-wrap gap-4">
|
<Link href={`/authors/${author.slug}`} class="flex flex-wrap gap-4">
|
||||||
<Image
|
<Image
|
||||||
|
@ -20,7 +20,7 @@ const { name, avatar, bio } = author.data
|
||||||
alt={`Avatar of ${name}`}
|
alt={`Avatar of ${name}`}
|
||||||
width={128}
|
width={128}
|
||||||
height={128}
|
height={128}
|
||||||
class="rounded-lg object-cover"
|
class="rounded-xl object-cover"
|
||||||
/>
|
/>
|
||||||
<div class="flex-grow">
|
<div class="flex-grow">
|
||||||
<h3 class="mb-1 text-lg font-semibold">{name}</h3>
|
<h3 class="mb-1 text-lg font-semibold">{name}</h3>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { Image } from 'astro:assets'
|
||||||
import { Badge } from '@/components/ui/badge'
|
import { Badge } from '@/components/ui/badge'
|
||||||
import { Separator } from '@/components/ui/separator'
|
import { Separator } from '@/components/ui/separator'
|
||||||
import Link from './Link.astro'
|
import Link from './Link.astro'
|
||||||
|
import { getEntry } from 'astro:content'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
entry: CollectionEntry<'blog'>
|
entry: CollectionEntry<'blog'>
|
||||||
|
@ -16,10 +17,26 @@ const { entry } = Astro.props as {
|
||||||
|
|
||||||
const formattedDate = formatDate(entry.data.date)
|
const formattedDate = formatDate(entry.data.date)
|
||||||
const readTime = readingTime(entry.body)
|
const readTime = readingTime(entry.body)
|
||||||
|
|
||||||
|
let author = null
|
||||||
|
if (
|
||||||
|
entry.data.author &&
|
||||||
|
typeof entry.data.author === 'object' &&
|
||||||
|
'collection' in entry.data.author
|
||||||
|
) {
|
||||||
|
author = await getEntry(entry.data.author)
|
||||||
|
} else if (typeof entry.data.author === 'string') {
|
||||||
|
author = {
|
||||||
|
data: {
|
||||||
|
name: entry.data.author,
|
||||||
|
avatar: '/favicons/android-chrome-512x512.png',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="not-prose rounded-lg border p-4 transition-colors duration-300 ease-in-out hover:bg-secondary/50"
|
class="not-prose rounded-xl border p-4 transition-colors duration-300 ease-in-out hover:bg-secondary/50"
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
href={`/${entry.collection}/${entry.slug}`}
|
href={`/${entry.collection}/${entry.slug}`}
|
||||||
|
@ -33,7 +50,7 @@ const readTime = readingTime(entry.body)
|
||||||
alt={entry.data.title}
|
alt={entry.data.title}
|
||||||
width={200}
|
width={200}
|
||||||
height={200}
|
height={200}
|
||||||
class="rounded-lg object-cover"
|
class="rounded-xl object-cover"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -48,6 +65,21 @@ const readTime = readingTime(entry.body)
|
||||||
<div
|
<div
|
||||||
class="mb-2 flex items-center space-x-2 text-xs text-muted-foreground"
|
class="mb-2 flex items-center space-x-2 text-xs text-muted-foreground"
|
||||||
>
|
>
|
||||||
|
{author && (
|
||||||
|
<>
|
||||||
|
<div class="flex items-center gap-1.5">
|
||||||
|
<Image
|
||||||
|
src={author.data.avatar}
|
||||||
|
alt={author.data.name}
|
||||||
|
width={18}
|
||||||
|
height={18}
|
||||||
|
class="rounded-full"
|
||||||
|
/>
|
||||||
|
<span>{author.data.name}</span>
|
||||||
|
</div>
|
||||||
|
<Separator orientation="vertical" className="h-4" />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<span>{formattedDate}</span>
|
<span>{formattedDate}</span>
|
||||||
<Separator orientation="vertical" className="h-4" />
|
<Separator orientation="vertical" className="h-4" />
|
||||||
<span>{readTime}</span>
|
<span>{readTime}</span>
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
---
|
|
||||||
interface Props {
|
|
||||||
date: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
const { date } = Astro.props
|
|
||||||
---
|
|
||||||
|
|
||||||
<time datetime={date.toISOString()}>
|
|
||||||
{
|
|
||||||
date.toLocaleDateString('en-US', {
|
|
||||||
month: 'long',
|
|
||||||
day: '2-digit',
|
|
||||||
year: 'numeric',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</time>
|
|
|
@ -1,15 +0,0 @@
|
||||||
---
|
|
||||||
import 'bootstrap-icons/font/bootstrap-icons.css'
|
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
URL: string
|
|
||||||
icon: string
|
|
||||||
icon_size: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const { URL, icon, icon_size } = Astro.props
|
|
||||||
---
|
|
||||||
|
|
||||||
<a href={URL} target={'_blank'} class={`inline-block ${icon_size}`}>
|
|
||||||
<i class={`bi bi-${icon}`}></i>
|
|
||||||
</a>
|
|
|
@ -27,7 +27,7 @@ function buildToc(headings: Heading[]) {
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<details open class="mb-8 block rounded-lg border p-3 xl:hidden">
|
<details open class="mb-8 block rounded-xl border p-3 xl:hidden">
|
||||||
<summary class="cursor-pointer text-xl font-semibold"
|
<summary class="cursor-pointer text-xl font-semibold"
|
||||||
>Table of Contents</summary
|
>Table of Contents</summary
|
||||||
>
|
>
|
||||||
|
|
76
src/components/ui/card.tsx
Normal file
76
src/components/ui/card.tsx
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
import * as React from "react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Card = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"rounded-xl border bg-card text-card-foreground shadow",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
Card.displayName = "Card"
|
||||||
|
|
||||||
|
const CardHeader = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
CardHeader.displayName = "CardHeader"
|
||||||
|
|
||||||
|
const CardTitle = React.forwardRef<
|
||||||
|
HTMLParagraphElement,
|
||||||
|
React.HTMLAttributes<HTMLHeadingElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<h3
|
||||||
|
ref={ref}
|
||||||
|
className={cn("font-semibold leading-none tracking-tight", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
CardTitle.displayName = "CardTitle"
|
||||||
|
|
||||||
|
const CardDescription = React.forwardRef<
|
||||||
|
HTMLParagraphElement,
|
||||||
|
React.HTMLAttributes<HTMLParagraphElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<p
|
||||||
|
ref={ref}
|
||||||
|
className={cn("text-sm text-muted-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
CardDescription.displayName = "CardDescription"
|
||||||
|
|
||||||
|
const CardContent = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
||||||
|
))
|
||||||
|
CardContent.displayName = "CardContent"
|
||||||
|
|
||||||
|
const CardFooter = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={cn("flex items-center p-6 pt-0", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
CardFooter.displayName = "CardFooter"
|
||||||
|
|
||||||
|
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
|
|
@ -2,8 +2,7 @@
|
||||||
import { type CollectionEntry, getCollection, getEntry } from 'astro:content'
|
import { type CollectionEntry, getCollection, getEntry } from 'astro:content'
|
||||||
import Layout from '@layouts/Layout.astro'
|
import Layout from '@layouts/Layout.astro'
|
||||||
import Container from '@components/Container.astro'
|
import Container from '@components/Container.astro'
|
||||||
import FormattedDate from '@components/FormattedDate.astro'
|
import { formatDate, readingTime } from '@lib/utils'
|
||||||
import { readingTime } from '@lib/utils'
|
|
||||||
import PostNavigation from '@components/PostNavigation.astro'
|
import PostNavigation from '@components/PostNavigation.astro'
|
||||||
import TableOfContents from '@components/TableOfContents.astro'
|
import TableOfContents from '@components/TableOfContents.astro'
|
||||||
import { Image } from 'astro:assets'
|
import { Image } from 'astro:assets'
|
||||||
|
@ -104,7 +103,7 @@ if (
|
||||||
alt={post.data.title}
|
alt={post.data.title}
|
||||||
width={1200}
|
width={1200}
|
||||||
height={630}
|
height={630}
|
||||||
class="mb-8 rounded-lg object-cover shadow-lg"
|
class="mb-8 rounded-xl object-cover shadow-lg"
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -144,7 +143,7 @@ if (
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
<FormattedDate date={post.data.date} />
|
<span>{formatDate(post.data.date)}</span>
|
||||||
<Separator orientation="vertical" className="h-4" />
|
<Separator orientation="vertical" className="h-4" />
|
||||||
<span>{readingTime(post.body)}</span>
|
<span>{readingTime(post.body)}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,6 +6,7 @@ import BlogCard from '@components/BlogCard.astro'
|
||||||
import { buttonVariants } from '@/components/ui/button'
|
import { buttonVariants } from '@/components/ui/button'
|
||||||
import { getCollection } from 'astro:content'
|
import { getCollection } from 'astro:content'
|
||||||
import Link from '@components/Link.astro'
|
import Link from '@components/Link.astro'
|
||||||
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||||
|
|
||||||
const blog = (await getCollection('blog'))
|
const blog = (await getCollection('blog'))
|
||||||
.filter((post) => !post.data.draft)
|
.filter((post) => !post.data.draft)
|
||||||
|
@ -16,8 +17,17 @@ const blog = (await getCollection('blog'))
|
||||||
<Layout title="Home" description="Home">
|
<Layout title="Home" description="Home">
|
||||||
<Container>
|
<Container>
|
||||||
<section class="space-y-6">
|
<section class="space-y-6">
|
||||||
<div class="min-w-full">
|
<Card>
|
||||||
<h1 class="mb-4 text-3xl font-bold">Occasionally, less is more</h1>
|
<CardHeader>
|
||||||
|
<CardTitle className="text-3xl">er·u·dite</CardTitle>
|
||||||
|
<CardDescription>/ˈer(y)əˌdīt/</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<p class="font-medium">adjective</p>
|
||||||
|
<p>having or showing great knowledge or learning.</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<div class="mt-8">
|
||||||
<p class="prose min-w-full dark:prose-invert">
|
<p class="prose min-w-full dark:prose-invert">
|
||||||
{SITE.TITLE} is an opinionated, no-frills static blogging template built
|
{SITE.TITLE} is an opinionated, no-frills static blogging template built
|
||||||
with Astro.
|
with Astro.
|
||||||
|
|
Loading…
Add table
Reference in a new issue