mirror of
https://github.com/JustAnimeCore/JustAnime.git
synced 2026-04-18 06:11:45 +00:00
seo
This commit is contained in:
@@ -5,6 +5,13 @@ import CategoryCard from "@/src/components/categorycard/CategoryCard";
|
||||
import Loader from "@/src/components/Loader/Loader";
|
||||
import Error from "@/src/components/error/Error";
|
||||
import PageSlider from "@/src/components/pageslider/PageSlider";
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import {
|
||||
generateAZListMeta,
|
||||
generatePaginationLinks,
|
||||
generateCanonicalUrl,
|
||||
generateCollectionSchema
|
||||
} from "@/src/utils/seo.utils";
|
||||
|
||||
function AtoZ({ path }) {
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
@@ -44,67 +51,98 @@ function AtoZ({ path }) {
|
||||
setSearchParams({ page: newPage });
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="max-w-[1600px] mx-auto flex flex-col mt-[64px] max-md:mt-[50px]">
|
||||
<div className="flex flex-col gap-y-2 max-[478px]:gap-y-0 mt-6">
|
||||
<h1 className="font-bold text-2xl text-white max-[478px]:text-[18px]">
|
||||
Sort By Letters
|
||||
</h1>
|
||||
<div className="flex gap-x-[7px] flex-wrap justify-start gap-y-2 max-md:justify-start">
|
||||
{[
|
||||
"All",
|
||||
"#",
|
||||
"0-9",
|
||||
...Array.from({ length: 26 }, (_, i) =>
|
||||
String.fromCharCode(65 + i)
|
||||
),
|
||||
].map((item, index) => {
|
||||
const linkPath =
|
||||
item.toLowerCase() === "all"
|
||||
? ""
|
||||
: item === "#"
|
||||
? "other"
|
||||
: item;
|
||||
const isActive =
|
||||
(currentLetter === "az-list" && item.toLowerCase() === "all") ||
|
||||
(currentLetter === "other" && item === "#") ||
|
||||
currentLetter === item.toLowerCase();
|
||||
const { title, description, keywords } = generateAZListMeta(currentLetter, page);
|
||||
const canonicalUrl = generateCanonicalUrl(`/az-list/${currentLetter === 'az-list' ? '' : currentLetter}${page > 1 ? `?page=${page}` : ''}`);
|
||||
const paginationLinks = generatePaginationLinks(`/az-list/${currentLetter}`, page, totalPages);
|
||||
const collectionSchema = generateCollectionSchema(categoryInfo, `Anime starting with ${currentLetter}`, `az-list/${currentLetter}`);
|
||||
|
||||
return (
|
||||
<Link
|
||||
to={`/az-list/${linkPath}`}
|
||||
key={index}
|
||||
className={`text-md bg-[#373646] py-1 px-4 rounded-md font-bold hover:text-black hover:bg-white hover:cursor-pointer transition-all ease-out ${
|
||||
isActive ? "text-black bg-white" : ""
|
||||
}`}
|
||||
>
|
||||
{item}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>{title}</title>
|
||||
<meta name="description" content={description} />
|
||||
<meta name="keywords" content={keywords} />
|
||||
<link rel="canonical" href={canonicalUrl} />
|
||||
|
||||
{paginationLinks.map((link, index) => (
|
||||
<link key={index} rel={link.rel} href={link.href} />
|
||||
))}
|
||||
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:url" content={canonicalUrl} />
|
||||
<meta property="og:type" content="website" />
|
||||
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:title" content={title} />
|
||||
<meta name="twitter:description" content={description} />
|
||||
|
||||
{collectionSchema && (
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify(collectionSchema)}
|
||||
</script>
|
||||
)}
|
||||
</Helmet>
|
||||
<div className="max-w-[1600px] mx-auto flex flex-col mt-[64px] max-md:mt-[50px]">
|
||||
<div className="flex flex-col gap-y-2 max-[478px]:gap-y-0 mt-6">
|
||||
<h1 className="font-bold text-2xl text-white max-[478px]:text-[18px]">
|
||||
Sort By Letters
|
||||
</h1>
|
||||
<div className="flex gap-x-[7px] flex-wrap justify-start gap-y-2 max-md:justify-start">
|
||||
{[
|
||||
"All",
|
||||
"#",
|
||||
"0-9",
|
||||
...Array.from({ length: 26 }, (_, i) =>
|
||||
String.fromCharCode(65 + i)
|
||||
),
|
||||
].map((item, index) => {
|
||||
const linkPath =
|
||||
item.toLowerCase() === "all"
|
||||
? ""
|
||||
: item === "#"
|
||||
? "other"
|
||||
: item;
|
||||
const isActive =
|
||||
(currentLetter === "az-list" && item.toLowerCase() === "all") ||
|
||||
(currentLetter === "other" && item === "#") ||
|
||||
currentLetter === item.toLowerCase();
|
||||
|
||||
return (
|
||||
<Link
|
||||
to={`/az-list/${linkPath}`}
|
||||
key={index}
|
||||
className={`text-md bg-[#373646] py-1 px-4 rounded-md font-bold hover:text-black hover:bg-white hover:cursor-pointer transition-all ease-out ${isActive ? "text-black bg-white" : ""
|
||||
}`}
|
||||
>
|
||||
{item}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full flex flex-col gap-y-8">
|
||||
<div>
|
||||
{categoryInfo && categoryInfo.length > 0 && (
|
||||
<CategoryCard
|
||||
data={categoryInfo}
|
||||
limit={categoryInfo.length}
|
||||
showViewMore={false}
|
||||
className="mt-8"
|
||||
cardStyle="grid-cols-8 max-[1600px]:grid-cols-6 max-[1200px]:grid-cols-4 max-[758px]:grid-cols-3 max-[478px]:grid-cols-3 max-[478px]:gap-x-2"
|
||||
/>
|
||||
)}
|
||||
<div className="flex justify-center w-full mt-8">
|
||||
<PageSlider
|
||||
page={page}
|
||||
totalPages={totalPages}
|
||||
handlePageChange={handlePageChange}
|
||||
/>
|
||||
<div className="w-full flex flex-col gap-y-8">
|
||||
<div>
|
||||
{categoryInfo && categoryInfo.length > 0 && (
|
||||
<CategoryCard
|
||||
data={categoryInfo}
|
||||
limit={categoryInfo.length}
|
||||
showViewMore={false}
|
||||
className="mt-8"
|
||||
cardStyle="grid-cols-8 max-[1600px]:grid-cols-6 max-[1200px]:grid-cols-4 max-[758px]:grid-cols-3 max-[478px]:grid-cols-3 max-[478px]:gap-x-2"
|
||||
/>
|
||||
)}
|
||||
<div className="flex justify-center w-full mt-8">
|
||||
<PageSlider
|
||||
page={page}
|
||||
totalPages={totalPages}
|
||||
handlePageChange={handlePageChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user