mirror of
https://github.com/Radiquum/AniX.git
synced 2025-04-30 18:09:40 +05:00
feat: add collections page
This commit is contained in:
parent
dbe9eba23f
commit
9e843be11f
7 changed files with 338 additions and 0 deletions
12
app/components/AddCollectionLink/AddCollectionLink.tsx
Normal file
12
app/components/AddCollectionLink/AddCollectionLink.tsx
Normal file
|
@ -0,0 +1,12 @@
|
|||
import Link from "next/link";
|
||||
|
||||
export const AddCollectionLink = (props: any) => {
|
||||
return (
|
||||
<Link href={`/collection/create`}>
|
||||
<div className="flex flex-col items-center justify-center w-full gap-2 text-black transition-colors bg-gray-100 border hover:bg-gray-200 border-gray-50 hover:border-gray-100 dark:border-gray-700 dark:hover:border-gray-600 dark:hover:bg-gray-500 aspect-video group dark:bg-gray-600 dark:text-white">
|
||||
<span className="w-8 h-8 iconify mdi--plus-circle dark:fill-white"></span>
|
||||
<p>Новая коллекция</p>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,15 @@
|
|||
.swiper-button:global(.swiper-button-disabled) {
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
||||
.section .swiper-button {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.section:hover .swiper-button {
|
||||
display: flex !important;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
}
|
97
app/components/CollectionCourusel/CollectionCourusel.tsx
Normal file
97
app/components/CollectionCourusel/CollectionCourusel.tsx
Normal file
|
@ -0,0 +1,97 @@
|
|||
"use client";
|
||||
import { useEffect } from "react";
|
||||
import { CollectionLink } from "../CollectionLink/CollectionLink";
|
||||
import { AddCollectionLink } from "../AddCollectionLink/AddCollectionLink";
|
||||
import Link from "next/link";
|
||||
|
||||
import Styles from "./CollectionCourusel.module.css";
|
||||
import Swiper from "swiper";
|
||||
import "swiper/css";
|
||||
import "swiper/css/navigation";
|
||||
import { Navigation } from "swiper/modules";
|
||||
|
||||
export const CollectionCourusel = (props: {
|
||||
sectionTitle: string;
|
||||
showAllLink?: string;
|
||||
content: any;
|
||||
isMyCollections?: boolean;
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
const options: any = {
|
||||
direction: "horizontal",
|
||||
spaceBetween: 8,
|
||||
allowTouchMove: true,
|
||||
slidesPerView: "auto",
|
||||
navigation: {
|
||||
enabled: false,
|
||||
nextEl: ".swiper-button-next",
|
||||
prevEl: ".swiper-button-prev",
|
||||
},
|
||||
breakpoints: {
|
||||
450: {
|
||||
navigation: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
modules: [Navigation],
|
||||
};
|
||||
new Swiper(".swiper", options);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<section className={`${Styles.section}`}>
|
||||
<div className="flex justify-between px-4 py-2 border-b-2 border-black dark:border-white">
|
||||
<h1 className="font-bold text-md sm:text-xl md:text-lg xl:text-xl">
|
||||
{props.sectionTitle}
|
||||
</h1>
|
||||
{props.showAllLink && (
|
||||
<Link href={props.showAllLink}>
|
||||
<div className="flex items-center">
|
||||
<p className="hidden text-xl font-bold sm:block">Показать все</p>
|
||||
<span className="w-6 h-6 iconify mdi--arrow-right"></span>
|
||||
</div>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
<div className="m-4">
|
||||
<div className="swiper">
|
||||
<div className="swiper-wrapper">
|
||||
{props.content.map((collection) => {
|
||||
return (
|
||||
<div
|
||||
className="swiper-slide"
|
||||
key={collection.id}
|
||||
style={{ width: "fit-content" }}
|
||||
>
|
||||
<div className="xl:w-[600px] sm:w-[400px] w-[80vw] aspect-video">
|
||||
<CollectionLink {...collection} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{props.isMyCollections && (
|
||||
<div className="swiper-slide" style={{ width: "fit-content" }}>
|
||||
<div className="xl:w-[600px] sm:w-[400px] w-[80vw] aspect-video">
|
||||
<AddCollectionLink />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={`swiper-button-prev ${Styles["swiper-button"]} after:iconify after:material-symbols--chevron-left aspect-square bg-black bg-opacity-25 backdrop-blur rounded-full after:bg-white`}
|
||||
style={
|
||||
{ "--swiper-navigation-size": "64px" } as React.CSSProperties
|
||||
}
|
||||
></div>
|
||||
<div
|
||||
className={`swiper-button-next ${Styles["swiper-button"]} after:iconify after:material-symbols--chevron-right aspect-square bg-black bg-opacity-25 backdrop-blur rounded-full after:bg-white`}
|
||||
style={
|
||||
{ "--swiper-navigation-size": "64px" } as React.CSSProperties
|
||||
}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
95
app/components/CollectionLink/CollectionLink.tsx
Normal file
95
app/components/CollectionLink/CollectionLink.tsx
Normal file
|
@ -0,0 +1,95 @@
|
|||
import Link from "next/link";
|
||||
import { sinceUnixDate } from "#/api/utils";
|
||||
import { Chip } from "#/components/Chip/Chip";
|
||||
|
||||
const profile_lists = {
|
||||
// 0: "Не смотрю",
|
||||
1: { name: "Смотрю", bg_color: "bg-green-500" },
|
||||
2: { name: "В планах", bg_color: "bg-purple-500" },
|
||||
3: { name: "Просмотрено", bg_color: "bg-blue-500" },
|
||||
4: { name: "Отложено", bg_color: "bg-yellow-500" },
|
||||
5: { name: "Брошено", bg_color: "bg-red-500" },
|
||||
};
|
||||
|
||||
export const CollectionLink = (props: any) => {
|
||||
const grade = props.grade.toFixed(1);
|
||||
const profile_list_status = props.profile_list_status;
|
||||
let user_list = null;
|
||||
if (profile_list_status != null || profile_list_status != 0) {
|
||||
user_list = profile_lists[profile_list_status];
|
||||
}
|
||||
return (
|
||||
<Link href={`/release/${props.id}`}>
|
||||
<div className="w-full aspect-video group">
|
||||
<div className="relative w-full h-full overflow-hidden bg-center bg-no-repeat bg-cover rounded-sm group-hover:animate-bg_zoom animate-bg_zoom_rev group-hover:[background-size:110%] " style={{
|
||||
backgroundImage: `linear-gradient(to bottom, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.9) 100%), url(${props.image})`,
|
||||
}}>
|
||||
<div className="absolute flex flex-wrap items-start justify-start gap-0.5 sm:gap-1 left-2 top-2">
|
||||
<Chip
|
||||
bg_color={
|
||||
grade == 0
|
||||
? "hidden"
|
||||
: grade < 2
|
||||
? "bg-red-500"
|
||||
: grade < 3
|
||||
? "bg-orange-500"
|
||||
: grade < 4
|
||||
? "bg-yellow-500"
|
||||
: "bg-green-500"
|
||||
}
|
||||
name={grade}
|
||||
/>
|
||||
{user_list && (
|
||||
<Chip bg_color={user_list.bg_color} name={user_list.name} />
|
||||
)}
|
||||
{props.status ? (
|
||||
<Chip name={props.status.name} />
|
||||
) : (
|
||||
props.status_id != 0 && (
|
||||
<Chip
|
||||
name={
|
||||
props.status_id == 1
|
||||
? "Завершено"
|
||||
: props.status_id == 2
|
||||
? "Онгоинг"
|
||||
: props.status_id == 3 && "Анонс"
|
||||
}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
<Chip
|
||||
name={props.episodes_released && props.episodes_released}
|
||||
name_2={
|
||||
props.episodes_total ? props.episodes_total + " эп." : "? эп."
|
||||
}
|
||||
devider="/"
|
||||
/>
|
||||
{props.last_view_episode && (
|
||||
<Chip
|
||||
name={
|
||||
props.last_view_episode.name
|
||||
? props.last_view_episode.name
|
||||
: `${props.last_view_episode.position + 1} серия`
|
||||
}
|
||||
name_2={
|
||||
"last_view_timestamp" in props &&
|
||||
sinceUnixDate(props.last_view_timestamp)
|
||||
}
|
||||
devider=", "
|
||||
/>
|
||||
)}
|
||||
{props.category && <Chip name={props.category.name} />}
|
||||
{props.is_favorite && (
|
||||
<div className="flex items-center justify-center bg-pink-500 rounded-sm">
|
||||
<span className="w-3 px-4 py-2.5 text-white sm:px-4 sm:py-3 xl:px-6 xl:py-4 iconify mdi--heart"></span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<p className="absolute text-xs text-white xl:text-base lg:text-lg left-2 bottom-2 right-2">
|
||||
{props.title_ru}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
};
|
|
@ -56,6 +56,15 @@ export const Navbar = () => {
|
|||
},
|
||||
{
|
||||
id: 5,
|
||||
icon: "material-symbols--collections-bookmark-outline",
|
||||
iconActive: "material-symbols--collections-bookmark",
|
||||
title: "Коллекции",
|
||||
href: "/collections",
|
||||
withAuthOnly: true,
|
||||
mobileMenu: true,
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
icon: "material-symbols--history",
|
||||
iconActive: "material-symbols--history",
|
||||
title: "История",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue