This commit is contained in:
VividTruthKeeper 2023-02-23 16:33:14 +05:00
parent d96ba1b4cb
commit 9300029673
27 changed files with 468 additions and 206 deletions

84
dist/assets/404-b9c88abe.svg vendored Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 60 KiB

File diff suppressed because one or more lines are too long

115
dist/assets/index-14c8607e.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

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

4
dist/index.html vendored
View File

@ -5,8 +5,8 @@
<!-- <link rel="icon" type="image/svg+xml" href="/vite.svg" /> --> <!-- <link rel="icon" type="image/svg+xml" href="/vite.svg" /> -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>HHM</title> <title>HHM</title>
<script type="module" crossorigin src="/assets/index-41c297bb.js"></script> <script type="module" crossorigin src="/assets/index-14c8607e.js"></script>
<link rel="stylesheet" href="/assets/index-93675728.css"> <link rel="stylesheet" href="/assets/index-10417d33.css">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

View File

@ -1,5 +1,7 @@
// Types // Types
import { import {
IFeaturedData,
IFeaturedDataAction,
INewsScroll, INewsScroll,
INewsScrollAction, INewsScrollAction,
IPostData, IPostData,
@ -30,3 +32,10 @@ export const setPost = (data: IPostData["data"]): IPostDataAction => ({
type: "SET_POST", type: "SET_POST",
payload: data, payload: data,
}); });
export const setFeatured = (
data: IFeaturedData["data"]
): IFeaturedDataAction => ({
type: "SET_FEATURED",
payload: data,
});

View File

@ -21,3 +21,18 @@ export const categoriesParams: IurlParamAdder[] = [
value: 1, value: 1,
}, },
]; ];
export const featuredParams: IurlParamAdder[] = [
{
name: "count",
value: 5,
},
{
name: "page",
value: 1,
},
{
name: "featured",
value: "true",
},
];

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 458 KiB

Binary file not shown.

View File

@ -1,18 +1,19 @@
// 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";
interface IProps { interface IProps {
type?: 'small' | 'big'; type?: "small" | "big";
img: string; img: string;
title: string; title: string;
id: number;
} }
const ContentItem = ({ type = 'small', img, title }: 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}`}>
<LazyLoadImage src={img} alt="" effect="blur" useIntersectionObserver /> <LazyLoadImage src={img} alt="" effect="blur" useIntersectionObserver />
<Link to="/news/1" className="main-content-item-overlay"> <Link to={`/news/${id}`} className="main-content-item-overlay">
<h2>{title}</h2> <h2>{title}</h2>
</Link> </Link>
</div> </div>

View File

@ -1,17 +1,20 @@
// Modules // Modules
import { Swiper, SwiperSlide } from "swiper/react"; import { Swiper, SwiperSlide } from "swiper/react";
import { Navigation, Pagination, Autoplay } from "swiper"; import { Navigation, Pagination, Autoplay } from "swiper";
import { v4 as uuidv4 } from "uuid";
// Images
import Placeholder from "../../assets/images/placeholder3.png";
// Components // Components
import ContentItem from "./ContentItem"; import ContentItem from "./ContentItem";
// Static // Static
import { titlePlaceholder } from "./MainContent"; import { IFeaturedData } from "../../types/store.types";
const ContentSlider = () => { // Types
interface IProps {
data: IFeaturedData["data"];
}
const ContentSlider = ({ data }: IProps) => {
return ( return (
<div className="main-content-slider"> <div className="main-content-slider">
<Swiper <Swiper
@ -28,18 +31,20 @@ const ContentSlider = () => {
clickable: true, clickable: true,
}} }}
> >
<SwiperSlide> {data.map((dataEl) => {
<ContentItem type="big" img={Placeholder} title={titlePlaceholder} /> return (
</SwiperSlide> <SwiperSlide key={uuidv4()}>
<SwiperSlide> <ContentItem
<ContentItem type="big" img={Placeholder} title={titlePlaceholder} /> id={dataEl.id}
</SwiperSlide> type="big"
<SwiperSlide> img={
<ContentItem type="big" img={Placeholder} title={titlePlaceholder} /> dataEl.featured_images ? dataEl.featured_images[0].path : ""
</SwiperSlide> }
<SwiperSlide> title={dataEl.title}
<ContentItem type="big" img={Placeholder} title={titlePlaceholder} /> />
</SwiperSlide> </SwiperSlide>
);
})}
</Swiper> </Swiper>
</div> </div>
); );

View File

@ -1,34 +1,110 @@
// Modules // Modules
import { LazyLoadComponent } from 'react-lazy-load-image-component'; import { useEffect, useState } from "react";
import { LazyLoadComponent } from "react-lazy-load-image-component";
// Images import { useSelector, useDispatch } from "react-redux";
import Placeholder from '../../assets/images/placeholder3.png';
// 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";
export const titlePlaceholder = // 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";
const MainContent = () => { const MainContent = () => {
const dispatch = useDispatch();
const data = useSelector<RootState, RootState["featured"]["data"]>(
(state) => state.featured.data
);
const api = new Api(url + "/posts", featuredParams);
const language = api.language;
const [lastLanguage, setLastLanguage] = useState<typeof language>(language);
const getData = () => {
api.get(data, (data) => dispatch(setFeatured(data)));
};
useEffect(() => {
if (data.length > 0) {
if (!(data[0].id > -1 && language === lastLanguage)) {
getData();
setLastLanguage(language);
}
}
}, [language, lastLanguage]);
return ( return (
<> <>
<LazyLoadComponent useIntersectionObserver> <LazyLoadComponent useIntersectionObserver>
<div className="main-content"> {data[0].id > -1 ? (
<SectionTitle title="Главное" /> data.length >= 5 ? (
<ContentSlider /> <div className="main-content">
<div className="main-content-top"> <SectionTitle title="Главное" />
<ContentItem type="big" img={Placeholder} title={titlePlaceholder} /> <ContentSlider data={data} />
<ContentItem img={Placeholder} title={titlePlaceholder} /> <div className="main-content-top">
</div> <ContentItem
<div className="main-content-bottom"> id={data[0].id}
<ContentItem img={Placeholder} title={titlePlaceholder} /> type="big"
<ContentItem img={Placeholder} title={titlePlaceholder} /> img={
<ContentItem img={Placeholder} title={titlePlaceholder} /> data[0].featured_images
</div> ? data[0].featured_images[0].path
</div> : ""
}
title={data[0].title}
/>
<ContentItem
id={data[1].id}
img={
data[1].featured_images
? 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
: ""
}
title={data[2].title}
/>
<ContentItem
id={data[3].id}
img={
data[3].featured_images
? 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
: ""
}
title={data[4].title}
/>
</div>
</div>
) : (
<Loader />
)
) : (
<Loader />
)}
</LazyLoadComponent> </LazyLoadComponent>
</> </>
); );

View File

@ -1,37 +1,34 @@
// Modules // Modules
import { v4 as uuiv4 } from 'uuid'; // import { v4 as uuiv4 } from "uuid";
// Components // Components
import SectionTitle from '../global/SectionTitle'; import SectionTitle from "../global/SectionTitle";
import VideosItem from './VideosItem'; // import VideosItem from "./VideosItem";
// Images // // Videos
import Placeholder from '../../assets/images/placeholder.jpg'; // import VideoPlaceholder from "../../assets/videos/placeholder.mp4";
// Videos
import VideoPlaceholder from '../../assets/videos/placeholder.mp4';
// Types // Types
import { videosDataType } from '../../types/videos.types'; // import { videosDataType } from "../../types/videos.types";
const videosData: videosDataType[] = [ // const videosData: videosDataType[] = [
{ // {
placeholder: Placeholder, // placeholder: Placeholder,
url: VideoPlaceholder, // url: VideoPlaceholder,
}, // },
{ // {
placeholder: Placeholder, // placeholder: Placeholder,
url: VideoPlaceholder, // url: VideoPlaceholder,
}, // },
{ // {
placeholder: Placeholder, // placeholder: Placeholder,
url: VideoPlaceholder, // url: VideoPlaceholder,
}, // },
{ // {
placeholder: Placeholder, // placeholder: Placeholder,
url: VideoPlaceholder, // url: VideoPlaceholder,
}, // },
]; // ];
const Videos = () => { const Videos = () => {
return ( return (
@ -41,10 +38,10 @@ const Videos = () => {
<SectionTitle <SectionTitle
title="Видео" title="Видео"
givenClass="videos" givenClass="videos"
linkData={{ link: '/', title: 'Посмотреть все' }} linkData={{ link: "/", title: "Посмотреть все" }}
/> />
<div className="videos-items"> <div className="videos-items">
{videosData.map((videosDataItem: videosDataType) => { {/* {videosData.map((videosDataItem: videosDataType) => {
return ( return (
<VideosItem <VideosItem
key={uuiv4()} key={uuiv4()}
@ -52,7 +49,7 @@ const Videos = () => {
placeholder={videosDataItem.placeholder} placeholder={videosDataItem.placeholder}
/> />
); );
})} })} */}
</div> </div>
</div> </div>
{/* </div> */} {/* </div> */}

View File

@ -7,9 +7,6 @@ import Aside from "../components/aside/Aside";
import NewsScroll from "../components/global/NewsScroll"; import NewsScroll from "../components/global/NewsScroll";
import MainImg from "../components/category/MainImg"; import MainImg from "../components/category/MainImg";
// Images
import Placeholder from "../assets/images/placeholder3.png";
const Category = () => { const Category = () => {
let { category } = useParams(); let { category } = useParams();
return ( return (

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 = () => {
@ -24,7 +24,7 @@ const Main = () => {
<NewsScroll title={true} /> <NewsScroll title={true} />
<Aside /> <Aside />
</div> </div>
<Videos /> {/* <Videos /> */}
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,5 +1,7 @@
// Types // Types
import { import {
IFeaturedData,
IFeaturedDataAction,
INewsScroll, INewsScroll,
INewsScrollAction, INewsScrollAction,
IPostData, IPostData,
@ -130,6 +132,65 @@ export const postReducer = (
} }
}; };
export const featuredInitialState = {
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 featuredReducer = (
state: IFeaturedData = featuredInitialState,
action: IFeaturedDataAction
) => {
switch (action.type) {
case "SET_FEATURED": {
return { ...state, data: action.payload };
}
default: {
return state;
}
}
};
export const searchDataReducer = ( export const searchDataReducer = (
state: ISearchResult = newsScrollInitialState, state: ISearchResult = newsScrollInitialState,
action: ISearchResultAction action: ISearchResultAction

View File

@ -8,6 +8,7 @@ import {
newsScrollReducer, newsScrollReducer,
postReducer, postReducer,
searchDataReducer, searchDataReducer,
featuredReducer,
} from "../reducers/dataReducer"; } from "../reducers/dataReducer";
import { searchReducer } from "../reducers/searchReducer"; import { searchReducer } from "../reducers/searchReducer";
@ -18,6 +19,7 @@ export const allReducers = combineReducers({
post: postReducer, post: postReducer,
search: searchReducer, search: searchReducer,
searchData: searchDataReducer, searchData: searchDataReducer,
featured: featuredReducer,
}); });
export const functionalityStore = configureStore({ export const functionalityStore = configureStore({

View File

@ -1,4 +1,5 @@
.all-inner { .all-inner {
min-height: 50vh;
padding: 5.6rem 0; padding: 5.6rem 0;
.loader { .loader {
margin: 4rem 0; margin: 4rem 0;

View File

@ -121,6 +121,9 @@
} }
@media screen and (max-width: 900px) { @media screen and (max-width: 900px) {
.main-content-item {
height: 40rem;
}
.main-content-bottom { .main-content-bottom {
display: none; display: none;
} }

View File

@ -39,7 +39,8 @@
width: 100%; width: 100%;
max-width: 70%; max-width: 70%;
display: flex; display: flex;
justify-content: flex-start; justify-self: center;
justify-content: center;
h1 { h1 {
width: fit-content; width: fit-content;
text-align: center; text-align: center;

View File

@ -62,12 +62,12 @@
} }
.news-article-image { .news-article-image {
min-height: 30rem; height: 56rem;
img, img,
span { span {
width: 100%; width: 100%;
height: 100%; height: 100%;
object-fit: cover; object-fit: contain;
} }
} }

View File

@ -47,7 +47,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 1.6rem; gap: 1.6rem;
overflow: hidden; overflow: auto;
width: 100%; width: 100%;
p { p {
white-space: nowrap; white-space: nowrap;
@ -155,4 +155,11 @@
} }
@media (max-width: 400px) { @media (max-width: 400px) {
.news-status-left {
p {
&:nth-child(n + 4) {
display: none;
}
}
}
} }

View File

@ -45,6 +45,14 @@ export interface IPostDataAction {
type: "SET_POST"; type: "SET_POST";
payload: IPostData["data"]; payload: IPostData["data"];
} }
export interface IFeaturedData {
data: IPostsData[];
}
export interface IFeaturedDataAction {
type: "SET_FEATURED";
payload: IFeaturedData["data"];
}
// //