mirror of
https://github.com/10h30/astroplate.git
synced 2026-06-05 15:08:00 +09:00
@@ -4,7 +4,7 @@ import config from "@/config/config.json";
|
||||
import { humanize, plainify, slugify } from "@/lib/utils/textConverter";
|
||||
import { FaRegFolder, FaRegUserCircle } from "react-icons/fa/index.js";
|
||||
|
||||
const { summary_length, blog_folder } = config.settings;
|
||||
const { summary_length, blog_folder }: {summary_length: number, blog_folder: string} = config.settings;
|
||||
const { data } = Astro.props;
|
||||
const { title, image, date, author, categories } = data.data;
|
||||
---
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
import { humanize } from "@/lib/utils/textConverter";
|
||||
|
||||
const { className } = Astro.props;
|
||||
const { className }: {className?: string} = Astro.props;
|
||||
|
||||
const paths = Astro.url.pathname.split("/").filter((x) => x);
|
||||
let parts = [
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { Image } from "@astrojs/image/components";
|
||||
import config from "@/config/config.json";
|
||||
|
||||
const { src, srcDarkmode } = Astro.props;
|
||||
const { src, srcDarkmode } : {src?: string, srcDarkmode?: string} = Astro.props;
|
||||
const {
|
||||
logo,
|
||||
logo_darkmode,
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
---
|
||||
const { section, currentPage, totalPages } = Astro.props;
|
||||
type Pagination = {
|
||||
section?: string, currentPage?: number, totalPages?: number
|
||||
}
|
||||
const { section, currentPage=1, totalPages=1 }: Pagination = Astro.props;
|
||||
|
||||
const indexPageLink = currentPage === 2;
|
||||
const hasPrevPage = currentPage > 1;
|
||||
const hasNextPage = totalPages > currentPage;
|
||||
const hasNextPage = totalPages > currentPage!;
|
||||
|
||||
let pageList = [];
|
||||
let pageList: number[] = [];
|
||||
for (let i = 1; i <= totalPages; i++) {
|
||||
pageList.push(i);
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import {
|
||||
IoLogoTwitter,
|
||||
} from "react-icons/io5/index.js";
|
||||
|
||||
const { base_url } = config.site;
|
||||
const { title, description, slug, className } = Astro.props;
|
||||
const { base_url }: {base_url: string} = config.site;
|
||||
const { title, description, slug, className }: {title?: string, description?: string, slug?: string, className?: string} = Astro.props;
|
||||
---
|
||||
|
||||
<ul class={`${className}`}>
|
||||
|
||||
@@ -35,6 +35,39 @@ import {
|
||||
IoMail,
|
||||
} from "react-icons/io5/index.js";
|
||||
|
||||
type SocialLink = {
|
||||
facebook: string,
|
||||
twitter: string,
|
||||
mastodon: string,
|
||||
instagram: string,
|
||||
youtube: string,
|
||||
linkedin: string,
|
||||
github: string,
|
||||
gitlab: string,
|
||||
discord: string,
|
||||
slack: string,
|
||||
medium: string,
|
||||
codepen: string,
|
||||
bitbucket: string,
|
||||
dribbble: string,
|
||||
behance: string,
|
||||
pinterest: string,
|
||||
soundcloud: string,
|
||||
tumblr: string,
|
||||
reddit: string,
|
||||
vk: string,
|
||||
whatsapp: string,
|
||||
snapchat: string,
|
||||
vimeo: string,
|
||||
tiktok: string,
|
||||
foursquare: string,
|
||||
rss: string,
|
||||
email: string,
|
||||
phone: string,
|
||||
address: string,
|
||||
skype: string,
|
||||
website: string,
|
||||
}
|
||||
const {
|
||||
facebook,
|
||||
twitter,
|
||||
@@ -67,7 +100,7 @@ const {
|
||||
address,
|
||||
skype,
|
||||
website,
|
||||
} = source;
|
||||
}: SocialLink = source;
|
||||
---
|
||||
|
||||
<ul class={className}>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
import config from "@/config/config.json";
|
||||
|
||||
const { theme_switcher, default_theme } = config.settings;
|
||||
const {className} = Astro.props;
|
||||
const { theme_switcher, default_theme }: { theme_switcher: boolean, default_theme: string } = config.settings;
|
||||
const {className}: {className?: string} = Astro.props;
|
||||
---
|
||||
|
||||
{
|
||||
|
||||
@@ -5,6 +5,8 @@ import config from "@/config/config.json";
|
||||
import menu from "@/config/menu.json";
|
||||
import social from "@/config/social.json";
|
||||
import { markdownify } from "@/lib/utils/textConverter";
|
||||
|
||||
const {footer}: {footer: {name: string, url: string}[]} = menu;
|
||||
---
|
||||
|
||||
<footer class="bg-theme-light dark:bg-darkmode-theme-light">
|
||||
@@ -16,7 +18,7 @@ import { markdownify } from "@/lib/utils/textConverter";
|
||||
<div class="mb-8 text-center lg:col-6 lg:mb-0">
|
||||
<ul>
|
||||
{
|
||||
menu.footer.map((menu) => (
|
||||
footer.map((menu) => (
|
||||
<li class="m-3 inline-block">
|
||||
<a href={menu.url}>{menu.name}</a>
|
||||
</li>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.astro";
|
||||
import { humanize } from "@/lib/utils/textConverter";
|
||||
|
||||
const { title } = Astro.props;
|
||||
const { title="" }: {title?: string} = Astro.props;
|
||||
---
|
||||
|
||||
<section>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { marked } from "marked";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
|
||||
const Tabs = ({ children }: any) => {
|
||||
const [active, setActive] = useState(0);
|
||||
const [defaultFocus, setDefaultFocus] = useState(false);
|
||||
const Tabs = ({ children }: {children: React.ReactElement}) => {
|
||||
const [active, setActive] = useState<number>(0);
|
||||
const [defaultFocus, setDefaultFocus] = useState<boolean>(false);
|
||||
|
||||
const tabRefs: any = useRef([]);
|
||||
const tabRefs: React.RefObject<HTMLElement[]> = useRef([]);
|
||||
useEffect(() => {
|
||||
if (defaultFocus) {
|
||||
//@ts-ignore
|
||||
tabRefs.current[active]?.focus();
|
||||
} else {
|
||||
setDefaultFocus(true);
|
||||
@@ -21,7 +22,7 @@ const Tabs = ({ children }: any) => {
|
||||
(match: RegExpMatchArray) => ({ name: match[1], children: match[0] })
|
||||
);
|
||||
|
||||
const handleKeyDown = (event: any, index: number) => {
|
||||
const handleKeyDown = (event: React.KeyboardEvent<EventTarget>, index: number) => {
|
||||
if (event.key === "Enter" || event.key === " ") {
|
||||
setActive(index);
|
||||
} else if (event.key === "ArrowRight") {
|
||||
@@ -34,7 +35,7 @@ const Tabs = ({ children }: any) => {
|
||||
return (
|
||||
<div className="tab">
|
||||
<ul className="tab-nav">
|
||||
{tabLinks.map((item: any, index: number) => (
|
||||
{tabLinks.map((item: {name: string, children: string}, index: number) => (
|
||||
<li
|
||||
key={index}
|
||||
className={`tab-nav-item ${index === active && "active"}`}
|
||||
@@ -42,15 +43,16 @@ const Tabs = ({ children }: any) => {
|
||||
tabIndex={index === active ? 0 : -1}
|
||||
onKeyDown={(event) => handleKeyDown(event, index)}
|
||||
onClick={() => setActive(index)}
|
||||
//@ts-ignore
|
||||
ref={(ref) => (tabRefs.current[index] = ref)}
|
||||
>
|
||||
{item.name}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{tabLinks.map((item, i) => (
|
||||
{tabLinks.map((item: {name: string, children: string}, i: number) => (
|
||||
<div
|
||||
className={active === i ? "tab-content block px-5" : "hidden"}
|
||||
className={active === i ? "tab-content block px-5" : "hidden"} key={i}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: marked.parseInline(item.children),
|
||||
}}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { slugify } from "./utils/textConverter";
|
||||
export const getTaxonomy = async (collection: string, name: string) => {
|
||||
const singlePages = await getSinglePage(collection);
|
||||
const taxonomyPages = singlePages.map((page) => page.data[name]);
|
||||
let taxonomies = [];
|
||||
let taxonomies: string[] = [];
|
||||
for (let i = 0; i < taxonomyPages.length; i++) {
|
||||
const categoryArray = taxonomyPages[i];
|
||||
for (let j = 0; j < categoryArray.length; j++) {
|
||||
@@ -20,7 +20,7 @@ export const getTaxonomy = async (collection: string, name: string) => {
|
||||
export const getAllTaxonomy = async (collection: string, name: string) => {
|
||||
const singlePages = await getSinglePage(collection);
|
||||
const taxonomyPages = singlePages.map((page) => page.data[name]);
|
||||
let taxonomies = [];
|
||||
let taxonomies: string[] = [];
|
||||
for (let i = 0; i < taxonomyPages.length; i++) {
|
||||
const categoryArray = taxonomyPages[i];
|
||||
for (let j = 0; j < categoryArray.length; j++) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { formatInTimeZone } from "date-fns-tz";
|
||||
|
||||
const dateFormat = (date:Date | string, format:string = "dd MMM, yyyy") => {
|
||||
const dateFormat = (date:Date | string, format:string = "dd MMM, yyyy"): string => {
|
||||
return formatInTimeZone(date, "America/New_York", format);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// content reading
|
||||
const readingTime = (content: string) => {
|
||||
const readingTime = (content: string): string => {
|
||||
const WPS = 275 / 60;
|
||||
|
||||
let images = 0;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// similer products
|
||||
const similerItems = (currentItem: any, allItems: any, slug: string) => {
|
||||
let categories: [] = [];
|
||||
let tags: [] = [];
|
||||
let categories: string[] = [];
|
||||
let tags: string[] = [];
|
||||
|
||||
// set categories
|
||||
if (currentItem.data.categories.length > 0) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { slugify } from "@/lib/utils/textConverter";
|
||||
|
||||
const taxonomyFilter = (posts: any[], name: string, key: any) =>
|
||||
const taxonomyFilter = (posts: any[], name: string, key: string) =>
|
||||
posts.filter((post) =>
|
||||
post.data[name].map((name: string) => slugify(name)).includes(key)
|
||||
);
|
||||
|
||||
@@ -7,22 +7,18 @@ marked.use({
|
||||
});
|
||||
|
||||
// slugify
|
||||
export const slugify = (content: string) => {
|
||||
if (!content) return null;
|
||||
export const slugify = (content: string): string => {
|
||||
|
||||
return slug(content);
|
||||
};
|
||||
|
||||
// markdownify
|
||||
export const markdownify = (content: string, div?:boolean) => {
|
||||
if (!content) return null;
|
||||
|
||||
export const markdownify = (content: string, div?:boolean): string => {
|
||||
return div? marked.parse(content) : marked.parseInline(content);
|
||||
};
|
||||
|
||||
// humanize
|
||||
export const humanize = (content: string) => {
|
||||
if (!content) return null;
|
||||
export const humanize = (content: string): string => {
|
||||
|
||||
return content
|
||||
.replace(/^[\s_]+|[\s_]+$/g, "")
|
||||
@@ -33,9 +29,7 @@ export const humanize = (content: string) => {
|
||||
};
|
||||
|
||||
// plainify
|
||||
export const plainify = (content: string) => {
|
||||
if (!content) return null;
|
||||
|
||||
export const plainify = (content: string): string => {
|
||||
const filterBrackets = content.replace(/<\/?[^>]+(>|$)/gm, "");
|
||||
const filterSpaces = filterBrackets.replace(/[\r\n]\s*[\r\n]/gm, "");
|
||||
const stripHTML = htmlEntityDecoder(filterSpaces);
|
||||
|
||||
@@ -3,7 +3,7 @@ import Base from "@/layouts/Base.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
export async function getStaticPaths(): Promise<{params: {regular: string}}[]> {
|
||||
const pages = await getSinglePage("pages");
|
||||
|
||||
const paths = pages.map((page) => ({
|
||||
|
||||
@@ -6,8 +6,9 @@ import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { slugify } from "@/lib/utils/textConverter";
|
||||
import type { Blog_folder } from "types";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
export async function getStaticPaths(): Promise<{params: {single: string}, props: {author: string}}[]> {
|
||||
const authors = await getSinglePage("authors");
|
||||
|
||||
const paths = authors.map((author) => ({
|
||||
@@ -19,7 +20,7 @@ export async function getStaticPaths() {
|
||||
return paths;
|
||||
}
|
||||
|
||||
const { blog_folder } = config.settings;
|
||||
const { blog_folder }: Blog_folder = config.settings;
|
||||
const { author } = Astro.props;
|
||||
const { title, social, meta_title, description, image } = author.data;
|
||||
const { Content } = await author.render();
|
||||
|
||||
@@ -7,7 +7,7 @@ import { getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import taxonomyFilter from "@/lib/utils/taxonomyFilter";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
export async function getStaticPaths(): Promise<{params: {category: string}}[]> {
|
||||
const categories = await getTaxonomy(
|
||||
config.settings.blog_folder,
|
||||
"categories"
|
||||
@@ -22,7 +22,7 @@ export async function getStaticPaths() {
|
||||
|
||||
const { category } = Astro.params;
|
||||
const posts = await getSinglePage(config.settings.blog_folder);
|
||||
const filterByCategories = taxonomyFilter(posts, "categories", category);
|
||||
const filterByCategories = taxonomyFilter(posts, "categories", category!);
|
||||
---
|
||||
|
||||
<Base title={category}>
|
||||
|
||||
@@ -4,8 +4,9 @@ import Base from "@/layouts/Base.astro";
|
||||
import { getAllTaxonomy, getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import { humanize } from "@/lib/utils/textConverter";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import type { Blog_folder } from "types";
|
||||
|
||||
const { blog_folder } = config.settings;
|
||||
const { blog_folder }: Blog_folder = config.settings;
|
||||
const categories = await getTaxonomy(blog_folder, "categories");
|
||||
const allCategories = await getAllTaxonomy(blog_folder, "categories");
|
||||
---
|
||||
@@ -16,7 +17,7 @@ const allCategories = await getAllTaxonomy(blog_folder, "categories");
|
||||
<div class="container text-center">
|
||||
<ul>
|
||||
{
|
||||
categories.map((category: any) => {
|
||||
categories.map((category: string) => {
|
||||
const count = allCategories.filter((c) => c === category).length;
|
||||
return (
|
||||
<li class="m-3 inline-block">
|
||||
|
||||
@@ -5,7 +5,7 @@ import PageHeader from "@/partials/PageHeader.astro";
|
||||
import { getEntryBySlug } from "astro:content";
|
||||
|
||||
const entry = await getEntryBySlug("pages", "contact");
|
||||
const { contact_form_action } = config.params;
|
||||
const { contact_form_action }: {contact_form_action: string} = config.params;
|
||||
const { title, description, meta_title, image } = entry.data;
|
||||
---
|
||||
|
||||
|
||||
+13
-8
@@ -6,11 +6,22 @@ import Testimonial from "@/partials/Testimonial.astro";
|
||||
import { Image } from "@astrojs/image/components";
|
||||
import { getEntryBySlug } from "astro:content";
|
||||
import { FaCheck } from "react-icons/fa/index.js";
|
||||
import type { Button, Feature } from "types";
|
||||
|
||||
interface Homepage {
|
||||
banner: {
|
||||
title: string
|
||||
content: string,
|
||||
image: string,
|
||||
button: Button,
|
||||
}
|
||||
features: Feature[]
|
||||
}
|
||||
|
||||
const homepage = await getEntryBySlug("homepage", "index");
|
||||
const testimonial = await getEntryBySlug("sections", "testimonial");
|
||||
const call_to_action = await getEntryBySlug("sections", "call-to-action");
|
||||
const { banner, features } = homepage.data;
|
||||
const { banner, features }: Homepage = homepage.data;
|
||||
---
|
||||
|
||||
<Base>
|
||||
@@ -50,13 +61,7 @@ const { banner, features } = homepage.data;
|
||||
{
|
||||
features.map(
|
||||
(
|
||||
feature: {
|
||||
button: any;
|
||||
image: string;
|
||||
bulletpoints: any;
|
||||
content: string;
|
||||
title: string;
|
||||
},
|
||||
feature,
|
||||
index: number
|
||||
) => (
|
||||
<section class={`section-sm ${index % 2 === 0 && "bg-gradient"}`}>
|
||||
|
||||
@@ -4,7 +4,7 @@ import Base from "@/layouts/Base.astro";
|
||||
import PostSingle from "@/layouts/PostSingle.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
export async function getStaticPaths(): Promise<{params: {single: string}, props: {post: any}}[]> {
|
||||
const posts = await getSinglePage(config.settings.blog_folder);
|
||||
|
||||
const paths = posts.map((post) => ({
|
||||
|
||||
@@ -17,7 +17,7 @@ const allCategories = await getAllTaxonomy(blog_folder, "categories");
|
||||
const categories = await getTaxonomy(blog_folder, "categories");
|
||||
const tags = await getTaxonomy(blog_folder, "tags");
|
||||
const sortedPosts = sortByDate(posts);
|
||||
const totalPages = Math.ceil(posts.length / config.settings.pagination);
|
||||
const totalPages: number = Math.ceil(posts.length / config.settings.pagination);
|
||||
const currentPosts = sortedPosts.slice(0, config.settings.pagination);
|
||||
---
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ export async function getStaticPaths() {
|
||||
|
||||
const { tag } = Astro.params;
|
||||
const posts = await getSinglePage(config.settings.blog_folder);
|
||||
const filterByCategories = taxonomyFilter(posts, "tags", tag);
|
||||
const filterByCategories = taxonomyFilter(posts, "tags", tag!);
|
||||
---
|
||||
|
||||
<Base title={tag}>
|
||||
|
||||
@@ -4,8 +4,9 @@ import Base from "@/layouts/Base.astro";
|
||||
import { getAllTaxonomy, getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import { humanize } from "@/lib/utils/textConverter";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import type { Blog_folder } from "types";
|
||||
|
||||
const { blog_folder } = config.settings;
|
||||
const { blog_folder }: Blog_folder = config.settings;
|
||||
const tags = await getTaxonomy(blog_folder, "tags");
|
||||
const allTags = await getAllTaxonomy(blog_folder, "tags");
|
||||
---
|
||||
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
export type Feature = {
|
||||
button: button
|
||||
image: string
|
||||
bulletpoints: string[]
|
||||
content: string
|
||||
title: string
|
||||
}
|
||||
|
||||
export type Button = {
|
||||
enable: boolean
|
||||
label: string
|
||||
link: string
|
||||
}
|
||||
|
||||
export type Blog_folder = {blog_folder: string};
|
||||
Reference in New Issue
Block a user