calendar and pagination
This commit is contained in:
parent
fa54a83ca8
commit
0b6e6dabb2
|
|
@ -1,21 +1,19 @@
|
|||
// Modules
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { url } from '../../url';
|
||||
import { Api } from '../../api/Api';
|
||||
import { asideParams } from '../../api/params';
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { useState, useEffect } from "react";
|
||||
import { url } from "../../url";
|
||||
import { Api } from "../../api/Api";
|
||||
import { asideParams } from "../../api/params";
|
||||
|
||||
// Components
|
||||
import SectionTitle from '../global/SectionTitle';
|
||||
import AsideNews from './AsideNews';
|
||||
import Calendar from './Calendar';
|
||||
import { IPostsData } from '../../types/data.types';
|
||||
import Loader from '../global/Loader';
|
||||
|
||||
import { dateParse } from '../../helpers/dateParser';
|
||||
import SectionTitle from "../global/SectionTitle";
|
||||
import AsideNews from "./AsideNews";
|
||||
import Calendar from "./Calendar";
|
||||
import { IPostsData } from "../../types/data.types";
|
||||
import Loader from "../global/Loader";
|
||||
|
||||
interface Props {
|
||||
type: 'latest' | 'popular';
|
||||
type: "latest" | "popular";
|
||||
}
|
||||
|
||||
interface IData {
|
||||
|
|
@ -23,7 +21,10 @@ interface IData {
|
|||
}
|
||||
|
||||
const Aside = ({ type }: Props) => {
|
||||
const api = new Api(url + `${type === 'popular' ? '/popular' : ''}/posts`, asideParams);
|
||||
const api = new Api(
|
||||
url + `${type === "popular" ? "/popular" : ""}/posts`,
|
||||
asideParams
|
||||
);
|
||||
const language = api.language;
|
||||
|
||||
const [data, setData] = useState<IData>();
|
||||
|
|
@ -37,25 +38,25 @@ const Aside = ({ type }: Props) => {
|
|||
<div className="aside-wrapper">
|
||||
<SectionTitle
|
||||
title={
|
||||
type === 'latest'
|
||||
type === "latest"
|
||||
? `${
|
||||
language === 'EN'
|
||||
? 'Latest news'
|
||||
: language === 'RU'
|
||||
? 'Последние новости'
|
||||
: 'Soňky habarlar'
|
||||
language === "EN"
|
||||
? "Latest news"
|
||||
: language === "RU"
|
||||
? "Последние новости"
|
||||
: "Soňky habarlar"
|
||||
}`
|
||||
: `${
|
||||
language === 'EN'
|
||||
? 'Most read'
|
||||
: language === 'RU'
|
||||
? 'Самое читаемое'
|
||||
: 'Köp okalýar'
|
||||
language === "EN"
|
||||
? "Most read"
|
||||
: language === "RU"
|
||||
? "Самое читаемое"
|
||||
: "Köp okalýar"
|
||||
}`
|
||||
}
|
||||
/>
|
||||
<div className="aside-inner">
|
||||
{type === 'popular' ? (
|
||||
{type === "popular" ? (
|
||||
data ? (
|
||||
(data as any).data.map((el: any) => {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
// Modules
|
||||
import { Link } from 'react-router-dom';
|
||||
import { LazyLoadImage } from 'react-lazy-load-image-component';
|
||||
import ReactPlayer from 'react-player';
|
||||
import { dateParse } from '../../helpers/dateParser';
|
||||
import { Link } from "react-router-dom";
|
||||
import { LazyLoadImage } from "react-lazy-load-image-component";
|
||||
import ReactPlayer from "react-player";
|
||||
|
||||
// Images
|
||||
// import { ReactComponent as ArrRight } from "../../assets/icons/arrow-right.svg";
|
||||
import placeholder from '../../assets/images/placeholder.webp';
|
||||
import placeholder from "../../assets/images/placeholder.webp";
|
||||
|
||||
// Components
|
||||
import NewsCategory from '../global/NewsCategory';
|
||||
import NewsDate from '../global/NewsDate';
|
||||
import NewsCategory from "../global/NewsCategory";
|
||||
import NewsDate from "../global/NewsDate";
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
|
|
@ -25,7 +25,13 @@ const AsideNews = ({ title, date, img, category, id, video }: Props) => {
|
|||
<div className="aside-news-wrapper">
|
||||
<div className="aside-news-image">
|
||||
{video && video.length > 53 ? (
|
||||
<ReactPlayer url={video} controls light={img} width="100%" height="100%" />
|
||||
<ReactPlayer
|
||||
url={video}
|
||||
controls
|
||||
light={img}
|
||||
width="100%"
|
||||
height="100%"
|
||||
/>
|
||||
) : (
|
||||
<LazyLoadImage
|
||||
src={img}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,17 @@
|
|||
// Modules
|
||||
import { useState, useEffect, useCallback, useMemo } from "react";
|
||||
import { useState, useCallback, useMemo } from "react";
|
||||
import { Calendar as ReactCalendar } from "react-calendar";
|
||||
import { LazyLoadComponent } from "react-lazy-load-image-component";
|
||||
import { v4 as uuiv4 } from "uuid";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
//
|
||||
import { Api } from "../../api/Api";
|
||||
import { url } from "../../url";
|
||||
import { IPostData } from "../../types/store.types";
|
||||
import Loader from "../global/Loader";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
const Calendar = () => {
|
||||
const navigate = useNavigate();
|
||||
const [value, onChange] = useState(new Date());
|
||||
|
||||
const [data, setData] = useState<any>();
|
||||
|
||||
const valueMemo = useMemo(() => ({ value, onChange }), [value, onChange]);
|
||||
const dataMemo = useMemo(() => ({ data, setData }), [data, setData]);
|
||||
|
||||
const constructDateParam = useCallback(() => {
|
||||
return `${value.getFullYear()}-${
|
||||
|
|
@ -34,34 +28,16 @@ const Calendar = () => {
|
|||
const api = new Api(url + `/posts`, [
|
||||
{ name: "date", value: constructDateParam() },
|
||||
]);
|
||||
useEffect(() => {
|
||||
api.get(dataMemo.data, dataMemo.setData);
|
||||
}, [value]);
|
||||
|
||||
return (
|
||||
<div className="calendar">
|
||||
<LazyLoadComponent useIntersectionObserver>
|
||||
<ReactCalendar value={value} onChange={valueMemo.onChange} />
|
||||
</LazyLoadComponent>
|
||||
<div className={"calendar-popup"}>
|
||||
{data ? (
|
||||
data[0] ? (
|
||||
<Link
|
||||
to={`/news/${data[0].id}`}
|
||||
className="calendar-popup-item"
|
||||
key={uuiv4()}
|
||||
>
|
||||
<p>{data[0].title}</p>
|
||||
</Link>
|
||||
) : (
|
||||
<div className="calendar-popup-item" key={uuiv4()}>
|
||||
<p>Нет событий</p>
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
<Loader />
|
||||
)}
|
||||
</div>
|
||||
<ReactCalendar
|
||||
value={valueMemo.value}
|
||||
onChange={valueMemo.onChange}
|
||||
onClickDay={() =>
|
||||
navigate(`/all?type=date&date=${constructDateParam()}`)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import Pagination from "./Pagination";
|
|||
|
||||
// Types
|
||||
import { INewPostsData } from "../../types/posts.types";
|
||||
import Loader from "./Loader";
|
||||
|
||||
interface IProps {
|
||||
data: INewPostsData;
|
||||
|
|
@ -27,7 +26,6 @@ const CustomNewsScroll = ({
|
|||
pageMemo,
|
||||
avoidFirst,
|
||||
}: IProps) => {
|
||||
console.log(data);
|
||||
return (
|
||||
<div className="news-scroll">
|
||||
<div className="news-scroll-wrapper">
|
||||
|
|
@ -71,9 +69,11 @@ const CustomNewsScroll = ({
|
|||
{pagination ? (
|
||||
data ? (
|
||||
<Pagination
|
||||
pages={data?.meta.total}
|
||||
next={data?.links.next}
|
||||
prev={data?.links.prev}
|
||||
activePage={pageMemo.activePage}
|
||||
setActivePage={pageMemo.setActivePage}
|
||||
total={data?.meta.total}
|
||||
/>
|
||||
) : null
|
||||
) : null}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,26 @@
|
|||
// Icons
|
||||
import { Dispatch, SetStateAction } from 'react';
|
||||
import { ReactComponent as Arr } from '../../assets/icons/pagintaion-arr.svg';
|
||||
import { Dispatch, SetStateAction } from "react";
|
||||
import { ReactComponent as Arr } from "../../assets/icons/pagintaion-arr.svg";
|
||||
|
||||
// Api
|
||||
import { Api } from "../../api/Api";
|
||||
|
||||
interface IProps {
|
||||
pages: number;
|
||||
next: string | null;
|
||||
prev: string | null;
|
||||
activePage: number;
|
||||
setActivePage: Dispatch<SetStateAction<number>>;
|
||||
total: number;
|
||||
}
|
||||
|
||||
const Pagination = ({ pages, activePage, setActivePage }: IProps) => {
|
||||
const Pagination = ({
|
||||
next,
|
||||
prev,
|
||||
activePage,
|
||||
setActivePage,
|
||||
total,
|
||||
}: IProps) => {
|
||||
const language = new Api("").language;
|
||||
const handleOnClick = (page: number) => {
|
||||
setActivePage(page);
|
||||
};
|
||||
|
|
@ -16,8 +28,9 @@ const Pagination = ({ pages, activePage, setActivePage }: IProps) => {
|
|||
<div className="pagination-wrapper">
|
||||
<button
|
||||
type="button"
|
||||
disabled={activePage - 1 < 1}
|
||||
onClick={() => handleOnClick(activePage - 1)}>
|
||||
disabled={!prev ? true : false}
|
||||
onClick={() => handleOnClick(activePage - 1)}
|
||||
>
|
||||
<Arr className="pagination-arr pagination-arr-left" />
|
||||
</button>
|
||||
<div className="pagination-nums">
|
||||
|
|
@ -25,10 +38,15 @@ const Pagination = ({ pages, activePage, setActivePage }: IProps) => {
|
|||
</div>
|
||||
<button
|
||||
type="button"
|
||||
disabled={activePage + 1 >= pages}
|
||||
onClick={() => handleOnClick(activePage + 1)}>
|
||||
disabled={!next ? true : false}
|
||||
onClick={() => handleOnClick(activePage + 1)}
|
||||
>
|
||||
<Arr className="pagination-arr pagination-arr-right" />
|
||||
</button>
|
||||
<span className="pagination-total">
|
||||
{Math.ceil(total / 10)}{" "}
|
||||
{language === "EN" ? "pages" : language === "RU" ? "страниц" : "sahypa"}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
export const dateParse = (date: string) => {
|
||||
try {
|
||||
const splitArr = date.split(' ');
|
||||
const dateYear = splitArr[0];
|
||||
const dateYearSplit = dateYear.split('-');
|
||||
const dateYearSplit = date.split("-");
|
||||
const finalDate = `${dateYearSplit[2]}.${dateYearSplit[1]}.${dateYearSplit[0]}`;
|
||||
return finalDate;
|
||||
} catch (err) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import Loader from "../components/global/Loader";
|
|||
import { IurlParamAdder } from "../types/api.types";
|
||||
import SectionTitle from "../components/global/SectionTitle";
|
||||
import { INewPostsData } from "../types/posts.types";
|
||||
import { dateParse } from "../helpers/dateParser";
|
||||
|
||||
const AllPosts = () => {
|
||||
const [searchParams] = useSearchParams();
|
||||
|
|
@ -23,6 +24,7 @@ const AllPosts = () => {
|
|||
[activePage, setActivePage]
|
||||
);
|
||||
const type = searchParams.get("type") || null;
|
||||
const date = searchParams.get("date") || null;
|
||||
|
||||
const [params, setParams] = useState<IurlParamAdder[]>(
|
||||
type !== null
|
||||
|
|
@ -51,7 +53,16 @@ const AllPosts = () => {
|
|||
},
|
||||
]
|
||||
);
|
||||
const api = new Api(url + "/pagination/new/posts", params);
|
||||
const api = new Api(
|
||||
url + "/pagination/new/posts",
|
||||
type === "date" && date
|
||||
? [
|
||||
{ name: "date", value: date },
|
||||
{ name: "count", value: 10 },
|
||||
{ name: "page", value: pageMemo.activePage },
|
||||
]
|
||||
: params
|
||||
);
|
||||
|
||||
const language = api.language;
|
||||
|
||||
|
|
@ -68,6 +79,7 @@ const AllPosts = () => {
|
|||
api.get(data, setData);
|
||||
}, [params]);
|
||||
|
||||
console.log(pageMemo.activePage);
|
||||
useEffect(() => {
|
||||
if (language !== lastLanguage) {
|
||||
api.get(data, setData);
|
||||
|
|
@ -79,7 +91,20 @@ const AllPosts = () => {
|
|||
<main className="all">
|
||||
<div className="container">
|
||||
<div className="all-inner">
|
||||
{type === "video" ? <SectionTitle title={"Видео"} /> : null}
|
||||
{type === "date" && date ? (
|
||||
<SectionTitle title={dateParse(date)} />
|
||||
) : null}
|
||||
{type === "video" ? (
|
||||
<SectionTitle
|
||||
title={
|
||||
language === "EN"
|
||||
? "Videos"
|
||||
: language === "RU"
|
||||
? "Видео"
|
||||
: "Videolar"
|
||||
}
|
||||
/>
|
||||
) : null}
|
||||
{data ? (
|
||||
<CustomNewsScroll
|
||||
data={data}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
.all-inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3.2rem;
|
||||
min-height: 50vh;
|
||||
padding: 5.6rem 0;
|
||||
.loader {
|
||||
|
|
|
|||
|
|
@ -73,6 +73,10 @@ h6 {
|
|||
column-gap: 1.8rem;
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
.container {
|
||||
padding: 0 1.5rem;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,17 @@
|
|||
.pagination-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4rem;
|
||||
|
||||
button {
|
||||
width: 3.2rem;
|
||||
height: 3.2rem;
|
||||
|
||||
svg {
|
||||
width: 3.2rem;
|
||||
height: 3.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pagination-nums {
|
||||
|
|
@ -14,9 +25,7 @@
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
// border: 0.1rem solid $main;
|
||||
// background: $main;
|
||||
color: $main;
|
||||
color: $black;
|
||||
font-size: 1.8rem;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
|
@ -32,3 +41,8 @@
|
|||
.pagination-arr-left {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.pagination-total {
|
||||
font-size: 1.8rem;
|
||||
color: $main;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue