This commit is contained in:
VividTruthKeeper 2023-02-08 21:37:00 +05:00
commit 5dda901bea
20 changed files with 451 additions and 109 deletions

27
package-lock.json generated
View File

@ -25,6 +25,7 @@
"react-spinners": "^0.13.8", "react-spinners": "^0.13.8",
"redux-thunk": "^2.4.2", "redux-thunk": "^2.4.2",
"sass": "^1.57.1", "sass": "^1.57.1",
"swiper": "^9.0.3",
"uuid": "^9.0.0", "uuid": "^9.0.0",
"vite-plugin-svgr": "^2.4.0" "vite-plugin-svgr": "^2.4.0"
}, },
@ -2278,6 +2279,11 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/ssr-window": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-4.0.2.tgz",
"integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ=="
},
"node_modules/supports-color": { "node_modules/supports-color": {
"version": "5.5.0", "version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@ -2305,6 +2311,27 @@
"resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz",
"integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ=="
}, },
"node_modules/swiper": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-9.0.3.tgz",
"integrity": "sha512-hHYI6CeUHcDyv6IakzAQrUv6nS5BMRn6KOkui16nhtdgYBlWgUdlaMbcdT0o4RJxpwSktCTLgpBtCm+WwwVYRw==",
"funding": [
{
"type": "patreon",
"url": "https://www.patreon.com/swiperjs"
},
{
"type": "open_collective",
"url": "http://opencollective.com/swiper"
}
],
"dependencies": {
"ssr-window": "^4.0.2"
},
"engines": {
"node": ">= 4.7.0"
}
},
"node_modules/to-fast-properties": { "node_modules/to-fast-properties": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",

View File

@ -26,6 +26,7 @@
"react-spinners": "^0.13.8", "react-spinners": "^0.13.8",
"redux-thunk": "^2.4.2", "redux-thunk": "^2.4.2",
"sass": "^1.57.1", "sass": "^1.57.1",
"swiper": "^9.0.3",
"uuid": "^9.0.0", "uuid": "^9.0.0",
"vite-plugin-svgr": "^2.4.0" "vite-plugin-svgr": "^2.4.0"
}, },

View File

@ -1,19 +1,22 @@
// Modules // Modules
import { Routes, Route } from "react-router-dom"; import { Routes, Route } from 'react-router-dom';
// Styles // Styles
import "react-lazy-load-image-component/src/effects/blur.css"; import 'swiper/swiper.css';
import "react-calendar/dist/Calendar.css"; import 'swiper/css/pagination';
import "./styles/style.scss"; import 'swiper/css/navigation';
import 'react-lazy-load-image-component/src/effects/blur.css';
import 'react-calendar/dist/Calendar.css';
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';
// 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';
const App = () => { const App = () => {
return ( return (

View File

@ -1,44 +1,41 @@
// Modules // Modules
import { Link } from "react-router-dom"; import { Link } from 'react-router-dom';
import { LazyLoadImage } from "react-lazy-load-image-component"; import { LazyLoadImage } from 'react-lazy-load-image-component';
// Images // Images
import { ReactComponent as ArrRight } from "../../assets/icons/arrow-right.svg"; import { ReactComponent as ArrRight } from '../../assets/icons/arrow-right.svg';
// Components // Components
import NewsCategory from "../global/NewsCategory"; import NewsCategory from '../global/NewsCategory';
import NewsDate from "../global/NewsDate"; import NewsDate from '../global/NewsDate';
interface Props { interface Props {
title: string; title: string;
date: string; date: string;
img: string; img: string;
category: string;
link: string;
} }
const AsideNews = ({ title, date, img }: Props) => { const AsideNews = ({ title, date, img, category, link }: Props) => {
return ( return (
<div className="aside-news"> <Link to={link} 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 src={img} alt="image" useIntersectionObserver effect="blur" />
src={img}
alt="image"
useIntersectionObserver
effect="blur"
/>
</div> </div>
<div className="aside-news-info"> <div className="aside-news-info">
<div className="aside-news-info-inner"> <div className="aside-news-info-inner">
<div className="aside-news-status"> <div className="aside-news-status">
<NewsCategory title="политика" /> <NewsCategory title={category} />
<NewsDate date={date} /> <NewsDate date={date} />
</div> </div>
<h2 className="aside-news-title">{title}</h2> <h2 className="aside-news-title">{title}</h2>
</div> </div>
<Link to={`/news/1`} className="aside-news-link"> {/* <Link to={link} className="aside-news-link">
<span>прочитать все</span> <ArrRight /> <span>прочитать все</span> <ArrRight />
</Link> </Link> */}
</div> </div>
</div> </div>
</div> </Link>
); );
}; };

View File

@ -1,16 +1,12 @@
// Modules // Modules
import { Link } from "react-router-dom"; import { Link } from 'react-router-dom';
interface Props { interface Props {
title: string; title: string;
} }
const NewsCategory = ({ title }: Props) => { const NewsCategory = ({ title }: Props) => {
return ( return <span className="news-category">{title}</span>;
<Link to={`/category/asd`} className="news-category">
{title}
</Link>
);
}; };
export default NewsCategory; export default NewsCategory;

View File

@ -6,14 +6,14 @@ import placeholder from '../../assets/images/placeholder.jpg';
// Interface // Interface
interface Props { interface Props {
state: boolean; sectionTitle: boolean;
} }
const NewsScroll = ({ state }: Props) => { const NewsScroll = ({ sectionTitle }: Props) => {
return ( return (
<div className="news-scroll"> <div className="news-scroll">
<div className="news-scroll-wrapper"> <div className="news-scroll-wrapper">
{state === true ? ( {sectionTitle === true ? (
<SectionTitle title="Лента новостей" linkData={{ link: '/', title: 'Посмотреть все' }} /> <SectionTitle title="Лента новостей" linkData={{ link: '/', title: 'Посмотреть все' }} />
) : null} ) : null}
<div className="news-scroll-inner"> <div className="news-scroll-inner">
@ -23,7 +23,6 @@ const NewsScroll = ({ state }: Props) => {
date="12.01.2023" date="12.01.2023"
category="Политика" category="Политика"
img={placeholder} img={placeholder}
link=""
/> />
<News <News
title="Президент Туркменистана провёл рабочее совещание по цифровой системе" title="Президент Туркменистана провёл рабочее совещание по цифровой системе"
@ -31,7 +30,6 @@ const NewsScroll = ({ state }: Props) => {
date="12.01.2023" date="12.01.2023"
category="Политика" category="Политика"
img={placeholder} img={placeholder}
link=""
/> />
<News <News
title="Президент Туркменистана провёл рабочее совещание по цифровой системе" title="Президент Туркменистана провёл рабочее совещание по цифровой системе"
@ -39,7 +37,6 @@ const NewsScroll = ({ state }: Props) => {
date="12.01.2023" date="12.01.2023"
category="Политика" category="Политика"
img={placeholder} img={placeholder}
link=""
/> />
<News <News
title="Президент Туркменистана провёл рабочее совещание по цифровой системе" title="Президент Туркменистана провёл рабочее совещание по цифровой системе"
@ -47,7 +44,6 @@ const NewsScroll = ({ state }: Props) => {
date="12.01.2023" date="12.01.2023"
category="Политика" category="Политика"
img={placeholder} img={placeholder}
link=""
/> />
<News <News
title="Президент Туркменистана провёл рабочее совещание по цифровой системе" title="Президент Туркменистана провёл рабочее совещание по цифровой системе"
@ -55,7 +51,6 @@ const NewsScroll = ({ state }: Props) => {
date="12.01.2023" date="12.01.2023"
category="Политика" category="Политика"
img={placeholder} img={placeholder}
link=""
/> />
</div> </div>
</div> </div>

View File

@ -0,0 +1,22 @@
// Modules
import { LazyLoadImage } from 'react-lazy-load-image-component';
import { Link } from 'react-router-dom';
interface IProps {
type?: 'small' | 'big';
img: string;
title: string;
}
const ContentItem = ({ type = 'small', img, title }: IProps) => {
return (
<div className={`main-content-item main-content-item__${type}`}>
<LazyLoadImage src={img} alt="" effect="blur" useIntersectionObserver />
<Link to="/news/1" className="main-content-item-overlay">
<h2>{title}</h2>
</Link>
</div>
);
};
export default ContentItem;

View File

@ -0,0 +1,46 @@
// Modules
import { Swiper, SwiperSlide } from 'swiper/react';
import { Navigation, Pagination, Autoplay } from 'swiper';
// Images
import Placeholder from '../../assets/images/placeholder3.png';
// Components
import ContentItem from './ContentItem';
// Static
import { titlePlaceholder } from './MainContent';
const ContentSlider = () => {
return (
<div className="main-content-slider">
<Swiper
spaceBetween={24}
slidesPerView={1}
loop
autoplay={{
delay: 3000,
disableOnInteraction: false,
}}
modules={[Navigation, Pagination, Autoplay]}
pagination={{
type: 'bullets',
}}>
<SwiperSlide>
<ContentItem type="big" img={Placeholder} title={titlePlaceholder} />
</SwiperSlide>
<SwiperSlide>
<ContentItem type="big" img={Placeholder} title={titlePlaceholder} />
</SwiperSlide>
<SwiperSlide>
<ContentItem type="big" img={Placeholder} title={titlePlaceholder} />
</SwiperSlide>
<SwiperSlide>
<ContentItem type="big" img={Placeholder} title={titlePlaceholder} />
</SwiperSlide>
</Swiper>
</div>
);
};
export default ContentSlider;

View File

@ -0,0 +1,37 @@
// Modules
import { LazyLoadComponent } from 'react-lazy-load-image-component';
// Images
import Placeholder from '../../assets/images/placeholder3.png';
// Components
import ContentItem from './ContentItem';
import SectionTitle from '../global/SectionTitle';
import ContentSlider from './ContentSlider';
export const titlePlaceholder =
'Полезная информация для поступающих на программы подготовки научных кадров в Туркменистане';
const MainContent = () => {
return (
<>
<LazyLoadComponent useIntersectionObserver>
<div className="main-content">
<SectionTitle title="Главное" />
<ContentSlider />
<div className="main-content-top">
<ContentItem type="big" img={Placeholder} title={titlePlaceholder} />
<ContentItem img={Placeholder} title={titlePlaceholder} />
</div>
<div className="main-content-bottom">
<ContentItem img={Placeholder} title={titlePlaceholder} />
<ContentItem img={Placeholder} title={titlePlaceholder} />
<ContentItem img={Placeholder} title={titlePlaceholder} />
</div>
</div>
</LazyLoadComponent>
</>
);
};
export default MainContent;

View File

@ -1,11 +1,11 @@
// Modules // Modules
import { Link } from "react-router-dom"; import { Link } from 'react-router-dom';
import { LazyLoadImage } from "react-lazy-load-image-component"; import { LazyLoadImage } from 'react-lazy-load-image-component';
// Images // Images
import { ReactComponent as ArrRight } from "../../assets/icons/arrow-right.svg"; import { ReactComponent as ArrRight } from '../../assets/icons/arrow-right.svg';
// Components // Components
import NewsCategory from "../global/NewsCategory"; import NewsCategory from '../global/NewsCategory';
import NewsDate from "../global/NewsDate"; import NewsDate from '../global/NewsDate';
interface Props { interface Props {
title: string; title: string;
@ -17,15 +17,10 @@ interface Props {
const News = ({ title, text, category, date, img }: Props) => { const News = ({ title, text, category, date, img }: Props) => {
return ( return (
<div className="news"> <Link to={`/news/1`} className="news">
<div className="news-wrapper"> <div className="news-wrapper">
<div className="news-image"> <div className="news-image">
<LazyLoadImage <LazyLoadImage src={img} alt="image" useIntersectionObserver effect="blur" />
src={img}
alt="image"
useIntersectionObserver
effect="blur"
/>
</div> </div>
<div className="news-info"> <div className="news-info">
<div className="news-info-inner"> <div className="news-info-inner">
@ -36,12 +31,12 @@ const News = ({ title, text, category, date, img }: Props) => {
</div> </div>
<div className="news-text">{text}</div> <div className="news-text">{text}</div>
</div> </div>
<Link to={`/news/1`} className="news-link"> {/* <Link to={`/news/1`} className="news-link">
<span>прочитать все</span> <ArrRight /> <span>прочитать все</span> <ArrRight />
</Link> </Link> */}
</div> </div>
</div> </div>
</div> </Link>
); );
}; };

View File

@ -1,18 +1,18 @@
// 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 // Images
import Placeholder from "../../assets/images/placeholder.jpg"; import Placeholder from '../../assets/images/placeholder.jpg';
// Videos // Videos
import VideoPlaceholder from "../../assets/videos/placeholder.mp4"; 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[] = [
{ {
@ -36,26 +36,26 @@ const videosData: videosDataType[] = [
const Videos = () => { const Videos = () => {
return ( return (
<section className="videos"> <section className="videos">
<div className="container"> {/* <div className="container"> */}
<div className="videos-inner"> <div className="videos-inner">
<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()}
url={videosDataItem.url} url={videosDataItem.url}
placeholder={videosDataItem.placeholder} placeholder={videosDataItem.placeholder}
/> />
); );
})} })}
</div>
</div> </div>
</div> </div>
{/* </div> */}
</section> </section>
); );
}; };

View File

@ -1,7 +1,8 @@
// 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';
const Main = () => { const Main = () => {
return ( return (
@ -9,8 +10,9 @@ const Main = () => {
<div className="news-section"> <div className="news-section">
<div className="container"> <div className="container">
<div className="news-inner"> <div className="news-inner">
<MainContent />
<div className="news-outer-wrapper"> <div className="news-outer-wrapper">
<NewsScroll state={true} /> <NewsScroll sectionTitle={true} />
<Aside /> <Aside />
</div> </div>
<Videos /> <Videos />

View File

@ -19,6 +19,7 @@
.react-calendar { .react-calendar {
border: none; border: none;
line-height: unset;
} }
.react-calendar__month-view__weekdays { .react-calendar__month-view__weekdays {
@ -86,13 +87,13 @@
.react-calendar__navigation__arrow.react-calendar__navigation__next-button { .react-calendar__navigation__arrow.react-calendar__navigation__next-button {
display: block; display: block;
background: url("../assets/icons/stroke-right-black.svg") no-repeat center; background: url('../assets/icons/stroke-right-black.svg') no-repeat center;
color: transparent; color: transparent;
} }
.react-calendar__navigation__arrow.react-calendar__navigation__prev-button { .react-calendar__navigation__arrow.react-calendar__navigation__prev-button {
display: block; display: block;
background: url("../assets/icons/stroke-left-black.svg") no-repeat center; background: url('../assets/icons/stroke-left-black.svg') no-repeat center;
color: transparent; color: transparent;
} }

View File

@ -9,6 +9,7 @@
.footer-wrapper { .footer-wrapper {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
gap: 2.4rem;
} }
.footer-nav-list { .footer-nav-list {
@ -20,6 +21,8 @@
.footer-nav-list-item { .footer-nav-list-item {
a { a {
white-space: nowrap;
text-overflow: ellipsis;
font-size: 1.8rem; font-size: 1.8rem;
color: $white; color: $white;
@include roboto; @include roboto;
@ -54,3 +57,27 @@
font-weight: 400; font-weight: 400;
max-width: 37rem; max-width: 37rem;
} }
@media (max-width: 1200px) {
.footer-wrapper {
flex-direction: column;
gap: 4rem;
}
.footer-nav-list {
grid-template-columns: repeat(3, auto);
}
}
@media (max-width: 700px) {
.footer-nav-list {
grid-template-columns: repeat(2, auto);
column-gap: 2.4rem;
}
}
// @media (max-width: 390px) {
// .footer-nav-list {
// grid-template-columns: auto;
// }
// }

View File

@ -1,5 +1,5 @@
@import url("https://fonts.googleapis.com/css2?family=Roboto&display=swap"); @import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
@import url("https://fonts.googleapis.com/css2?family=Raleway&display=swap"); @import url('https://fonts.googleapis.com/css2?family=Raleway&display=swap');
* { * {
margin: 0; margin: 0;
@ -71,3 +71,9 @@ h6 {
.react-calendar__month-view__days { .react-calendar__month-view__days {
column-gap: 1.8rem; column-gap: 1.8rem;
} }
@media screen and (max-width: 900px) {
.container {
padding: 0 1.5rem;
}
}

View File

@ -1,3 +1,119 @@
.main { .main {
padding: 5.6rem 0; padding: 5.6rem 0;
} }
.main-content {
display: flex;
flex-direction: column;
gap: 2.4rem;
}
.main-content-top {
display: grid;
grid-template-columns: calc(67% - 1.2rem) calc(33% - 1.2rem);
gap: 2.4rem;
height: 40rem;
}
.main-content-bottom {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 2.4rem;
height: 23.7rem;
}
.main-content-item {
position: relative;
@include wh100;
overflow: hidden;
span {
display: block !important;
@include wh100;
}
img {
@include wh100;
object-fit: cover;
}
&-overlay {
position: absolute;
top: 0;
left: 0;
@include wh100;
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;
h2 {
color: $white;
font-size: 1.8rem;
}
}
&__big {
&-overlay {
padding: 2.4rem;
}
h2 {
font-size: 2.4rem;
}
}
}
.main-content-slider {
display: none;
}
.swiper-wrapper {
padding-bottom: 4rem;
}
.swiper-pagination {
bottom: 0rem;
}
.swiper-pagination-bullet {
background: $gray-dark;
width: 0.8rem;
height: 0.8rem;
transition: 0.5s all ease;
&-active {
width: 2.4rem;
transition: 0.5s all ease;
background: $main;
border-radius: 5.3rem;
}
}
// Media
@media screen and (max-width: 1020px) {
.main-content-top {
grid-template-columns: 1fr;
gap: 0;
.main-content-item__small {
display: none;
}
}
.main-content-bottom {
height: 19rem;
}
}
@media screen and (max-width: 900px) {
.main-content-bottom {
display: none;
}
.main-content-top {
display: none;
}
.main-content-slider {
display: block;
}
}

View File

@ -9,3 +9,9 @@
flex-direction: column; flex-direction: column;
gap: 5.6rem; gap: 5.6rem;
} }
@media (max-width: 1024px) {
.news-outer-wrapper {
grid-template-columns: 1fr;
}
}

View File

@ -22,6 +22,10 @@
font-size: 2.4rem; font-size: 2.4rem;
font-weight: 700; font-weight: 700;
@include raleway; @include raleway;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
} }
.news-status { .news-status {
@ -47,3 +51,48 @@
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
overflow: hidden; overflow: hidden;
} }
@media (max-width: 768px) {
.news-wrapper {
flex-direction: column;
}
.news-image {
width: 100%;
height: 16rem;
overflow: hidden;
object-fit: cover;
object-position: center;
img {
height: 100%;
width: 100%;
object-fit: cover;
object-position: center;
}
span {
display: block !important;
height: 100%;
}
}
.news-title {
font-size: 1.6rem;
}
.news-text {
display: none;
}
.new-status {
order: 1;
}
.news-info {
align-items: start;
}
.news-link {
display: none;
}
}

View File

@ -1,7 +1,3 @@
.videos {
// padding: 5.6rem 0;
}
.videos-inner { .videos-inner {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -40,3 +36,23 @@
color: $black; color: $black;
} }
} }
// Media
@media screen and (max-width: 1150px) {
.videos-items {
grid-template-columns: 1fr 1fr;
}
.videos-item-video {
min-height: 30vw;
}
}
@media screen and (max-width: 780px) {
.videos-items {
grid-template-columns: 1fr;
}
.videos-item-video {
min-height: 40vw;
}
}

View File

@ -1,18 +1,18 @@
@import "./variables"; @import './variables';
@import "./mixins"; @import './mixins';
@import "./general"; @import './general';
@import "./nav"; @import './nav';
@import "./main"; @import './main';
@import "./videos"; @import './videos';
@import "./section-title"; @import './section-title';
@import "./footer"; @import './footer';
@import "./news"; @import './news';
@import "./newsCategory"; @import './newsCategory';
@import "./newsDate"; @import './newsDate';
@import "./newsScroll"; @import './newsScroll';
@import "./asideNews"; @import './asideNews';
@import "./aside"; @import './aside';
@import "./news-section"; @import './news-section';
@import "./news-article"; @import './news-article';
@import "./category"; @import './category';
@import "./calendar"; @import './calendar';