v1
This commit is contained in:
20
src/pages/404.astro
Normal file
20
src/pages/404.astro
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { markdownify } from "@/lib/utils/textConverter";
|
||||
import { getEntryBySlug } from "astro:content";
|
||||
const entry = await getEntryBySlug("pages", "404");
|
||||
const { Content } = await entry.render();
|
||||
---
|
||||
|
||||
<Base title={entry.data.title}>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="flex h-[40vh] items-center justify-center">
|
||||
<div class="text-center">
|
||||
<h1 class="mb-4" set:html={markdownify(entry.data.title)} />
|
||||
<Content />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Base>
|
||||
42
src/pages/[regular].astro
Normal file
42
src/pages/[regular].astro
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import Default from "@/layouts/Default.astro";
|
||||
import PostSingle from "@/layouts/PostSingle.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import type { TPost } from "@/types";
|
||||
|
||||
const getPosts = (await getSinglePage("posts")) as TPost[];
|
||||
const postsSlug = getPosts.map((item) => item.slug);
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getSinglePage("posts");
|
||||
const pages = await getSinglePage("pages");
|
||||
const allPages = [...pages, ...posts];
|
||||
|
||||
const paths = allPages.map((page: any) => ({
|
||||
params: {
|
||||
regular: page.slug,
|
||||
},
|
||||
props: { page },
|
||||
}));
|
||||
return paths;
|
||||
}
|
||||
|
||||
const { page } = Astro.props;
|
||||
const { title, meta_title, description, image } = page.data;
|
||||
---
|
||||
|
||||
<Base
|
||||
title={title}
|
||||
meta_title={meta_title}
|
||||
description={description}
|
||||
image={image}
|
||||
>
|
||||
{
|
||||
postsSlug.includes(page.slug) ? (
|
||||
<PostSingle post={page} />
|
||||
) : (
|
||||
<Default data={page} />
|
||||
)
|
||||
}
|
||||
</Base>
|
||||
66
src/pages/about.astro
Normal file
66
src/pages/about.astro
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
import { Image } from "astro:assets";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { markdownify } from "@/lib/utils/textConverter";
|
||||
import { getEntryBySlug } from "astro:content";
|
||||
|
||||
const entry = await getEntryBySlug("about", "index");
|
||||
const { Content } = await entry.render();
|
||||
const { title, description, meta_title, image, what_i_do } = entry.data;
|
||||
---
|
||||
|
||||
<Base
|
||||
title={title}
|
||||
meta_title={meta_title}
|
||||
description={description}
|
||||
image={image}
|
||||
>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="row md:gx-4">
|
||||
<div class="sm:col-5 md:col-4">
|
||||
{
|
||||
image && (
|
||||
<div class="img-cover mb-8">
|
||||
<Image
|
||||
src={image}
|
||||
width={295}
|
||||
height={395}
|
||||
alt={title}
|
||||
class="rounded-lg w-full"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div class="sm:col-7 md:col-8">
|
||||
<h1 set:html={markdownify(title)} class="h3 mb-8" />
|
||||
|
||||
<div class="content">
|
||||
<Content />
|
||||
</div>
|
||||
<a href="/contact" class="btn btn-primary text-white py-2"
|
||||
>Get In Touch</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section pt-0">
|
||||
<div class="container">
|
||||
<h3 class="page-heading mb-20">{what_i_do.title}</h3>
|
||||
<div class="row justify-center gy-4 text-center">
|
||||
{
|
||||
what_i_do.items.map((item: any) => (
|
||||
<div class="lg:col-4 md:col-6">
|
||||
<i class="{{.icon}} fa-3x text-primary mb-4" />
|
||||
<h4 class="text-dark font-weight-700 mb-3">{item.title}</h4>
|
||||
<p>{item.description}</p>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Base>
|
||||
110
src/pages/authors/[single].astro
Normal file
110
src/pages/authors/[single].astro
Normal file
@@ -0,0 +1,110 @@
|
||||
---
|
||||
import { Image } from "astro:assets";
|
||||
import AuthorSingle from "@/layouts/AuthorSingle.astro";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import dateFormat from "@/lib/utils/dateFormat";
|
||||
|
||||
import { sortByDate } from "@/lib/utils/sortFunctions";
|
||||
import { humanize, slugify } from "@/lib/utils/textConverter";
|
||||
import { BiCalendarEdit, BiCategoryAlt } from "react-icons/bi";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const authors = await getSinglePage("authors");
|
||||
|
||||
const paths = authors.map((author: any) => ({
|
||||
params: {
|
||||
single: author.slug,
|
||||
},
|
||||
props: { author },
|
||||
}));
|
||||
return paths;
|
||||
}
|
||||
|
||||
const { author } = Astro.props;
|
||||
const { title, meta_title, description, image } = author.data;
|
||||
|
||||
// Author Posts
|
||||
const posts = await getSinglePage("posts");
|
||||
const sortPostsByDate = sortByDate(posts);
|
||||
const currentPosts = sortPostsByDate.filter((post) => {
|
||||
return post.data.authors
|
||||
.map((author: string) => slugify(author))
|
||||
.includes(slugify(title));
|
||||
});
|
||||
---
|
||||
|
||||
<Base
|
||||
title={title}
|
||||
meta_title={meta_title}
|
||||
description={description}
|
||||
image={image}
|
||||
>
|
||||
<AuthorSingle author={author} />
|
||||
|
||||
{
|
||||
currentPosts.length > 0 && (
|
||||
<section class="section pt-0">
|
||||
<div class="container">
|
||||
<h2 class="mb-8 text-center h3">Recent Posts</h2>
|
||||
<div
|
||||
class={`row gy-4 ${currentPosts.length < 3 ? "justify-center" : ""}`}
|
||||
>
|
||||
{currentPosts.map((post: any, i: number) => (
|
||||
<div class="col-12 sm:col-6 lg:col-4">
|
||||
{post.data.image && (
|
||||
<a
|
||||
href={`/${post.slug}`}
|
||||
class="rounded-lg block hover:text-primary overflow-hidden group"
|
||||
>
|
||||
<Image
|
||||
class="group-hover:scale-[1.05] transition duration-300 w-full"
|
||||
src={post.data.image}
|
||||
alt={post.data.title}
|
||||
width={445}
|
||||
height={230}
|
||||
/>
|
||||
</a>
|
||||
)}
|
||||
<ul class="mt-4 text-text flex flex-wrap items-center text-sm">
|
||||
<li class="mb-2 mr-4 flex items-center flex-wrap font-medium">
|
||||
<BiCalendarEdit className="mr-1 h-[16px] w-[16px] text-gray-600" />
|
||||
<>{dateFormat(post.data.date)}</>
|
||||
</li>
|
||||
<li class="mb-2 mr-4 flex items-center flex-wrap">
|
||||
<BiCategoryAlt className="mr-1 h-[16px] w-[16px] text-gray-600" />
|
||||
<>
|
||||
<ul>
|
||||
{post.data.categories.map(
|
||||
(category: string, i: number) => (
|
||||
<li class="inline-block">
|
||||
<a
|
||||
href={`/categories/${slugify(category)}`}
|
||||
class="mr-2 hover:text-primary font-medium"
|
||||
>
|
||||
{humanize(category)}
|
||||
{i !== post.data.categories.length - 1 && ","}
|
||||
</a>
|
||||
</li>
|
||||
),
|
||||
)}
|
||||
</ul>
|
||||
</>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 class="h5">
|
||||
<a
|
||||
href={`/${post.slug}`}
|
||||
class="block hover:text-primary transition duration-300"
|
||||
>
|
||||
{post.data.title}
|
||||
</a>
|
||||
</h3>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
</Base>
|
||||
24
src/pages/authors/index.astro
Normal file
24
src/pages/authors/index.astro
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
import config from "@/config/config.json";
|
||||
import Authors from "@/layouts/Authors.astro";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import Pagination from "@/layouts/components/Pagination.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { sortByDate } from "@/lib/utils/sortFunctions";
|
||||
import { markdownify } from "@/lib/utils/textConverter";
|
||||
|
||||
const authors = await getSinglePage("authors");
|
||||
const sortedPosts = sortByDate(authors);
|
||||
const totalPages = Math.ceil(authors.length / config.settings.pagination);
|
||||
const currentPosts = sortedPosts.slice(0, config.settings.pagination);
|
||||
---
|
||||
|
||||
<Base title={"Authors"}>
|
||||
<section class="section">
|
||||
<div class="container text-center">
|
||||
<h1 set:text={markdownify("Authors")} class="page-heading h2" />
|
||||
<Authors authors={currentPosts} />
|
||||
<Pagination section={"authors"} currentPage={1} totalPages={totalPages} />
|
||||
</div>
|
||||
</section>
|
||||
</Base>
|
||||
47
src/pages/authors/page/[slug].astro
Normal file
47
src/pages/authors/page/[slug].astro
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
import config from "@/config/config.json";
|
||||
import Authors from "@/layouts/Authors.astro";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import Pagination from "@/layouts/components/Pagination.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { sortByDate } from "@/lib/utils/sortFunctions";
|
||||
import { markdownify } from "@/lib/utils/textConverter";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const authors = await getSinglePage("authors");
|
||||
const totalPages = Math.ceil(authors.length / config.settings.pagination);
|
||||
const paths = [];
|
||||
|
||||
for (let i = 1; i < totalPages; i++) {
|
||||
paths.push({
|
||||
params: {
|
||||
slug: (i + 1).toString(),
|
||||
},
|
||||
});
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
const { slug } = Astro.params;
|
||||
const authors = await getSinglePage("authors");
|
||||
const sortedPosts = sortByDate(authors);
|
||||
const totalPages = Math.ceil(authors.length / config.settings.pagination);
|
||||
const currentPage = slug && !isNaN(Number(slug)) ? Number(slug) : 1;
|
||||
const indexOfLastPost = currentPage * config.settings.pagination;
|
||||
const indexOfFirstPost = indexOfLastPost - config.settings.pagination;
|
||||
const currentPosts = sortedPosts.slice(indexOfFirstPost, indexOfLastPost);
|
||||
---
|
||||
|
||||
<Base title={"Authors"}>
|
||||
<section class="section">
|
||||
<div class="container text-center">
|
||||
<h1 set:text={markdownify("Authors")} class="page-heading h2" />
|
||||
<Authors authors={currentPosts} />
|
||||
<Pagination
|
||||
section={"authors"}
|
||||
currentPage={currentPage}
|
||||
totalPages={totalPages}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</Base>
|
||||
35
src/pages/categories/[category].astro
Normal file
35
src/pages/categories/[category].astro
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import Posts from "@/layouts/Posts.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import taxonomyFilter from "@/lib/utils/taxonomyFilter";
|
||||
import { humanize } from "@/lib/utils/textConverter";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const categories = await getTaxonomy("posts", "categories");
|
||||
|
||||
return categories.map((category) => {
|
||||
return {
|
||||
params: { category },
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const { category } = Astro.params;
|
||||
|
||||
const posts = await getSinglePage("posts");
|
||||
const filterByCategory = taxonomyFilter(posts, "categories", category);
|
||||
|
||||
const title = humanize(category || "");
|
||||
---
|
||||
|
||||
<Base title={title || "Category"}>
|
||||
<div class="section">
|
||||
<div class="container">
|
||||
<p class="text-center mb-4">Showing Posts From</p>
|
||||
<h1 class="h2 mb-16 text-center text-primary">{title}</h1>
|
||||
<Posts posts={filterByCategory} fluid={false} />
|
||||
</div>
|
||||
</div>
|
||||
</Base>
|
||||
32
src/pages/categories/index.astro
Normal file
32
src/pages/categories/index.astro
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import { humanize } from "@/lib/utils/textConverter";
|
||||
|
||||
const categories = await getTaxonomy("posts", "categories");
|
||||
|
||||
import { BiCategoryAlt } from "react-icons/bi";
|
||||
---
|
||||
|
||||
<Base title={"Categories"}>
|
||||
<section class="section">
|
||||
<div class="container text-center">
|
||||
<h1 class="h2 page-heading">Categories</h1>
|
||||
<ul class="space-x-4">
|
||||
{
|
||||
categories.map((category) => (
|
||||
<li class="inline-block">
|
||||
<a
|
||||
href={`/categories/${category}`}
|
||||
class="rounded-lg bg-theme-light px-4 py-2 text-dark transition hover:bg-primary hover:text-white flex items-center group"
|
||||
>
|
||||
<BiCategoryAlt className="mr-1 text-primary group-hover:text-white transition h-6 w-6 scale-75" />
|
||||
<>{humanize(category || "")}</>
|
||||
</a>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</Base>
|
||||
80
src/pages/contact.astro
Normal file
80
src/pages/contact.astro
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { markdownify } from "@/lib/utils/textConverter";
|
||||
import { getEntryBySlug } from "astro:content";
|
||||
import { FaAddressCard, FaEnvelope, FaPhoneAlt } from "react-icons/fa";
|
||||
|
||||
const entry = await getEntryBySlug("pages", "contact");
|
||||
const { contact_form_action } = config.params;
|
||||
const { address, email, phone } = config.contactinfo;
|
||||
const { title, description, meta_title, image } = entry.data;
|
||||
---
|
||||
|
||||
<Base
|
||||
title={title}
|
||||
meta_title={meta_title}
|
||||
description={description}
|
||||
image={image}
|
||||
>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 set:html={markdownify(title)} class="h2 page-heading" />
|
||||
<div class="row md:gx-5 gy-5">
|
||||
<div class="sm:col-5 md:col-4">
|
||||
<p class="mb-8 text-2xl font-bold text-theme-dark">Contact Info</p>
|
||||
<ul class="flex flex-col space-y-8">
|
||||
<li>
|
||||
<div class="flex text-theme-dark items-center text-xl">
|
||||
<FaAddressCard className="mr-3 text-primary" />
|
||||
<p class="font-semibold">Address</p>
|
||||
</div>
|
||||
<p set:html={markdownify(address)} class="mt-2 leading-5 pl-8" />
|
||||
</li>
|
||||
<li>
|
||||
<div class="flex text-theme-dark items-center text-xl">
|
||||
<FaEnvelope className="mr-3 text-primary" />
|
||||
<p class="font-semibold">Email</p>
|
||||
</div>
|
||||
<p set:html={markdownify(email)} class="mt-2 leading-5 pl-8 content" />
|
||||
</li>
|
||||
<li>
|
||||
<div class="flex text-theme-dark items-center text-xl">
|
||||
<FaPhoneAlt className="mr-3 text-primary" />
|
||||
<p class="font-semibold">Phone</p>
|
||||
</div>
|
||||
<p set:html={markdownify(phone)} class="mt-2 leading-5 pl-8" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="sm:col-7 md:col-8">
|
||||
<form class="contact-form row gy-2 justify-center" method="POST" action={contact_form_action}>
|
||||
<div class="lg:col-6">
|
||||
<label class="mb-2 block" for="name">Name <span class="text-red-600">*</span></label>
|
||||
<input class="form-input w-full" name="name" type="text" required />
|
||||
</div>
|
||||
<div class="lg:col-6">
|
||||
<label class="mb-2 block" for="email">Email <span class="text-red-600">*</span></label>
|
||||
<input class="form-input w-full" name="email" type="email" required />
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="mb-2 block" for="subject">Subject</label>
|
||||
<input
|
||||
class="form-input w-full"
|
||||
name="subject"
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="mb-2 block" for="message">Message <span class="text-red-600">*</span></label>
|
||||
<textarea class="form-textarea w-full" rows="4"></textarea>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button class="btn btn-primary mt-2">Submit Now</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Base>
|
||||
22
src/pages/index.astro
Normal file
22
src/pages/index.astro
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import Pagination from "@/layouts/components/Pagination.astro";
|
||||
import Posts from "@/layouts/Posts.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { sortByDate } from "@/lib/utils/sortFunctions";
|
||||
|
||||
const posts = await getSinglePage("posts");
|
||||
const sortedPosts = sortByDate(posts);
|
||||
const totalPages = Math.ceil(posts.length / config.settings.pagination);
|
||||
const currentPosts = sortedPosts.slice(0, config.settings.pagination);
|
||||
---
|
||||
|
||||
<Base>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<Posts posts={currentPosts} className="mb-16" />
|
||||
<Pagination currentPage={1} totalPages={totalPages} />
|
||||
</div>
|
||||
</section>
|
||||
</Base>
|
||||
41
src/pages/page/[slug].astro
Normal file
41
src/pages/page/[slug].astro
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import Pagination from "@/layouts/components/Pagination.astro";
|
||||
import Posts from "@/layouts/Posts.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { sortByDate } from "@/lib/utils/sortFunctions";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getSinglePage("posts");
|
||||
const totalPages = Math.ceil(posts.length / config.settings.pagination);
|
||||
const paths = [];
|
||||
|
||||
for (let i = 1; i < totalPages; i++) {
|
||||
paths.push({
|
||||
params: {
|
||||
slug: (i + 1).toString(),
|
||||
},
|
||||
});
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
const { slug } = Astro.params;
|
||||
const posts = await getSinglePage("posts");
|
||||
const sortedPosts = sortByDate(posts);
|
||||
const totalPages = Math.ceil(posts.length / config.settings.pagination);
|
||||
const currentPage = slug && !isNaN(Number(slug)) ? Number(slug) : 1;
|
||||
const indexOfLastPost = currentPage * config.settings.pagination;
|
||||
const indexOfFirstPost = indexOfLastPost - config.settings.pagination;
|
||||
const currentPosts = sortedPosts.slice(indexOfFirstPost, indexOfLastPost);
|
||||
---
|
||||
|
||||
<Base>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<Posts className="mb-16" posts={currentPosts} />
|
||||
<Pagination totalPages={totalPages} currentPage={currentPage} />
|
||||
</div>
|
||||
</section>
|
||||
</Base>
|
||||
23
src/pages/search.astro
Normal file
23
src/pages/search.astro
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import SearchBar from "@/layouts/SearchBar";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
|
||||
// Retrieve all articles
|
||||
const posts = await getSinglePage("posts");
|
||||
|
||||
// List of items to search in
|
||||
const searchList = posts.map((item: any) => ({
|
||||
slug: item.slug,
|
||||
data: item.data,
|
||||
content: item.body,
|
||||
}));
|
||||
---
|
||||
|
||||
<Base title={`Search`}>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<SearchBar client:load searchList={searchList} />
|
||||
</div>
|
||||
</section>
|
||||
</Base>
|
||||
35
src/pages/tags/[tag].astro
Normal file
35
src/pages/tags/[tag].astro
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import Posts from "@/layouts/Posts.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import taxonomyFilter from "@/lib/utils/taxonomyFilter";
|
||||
import { humanize } from "@/lib/utils/textConverter";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const tags = await getTaxonomy("posts", "tags");
|
||||
|
||||
return tags.map((tag) => {
|
||||
return {
|
||||
params: { tag },
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const { tag } = Astro.params;
|
||||
|
||||
const posts = await getSinglePage("posts");
|
||||
const filterByTags = taxonomyFilter(posts, "tags", tag);
|
||||
|
||||
const title = humanize(tag || "");
|
||||
---
|
||||
|
||||
<Base title={title || "Tag"}>
|
||||
<div class="section">
|
||||
<div class="container">
|
||||
<p class="text-center mb-4">Showing Posts From</p>
|
||||
<h1 class="h2 mb-16 text-center text-primary">{title}</h1>
|
||||
<Posts posts={filterByTags} fluid={false} />
|
||||
</div>
|
||||
</div>
|
||||
</Base>
|
||||
32
src/pages/tags/index.astro
Normal file
32
src/pages/tags/index.astro
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import { humanize } from "@/lib/utils/textConverter";
|
||||
|
||||
import { FaHashtag } from "react-icons/fa";
|
||||
|
||||
const tags = await getTaxonomy("posts", "tags");
|
||||
---
|
||||
|
||||
<Base title={"Tags"}>
|
||||
<section class="section">
|
||||
<div class="container text-center">
|
||||
<h1 class="h2 page-heading">Tags</h1>
|
||||
<ul class="space-x-4">
|
||||
{
|
||||
tags.map((tag) => (
|
||||
<li class="inline-block">
|
||||
<a
|
||||
href={`/tags/${tag}`}
|
||||
class="rounded-lg bg-theme-light px-4 py-2 text-dark transition hover:bg-primary hover:text-white flex items-center group"
|
||||
>
|
||||
<FaHashtag className="mr-1 text-primary group-hover:text-white transition" />
|
||||
<>{humanize(tag || "")}</>
|
||||
</a>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</Base>
|
||||
Reference in New Issue
Block a user