This commit is contained in:
VividTruthKeeper 2023-03-02 00:52:59 +05:00
parent a350558893
commit c490bae0ac
7 changed files with 189 additions and 122 deletions

View File

@ -1,64 +1,64 @@
import { IurlParamAdder } from '../types/api.types'; import { IurlParamAdder } from "../types/api.types";
export const newsScrollParams: IurlParamAdder[] = [ export const newsScrollParams: IurlParamAdder[] = [
{ {
name: 'count', name: "count",
value: 5, value: 5,
}, },
{ {
name: 'page', name: "page",
value: 1, value: 1,
}, },
]; ];
export const AsideParams: IurlParamAdder[] = [ export const asideParams: IurlParamAdder[] = [
{ {
name: 'count', name: "count",
value: 5, value: 5,
}, },
{ {
name: 'page', name: "page",
value: 1, value: 1,
}, },
]; ];
export const categoriesParams: IurlParamAdder[] = [ export const categoriesParams: IurlParamAdder[] = [
{ {
name: 'count', name: "count",
value: 100, value: 100,
}, },
{ {
name: 'page', name: "page",
value: 1, value: 1,
}, },
]; ];
export const featuredParams: IurlParamAdder[] = [ export const featuredParams: IurlParamAdder[] = [
{ {
name: 'count', name: "count",
value: 5, value: 5,
}, },
{ {
name: 'page', name: "page",
value: 1, value: 1,
}, },
{ {
name: 'featured', name: "featured",
value: 'true', value: "true",
}, },
]; ];
export const videoParams: IurlParamAdder[] = [ export const videoParams: IurlParamAdder[] = [
{ {
name: 'count', name: "count",
value: 10, value: 10,
}, },
{ {
name: 'page', name: "page",
value: 1, value: 1,
}, },
{ {
name: 'type', name: "type",
value: 'video', value: "video",
}, },
]; ];

View File

@ -1,37 +1,32 @@
// Modules // Modules
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from "uuid";
import { useState, useEffect } from 'react'; import { useState, useEffect } from "react";
import { url } from '../../url'; import { url } from "../../url";
import { Api } from '../../api/Api'; import { Api } from "../../api/Api";
import { AsideParams } from '../../api/params'; import { asideParams } from "../../api/params";
// Components // Components
import SectionTitle from '../global/SectionTitle'; import SectionTitle from "../global/SectionTitle";
import AsideNews from './AsideNews'; import AsideNews from "./AsideNews";
import Calendar from './Calendar'; import Calendar from "./Calendar";
import { IPostsData } from '../../types/data.types'; import { IPostsData } from "../../types/data.types";
import Loader from '../global/Loader'; import Loader from "../global/Loader";
interface Props { interface Props {
type: 'latest' | 'popular'; type: "latest" | "popular";
} }
interface Ipost { interface IData {
id: number;
title: string;
img: string;
published_at: string | number;
category: string;
}
interface Idata {
data: IPostsData[]; data: IPostsData[];
} }
const Aside = ({ type }: Props) => { const Aside = ({ type }: Props) => {
const api = new Api(url + `${type === 'popular' ? '/popular' : '/popular'}/posts`, AsideParams); const api = new Api(
url + `${type === "popular" ? "/popular" : ""}/posts`,
asideParams
);
const [data, setData] = useState<Idata>(); const [data, setData] = useState<IData>();
useEffect(() => { useEffect(() => {
api.get(data, setData); api.get(data, setData);
@ -40,17 +35,39 @@ const Aside = ({ type }: Props) => {
return ( return (
<div className="aside"> <div className="aside">
<div className="aside-wrapper"> <div className="aside-wrapper">
<SectionTitle title={type === 'latest' ? 'Последние новости' : 'Самое читаемое'} /> <SectionTitle
title={type === "latest" ? "Последние новости" : "Самое читаемое"}
/>
<div className="aside-inner"> <div className="aside-inner">
{data ? ( {type === "popular" ? (
data.data.map((el) => { data ? (
(data as any).data.map((el: any) => {
return (
<AsideNews
key={uuidv4()}
title={el.title}
date={el.published_at}
category={el.categories[0].name}
img={
el.featured_images[0] ? el.featured_images[0].path : ""
}
id={el.id}
/>
);
})
) : (
<Loader />
)
) : data ? (
(data as any).map((el: any) => {
return ( return (
<AsideNews <AsideNews
key={uuidv4()} key={uuidv4()}
title={el.title} title={el.title}
date={el.published_at} date={el.published_at}
category={el.categories[0].name} category={el.categories[0].name}
img={el.featured_images[0] ? el.featured_images[0].path : ''} img={el.featured_images[0] ? el.featured_images[0].path : ""}
id={el.id}
/> />
); );
}) })

View File

@ -1,23 +1,24 @@
// 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";
// Images // Images
// import { ReactComponent as ArrRight } from "../../assets/icons/arrow-right.svg"; // 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 // Components
import NewsCategory from '../global/NewsCategory'; import NewsCategory from "../global/NewsCategory";
import NewsDate from '../global/NewsDate'; import NewsDate from "../global/NewsDate";
interface Props { interface Props {
title: string; title: string;
date: string; date: string;
img: string; img: string;
category: string; category: string;
id: number;
} }
const AsideNews = ({ title, date, img, category }: Props) => { const AsideNews = ({ title, date, img, category, id }: Props) => {
return ( return (
<div className="aside-news"> <Link to={`/news/${id}`} className="aside-news">
<div className="aside-news-wrapper"> <div className="aside-news-wrapper">
<div className="aside-news-image"> <div className="aside-news-image">
<LazyLoadImage <LazyLoadImage
@ -38,7 +39,7 @@ const AsideNews = ({ title, date, img, category }: Props) => {
</div> </div>
</div> </div>
</div> </div>
</div> </Link>
); );
}; };

View File

@ -1,42 +1,45 @@
// 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";
interface Props { interface Props {
title: boolean; title: boolean;
category?: number; category?: number;
count?: number;
avoidFirst?: boolean;
} }
const NewsScroll = ({ title, category }: 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;
const api = new Api(url + '/posts', params); const api = new Api(url + "/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();
@ -47,8 +50,12 @@ const NewsScroll = ({ title, category }: Props) => {
useEffect(() => { useEffect(() => {
if (rawData.length > 0) { if (rawData.length > 0) {
if (!((rawData as IPostsData[])[0].id > -1 && lastLanguage === language)) { if (
api.get(rawData, (rawData: IPostsData[]) => dispatch(setNewsScroll(rawData))); !((rawData as IPostsData[])[0].id > -1 && lastLanguage === language)
) {
api.get(rawData, (rawData: IPostsData[]) =>
dispatch(setNewsScroll(rawData))
);
setLastLanguage(language); setLastLanguage(language);
} }
} }
@ -71,24 +78,48 @@ const NewsScroll = ({ title, category }: Props) => {
{title === true ? ( {title === true ? (
<SectionTitle <SectionTitle
title="Лента новостей" title="Лента новостей"
linkData={{ link: '/all', title: 'Посмотреть все' }} linkData={{ link: "/all", title: "Посмотреть все" }}
/> />
) : null} ) : null}
<div className="news-scroll-inner"> <div className="news-scroll-inner">
{filteredData.length > 0 ? ( {filteredData.length > 0 ? (
(filteredData as IPostsData[])[0].id > -1 ? ( (filteredData as IPostsData[])[0].id > -1 ? (
(filteredData as IPostsData[]).map((dataEl, index) => { (filteredData as IPostsData[]).map((dataEl, index) => {
return ( if (avoidFirst) {
<News if (index > 0) {
key={uuidv4()} return (
id={dataEl.id} <News
title={dataEl.title} key={uuidv4()}
text={dataEl.excerpt} id={dataEl.id}
date={dataEl.published_at} title={dataEl.title}
categories={dataEl.categories} text={dataEl.excerpt}
img={dataEl.featured_images[0] ? dataEl.featured_images[0].path : ''} date={dataEl.published_at}
/> categories={dataEl.categories}
); img={
dataEl.featured_images[0]
? dataEl.featured_images[0].path
: ""
}
/>
);
}
} else {
return (
<News
key={uuidv4()}
id={dataEl.id}
title={dataEl.title}
text={dataEl.excerpt}
date={dataEl.published_at}
categories={dataEl.categories}
img={
dataEl.featured_images[0]
? dataEl.featured_images[0].path
: ""
}
/>
);
}
}) })
) : ( ) : (
<Loader /> <Loader />

View File

@ -1,11 +1,11 @@
// Modules // Modules
import { motion } from 'framer-motion'; import { motion } from "framer-motion";
// Components // Components
import { useParams } from 'react-router-dom'; import { useParams } from "react-router-dom";
import Aside from '../components/aside/Aside'; import Aside from "../components/aside/Aside";
import NewsScroll from '../components/global/NewsScroll'; import NewsScroll from "../components/global/NewsScroll";
import MainImg from '../components/category/MainImg'; import MainImg from "../components/category/MainImg";
const Category = () => { const Category = () => {
let { category } = useParams(); let { category } = useParams();
@ -14,15 +14,21 @@ const Category = () => {
className="category" className="category"
initial={{ opacity: 0, scale: 0.8 }} initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1, transition: { duration: 0.15 } }} animate={{ opacity: 1, scale: 1, transition: { duration: 0.15 } }}
exit={{ opacity: 0, scale: 0.8, transition: { duration: 0.15 } }}> exit={{ opacity: 0, scale: 0.8, transition: { duration: 0.15 } }}
>
<div className="container"> <div className="container">
<div className="category-inner"> <div className="category-inner">
<div className="category-left"> <div className="category-left">
<MainImg /> <MainImg />
<NewsScroll title={false} category={parseInt(category as string)} /> <NewsScroll
title={false}
category={parseInt(category as string)}
count={11}
avoidFirst
/>
</div> </div>
<div className="category-right"> <div className="category-right">
<Aside type="popular" /> <Aside type="latest" />
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,11 +1,11 @@
// Modules // Modules
import { motion } from 'framer-motion'; import { motion } from "framer-motion";
// Components // Components
import Aside from '../components/aside/Aside'; import Aside from "../components/aside/Aside";
import NewsScroll from '../components/global/NewsScroll'; import NewsScroll from "../components/global/NewsScroll";
import Videos from '../components/videos/Videos'; import Videos from "../components/videos/Videos";
import MainContent from '../components/main/MainContent'; import MainContent from "../components/main/MainContent";
const Main = () => { const Main = () => {
return ( return (
@ -13,8 +13,9 @@ const Main = () => {
className="main" className="main"
initial={{ opacity: 0, scale: 0.8 }} initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1, transition: { duration: 0.15 } }} animate={{ opacity: 1, scale: 1, transition: { duration: 0.15 } }}
exit={{ opacity: 0, scale: 0.8, transition: { duration: 0.15 } }}> exit={{ opacity: 0, scale: 0.8, transition: { duration: 0.15 } }}
<h1 style={{ display: 'none' }}>Туркменистан новостной портал</h1> >
<h1 style={{ display: "none" }}>Туркменистан новостной портал</h1>
<div className="news-section"> <div className="news-section">
<div className="container"> <div className="container">
<div className="news-inner"> <div className="news-inner">

View File

@ -1,29 +1,29 @@
// Modules // Modules
import { Link, useParams } from 'react-router-dom'; import { Link, useParams } from "react-router-dom";
import { useEffect, useState } from 'react'; import { useEffect, useState } from "react";
import { useSelector, useDispatch } from 'react-redux'; import { useSelector, useDispatch } from "react-redux";
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from "uuid";
import { motion } from 'framer-motion'; import { motion } from "framer-motion";
// Components // Components
import Aside from '../components/aside/Aside'; import Aside from "../components/aside/Aside";
import NewsArticleSlider from '../components/news/NewsArticleSlider'; import NewsArticleSlider from "../components/news/NewsArticleSlider";
import Loader from '../components/global/Loader'; import Loader from "../components/global/Loader";
// import VideosItem from "../components/videos/VideosItem"; // import VideosItem from "../components/videos/VideosItem";
// Icons // Icons
import { ReactComponent as Share } from '../assets/icons/share.svg'; import { ReactComponent as Share } from "../assets/icons/share.svg";
// Types // Types
import { RootState } from '../types/store.types'; import { RootState } from "../types/store.types";
import { IPostData } from '../types/store.types'; import { IPostData } from "../types/store.types";
// Actions // Actions
import { setPost } from '../actions/setData'; import { setPost } from "../actions/setData";
// Api // Api
import { Api } from '../api/Api'; import { Api } from "../api/Api";
import { url } from '../url'; import { url } from "../url";
const NewsArticle = () => { const NewsArticle = () => {
const { id } = useParams(); const { id } = useParams();
@ -35,21 +35,27 @@ const NewsArticle = () => {
const [lastLanguage, setLastLanguage] = useState<string>(language); const [lastLanguage, setLastLanguage] = useState<string>(language);
// redux // redux
const data = useSelector<RootState, RootState['post']['data']>((state) => state.post.data); const data = useSelector<RootState, RootState["post"]["data"]>(
(state) => state.post.data
);
const dispatch = useDispatch(); const dispatch = useDispatch();
useEffect(() => { useEffect(() => {
if (!(data.data.id === parseInt(id as string) && lastLanguage === language)) { if (
api.get(data, (data: IPostData['data']) => dispatch(setPost(data))); !(data.data.id === parseInt(id as string) && lastLanguage === language)
) {
api.get(data, (data: IPostData["data"]) => dispatch(setPost(data)));
setLastLanguage(language); setLastLanguage(language);
} }
}, [language, lastLanguage]); }, [language, lastLanguage]);
// SEO // SEO
useEffect(() => { useEffect(() => {
const metaDescription: any = document.querySelector('meta#meta-description'); const metaDescription: any = document.querySelector(
const metaKeywords: any = document.querySelector('meta#meta-keywords'); "meta#meta-description"
const title: any = document.querySelector('title'); );
const metaKeywords: any = document.querySelector("meta#meta-keywords");
const title: any = document.querySelector("title");
try { try {
title.innerText = data.data.powerseo_title; title.innerText = data.data.powerseo_title;
metaDescription.content = data.data.powerseo_description; metaDescription.content = data.data.powerseo_description;
@ -64,7 +70,8 @@ const NewsArticle = () => {
className="news-article" className="news-article"
initial={{ opacity: 0, scale: 0.8 }} initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1, transition: { duration: 0.15 } }} animate={{ opacity: 1, scale: 1, transition: { duration: 0.15 } }}
exit={{ opacity: 0, scale: 0.8, transition: { duration: 0.15 } }}> exit={{ opacity: 0, scale: 0.8, transition: { duration: 0.15 } }}
>
<div className="container"> <div className="container">
<div className="news-article-inner"> <div className="news-article-inner">
{data.data.id > -1 ? ( {data.data.id > -1 ? (
@ -76,13 +83,16 @@ const NewsArticle = () => {
<Link <Link
key={uuidv4()} key={uuidv4()}
to={`/category/${category.id}`} to={`/category/${category.id}`}
className="news-article-category"> className="news-article-category"
>
{category.name} {category.name}
</Link> </Link>
))} ))}
</div> </div>
<div className="news-article-right"> <div className="news-article-right">
<h3 className="news-article-date">{data.data.published_at}</h3> <h3 className="news-article-date">
{data.data.published_at}
</h3>
</div> </div>
</div> </div>
<h2 className="news-article-title">{data.data.title}</h2> <h2 className="news-article-title">{data.data.title}</h2>
@ -104,7 +114,8 @@ const NewsArticle = () => {
</div> </div>
<p <p
className="news-article-text" className="news-article-text"
dangerouslySetInnerHTML={{ __html: data.data.content_html }}></p> dangerouslySetInnerHTML={{ __html: data.data.content_html }}
></p>
<button className="share-btn"> <button className="share-btn">
<Share /> <span>Поделиться</span> <Share /> <span>Поделиться</span>
</button> </button>
@ -112,7 +123,7 @@ const NewsArticle = () => {
) : ( ) : (
<Loader /> <Loader />
)} )}
<Aside type="popular" /> <Aside type="latest" />
</div> </div>
</div> </div>
</motion.div> </motion.div>