This commit is contained in:
VividTruthKeeper 2023-03-07 15:30:16 +05:00
commit a720f98626
5 changed files with 163 additions and 202 deletions

View File

@ -1,26 +1,26 @@
// Modules
import { useEffect, useState } from "react";
import { v4 as uuidv4 } from "uuid";
import { useSelector, useDispatch } from "react-redux";
import { useEffect, useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import { useSelector, useDispatch } from 'react-redux';
// Components
import News from "../news/News";
import SectionTitle from "./SectionTitle";
import Loader from "./Loader";
import Pagination from "./Pagination";
import News from '../news/News';
import SectionTitle from './SectionTitle';
import Loader from './Loader';
import Pagination from './Pagination';
// Api
import { url } from "../../url";
import { Api } from "../../api/Api";
import { newsScrollParams } from "../../api/params";
import { url } from '../../url';
import { Api } from '../../api/Api';
import { newsScrollParams } from '../../api/params';
// Types
import { IPostsData } from "../../types/data.types";
import { RootState } from "../../types/store.types";
import { IPostsData } from '../../types/data.types';
import { RootState } from '../../types/store.types';
// Actions
import { setNewsScroll } from "../../actions/setData";
import { INewPostsData } from "../../types/posts.types";
import { setNewsScroll } from '../../actions/setData';
import { INewPostsData } from '../../types/posts.types';
interface Props {
title: boolean;
@ -31,16 +31,16 @@ interface Props {
const NewsScroll = ({ title, category, count, avoidFirst }: Props) => {
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 + "/pagination/posts", params);
const api = new Api(url + '/pagination/posts', params);
const language = api.language;
const [lastLanguage, setLastLanguage] = useState<string>(language);
// redux
const rawData = useSelector<RootState, RootState["newsScroll"]["data"]>(
(state) => state.newsScroll.data
const rawData = useSelector<RootState, RootState['newsScroll']['data']>(
(state) => state.newsScroll.data,
);
const dispatch = useDispatch();
@ -58,9 +58,9 @@ const NewsScroll = ({ title, category, count, avoidFirst }: Props) => {
}
}, [language, lastLanguage]);
const [filteredData, setFilteredData] = useState<
INewPostsData["data"]["data"]
>(rawData.data.data);
const [filteredData, setFilteredData] = useState<INewPostsData['data']['data']>(
rawData.data.data,
);
useEffect(() => {
const filtered = rawData.data.data.filter((el, index) => {
@ -76,31 +76,23 @@ const NewsScroll = ({ title, category, count, avoidFirst }: Props) => {
<div className="news-scroll-wrapper">
{title === true ? (
<SectionTitle
title="Лента новостей"
linkData={{ link: "/all", title: "Посмотреть все" }}
title={
language === 'EN' ? 'Newsline' : language === 'RU' ? 'Лента новостей' : 'Habarlar'
}
linkData={{
link: '/all',
title: `${
language === 'EN' ? 'View all' : language === 'RU' ? 'Посмотреть все' : 'Doly gör'
}`,
}}
/>
) : null}
<div className="news-scroll-inner">
{filteredData.length > 0 ? (
(filteredData as INewPostsData["data"]["data"])[0].id > -1 ? (
(filteredData as INewPostsData["data"]["data"]).map(
(dataEl, index) => {
if (avoidFirst) {
if (index > 0) {
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]?.path}
video={dataEl?.video}
/>
);
}
} else {
(filteredData as INewPostsData['data']['data'])[0].id > -1 ? (
(filteredData as INewPostsData['data']['data']).map((dataEl, index) => {
if (avoidFirst) {
if (index > 0) {
return (
<News
key={uuidv4()}
@ -114,8 +106,21 @@ const NewsScroll = ({ title, category, count, avoidFirst }: 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]?.path}
video={dataEl?.video}
/>
);
}
)
})
) : (
<Loader />
)

View File

@ -1,29 +1,29 @@
// Modules
import { useState } from "react";
import { Link } from "react-router-dom";
import { motion } from "framer-motion";
import { Api } from "../../api/Api";
import { useState } from 'react';
import { Link } from 'react-router-dom';
import { motion } from 'framer-motion';
import { Api } from '../../api/Api';
// Icons
import { ReactComponent as Logo } from "../../assets/icons/logo.svg";
import { ReactComponent as Instagram } from "../../assets/icons/insta-black.svg";
import { ReactComponent as Facebook } from "../../assets/icons/fb-black.svg";
import { ReactComponent as TikTok } from "../../assets/icons/tiktok-black.svg";
import { ReactComponent as Logo } from '../../assets/icons/logo.svg';
import { ReactComponent as Instagram } from '../../assets/icons/insta-black.svg';
import { ReactComponent as Facebook } from '../../assets/icons/fb-black.svg';
import { ReactComponent as TikTok } from '../../assets/icons/tiktok-black.svg';
// Components
import Search from "./Search";
import LanguageSelect from "./LanguageSelect";
import Search from './Search';
import LanguageSelect from './LanguageSelect';
// Hooks
import useMediaQuery from "../../hooks/useMediaQuery";
import useMediaQuery from '../../hooks/useMediaQuery';
// Animation
import { searchMobileMotion } from "../../animations/search.animation";
import { searchMobileMotion } from '../../animations/search.animation';
const Nav = () => {
const isSmall = useMediaQuery("(max-width: 850px)");
const isSmall = useMediaQuery('(max-width: 850px)');
const [isInputFocused, setIsInputFocused] = useState<boolean>(false);
const language = new Api("").language;
const language = new Api('').language;
return (
<nav className="nav">
<div className="container">
@ -36,40 +36,37 @@ const Nav = () => {
setIsInputFocused={setIsInputFocused}
/>
<LanguageSelect
isSmall={isSmall}
isInputFocused={isInputFocused}
/>
<LanguageSelect isSmall={isSmall} isInputFocused={isInputFocused} />
</div>
<div className="nav-mid">
<Link to="/">
<h1>
{language === "TM"
? "Türkmenistan Habarlar Portaly"
: language === "RU"
? "Туркменистан новостной портал"
: language === "EN"
? "Turkmenistan news portal"
: ""}
{language === 'TM'
? 'Türkmenistan Habarlar Portaly'
: language === 'RU'
? 'Туркменистан новостной портал'
: language === 'EN'
? 'Turkmenistan news portal'
: ''}
</h1>
</Link>
</div>
<div className="nav-right">
<ul>
<li>
<a href="#" target={"_blank"}>
<a href="#" target={'_blank'}>
<Instagram />
{/* <span>hhm@inst.com</span> */}
</a>
</li>
<li>
<a href="#" target={"_blank"}>
<a href="#" target={'_blank'}>
<Facebook />
{/* <span>hhm@face.com</span> */}
</a>
</li>
<li>
<a href="#" target={"_blank"}>
<a href="#" target={'_blank'}>
<TikTok />
{/* <span>@hhm</span> */}
</a>
@ -81,30 +78,26 @@ const Nav = () => {
<motion.div className="nav-inner mobile">
<motion.div
className="nav-mid"
initial={isSmall ? "logoRest" : {}}
animate={
isSmall ? (isInputFocused ? "logoActive" : "logoRest") : {}
}
variants={searchMobileMotion}
>
initial={isSmall ? 'logoRest' : {}}
animate={isSmall ? (isInputFocused ? 'logoActive' : 'logoRest') : {}}
variants={searchMobileMotion}>
<Link to="/">
<h1>
{language === "TM"
? "Türkmenistan Habarlar Portaly"
: language === "RU"
? "Туркменистан новостной портал"
: language === "EN"
? "Turkmenistan news portal"
: ""}
{language === 'TM'
? 'Türkmenistan Habarlar Portaly'
: language === 'RU'
? 'Туркменистан новостной портал'
: language === 'EN'
? 'Turkmenistan news portal'
: ''}
</h1>
</Link>
</motion.div>
<motion.div
className="search-wrap"
initial={isSmall ? "rest" : {}}
animate={isSmall ? (isInputFocused ? "active" : "rest") : {}}
variants={searchMobileMotion}
>
initial={isSmall ? 'rest' : {}}
animate={isSmall ? (isInputFocused ? 'active' : 'rest') : {}}
variants={searchMobileMotion}>
<Search
isSmall={isSmall}
isInputFocused={isInputFocused}
@ -112,10 +105,7 @@ const Nav = () => {
/>
</motion.div>
<div className="lang-wrap">
<LanguageSelect
isSmall={isSmall}
isInputFocused={isInputFocused}
/>
<LanguageSelect isSmall={isSmall} isInputFocused={isInputFocused} />
</div>
</motion.div>
)}

View File

@ -1,21 +1,19 @@
// Modules
import { Dispatch, SetStateAction } from "react";
import { motion } from "framer-motion";
import { useSelector, useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import { useRef } from "react";
import { Dispatch, SetStateAction } from 'react';
import { motion } from 'framer-motion';
import { useSelector, useDispatch } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import { useRef } from 'react';
import { Api } from '../../api/Api';
// Animations
import {
searchMotion,
searchMobileMotion,
} from "../../animations/search.animation";
import { searchMotion, searchMobileMotion } from '../../animations/search.animation';
// Types
import { RootState } from "../../types/store.types";
import { RootState } from '../../types/store.types';
// Actions
import { setSearch } from "../../actions/setSearch";
import { setSearch } from '../../actions/setSearch';
interface IProps {
isSmall: boolean;
@ -24,18 +22,20 @@ interface IProps {
}
const Search = ({ isSmall, isInputFocused, setIsInputFocused }: IProps) => {
const language = new Api('').language;
const onInputChange = (value: string) => {
dispatch(setSearch(value));
};
const searchValue = useSelector<RootState, RootState["search"]["value"]>(
(state) => state.search.value
const searchValue = useSelector<RootState, RootState['search']['value']>(
(state) => state.search.value,
);
// redux
const dispatch = useDispatch();
const inputValue = useSelector<RootState, RootState["search"]["value"]>(
(state) => state.search.value
const inputValue = useSelector<RootState, RootState['search']['value']>(
(state) => state.search.value,
);
const navigate = useNavigate();
@ -53,29 +53,25 @@ const Search = ({ isSmall, isInputFocused, setIsInputFocused }: IProps) => {
}
}}
variants={searchMobileMotion}
initial={isSmall ? "borderRest" : {}}
animate={isSmall ? (isInputFocused ? "borderActive" : "borderRest") : {}}
>
initial={isSmall ? 'borderRest' : {}}
animate={isSmall ? (isInputFocused ? 'borderActive' : 'borderRest') : {}}>
<input
type="text"
value={inputValue}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
onInputChange(event.target.value)
}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => onInputChange(event.target.value)}
onFocus={() => {
setIsInputFocused(true);
}}
onBlur={() => {
setIsInputFocused(false);
onInputChange("");
onInputChange('');
}}
/>
<motion.div
className="search-content"
initial={"rest"}
animate={inputValue.length > 0 ? "active" : "rest"}
variants={searchMotion}
>
initial={'rest'}
animate={inputValue.length > 0 ? 'active' : 'rest'}
variants={searchMotion}>
<motion.svg
width="13"
height="14"
@ -83,15 +79,8 @@ const Search = ({ isSmall, isInputFocused, setIsInputFocused }: IProps) => {
fill="none"
xmlns="http://www.w3.org/2000/svg"
variants={searchMobileMotion}
initial={isSmall ? "loopRest" : "loopActive"}
animate={
isSmall
? isInputFocused
? "loopActive"
: "loopRest"
: "loopActive"
}
>
initial={isSmall ? 'loopRest' : 'loopActive'}
animate={isSmall ? (isInputFocused ? 'loopActive' : 'loopRest') : 'loopActive'}>
<g clipPath="url(#clip0_138_523)">
<path
d="M11.9163 12.8394L10.833 11.7561M6.22884 12.2978C6.9046 12.2978 7.57375 12.1647 8.19807 11.9061C8.82239 11.6475 9.38966 11.2684 9.8675 10.7906C10.3453 10.3128 10.7244 9.74548 10.983 9.12116C11.2416 8.49684 11.3747 7.8277 11.3747 7.15194C11.3747 6.47618 11.2416 5.80703 10.983 5.18271C10.7244 4.55839 10.3453 3.99112 9.8675 3.51328C9.38966 3.03545 8.82239 2.65641 8.19807 2.39781C7.57375 2.1392 6.9046 2.0061 6.22884 2.0061C4.86408 2.0061 3.55522 2.54825 2.59019 3.51328C1.62516 4.47831 1.08301 5.78718 1.08301 7.15194C1.08301 8.5167 1.62516 9.82556 2.59019 10.7906C3.55522 11.7556 4.86408 12.2978 6.22884 12.2978V12.2978Z"
@ -103,27 +92,15 @@ const Search = ({ isSmall, isInputFocused, setIsInputFocused }: IProps) => {
</g>
<defs>
<clipPath id="clip0_138_523">
<rect
width="13"
height="13"
fill="white"
transform="translate(0 0.922791)"
/>
<rect width="13" height="13" fill="white" transform="translate(0 0.922791)" />
</clipPath>
</defs>
</motion.svg>
<motion.span
variants={searchMobileMotion}
initial={isSmall ? "placeholderRest" : {}}
animate={
isSmall
? isInputFocused
? "placeholderActive"
: "placeholderRest"
: {}
}
>
Search
initial={isSmall ? 'placeholderRest' : {}}
animate={isSmall ? (isInputFocused ? 'placeholderActive' : 'placeholderRest') : {}}>
{language === 'EN' ? 'Search' : language === 'RU' ? 'Искать' : 'Gözle'}
</motion.span>
</motion.div>
</motion.form>

View File

@ -1,37 +1,34 @@
// Modules
import { useLocation } from "react-router-dom";
import { v4 as uuidv4 } from "uuid";
import { useDispatch, useSelector } from "react-redux";
import { useEffect, useState } from "react";
import { useLocation } from 'react-router-dom';
import { v4 as uuidv4 } from 'uuid';
import { useDispatch, useSelector } from 'react-redux';
import { useEffect, useState } from 'react';
// Types
import { ICategoryData, RootState } from "../../types/store.types";
import { ICategoriesData } from "../../types/data.types";
import { ICategoryData, RootState } from '../../types/store.types';
import { ICategoriesData } from '../../types/data.types';
// Actions
import { setActiveLink } from "../../actions/setActiveLink.action";
import { setActiveLink } from '../../actions/setActiveLink.action';
// Api
import { Api } from "../../api/Api";
import { url } from "../../url";
import { categoriesParams } from "../../api/params";
import { Api } from '../../api/Api';
import { url } from '../../url';
import { categoriesParams } from '../../api/params';
// Components
import Loader from "../global/Loader";
import SubNavLi from "./SubNavLi";
import SubNavLiMain from "./SubNavLiMain";
import { setCategories } from "../../actions/setData";
import Loader from '../global/Loader';
import SubNavLi from './SubNavLi';
import SubNavLiMain from './SubNavLiMain';
import { setCategories } from '../../actions/setData';
const SubNav = () => {
const activeLink = useSelector<RootState, RootState["activeLink"]["active"]>(
(state) => state.activeLink.active
);
const language = useSelector<RootState, RootState["language"]["title"]>(
(state) => state.language.title
const activeLink = useSelector<RootState, RootState['activeLink']['active']>(
(state) => state.activeLink.active,
);
const categories = useSelector<RootState, RootState["categories"]["data"]>(
(state) => state.categories.data
const categories = useSelector<RootState, RootState['categories']['data']>(
(state) => state.categories.data,
);
const dispatch = useDispatch();
@ -41,40 +38,30 @@ const SubNav = () => {
};
// Api
const api = new Api(url + "/categories", categoriesParams);
const api = new Api(url + '/categories', categoriesParams);
const language = api.language;
useEffect(() => {
api.get(categories, (data: ICategoryData["data"]) =>
dispatch(setCategories(data))
);
api.get(categories, (data: ICategoryData['data']) => dispatch(setCategories(data)));
}, [language]);
const location = useLocation();
useEffect(() => {
if (!location.pathname.includes("category")) {
if (!location.pathname.includes('category')) {
onClickLink(0);
return;
}
const category =
location.pathname.split("/")[location.pathname.split("/").length - 1];
const category = location.pathname.split('/')[location.pathname.split('/').length - 1];
onClickLink(parseInt(category));
}, [location]);
return (
<nav className="subnav">
<div className="container">
<ul
className={`subnav-inner ${
!(categories.data[0].id > -1) ? "loading" : ""
}`}
>
<ul className={`subnav-inner ${!(categories.data[0].id > -1) ? 'loading' : ''}`}>
{categories.data[0].id > -1 ? (
<>
<SubNavLiMain
data={categories}
activeLink={activeLink}
onClickLink={onClickLink}
/>
<SubNavLiMain data={categories} activeLink={activeLink} onClickLink={onClickLink} />
{categories.data.map((dataEl, index) =>
index <= 4 ? (
<SubNavLi
@ -83,7 +70,7 @@ const SubNav = () => {
activeLink={activeLink}
onClickLink={onClickLink}
/>
) : null
) : null,
)}
</>
) : (

View File

@ -1,16 +1,17 @@
// Modules
import { motion } from "framer-motion";
import { useState } from "react";
import { v4 as uuidv4 } from "uuid";
import { motion } from 'framer-motion';
import { useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import { Api } from '../../api/Api';
// Animations
import { catMotion, linkMotion } from "../../animations/subNav.animations";
import { catMotion, linkMotion } from '../../animations/subNav.animations';
// Types
import { ICategoriesData } from "../../types/data.types";
import { ICategoriesData } from '../../types/data.types';
// Components
import NavDropdown from "./NavDropdown";
import NavDropdown from './NavDropdown';
interface IProps {
activeLink: number;
@ -19,14 +20,16 @@ interface IProps {
}
const SubNavLiMain = ({ activeLink, data, onClickLink }: IProps) => {
// Language
const language = new Api('').language;
const [dropdownOpen, setDropdownOpen] = useState<boolean>(false);
return (
<motion.li
className="sub-nav-li-main"
initial={"active"}
initial={'active'}
variants={linkMotion}
onClick={() => setDropdownOpen(!dropdownOpen)}
>
onClick={() => setDropdownOpen(!dropdownOpen)}>
<motion.div className="inner">
<motion.svg
width="24"
@ -35,9 +38,8 @@ const SubNavLiMain = ({ activeLink, data, onClickLink }: IProps) => {
fill="none"
xmlns="http://www.w3.org/2000/svg"
variants={catMotion}
initial={"menuRest"}
animate={dropdownOpen ? "menuActive" : "menuRest"}
>
initial={'menuRest'}
animate={dropdownOpen ? 'menuActive' : 'menuRest'}>
<g clipPath="url(#clip0_343_1783)">
<path
d="M20.05 11.0001H3.95C3.42533 11.0001 3 11.4255 3 11.9501V12.0501C3 12.5748 3.42533 13.0001 3.95 13.0001H20.05C20.5747 13.0001 21 12.5748 21 12.0501V11.9501C21 11.4255 20.5747 11.0001 20.05 11.0001Z"
@ -58,23 +60,23 @@ const SubNavLiMain = ({ activeLink, data, onClickLink }: IProps) => {
</clipPath>
</defs>
</motion.svg>
<p className={activeLink === 0 ? "active" : ""}>Категории</p>
<p className={activeLink === 0 ? 'active' : ''}>
{language === 'EN' ? 'Categoryes' : language === 'RU' ? 'Категории' : 'Kategoriýalar'}
</p>
<p>|</p>
<p>
<motion.span
variants={catMotion}
initial={"rest"}
animate={activeLink === 0 ? "active" : "rest"}
>
Главная
initial={'rest'}
animate={activeLink === 0 ? 'active' : 'rest'}>
{language === 'EN' ? 'Home' : language === 'RU' ? 'Главная' : 'Esasy sahypa'}
</motion.span>
{data.data.map((el) => (
<motion.span
key={uuidv4()}
variants={catMotion}
initial={"rest"}
animate={activeLink === el.id ? "active" : "rest"}
>
initial={'rest'}
animate={activeLink === el.id ? 'active' : 'rest'}>
{el.name}
</motion.span>
))}