This commit is contained in:
VividTruthKeeper 2023-03-03 14:25:18 +05:00
commit 05b484d0af
27 changed files with 568 additions and 461 deletions

File diff suppressed because one or more lines are too long

120
dist/assets/index-20511609.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
dist/index.html vendored
View File

@ -6,8 +6,8 @@
<meta name="description" id="meta-description" content="" />
<meta name="keywords" id="meta-keywords" content="" />
<title>Türkmenistan Habarlar Portaly</title>
<script type="module" crossorigin src="/assets/index-097f0fa2.js"></script>
<link rel="stylesheet" href="/assets/index-8f4a309c.css">
<script type="module" crossorigin src="/assets/index-20511609.js"></script>
<link rel="stylesheet" href="/assets/index-f119abb1.css">
</head>
<body>
<div id="root"></div>

View File

@ -1,34 +1,35 @@
// Modules
import { Routes, Route, useLocation } from "react-router-dom";
import { AnimatePresence } from "framer-motion";
import ScrollToTop from "./hooks/ScrollToTop";
import { Routes, Route, useLocation } from 'react-router-dom';
import { AnimatePresence } from 'framer-motion';
import ScrollToTop from './hooks/ScrollToTop';
// import { changeLanguage } from "i18next";
// Styles
import "swiper/swiper.css";
import "swiper/css/pagination";
import "swiper/css/navigation";
import "react-lazy-load-image-component/src/effects/opacity.css";
import "react-calendar/dist/Calendar.css";
import "./styles/style.scss";
import 'swiper/swiper.css';
import 'swiper/css/pagination';
import 'swiper/css/navigation';
import 'react-lazy-load-image-component/src/effects/opacity.css';
import 'react-calendar/dist/Calendar.css';
import './styles/style.scss';
// Pages
import Main from "./pages/Main";
import NewsArticle from "./pages/NewsArticle";
import Category from "./pages/Category";
import SearchResult from "./pages/SearchResult";
import AllPosts from "./pages/AllPosts";
import NotFound404 from "./pages/NotFound404";
import Main from './pages/Main';
import NewsArticle from './pages/NewsArticle';
import Category from './pages/Category';
import SearchResult from './pages/SearchResult';
import AllPosts from './pages/AllPosts';
import NotFound404 from './pages/NotFound404';
// import Video from './pages/Video';
// Components
import Header from "./components/header/Header";
import Footer from "./components/footer/Footer";
import { Api } from "./api/Api";
import { useEffect } from "react";
import Header from './components/header/Header';
import Footer from './components/footer/Footer';
import { Api } from './api/Api';
import { useEffect } from 'react';
const App = () => {
const location = useLocation();
const language = new Api("").language;
const language = new Api('').language;
// useEffect(() => {
// changeLanguage(language);
@ -36,14 +37,14 @@ const App = () => {
useEffect(() => {
try {
const title = document.querySelector("title") as any;
language === "EN"
? (title.innerText = "Turkmenistan News Portal")
: language === "RU"
? (title.innerText = "Туркменистан новостной портал")
: language === "TM"
? (title.innerText = "Türkmenistan Habarlar Portaly")
: "Türkmenistan Habarlar Portaly";
const title = document.querySelector('title') as any;
language === 'EN'
? (title.innerText = 'Turkmenistan News Portal')
: language === 'RU'
? (title.innerText = 'Туркменистан новостной портал')
: language === 'TM'
? (title.innerText = 'Türkmenistan Habarlar Portaly')
: 'Türkmenistan Habarlar Portaly';
} catch (err) {
console.log(err);
}
@ -59,7 +60,7 @@ const App = () => {
<Route path="/category/:category" element={<Category />} />
<Route path="/news/:id" element={<NewsArticle />} />
<Route path="/search/:word" element={<SearchResult />} />
<Route path="/all/:category" element={<AllPosts />} />
<Route path="/all" element={<AllPosts />} />
<Route path="*" element={<NotFound404 />} />
</Routes>
</AnimatePresence>

View File

@ -8,34 +8,35 @@ import {
IPostDataAction,
ISearchResult,
ISearchResultAction,
} from "../types/store.types";
IVideoData,
IVideoDataAction,
} from '../types/store.types';
// NewsScroll
export const setNewsScroll = (
data: INewsScroll["data"]
): INewsScrollAction => ({
type: "SET_NEWS_SCROLL",
export const setNewsScroll = (data: INewsScroll['data']): INewsScrollAction => ({
type: 'SET_NEWS_SCROLL',
payload: data,
});
export const setSearchResult = (
data: ISearchResult["data"]
): ISearchResultAction => ({
type: "SET_SEARCH_DATA",
export const setSearchResult = (data: ISearchResult['data']): ISearchResultAction => ({
type: 'SET_SEARCH_DATA',
payload: data,
});
// Post
export const setPost = (data: IPostData["data"]): IPostDataAction => ({
type: "SET_POST",
export const setPost = (data: IPostData['data']): IPostDataAction => ({
type: 'SET_POST',
payload: data,
});
export const setFeatured = (
data: IFeaturedData["data"]
): IFeaturedDataAction => ({
type: "SET_FEATURED",
export const setVideo = (data: IVideoData['data']): IVideoDataAction => ({
type: 'SET_VIDEO',
payload: data,
});
export const setFeatured = (data: IFeaturedData['data']): IFeaturedDataAction => ({
type: 'SET_FEATURED',
payload: data,
});

View File

@ -11,6 +11,17 @@ export const newsScrollParams: IurlParamAdder[] = [
},
];
export const asideParams: IurlParamAdder[] = [
{
name: "count",
value: 5,
},
{
name: "page",
value: 1,
},
];
export const categoriesParams: IurlParamAdder[] = [
{
name: "count",
@ -36,3 +47,18 @@ export const featuredParams: IurlParamAdder[] = [
value: "true",
},
];
export const videoParams: IurlParamAdder[] = [
{
name: "count",
value: 10,
},
{
name: "page",
value: 1,
},
{
name: "type",
value: "video",
},
];

View File

@ -1,49 +1,79 @@
// 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";
// 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";
interface Props {
type: "latest" | "popular";
}
interface IData {
data: IPostsData[];
}
const Aside = ({ type }: Props) => {
const api = new Api(
url + `${type === "popular" ? "/popular" : ""}/posts`,
asideParams
);
const [data, setData] = useState<IData>();
useEffect(() => {
api.get(data, setData);
}, []);
const Aside = () => {
return (
<div className="aside">
<div className="aside-wrapper">
<SectionTitle title="Самое читаемое" />
<SectionTitle
title={type === "latest" ? "Последние новости" : "Самое читаемое"}
/>
<div className="aside-inner">
{type === "popular" ? (
data ? (
(data as any).data.map((el: any) => {
return (
<AsideNews
title="Президент Туркменистана провёл рабочее совещание по цифровой системе"
date="12.01.2023"
category="Политика"
img={""}
link=""
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 (
<AsideNews
title="Президент Туркменистана провёл рабочее совещание по цифровой системе"
date="12.01.2023"
category="Политика"
img={""}
link=""
/>
<AsideNews
title="Президент Туркменистана провёл рабочее совещание по цифровой системе"
date="12.01.2023"
category="Политика"
img={""}
link=""
/>
<AsideNews
title="Президент Туркменистана провёл рабочее совещание по цифровой системе"
date="12.01.2023"
category="Политика"
img={""}
link=""
/>
<AsideNews
title="Президент Туркменистана провёл рабочее совещание по цифровой системе"
date="12.01.2023"
category="Политика"
img={""}
link=""
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 />
)}
</div>
</div>
<div className="aside-calendar">

View File

@ -13,12 +13,12 @@ interface Props {
date: string;
img: string;
category: string;
link: string;
id: number;
}
const AsideNews = ({ title, date, img, category, link }: Props) => {
const AsideNews = ({ title, date, img, category, id }: Props) => {
return (
<Link to={link} className="aside-news">
<Link to={`/news/${id}`} className="aside-news">
<div className="aside-news-wrapper">
<div className="aside-news-image">
<LazyLoadImage

View File

@ -1,5 +1,5 @@
// Modules
import { Link } from "react-router-dom";
// import { Link } from "react-router-dom";
interface Props {
title: string;

View File

@ -7,6 +7,7 @@ import { useSelector, useDispatch } from "react-redux";
import News from "../news/News";
import SectionTitle from "./SectionTitle";
import Loader from "./Loader";
import Pagination from "./Pagination";
// Api
import { url } from "../../url";
@ -23,11 +24,14 @@ 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;
count ? (params[0].value = count) : null;
const api = new Api(url + "/posts", params);
const language = api.language;
@ -61,7 +65,7 @@ const NewsScroll = ({ title, category }: Props) => {
useEffect(() => {
const filtered = rawData.filter((el, index) => {
if (index > 0) {
if (index >= 0) {
return el;
}
});
@ -74,13 +78,15 @@ const NewsScroll = ({ title, category }: Props) => {
{title === true ? (
<SectionTitle
title="Лента новостей"
linkData={{ link: "/all/null", 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()}
@ -96,6 +102,24 @@ const NewsScroll = ({ title, category }: Props) => {
}
/>
);
}
} 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,30 +1,32 @@
// Modules
import { LazyLoadImage } from "react-lazy-load-image-component";
import { Link } from "react-router-dom";
import placeholder from "../../assets/images/placeholder.webp";
import { LazyLoadImage } from 'react-lazy-load-image-component';
import { Link } from 'react-router-dom';
import placeholder from '../../assets/images/placeholder.webp';
interface IProps {
type?: "small" | "big";
type?: 'small' | 'big';
img: string;
title: string;
id: number;
}
const ContentItem = ({ type = "small", img, title, id }: IProps) => {
const ContentItem = ({ type = 'small', img, title, id }: IProps) => {
return (
<div className={`main-content-item main-content-item__${type}`}>
<div
className={`main-content-item main-content-item__${type}`}
style={{
backgroundImage: `url(${img})`,
backgroundRepeat: 'no-repeat',
backgroundSize: 'cover',
}}>
<LazyLoadImage
src={img}
alt={img}
effect="opacity"
useIntersectionObserver
placeholderSrc={placeholder}
style={{
backgroundImage: `url(${img})`,
backgroundRepeat: "no-repeat",
backgroundSize: "cover",
}}
/>
<div className="bg-blur"></div>
<Link to={`/news/${id}`} className="main-content-item-overlay">
<h2>{title}</h2>
</Link>

View File

@ -1,29 +1,29 @@
// Modules
import { useEffect, useState } from "react";
import { LazyLoadComponent } from "react-lazy-load-image-component";
import { useSelector, useDispatch } from "react-redux";
import { useEffect, useState } from 'react';
import { LazyLoadComponent } from 'react-lazy-load-image-component';
import { useSelector, useDispatch } from 'react-redux';
// Components
import ContentItem from "./ContentItem";
import SectionTitle from "../global/SectionTitle";
import ContentSlider from "./ContentSlider";
import Loader from "../global/Loader";
import ContentItem from './ContentItem';
import SectionTitle from '../global/SectionTitle';
import ContentSlider from './ContentSlider';
import Loader from '../global/Loader';
// Types
import { RootState } from "../../types/store.types";
import { RootState } from '../../types/store.types';
// Api
import { url } from "../../url";
import { Api } from "../../api/Api";
import { featuredParams } from "../../api/params";
import { setFeatured } from "../../actions/setData";
import { url } from '../../url';
import { Api } from '../../api/Api';
import { featuredParams } from '../../api/params';
import { setFeatured } from '../../actions/setData';
const MainContent = () => {
const dispatch = useDispatch();
const data = useSelector<RootState, RootState["featured"]["data"]>(
(state) => state.featured.data
const data = useSelector<RootState, RootState['featured']['data']>(
(state) => state.featured.data,
);
const api = new Api(url + "/posts", featuredParams);
const api = new Api(url + '/posts', featuredParams);
const language = api.language;
const [lastLanguage, setLastLanguage] = useState<typeof language>(language);
@ -52,49 +52,29 @@ const MainContent = () => {
<ContentItem
id={data[0].id}
type="big"
img={
data[0].featured_images
? data[0].featured_images[0].path
: ""
}
img={data[0].featured_images[0] ? data[0].featured_images[0].path : ''}
title={data[0].title}
/>
<ContentItem
id={data[1].id}
img={
data[1].featured_images
? data[1].featured_images[0].path
: ""
}
img={data[1].featured_images[0] ? data[1].featured_images[0].path : ''}
title={data[1].title}
/>
</div>
<div className="main-content-bottom">
<ContentItem
id={data[2].id}
img={
data[2].featured_images
? data[2].featured_images[0].path
: ""
}
img={data[2].featured_images[0] ? data[2].featured_images[0].path : ''}
title={data[2].title}
/>
<ContentItem
id={data[3].id}
img={
data[3].featured_images
? data[3].featured_images[0].path
: ""
}
img={data[3].featured_images[0] ? data[3].featured_images[0].path : ''}
title={data[3].title}
/>
<ContentItem
id={data[4].id}
img={
data[4].featured_images
? data[4].featured_images[0].path
: ""
}
img={data[4].featured_images[0] ? data[4].featured_images[0].path : ''}
title={data[4].title}
/>
</div>

View File

@ -1,58 +1,62 @@
// Modules
// import { v4 as uuiv4 } from "uuid";
import { useEffect, useState } from 'react';
import { v4 as uuiv4 } from 'uuid';
import { useSelector, useDispatch } from 'react-redux';
// Components
import SectionTitle from "../global/SectionTitle";
// import VideosItem from "./VideosItem";
// // Videos
// import VideoPlaceholder from "../../assets/videos/placeholder.mp4";
import SectionTitle from '../global/SectionTitle';
import VideosItem from './VideosItem';
// Types
// import { videosDataType } from "../../types/videos.types";
import { RootState } from '../../types/store.types';
// const videosData: videosDataType[] = [
// {
// placeholder: Placeholder,
// url: VideoPlaceholder,
// },
// {
// placeholder: Placeholder,
// url: VideoPlaceholder,
// },
// {
// placeholder: Placeholder,
// url: VideoPlaceholder,
// },
// {
// placeholder: Placeholder,
// url: VideoPlaceholder,
// },
// ];
// Api
import { Api } from '../../api/Api';
import { url } from '../../url';
import { videoParams } from '../../api/params';
// Actions
import { setVideo } from '../../actions/setData';
const Videos = () => {
const data = useSelector<RootState, RootState['video']['data']>((state) => state.video.data);
const api = new Api(url + '/posts', videoParams);
const language = api.language;
const dispatch = useDispatch();
const [lastLanguage, setLastLanguage] = useState<typeof language>(language);
useEffect(() => {
if (!(lastLanguage === language && data[0].id > -1)) {
api.get(data, (data) => dispatch(setVideo(data)));
setLastLanguage(language);
}
}, [lastLanguage, language]);
return (
<section className="videos">
{/* <div className="container"> */}
<div className="videos-inner">
<SectionTitle
title="Видео"
givenClass="videos"
linkData={{ link: "/", title: "Посмотреть все" }}
linkData={{ link: '/all?type=video', title: 'Посмотреть все' }}
/>
<div className="videos-items">
{/* {videosData.map((videosDataItem: videosDataType) => {
{data.map((videosDataItem, index) => {
if (index <= 4) {
return (
<VideosItem
key={uuiv4()}
url={videosDataItem.url}
placeholder={videosDataItem.placeholder}
url={videosDataItem.video || ''}
placeholder={
videosDataItem.featured_images[0] ? videosDataItem.featured_images[0].path : ''
}
date={videosDataItem.published_at}
excerpt={videosDataItem.excerpt}
/>
);
})} */}
}
})}
</div>
</div>
{/* </div> */}
</section>
);
};

View File

@ -1,26 +1,20 @@
// Modules
import ReactPlayer from "react-player";
import { LazyLoadComponent } from "react-lazy-load-image-component";
import ReactPlayer from 'react-player';
import { LazyLoadComponent } from 'react-lazy-load-image-component';
// Types
import { videosDataType } from "../../types/videos.types";
import { videosDataType } from '../../types/videos.types';
const VideosItem = ({ url, placeholder }: videosDataType) => {
const VideosItem = ({ url, placeholder, date, excerpt }: videosDataType) => {
return (
<div className="videos-item">
<LazyLoadComponent useIntersectionObserver>
<div className="videos-item-video">
<ReactPlayer
url={url}
controls
light={placeholder}
width="100%"
height="100%"
/>
<ReactPlayer url={url} controls light={placeholder} width="100%" height="100%" />
</div>
<div className="videos-item-data">
<span>11.01.2023</span>
<p>В Туркменистане отметили Новый год</p>
<span>{date}</span>
<p>{excerpt}</p>
</div>
</LazyLoadComponent>
</div>

View File

@ -1,52 +1,52 @@
// Modules
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import { useState, useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
// Api
import { Api } from "../api/Api";
import { url } from "../url";
import { Api } from '../api/Api';
import { url } from '../url';
// Components
import CustomNewsScroll from "../components/global/CustomNewsScroll";
import Loader from "../components/global/Loader";
import CustomNewsScroll from '../components/global/CustomNewsScroll';
import Loader from '../components/global/Loader';
// Types
import { IurlParamAdder } from "../types/api.types";
import { IPostsData } from "../types/data.types";
import { IurlParamAdder } from '../types/api.types';
import { IPostsData } from '../types/data.types';
import SectionTitle from '../components/global/SectionTitle';
const AllPosts = () => {
const { category } = useParams();
const categoryParam =
category !== ("null" || undefined) ? (category as string) : "";
const [searchParams, setSearchParams] = useSearchParams();
const type = searchParams.get('type') || null;
const [params, setParams] = useState<IurlParamAdder[]>(
category !== ("null" || undefined)
type !== null
? [
{
name: "count",
name: 'count',
value: 10,
},
{
name: "page",
name: 'page',
value: 1,
},
{
name: "category",
value: categoryParam,
name: 'type',
value: type,
},
]
: [
{
name: "count",
name: 'count',
value: 10,
},
{
name: "page",
name: 'page',
value: 1,
},
]
],
);
const api = new Api(url + "/posts", params);
const api = new Api(url + '/posts', params);
const language = api.language;
@ -68,11 +68,8 @@ const AllPosts = () => {
<main className="all">
<div className="container">
<div className="all-inner">
{data ? (
<CustomNewsScroll data={data} pagination={false} />
) : (
<Loader />
)}
{type === 'video' ? <SectionTitle title={'Видео'} /> : null}
{data ? <CustomNewsScroll data={data} pagination={false} /> : <Loader />}
</div>
</div>
</main>

View File

@ -45,10 +45,15 @@ const Category = () => {
) : (
<Loader />
)}
<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 />
<Aside type="latest" />
</div>
</div>
</div>

View File

@ -4,7 +4,7 @@ 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 Videos from "../components/videos/Videos";
import MainContent from "../components/main/MainContent";
const Main = () => {
@ -22,9 +22,9 @@ const Main = () => {
<MainContent />
<div className="news-outer-wrapper">
<NewsScroll title={true} />
<Aside />
<Aside type="popular" />
</div>
{/* <Videos /> */}
<Videos />
</div>
</div>
</div>

View File

@ -9,7 +9,7 @@ import { motion } from "framer-motion";
import Aside from "../components/aside/Aside";
import NewsArticleSlider from "../components/news/NewsArticleSlider";
import Loader from "../components/global/Loader";
import VideosItem from "../components/videos/VideosItem";
// import VideosItem from "../components/videos/VideosItem";
// Icons
import { ReactComponent as Share } from "../assets/icons/share.svg";
@ -123,7 +123,7 @@ const NewsArticle = () => {
) : (
<Loader />
)}
<Aside />
<Aside type="latest" />
</div>
</div>
</motion.div>

View File

@ -8,7 +8,9 @@ import {
IPostDataAction,
ISearchResult,
ISearchResultAction,
} from "../types/store.types";
IVideoData,
IVideoDataAction,
} from '../types/store.types';
// NewsScroll
@ -16,54 +18,54 @@ export const newsScrollInitialState = {
data: [
{
id: -1,
title: "",
slug: "",
excerpt: "",
published_at: "",
title: '',
slug: '',
excerpt: '',
published_at: '',
featured_images: [
{
id: -1,
disk_name: "",
file_name: "",
path: "",
extension: "",
disk_name: '',
file_name: '',
path: '',
extension: '',
},
{
id: -1,
disk_name: "",
file_name: "",
path: "",
extension: "",
disk_name: '',
file_name: '',
path: '',
extension: '',
},
{
id: -1,
disk_name: "",
file_name: "",
path: "",
extension: "",
disk_name: '',
file_name: '',
path: '',
extension: '',
},
],
content_html: "",
content_html: '',
categories: [
{
id: -1,
name: "",
name: '',
},
],
video: null,
powerseo_title: "",
powerseo_description: "",
powerseo_keywords: "",
powerseo_title: '',
powerseo_description: '',
powerseo_keywords: '',
},
],
};
export const newsScrollReducer = (
state: INewsScroll = newsScrollInitialState,
action: INewsScrollAction
action: INewsScrollAction,
) => {
switch (action.type) {
case "SET_NEWS_SCROLL": {
case 'SET_NEWS_SCROLL': {
return { ...state, data: action.payload };
}
default: {
@ -78,54 +80,51 @@ export const postInitialState = {
data: {
data: {
id: -1,
title: "",
slug: "",
excerpt: "",
published_at: "",
title: '',
slug: '',
excerpt: '',
published_at: '',
video: null,
featured_images: [
{
id: -1,
disk_name: "",
file_name: "",
path: "",
extension: "",
disk_name: '',
file_name: '',
path: '',
extension: '',
},
{
id: -1,
disk_name: "",
file_name: "",
path: "",
extension: "",
disk_name: '',
file_name: '',
path: '',
extension: '',
},
{
id: -1,
disk_name: "",
file_name: "",
path: "",
extension: "",
disk_name: '',
file_name: '',
path: '',
extension: '',
},
],
content_html: "",
content_html: '',
categories: [
{
id: -1,
name: "",
name: '',
},
],
powerseo_title: "",
powerseo_description: "",
powerseo_keywords: "",
powerseo_title: '',
powerseo_description: '',
powerseo_keywords: '',
},
},
};
export const postReducer = (
state: IPostData = postInitialState,
action: IPostDataAction
) => {
export const postReducer = (state: IPostData = postInitialState, action: IPostDataAction) => {
switch (action.type) {
case "SET_POST": {
case 'SET_POST': {
return { ...state, data: action.payload };
}
default: {
@ -138,54 +137,54 @@ export const featuredInitialState = {
data: [
{
id: -1,
title: "",
slug: "",
excerpt: "",
published_at: "",
title: '',
slug: '',
excerpt: '',
published_at: '',
video: null,
featured_images: [
{
id: -1,
disk_name: "",
file_name: "",
path: "",
extension: "",
disk_name: '',
file_name: '',
path: '',
extension: '',
},
{
id: -1,
disk_name: "",
file_name: "",
path: "",
extension: "",
disk_name: '',
file_name: '',
path: '',
extension: '',
},
{
id: -1,
disk_name: "",
file_name: "",
path: "",
extension: "",
disk_name: '',
file_name: '',
path: '',
extension: '',
},
],
content_html: "",
content_html: '',
categories: [
{
id: -1,
name: "",
name: '',
},
],
powerseo_title: "",
powerseo_description: "",
powerseo_keywords: "",
powerseo_title: '',
powerseo_description: '',
powerseo_keywords: '',
},
],
};
export const featuredReducer = (
state: IFeaturedData = featuredInitialState,
action: IFeaturedDataAction
action: IFeaturedDataAction,
) => {
switch (action.type) {
case "SET_FEATURED": {
case 'SET_FEATURED': {
return { ...state, data: action.payload };
}
default: {
@ -196,10 +195,10 @@ export const featuredReducer = (
export const searchDataReducer = (
state: ISearchResult = newsScrollInitialState,
action: ISearchResultAction
action: ISearchResultAction,
) => {
switch (action.type) {
case "SET_SEARCH_DATA": {
case 'SET_SEARCH_DATA': {
return { data: action.payload };
}
default: {
@ -207,3 +206,17 @@ export const searchDataReducer = (
}
}
};
export const videoReducer = (
state: IVideoData = newsScrollInitialState,
action: IVideoDataAction,
) => {
switch (action.type) {
case 'SET_VIDEO': {
return { ...state, data: action.payload };
}
default: {
return state;
}
}
};

View File

@ -1,16 +1,17 @@
// Modules
import { combineReducers, configureStore } from "@reduxjs/toolkit";
import { combineReducers, configureStore } from '@reduxjs/toolkit';
// Reducers
import { activeLinkReducer } from "../reducers/activeLink.reducer";
import { languageReducer } from "../reducers/language.reducer";
import { activeLinkReducer } from '../reducers/activeLink.reducer';
import { languageReducer } from '../reducers/language.reducer';
import {
newsScrollReducer,
postReducer,
searchDataReducer,
featuredReducer,
} from "../reducers/dataReducer";
import { searchReducer } from "../reducers/searchReducer";
videoReducer,
} from '../reducers/dataReducer';
import { searchReducer } from '../reducers/searchReducer';
export const allReducers = combineReducers({
activeLink: activeLinkReducer,
@ -20,6 +21,7 @@ export const allReducers = combineReducers({
search: searchReducer,
searchData: searchDataReducer,
featured: featuredReducer,
video: videoReducer,
});
export const functionalityStore = configureStore({

View File

@ -31,8 +31,9 @@
.aside-news-status {
display: flex;
align-items: center;
justify-content: space-between;
// align-items: center;
gap: 0.4rem;
flex-direction: column;
}
.aside-news-link {
@ -51,6 +52,8 @@
.aside-news-image {
display: block;
max-width: 16.4rem;
max-height: 12rem;
width: 100%;
height: 100%;

View File

@ -27,6 +27,20 @@
@include wh100;
overflow: hidden;
.bg-blur {
backdrop-filter: blur(0.3rem);
z-index: 2;
position: absolute;
top: 0;
left: 0%;
@include wh100;
}
img {
position: relative;
z-index: 3;
}
span {
display: block !important;
@include wh100;
@ -42,15 +56,11 @@
top: 0;
left: 0;
@include wh100;
background: linear-gradient(
180deg,
rgba(0, 0, 0, 0) 50%,
rgba(0, 0, 0, 0.7) 100%
);
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.7) 100%);
display: flex;
padding: 1.6rem;
align-items: flex-end;
z-index: 2;
z-index: 4;
h2 {
color: $white;

View File

@ -216,7 +216,7 @@
.inner {
overflow: hidden;
display: grid;
grid-template-columns: 2.4rem 8rem 1rem 18rem;
grid-template-columns: 2.4rem 9rem 1rem 18rem;
gap: 0.8rem;
}
p {
@ -230,7 +230,7 @@
white-space: nowrap;
font-size: 1.6rem;
color: inherit;
font-family: "Raleway", sans-serif;
font-family: 'Raleway', sans-serif;
-webkit-user-drag: none;
white-space: normal;
text-align: center;

View File

@ -1,7 +1,7 @@
.news-wrapper {
display: grid;
grid-template-columns: 32rem 1fr;
grid-template-rows: 20rem;
grid-template-rows: 22rem;
gap: 1.6rem;
.loader {

View File

@ -1,26 +1,26 @@
// Reducers
import { allReducers } from "../store/functionality";
import { allReducers } from '../store/functionality';
// Types
import { IPostsData } from "./data.types";
import { IPostsData } from './data.types';
// NavLink
export interface ActiveLinkType {
active: number;
}
export interface ActiveLinkActionType {
type: "SET_ACTIVE_LINK";
type: 'SET_ACTIVE_LINK';
payload: number;
}
// Language
export interface ILanguage {
title: "RU" | "EN" | "TM";
title: 'RU' | 'EN' | 'TM';
}
export interface ILanguageAction {
type: "SET_LANGUAGE";
payload: "RU" | "EN" | "TM";
type: 'SET_LANGUAGE';
payload: 'RU' | 'EN' | 'TM';
}
// NewsScroll
@ -29,8 +29,8 @@ export interface INewsScroll {
data: IPostsData[];
}
export interface INewsScrollAction {
type: "SET_NEWS_SCROLL";
payload: INewsScroll["data"];
type: 'SET_NEWS_SCROLL';
payload: INewsScroll['data'];
}
// Post
@ -42,16 +42,24 @@ export interface IPostData {
}
export interface IPostDataAction {
type: "SET_POST";
payload: IPostData["data"];
type: 'SET_POST';
payload: IPostData['data'];
}
export interface IVideoData {
data: IPostsData[];
}
export interface IVideoDataAction {
type: 'SET_VIDEO';
payload: INewsScroll['data'];
}
export interface IFeaturedData {
data: IPostsData[];
}
export interface IFeaturedDataAction {
type: "SET_FEATURED";
payload: IFeaturedData["data"];
type: 'SET_FEATURED';
payload: IFeaturedData['data'];
}
//
@ -60,16 +68,16 @@ export interface ISearchData {
value: string;
}
export interface ISearchDataAction {
type: "SET_SEARCH";
payload: ISearchData["value"];
type: 'SET_SEARCH';
payload: ISearchData['value'];
}
export interface ISearchResult {
data: IPostsData[];
}
export interface ISearchResultAction {
type: "SET_SEARCH_DATA";
payload: ISearchResult["data"];
type: 'SET_SEARCH_DATA';
payload: ISearchResult['data'];
}
// ALL TYPES BEFORE THIS LINE ==================

View File

@ -1,4 +1,6 @@
export interface videosDataType {
url: string;
placeholder: string;
date: string;
excerpt: string;
}