initialize project

This commit is contained in:
somrat sorkar
2023-04-17 12:50:29 +06:00
commit 8badd3f3e7
106 changed files with 4564 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
---
import { Image } from "@astrojs/image/components";
import { plainify } from "@lib/utils/textConverter";
import Social from "./Social.astro";
const { data } = Astro.props;
const { title, image, social } = data.data;
---
<div
class="rounded bg-theme-light p-8 text-center dark:bg-darkmode-theme-light"
>
{
image && (
<Image
class="mx-auto mb-6 rounded"
src={image}
alt={title}
width={120}
height={120}
/>
)
}
<h4 class="mb-3">
<a href={`/authors/${data.slug}`}>{title}</a>
</h4>
<p class="mb-4">
{plainify(data.body?.slice(0, 100))}
</p>
<Social source={social} className="social-icons" />
</div>
+55
View File
@@ -0,0 +1,55 @@
---
import { Image } from "@astrojs/image/components";
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 { data } = Astro.props;
const { title, image, date, author, categories } = data.data;
---
<div class="bg-body dark:bg-darkmode-body">
{
image && (
<Image
class="mb-6 w-full rounded"
src={image}
alt={title}
width={445}
height={230}
/>
)
}
<h4 class="mb-3">
<a href={`/${blog_folder}/${data.slug}`}>
{title}
</a>
</h4>
<ul class="mb-4">
<li class="mr-4 inline-block">
<a href={`/authors/${slugify(author)}`}>
<FaRegUserCircle className={"mr-2 -mt-1 inline-block"} />
{humanize(author)}
</a>
</li>
<li class="mr-4 inline-block">
<FaRegFolder className={"mr-2 -mt-1 inline-block"} />
{
categories.map((category: string, index: number) => (
<a href={`/categories/${slugify(category)}`}>
{humanize(category)}
{index !== categories.length - 1 && ","}
</a>
))
}
</li>
</ul>
<p class="mb-6">{plainify(data.body?.slice(0, Number(summary_length)))}</p>
<a
class="btn btn-outline-primary btn-sm"
href={`/${blog_folder}/${data.slug}`}
>
read more
</a>
</div>
+43
View File
@@ -0,0 +1,43 @@
---
import { humanize } from "@lib/utils/textConverter";
const { className } = Astro.props;
const paths = Astro.url.pathname.split("/").filter((x) => x);
let parts = [
{
label: "Home",
href: "/",
"aria-label": Astro.url.pathname === "/" ? "page" : undefined,
},
];
paths.forEach((label: string, i: number) => {
const href = `/${paths.slice(0, i + 1).join("/")}`;
label !== "page" &&
parts.push({
label: humanize(label.replace(/[-_]/g, " ")) || "",
href,
"aria-label": Astro.url.pathname === href ? "page" : undefined,
});
});
---
<nav aria-label="Breadcrumb" class={className}>
<ol class="inline-flex" role="list">
{
parts.map(({ label, ...attrs }, index) => (
<li class="mx-1 capitalize" role="listitem">
{index > 0 && <span class="inlin-block mr-1">/</span>}
{index !== parts.length - 1 ? (
<a class="text-primary dark:text-darkmode-primary" {...attrs}>
{label}
</a>
) : (
<span class="text-light dark:text-darkmode-light">{label}</span>
)}
</li>
))
}
</ol>
</nav>
+64
View File
@@ -0,0 +1,64 @@
---
import { Image } from "@astrojs/image/components";
import config from "@config/config.json";
const { src, srcDarkmode } = Astro.props;
const {
logo,
logo_darkmode,
logo_width,
logo_height,
logo_text,
title,
}: {
logo: string;
logo_darkmode: string;
logo_width: any;
logo_height: any;
logo_text: string;
title: string;
} = config.site;
const { theme_switcher }: { theme_switcher: boolean } = config.settings;
---
<a href="/" class="navbar-brand inline-block">
{
src || srcDarkmode || logo || logo_darkmode ? (
<>
<Image
src={src ? src : logo}
class={`${theme_switcher && "dark:hidden"}`}
width={logo_width.replace("px", "") * 2}
height={logo_height.replace("px", "") * 2}
alt={title}
fit={"contain"}
background={"rgba(0,0,0,0)"}
style={{
height: logo_height.replace("px", "") + "px",
width: logo_width.replace("px", "") + "px",
}}
/>
{theme_switcher && (
<Image
src={srcDarkmode ? srcDarkmode : logo_darkmode}
class={"hidden dark:inline-block"}
width={logo_width.replace("px", "") * 2}
height={logo_height.replace("px", "") * 2}
alt={title}
fit={"contain"}
background={"rgba(0,0,0,0)"}
style={{
height: logo_height.replace("px", "") + "px",
width: logo_width.replace("px", "") + "px",
}}
/>
)}
</>
) : logo_text ? (
logo_text
) : (
title
)
}
</a>
+129
View File
@@ -0,0 +1,129 @@
---
const { section, currentPage, totalPages } = Astro.props;
const indexPageLink = currentPage === 2;
const hasPrevPage = currentPage > 1;
const hasNextPage = totalPages > currentPage;
let pageList = [];
for (let i = 1; i <= totalPages; i++) {
pageList.push(i);
}
---
{
totalPages > 1 && (
<nav
class="flex items-center justify-center space-x-3"
aria-label="Pagination"
>
{/* previous */}
{hasPrevPage ? (
<a
href={
indexPageLink
? `${section ? "/" + section : "/"}`
: `${section ? "/" + section : ""}/page/${currentPage - 1}`
}
class="rounded px-2 py-1.5 text-dark hover:bg-theme-light dark:text-darkmode-dark dark:hover:bg-darkmode-theme-light"
>
<span class="sr-only">Previous</span>
<svg
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
height="30"
width="30"
>
<path
fill-rule="evenodd"
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
clip-rule="evenodd"
/>
</svg>
</a>
) : (
<span class="rounded px-2 py-1.5 text-light">
<span class="sr-only">Previous</span>
<svg
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
height="30"
width="30"
>
<path
fill-rule="evenodd"
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
clip-rule="evenodd"
/>
</svg>
</span>
)}
{/* page index */}
{pageList.map((pagination, i) =>
pagination === currentPage ? (
<span
aria-current="page"
class="rounded bg-primary px-4 py-2 text-white dark:bg-darkmode-primary dark:text-dark"
>
{pagination}
</span>
) : (
<a
href={
i === 0
? `${section ? "/" + section : "/"}`
: `${section ? "/" + section : ""}/page/${pagination}`
}
aria-current="page"
class="rounded px-4 py-2 text-dark hover:bg-theme-light dark:text-darkmode-dark dark:hover:bg-darkmode-theme-light"
>
{pagination}
</a>
)
)}
{/* next page */}
{hasNextPage ? (
<a
href={`${section ? "/" + section : ""}/page/${currentPage + 1}`}
class="rounded px-2 py-1.5 text-dark hover:bg-theme-light dark:text-darkmode-dark dark:hover:bg-darkmode-theme-light"
>
<span class="sr-only">Next</span>
<svg
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
height="30"
width="30"
>
<path
fill-rule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd"
/>
</svg>
</a>
) : (
<span class="rounded px-2 py-1.5 text-light">
<span class="sr-only">Next</span>
<svg
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
height="30"
width="30"
>
<path
fill-rule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd"
/>
</svg>
</span>
)}
</nav>
)
}
+55
View File
@@ -0,0 +1,55 @@
---
import config from "@config/config.json";
import {
IoLogoFacebook,
IoLogoLinkedin,
IoLogoPinterest,
IoLogoTwitter,
} from "react-icons/io5/index.js";
const { base_url } = config.site;
const { title, description, slug, className } = Astro.props;
---
<ul class={`${className}`}>
<li class="inline-block">
<a
aria-label="facebook share button"
href={`https://facebook.com/sharer/sharer.php?u=${base_url}/${slug}`}
target="_blank"
rel="noreferrer noopener"
>
<IoLogoFacebook />
</a>
</li>
<li class="inline-block">
<a
aria-label="twitter share button"
href={`https://twitter.com/intent/tweet/?text=${title}&amp;url=${base_url}/${slug}`}
target="_blank"
rel="noreferrer noopener"
>
<IoLogoTwitter />
</a>
</li>
<li class="inline-block">
<a
aria-label="linkedin share button"
href={`https://www.linkedin.com/shareArticle?mini=true&url=${base_url}/${slug}&title=${title}&summary=${description}&source=${base_url}`}
target="_blank"
rel="noreferrer noopener"
>
<IoLogoLinkedin />
</a>
</li>
<li class="inline-block">
<a
aria-label="pinterest share button"
href={`https://pinterest.com/pin/create/button/?url=${base_url}/${slug}&media=&description=${description}`}
target="_blank"
rel="noreferrer noopener"
>
<IoLogoPinterest />
</a>
</li>
</ul>
+498
View File
@@ -0,0 +1,498 @@
---
const { source, className } = Astro.props;
import {
IoCall,
IoGlobeOutline,
IoLocation,
IoLogoBehance,
IoLogoBitbucket,
IoLogoCodepen,
IoLogoDiscord,
IoLogoDribbble,
IoLogoFacebook,
IoLogoFoursquare,
IoLogoGithub,
IoLogoGitlab,
IoLogoInstagram,
IoLogoLinkedin,
IoLogoMastodon,
IoLogoMedium,
IoLogoPinterest,
IoLogoReddit,
IoLogoRss,
IoLogoSkype,
IoLogoSlack,
IoLogoSnapchat,
IoLogoSoundcloud,
IoLogoTiktok,
IoLogoTumblr,
IoLogoTwitter,
IoLogoVimeo,
IoLogoVk,
IoLogoWhatsapp,
IoLogoYoutube,
IoMail,
} from "react-icons/io5/index.js";
const {
facebook,
twitter,
mastodon,
instagram,
youtube,
linkedin,
github,
gitlab,
discord,
slack,
medium,
codepen,
bitbucket,
dribbble,
behance,
pinterest,
soundcloud,
tumblr,
reddit,
vk,
whatsapp,
snapchat,
vimeo,
tiktok,
foursquare,
rss,
email,
phone,
address,
skype,
website,
} = source;
---
<ul class={className}>
{
facebook && (
<li class="inline-block">
<a
aria-label="facebook"
href={facebook}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoFacebook />
</a>
</li>
)
}
{
twitter && (
<li class="inline-block">
<a
aria-label="twitter"
href={twitter}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoTwitter />
</a>
</li>
)
}
{
mastodon && (
<li class="inline-block">
<a
aria-label="mastodon"
href={mastodon}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoMastodon />
</a>
</li>
)
}
{
instagram && (
<li class="inline-block">
<a
aria-label="instagram"
href={instagram}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoInstagram />
</a>
</li>
)
}
{
youtube && (
<li class="inline-block">
<a
aria-label="youtube"
href={youtube}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoYoutube />
</a>
</li>
)
}
{
linkedin && (
<li class="inline-block">
<a
aria-label="linkedin"
href={linkedin}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoLinkedin />
</a>
</li>
)
}
{
github && (
<li class="inline-block">
<a
aria-label="github"
href={github}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoGithub />
</a>
</li>
)
}
{
gitlab && (
<li class="inline-block">
<a
aria-label="gitlab"
href={gitlab}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoGitlab />
</a>
</li>
)
}
{
discord && (
<li class="inline-block">
<a
aria-label="discord"
href={discord}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoDiscord />
</a>
</li>
)
}
{
slack && (
<li class="inline-block">
<a
aria-label="slack"
href={slack}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoSlack />
</a>
</li>
)
}
{
medium && (
<li class="inline-block">
<a
aria-label="medium"
href={medium}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoMedium />
</a>
</li>
)
}
{
codepen && (
<li class="inline-block">
<a
aria-label="codepen"
href={codepen}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoCodepen />
</a>
</li>
)
}
{
bitbucket && (
<li class="inline-block">
<a
aria-label="bitbucket"
href={bitbucket}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoBitbucket />
</a>
</li>
)
}
{
dribbble && (
<li class="inline-block">
<a
aria-label="dribbble"
href={dribbble}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoDribbble />
</a>
</li>
)
}
{
behance && (
<li class="inline-block">
<a
aria-label="behance"
href={behance}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoBehance />
</a>
</li>
)
}
{
pinterest && (
<li class="inline-block">
<a
aria-label="pinterest"
href={pinterest}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoPinterest />
</a>
</li>
)
}
{
soundcloud && (
<li class="inline-block">
<a
aria-label="soundcloud"
href={soundcloud}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoSoundcloud />
</a>
</li>
)
}
{
tumblr && (
<li class="inline-block">
<a
aria-label="tumblr"
href={tumblr}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoTumblr />
</a>
</li>
)
}
{
reddit && (
<li class="inline-block">
<a
aria-label="reddit"
href={reddit}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoReddit />
</a>
</li>
)
}
{
vk && (
<li class="inline-block">
<a
aria-label="vk"
href={vk}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoVk />
</a>
</li>
)
}
{
whatsapp && (
<li class="inline-block">
<a
aria-label="whatsapp"
href={whatsapp}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoWhatsapp />
</a>
</li>
)
}
{
snapchat && (
<li class="inline-block">
<a
aria-label="snapchat"
href={snapchat}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoSnapchat />
</a>
</li>
)
}
{
vimeo && (
<li class="inline-block">
<a
aria-label="vimeo"
href={vimeo}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoVimeo />
</a>
</li>
)
}
{
tiktok && (
<li class="inline-block">
<a
aria-label="tiktok"
href={tiktok}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoTiktok />
</a>
</li>
)
}
{
foursquare && (
<li class="inline-block">
<a
aria-label="foursquare"
href={foursquare}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoFoursquare />
</a>
</li>
)
}
{
skype && (
<li class="inline-block">
<a
aria-label="skype"
href={skype}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoSkype />
</a>
</li>
)
}
{
website && (
<li class="inline-block">
<a
aria-label="website"
href={website}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoGlobeOutline />
</a>
</li>
)
}
{
rss && (
<li class="inline-block">
<a
aria-label="rss feed"
href={rss}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLogoRss />
</a>
</li>
)
}
{
email && (
<li class="inline-block">
<a aria-label="email" href={`mailto:${email}`}>
<IoMail />
</a>
</li>
)
}
{
phone && (
<li class="inline-block">
<a aria-label="telephone" href={`tel:${phone}`}>
<IoCall />
</a>
</li>
)
}
{
address && (
<li class="inline-block">
<a
aria-label="location"
href={address}
target="_blank"
rel="noopener noreferrer nofollow"
>
<IoLocation />
</a>
</li>
)
}
</ul>
+73
View File
@@ -0,0 +1,73 @@
---
import config from "@config/config.json";
const { theme_switcher, default_theme } = config.settings;
const {className} = Astro.props;
---
{
theme_switcher && (
<div class={`theme-switcher ${className}`}>
<input id="theme-switcher" data-theme-switcher type="checkbox" />
<label for="theme-switcher">
<span>
<!-- sun -->
<svg
class="absolute left-[4px] top-[4px] z-10 opacity-100 dark:opacity-0"
viewBox="0 0 56 56"
fill="#fff"
height="16"
width="16"
>
<path
d="M30 4.6c0-1-.9-2-2-2a2 2 0 0 0-2 2v5c0 1 .9 2 2 2s2-1 2-2Zm9.6 9a2 2 0 0 0 0 2.8c.8.8 2 .8 2.9 0L46 13a2 2 0 0 0 0-2.9 2 2 0 0 0-3 0Zm-26 2.8c.7.8 2 .8 2.8 0 .8-.7.8-2 0-2.9L13 10c-.7-.7-2-.8-2.9 0-.7.8-.7 2.1 0 3ZM28 16a12 12 0 0 0-12 12 12 12 0 0 0 12 12 12 12 0 0 0 12-12 12 12 0 0 0-12-12Zm23.3 14c1.1 0 2-.9 2-2s-.9-2-2-2h-4.9a2 2 0 0 0-2 2c0 1.1 1 2 2 2ZM4.7 26a2 2 0 0 0-2 2c0 1.1.9 2 2 2h4.9c1 0 2-.9 2-2s-1-2-2-2Zm37.8 13.6a2 2 0 0 0-3 0 2 2 0 0 0 0 2.9l3.6 3.5a2 2 0 0 0 2.9 0c.8-.8.8-2.1 0-3ZM10 43.1a2 2 0 0 0 0 2.9c.8.7 2.1.8 3 0l3.4-3.5c.8-.8.8-2.1 0-2.9-.8-.8-2-.8-2.9 0Zm20 3.4c0-1.1-.9-2-2-2a2 2 0 0 0-2 2v4.9c0 1 .9 2 2 2s2-1 2-2Z"
></path>
</svg>
<!-- moon -->
<svg
class="absolute left-[4px] top-[4px] z-10 opacity-0 dark:opacity-100"
viewBox="0 0 24 24"
fill="none"
height="16"
width="16"
>
<path
fill="#000"
fill-rule="evenodd"
clip-rule="evenodd"
d="M8.2 2.2c1-.4 2 .6 1.6 1.5-1 3-.4 6.4 1.8 8.7a8.4 8.4 0 0 0 8.7 1.8c1-.3 2 .5 1.5 1.5v.1a10.3 10.3 0 0 1-9.4 6.2A10.3 10.3 0 0 1 3.2 6.7c1-2 2.9-3.5 4.9-4.4Z"
></path>
</svg>
</span>
</label>
</div>
)
}
<script is:inline define:vars={{ defaultTheme: default_theme }}>
var darkMode = defaultTheme === "dark" ? true : false;
var themeSwitch = document.querySelectorAll("[data-theme-switcher]");
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
darkMode = true;
}
if (localStorage.getItem("theme") === "dark") {
darkMode = true;
} else if (localStorage.getItem("theme") === "light") {
darkMode = false;
}
if (darkMode) {
document.documentElement.classList.toggle("dark");
}
document.addEventListener("DOMContentLoaded", () => {
[].forEach.call(themeSwitch, function (ts) {
ts.checked = darkMode ? true : false;
ts.addEventListener("click", () => {
document.documentElement.classList.toggle("dark");
localStorage.setItem(
"theme",
document.documentElement.classList.contains("dark") ? "dark" : "light"
);
});
});
});
</script>
+15
View File
@@ -0,0 +1,15 @@
---
---
{
process.env.NODE_ENV === "development" && (
<div class="fixed top-0 left-0 z-50 flex w-[30px] items-center justify-center bg-gray-200 py-[2.5px] text-[12px] uppercase text-black sm:bg-red-200 md:bg-yellow-200 lg:bg-green-200 xl:bg-blue-200 2xl:bg-pink-200">
<span class="block sm:hidden">all</span>
<span class="hidden sm:block md:hidden">sm</span>
<span class="hidden md:block lg:hidden">md</span>
<span class="hidden lg:block xl:hidden">lg</span>
<span class="hidden xl:block 2xl:hidden">xl</span>
<span class="hidden 2xl:block">2xl</span>
</div>
)
}