new posts link

This commit is contained in:
VividTruthKeeper 2023-03-08 01:18:27 +05:00
parent cfc5f4a153
commit 1b644b5154
11 changed files with 198 additions and 162 deletions

View File

@ -4,12 +4,10 @@ import { v4 as uuidv4 } from "uuid";
// Components // Components
import News from "../news/News"; import News from "../news/News";
import Loader from "./Loader";
import Pagination from "./Pagination"; import Pagination from "./Pagination";
// Types // Types
import { INewPostsData } from "../../types/posts.types"; import { INewPostsData } from "../../types/posts.types";
import { Dispatch } from "@reduxjs/toolkit";
interface IProps { interface IProps {
data: INewPostsData; data: INewPostsData;
@ -33,8 +31,8 @@ const CustomNewsScroll = ({
<div className="news-scroll"> <div className="news-scroll">
<div className="news-scroll-wrapper"> <div className="news-scroll-wrapper">
<div className="news-scroll-inner"> <div className="news-scroll-inner">
{data?.data?.data?.length > 0 ? ( {data?.data[0].id > -1 ? (
data.data.data.map((dataEl, index) => { data.data.map((dataEl, index) => {
if (avoidFirst) { if (avoidFirst) {
if (index > 0) { if (index > 0) {
return ( return (
@ -70,9 +68,9 @@ const CustomNewsScroll = ({
)} )}
</div> </div>
{pagination ? ( {pagination ? (
data?.data?.data?.length > 0 ? ( data?.data[0].id > -1 ? (
<Pagination <Pagination
pages={data?.data?.total} pages={data?.meta.total}
activePage={pageMemo.activePage} activePage={pageMemo.activePage}
setActivePage={pageMemo.setActivePage} setActivePage={pageMemo.setActivePage}
/> />

View File

@ -1,26 +1,26 @@
// Modules // Modules
import { useEffect, useState } from 'react'; import { useEffect, useState } from "react";
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from "uuid";
import { useSelector, useDispatch } from 'react-redux'; import { useSelector, useDispatch } from "react-redux";
// Components // Components
import News from '../news/News'; import News from "../news/News";
import SectionTitle from './SectionTitle'; import SectionTitle from "./SectionTitle";
import Loader from './Loader'; import Loader from "./Loader";
import Pagination from './Pagination'; import Pagination from "./Pagination";
// Api // Api
import { url } from '../../url'; import { url } from "../../url";
import { Api } from '../../api/Api'; import { Api } from "../../api/Api";
import { newsScrollParams } from '../../api/params'; import { newsScrollParams } from "../../api/params";
// Types // Types
import { IPostsData } from '../../types/data.types'; import { IPostsData } from "../../types/data.types";
import { RootState } from '../../types/store.types'; import { RootState } from "../../types/store.types";
// Actions // Actions
import { setNewsScroll } from '../../actions/setData'; import { setNewsScroll } from "../../actions/setData";
import { INewPostsData } from '../../types/posts.types'; import { INewPostsData } from "../../types/posts.types";
interface Props { interface Props {
title: boolean; title: boolean;
@ -31,16 +31,16 @@ interface Props {
const NewsScroll = ({ title, category, count, avoidFirst }: Props) => { const NewsScroll = ({ title, category, count, avoidFirst }: Props) => {
const params = newsScrollParams.slice(); const params = newsScrollParams.slice();
category ? params.push({ name: 'category', value: category }) : null; category ? params.push({ name: "category", value: category }) : null;
count ? (params[0].value = count) : null; count ? (params[0].value = count) : null;
const api = new Api(url + '/pagination/posts', params); const api = new Api(url + "/pagination/new/posts", params);
const language = api.language; const language = api.language;
const [lastLanguage, setLastLanguage] = useState<string>(language); const [lastLanguage, setLastLanguage] = useState<string>(language);
// redux // redux
const rawData = useSelector<RootState, RootState['newsScroll']['data']>( const rawData = useSelector<RootState, RootState["newsScroll"]["data"]>(
(state) => state.newsScroll.data, (state) => state.newsScroll.data
); );
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -50,7 +50,7 @@ const NewsScroll = ({ title, category, count, avoidFirst }: Props) => {
}, [category]); }, [category]);
useEffect(() => { useEffect(() => {
if (rawData.status_code > 0) { if (rawData.data[0].id > 0) {
if (!(lastLanguage === language)) { if (!(lastLanguage === language)) {
api.get(rawData, (rawData) => dispatch(setNewsScroll(rawData))); api.get(rawData, (rawData) => dispatch(setNewsScroll(rawData)));
setLastLanguage(language); setLastLanguage(language);
@ -58,12 +58,12 @@ const NewsScroll = ({ title, category, count, avoidFirst }: Props) => {
} }
}, [language, lastLanguage]); }, [language, lastLanguage]);
const [filteredData, setFilteredData] = useState<INewPostsData['data']['data']>( const [filteredData, setFilteredData] = useState<INewPostsData["data"]>(
rawData.data.data, rawData.data
); );
useEffect(() => { useEffect(() => {
const filtered = rawData.data.data.filter((el, index) => { const filtered = rawData.data.filter((el, index) => {
if (index >= 0) { if (index >= 0) {
return el; return el;
} }
@ -77,20 +77,28 @@ const NewsScroll = ({ title, category, count, avoidFirst }: Props) => {
{title === true ? ( {title === true ? (
<SectionTitle <SectionTitle
title={ title={
language === 'EN' ? 'Newsline' : language === 'RU' ? 'Лента новостей' : 'Habarlar' language === "EN"
? "Newsline"
: language === "RU"
? "Лента новостей"
: "Habarlar"
} }
linkData={{ linkData={{
link: '/all', link: "/all",
title: `${ title: `${
language === 'EN' ? 'View all' : language === 'RU' ? 'Посмотреть все' : 'Doly gör' language === "EN"
? "View all"
: language === "RU"
? "Посмотреть все"
: "Doly gör"
}`, }`,
}} }}
/> />
) : null} ) : null}
<div className="news-scroll-inner"> <div className="news-scroll-inner">
{filteredData.length > 0 ? ( {filteredData.length > 0 ? (
(filteredData as INewPostsData['data']['data'])[0].id > -1 ? ( (filteredData as INewPostsData["data"])[0].id > -1 ? (
(filteredData as INewPostsData['data']['data']).map((dataEl, index) => { (filteredData as INewPostsData["data"]).map((dataEl, index) => {
if (avoidFirst) { if (avoidFirst) {
if (index > 0) { if (index > 0) {
return ( return (
@ -102,7 +110,7 @@ const NewsScroll = ({ title, category, count, avoidFirst }: Props) => {
date={dataEl?.published_at} date={dataEl?.published_at}
categories={dataEl?.categories} categories={dataEl?.categories}
img={dataEl?.featured_images[0]?.path} img={dataEl?.featured_images[0]?.path}
video={dataEl?.video} video={{ type: dataEl?.type, url: dataEl?.video }}
/> />
); );
} }
@ -116,7 +124,7 @@ const NewsScroll = ({ title, category, count, avoidFirst }: Props) => {
date={dataEl?.published_at} date={dataEl?.published_at}
categories={dataEl?.categories} categories={dataEl?.categories}
img={dataEl?.featured_images[0]?.path} img={dataEl?.featured_images[0]?.path}
video={dataEl?.video} video={{ type: dataEl?.type, url: dataEl?.video }}
/> />
); );
} }

View File

@ -7,6 +7,7 @@ import { Link } from "react-router-dom";
// Types // Types
import { ICategoriesData } from "../../types/data.types"; import { ICategoriesData } from "../../types/data.types";
import { dropdownMotion } from "../../animations/subNav.animations"; import { dropdownMotion } from "../../animations/subNav.animations";
import { Api } from "../../api/Api";
interface IProps { interface IProps {
dropdownOpen: boolean; dropdownOpen: boolean;
@ -23,6 +24,7 @@ const NavDropdown = ({
onClickLink, onClickLink,
activeLink, activeLink,
}: IProps) => { }: IProps) => {
const language = new Api("").language;
return ( return (
<motion.div <motion.div
className="nav-dropdown" className="nav-dropdown"
@ -38,7 +40,11 @@ const NavDropdown = ({
initial={"linkRest"} initial={"linkRest"}
animate={activeLink === 0 ? "linkActive" : "linkRest"} animate={activeLink === 0 ? "linkActive" : "linkRest"}
> >
Главная {language === "EN"
? "Home"
: language === "RU"
? "Главная"
: "Esasy sahypa"}
</motion.span> </motion.span>
</Link> </Link>
</li> </li>

View File

@ -22,12 +22,12 @@ const MainContent = () => {
const data = useSelector<RootState, RootState["featured"]["data"]>( const data = useSelector<RootState, RootState["featured"]["data"]>(
(state) => state.featured.data (state) => state.featured.data
); );
const api = new Api(url + "/pagination/posts", featuredParams); const api = new Api(url + "/pagination/new/posts", featuredParams);
const language = api.language; const language = api.language;
const [lastLanguage, setLastLanguage] = useState<typeof language>(language); const [lastLanguage, setLastLanguage] = useState<typeof language>(language);
useEffect(() => { useEffect(() => {
if (!(data.status_code > 0 && language === lastLanguage)) { if (!(data.data[0].id > -1 && language === lastLanguage)) {
api.get(data, (data: INewPostsData) => dispatch(setFeatured(data))); api.get(data, (data: INewPostsData) => dispatch(setFeatured(data)));
setLastLanguage(language); setLastLanguage(language);
} }
@ -35,38 +35,38 @@ const MainContent = () => {
return ( return (
<div className="main-content-wrapper"> <div className="main-content-wrapper">
{data.status_code > 0 ? ( {data.data[0].id > -1 ? (
data.data.data.length >= 5 ? ( data.data.length >= 5 ? (
<div className="main-content"> <div className="main-content">
<ContentSlider data={data.data.data} /> <ContentSlider data={data.data} />
<div className="main-content-top"> <div className="main-content-top">
<ContentItem <ContentItem
id={data?.data?.data[0]?.id} id={data?.data[0]?.id}
type="big" type="big"
img={data?.data?.data[0]?.featured_images[0]?.path} img={data?.data[0]?.featured_images[0]?.path}
title={data?.data?.data[0]?.title} title={data?.data[0]?.title}
/> />
<ContentItem <ContentItem
id={data?.data?.data[1]?.id} id={data?.data[1]?.id}
img={data?.data?.data[1]?.featured_images[0]?.path} img={data?.data[1]?.featured_images[0]?.path}
title={data?.data?.data[1]?.title} title={data?.data[1]?.title}
/> />
</div> </div>
<div className="main-content-bottom"> <div className="main-content-bottom">
<ContentItem <ContentItem
id={data?.data?.data[2]?.id} id={data?.data[2]?.id}
img={data?.data?.data[2]?.featured_images[0]?.path} img={data?.data[2]?.featured_images[0]?.path}
title={data?.data?.data[2]?.title} title={data?.data[2]?.title}
/> />
<ContentItem <ContentItem
id={data?.data?.data[3]?.id} id={data?.data[3]?.id}
img={data?.data?.data[3]?.featured_images[0]?.path} img={data?.data[3]?.featured_images[0]?.path}
title={data?.data?.data[3]?.title} title={data?.data[3]?.title}
/> />
<ContentItem <ContentItem
id={data?.data?.data[4]?.id} id={data?.data[4]?.id}
img={data?.data?.data[4]?.featured_images[0]?.path} img={data?.data[4]?.featured_images[0]?.path}
title={data?.data?.data[4]?.title} title={data?.data[4]?.title}
/> />
</div> </div>
</div> </div>

View File

@ -1,24 +1,27 @@
// Modules // Modules
import { Link } from 'react-router-dom'; import { Link } from "react-router-dom";
import { LazyLoadImage } from 'react-lazy-load-image-component'; import { LazyLoadImage } from "react-lazy-load-image-component";
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from "uuid";
import ReactPlayer from 'react-player'; import ReactPlayer from "react-player";
// Components // Components
import NewsCategory from '../global/NewsCategory'; import NewsCategory from "../global/NewsCategory";
import NewsDate from '../global/NewsDate'; import NewsDate from "../global/NewsDate";
import { IPostsData } from '../../types/data.types'; import { IPostsData } from "../../types/data.types";
import placeholder from '../../assets/images/placeholder.webp'; import placeholder from "../../assets/images/placeholder.webp";
import { dateParse } from '../../helpers/dateParser'; import { dateParse } from "../../helpers/dateParser";
interface Props { interface Props {
id: IPostsData['id']; id: IPostsData["id"];
title: IPostsData['title']; title: IPostsData["title"];
text: IPostsData['content_html']; text: IPostsData["content_html"];
categories: IPostsData['categories']; categories: IPostsData["categories"];
date: IPostsData['published_at']; date: IPostsData["published_at"];
img: IPostsData['featured_images'][0]['path']; img: IPostsData["featured_images"][0]["path"];
video: IPostsData['video']; video: {
type: string;
url: string;
};
} }
const News = ({ id, title, text, categories, date, img, video }: Props) => { const News = ({ id, title, text, categories, date, img, video }: Props) => {
@ -26,8 +29,14 @@ const News = ({ id, title, text, categories, date, img, video }: Props) => {
<Link to={`/news/${id}`}> <Link to={`/news/${id}`}>
<div className="news-wrapper"> <div className="news-wrapper">
<div className="news-image"> <div className="news-image">
{video && video.length > 0 ? ( {video.type === "video" ? (
<ReactPlayer url={video} controls light={img} width="100%" height="100%" /> <ReactPlayer
url={video.url}
controls
light={img}
width="100%"
height="100%"
/>
) : ( ) : (
<LazyLoadImage <LazyLoadImage
src={img} src={img}
@ -51,7 +60,10 @@ const News = ({ id, title, text, categories, date, img, video }: Props) => {
<NewsDate date={dateParse(date)} /> <NewsDate date={dateParse(date)} />
</div> </div>
</div> </div>
<div className="news-text" dangerouslySetInnerHTML={{ __html: text }}></div> <div
className="news-text"
dangerouslySetInnerHTML={{ __html: text }}
></div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,35 +1,37 @@
// Modules // Modules
import { useEffect, useState } from 'react'; import { useEffect, useState } from "react";
import { v4 as uuiv4 } from 'uuid'; import { v4 as uuiv4 } from "uuid";
import { useSelector, useDispatch } from 'react-redux'; import { useSelector, useDispatch } from "react-redux";
import { dateParse } from '../../helpers/dateParser'; import { dateParse } from "../../helpers/dateParser";
// Components // Components
import SectionTitle from '../global/SectionTitle'; import SectionTitle from "../global/SectionTitle";
import VideosItem from './VideosItem'; import VideosItem from "./VideosItem";
// Types // Types
import { RootState } from '../../types/store.types'; import { RootState } from "../../types/store.types";
// Api // Api
import { Api } from '../../api/Api'; import { Api } from "../../api/Api";
import { url } from '../../url'; import { url } from "../../url";
import { videoParams } from '../../api/params'; import { videoParams } from "../../api/params";
// Actions // Actions
import { setVideo } from '../../actions/setData'; import { setVideo } from "../../actions/setData";
import Loader from '../global/Loader'; import Loader from "../global/Loader";
const Videos = () => { const Videos = () => {
const data = useSelector<RootState, RootState['video']['data']>((state) => state.video.data); const data = useSelector<RootState, RootState["video"]["data"]>(
const api = new Api(url + '/pagination/posts', videoParams); (state) => state.video.data
);
const api = new Api(url + "/pagination/new/posts", videoParams);
const language = api.language; const language = api.language;
const dispatch = useDispatch(); const dispatch = useDispatch();
const [lastLanguage, setLastLanguage] = useState<typeof language>(language); const [lastLanguage, setLastLanguage] = useState<typeof language>(language);
useEffect(() => { useEffect(() => {
if (!(lastLanguage === language && data.status_code > 0)) { if (!(lastLanguage === language && data.data[0].id > -1)) {
api.get(data, (data) => dispatch(setVideo(data))); api.get(data, (data) => dispatch(setVideo(data)));
setLastLanguage(language); setLastLanguage(language);
} }
@ -39,28 +41,38 @@ const Videos = () => {
<div className="videos-inner"> <div className="videos-inner">
<SectionTitle <SectionTitle
givenClass="videos" givenClass="videos"
title={language === 'EN' ? 'Videos' : language === 'RU' ? 'Видео' : 'Videolar'} title={
language === "EN"
? "Videos"
: language === "RU"
? "Видео"
: "Videolar"
}
linkData={{ linkData={{
link: '/all?type=video', link: "/all?type=video",
title: `${ title: `${
language === 'EN' ? 'View all' : language === 'RU' ? 'Посмотреть все' : 'Doly gör' language === "EN"
? "View all"
: language === "RU"
? "Посмотреть все"
: "Doly gör"
}`, }`,
}} }}
/> />
<div className="videos-items"> <div className="videos-items">
{data.status_code > 0 ? ( {data.data[0].id > -1 ? (
data.data.data.map((videosDataItem, index) => { data.data.map((videosDataItem, index) => {
if (index <= 4) { if (index <= 4) {
return ( return (
<VideosItem <VideosItem
key={uuiv4()} key={uuiv4()}
url={videosDataItem.video || ''} url={videosDataItem.video || ""}
placeholder={ placeholder={
videosDataItem.featured_images[0] videosDataItem.featured_images[0]
? videosDataItem.featured_images[0].path ? videosDataItem.featured_images[0].path
: '' : ""
} }
date={dateParse(videosDataItem.published_at)} date={videosDataItem.published_at}
excerpt={videosDataItem.excerpt} excerpt={videosDataItem.excerpt}
/> />
); );

View File

@ -51,7 +51,7 @@ const AllPosts = () => {
}, },
] ]
); );
const api = new Api(url + "/pagination/posts", params); const api = new Api(url + "/pagination/new/posts", params);
const language = api.language; const language = api.language;

View File

@ -27,7 +27,7 @@ const Category = () => {
() => ({ activePage, setActivePage }), () => ({ activePage, setActivePage }),
[activePage, setActivePage] [activePage, setActivePage]
); );
const api = new Api(url + "/pagination/posts", params); const api = new Api(url + "/pagination/new/posts", params);
useEffect(() => { useEffect(() => {
const newParams = params.slice(); const newParams = params.slice();
@ -46,9 +46,9 @@ const Category = () => {
<div className="category-left"> <div className="category-left">
{data ? ( {data ? (
<ContentItem <ContentItem
id={data?.data?.data[0]?.id} id={data?.data[0]?.id}
img={data?.data?.data[0]?.featured_images[0]?.path} img={data?.data[0]?.featured_images[0]?.path}
title={data?.data?.data[0]?.title} title={data?.data[0]?.title}
type={"big"} type={"big"}
/> />
) : ( ) : (

View File

@ -39,7 +39,7 @@ const SearchResult = () => {
value: 1, value: 1,
}, },
]); ]);
const api = new Api(url + "/pagination/posts", params); const api = new Api(url + "/pagination/new/posts", params);
const language = api.language; const language = api.language;
const [lastLanguage, setLastLanguage] = useState<typeof language>(language); const [lastLanguage, setLastLanguage] = useState<typeof language>(language);
@ -71,10 +71,16 @@ const SearchResult = () => {
<div className="sresult-inner"> <div className="sresult-inner">
<div className="sresult-title"> <div className="sresult-title">
<LoopBlack /> <LoopBlack />
<h1>Результаты по поиску "{word}"</h1> <h1>
{language === "EN"
? `Results for "${word}"`
: language === "RU"
? `Результаты по поиску "${word}"`
: `"${word}" gözleg boýunça netijeler`}
</h1>
</div> </div>
<div className="sresult-content"> <div className="sresult-content">
{data.status_code > 0 ? ( {data.data[0].id > -1 ? (
<CustomNewsScroll <CustomNewsScroll
pagination={true} pagination={true}
data={data} data={data}

View File

@ -18,32 +18,35 @@ import {
export const newScroll: INewsScroll = { export const newScroll: INewsScroll = {
data: { data: {
status_code: -1, data: [
message: "", {
data: { id: -1,
title: "",
slug: "",
excerpt: "",
published_at: "",
categories: [],
video: "",
featured_images: [],
powerseo_description: "",
content_html: "",
powerseo_keywords: "",
powerseo_title: "",
type: "",
},
],
links: {
first: "",
last: "",
prev: null,
next: "",
},
meta: {
current_page: -1, current_page: -1,
data: [
{
id: -1,
title: "",
slug: "",
excerpt: "",
published_at: "",
summary: "",
has_summary: false,
categories: [],
video: null,
featured_images: [],
},
],
first_page_url: "",
from: -1, from: -1,
last_page: -1, last_page: -1,
last_page_url: "",
next_page_url: "",
path: "", path: "",
per_page: "-1", per_page: "",
prev_page_url: null,
to: -1, to: -1,
total: -1, total: -1,
}, },

View File

@ -1,22 +1,7 @@
export interface INewPostsData { export interface INewPostsData {
status_code: number;
message: string;
data: Data;
}
export interface Data {
current_page: number;
data: Datum[]; data: Datum[];
first_page_url: string; links: Links;
from: number; meta: Meta;
last_page: number;
last_page_url: string;
next_page_url: string;
path: string;
per_page: string;
prev_page_url: string | null;
to: number;
total: number;
} }
export interface Datum { export interface Datum {
@ -25,36 +10,42 @@ export interface Datum {
slug: string; slug: string;
excerpt: string; excerpt: string;
published_at: string; published_at: string;
video: string | null; type: string;
summary: string;
has_summary: boolean;
featured_images: FeaturedImage[]; featured_images: FeaturedImage[];
video: string;
content_html: string;
categories: Category[]; categories: Category[];
powerseo_title: string;
powerseo_description: string;
powerseo_keywords: string;
} }
export interface Category { export interface Category {
id: number; id: number;
name: string; name: string;
pivot: Pivot;
}
export interface Pivot {
post_id: number;
category_id: number;
} }
export interface FeaturedImage { export interface FeaturedImage {
id: number; id: number;
disk_name: string; disk_name: string;
file_name: string; file_name: string;
file_size: number;
content_type: string;
title: string;
description: string | null;
field: string;
sort_order: number;
created_at: string;
updated_at: string;
path: string; path: string;
extension: string; extension: string;
} }
export interface Links {
first: string;
last: string;
prev: null | string;
next: null | string;
}
export interface Meta {
current_page: number;
from: number;
last_page: number;
path: string;
per_page: string;
to: number;
total: number;
}