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

View File

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

View File

@ -8,34 +8,35 @@ import {
IPostDataAction, IPostDataAction,
ISearchResult, ISearchResult,
ISearchResultAction, ISearchResultAction,
} from "../types/store.types"; IVideoData,
IVideoDataAction,
} from '../types/store.types';
// NewsScroll // NewsScroll
export const setNewsScroll = ( export const setNewsScroll = (data: INewsScroll['data']): INewsScrollAction => ({
data: INewsScroll["data"] type: 'SET_NEWS_SCROLL',
): INewsScrollAction => ({
type: "SET_NEWS_SCROLL",
payload: data, payload: data,
}); });
export const setSearchResult = ( export const setSearchResult = (data: ISearchResult['data']): ISearchResultAction => ({
data: ISearchResult["data"] type: 'SET_SEARCH_DATA',
): ISearchResultAction => ({
type: "SET_SEARCH_DATA",
payload: data, payload: data,
}); });
// Post // Post
export const setPost = (data: IPostData["data"]): IPostDataAction => ({ export const setPost = (data: IPostData['data']): IPostDataAction => ({
type: "SET_POST", type: 'SET_POST',
payload: data, payload: data,
}); });
export const setFeatured = ( export const setVideo = (data: IVideoData['data']): IVideoDataAction => ({
data: IFeaturedData["data"] type: 'SET_VIDEO',
): IFeaturedDataAction => ({ payload: data,
type: "SET_FEATURED", });
export const setFeatured = (data: IFeaturedData['data']): IFeaturedDataAction => ({
type: 'SET_FEATURED',
payload: data, 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[] = [ export const categoriesParams: IurlParamAdder[] = [
{ {
name: "count", name: "count",
@ -36,3 +47,18 @@ export const featuredParams: IurlParamAdder[] = [
value: "true", 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 // 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 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 ( return (
<div className="aside"> <div className="aside">
<div className="aside-wrapper"> <div className="aside-wrapper">
<SectionTitle title="Самое читаемое" /> <SectionTitle
title={type === "latest" ? "Последние новости" : "Самое читаемое"}
/>
<div className="aside-inner"> <div className="aside-inner">
<AsideNews {type === "popular" ? (
title="Президент Туркменистана провёл рабочее совещание по цифровой системе" data ? (
date="12.01.2023" (data as any).data.map((el: any) => {
category="Политика" return (
img={""} <AsideNews
link="" key={uuidv4()}
/> title={el.title}
<AsideNews date={el.published_at}
title="Президент Туркменистана провёл рабочее совещание по цифровой системе" category={el.categories[0].name}
date="12.01.2023" img={
category="Политика" el.featured_images[0] ? el.featured_images[0].path : ""
img={""} }
link="" id={el.id}
/> />
<AsideNews );
title="Президент Туркменистана провёл рабочее совещание по цифровой системе" })
date="12.01.2023" ) : (
category="Политика" <Loader />
img={""} )
link="" ) : data ? (
/> (data as any).map((el: any) => {
<AsideNews return (
title="Президент Туркменистана провёл рабочее совещание по цифровой системе" <AsideNews
date="12.01.2023" key={uuidv4()}
category="Политика" title={el.title}
img={""} date={el.published_at}
link="" category={el.categories[0].name}
/> img={el.featured_images[0] ? el.featured_images[0].path : ""}
<AsideNews id={el.id}
title="Президент Туркменистана провёл рабочее совещание по цифровой системе" />
date="12.01.2023" );
category="Политика" })
img={""} ) : (
link="" <Loader />
/> )}
</div> </div>
</div> </div>
<div className="aside-calendar"> <div className="aside-calendar">

View File

@ -13,12 +13,12 @@ interface Props {
date: string; date: string;
img: string; img: string;
category: string; category: string;
link: string; id: number;
} }
const AsideNews = ({ title, date, img, category, link }: Props) => { const AsideNews = ({ title, date, img, category, id }: Props) => {
return ( return (
<Link to={link} 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

View File

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

View File

@ -7,6 +7,7 @@ import { useSelector, useDispatch } from "react-redux";
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";
// Api // Api
import { url } from "../../url"; import { url } from "../../url";
@ -23,11 +24,14 @@ 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;
@ -61,7 +65,7 @@ const NewsScroll = ({ title, category }: Props) => {
useEffect(() => { useEffect(() => {
const filtered = rawData.filter((el, index) => { const filtered = rawData.filter((el, index) => {
if (index > 0) { if (index >= 0) {
return el; return el;
} }
}); });
@ -74,28 +78,48 @@ const NewsScroll = ({ title, category }: Props) => {
{title === true ? ( {title === true ? (
<SectionTitle <SectionTitle
title="Лента новостей" title="Лента новостей"
linkData={{ link: "/all/null", 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={ date={dataEl.published_at}
dataEl.featured_images[0] categories={dataEl.categories}
? 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 /> <Loader />

View File

@ -1,30 +1,32 @@
// Modules // Modules
import { LazyLoadImage } from "react-lazy-load-image-component"; import { LazyLoadImage } from 'react-lazy-load-image-component';
import { Link } from "react-router-dom"; import { Link } from 'react-router-dom';
import placeholder from "../../assets/images/placeholder.webp"; import placeholder from '../../assets/images/placeholder.webp';
interface IProps { interface IProps {
type?: "small" | "big"; type?: 'small' | 'big';
img: string; img: string;
title: string; title: string;
id: number; id: number;
} }
const ContentItem = ({ type = "small", img, title, id }: IProps) => { const ContentItem = ({ type = 'small', img, title, id }: IProps) => {
return ( 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 <LazyLoadImage
src={img} src={img}
alt={img} alt={img}
effect="opacity" effect="opacity"
useIntersectionObserver useIntersectionObserver
placeholderSrc={placeholder} 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"> <Link to={`/news/${id}`} className="main-content-item-overlay">
<h2>{title}</h2> <h2>{title}</h2>
</Link> </Link>

View File

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

View File

@ -1,58 +1,62 @@
// Modules // 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 // Components
import SectionTitle from "../global/SectionTitle"; import SectionTitle from '../global/SectionTitle';
// import VideosItem from "./VideosItem"; import VideosItem from './VideosItem';
// // Videos
// import VideoPlaceholder from "../../assets/videos/placeholder.mp4";
// Types // Types
// import { videosDataType } from "../../types/videos.types"; import { RootState } from '../../types/store.types';
// const videosData: videosDataType[] = [ // Api
// { import { Api } from '../../api/Api';
// placeholder: Placeholder, import { url } from '../../url';
// url: VideoPlaceholder, import { videoParams } from '../../api/params';
// },
// { // Actions
// placeholder: Placeholder, import { setVideo } from '../../actions/setData';
// url: VideoPlaceholder,
// },
// {
// placeholder: Placeholder,
// url: VideoPlaceholder,
// },
// {
// placeholder: Placeholder,
// url: VideoPlaceholder,
// },
// ];
const Videos = () => { 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 ( return (
<section className="videos"> <section className="videos">
{/* <div className="container"> */}
<div className="videos-inner"> <div className="videos-inner">
<SectionTitle <SectionTitle
title="Видео" title="Видео"
givenClass="videos" givenClass="videos"
linkData={{ link: "/", title: "Посмотреть все" }} linkData={{ link: '/all?type=video', title: 'Посмотреть все' }}
/> />
<div className="videos-items"> <div className="videos-items">
{/* {videosData.map((videosDataItem: videosDataType) => { {data.map((videosDataItem, index) => {
return ( if (index <= 4) {
<VideosItem return (
key={uuiv4()} <VideosItem
url={videosDataItem.url} key={uuiv4()}
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> </div>
{/* </div> */}
</section> </section>
); );
}; };

View File

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

View File

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

View File

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

View File

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

View File

@ -9,7 +9,7 @@ import { motion } from "framer-motion";
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";
@ -123,7 +123,7 @@ const NewsArticle = () => {
) : ( ) : (
<Loader /> <Loader />
)} )}
<Aside /> <Aside type="latest" />
</div> </div>
</div> </div>
</motion.div> </motion.div>

View File

@ -8,7 +8,9 @@ import {
IPostDataAction, IPostDataAction,
ISearchResult, ISearchResult,
ISearchResultAction, ISearchResultAction,
} from "../types/store.types"; IVideoData,
IVideoDataAction,
} from '../types/store.types';
// NewsScroll // NewsScroll
@ -16,54 +18,54 @@ export const newsScrollInitialState = {
data: [ data: [
{ {
id: -1, id: -1,
title: "", title: '',
slug: "", slug: '',
excerpt: "", excerpt: '',
published_at: "", published_at: '',
featured_images: [ featured_images: [
{ {
id: -1, id: -1,
disk_name: "", disk_name: '',
file_name: "", file_name: '',
path: "", path: '',
extension: "", extension: '',
}, },
{ {
id: -1, id: -1,
disk_name: "", disk_name: '',
file_name: "", file_name: '',
path: "", path: '',
extension: "", extension: '',
}, },
{ {
id: -1, id: -1,
disk_name: "", disk_name: '',
file_name: "", file_name: '',
path: "", path: '',
extension: "", extension: '',
}, },
], ],
content_html: "", content_html: '',
categories: [ categories: [
{ {
id: -1, id: -1,
name: "", name: '',
}, },
], ],
video: null, video: null,
powerseo_title: "", powerseo_title: '',
powerseo_description: "", powerseo_description: '',
powerseo_keywords: "", powerseo_keywords: '',
}, },
], ],
}; };
export const newsScrollReducer = ( export const newsScrollReducer = (
state: INewsScroll = newsScrollInitialState, state: INewsScroll = newsScrollInitialState,
action: INewsScrollAction action: INewsScrollAction,
) => { ) => {
switch (action.type) { switch (action.type) {
case "SET_NEWS_SCROLL": { case 'SET_NEWS_SCROLL': {
return { ...state, data: action.payload }; return { ...state, data: action.payload };
} }
default: { default: {
@ -78,54 +80,51 @@ export const postInitialState = {
data: { data: {
data: { data: {
id: -1, id: -1,
title: "", title: '',
slug: "", slug: '',
excerpt: "", excerpt: '',
published_at: "", published_at: '',
video: null, video: null,
featured_images: [ featured_images: [
{ {
id: -1, id: -1,
disk_name: "", disk_name: '',
file_name: "", file_name: '',
path: "", path: '',
extension: "", extension: '',
}, },
{ {
id: -1, id: -1,
disk_name: "", disk_name: '',
file_name: "", file_name: '',
path: "", path: '',
extension: "", extension: '',
}, },
{ {
id: -1, id: -1,
disk_name: "", disk_name: '',
file_name: "", file_name: '',
path: "", path: '',
extension: "", extension: '',
}, },
], ],
content_html: "", content_html: '',
categories: [ categories: [
{ {
id: -1, id: -1,
name: "", name: '',
}, },
], ],
powerseo_title: "", powerseo_title: '',
powerseo_description: "", powerseo_description: '',
powerseo_keywords: "", powerseo_keywords: '',
}, },
}, },
}; };
export const postReducer = ( export const postReducer = (state: IPostData = postInitialState, action: IPostDataAction) => {
state: IPostData = postInitialState,
action: IPostDataAction
) => {
switch (action.type) { switch (action.type) {
case "SET_POST": { case 'SET_POST': {
return { ...state, data: action.payload }; return { ...state, data: action.payload };
} }
default: { default: {
@ -138,54 +137,54 @@ export const featuredInitialState = {
data: [ data: [
{ {
id: -1, id: -1,
title: "", title: '',
slug: "", slug: '',
excerpt: "", excerpt: '',
published_at: "", published_at: '',
video: null, video: null,
featured_images: [ featured_images: [
{ {
id: -1, id: -1,
disk_name: "", disk_name: '',
file_name: "", file_name: '',
path: "", path: '',
extension: "", extension: '',
}, },
{ {
id: -1, id: -1,
disk_name: "", disk_name: '',
file_name: "", file_name: '',
path: "", path: '',
extension: "", extension: '',
}, },
{ {
id: -1, id: -1,
disk_name: "", disk_name: '',
file_name: "", file_name: '',
path: "", path: '',
extension: "", extension: '',
}, },
], ],
content_html: "", content_html: '',
categories: [ categories: [
{ {
id: -1, id: -1,
name: "", name: '',
}, },
], ],
powerseo_title: "", powerseo_title: '',
powerseo_description: "", powerseo_description: '',
powerseo_keywords: "", powerseo_keywords: '',
}, },
], ],
}; };
export const featuredReducer = ( export const featuredReducer = (
state: IFeaturedData = featuredInitialState, state: IFeaturedData = featuredInitialState,
action: IFeaturedDataAction action: IFeaturedDataAction,
) => { ) => {
switch (action.type) { switch (action.type) {
case "SET_FEATURED": { case 'SET_FEATURED': {
return { ...state, data: action.payload }; return { ...state, data: action.payload };
} }
default: { default: {
@ -196,10 +195,10 @@ export const featuredReducer = (
export const searchDataReducer = ( export const searchDataReducer = (
state: ISearchResult = newsScrollInitialState, state: ISearchResult = newsScrollInitialState,
action: ISearchResultAction action: ISearchResultAction,
) => { ) => {
switch (action.type) { switch (action.type) {
case "SET_SEARCH_DATA": { case 'SET_SEARCH_DATA': {
return { data: action.payload }; return { data: action.payload };
} }
default: { 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 // Modules
import { combineReducers, configureStore } from "@reduxjs/toolkit"; import { combineReducers, configureStore } from '@reduxjs/toolkit';
// Reducers // Reducers
import { activeLinkReducer } from "../reducers/activeLink.reducer"; import { activeLinkReducer } from '../reducers/activeLink.reducer';
import { languageReducer } from "../reducers/language.reducer"; import { languageReducer } from '../reducers/language.reducer';
import { import {
newsScrollReducer, newsScrollReducer,
postReducer, postReducer,
searchDataReducer, searchDataReducer,
featuredReducer, featuredReducer,
} from "../reducers/dataReducer"; videoReducer,
import { searchReducer } from "../reducers/searchReducer"; } from '../reducers/dataReducer';
import { searchReducer } from '../reducers/searchReducer';
export const allReducers = combineReducers({ export const allReducers = combineReducers({
activeLink: activeLinkReducer, activeLink: activeLinkReducer,
@ -20,6 +21,7 @@ export const allReducers = combineReducers({
search: searchReducer, search: searchReducer,
searchData: searchDataReducer, searchData: searchDataReducer,
featured: featuredReducer, featured: featuredReducer,
video: videoReducer,
}); });
export const functionalityStore = configureStore({ export const functionalityStore = configureStore({

View File

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

View File

@ -27,6 +27,20 @@
@include wh100; @include wh100;
overflow: hidden; 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 { span {
display: block !important; display: block !important;
@include wh100; @include wh100;
@ -42,15 +56,11 @@
top: 0; top: 0;
left: 0; left: 0;
@include wh100; @include wh100;
background: linear-gradient( background: linear-gradient(180deg, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.7) 100%);
180deg,
rgba(0, 0, 0, 0) 50%,
rgba(0, 0, 0, 0.7) 100%
);
display: flex; display: flex;
padding: 1.6rem; padding: 1.6rem;
align-items: flex-end; align-items: flex-end;
z-index: 2; z-index: 4;
h2 { h2 {
color: $white; color: $white;

View File

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

View File

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

View File

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

View File

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