Fix minimal details
This commit is contained in:
@ -5,6 +5,7 @@ import { defineConfig } from "astro/config";
|
||||
|
||||
import tailwind from "@astrojs/tailwind";
|
||||
import sitemap from "@astrojs/sitemap";
|
||||
import partytown from "@astrojs/partytown";
|
||||
import image from "@astrojs/image";
|
||||
|
||||
import { SITE } from "./src/config.mjs";
|
||||
@ -26,6 +27,9 @@ export default defineConfig({
|
||||
},
|
||||
}),
|
||||
sitemap(),
|
||||
partytown({
|
||||
config: { forward: ["dataLayer.push"] },
|
||||
}),
|
||||
image(),
|
||||
],
|
||||
|
||||
|
@ -11,10 +11,10 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/image": "^0.3.3",
|
||||
"@astrojs/partytown": "^1.0.0",
|
||||
"@astrojs/rss": "^1.0.0",
|
||||
"@astrojs/sitemap": "^1.0.0",
|
||||
"@astrojs/tailwind": "^1.0.0",
|
||||
"@julian_cataldo/astro-analytics": "^0.11.5",
|
||||
"@tailwindcss/typography": "^0.5.4",
|
||||
"astro": "^1.0.0",
|
||||
"astro-icon": "^0.7.3",
|
||||
|
@ -3,10 +3,14 @@ const { } = Astro.props;
|
||||
---
|
||||
|
||||
<script is:inline>
|
||||
// Set "light" theme as default
|
||||
// if (!localStorage.theme) {
|
||||
// localStorage.theme = "light";
|
||||
// }
|
||||
|
||||
if (
|
||||
localStorage.theme === "dark" ||
|
||||
(!("theme" in localStorage) &&
|
||||
window.matchMedia("(prefers-color-scheme: dark)").matches)
|
||||
(!("theme" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches)
|
||||
) {
|
||||
document.documentElement.classList.add("dark");
|
||||
} else {
|
||||
@ -31,9 +35,7 @@ const { } = Astro.props;
|
||||
|
||||
attachEvent("[data-aw-toggle-color-scheme]", "click", function (elem) {
|
||||
document.documentElement.classList.toggle("dark");
|
||||
localStorage.theme = document.documentElement.classList.contains("dark")
|
||||
? "dark"
|
||||
: "light";
|
||||
localStorage.theme = document.documentElement.classList.contains("dark") ? "dark" : "light";
|
||||
});
|
||||
};
|
||||
window.onpageshow = function () {
|
||||
|
16
src/components/core/GoogleAnalytics.astro
Normal file
16
src/components/core/GoogleAnalytics.astro
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
const { id = "G-XXXXXXXXXX", partytown = false } = Astro.props;
|
||||
|
||||
const attrs = partytown ? { type: "text/partytown" } : {};
|
||||
---
|
||||
|
||||
<script is:inline async src={`https://www.googletagmanager.com/gtag/js?id=${id}`} {...attrs}></script>
|
||||
|
||||
<script is:inline define:vars={{ id }} {...attrs}>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag() {
|
||||
dataLayer.push(arguments);
|
||||
}
|
||||
gtag("js", new Date());
|
||||
gtag("config", id);
|
||||
</script>
|
@ -1,11 +1,14 @@
|
||||
---
|
||||
import { getImage } from "@astrojs/image";
|
||||
import { getRelativeUrlByFilePath } from "~/utils/getRelativeUrlByFilePath";
|
||||
import { getRelativeUrlByFilePath } from "~/utils/directories";
|
||||
|
||||
import GoogleAnalytics from "~/components/core/GoogleAnalytics.astro";
|
||||
import defaultImageSrc from "~/assets/images/default.png";
|
||||
|
||||
import { SITE } from "~/config.mjs";
|
||||
|
||||
const { src: defaultImage } = await getImage({
|
||||
src: import("~/assets/images/default.png"),
|
||||
src: defaultImageSrc,
|
||||
width: 1200,
|
||||
height: 628,
|
||||
});
|
||||
@ -16,7 +19,7 @@ const {
|
||||
image: _image = defaultImage,
|
||||
canonical,
|
||||
noindex = false,
|
||||
nofollow = false
|
||||
nofollow = false,
|
||||
} = Astro.props;
|
||||
|
||||
const image =
|
||||
@ -29,42 +32,40 @@ const image =
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
<link rel="shortcut icon" href="/favicon.ico" />
|
||||
|
||||
<title>{title}</title>
|
||||
<meta name="description" content={description} />
|
||||
{canonical &&
|
||||
<link rel="canonical" href={canonical} />}
|
||||
{canonical && <link rel="canonical" href={canonical} />}
|
||||
|
||||
<meta name="robots" content={`${noindex ? "noindex" : "index"}, ${nofollow ? "nofollow" : "follow"}`} />
|
||||
|
||||
<!-- Google / Search Engine Tags -->
|
||||
<meta itemprop="name" content={title} />
|
||||
<meta itemprop="description" content={description} />
|
||||
{image &&
|
||||
<meta itemprop="image" content={image} />}
|
||||
{image && <meta itemprop="image" content={image} />}
|
||||
|
||||
<!-- Facebook Meta Tags -->
|
||||
{canonical &&
|
||||
<meta property="og:url" content={canonical} />}
|
||||
{canonical && <meta property="og:url" content={canonical} />}
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
{image &&
|
||||
<meta property="og:image" content={image} />}
|
||||
{image && <meta property="og:image" content={image} />}
|
||||
|
||||
<!-- Twitter Meta Tags -->
|
||||
{canonical &&
|
||||
<meta name="twitter:url" content={canonical} />}
|
||||
{canonical && <meta name="twitter:url" content={canonical} />}
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={title} />
|
||||
<meta name="twitter:description" content={description} />
|
||||
{image &&
|
||||
<meta name="twitter:image" content={image} />}
|
||||
{image && <meta name="twitter:image" content={image} />}
|
||||
|
||||
<!-- Fonts -->
|
||||
<!-- Google Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;700&display=swap" rel="stylesheet" />
|
||||
|
||||
<!-- Google Site Verification -->
|
||||
{SITE.googleSiteVerificationId &&
|
||||
<meta name="google-site-verification" content={SITE.googleSiteVerificationId} />}
|
||||
{SITE.googleSiteVerificationId && <meta name="google-site-verification" content={SITE.googleSiteVerificationId} />}
|
||||
|
||||
<!-- Google Analytics -->
|
||||
{SITE.googleAnalyticsId && <GoogleAnalytics id={SITE.googleAnalyticsId} partytown={true} />}
|
||||
|
@ -1,4 +1,6 @@
|
||||
---
|
||||
import { Icon } from "astro-icon";
|
||||
|
||||
const {} = Astro.props;
|
||||
---
|
||||
|
||||
@ -6,18 +8,22 @@ const { } = Astro.props;
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6">
|
||||
<div class="py-12 md:py-20">
|
||||
<div class="max-w-3xl mx-auto text-center p-6 rounded-md shadow-xl dark:shadow-none">
|
||||
<h2 class="text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-4">
|
||||
<span>Astro</span> + <span class="whitespace-nowrap">Tailwind CSS
|
||||
</span>
|
||||
<h2 class="text-4xl md:text-4xl font-bold leading-tighter tracking-tighter mb-4 font-heading">
|
||||
<span>Astro</span> + <span class="whitespace-nowrap">Tailwind CSS</span>
|
||||
</h2>
|
||||
<p class="text-xl text-gray-600 dark:text-slate-400">
|
||||
Be very surprised by these huge fake numbers you are seeing on this
|
||||
page. <br class="hidden md:inline" />Don't waste more time! :P
|
||||
Be very surprised by these huge fake numbers you are seeing on this page. <br class="hidden md:inline" />Don't
|
||||
waste more time! :P
|
||||
</p>
|
||||
|
||||
<div class="mt-6">
|
||||
<a class="btn text-white bg-blue-600 hover:bg-blue-800 sm:mb-0 font-bold"
|
||||
href="https://github.com/onwidget/astrowind" target="_blank" rel="noopener">Get template
|
||||
<a
|
||||
class="btn text-white bg-primary-600 hover:bg-primary-800 mb-4 sm:mb-0 font-bold"
|
||||
href="https://github.com/onwidget/astrowind"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<Icon name="tabler:download" class="w-5 h-5 mr-1 hidden sm:inline-block" /> Get template
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,72 +1,74 @@
|
||||
---
|
||||
import { Icon } from "astro-icon";
|
||||
|
||||
const {} = Astro.props;
|
||||
|
||||
const items = [
|
||||
{
|
||||
title: "Headers",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.",
|
||||
icon: "flat-color-icons:home"
|
||||
description:
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.",
|
||||
icon: "flat-color-icons:home",
|
||||
},
|
||||
{
|
||||
title: "Footers",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.",
|
||||
icon: "flat-color-icons:faq"
|
||||
description:
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.",
|
||||
icon: "flat-color-icons:faq",
|
||||
},
|
||||
{
|
||||
title: "Features",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.",
|
||||
icon: "flat-color-icons:video-projector"
|
||||
description:
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.",
|
||||
icon: "flat-color-icons:video-projector",
|
||||
},
|
||||
{
|
||||
title: "Call-to-Action",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.",
|
||||
icon: "flat-color-icons:video-projector"
|
||||
description:
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.",
|
||||
icon: "flat-color-icons:video-projector",
|
||||
},
|
||||
{
|
||||
title: "Pricing",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.",
|
||||
icon: "flat-color-icons:calculator"
|
||||
description:
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.",
|
||||
icon: "flat-color-icons:calculator",
|
||||
},
|
||||
{
|
||||
title: "Testimonial",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.",
|
||||
icon: "flat-color-icons:voice-presentation"
|
||||
}
|
||||
]
|
||||
description:
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore.",
|
||||
icon: "flat-color-icons:voice-presentation",
|
||||
},
|
||||
];
|
||||
---
|
||||
|
||||
<section class="relative">
|
||||
<div class="absolute inset-0 bg-blue-50 dark:bg-slate-800 pointer-events-none mb-32" aria-hidden="true">
|
||||
</div>
|
||||
<div class="absolute inset-0 bg-primary-50 dark:bg-slate-800 pointer-events-none mb-32" aria-hidden="true"></div>
|
||||
<div class="relative max-w-6xl mx-auto px-4 sm:px-6">
|
||||
<div class="py-4 pt-8 sm:py-6 lg:py-8 lg:pt-12">
|
||||
<div class="mb-8 text-center">
|
||||
<p class="text-base text-blue-600 dark:text-blue-200 font-semibold tracking-wide uppercase">
|
||||
Components
|
||||
</p>
|
||||
<h2 class="text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-4">
|
||||
<p class="text-base text-primary-600 dark:text-primary-200 font-semibold tracking-wide uppercase">Components</p>
|
||||
<h2 class="text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-4 font-heading">
|
||||
Most used widgets
|
||||
</h2>
|
||||
<p class="max-w-3xl mx-auto text-center text-xl text-gray-600 dark:text-slate-400">
|
||||
Provides frequently used components for building websites using
|
||||
Tailwind CSS
|
||||
Provides frequently used components for building websites using Tailwind CSS
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid gap-6 md:grid-cols-2 lg:grid-cols-3 items-start my-12 dark:text-white">
|
||||
{items.map(({ title, description, icon }) => (
|
||||
<div
|
||||
class="relative flex flex-col p-6 bg-white dark:bg-slate-900 rounded shadow-xl hover:shadow-lg transition dark:border dark:border-slate-800">
|
||||
{
|
||||
items.map(({ title, description, icon }) => (
|
||||
<div class="relative flex flex-col p-6 bg-white dark:bg-slate-900 rounded shadow-xl hover:shadow-lg transition dark:border dark:border-slate-800">
|
||||
<div class="flex items-center mb-4">
|
||||
<Icon name={icon} class="w-12 h-12" />
|
||||
|
||||
<div class="ml-4 text-xl font-bold">{title}</div>
|
||||
</div>
|
||||
<p class="text-gray-500 dark:text-gray-400 text-md">
|
||||
{description}
|
||||
</p>
|
||||
<p class="text-gray-500 dark:text-gray-400 text-md">{description}</p>
|
||||
</div>
|
||||
))}
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,9 +1,10 @@
|
||||
---
|
||||
import Picture from "~/components/core/Picture.astro";
|
||||
import PostTags from "~/components/widgets/PostTags.astro";
|
||||
|
||||
import { getPermalink } from "~/utils/permalinks";
|
||||
import { findImage } from "~/utils/findImage";
|
||||
import { getFormattedDate } from "~/utils/getFormatedDate";
|
||||
import PostTags from "./PostTags.astro";
|
||||
import { findImage } from "~/utils/images";
|
||||
import { getFormattedDate } from "~/utils/utils";
|
||||
|
||||
const { post } = Astro.props;
|
||||
|
||||
@ -13,16 +14,25 @@ const image = await findImage(post.image);
|
||||
<article class="max-w-md mx-auto md:max-w-none grid md:grid-cols-2 gap-6 md:gap-8">
|
||||
<a class="relative block group" href="#0">
|
||||
<div
|
||||
class="relative h-0 pb-[56.25%] md:pb-[75%] md:h-80 lg:pb-[56.25%] overflow-hidden bg-gray-400 dark:bg-slate-700 rounded shadow-lg">
|
||||
<Picture src={image} class="absolute inset-0 w-full h-full object-cover mb-6 rounded shadow-lg" widths={[400,
|
||||
768]} sizes="(max-width: 767px) 400px, 768px" alt={post.description} aspectRatio={1} />
|
||||
class="relative h-0 pb-[56.25%] md:pb-[75%] md:h-80 lg:pb-[56.25%] overflow-hidden bg-gray-400 dark:bg-slate-700 rounded shadow-lg"
|
||||
>
|
||||
<Picture
|
||||
src={image}
|
||||
class="absolute inset-0 w-full h-full object-cover mb-6 rounded shadow-lg"
|
||||
widths={[400, 768]}
|
||||
sizes="(max-width: 767px) 400px, 768px"
|
||||
alt={post.description}
|
||||
aspectRatio={1}
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<div>
|
||||
<header>
|
||||
<h2 class="text-xl sm:text-2xl font-bold leading-snug mb-2 font-heading">
|
||||
<a class="hover:text-blue-600 underline underline-offset-4 decoration-1 decoration-dotted transition ease-in duration-200"
|
||||
href={getPermalink(post.slug, "post")}>
|
||||
<a
|
||||
class="hover:text-primary-600 underline underline-offset-4 decoration-1 decoration-dotted transition ease-in duration-200"
|
||||
href={getPermalink(post.slug, "post")}
|
||||
>
|
||||
{post.title}
|
||||
</a>
|
||||
</h2>
|
||||
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
import Picture from "~/components/core/Picture.astro";
|
||||
import { getFormattedDate } from "~/utils/getFormatedDate";
|
||||
import PostTags from "~/components/widgets/PostTags.astro";
|
||||
import { getFormattedDate } from "~/utils/utils";
|
||||
|
||||
const { post } = Astro.props;
|
||||
---
|
||||
@ -13,19 +13,26 @@ const { post } = Astro.props;
|
||||
<time datetime={post.pubDate}>{getFormattedDate(post.pubDate)}</time> ~ {Math.ceil(post.readingTime)} min read
|
||||
</p>
|
||||
<h1
|
||||
class="px-4 sm:px-6 max-w-3xl mx-auto text-center text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-8 font-heading">
|
||||
class="px-4 sm:px-6 max-w-3xl mx-auto text-center text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-8 font-heading"
|
||||
>
|
||||
{post.title}
|
||||
</h1>
|
||||
{
|
||||
post.image && (
|
||||
<Picture src={post.image}
|
||||
class="max-w-full lg:max-w-6xl mx-auto mt-4 mb-6 sm:rounded-md bg-gray-400 dark:bg-slate-700" widths={[400,
|
||||
900]} sizes="(max-width: 900px) 400px, 900px" alt={post.description} aspectRatio="16:9" />
|
||||
<Picture
|
||||
src={post.image}
|
||||
class="max-w-full lg:max-w-6xl mx-auto mt-4 mb-6 sm:rounded-md bg-gray-400 dark:bg-slate-700"
|
||||
widths={[400, 900]}
|
||||
sizes="(max-width: 900px) 400px, 900px"
|
||||
alt={post.description}
|
||||
aspectRatio="16:9"
|
||||
/>
|
||||
)
|
||||
}
|
||||
</header>
|
||||
<div
|
||||
class="container mx-auto px-8 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-blue-600 dark:prose-a:text-blue-400 prose-img:rounded-md prose-img:shadow-lg mt-8">
|
||||
class="container mx-auto px-8 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-600 dark:prose-a:text-primary-400 prose-img:rounded-md prose-img:shadow-lg mt-8"
|
||||
>
|
||||
<Fragment set:html={post.body} />
|
||||
</div>
|
||||
<div class="container mx-auto px-8 sm:px-6 max-w-3xl mt-8">
|
||||
|
@ -1,4 +1,6 @@
|
||||
---
|
||||
import { getHomePermalink } from "~/utils/permalinks";
|
||||
|
||||
const {} = Astro.props;
|
||||
---
|
||||
|
||||
@ -7,18 +9,17 @@ const { } = Astro.props;
|
||||
<div class="max-w-md text-center">
|
||||
<h2 class="mb-8 font-bold text-9xl">
|
||||
<span class="sr-only">Error</span>
|
||||
<span class="bg-clip-text text-transparent bg-gradient-to-r from-blue-500 to-pink-500">404
|
||||
</span>
|
||||
<span class="bg-clip-text text-transparent bg-gradient-to-r from-primary-500 to-secondary-500">404</span>
|
||||
</h2>
|
||||
<p class="text-3xl font-semibold md:text-3xl">
|
||||
Sorry, we couldn't find this page.
|
||||
</p>
|
||||
<p class="text-3xl font-semibold md:text-3xl">Sorry, we couldn't find this page.</p>
|
||||
<p class="mt-4 mb-8 text-lg text-gray-600 dark:text-slate-400">
|
||||
But dont worry, you can find plenty of other things on our homepage.
|
||||
</p>
|
||||
<a rel="noopener noreferrer" href="/"
|
||||
class="btn text-white bg-gray-900 hover:bg-gray-800 dark:bg-gray-700 dark:hover:bg-gray-800 ml-4">Back to
|
||||
homepage
|
||||
<a
|
||||
rel="noopener noreferrer"
|
||||
href={getHomePermalink()}
|
||||
class="btn text-white bg-gray-900 hover:bg-gray-800 dark:bg-gray-700 dark:hover:bg-gray-800 ml-4"
|
||||
>Back to homepage
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +1,6 @@
|
||||
---
|
||||
import { Icon } from "astro-icon";
|
||||
|
||||
const {} = Astro.props;
|
||||
|
||||
const items = [
|
||||
@ -33,8 +34,7 @@ const items = [
|
||||
It ceases to exist without me. No, you clearly don't know who you're talking to, so let me clue you in.`,
|
||||
},
|
||||
{
|
||||
question:
|
||||
"If you could only ask one question to each person you meet, what would that question be?",
|
||||
question: "If you could only ask one question to each person you meet, what would that question be?",
|
||||
answer: `This is not about revenge. This is about justice. A lot of things can change in twelve years, Admiral. Well, that's certainly good to know. About four years. I got tired of hearing how young I looked.`,
|
||||
},
|
||||
],
|
||||
@ -44,7 +44,7 @@ const items = [
|
||||
<div class="px-4 py-16 mx-auto max-w-6xl lg:py-20">
|
||||
<div class="max-w-xl sm:mx-auto lg:max-w-2xl">
|
||||
<div class="max-w-xl mb-10 md:mx-auto sm:text-center lg:max-w-2xl md:mb-12">
|
||||
<h2 class="max-w-lg mb-4 font-sans text-3xl font-bold leading-none tracking-tight sm:text-4xl md:mx-auto">
|
||||
<h2 class="max-w-lg mb-4 text-3xl font-bold leading-none tracking-tight sm:text-4xl md:mx-auto font-heading">
|
||||
Frequently Asked Questions
|
||||
</h2>
|
||||
</div>
|
||||
@ -57,7 +57,7 @@ const items = [
|
||||
{subitems.map(({ question, answer }) => (
|
||||
<div>
|
||||
<p class="mb-4 text-xl font-bold">
|
||||
<Icon name="tabler:arrow-down-right" class="w-7 h-7 text-blue-500 inline-block icon-bold" />
|
||||
<Icon name="tabler:arrow-down-right" class="w-7 h-7 text-primary-500 inline-block icon-bold" />
|
||||
{question}
|
||||
</p>
|
||||
{answer.split("\n\n").map((paragraph) => (
|
||||
|
@ -12,230 +12,214 @@ const { } = Astro.props;
|
||||
<a class="inline-block font-bold text-xl" href="/">AstroWind</a>
|
||||
</div>
|
||||
<div class="text-sm text-gray-600">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 hover:underline transition duration-150 ease-in-out"
|
||||
href="#">Terms
|
||||
<a
|
||||
class="text-gray-600 hover:text-gray-700 dark:text-gray-400 hover:underline transition duration-150 ease-in-out"
|
||||
href="#"
|
||||
>Terms
|
||||
</a> ·
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 hover:underline transition duration-150 ease-in-out"
|
||||
href="#">Privacy Policy
|
||||
<a
|
||||
class="text-gray-600 hover:text-gray-700 dark:text-gray-400 hover:underline transition duration-150 ease-in-out"
|
||||
href="#"
|
||||
>Privacy Policy
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-6 md:col-span-3 lg:col-span-2">
|
||||
<div class="text-gray-800 dark:text-gray-300 font-medium mb-2">
|
||||
Product
|
||||
</div>
|
||||
<div class="text-gray-800 dark:text-gray-300 font-medium mb-2">Product</div>
|
||||
<ul class="text-sm">
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Features
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Features
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Security
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Security
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Team
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Team
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Enterprise
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Enterprise
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Customer stories
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Customer stories
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Pricing
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Pricing
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Resources
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Resources
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-span-6 md:col-span-3 lg:col-span-2">
|
||||
<div class="text-gray-800 dark:text-gray-300 font-medium mb-2">
|
||||
Platform
|
||||
</div>
|
||||
<div class="text-gray-800 dark:text-gray-300 font-medium mb-2">Platform</div>
|
||||
<ul class="text-sm">
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Developer API
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Developer API
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Partners
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Partners
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Atom
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Atom
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Electron
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Electron
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">GitHub Desktop
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>GitHub Desktop
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-span-6 md:col-span-3 lg:col-span-2">
|
||||
<div class="text-gray-800 dark:text-gray-300 font-medium mb-2">
|
||||
Support
|
||||
</div>
|
||||
<div class="text-gray-800 dark:text-gray-300 font-medium mb-2">Support</div>
|
||||
<ul class="text-sm">
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Docs
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Docs
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Community Forum
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Community Forum
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Professional Services
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Professional Services
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Skills
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Skills
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Status
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Status
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-span-6 md:col-span-3 lg:col-span-2">
|
||||
<div class="text-gray-800 dark:text-gray-300 font-medium mb-2">
|
||||
Company
|
||||
</div>
|
||||
<div class="text-gray-800 dark:text-gray-300 font-medium mb-2">Company</div>
|
||||
<ul class="text-sm">
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">About
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>About
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Blog
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Blog
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Careers
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Careers
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Press
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Press
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Inclusion
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Inclusion
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Social Impact
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Social Impact
|
||||
</a>
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out"
|
||||
href="#">Shop
|
||||
<a class="text-gray-600 hover:text-gray-700 dark:text-gray-400 transition duration-150 ease-in-out" href="#"
|
||||
>Shop
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- <div class="col-span-12 md:col-span-3 lg:col-span-3">
|
||||
<div class="text-gray-800 dark:text-gray-300 font-medium mb-2">
|
||||
Subscribe
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
||||
Get the latest news and articles to your inbox every month.
|
||||
</p>
|
||||
<form>
|
||||
<div class="flex flex-wrap mb-4">
|
||||
<div class="w-full">
|
||||
<label class="block text-sm sr-only" for="newsletter">Email
|
||||
</label>
|
||||
<div class="relative flex items-center max-w-xs">
|
||||
<input id="newsletter" type="email"
|
||||
class="form-input w-full text-gray-800 px-3 py-2 pr-12 text-sm border rounded-sm dark:bg-transparent dark:border-slate-600 dark:text-gray-400"
|
||||
placeholder="Your email" />
|
||||
<button type="submit" class="absolute inset-0 left-auto" aria-label="Subscribe">
|
||||
<span class="absolute inset-0 right-auto w-px -ml-px my-2 bg-gray-300 dark:bg-slate-600"
|
||||
aria-hidden="true"></span>
|
||||
|
||||
<Icon name="tabler:arrow-right" class="w-5 h-5 text-primary-600 mx-3 flex-shrink-0" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="md:flex md:items-center md:justify-between py-4 md:py-8">
|
||||
<ul class="flex mb-6 md:order-1 md:ml-4 md:mb-0">
|
||||
<div class="md:flex md:items-center md:justify-between py-6 md:py-8">
|
||||
<ul class="flex mb-4 md:order-1 -ml-2 md:ml-4 md:mb-0">
|
||||
<li>
|
||||
<a class="flex justify-center items-center text-gray-600 hover:text-gray-700 bg-white hover:bg-white-100 rounded-full shadow transition duration-150 ease-in-out dark:bg-gray-800 dark:text-gray-400 p-1.5"
|
||||
aria-label="Twitter" href="#">
|
||||
<Icon name="tabler:brand-twitter" class="w-5 h-5" />
|
||||
<a
|
||||
class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center"
|
||||
aria-label="Twitter"
|
||||
href="#"
|
||||
>
|
||||
<Icon name="tabler:brand-twitter" class="w-6 h-6 md:w-5 md:h-5" />
|
||||
</a>
|
||||
</li>
|
||||
<li class="ml-4">
|
||||
<a class="flex justify-center items-center text-gray-600 hover:text-gray-700 bg-white hover:bg-white-100 rounded-full shadow transition duration-150 ease-in-out dark:bg-gray-800 dark:text-gray-400 p-1.5"
|
||||
aria-label="Instagram" href="#">
|
||||
<Icon name="tabler:brand-instagram" class="w-5 h-5" />
|
||||
<li>
|
||||
<a
|
||||
class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center"
|
||||
aria-label="Instagram"
|
||||
href="#"
|
||||
>
|
||||
<Icon name="tabler:brand-instagram" class="w-6 h-6 md:w-5 md:h-5" />
|
||||
</a>
|
||||
</li>
|
||||
<li class="ml-4">
|
||||
<a class="flex justify-center items-center text-gray-600 hover:text-gray-700 bg-white hover:bg-white-100 rounded-full shadow transition duration-150 ease-in-out dark:bg-gray-800 dark:text-gray-400 p-1.5"
|
||||
aria-label="Facebook" href="#">
|
||||
<Icon name="tabler:brand-facebook" class="w-5 h-5" />
|
||||
<li>
|
||||
<a
|
||||
class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center"
|
||||
aria-label="Facebook"
|
||||
href="#"
|
||||
>
|
||||
<Icon name="tabler:brand-facebook" class="w-6 h-6 md:w-5 md:h-5" />
|
||||
</a>
|
||||
</li>
|
||||
<li class="ml-4">
|
||||
<a class="flex justify-center items-center text-gray-600 hover:text-gray-700 bg-white hover:bg-white-100 rounded-full shadow transition duration-150 ease-in-out dark:bg-gray-800 dark:text-gray-400 p-1.5"
|
||||
aria-label="RSS" href="/rss.xml">
|
||||
<Icon name="tabler:rss" class="w-5 h-5" />
|
||||
<li>
|
||||
<a
|
||||
class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center"
|
||||
aria-label="RSS"
|
||||
href="/rss.xml"
|
||||
>
|
||||
<Icon name="tabler:rss" class="w-6 h-6 md:w-5 md:h-5" />
|
||||
</a>
|
||||
</li>
|
||||
<li class="ml-4">
|
||||
<a class="flex justify-center items-center text-gray-600 hover:text-gray-700 bg-white hover:bg-white-100 rounded-full shadow transition duration-150 ease-in-out dark:bg-gray-800 dark:text-gray-400 p-1.5"
|
||||
aria-label="Github" href="https://github.com/onwidget/astrowind">
|
||||
<Icon name="tabler:brand-github" class="w-5 h-5" />
|
||||
<li>
|
||||
<a
|
||||
class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center"
|
||||
aria-label="Github"
|
||||
href="https://github.com/onwidget/astrowind"
|
||||
>
|
||||
<Icon name="tabler:brand-github" class="w-6 h-6 md:w-5 md:h-5" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="text-sm text-gray-700 mr-4 dark:text-slate-400">
|
||||
<span
|
||||
class="w-5 h-5 md:w-6 md:h-6 md:-mt-0.5 bg-cover mr-1.5 float-left rounded-sm bg-[url(https://onwidget.com/favicon/favicon-32x32.png)]">
|
||||
class="w-5 h-5 md:w-6 md:h-6 md:-mt-0.5 bg-cover mr-1.5 float-left rounded-sm bg-[url(https://onwidget.com/favicon/favicon-32x32.png)]"
|
||||
>
|
||||
</span>
|
||||
Made by <a class="text-blue-600 hover:underline dark:text-gray-200" href="https://onwidget.com/">
|
||||
onWidget
|
||||
</a>. All rights reserved.
|
||||
Made by <a class="text-blue-600 hover:underline dark:text-gray-200" href="https://onwidget.com/"> onWidget</a> ·
|
||||
All rights reserved.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,71 +1,98 @@
|
||||
---
|
||||
import { Icon } from "astro-icon";
|
||||
import Logo from "~/components/widgets/Logo.astro";
|
||||
|
||||
import { getPermalink, getBlogPermalink, getHomePermalink } from "~/utils/permalinks";
|
||||
|
||||
const {} = Astro.props;
|
||||
---
|
||||
|
||||
<header
|
||||
class="sticky top-0 z-40 flex-none mx-auto w-full bg-white md:bg-white/90 dark:bg-slate-900 dark:md:bg-slate-900/90 md:backdrop-blur-sm border-b dark:border-b-0">
|
||||
class="sticky top-0 z-40 flex-none mx-auto w-full bg-white md:bg-white/90 dark:bg-slate-900 dark:md:bg-slate-900/90 md:backdrop-blur-sm border-b dark:border-b-0"
|
||||
>
|
||||
<div class="py-3 px-3 mx-auto w-full md:flex md:justify-between max-w-6xl md:px-4">
|
||||
<div class="flex justify-between">
|
||||
<a class="flex items-center" href={getHomePermalink()}>
|
||||
<Logo />
|
||||
</a>
|
||||
<div class="flex items-center md:hidden">
|
||||
<button type="button"
|
||||
<button
|
||||
type="button"
|
||||
class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center"
|
||||
aria-label="Toggle between Dark and Light mode" data-aw-toggle-color-scheme>
|
||||
aria-label="Toggle between Dark and Light mode"
|
||||
data-aw-toggle-color-scheme
|
||||
>
|
||||
<Icon name="tabler:sun" class="w-6 h-6" />
|
||||
</button>
|
||||
<button
|
||||
class="ml-1.5 text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center transition"
|
||||
aria-label="Toggle Menu" data-aw-toggle-menu>
|
||||
aria-label="Toggle Menu"
|
||||
data-aw-toggle-menu
|
||||
>
|
||||
<Icon name="tabler:menu" class="w-6 h-6" optimize={false} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="items-center w-full md:w-auto hidden md:flex text-gray-600 dark:text-slate-200 h-screen md:h-auto"
|
||||
aria-label="Main navigation" id="menu">
|
||||
<nav
|
||||
class="items-center w-full md:w-auto hidden md:flex text-gray-600 dark:text-slate-200 h-screen md:h-auto"
|
||||
aria-label="Main navigation"
|
||||
id="menu"
|
||||
>
|
||||
<ul
|
||||
class="flex flex-col pt-8 md:pt-0 md:flex-row md:self-center collapse w-full md:w-auto collapsed text-xl md:text-base">
|
||||
class="flex flex-col pt-8 md:pt-0 md:flex-row md:self-center collapse w-full md:w-auto collapsed text-xl md:text-base"
|
||||
>
|
||||
<li>
|
||||
<a class="font-medium hover:text-gray-900 dark:hover:text-white px-4 py-3 flex items-center transition duration-150 ease-in-out"
|
||||
href="#">Pages
|
||||
<a
|
||||
class="font-medium hover:text-gray-900 dark:hover:text-white px-4 py-3 flex items-center transition duration-150 ease-in-out"
|
||||
href="#"
|
||||
>Pages
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-medium hover:text-gray-900 dark:hover:text-white px-4 py-3 flex items-center transition duration-150 ease-in-out"
|
||||
href={getPermalink("useful-resources-to-create-websites", "post")}>Resources
|
||||
<a
|
||||
class="font-medium hover:text-gray-900 dark:hover:text-white px-4 py-3 flex items-center transition duration-150 ease-in-out"
|
||||
href={getPermalink("useful-resources-to-create-websites", "post")}
|
||||
>Resources
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="font-medium hover:text-gray-900 dark:hover:text-white px-4 py-3 flex items-center transition duration-150 ease-in-out"
|
||||
href={getBlogPermalink()}>Blog
|
||||
<a
|
||||
class="font-medium hover:text-gray-900 dark:hover:text-white px-4 py-3 flex items-center transition duration-150 ease-in-out"
|
||||
href={getBlogPermalink()}
|
||||
>Blog
|
||||
</a>
|
||||
</li>
|
||||
<li class="md:hidden">
|
||||
<a class="font-bold hover:text-gray-900 dark:hover:text-white px-4 py-3 flex items-center transition duration-150 ease-in-out"
|
||||
href="https://github.com/onwidget/astrowind">
|
||||
<a
|
||||
class="font-bold hover:text-gray-900 dark:hover:text-white px-4 py-3 flex items-center transition duration-150 ease-in-out"
|
||||
href="https://github.com/onwidget/astrowind"
|
||||
>
|
||||
Github
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="md:self-center flex items-center mb-4 md:mb-0 collapse collapsed">
|
||||
<div class="hidden items-center mr-3 md:flex">
|
||||
<button type="button"
|
||||
<div class="md:self-center flex items-center mb-4 md:mb-0 ml-2">
|
||||
<div class="hidden items-center md:flex">
|
||||
<button
|
||||
type="button"
|
||||
class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center"
|
||||
aria-label="Toggle between Dark and Light mode" data-aw-toggle-color-scheme>
|
||||
aria-label="Toggle between Dark and Light mode"
|
||||
data-aw-toggle-color-scheme
|
||||
>
|
||||
<Icon name="tabler:sun" class="w-5 h-5" />
|
||||
</button>
|
||||
<a class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center"
|
||||
aria-label="RSS Feed" href="/rss.xml">
|
||||
<a
|
||||
class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center"
|
||||
aria-label="RSS Feed"
|
||||
href="/rss.xml"
|
||||
>
|
||||
<Icon name="tabler:rss" class="w-5 h-5" />
|
||||
</a>
|
||||
<a href="https://github.com/onwidget/astrowind"
|
||||
class="inline-block text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 mr-1"
|
||||
aria-label="Astrowind Github">
|
||||
<a
|
||||
href="https://github.com/onwidget/astrowind"
|
||||
class="inline-block text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5"
|
||||
aria-label="Astrowind Github"
|
||||
>
|
||||
<Icon name="tabler:brand-github" class="w-5 h-5" />
|
||||
</a>
|
||||
</div>
|
||||
|
@ -1,49 +1,59 @@
|
||||
---
|
||||
import { Icon } from "astro-icon";
|
||||
import Picture from "~/components/core/Picture.astro";
|
||||
|
||||
const {} = Astro.props;
|
||||
---
|
||||
|
||||
<section>
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6">
|
||||
<div class="py-12 md:py-20">
|
||||
<div class="text-center pb-12 md:pb-16">
|
||||
<h1 class="text-5xl md:text-[3.50rem] font-bold leading-tighter tracking-tighter mb-4">
|
||||
<div class="text-center pb-10 md:pb-16">
|
||||
<h1 class="text-5xl md:text-[3.50rem] font-bold leading-tighter tracking-tighter mb-4 font-heading">
|
||||
Your website with
|
||||
<span class="bg-clip-text text-transparent bg-gradient-to-r from-blue-500 to-pink-500">Astro
|
||||
</span> +
|
||||
<span class="bg-clip-text text-transparent bg-gradient-to-r from-primary-500 to-secondary-500">Astro</span> +
|
||||
<span
|
||||
class="bg-clip-text text-transparent bg-gradient-to-r from-blue-500 to-pink-500 whitespace-nowrap">Tailwind
|
||||
CSS
|
||||
class="bg-clip-text text-transparent bg-gradient-to-r from-primary-500 to-secondary-500 whitespace-nowrap"
|
||||
>Tailwind CSS
|
||||
</span>
|
||||
</h1>
|
||||
<div class="max-w-3xl mx-auto">
|
||||
<p class="text-xl text-gray-600 mb-8 dark:text-slate-400">
|
||||
AstroWind is a production ready template to start your new website
|
||||
using Astro + Tailwind CSS. It has been designed following Best
|
||||
Practices, SEO, Accessibility, Dark Mode, great Page Speed, image
|
||||
optimization, sitemap generation and more.
|
||||
AstroWind is a production ready template to start your new website using Astro + Tailwind CSS. It has been
|
||||
designed following Best Practices, SEO, Accessibility, Dark Mode, great Page Speed, image optimization,
|
||||
sitemap generation and more.
|
||||
</p>
|
||||
<div class="max-w-none flex justify-center">
|
||||
<div>
|
||||
<a class="btn text-white bg-blue-600 hover:bg-blue-800 mb-4 sm:mb-0 font-bold"
|
||||
href="https://github.com/onwidget/astrowind" target="_blank" rel="noopener">Get template
|
||||
<a
|
||||
class="btn text-white bg-primary-600 hover:bg-primary-800 mb-4 sm:mb-0 font-bold"
|
||||
href="https://github.com/onwidget/astrowind"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<Icon name="tabler:download" class="w-5 h-5 mr-1 hidden sm:inline-block" /> Get template
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a class="btn text-white bg-gray-900 hover:bg-gray-800 dark:bg-gray-700 dark:hover:bg-gray-800 ml-4"
|
||||
href="#features">Learn more
|
||||
<a
|
||||
class="btn text-white bg-gray-900 hover:bg-gray-700 dark:bg-gray-700 dark:hover:bg-gray-800 ml-4"
|
||||
href="#features"
|
||||
>Learn more
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="relative flex justify-center mb-8">
|
||||
<div class="flex flex-col justify-center">
|
||||
<Picture src={import("~/assets/images/hero.jpg")}
|
||||
class="mx-auto rounded-md shadow-lg bg-gray-400 dark:bg-slate-700" widths={[400, 768]}
|
||||
sizes=" (max-width: 767px) 400px, 768px" alt="Hero Image" aspectRatio="16:9" />
|
||||
</div>
|
||||
<div class="relative mb-8 m-auto max-w-3xl">
|
||||
<Picture
|
||||
src={import("~/assets/images/hero.jpg")}
|
||||
class="mx-auto rounded-md shadow-lg bg-gray-400 dark:bg-slate-700 w-full"
|
||||
widths={[400, 768]}
|
||||
sizes=" (max-width: 767px) 400px, 768px"
|
||||
alt="Hero Image"
|
||||
aspectRatio="16:9"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,51 +1,59 @@
|
||||
---
|
||||
import Picture from "~/components/core/Picture.astro";
|
||||
import { findPostsByIds } from "~/utils/fetchPosts";
|
||||
import { findImage } from "~/utils/findImage";
|
||||
|
||||
import { findPostsByIds } from "~/utils/posts";
|
||||
import { findImage } from "~/utils/images";
|
||||
import { getPermalink } from "~/utils/permalinks";
|
||||
|
||||
const {} = Astro.props;
|
||||
|
||||
const ids = [
|
||||
"get-started-website-with-astro-tailwind-css",
|
||||
"how-to-customize-astrowind-to-your-brand",
|
||||
"useful-resources-to-create-websites",
|
||||
"astrowind-template-in-depth"
|
||||
]
|
||||
"astrowind-template-in-depth",
|
||||
];
|
||||
|
||||
const items = (await Promise.all((await findPostsByIds(ids))
|
||||
.map(async (item) =>
|
||||
({ ...item, image: await findImage(item.image) }
|
||||
))));
|
||||
const items = await Promise.all(
|
||||
(await findPostsByIds(ids)).map(async (item) => ({ ...item, image: await findImage(item.image) }))
|
||||
);
|
||||
---
|
||||
|
||||
<section class="px-4 py-16 mx-auto max-w-6xl lg:py-20">
|
||||
<div class="flex flex-col mb-6 lg:justify-between lg:flex-row md:mb-8">
|
||||
<h2 class="max-w-lg mb-2 font-sans text-3xl font-bold tracking-tight sm:text-4xl sm:leading-none lg:mb-5 group">
|
||||
<span class="inline-block mb-1 sm:mb-4">Find out more content<br class="hidden md:block" /> in our Blog
|
||||
</span>
|
||||
<h2 class="max-w-lg mb-2 text-3xl font-bold tracking-tight sm:text-4xl sm:leading-none lg:mb-5 group font-heading">
|
||||
<span class="inline-block mb-1 sm:mb-4">Find out more content<br class="hidden md:block" /> in our Blog</span>
|
||||
</h2>
|
||||
|
||||
<p class="text-gray-700 dark:text-slate-400 lg:text-sm lg:max-w-md">
|
||||
The blog will be used to display AstroWind documentation. Each new article
|
||||
will be an important step that you will need to know to be an expert in
|
||||
creating a website using Astro + Tailwind CSS The blog does not exist yet,
|
||||
but very soon. Astro is a very interesting technology. Thanks.
|
||||
The blog will be used to display AstroWind documentation. Each new article will be an important step that you will
|
||||
need to know to be an expert in creating a website using Astro + Tailwind CSS The blog does not exist yet, but
|
||||
very soon. Astro is a very interesting technology. Thanks.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-6 row-gap-5 md:grid-cols-2 lg:grid-cols-4 -mb-6">
|
||||
{items.map((post) => (
|
||||
{
|
||||
items.map((post) => (
|
||||
<article class="mb-6 transition">
|
||||
<Picture src={post.image} class="object-cover w-full h-64 mb-6 rounded shadow-lg bg-gray-400 dark:bg-slate-700"
|
||||
widths={[400]} alt="Post 2 Image" aspectRatio="16:9" />
|
||||
<h3 class="mb-2 text-xl font-bold leading-snug sm:text-2xl">
|
||||
<a href={getPermalink(post.slug, "type")}
|
||||
class="hover:text-blue-600 underline underline-offset-4 decoration-1 decoration-dotted transition ease-in duration-200">{post.title}
|
||||
<Picture
|
||||
src={post.image}
|
||||
class="object-cover w-full h-64 mb-6 rounded shadow-lg bg-gray-400 dark:bg-slate-700"
|
||||
widths={[400]}
|
||||
alt="Post 2 Image"
|
||||
aspectRatio="16:9"
|
||||
/>
|
||||
<h3 class="mb-2 text-xl font-bold leading-snug sm:text-2xl font-heading">
|
||||
<a
|
||||
href={getPermalink(post.slug, "type")}
|
||||
class="hover:text-primary-600 underline underline-offset-4 decoration-1 decoration-dotted transition ease-in duration-200"
|
||||
>
|
||||
{post.title}
|
||||
</a>
|
||||
</h3>
|
||||
<p class="text-gray-700 dark:text-gray-400">
|
||||
{post.excerpt || post.description}
|
||||
</p>
|
||||
<p class="text-gray-700 dark:text-gray-400">{post.excerpt || post.description}</p>
|
||||
</article>
|
||||
))}
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</section>
|
@ -1,20 +1,28 @@
|
||||
---
|
||||
import { Icon } from "astro-icon"
|
||||
import { Icon } from "astro-icon";
|
||||
const { prevUrl, nextUrl, prevText = "Newer posts", nextText = "Older posts" } = Astro.props;
|
||||
---
|
||||
|
||||
{(prevUrl || nextUrl) && (
|
||||
{
|
||||
(prevUrl || nextUrl) && (
|
||||
<div class="container flex">
|
||||
<div class="flex flex-row mx-auto container justify-between">
|
||||
<a href={prevUrl} class={`btn font-medium text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white shadow-none mr-2
|
||||
${ !prevUrl ? "invisible" : "" }`}>
|
||||
<a
|
||||
href={prevUrl}
|
||||
class={`btn font-medium text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white shadow-none mr-2
|
||||
${!prevUrl ? "invisible" : ""}`}
|
||||
>
|
||||
<div class="flex flex-row align-middle">
|
||||
<Icon name="tabler:arrow-left" class="w-6 h-6" />
|
||||
<p class="ml-2">{prevText}</p>
|
||||
</div>
|
||||
</a>
|
||||
<a href={nextUrl} class={`btn font-medium text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white shadow-none ${
|
||||
!nextUrl ? "invisible" : "" }`}>
|
||||
<a
|
||||
href={nextUrl}
|
||||
class={`btn font-medium text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white shadow-none ${
|
||||
!nextUrl ? "invisible" : ""
|
||||
}`}
|
||||
>
|
||||
<div class="flex flex-row align-middle">
|
||||
<span class="mr-2">{nextText}</span>
|
||||
<Icon name="tabler:arrow-right" class="w-6 h-6" />
|
||||
@ -22,4 +30,5 @@ const { prevUrl, nextUrl, prevText = "Newer posts", nextText = "Older posts" } =
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)
|
||||
}
|
||||
|
@ -1,12 +1,17 @@
|
||||
---
|
||||
import { getPermalink } from "~/utils/permalinks";
|
||||
const { tags } = Astro.props;
|
||||
|
||||
const { tags, class: className = "text-sm" } = Astro.props;
|
||||
---
|
||||
|
||||
{tags && Array.isArray(tags) && <ul>
|
||||
{tags.map(tag => (
|
||||
<li class="bg-gray-100 dark:bg-slate-700 inline-block mr-2 mb-2 py-0.5 px-2"><a href={getPermalink(tag, "tag" )}>{tag}</a></li>
|
||||
))
|
||||
}
|
||||
{
|
||||
tags && Array.isArray(tags) && (
|
||||
<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">
|
||||
<a href={getPermalink(tag, "tag")}>{tag}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
@ -5,36 +5,22 @@ const { } = Astro.props;
|
||||
<div class="px-4 py-8 md:py-16 sm:px-6 mx-auto md:px-24 lg:px-8 lg:py-20 max-w-6xl">
|
||||
<div class="grid grid-cols-2 row-gap-8 md:grid-cols-4">
|
||||
<div class="text-center md:border-r dark:md:border-slate-500 mb-10 md:mb-0">
|
||||
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-blue-500">
|
||||
132K
|
||||
</div>
|
||||
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-primary-500 font-heading">132K</div>
|
||||
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">
|
||||
Downloads
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-center md:border-r dark:md:border-slate-500 mb-10 md:mb-0">
|
||||
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-blue-500">
|
||||
24.8K
|
||||
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-primary-500 font-heading">24.8K</div>
|
||||
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">Stars</p>
|
||||
</div>
|
||||
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">
|
||||
Stars
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-center md:border-r dark:md:border-slate-500">
|
||||
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-blue-500">
|
||||
10.3K
|
||||
</div>
|
||||
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">
|
||||
Forks
|
||||
</p>
|
||||
<div class="text-center md:border-r dark:md:border-slate-500 font-heading">
|
||||
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-primary-500">10.3K</div>
|
||||
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">Forks</p>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-blue-500">
|
||||
48.4K
|
||||
</div>
|
||||
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">
|
||||
Users
|
||||
</p>
|
||||
<div class="text-4xl font-bold lg:text-5xl xl:text-6xl text-primary-500 font-heading">48.4K</div>
|
||||
<p class="text-sm font-medium tracking-widest text-gray-800 dark:text-slate-400 uppercase lg:text-base">Users</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,4 +1,5 @@
|
||||
---
|
||||
import { Icon } from "astro-icon";
|
||||
const {} = Astro.props;
|
||||
---
|
||||
|
||||
@ -10,19 +11,23 @@ const { } = Astro.props;
|
||||
<div class="w-full lg:w-1/2 px-0 sm:px-8">
|
||||
<div class="mb-12 lg:mb-0 pb-12 lg:pb-0 border-b lg:border-b-0">
|
||||
<h2 class="mb-4 text-3xl lg:text-4xl font-bold font-heading">
|
||||
Sed ac magna sit amet risus tristique interdum, at vel velit in
|
||||
hac habitasse platea dictumst.
|
||||
Sed ac magna sit amet risus tristique interdum, at vel velit in hac habitasse platea dictumst.
|
||||
</h2>
|
||||
|
||||
<p class="mb-8 text-xl text-gray-600 dark:text-slate-400">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi
|
||||
sagittis, quam nec venenatis lobortis, mi risus tempus nulla,
|
||||
sed porttitor est nibh at nulla. Praesent placerat enim ut ex
|
||||
tincidunt vehicula. Fusce sit amet dui tellus.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, quam nec venenatis lobortis, mi
|
||||
risus tempus nulla, sed porttitor est nibh at nulla. Praesent placerat enim ut ex tincidunt vehicula.
|
||||
Fusce sit amet dui tellus.
|
||||
</p>
|
||||
|
||||
<div class="w-full">
|
||||
<a class="btn bg-blue-600 hover:bg-blue-700 text-white font-bold"
|
||||
href="https://github.com/onwidget/astrowind" target="_blank" rel="noopener">
|
||||
Get template
|
||||
<a
|
||||
class="btn text-white bg-primary-600 hover:bg-primary-800 mb-4 sm:mb-0 font-bold"
|
||||
href="https://github.com/onwidget/astrowind"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<Icon name="tabler:download" class="w-5 h-5 mr-1 hidden sm:inline-block" /> Get template
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -32,50 +37,48 @@ const { } = Astro.props;
|
||||
<li class="flex md:-mx-4">
|
||||
<div class="pr-4 sm:pl-4">
|
||||
<span
|
||||
class="flex w-16 h-16 mx-auto items-center justify-center text-2xl font-bold font-heading rounded-full bg-blue-50 text-blue-600">
|
||||
class="flex w-16 h-16 mx-auto items-center justify-center text-2xl font-bold rounded-full bg-primary-50 text-primary-600"
|
||||
>
|
||||
1
|
||||
</span>
|
||||
</div>
|
||||
<div class="px-4">
|
||||
<h3 class="mb-4 text-xl font-semibold">
|
||||
Responsive Elements
|
||||
</h3>
|
||||
<h3 class="mb-4 text-xl font-semibold font-heading">Responsive Elements</h3>
|
||||
<p class="text-gray-500 dark:text-gray-400">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
Morbi sagittis, quam nec venenatis lobortis, mi risus tempus
|
||||
nulla.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, quam nec venenatis
|
||||
lobortis, mi risus tempus nulla.
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
<li class="flex md:-mx-4">
|
||||
<div class="pr-4 sm:pl-4">
|
||||
<span
|
||||
class="flex w-16 h-16 mx-auto items-center justify-center text-2xl font-bold font-heading rounded-full bg-blue-50 text-blue-600">
|
||||
class="flex w-16 h-16 mx-auto items-center justify-center text-2xl font-bold rounded-full bg-primary-50 text-primary-600"
|
||||
>
|
||||
2
|
||||
</span>
|
||||
</div>
|
||||
<div class="px-4">
|
||||
<h3 class="mb-4 text-xl font-semibold">Flexible Team</h3>
|
||||
<h3 class="mb-4 text-xl font-semibold font-heading">Flexible Team</h3>
|
||||
<p class="text-gray-500 dark:text-gray-400">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
Morbi sagittis, quam nec venenatis lobortis, mi risus tempus
|
||||
nulla.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, quam nec venenatis
|
||||
lobortis, mi risus tempus nulla.
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
<li class="flex md:-mx-4">
|
||||
<div class="pr-4 sm:pl-4">
|
||||
<span
|
||||
class="flex w-16 h-16 mx-auto items-center justify-center text-2xl font-bold font-heading rounded-full bg-blue-50 text-blue-600">
|
||||
class="flex w-16 h-16 mx-auto items-center justify-center text-2xl font-bold rounded-full bg-primary-50 text-primary-600"
|
||||
>
|
||||
3
|
||||
</span>
|
||||
</div>
|
||||
<div class="px-4">
|
||||
<h3 class="mb-4 text-xl font-semibold">Ecologic Software</h3>
|
||||
<h3 class="mb-4 text-xl font-semibold font-heading">Ecologic Software</h3>
|
||||
<p class="text-gray-500 dark:text-gray-400">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
Morbi sagittis, quam nec venenatis lobortis, mi risus tempus
|
||||
nulla.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, quam nec venenatis
|
||||
lobortis, mi risus tempus nulla.
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -9,82 +9,70 @@ const { } = Astro.props;
|
||||
<div class="grid gap-6 row-gap-10 md:grid-cols-2">
|
||||
<div class="md:pb-6 md:pr-16">
|
||||
<h2 class="mb-8 text-3xl lg:text-4xl font-bold font-heading">
|
||||
Sed ac magna sit amet risus tristique interdum.
|
||||
hac.
|
||||
Sed ac magna sit amet risus tristique interdum. hac.
|
||||
</h2>
|
||||
<div class="flex">
|
||||
<div class="flex flex-col items-center mr-4">
|
||||
<div>
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-full border-pink-500 border-2">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-full border-secondary-500 border-2">
|
||||
<Icon name="tabler:arrow-down" class="w-6 h-6 text-gray-600 dark:text-slate-200 icon-bold" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-px h-full bg-gray-300 dark:bg-slate-500"></div>
|
||||
</div>
|
||||
<div class="pt-1 pb-8">
|
||||
<p class="mb-2 text-xl font-bold text-gray-900 dark:text-slate-300">
|
||||
Step 1
|
||||
</p>
|
||||
<p class="mb-2 text-xl font-bold text-gray-900 dark:text-slate-300">Step 1</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi
|
||||
sagittis, quam nec venenatis lobortis, mi risus tempus nulla, sed
|
||||
porttitor est nibh at nulla. Praesent placerat enim ut ex tincidunt
|
||||
vehicula. Fusce sit amet dui tellus.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, quam nec venenatis lobortis, mi
|
||||
risus tempus nulla, sed porttitor est nibh at nulla. Praesent placerat enim ut ex tincidunt vehicula. Fusce
|
||||
sit amet dui tellus.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<div class="flex flex-col items-center mr-4">
|
||||
<div>
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-full border-pink-500 border-2">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-full border-secondary-500 border-2">
|
||||
<Icon name="tabler:arrow-down" class="w-6 h-6 text-gray-600 dark:text-slate-200 icon-bold" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-px h-full bg-gray-300 dark:bg-slate-500"></div>
|
||||
</div>
|
||||
<div class="pt-1 pb-8">
|
||||
<p class="mb-2 text-xl font-bold text-gray-900 dark:text-slate-300">
|
||||
Step 2
|
||||
</p>
|
||||
<p class="mb-2 text-xl font-bold text-gray-900 dark:text-slate-300">Step 2</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi
|
||||
sagittis, quam nec venenatis lobortis, mi risus tempus nulla, sed
|
||||
porttitor est nibh at nulla.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, quam nec venenatis lobortis, mi
|
||||
risus tempus nulla, sed porttitor est nibh at nulla.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<div class="flex flex-col items-center mr-4">
|
||||
<div>
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-full border-pink-500 border-2">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-full border-secondary-500 border-2">
|
||||
<Icon name="tabler:arrow-down" class="w-6 h-6 text-gray-600 dark:text-slate-200 icon-bold" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-px h-full bg-gray-300 dark:bg-slate-500"></div>
|
||||
</div>
|
||||
<div class="pt-1 pb-8">
|
||||
<p class="mb-2 text-xl font-bold text-gray-900 dark:text-slate-300">
|
||||
Step 3
|
||||
</p>
|
||||
<p class="mb-2 text-xl font-bold text-gray-900 dark:text-slate-300">Step 3</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi
|
||||
sagittis, quam nec venenatis lobortis, mi risus tempus nulla, sed
|
||||
porttitor est nibh at nulla.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, quam nec venenatis lobortis, mi
|
||||
risus tempus nulla, sed porttitor est nibh at nulla.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<div class="flex flex-col items-center mr-4">
|
||||
<div>
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-full border-blue-600 border-2">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-full border-primary-600 border-2">
|
||||
<Icon name="tabler:check" class="w-6 h-6 text-gray-600 dark:text-slate-200 icon-bold" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-1">
|
||||
<p class="mb-2 text-xl font-bold text-gray-900 dark:text-slate-300">
|
||||
Ready!
|
||||
</p>
|
||||
<p class="mb-2 text-xl font-bold text-gray-900 dark:text-slate-300">Ready!</p>
|
||||
<p class="text-gray-700"></p>
|
||||
</div>
|
||||
</div>
|
||||
@ -92,8 +80,12 @@ const { } = Astro.props;
|
||||
<div class="relative">
|
||||
<Picture
|
||||
class="inset-0 object-cover object-top w-full rounded-md shadow-lg md:absolute md:h-full bg-gray-400 dark:bg-slate-700"
|
||||
src={import("~/assets/images/astronaut.jpg")} widths={[400, 768]} sizes="(max-width: 768px) 100vw, 432px"
|
||||
alt="Astronaut" aspectRatio="432:768" />
|
||||
src={import("~/assets/images/astronaut.jpg")}
|
||||
widths={[400, 768]}
|
||||
sizes="(max-width: 768px) 100vw, 432px"
|
||||
alt="Astronaut"
|
||||
aspectRatio="432:768"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
@ -40,19 +40,18 @@ const items = [
|
||||
---
|
||||
|
||||
<section class="scroll-mt-16" id="features">
|
||||
<div class="px-4 py-16 mx-auto max-w-6xl lg:px-8 lg:py-20 bg-blue-50 dark:bg-slate-800">
|
||||
<div class="px-4 py-16 mx-auto max-w-6xl lg:px-8 lg:py-20 bg-primary-50 dark:bg-slate-800">
|
||||
<div class="max-w-xl mb-10 md:mx-auto sm:text-center lg:max-w-2xl md:mb-12">
|
||||
<p class="text-base text-blue-600 dark:text-blue-200 font-semibold tracking-wide uppercase">
|
||||
Features
|
||||
</p>
|
||||
<h2 class="text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-4">
|
||||
<p class="text-base text-primary-600 dark:text-primary-200 font-semibold tracking-wide uppercase">Features</p>
|
||||
<h2 class="text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-4 font-heading">
|
||||
What's interesting about <span
|
||||
class="bg-clip-text text-transparent bg-gradient-to-r from-blue-500 to-pink-500 whitespace-nowrap">AstroWind
|
||||
class="bg-clip-text text-transparent bg-gradient-to-r from-primary-500 to-secondary-500 whitespace-nowrap"
|
||||
>AstroWind
|
||||
</span>
|
||||
</h2>
|
||||
<p class="max-w-3xl mx-auto sm:text-center text-xl text-gray-600 dark:text-slate-400">
|
||||
Sed ut perspiciatis unde omnis iste natus error sit voluptatem
|
||||
accusantium doloremque rem aperiam, eaque ipsa quae.
|
||||
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque rem aperiam, eaque ipsa
|
||||
quae.
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid mx-auto space-y-6 md:grid-cols-2 md:space-y-0">
|
||||
@ -62,26 +61,24 @@ const items = [
|
||||
{subitems.map(({ title, description }) => (
|
||||
<div class="flex flex-row max-w-md">
|
||||
<div class="mb-4 mr-4">
|
||||
<div class="flex items-center justify-center w-12 h-12 rounded-full bg-blue-500">
|
||||
<div class="flex items-center justify-center w-12 h-12 rounded-full bg-primary-500">
|
||||
<svg class="w-12 h-12 p-0.5" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<rect class="fill-current text-blue-600" width="64" height="64" rx="32" />
|
||||
<rect class="fill-current text-primary-600" width="64" height="64" rx="32" />
|
||||
<g stroke-linecap="square" stroke-width="2">
|
||||
<path class="stroke-current text-white" d="M20.571 20.571h13.714v17.143H20.571z"></path>
|
||||
<path class="stroke-current text-blue-300" d="M38.858 26.993l6.397 1.73-4.473 16.549-13.24-3.58">
|
||||
</path>
|
||||
<path class="stroke-current text-white" d="M20.571 20.571h13.714v17.143H20.571z" />
|
||||
<path
|
||||
class="stroke-current text-primary-300"
|
||||
d="M38.858 26.993l6.397 1.73-4.473 16.549-13.24-3.58"
|
||||
></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="mb-3 text-xl font-bold">
|
||||
{title}
|
||||
</h3>
|
||||
<p>
|
||||
{description}
|
||||
</p>
|
||||
<h3 class="mb-3 text-xl font-bold">{title}</h3>
|
||||
<p>{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
@ -158,7 +158,7 @@ Sint ea anim ipsum ad commodo cupidatat do **exercitation** incididunt et minim
|
||||
|
||||
*Proident sit veniam in est proident officia adipisicing* ea tempor cillum non cillum velit deserunt. Voluptate laborum incididunt sit consectetur Lorem irure incididunt voluptate nostrud. Commodo ut eiusmod tempor cupidatat esse enim minim ex anim consequat. Mollit sint culpa qui laboris quis consectetur ad sint esse. Amet anim anim minim ullamco et duis non irure. Sit tempor adipisicing ea laboris `culpa ex duis sint` anim aute reprehenderit id eu ea. Aute [excepteur proident](#!) Lorem minim adipisicing nostrud mollit ad ut voluptate do nulla esse occaecat aliqua sint anim.
|
||||
|
||||

|
||||

|
||||
|
||||
Incididunt in culpa cupidatat mollit cillum qui proident sit. In cillum aliquip incididunt voluptate magna amet cupidatat cillum pariatur sint aliqua est _enim **anim** voluptate_. Magna aliquip proident incididunt id duis pariatur eiusmod incididunt commodo culpa dolore sit. Culpa do nostrud elit ad exercitation anim pariatur non minim nisi **adipisicing sunt _officia_**. Do deserunt magna mollit Lorem commodo ipsum do cupidatat mollit enim ut elit veniam ea voluptate.
|
||||
|
||||
|
@ -1,28 +1,20 @@
|
||||
---
|
||||
import { SITE } from "~/config.mjs"
|
||||
|
||||
import "~/assets/styles/base.css";
|
||||
|
||||
import MetaTags from "~/components/core/MetaTags.astro";
|
||||
import BasicScripts from "~/components/core/BasicScripts.astro";
|
||||
import Analytics from '@julian_cataldo/astro-analytics/Analytics.astro';
|
||||
|
||||
const { meta = {} } = Astro.props;
|
||||
const { googleAnalyticsId = false } = SITE;
|
||||
---
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="motion-safe:scroll-smooth 2xl:text-[24px]">
|
||||
|
||||
<head>
|
||||
<MetaTags {...meta} />
|
||||
{googleAnalyticsId &&
|
||||
<Analytics id={googleAnalyticsId} />}
|
||||
</head>
|
||||
|
||||
<body class="antialiased text-gray-900 dark:text-slate-300 tracking-tight bg-white dark:bg-slate-900">
|
||||
<slot />
|
||||
<BasicScripts />
|
||||
</body>
|
||||
|
||||
</html>
|
@ -7,7 +7,9 @@ const { meta } = Astro.props;
|
||||
<Layout meta={meta}>
|
||||
<section class="px-8 sm:px-6 py-12 sm:py-16 lg:py-20 mx-auto max-w-3xl">
|
||||
<header>
|
||||
<h1 class="text-center text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-8 md:mb-16">
|
||||
<h1
|
||||
class="text-center text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-8 md:mb-16 font-heading"
|
||||
>
|
||||
<slot name="title" />
|
||||
</h1>
|
||||
</header>
|
||||
|
@ -1,6 +1,5 @@
|
||||
---
|
||||
import Layout from "~/layouts/BaseLayout.astro";
|
||||
|
||||
import Header from "~/components/widgets/Header.astro";
|
||||
import Footer from "~/components/widgets/Footer.astro";
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
---
|
||||
import { SITE, BLOG } from "~/config.mjs";
|
||||
import { fetchPosts } from "~/utils/fetchPosts";
|
||||
|
||||
import Layout from "~/layouts/BlogLayout.astro";
|
||||
import BlogList from "~/components/widgets/BlogList.astro";
|
||||
import Pagination from "~/components/widgets/Pagination.astro";
|
||||
import { getCanonical, getPermalink, BLOG_BASE } from "~/utils/permalinks";
|
||||
|
||||
import { fetchPosts } from "~/utils/posts";
|
||||
import { getCanonical, getPermalink, BLOG_BASE } from "~/utils/permalinks";
|
||||
|
||||
export async function getStaticPaths({ paginate }) {
|
||||
if (BLOG?.disabled) return [];
|
||||
@ -24,15 +25,14 @@ const currentPage = page.currentPage ?? 1;
|
||||
const meta = {
|
||||
title: `Blog ${currentPage > 1 ? `— Page ${currentPage} ` : ""}— ${SITE.name}`,
|
||||
description: SITE.description,
|
||||
canonical: getCanonical(getPermalink(page.url.current))
|
||||
}
|
||||
canonical: getCanonical(getPermalink(page.url.current)),
|
||||
};
|
||||
---
|
||||
|
||||
<Layout meta={meta}>
|
||||
<Fragment slot="title">
|
||||
News and step-by-step guides about
|
||||
<span class="bg-clip-text text-transparent bg-gradient-to-r from-blue-500 to-pink-500">AstroWind
|
||||
</span>
|
||||
<span class="bg-clip-text text-transparent bg-gradient-to-r from-primary-500 to-secondary-500">AstroWind</span>
|
||||
</Fragment>
|
||||
<BlogList posts={page.data} />
|
||||
<Pagination prevUrl={page.url.prev} nextUrl={page.url.next} />
|
||||
|
@ -1,11 +1,12 @@
|
||||
---
|
||||
import { SITE, BLOG } from "~/config.mjs";
|
||||
import { getCanonical, getPermalink, cleanSlug, BLOG_BASE } from "~/utils/permalinks";
|
||||
import { fetchPosts } from "~/utils/fetchPosts";
|
||||
import { findImage } from "~/utils/findImage";
|
||||
|
||||
import Layout from "~/layouts/PageLayout.astro";
|
||||
import BlogPost from "~/components/widgets/BlogPost.astro";
|
||||
|
||||
import { getCanonical, getPermalink, cleanSlug, BLOG_BASE } from "~/utils/permalinks";
|
||||
import { fetchPosts } from "~/utils/posts";
|
||||
import { findImage } from "~/utils/images";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
if (BLOG?.disabled) return [];
|
||||
@ -25,7 +26,7 @@ const meta = {
|
||||
description: post.description,
|
||||
canonical: post.canonical || getCanonical(getPermalink(post.slug, "post")),
|
||||
image: await findImage(post.image),
|
||||
}
|
||||
};
|
||||
---
|
||||
|
||||
<Layout meta={meta}>
|
||||
|
@ -1,30 +1,33 @@
|
||||
---
|
||||
|
||||
import { SITE, BLOG } from "~/config.mjs";
|
||||
import { fetchPosts } from "~/utils/fetchPosts";
|
||||
|
||||
import Layout from "~/layouts/BlogLayout.astro";
|
||||
import BlogList from "~/components/widgets/BlogList.astro";
|
||||
import Pagination from "~/components/widgets/Pagination.astro";
|
||||
import { getCanonical, getPermalink, cleanSlug, CATEGORY_BASE } from "~/utils/permalinks";
|
||||
|
||||
import { fetchPosts } from "~/utils/posts";
|
||||
import { getCanonical, getPermalink, cleanSlug, CATEGORY_BASE } from "~/utils/permalinks";
|
||||
|
||||
export async function getStaticPaths({ paginate }) {
|
||||
if (BLOG?.disabled || BLOG?.category?.disabled) return [];
|
||||
|
||||
const posts = await fetchPosts();
|
||||
|
||||
const categories = new Set()
|
||||
posts.map(post => {
|
||||
typeof post.category === "string" && categories.add(post.category.toLowerCase())
|
||||
})
|
||||
const categories = new Set();
|
||||
posts.map((post) => {
|
||||
typeof post.category === "string" && categories.add(post.category.toLowerCase());
|
||||
});
|
||||
|
||||
return Array.from(categories).map((category) => (
|
||||
paginate(posts.filter((post) => typeof post.category === "string" && category === post.category.toLowerCase()), {
|
||||
return Array.from(categories).map((category) =>
|
||||
paginate(
|
||||
posts.filter((post) => typeof post.category === "string" && category === post.category.toLowerCase()),
|
||||
{
|
||||
params: { category: cleanSlug(category), categories: CATEGORY_BASE || undefined },
|
||||
pageSize: BLOG.postsPerPage,
|
||||
props: { category }
|
||||
})
|
||||
))
|
||||
props: { category },
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const { page, category } = Astro.props;
|
||||
@ -34,8 +37,8 @@ const currentPage = page.currentPage ?? 1;
|
||||
const meta = {
|
||||
title: `Category '${category}' ${currentPage > 1 ? `— Page ${currentPage} ` : ""}— ${SITE.name}`,
|
||||
description: SITE.description,
|
||||
canonical: getCanonical(getPermalink(page.url.current))
|
||||
}
|
||||
canonical: getCanonical(getPermalink(page.url.current)),
|
||||
};
|
||||
---
|
||||
|
||||
<Layout meta={{ ...meta, noindex: true }}>
|
||||
|
@ -1,29 +1,33 @@
|
||||
---
|
||||
import { SITE, BLOG } from "~/config.mjs";
|
||||
import { fetchPosts } from "~/utils/fetchPosts";
|
||||
|
||||
import Layout from "~/layouts/BlogLayout.astro";
|
||||
import BlogList from "~/components/widgets/BlogList.astro";
|
||||
import Pagination from "~/components/widgets/Pagination.astro";
|
||||
import { getCanonical, getPermalink, cleanSlug, TAG_BASE } from "~/utils/permalinks";
|
||||
|
||||
import { fetchPosts } from "~/utils/posts";
|
||||
import { getCanonical, getPermalink, cleanSlug, TAG_BASE } from "~/utils/permalinks";
|
||||
|
||||
export async function getStaticPaths({ paginate }) {
|
||||
if (BLOG?.disabled || BLOG?.tag?.disabled) return [];
|
||||
|
||||
const posts = await fetchPosts();
|
||||
|
||||
const tags = new Set()
|
||||
posts.map(post => {
|
||||
Array.isArray(post.tags) && post.tags.map(tag => tags.add(tag.toLowerCase()))
|
||||
})
|
||||
const tags = new Set();
|
||||
posts.map((post) => {
|
||||
Array.isArray(post.tags) && post.tags.map((tag) => tags.add(tag.toLowerCase()));
|
||||
});
|
||||
|
||||
return Array.from(tags).map((tag) => (
|
||||
paginate(posts.filter((post) => Array.isArray(post.tags) && post.tags.includes(tag)), {
|
||||
return Array.from(tags).map((tag) =>
|
||||
paginate(
|
||||
posts.filter((post) => Array.isArray(post.tags) && post.tags.includes(tag)),
|
||||
{
|
||||
params: { tag: cleanSlug(tag), tags: TAG_BASE || undefined },
|
||||
pageSize: BLOG.postsPerPage,
|
||||
props: { tag },
|
||||
})
|
||||
))
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const { page, tag } = Astro.props;
|
||||
@ -33,8 +37,8 @@ const currentPage = page.currentPage ?? 1;
|
||||
const meta = {
|
||||
title: `Posts by tag '${tag}' ${currentPage > 1 ? `— Page ${currentPage} ` : ""}— ${SITE.name}`,
|
||||
description: SITE.description,
|
||||
canonical: getCanonical(getPermalink(page.url.current))
|
||||
}
|
||||
canonical: getCanonical(getPermalink(page.url.current)),
|
||||
};
|
||||
---
|
||||
|
||||
<Layout meta={{ ...meta, noindex: true }}>
|
||||
|
@ -17,7 +17,7 @@ const meta = {
|
||||
title: SITE.title,
|
||||
description: SITE.description,
|
||||
canonical: getCanonical(getHomePermalink()),
|
||||
}
|
||||
};
|
||||
---
|
||||
|
||||
<Layout meta={meta}>
|
||||
|
@ -1,13 +1,20 @@
|
||||
import rss from "@astrojs/rss";
|
||||
|
||||
import { SITE } from "~/config.mjs";
|
||||
import { fetchPosts } from "~/utils/fetchPosts";
|
||||
import { SITE, BLOG } from "~/config.mjs";
|
||||
import { fetchPosts } from "~/utils/posts";
|
||||
import { getPermalink } from "~/utils/permalinks";
|
||||
|
||||
export const get = async () => {
|
||||
if (BLOG.disabled) {
|
||||
return new Response(null, {
|
||||
status: 404,
|
||||
statusText: 'Not found'
|
||||
});
|
||||
}
|
||||
|
||||
const posts = await fetchPosts();
|
||||
|
||||
export const get = () =>
|
||||
rss({
|
||||
return rss({
|
||||
title: `${SITE.name}’s Blog`,
|
||||
description: SITE.description,
|
||||
site: import.meta.env.SITE,
|
||||
@ -19,3 +26,4 @@ export const get = () =>
|
||||
pubDate: post.pubDate,
|
||||
})),
|
||||
});
|
||||
}
|
22
src/utils/directories.js
Normal file
22
src/utils/directories.js
Normal file
@ -0,0 +1,22 @@
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
/** */
|
||||
export const getProjectRootDir = () => {
|
||||
const mode = import.meta.env.MODE;
|
||||
|
||||
return mode === "production" ? path.join(__dirname, "../") : path.join(__dirname, "../../");
|
||||
};
|
||||
|
||||
const __srcFolder = path.join(getProjectRootDir(), "/src");
|
||||
|
||||
/** */
|
||||
export const getRelativeUrlByFilePath = (filepath) => {
|
||||
if (filepath) {
|
||||
return filepath.replace(__srcFolder, "");
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
@ -1,14 +0,0 @@
|
||||
const load = async function () {
|
||||
let images = [];
|
||||
try {
|
||||
images = import.meta.glob("~/assets/images/*");
|
||||
} catch (e) {}
|
||||
return images;
|
||||
};
|
||||
|
||||
let _images;
|
||||
|
||||
export const fetchLocalImages = async () => {
|
||||
_images = _images || load();
|
||||
return await _images;
|
||||
};
|
@ -1,24 +0,0 @@
|
||||
import getReadingTime from "reading-time";
|
||||
|
||||
export const getNormalizedPost = async (post) => {
|
||||
const { frontmatter, compiledContent, rawContent, file } = post;
|
||||
|
||||
return {
|
||||
pubDate: frontmatter.pubDate,
|
||||
draft: frontmatter.draft,
|
||||
|
||||
canonical: frontmatter.canonical,
|
||||
slug: file.split("/").pop().split(".").shift(),
|
||||
|
||||
title: frontmatter.title,
|
||||
description: frontmatter.description,
|
||||
body: compiledContent(),
|
||||
image: frontmatter.image,
|
||||
|
||||
excerpt: frontmatter.excerpt,
|
||||
authors: frontmatter.authors,
|
||||
category: frontmatter.category,
|
||||
tags: frontmatter.tags,
|
||||
readingTime: Math.ceil(getReadingTime(rawContent()).minutes),
|
||||
};
|
||||
};
|
@ -1,12 +0,0 @@
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export const getProjectRootDir = () => {
|
||||
const mode = import.meta.env.MODE;
|
||||
|
||||
return mode === "production"
|
||||
? path.join(__dirname, "../")
|
||||
: path.join(__dirname, "../../");
|
||||
};
|
@ -1,12 +0,0 @@
|
||||
import path from "path";
|
||||
import { getProjectRootDir } from "./getProjectRootDir";
|
||||
|
||||
const __srcFolder = path.join(getProjectRootDir(), "/src");
|
||||
|
||||
export const getRelativeUrlByFilePath = (filepath) => {
|
||||
if (filepath) {
|
||||
return filepath.replace(__srcFolder, "");
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
@ -1,5 +1,20 @@
|
||||
import { fetchLocalImages } from "~/utils/fetchLocalImages";
|
||||
const load = async function () {
|
||||
let images = [];
|
||||
try {
|
||||
images = import.meta.glob("~/assets/images/*");
|
||||
} catch (e) {}
|
||||
return images;
|
||||
};
|
||||
|
||||
let _images;
|
||||
|
||||
/** */
|
||||
export const fetchLocalImages = async () => {
|
||||
_images = _images || load();
|
||||
return await _images;
|
||||
};
|
||||
|
||||
/** */
|
||||
export const findImage = async (imagePath) => {
|
||||
if (typeof imagePath !== "string") {
|
||||
return null;
|
||||
@ -16,7 +31,5 @@ export const findImage = async (imagePath) => {
|
||||
const images = await fetchLocalImages();
|
||||
const key = imagePath.replace("~/", "/src/");
|
||||
|
||||
return typeof images[key] === "function"
|
||||
? (await images[key]())["default"]
|
||||
: null;
|
||||
return typeof images[key] === "function" ? (await images[key]())["default"] : null;
|
||||
};
|
@ -1,17 +1,17 @@
|
||||
import slugify from 'limax';
|
||||
import slugify from "limax";
|
||||
|
||||
import { SITE, BLOG } from "~/config.mjs";
|
||||
|
||||
const trim = (str, ch) => {
|
||||
let start = 0, end = str.length;
|
||||
while(start < end && str[start] === ch)
|
||||
++start;
|
||||
while(end > start && str[end - 1] === ch)
|
||||
--end;
|
||||
return (start > 0 || end < str.length) ? str.substring(start, end) : str;
|
||||
}
|
||||
let start = 0,
|
||||
end = str.length;
|
||||
while (start < end && str[start] === ch) ++start;
|
||||
while (end > start && str[end - 1] === ch) --end;
|
||||
return start > 0 || end < str.length ? str.substring(start, end) : str;
|
||||
};
|
||||
|
||||
const trimSlash = (s) => trim(trim(s, "/"));
|
||||
const createPath = (...params) => "/" + params.filter((el) => !!el).join("/")
|
||||
const createPath = (...params) => "/" + params.filter((el) => !!el).join("/");
|
||||
|
||||
const basePathname = trimSlash(SITE.basePathname);
|
||||
|
||||
@ -21,17 +21,19 @@ export const BLOG_BASE = cleanSlug(BLOG.slug);
|
||||
export const CATEGORY_BASE = cleanSlug(BLOG?.category?.slug);
|
||||
export const TAG_BASE = cleanSlug(BLOG?.tag?.slug);
|
||||
|
||||
/** */
|
||||
export const getCanonical = (path = "") => new URL(path, SITE.origin);
|
||||
|
||||
/** */
|
||||
export const getPermalink = (slug = "", type = "page") => {
|
||||
const _slug = cleanSlug(slug);
|
||||
|
||||
switch (type) {
|
||||
case "category":
|
||||
return createPath(basePathname, CATEGORY_BASE, _slug)
|
||||
return createPath(basePathname, CATEGORY_BASE, _slug);
|
||||
|
||||
case "tag":
|
||||
return createPath(basePathname, TAG_BASE, _slug)
|
||||
return createPath(basePathname, TAG_BASE, _slug);
|
||||
|
||||
case "post":
|
||||
return createPath(basePathname, BLOG.postsWithoutBlogSlug ? "" : BLOG_BASE, _slug);
|
||||
@ -42,8 +44,11 @@ export const getPermalink = (slug = "", type = "page") => {
|
||||
}
|
||||
};
|
||||
|
||||
/** */
|
||||
export const getBlogPermalink = () => getPermalink(BLOG_BASE);
|
||||
|
||||
/** */
|
||||
export const getHomePermalink = () => {
|
||||
const permalink = getPermalink();
|
||||
return permalink !== "/" ? permalink + "/" : permalink;
|
||||
}
|
||||
};
|
||||
|
@ -1,4 +1,30 @@
|
||||
import { getNormalizedPost } from "~/utils/getNormalizedPost";
|
||||
import getReadingTime from "reading-time";
|
||||
|
||||
const getNormalizedPost = async (post) => {
|
||||
const { frontmatter, compiledContent, rawContent, file } = post;
|
||||
const ID = file.split("/").pop().split(".").shift();
|
||||
|
||||
return {
|
||||
id: ID,
|
||||
|
||||
pubDate: frontmatter.pubDate,
|
||||
draft: frontmatter.draft,
|
||||
|
||||
canonical: frontmatter.canonical,
|
||||
slug: frontmatter.slug || ID,
|
||||
|
||||
title: frontmatter.title,
|
||||
description: frontmatter.description,
|
||||
body: compiledContent(),
|
||||
image: frontmatter.image,
|
||||
|
||||
excerpt: frontmatter.excerpt,
|
||||
authors: frontmatter.authors,
|
||||
category: frontmatter.category,
|
||||
tags: frontmatter.tags,
|
||||
readingTime: Math.ceil(getReadingTime(rawContent()).minutes),
|
||||
};
|
||||
};
|
||||
|
||||
const load = async function () {
|
||||
const posts = import.meta.glob("~/data/posts/**/*.md", {
|
||||
@ -18,12 +44,14 @@ const load = async function () {
|
||||
|
||||
let _posts;
|
||||
|
||||
/** */
|
||||
export const fetchPosts = async () => {
|
||||
_posts = _posts || load();
|
||||
|
||||
return await _posts;
|
||||
};
|
||||
|
||||
/** */
|
||||
export const findPostsByIds = async (ids) => {
|
||||
if (!Array.isArray(ids)) return [];
|
||||
|
||||
@ -31,7 +59,7 @@ export const findPostsByIds = async (ids) => {
|
||||
|
||||
return ids.reduce(function (r, id) {
|
||||
posts.some(function (post) {
|
||||
return id === post.ID && r.push(post);
|
||||
return id === post.id && r.push(post);
|
||||
});
|
||||
return r;
|
||||
}, []);
|
@ -1,3 +1,4 @@
|
||||
/** */
|
||||
export const getFormattedDate = (date) =>
|
||||
date
|
||||
? new Date(date).toLocaleDateString("en-us", {
|
@ -1,14 +1,44 @@
|
||||
const defaultTheme = require("tailwindcss/defaultTheme");
|
||||
const colors = require("tailwindcss/colors")
|
||||
|
||||
module.exports = {
|
||||
content: ["./src/**/*.{astro,html,js,jsx,md,svelte,ts,tsx,vue}"],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: colors.blue,
|
||||
secondary: colors.pink,
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['"IBM Plex Sans"', ...defaultTheme.fontFamily.sans],
|
||||
sans: ["'IBM Plex Sans'", ...defaultTheme.fontFamily.sans],
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [require("@tailwindcss/typography")],
|
||||
darkMode: "class",
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Alternative tailwind.config.js
|
||||
|
||||
NOTE: Add this fonts to <head>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;500;700&display=swap" rel="stylesheet" />
|
||||
*/
|
||||
|
||||
// module.exports = {
|
||||
// content: ["./src/**/*.{astro,html,js,jsx,md,svelte,ts,tsx,vue}"],
|
||||
// theme: {
|
||||
// extend: {
|
||||
// colors: {
|
||||
// primary: colors.cyan,
|
||||
// secondary: colors.lime,
|
||||
// },
|
||||
// fontFamily: {
|
||||
// sans: ["'Nunito'", ...defaultTheme.fontFamily.sans],
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// plugins: [require("@tailwindcss/typography")],
|
||||
// darkMode: "class",
|
||||
// };
|
Reference in New Issue
Block a user