diff --git a/src/actions/setData.ts b/src/actions/setData.ts index 66702f2..21a307c 100644 --- a/src/actions/setData.ts +++ b/src/actions/setData.ts @@ -1,5 +1,12 @@ // Types -import { INewsScroll, INewsScrollAction } from "../types/store.types"; +import { + INewsScroll, + INewsScrollAction, + IPostData, + IPostDataAction, +} from "../types/store.types"; + +// NewsScroll export const setNewsScroll = ( data: INewsScroll["data"] @@ -7,3 +14,10 @@ export const setNewsScroll = ( type: "SET_NEWS_SCROLL", payload: data, }); + +// Post + +export const setPost = (data: IPostData["data"]): IPostDataAction => ({ + type: "SET_POST", + payload: data, +}); diff --git a/src/components/global/NewsScroll.tsx b/src/components/global/NewsScroll.tsx index 7a612da..3625b48 100644 --- a/src/components/global/NewsScroll.tsx +++ b/src/components/global/NewsScroll.tsx @@ -15,7 +15,7 @@ import { newsScrollParams } from "../../api/params"; // Types import { IPostsData } from "../../types/data.types"; -import { ILanguage, RootState } from "../../types/store.types"; +import { RootState } from "../../types/store.types"; // Actions import { setNewsScroll } from "../../actions/setData"; @@ -30,13 +30,13 @@ const NewsScroll = ({ title }: Props) => { const [lastLanguage, setLastLanguage] = useState(language); // redux - const data = useSelector( - (state) => state.dataReducer.data + const data = useSelector( + (state) => state.newsScroll.data ); const dispatch = useDispatch(); useEffect(() => { - if (!(data[0].id > -1 && lastLanguage === language)) { + if (!((data as IPostsData[])[0].id > -1 && lastLanguage === language)) { api.get(data, (data: IPostsData[]) => dispatch(setNewsScroll(data))); setLastLanguage(language); } @@ -54,7 +54,7 @@ const NewsScroll = ({ title }: Props) => { ) : null}
{data ? ( - data.map((dataEl) => { + (data as IPostsData[]).map((dataEl) => { return ( { return ( @@ -24,8 +24,10 @@ const ContentSlider = () => { }} modules={[Navigation, Pagination, Autoplay]} pagination={{ - type: 'bullets', - }}> + type: "bullets", + clickable: true, + }} + > diff --git a/src/components/news/NewsArticleImg.tsx b/src/components/news/NewsArticleImg.tsx index ce35517..89acb03 100644 --- a/src/components/news/NewsArticleImg.tsx +++ b/src/components/news/NewsArticleImg.tsx @@ -3,14 +3,12 @@ import { LazyLoadImage } from "react-lazy-load-image-component"; interface IProps { img: string; - title: string; } -const NewsArticleImg = ({ img, title }: IProps) => { +const NewsArticleImg = ({ img }: IProps) => { return (
-
); }; diff --git a/src/components/news/NewsArticleSlider.tsx b/src/components/news/NewsArticleSlider.tsx index 655fba9..9d98902 100644 --- a/src/components/news/NewsArticleSlider.tsx +++ b/src/components/news/NewsArticleSlider.tsx @@ -1,16 +1,18 @@ // Modules import { Swiper, SwiperSlide } from "swiper/react"; import { Navigation, Pagination, Autoplay } from "swiper"; +import { v4 as uuidv4 } from "uuid"; // Components import NewsArticleImg from "./NewsArticleImg"; -// Images -import Placeholder from "../../assets/images/placeholder3.png"; +import { IPostData } from "../../types/store.types"; -import { titlePlaceholder } from "../main/MainContent"; +interface IProps { + images: IPostData["data"]["data"]["featured_images"]; +} -const NewsArticleSlider = () => { +const NewsArticleSlider = ({ images }: IProps) => { return (
{ modules={[Navigation, Pagination, Autoplay]} pagination={{ type: "bullets", + clickable: true, }} > - - - - - - - - - - - - + {images.map((img) => ( + + + + ))}
); diff --git a/src/pages/NewsArticle.tsx b/src/pages/NewsArticle.tsx index 2a38b1a..3e22d03 100644 --- a/src/pages/NewsArticle.tsx +++ b/src/pages/NewsArticle.tsx @@ -1,75 +1,93 @@ // Modules -import { LazyLoadImage } from "react-lazy-load-image-component"; +import { Link, useParams } from "react-router-dom"; +import { useEffect, useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { v4 as uuidv4 } from "uuid"; // Components import Aside from "../components/aside/Aside"; import NewsArticleSlider from "../components/news/NewsArticleSlider"; - -// Images -import placeholder from "../assets/images/placeholder3.png"; +import Loader from "../components/global/Loader"; // Icons import { ReactComponent as Share } from "../assets/icons/share.svg"; +// Types +import { RootState } from "../types/store.types"; +import { IPostData } from "../types/store.types"; + +// Actions +import { setPost } from "../actions/setData"; + +// Api +import { Api } from "../api/Api"; +import { url } from "../url"; + const NewsArticle = () => { + const { id } = useParams(); + + // api + const api = new Api(`${url}/posts/${id}`); + + const language = api.language; + const [lastLanguage, setLastLanguage] = useState(language); + + // redux + const data = useSelector( + (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))); + setLastLanguage(language); + } + }, [language, lastLanguage]); + return (
-
-
-
-

Спорт

-

15:23, 21 января 2023

+ {data.data.id > -1 ? ( +
+
+
+
+ {data.data.categories.map((category) => ( + + {category.name} + + ))} +
+
+

+ {data.data.published_at} +

+
+
+

{data.data.title}

-

- В федерации футбола Туркменистана подвели итоги прошедшего года - и наметили курс на 2023 год -

+
+ +
+

+
-
- -
-

- Lorem ipsum dolor sit amet consectetur. Vestibulum eget elementum - urna tincidunt diam commodo mauris ac sodales. Lorem ipsum dolor - sit amet consectetur. Lorem ipsum dolor sit amet consectetur. - Lorem ipsum dolor sit amet consectetur. Vestibulum eget elementum - urna tincidunt diam commodo mauris ac sodales. Lorem ipsum dolor - sit amet consectetur.
-
Lorem ipsum dolor sit amet consectetur. Lorem ipsum dolor - sit amet consectetur. Vestibulum eget elementum urna tincidunt - diam commodo mauris ac sodales. Lorem ipsum dolor sit amet - consectetur. Lorem ipsum dolor sit amet consectetur. Lorem ipsum - dolor sit amet consectetur. Vestibulum eget elementum urna - tincidunt diam commodo mauris ac sodales. -
-
Lorem ipsum dolor sit amet consectetur. Vestibulum eget - elementum urna tincidunt diam commodo mauris ac sodales. Lorem - ipsum dolor sit amet consectetur. Lorem ipsum dolor sit amet - consectetur. Lorem ipsum dolor sit amet consectetur. -
-
Vestibulum eget elementum urna tincidunt diam commodo - mauris ac sodales. Lorem ipsum dolor sit amet consectetur. Lorem - ipsum dolor sit amet consectetur. Lorem ipsum dolor sit amet - consectetur. Vestibulum eget elementum urna tincidunt diam commodo - mauris ac sodales. -
-
Lorem ipsum dolor sit amet consectetur. Vestibulum eget - elementum urna tincidunt diam commodo mauris ac sodales. Lorem - ipsum dolor sit amet consectetur. Lorem ipsum dolor sit amet - consectetur. Lorem ipsum dolor sit amet consectetur. -
-
Vestibulum eget elementum urna tincidunt diam commodo - mauris ac sodales. Lorem ipsum dolor sit amet consectetur. Lorem - ipsum dolor sit amet consectetur. Lorem ipsum dolor sit amet - consectetur. Vestibulum eget elementum urna tincidunt diam commodo - mauris ac sodales. -

- -
+ ) : ( + + )}
diff --git a/src/reducers/dataReducer.ts b/src/reducers/dataReducer.ts index ea05a76..b3ad928 100644 --- a/src/reducers/dataReducer.ts +++ b/src/reducers/dataReducer.ts @@ -1,7 +1,12 @@ // Types -import { INewsScroll, INewsScrollAction } from "../types/store.types"; +import { + INewsScroll, + INewsScrollAction, + IPostData, + IPostDataAction, +} from "../types/store.types"; -export const postsInitialState = { +export const newsScrollInitialState = { data: [ { id: -1, @@ -46,8 +51,8 @@ export const postsInitialState = { ], }; -export const dataReducer = ( - state: INewsScroll = postsInitialState, +export const newsScrollReducer = ( + state: INewsScroll = newsScrollInitialState, action: INewsScrollAction ) => { switch (action.type) { @@ -59,3 +64,62 @@ export const dataReducer = ( } } }; + +export const postInitialState = { + data: { + data: { + id: -1, + title: "", + slug: "", + excerpt: "", + published_at: "", + featured_images: [ + { + id: -1, + disk_name: "", + file_name: "", + path: "", + extension: "", + }, + { + id: -1, + disk_name: "", + file_name: "", + path: "", + extension: "", + }, + { + id: -1, + disk_name: "", + file_name: "", + path: "", + extension: "", + }, + ], + content_html: "", + categories: [ + { + id: -1, + name: "", + }, + ], + powerseo_title: "", + powerseo_description: "", + powerseo_keywords: "", + }, + }, +}; + +export const postReducer = ( + state: IPostData = postInitialState, + action: IPostDataAction +) => { + switch (action.type) { + case "SET_POST": { + return { ...state, data: action.payload }; + } + default: { + return state; + } + } +}; diff --git a/src/store/data.ts b/src/store/data.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/store/functionality.ts b/src/store/functionality.ts index e82cb7b..d970709 100644 --- a/src/store/functionality.ts +++ b/src/store/functionality.ts @@ -4,12 +4,13 @@ import { combineReducers, configureStore } from "@reduxjs/toolkit"; // Reducers import { activeLinkReducer } from "../reducers/activeLink.reducer"; import { languageReducer } from "../reducers/language.reducer"; -import { dataReducer } from "../reducers/dataReducer"; +import { newsScrollReducer, postReducer } from "../reducers/dataReducer"; export const allReducers = combineReducers({ activeLink: activeLinkReducer, language: languageReducer, - dataReducer, + newsScroll: newsScrollReducer, + post: postReducer, }); export const functionalityStore = configureStore({ diff --git a/src/styles/_news-article.scss b/src/styles/_news-article.scss index 6236488..2fdd389 100644 --- a/src/styles/_news-article.scss +++ b/src/styles/_news-article.scss @@ -20,7 +20,14 @@ .news-article-status { display: flex; - gap: 3.2rem; + gap: 2.4rem; + align-items: center; + justify-content: space-between; +} + +.news-article-left { + display: flex; + gap: 2.4rem; align-items: center; } @@ -47,6 +54,7 @@ } .news-article-image { + min-height: 30rem; img { width: 100%; height: 100%; diff --git a/src/types/store.types.ts b/src/types/store.types.ts index 3de8941..cda4256 100644 --- a/src/types/store.types.ts +++ b/src/types/store.types.ts @@ -4,6 +4,7 @@ import { allReducers } from "../store/functionality"; // Types import { IPostsData } from "./data.types"; +// NavLink export interface ActiveLinkType { active: number; } @@ -12,6 +13,7 @@ export interface ActiveLinkActionType { payload: number; } +// Language export interface ILanguage { title: "RU" | "EN" | "TM"; } @@ -21,6 +23,8 @@ export interface ILanguageAction { payload: "RU" | "EN" | "TM"; } +// NewsScroll + export interface INewsScroll { data: IPostsData[]; } @@ -29,6 +33,19 @@ export interface INewsScrollAction { payload: INewsScroll["data"]; } +// Post + +export interface IPostData { + data: { + data: IPostsData; + }; +} + +export interface IPostDataAction { + type: "SET_POST"; + payload: IPostData["data"]; +} + // ALL TYPES BEFORE THIS LINE ================== export type RootState = ReturnType;