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[] = [
{
name: 'count',
name: "count",
value: 5,
},
{
name: 'page',
name: "page",
value: 1,
},
];
export const AsideParams: IurlParamAdder[] = [
export const asideParams: IurlParamAdder[] = [
{
name: 'count',
name: "count",
value: 5,
},
{
name: 'page',
name: "page",
value: 1,
},
];
export const categoriesParams: IurlParamAdder[] = [
{
name: 'count',
name: "count",
value: 100,
},
{
name: 'page',
name: "page",
value: 1,
},
];
export const featuredParams: IurlParamAdder[] = [
{
name: 'count',
name: "count",
value: 5,
},
{
name: 'page',
name: "page",
value: 1,
},
{
name: 'featured',
value: 'true',
name: "featured",
value: "true",
},
];
export const videoParams: IurlParamAdder[] = [
{
name: 'count',
name: "count",
value: 10,
},
{
name: 'page',
name: "page",
value: 1,
},
{
name: 'type',
value: 'video',
name: "type",
value: "video",
},
];

View File

@ -1,37 +1,32 @@
// 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 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 Ipost {
id: number;
title: string;
img: string;
published_at: string | number;
category: string;
}
interface Idata {
interface IData {
data: IPostsData[];
}
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(() => {
api.get(data, setData);
@ -40,17 +35,39 @@ const Aside = ({ type }: Props) => {
return (
<div className="aside">
<div className="aside-wrapper">
<SectionTitle title={type === 'latest' ? 'Последние новости' : 'Самое читаемое'} />
<SectionTitle
title={type === "latest" ? "Последние новости" : "Самое читаемое"}
/>
<div className="aside-inner">
{data ? (
data.data.map((el) => {
{type === "popular" ? (
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 : ''}
img={
el.featured_images[0] ? el.featured_images[0].path : ""
}
id={el.id}
/>
);
})
) : (
<Loader />
)
) : data ? (
(data as any).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}
/>
);
})

View File

@ -1,23 +1,24 @@
// Modules
import { Link } from 'react-router-dom';
import { LazyLoadImage } from 'react-lazy-load-image-component';
import { Link } from "react-router-dom";
import { LazyLoadImage } from "react-lazy-load-image-component";
// 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;
date: string;
img: string;
category: string;
id: number;
}
const AsideNews = ({ title, date, img, category }: Props) => {
const AsideNews = ({ title, date, img, category, id }: Props) => {
return (
<div className="aside-news">
<Link to={`/news/${id}`} className="aside-news">
<div className="aside-news-wrapper">
<div className="aside-news-image">
<LazyLoadImage
@ -38,7 +39,7 @@ const AsideNews = ({ title, date, img, category }: Props) => {
</div>
</div>
</div>
</div>
</Link>
);
};

View File

@ -1,42 +1,45 @@
// Modules
import { useEffect, useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import { useSelector, useDispatch } from 'react-redux';
import { useEffect, useState } from "react";
import { v4 as uuidv4 } from "uuid";
import { useSelector, useDispatch } from "react-redux";
// Components
import News from '../news/News';
import SectionTitle from './SectionTitle';
import Loader from './Loader';
import Pagination from './Pagination';
import News from "../news/News";
import SectionTitle from "./SectionTitle";
import Loader from "./Loader";
import Pagination from "./Pagination";
// Api
import { url } from '../../url';
import { Api } from '../../api/Api';
import { newsScrollParams } from '../../api/params';
import { url } from "../../url";
import { Api } from "../../api/Api";
import { newsScrollParams } from "../../api/params";
// Types
import { IPostsData } from '../../types/data.types';
import { RootState } from '../../types/store.types';
import { IPostsData } from "../../types/data.types";
import { RootState } from "../../types/store.types";
// Actions
import { setNewsScroll } from '../../actions/setData';
import { setNewsScroll } from "../../actions/setData";
interface Props {
title: boolean;
category?: number;
count?: number;
avoidFirst?: boolean;
}
const NewsScroll = ({ title, category }: Props) => {
const NewsScroll = ({ title, category, count, avoidFirst }: Props) => {
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 [lastLanguage, setLastLanguage] = useState<string>(language);
// redux
const rawData = useSelector<RootState, RootState['newsScroll']['data']>(
(state) => state.newsScroll.data,
const rawData = useSelector<RootState, RootState["newsScroll"]["data"]>(
(state) => state.newsScroll.data
);
const dispatch = useDispatch();
@ -47,8 +50,12 @@ const NewsScroll = ({ title, category }: Props) => {
useEffect(() => {
if (rawData.length > 0) {
if (!((rawData as IPostsData[])[0].id > -1 && lastLanguage === language)) {
api.get(rawData, (rawData: IPostsData[]) => dispatch(setNewsScroll(rawData)));
if (
!((rawData as IPostsData[])[0].id > -1 && lastLanguage === language)
) {
api.get(rawData, (rawData: IPostsData[]) =>
dispatch(setNewsScroll(rawData))
);
setLastLanguage(language);
}
}
@ -71,13 +78,15 @@ const NewsScroll = ({ title, category }: Props) => {
{title === true ? (
<SectionTitle
title="Лента новостей"
linkData={{ link: '/all', title: 'Посмотреть все' }}
linkData={{ link: "/all", title: "Посмотреть все" }}
/>
) : null}
<div className="news-scroll-inner">
{filteredData.length > 0 ? (
(filteredData as IPostsData[])[0].id > -1 ? (
(filteredData as IPostsData[]).map((dataEl, index) => {
if (avoidFirst) {
if (index > 0) {
return (
<News
key={uuidv4()}
@ -86,9 +95,31 @@ const NewsScroll = ({ title, category }: Props) => {
text={dataEl.excerpt}
date={dataEl.published_at}
categories={dataEl.categories}
img={dataEl.featured_images[0] ? dataEl.featured_images[0].path : ''}
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 />

View File

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

View File

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

View File

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