Add support for new config.yaml
This commit is contained in:
@ -28,8 +28,27 @@ import '@fontsource-variable/inter';
|
||||
--aw-color-primary: rgb(30 64 175);
|
||||
--aw-color-secondary: rgb(30 58 138);
|
||||
--aw-color-accent: rgb(109 40 217);
|
||||
--aw-color-text-page: rgb(17 24 39);
|
||||
|
||||
--aw-color-text-heading: rgb(0 0 0);
|
||||
--aw-color-text-default: rgb(16 16 16);
|
||||
--aw-color-text-muted: rgb(16 16 16 / 66%);
|
||||
--aw-color-bg-page: rgb(255 255 255);
|
||||
|
||||
--aw-color-bg-page-dark: rgb(3 6 32);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--aw-font-sans: 'Inter Variable';
|
||||
--aw-font-serif: var(--aw-font-sans);
|
||||
--aw-font-heading: var(--aw-font-sans);
|
||||
|
||||
--aw-color-primary: rgb(30 64 175);
|
||||
--aw-color-secondary: rgb(30 58 138);
|
||||
--aw-color-accent: rgb(109 40 217);
|
||||
|
||||
--aw-color-text-heading: rgb(0 0 0);
|
||||
--aw-color-text-default: rgb(229 236 246);
|
||||
--aw-color-text-muted: rgb(229 236 246 / 66%);
|
||||
--aw-color-bg-page: var(--aw-color-bg-page-dark);
|
||||
}
|
||||
</style>
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
import { SITE } from '~/config.mjs';
|
||||
import { SITE_CONFIG } from '~/utils/config';
|
||||
---
|
||||
|
||||
<span class="self-center ml-2 text-2xl md:text-xl font-bold text-gray-900 whitespace-nowrap dark:text-white">
|
||||
🚀 {SITE?.name}
|
||||
🚀 {SITE_CONFIG?.name}
|
||||
</span>
|
||||
|
@ -1,7 +1,8 @@
|
||||
---
|
||||
import { Picture } from '@astrojs/image/components';
|
||||
import type { ImageMetadata } from 'astro';
|
||||
|
||||
import { BLOG } from '~/config.mjs';
|
||||
import { APP_BLOG_CONFIG } from '~/utils/config';
|
||||
import type { Post } from '~/types';
|
||||
|
||||
import { findImage } from '~/utils/images';
|
||||
@ -12,7 +13,7 @@ export interface Props {
|
||||
}
|
||||
|
||||
const { post } = Astro.props;
|
||||
const image = await findImage(post.image);
|
||||
const image = (await findImage(post.image)) as ImageMetadata | undefined;
|
||||
---
|
||||
|
||||
<article class="mb-6 transition">
|
||||
@ -38,7 +39,7 @@ const image = await findImage(post.image);
|
||||
</div>
|
||||
<h3 class="mb-2 text-xl font-bold leading-tight sm:text-2xl font-heading">
|
||||
{
|
||||
BLOG?.post?.disabled ? (
|
||||
!APP_BLOG_CONFIG?.post?.isEnabled ? (
|
||||
post.title
|
||||
) : (
|
||||
<a
|
||||
@ -50,5 +51,5 @@ const image = await findImage(post.image);
|
||||
)
|
||||
}
|
||||
</h3>
|
||||
<p class="text-muted dark:text-slate-400 text-lg">{post.excerpt || post.description}</p>
|
||||
<p class="text-muted dark:text-slate-400 text-lg">{post.excerpt}</p>
|
||||
</article>
|
||||
|
@ -1,53 +0,0 @@
|
||||
---
|
||||
import Grid from '~/components/blog/Grid.astro';
|
||||
|
||||
import { getBlogPermalink } from '~/utils/permalinks';
|
||||
import { findPostsByIds } from '~/utils/blog';
|
||||
|
||||
export interface Props {
|
||||
title?: string;
|
||||
allPostsText?: string;
|
||||
allPostsLink?: string | URL;
|
||||
information?: string;
|
||||
postIds: string[];
|
||||
}
|
||||
|
||||
const {
|
||||
title = await Astro.slots.render('title'),
|
||||
allPostsText = 'View all posts',
|
||||
allPostsLink = getBlogPermalink(),
|
||||
information = await Astro.slots.render('information'),
|
||||
postIds = [],
|
||||
} = Astro.props;
|
||||
|
||||
const posts = await findPostsByIds(postIds);
|
||||
---
|
||||
|
||||
<section class="px-4 py-16 mx-auto max-w-7xl lg:py-20">
|
||||
<div class="flex flex-col lg:justify-between lg:flex-row mb-8">
|
||||
<div class="md:max-w-sm">
|
||||
{
|
||||
title && (
|
||||
<h2
|
||||
class="text-3xl font-bold tracking-tight sm:text-4xl sm:leading-none group font-heading mb-2"
|
||||
set:html={title}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
allPostsText && allPostsLink && (
|
||||
<a
|
||||
class="text-muted dark:text-slate-400 hover:text-primary transition ease-in duration-200 block mb-6 md:mb-0"
|
||||
href={allPostsLink}
|
||||
>
|
||||
{allPostsText} »
|
||||
</a>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
||||
{information && <p class="text-muted dark:text-slate-400 lg:text-sm lg:max-w-md" set:html={information} />}
|
||||
</div>
|
||||
|
||||
<Grid posts={posts} />
|
||||
</section>
|
@ -1,53 +0,0 @@
|
||||
---
|
||||
import Grid from '~/components/blog/Grid.astro';
|
||||
|
||||
import { getBlogPermalink } from '~/utils/permalinks';
|
||||
import { findLatestPosts } from '~/utils/blog';
|
||||
|
||||
export interface Props {
|
||||
title?: string;
|
||||
allPostsText?: string;
|
||||
allPostsLink?: string | URL;
|
||||
information?: string;
|
||||
count?: number;
|
||||
}
|
||||
|
||||
const {
|
||||
title = await Astro.slots.render('title'),
|
||||
allPostsText = 'View all posts',
|
||||
allPostsLink = getBlogPermalink(),
|
||||
information = await Astro.slots.render('information'),
|
||||
count = 4,
|
||||
} = Astro.props;
|
||||
|
||||
const posts = await findLatestPosts({ count });
|
||||
---
|
||||
|
||||
<section class="px-4 py-16 mx-auto max-w-7xl lg:py-20">
|
||||
<div class="flex flex-col lg:justify-between lg:flex-row mb-8">
|
||||
<div class="md:max-w-sm">
|
||||
{
|
||||
title && (
|
||||
<h2
|
||||
class="text-3xl font-bold tracking-tight sm:text-4xl sm:leading-none group font-heading mb-2"
|
||||
set:html={title}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
allPostsText && allPostsLink && (
|
||||
<a
|
||||
class="text-muted dark:text-slate-400 hover:text-primary transition ease-in duration-200 block mb-6 lg:mb-0"
|
||||
href={allPostsLink}
|
||||
>
|
||||
{allPostsText} »
|
||||
</a>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
||||
{information && <p class="text-muted dark:text-slate-400 lg:text-sm lg:max-w-md" set:html={information} />}
|
||||
</div>
|
||||
|
||||
<Grid posts={posts} />
|
||||
</section>
|
@ -1,9 +1,10 @@
|
||||
---
|
||||
import { Icon } from 'astro-icon/components';
|
||||
import { Picture } from '@astrojs/image/components';
|
||||
import type { ImageMetadata } from 'astro';
|
||||
import { Icon } from 'astro-icon/components';
|
||||
import PostTags from '~/components/blog/Tags.astro';
|
||||
|
||||
import { BLOG } from '~/config.mjs';
|
||||
import { APP_BLOG_CONFIG } from '~/utils/config';
|
||||
import type { Post } from '~/types';
|
||||
|
||||
import { getPermalink } from '~/utils/permalinks';
|
||||
@ -15,9 +16,9 @@ export interface Props {
|
||||
}
|
||||
|
||||
const { post } = Astro.props;
|
||||
const image = await findImage(post.image);
|
||||
const image = (await findImage(post.image)) as ImageMetadata | undefined;
|
||||
|
||||
const link = !BLOG?.post?.disabled ? getPermalink(post.permalink, 'post') : '';
|
||||
const link = APP_BLOG_CONFIG?.post?.isEnabled ? getPermalink(post.permalink, 'post') : '';
|
||||
---
|
||||
|
||||
<article class={`max-w-md mx-auto md:max-w-none grid gap-6 md:gap-8 ${image ? 'md:grid-cols-2' : ''}`}>
|
||||
|
@ -16,6 +16,7 @@ export interface Props {
|
||||
}
|
||||
|
||||
const { post, url } = Astro.props;
|
||||
const Content = post?.Content || null;
|
||||
---
|
||||
|
||||
<section class="py-8 sm:py-16 lg:py-20 mx-auto">
|
||||
@ -57,7 +58,7 @@ const { post, url } = Astro.props;
|
||||
class="max-w-full lg:max-w-6xl mx-auto mb-6 sm:rounded-md bg-gray-400 dark:bg-slate-700"
|
||||
widths={[400, 900]}
|
||||
sizes="(max-width: 900px) 400px, 900px"
|
||||
alt={post.description || ''}
|
||||
alt={post?.excerpt || ''}
|
||||
loading="eager"
|
||||
aspectRatio={16 / 9}
|
||||
width={900}
|
||||
@ -77,11 +78,8 @@ const { post, url } = Astro.props;
|
||||
class="mx-auto px-6 sm:px-6 max-w-3xl prose prose-lg lg:prose-xl dark:prose-invert dark:prose-headings:text-slate-300 prose-md prose-headings:font-heading prose-headings:leading-tighter prose-headings:tracking-tighter prose-headings:font-bold prose-a:text-primary dark:prose-a:text-blue-400 prose-img:rounded-md prose-img:shadow-lg mt-8"
|
||||
>
|
||||
{
|
||||
post.Content ? (
|
||||
<>
|
||||
{/* @ts-ignore */}
|
||||
<post.Content />
|
||||
</>
|
||||
Content ? (
|
||||
<Content />
|
||||
) : (
|
||||
<Fragment set:html={post.content} />
|
||||
)
|
||||
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
import { getPermalink } from '~/utils/permalinks';
|
||||
|
||||
import { BLOG } from '~/config.mjs';
|
||||
import { APP_BLOG_CONFIG } from '~/utils/config';
|
||||
import type { Post } from '~/types';
|
||||
|
||||
export interface Props {
|
||||
@ -23,7 +23,7 @@ const { tags, class: className = 'text-sm', title = undefined, isCategory = fals
|
||||
<ul class={className}>
|
||||
{tags.map((tag) => (
|
||||
<li class="bg-gray-100 dark:bg-slate-700 inline-block mr-2 mb-2 py-0.5 px-2 lowercase font-medium">
|
||||
{BLOG?.tag?.disabled ? (
|
||||
{!APP_BLOG_CONFIG?.tag?.isEnabled ? (
|
||||
tag
|
||||
) : (
|
||||
<a
|
||||
|
8
src/components/common/Analytics.astro
Normal file
8
src/components/common/Analytics.astro
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
import { GoogleAnalytics } from '@astrolib/analytics';
|
||||
import { ANALYTICS_CONFIG } from "~/utils/config";
|
||||
|
||||
---
|
||||
|
||||
<!-- Google Analytics -->
|
||||
{ANALYTICS_CONFIG?.vendors?.googleAnalytics?.isEnabled && <GoogleAnalytics id={String(ANALYTICS_CONFIG.vendors.googleAnalytics)} partytown={true} />}
|
33
src/components/common/ApplyColorMode.astro
Normal file
33
src/components/common/ApplyColorMode.astro
Normal file
@ -0,0 +1,33 @@
|
||||
---
|
||||
import { UI_CONFIG } from "~/utils/config";
|
||||
|
||||
// TODO: This code is temporary
|
||||
---
|
||||
|
||||
<script is:inline define:vars={{ defaultTheme: UI_CONFIG.theme || "system" }}>
|
||||
function applyTheme(theme) {
|
||||
if (theme === "dark") {
|
||||
document.documentElement.classList.add("dark");
|
||||
} else {
|
||||
document.documentElement.classList.remove("dark");
|
||||
}
|
||||
const matches = document.querySelectorAll("[data-aw-toggle-color-scheme] > input");
|
||||
|
||||
if (matches && matches.length) {
|
||||
matches.forEach((elem) => {
|
||||
elem.checked = theme !== "dark";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ((defaultTheme && defaultTheme.endsWith(":only")) || (!localStorage.theme && defaultTheme !== "system")) {
|
||||
applyTheme(defaultTheme.replace(":only", ""));
|
||||
} else if (
|
||||
localStorage.theme === "dark" ||
|
||||
(!("theme" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches)
|
||||
) {
|
||||
applyTheme("dark");
|
||||
} else {
|
||||
applyTheme("light");
|
||||
}
|
||||
</script>
|
@ -1,8 +1,8 @@
|
||||
---
|
||||
import { SITE } from '~/config.mjs';
|
||||
import { UI_CONFIG } from '~/utils/config';
|
||||
---
|
||||
|
||||
<script is:inline define:vars={{ defaultTheme: SITE.defaultTheme }}>
|
||||
<script is:inline define:vars={{ defaultTheme: UI_CONFIG.theme }}>
|
||||
function applyTheme(theme) {
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.classList.add('dark');
|
||||
|
8
src/components/common/CommonMeta.astro
Normal file
8
src/components/common/CommonMeta.astro
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
import { getAsset } from '~/utils/permalinks';
|
||||
---
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<link rel="sitemap" href={getAsset('/sitemap-index.xml')} />
|
@ -1,88 +0,0 @@
|
||||
---
|
||||
import { AstroSeo } from '@astrolib/seo';
|
||||
import { GoogleAnalytics } from '@astrolib/analytics';
|
||||
import { getImage } from '@astrojs/image';
|
||||
|
||||
import { SITE } from '~/config.mjs';
|
||||
import { MetaSEO } from '~/types';
|
||||
import { getCanonical, getAsset } from '~/utils/permalinks';
|
||||
import { getRelativeUrlByFilePath } from '~/utils/directories';
|
||||
|
||||
export interface Props extends MetaSEO {
|
||||
dontUseTitleTemplate?: boolean;
|
||||
}
|
||||
|
||||
const defaultImage = SITE.defaultImage
|
||||
? (
|
||||
await getImage({
|
||||
src: SITE.defaultImage,
|
||||
alt: 'Default image',
|
||||
width: 1200,
|
||||
height: 628,
|
||||
})
|
||||
).src
|
||||
: '';
|
||||
|
||||
const {
|
||||
title = SITE.name,
|
||||
description = '',
|
||||
image: _image = defaultImage,
|
||||
|
||||
canonical = getCanonical(String(Astro.url.pathname)),
|
||||
noindex = false,
|
||||
nofollow = false,
|
||||
|
||||
ogTitle = title,
|
||||
ogType = 'website',
|
||||
|
||||
dontUseTitleTemplate = false,
|
||||
} = Astro.props;
|
||||
|
||||
const image =
|
||||
typeof _image === 'string'
|
||||
? new URL(_image, Astro.site)
|
||||
: _image && typeof _image['src'] !== 'undefined'
|
||||
? // @ts-ignore
|
||||
new URL(getRelativeUrlByFilePath(_image.src), Astro.site)
|
||||
: null;
|
||||
---
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<AstroSeo
|
||||
title={title}
|
||||
titleTemplate={dontUseTitleTemplate ? '%s' : `%s — ${SITE.name}`}
|
||||
description={description}
|
||||
canonical={String(canonical)}
|
||||
noindex={noindex}
|
||||
nofollow={nofollow}
|
||||
openGraph={{
|
||||
url: String(canonical),
|
||||
title: ogTitle,
|
||||
description: description,
|
||||
type: ogType,
|
||||
images: image
|
||||
? [
|
||||
{
|
||||
url: image.toString(),
|
||||
alt: ogTitle,
|
||||
},
|
||||
]
|
||||
: undefined,
|
||||
// site_name: 'SiteName',
|
||||
}}
|
||||
twitter={{
|
||||
// handle: '@handle',
|
||||
// site: '@site',
|
||||
cardType: image ? 'summary_large_image' : undefined,
|
||||
}}
|
||||
/>
|
||||
|
||||
<!-- Google Site Verification -->
|
||||
{SITE.googleSiteVerificationId && <meta name="google-site-verification" content={SITE.googleSiteVerificationId} />}
|
||||
|
||||
<!-- Google Analytics -->
|
||||
{SITE.googleAnalyticsId && <GoogleAnalytics id={String(SITE.googleAnalyticsId)} partytown={true} />}
|
||||
|
||||
<link rel="sitemap" href={getAsset('/sitemap-index.xml')} />
|
68
src/components/common/Metadata.astro
Normal file
68
src/components/common/Metadata.astro
Normal file
@ -0,0 +1,68 @@
|
||||
---
|
||||
import merge from 'lodash.merge';
|
||||
import { AstroSeo } from '@astrolib/seo';
|
||||
|
||||
import type { AstroSeoProps } from '@astrolib/seo/src/types';
|
||||
|
||||
import { SITE_CONFIG, METADATA_CONFIG, I18N_CONFIG } from '~/utils/config';
|
||||
import { MetaData } from '~/types';
|
||||
import { getCanonical } from '~/utils/permalinks';
|
||||
|
||||
import { adaptOpenGraphImages } from '~/utils/images';
|
||||
|
||||
export interface Props extends MetaData {
|
||||
dontUseTitleTemplate?: boolean;
|
||||
}
|
||||
|
||||
const {
|
||||
title,
|
||||
ignoreTitleTemplate = false,
|
||||
canonical = String(getCanonical(String(Astro.url.pathname))),
|
||||
robots = {},
|
||||
description,
|
||||
openGraph = {},
|
||||
twitter = {},
|
||||
} = Astro.props;
|
||||
|
||||
const seoProps: AstroSeoProps = merge(
|
||||
{
|
||||
title: '',
|
||||
titleTemplate: '%s',
|
||||
canonical: canonical,
|
||||
noindex: true,
|
||||
nofollow: true,
|
||||
description: undefined,
|
||||
openGraph: {
|
||||
url: canonical,
|
||||
siteName: SITE_CONFIG?.name,
|
||||
images: [],
|
||||
locale: I18N_CONFIG?.language || 'en',
|
||||
type: 'website',
|
||||
},
|
||||
twitter: {
|
||||
cardType: openGraph?.images?.length ? 'summary_large_image' : 'summary',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: METADATA_CONFIG?.title?.default,
|
||||
titleTemplate: METADATA_CONFIG?.title?.template,
|
||||
noindex: typeof METADATA_CONFIG?.robots?.index !== 'undefined' ? !METADATA_CONFIG.robots.index : undefined,
|
||||
nofollow: typeof METADATA_CONFIG?.robots?.follow !== 'undefined' ? !METADATA_CONFIG.robots.follow : undefined,
|
||||
description: METADATA_CONFIG?.description,
|
||||
openGraph: METADATA_CONFIG?.openGraph,
|
||||
twitter: METADATA_CONFIG?.twitter,
|
||||
},
|
||||
{
|
||||
title: title,
|
||||
titleTemplate: ignoreTitleTemplate ? '%s' : undefined,
|
||||
canonical: canonical,
|
||||
noindex: typeof robots?.index !== 'undefined' ? !robots.index : undefined,
|
||||
nofollow: typeof robots?.follow !== 'undefined' ? !robots.follow : undefined,
|
||||
description: description,
|
||||
openGraph: { url: canonical, ...openGraph },
|
||||
twitter: twitter,
|
||||
}
|
||||
);
|
||||
---
|
||||
|
||||
<AstroSeo {...{ ...seoProps, openGraph: await adaptOpenGraphImages(seoProps?.openGraph, Astro.site) }} />
|
5
src/components/common/SiteVerification.astro
Normal file
5
src/components/common/SiteVerification.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import { SITE_CONFIG } from "~/utils/config";
|
||||
---
|
||||
|
||||
{SITE_CONFIG.googleSiteVerificationId && <meta name="google-site-verification" content={SITE_CONFIG.googleSiteVerificationId} />}
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
import { Icon } from 'astro-icon/components';
|
||||
|
||||
import { SITE } from '~/config.mjs';
|
||||
import { UI_CONFIG } from '~/utils/config';
|
||||
|
||||
export interface Props {
|
||||
label?: string;
|
||||
@ -20,7 +20,7 @@ const {
|
||||
---
|
||||
|
||||
{
|
||||
!(SITE?.defaultTheme && SITE.defaultTheme.endsWith(':only')) && (
|
||||
!(UI_CONFIG.theme && UI_CONFIG.theme.endsWith(':only')) && (
|
||||
<button type="button" class={className} aria-label={label} data-aw-toggle-color-scheme>
|
||||
<Icon name={iconName} class={iconClass} />
|
||||
</button>
|
||||
|
64
src/components/widgets/BlogHighlightedPosts.astro
Normal file
64
src/components/widgets/BlogHighlightedPosts.astro
Normal file
@ -0,0 +1,64 @@
|
||||
---
|
||||
import { APP_BLOG_CONFIG } from "~/utils/config";
|
||||
|
||||
import Grid from "~/components/blog/Grid.astro";
|
||||
|
||||
import { getBlogPermalink } from "~/utils/permalinks";
|
||||
import { findPostsByIds } from "~/utils/blog";
|
||||
import WidgetWrapper from "~/components/ui/WidgetWrapper.astro";
|
||||
import type { Widget } from "~/types";
|
||||
|
||||
export interface Props extends Widget {
|
||||
title?: string;
|
||||
linkText?: string;
|
||||
linkUrl?: string | URL;
|
||||
information?: string;
|
||||
postIds: string[];
|
||||
}
|
||||
|
||||
const {
|
||||
title = await Astro.slots.render("title"),
|
||||
linkText = "View all posts",
|
||||
linkUrl = getBlogPermalink(),
|
||||
information = await Astro.slots.render("information"),
|
||||
postIds = [],
|
||||
|
||||
id,
|
||||
isDark = false,
|
||||
classes = {},
|
||||
bg = await Astro.slots.render("bg"),
|
||||
} = Astro.props;
|
||||
|
||||
const posts = APP_BLOG_CONFIG.isEnabled ? await findPostsByIds(postIds) : [];
|
||||
---
|
||||
|
||||
{
|
||||
APP_BLOG_CONFIG.isEnabled ? (
|
||||
<WidgetWrapper id={id} isDark={isDark} containerClass={classes?.container} bg={bg}>
|
||||
<div class="flex flex-col lg:justify-between lg:flex-row mb-8">
|
||||
{title && (
|
||||
<div class="md:max-w-sm">
|
||||
<h2
|
||||
class="text-3xl font-bold tracking-tight sm:text-4xl sm:leading-none group font-heading mb-2"
|
||||
set:html={title}
|
||||
/>
|
||||
{APP_BLOG_CONFIG.list.isEnabled && linkText && linkUrl && (
|
||||
<a
|
||||
class="text-muted dark:text-slate-400 hover:text-primary transition ease-in duration-200 block mb-6 lg:mb-0"
|
||||
href={linkUrl}
|
||||
>
|
||||
{linkText} »
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{information && <p class="text-muted dark:text-slate-400 lg:text-sm lg:max-w-md" set:html={information} />}
|
||||
</div>
|
||||
|
||||
<Grid posts={posts} />
|
||||
</WidgetWrapper>
|
||||
) : (
|
||||
<Fragment />
|
||||
)
|
||||
}
|
64
src/components/widgets/BlogLatestPosts.astro
Normal file
64
src/components/widgets/BlogLatestPosts.astro
Normal file
@ -0,0 +1,64 @@
|
||||
---
|
||||
import { APP_BLOG_CONFIG } from "~/utils/config";
|
||||
|
||||
import Grid from "~/components/blog/Grid.astro";
|
||||
|
||||
import { getBlogPermalink } from "~/utils/permalinks";
|
||||
import { findLatestPosts } from "~/utils/blog";
|
||||
import WidgetWrapper from "~/components/ui/WidgetWrapper.astro";
|
||||
import type { Widget } from "~/types";
|
||||
|
||||
export interface Props extends Widget {
|
||||
title?: string;
|
||||
linkText?: string;
|
||||
linkUrl?: string | URL;
|
||||
information?: string;
|
||||
count?: number;
|
||||
}
|
||||
|
||||
const {
|
||||
title = await Astro.slots.render("title"),
|
||||
linkText = "View all posts",
|
||||
linkUrl = getBlogPermalink(),
|
||||
information = await Astro.slots.render("information"),
|
||||
count = 4,
|
||||
|
||||
id,
|
||||
isDark = false,
|
||||
classes = {},
|
||||
bg = await Astro.slots.render("bg"),
|
||||
} = Astro.props;
|
||||
|
||||
const posts = APP_BLOG_CONFIG.isEnabled ? await findLatestPosts({ count }) : [];
|
||||
---
|
||||
|
||||
{
|
||||
APP_BLOG_CONFIG.isEnabled ? (
|
||||
<WidgetWrapper id={id} isDark={isDark} containerClass={classes?.container} bg={bg}>
|
||||
<div class="flex flex-col lg:justify-between lg:flex-row mb-8">
|
||||
{title && (
|
||||
<div class="md:max-w-sm">
|
||||
<h2
|
||||
class="text-3xl font-bold tracking-tight sm:text-4xl sm:leading-none group font-heading mb-2"
|
||||
set:html={title}
|
||||
/>
|
||||
{APP_BLOG_CONFIG.list.isEnabled && linkText && linkUrl && (
|
||||
<a
|
||||
class="text-muted dark:text-slate-400 hover:text-primary transition ease-in duration-200 block mb-6 lg:mb-0"
|
||||
href={linkUrl}
|
||||
>
|
||||
{linkText} »
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{information && <p class="text-muted dark:text-slate-400 lg:text-sm lg:max-w-md" set:html={information} />}
|
||||
</div>
|
||||
|
||||
<Grid posts={posts} />
|
||||
</WidgetWrapper>
|
||||
) : (
|
||||
<Fragment />
|
||||
)
|
||||
}
|
@ -31,7 +31,7 @@ const {
|
||||
} = Astro.props;
|
||||
---
|
||||
|
||||
<section class:list={[{ 'pt-0 md:pt-0': isAfterContent }, 'bg-blue-50 dark:bg-slate-800 py-16 md:py-20 not-prose']}>
|
||||
<section class:list={[{ 'pt-0 md:pt-0': isAfterContent }, 'bg-blue-50 dark:bg-page py-16 md:py-20 not-prose']}>
|
||||
<div class="max-w-xl sm:mx-auto lg:max-w-2xl">
|
||||
{
|
||||
(title || subtitle || tagline) && (
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
import { Icon } from 'astro-icon/components';
|
||||
import { SITE } from '~/config.mjs';
|
||||
import { SITE_CONFIG } from '~/utils/config';
|
||||
import { getHomePermalink } from '~/utils/permalinks';
|
||||
|
||||
interface Link {
|
||||
@ -32,7 +32,7 @@ const { socialLinks = [], secondaryLinks = [], links = [], footNote = '', theme
|
||||
<div class="grid grid-cols-12 gap-4 gap-y-8 sm:gap-8 py-8 md:py-12">
|
||||
<div class="col-span-12 lg:col-span-4">
|
||||
<div class="mb-2">
|
||||
<a class="inline-block font-bold text-xl" href={getHomePermalink()}>{SITE?.name}</a>
|
||||
<a class="inline-block font-bold text-xl" href={getHomePermalink()}>{SITE_CONFIG?.name}</a>
|
||||
</div>
|
||||
<div class="text-sm text-muted">
|
||||
{
|
||||
|
@ -44,7 +44,8 @@ const {
|
||||
aspectRatio="432:768"
|
||||
width={432}
|
||||
height={768}
|
||||
{...image}
|
||||
src={image?.src}
|
||||
alt={image?.alt || ""}
|
||||
/>
|
||||
))
|
||||
}
|
||||
|
Reference in New Issue
Block a user