Release 2025-05-19
This commit is contained in:
@@ -1,101 +0,0 @@
|
||||
---
|
||||
import BaseHead from '../components/BaseHead.astro'
|
||||
import Footer from '../components/Footer.astro'
|
||||
import Header from '../components/Header.astro'
|
||||
import { cn } from '../lib/cn'
|
||||
|
||||
import type { AstroChildren } from '../lib/astro'
|
||||
import type { ComponentProps } from 'astro/types'
|
||||
|
||||
import '@fontsource-variable/space-grotesk'
|
||||
import '../styles/global.css'
|
||||
|
||||
type Props = ComponentProps<typeof BaseHead> & {
|
||||
children: AstroChildren
|
||||
errors?: string[]
|
||||
success?: string[]
|
||||
className?: {
|
||||
body?: string
|
||||
main?: string
|
||||
footer?: string
|
||||
}
|
||||
showSplashText?: boolean
|
||||
widthClassName?:
|
||||
| 'container'
|
||||
| 'max-w-none'
|
||||
| 'max-w-screen-2xl'
|
||||
| 'max-w-screen-lg'
|
||||
| 'max-w-screen-md'
|
||||
| 'max-w-screen-sm'
|
||||
| 'max-w-screen-xl'
|
||||
| 'max-w-screen-xs'
|
||||
}
|
||||
|
||||
const {
|
||||
errors = [],
|
||||
success = [],
|
||||
className,
|
||||
widthClassName = 'max-w-screen-2xl',
|
||||
showSplashText,
|
||||
...baseHeadProps
|
||||
} = Astro.props
|
||||
|
||||
const actualErrors = [...errors, ...Astro.locals.banners.errors]
|
||||
const actualSuccess = [...success, ...Astro.locals.banners.successes]
|
||||
---
|
||||
|
||||
<html lang="en" transition:name="root" transition:animate="none">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<BaseHead {...baseHeadProps} />
|
||||
</head>
|
||||
<body class={cn('bg-night-700 text-day-300 flex min-h-dvh flex-col *:shrink-0', className?.body)}>
|
||||
<Header
|
||||
classNames={{
|
||||
nav: cn(
|
||||
(widthClassName === 'max-w-none' || widthClassName === 'max-w-screen-2xl') && 'lg:px-8 2xl:px-12',
|
||||
widthClassName
|
||||
),
|
||||
}}
|
||||
showSplashText={showSplashText}
|
||||
/>
|
||||
|
||||
{
|
||||
actualSuccess.length > 0 && (
|
||||
<ul class="container mx-auto my-4 space-y-4 px-4">
|
||||
{actualSuccess.map((message) => (
|
||||
<li class="font-title rounded-lg border border-green-500/30 bg-green-500/20 px-4 py-3 text-green-400">
|
||||
{message}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
actualErrors.length > 0 && (
|
||||
<ul class="container mx-auto my-4 space-y-4 px-4">
|
||||
{actualErrors.map((error) => (
|
||||
<li class="font-title rounded-lg border border-red-500/30 bg-red-500/20 px-4 py-3 text-red-400">
|
||||
{error}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
<main
|
||||
class={cn(
|
||||
'container mx-auto mt-4 mb-12 grow px-4',
|
||||
className?.main,
|
||||
(widthClassName === 'max-w-none' || widthClassName === 'max-w-screen-2xl') && 'lg:px-8 2xl:px-12',
|
||||
widthClassName
|
||||
)}
|
||||
>
|
||||
<slot />
|
||||
</main>
|
||||
|
||||
<Footer class={className?.footer} />
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,72 +0,0 @@
|
||||
---
|
||||
import { makeOgImageUrl, type OgImageAllTemplatesWithProps } from '../components/OgImage'
|
||||
import { KYCNOTME_SCHEMA_MINI } from '../lib/schema'
|
||||
|
||||
import BaseLayout from './BaseLayout.astro'
|
||||
|
||||
import type { AstroChildren } from '../lib/astro'
|
||||
import type { MarkdownLayoutProps } from 'astro'
|
||||
import type { ComponentProps } from 'astro/types'
|
||||
import type { Article, WithContext } from 'schema-dts'
|
||||
|
||||
type Props = ComponentProps<typeof BaseLayout> &
|
||||
MarkdownLayoutProps<{
|
||||
children: AstroChildren
|
||||
title: string
|
||||
author: string
|
||||
pubDate: string
|
||||
description: string
|
||||
}>
|
||||
|
||||
const { frontmatter, schemas, ...baseLayoutProps } = Astro.props
|
||||
const publishDate = frontmatter.pubDate ? new Date(frontmatter.pubDate) : null
|
||||
const ogImageTemplateData = {
|
||||
template: 'generic',
|
||||
title: frontmatter.title,
|
||||
} satisfies OgImageAllTemplatesWithProps
|
||||
const weAreAuthor = frontmatter.author.toLowerCase().trim() === 'kycnot.me'
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
{...baseLayoutProps}
|
||||
pageTitle={frontmatter.title}
|
||||
description={frontmatter.description}
|
||||
ogImage={ogImageTemplateData}
|
||||
schemas={[
|
||||
{
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'Article',
|
||||
headline: frontmatter.title,
|
||||
description: frontmatter.description,
|
||||
datePublished: publishDate?.toISOString(),
|
||||
dateModified: publishDate?.toISOString(),
|
||||
image: makeOgImageUrl(ogImageTemplateData, Astro.url),
|
||||
author: frontmatter.author
|
||||
? weAreAuthor
|
||||
? KYCNOTME_SCHEMA_MINI
|
||||
: {
|
||||
'@type': 'Person',
|
||||
name: frontmatter.author,
|
||||
}
|
||||
: undefined,
|
||||
publisher: KYCNOTME_SCHEMA_MINI,
|
||||
mainEntityOfPage: {
|
||||
'@type': 'WebPage',
|
||||
url: Astro.url.href,
|
||||
},
|
||||
} satisfies WithContext<Article>,
|
||||
...(schemas ?? []),
|
||||
]}
|
||||
>
|
||||
<div
|
||||
class="prose prose-invert prose-headings:text-green-400 prose-h1:text-[2.5rem] prose-h1:font-bold prose-h1:my-8 prose-h1:drop-shadow-[0_0_10px_rgba(0,255,0,0.3)] prose-h2:text-green-500 prose-h2:text-[1.8rem] prose-h2:font-semibold prose-h2:my-6 prose-h2:border-b prose-h2:border-green-900 prose-h2:pb-1 prose-h3:text-green-600 prose-h3:text-[1.4rem] prose-h3:font-semibold prose-h3:my-4 prose-h4:text-green-700 prose-h4:text-[1.2rem] prose-h4:font-semibold prose-h4:my-3 prose-strong:font-semibold prose-strong:drop-shadow-[0_0_5px_rgba(0,255,0,0.2)] prose-p:text-gray-300 prose-p:my-4 prose-p:leading-relaxed prose-a:text-green-400 prose-a:no-underline prose-a:transition-all prose-a:border-b prose-a:border-green-900 prose-a:hover:text-green-400 prose-a:hover:drop-shadow-[0_0_8px_rgba(0,255,0,0.4)] prose-a:hover:border-green-400 prose-ul:text-gray-300 prose-ol:text-gray-300 prose-li:my-2 prose-li:leading-relaxed mx-auto"
|
||||
>
|
||||
<h1>{frontmatter.title}</h1>
|
||||
<p class="text-gray-500">
|
||||
{frontmatter.author && `by ${frontmatter.author}`}
|
||||
{frontmatter.pubDate && ` | ${new Date(frontmatter.pubDate).toLocaleDateString()}`}
|
||||
</p>
|
||||
|
||||
<slot />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -1,38 +0,0 @@
|
||||
---
|
||||
import { Icon } from 'astro-icon/components'
|
||||
|
||||
import { cn } from '../lib/cn'
|
||||
|
||||
import BaseLayout from './BaseLayout.astro'
|
||||
|
||||
import type { ComponentProps } from 'astro/types'
|
||||
|
||||
type Props = Omit<ComponentProps<typeof BaseLayout>, 'widthClassName'> & {
|
||||
layoutHeader: { icon: string; title: string; subtitle: string }
|
||||
}
|
||||
|
||||
const { layoutHeader, ...baseLayoutProps } = Astro.props
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
className={{
|
||||
...baseLayoutProps.className,
|
||||
main: cn('xs:items-center-safe flex grow flex-col justify-center-safe', baseLayoutProps.className?.main),
|
||||
}}
|
||||
{...baseLayoutProps}
|
||||
>
|
||||
<div
|
||||
class="bg-night-800 border-night-500 xs:block xs:max-w-screen-xs contents w-full rounded-xl border p-8"
|
||||
>
|
||||
<div class="bg-day-200 mx-auto flex size-12 items-center justify-center rounded-lg">
|
||||
<Icon name={layoutHeader.icon} class="text-night-800 size-8" />
|
||||
</div>
|
||||
|
||||
<h1 class="font-title text-day-200 mt-1 text-center text-3xl font-semibold">
|
||||
{layoutHeader.title}
|
||||
</h1>
|
||||
<p class="text-day-500 xs:mb-8 mt-1 mb-6 text-center">{layoutHeader.subtitle}</p>
|
||||
|
||||
<slot />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
Reference in New Issue
Block a user