api integrations

This commit is contained in:
VividTruthKeeper 2022-07-17 01:29:46 +05:00
parent 30d4e5a788
commit 6836146f92
22 changed files with 486 additions and 295 deletions

View File

@ -1,7 +1,7 @@
// Modules
import { Routes, Route } from "react-router-dom";
import { useState, useMemo } from "react";
import { LoaderContext } from "./context/LoaderContext";
import { EventContext } from "./context/LoaderContext";
// Styles
import "./styles/style.scss";
@ -10,6 +10,9 @@ import "./styles/style.scss";
import Nav from "./components/global/Nav";
import Footer from "./components/global/Footer";
// Type
import { loaderType } from "./types/contextType";
// Pages
import Main from "./pages/Main";
import Events from "./pages/Events";
@ -23,20 +26,19 @@ import Calendar from "./components/global/Calendar";
const App = () => {
// Types
type drop = [boolean, React.Dispatch<React.SetStateAction<boolean>>];
type loaderType = [boolean, React.Dispatch<React.SetStateAction<boolean>>];
// State
const [dropdown, setDropdown]: drop = useState(false);
const [loader, setLoader]: loaderType = useState(false);
const [eventData, setEventData]: loaderType = useState(null);
// Stack state into Memo
const loaderValue = useMemo(
() => ({ loader, setLoader }),
[loader, setLoader]
() => ({ eventData, setEventData }),
[eventData, setEventData]
);
return (
<LoaderContext.Provider value={loaderValue}>
<EventContext.Provider value={loaderValue}>
<div className="App">
<Nav dropdown={dropdown} setDropdown={setDropdown} />
<div className="inner-body">
@ -53,7 +55,7 @@ const App = () => {
</div>
<Footer dropdown={dropdown} setDropdown={setDropdown} />
</div>
</LoaderContext.Provider>
</EventContext.Provider>
);
};

View File

@ -1,60 +1,66 @@
// Modules
import { useState, useEffect } from "react";
import { v4 as uuidv4 } from "uuid";
// Components
import Event from "../global/Event";
import EventSkeleton from "../global/EventSkeleton";
// Images
import competition from "../../images/competition.jpg";
import competition2 from "../../images/competition2.jpg";
import competition3 from "../../images/competition3.jpg";
// Helpers
import { getAsidePosts } from "../../helpers/apiRequests";
// Types
import { eventProps } from "../../types/eventProps";
const eventsData: eventProps[] = [
{
image: competition,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition2,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition3,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
];
import { eventType } from "../../types/eventProps";
const EventAside = () => {
// State
const [events, setEvents]: eventType = useState({
data: [
{
id: -1,
title: "",
published_at: "",
featured_images: [
{
id: -1,
path: "",
},
],
content_html: "",
},
],
links: {
prev: null,
next: null,
},
meta: {
current_page: -1,
total: -1,
},
loaded: false,
});
useEffect(() => {
getAsidePosts(setEvents);
}, []);
return (
<aside className="latest">
<h2 className="latest-title">Последние новости</h2>
<div className="latest-content">
{eventsData.map((evnt) => {
return (
<Event
key={uuidv4()}
image={evnt.image}
text={evnt.text}
time={evnt.time}
date={evnt.date}
/>
);
})}
{events.loaded
? events.data.map((evnt) => {
return (
<Event
key={uuidv4()}
image={evnt.featured_images[0].path}
title={evnt.title}
time={"00:00"}
date={evnt.published_at}
content={evnt.content_html}
/>
);
})
: ["", "", "", ""].map(() => <EventSkeleton key={uuidv4()} />)}
</div>
</aside>
);

View File

@ -1,15 +1,40 @@
// Modules
import { Link } from "react-router-dom";
import { useContext } from "react";
import { EventContext } from "../../context/LoaderContext";
// Components
import EventDate from "./EventDate";
// Types
import { eventProps } from "../../types/eventProps";
import { eventProp } from "../../types/eventProps";
const Event = ({ image, time, date, text }: eventProps) => {
const Event = ({ image, time, date, title, content }: eventProp) => {
const { setEventData } = useContext(EventContext);
return (
<Link to={"/"} className="event">
<Link
to={"/event"}
className="event"
onClick={() => {
localStorage.setItem(
"event",
JSON.stringify({
image: image,
time: time,
date: date,
title: title,
content: content,
})
);
setEventData({
image: image,
time: time,
date: date,
title: title,
content: content,
});
}}
>
<div className="event-top">
<div className="event-img">
<img src={image} alt="" />
@ -17,7 +42,7 @@ const Event = ({ image, time, date, text }: eventProps) => {
<EventDate time={time} date={date} />
</div>
<div className="event-bottom">
<p>{text}</p>
<p>{title}</p>
</div>
</Link>
);

View File

@ -0,0 +1,15 @@
const EventSkeleton = () => {
return (
<a className="event skeleton">
<div className="event-top">
<div className="event-img"></div>
<p></p>
</div>
<div className="event-bottom">
<p></p>
</div>
</a>
);
};
export default EventSkeleton;

View File

@ -1,75 +1,72 @@
// Modules
import { useState, useEffect } from "react";
import { v4 as uuidv4 } from "uuid";
// Components
import SectionTitle from "../global/SectionTitle";
import Event from "../global/Event";
import EventSkeleton from "../global/EventSkeleton";
// Images
import competition from "../../images/competition.jpg";
import competition2 from "../../images/competition2.jpg";
import competition3 from "../../images/competition3.jpg";
// Helpers
import { getMainPosts } from "../../helpers/apiRequests";
// Types
import { eventProps } from "../../types/eventProps";
const eventsData: eventProps[] = [
{
image: competition,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition2,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition3,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition2,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition3,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
];
import { eventType } from "../../types/eventProps";
const EventsSection = () => {
// State
const [events, setEvents]: eventType = useState({
data: [
{
id: -1,
title: "",
published_at: "",
featured_images: [
{
id: -1,
path: "",
},
],
content_html: "",
},
],
links: {
prev: null,
next: null,
},
meta: {
current_page: -1,
total: -1,
},
loaded: false,
});
useEffect(() => {
getMainPosts(setEvents);
}, []);
return (
<section className="events">
<div className="container">
<div className="events-inner">
<SectionTitle title="События и новости" />
<div className="events-content">
{eventsData.map((evnt) => {
return (
<Event
key={uuidv4()}
image={evnt.image}
text={evnt.text}
time={evnt.time}
date={evnt.date}
/>
);
})}
{events.loaded
? events.data.map((evnt) => {
return (
<Event
key={uuidv4()}
image={evnt.featured_images[0].path}
title={evnt.title}
time={"00:00"}
date={evnt.published_at}
content={evnt.content_html}
/>
);
})
: ["", "", "", "", "", ""].map(() => (
<EventSkeleton key={uuidv4()} />
))}
</div>
</div>
</div>

View File

@ -1,3 +1,4 @@
import { createContext } from "react";
import { loaderType } from "../types/contextType";
export const LoaderContext = createContext({});
export const EventContext = createContext<loaderType | null>(null);

View File

@ -1,21 +1,62 @@
// links
import axios from "axios";
import { SlideProps } from "../types/mainSliderSlide";
import { partnersType } from "../types/partnersType";
import { sliderDataUrl, partners } from "../links";
import { eventType } from "../types/eventProps";
// Links
import {
sliderDataUrl,
partners,
postsMain,
postsAll,
postsAside,
} from "../links";
export const getMainSliderData = (
setState: React.Dispatch<SlideProps[]>
): void => {
axios.get(sliderDataUrl).then((res) => {
setState(res.data.data);
});
axios
.get(sliderDataUrl)
.then((res) => {
setState(res.data.data);
})
.catch(() => {});
};
export const getPartnerSliderData = (
setState: React.Dispatch<partnersType[]>
): void => {
axios.get(partners).then((res) => {
setState(res.data.data);
});
axios
.get(partners)
.then((res) => {
setState(res.data.data);
})
.catch(() => {});
};
export const getMainPosts = (setState: eventType[1]): void => {
axios
.get(postsMain)
.then((res) => {
setState({ ...res.data, loaded: true });
})
.catch();
};
export const getAllPosts = (setState: eventType[1]): void => {
axios
.get(postsAll)
.then((res) => {
setState({ ...res.data, loaded: true });
})
.catch();
};
export const getAsidePosts = (setState: eventType[1]): void => {
axios
.get(postsAside)
.then((res) => {
setState({ ...res.data, loaded: true });
})
.catch();
};

BIN
src/images/chess.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

View File

@ -1,3 +1,11 @@
export const hosting = "http://tkf.com.tm";
export const sliderDataUrl = hosting + "/api/v1/sliders";
export const partners = hosting + "/api/v1/partners";
export const hosting: string = "http://tkf.com.tm";
export const sliderDataUrl: string = hosting + "/api/v1/sliders";
export const partners: string = hosting + "/api/v1/partners";
export const postsMain: string =
hosting + "/api/v1/posts?locale=ru&per_page=6&sort_order=asc";
export const postsAll: string =
hosting + "/api/v1/posts?locale=ru&per_page=15&sort_order=asc";
export const postsAside: string =
hosting + "/api/v1/posts?locale=ru&per_page=4&sort_order=asc";

View File

@ -1,4 +1,5 @@
// Modules
import { useEffect } from "react";
// Icons
import bg from "../icons/green-bg.svg";
@ -7,6 +8,9 @@ import bg from "../icons/green-bg.svg";
import ContactForm from "../components/contact/ContactForm";
const Contacts = () => {
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return (
<main className="contact">
<div className="contact-bg">

View File

@ -1,98 +1,44 @@
// Modules
import { useContext, useEffect } from "react";
import { EventContext } from "../context/LoaderContext";
// Components
import EventAside from "../components/event_item/EventAside";
import EventDate from "../components/global/EventDate";
// Images
import chess from "../images/chess.jpg";
import prizes from "../images/prizes.jpg";
// Link: /event
// Link
const EventItem = () => {
useEffect(() => {
window.scrollTo(0, 0);
}, []);
const { eventData } = useContext(EventContext);
return (
<main className="eventitem">
<div className="container">
<div className="eventitem-inner">
<div className="eventitem-content">
<div className="eventitem-top">
<EventDate time={"02:58"} date={"16.12.2021"} />
<h2>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Velit
pellentesque mattis aliquet semper.
</h2>
</div>
<div className="eventitem-bottom">
<div className="eventitem-img">
<img src={chess} alt="" />
{eventData ? (
<div className="eventitem-top">
<EventDate time={eventData.time} date={eventData.date} />
<h2>{eventData.title}</h2>
</div>
<p>
The chess federations of Turkmenistan and Armenia held the first
remote session, which was attended by famous chess
representatives of the two stated, including heads of
federations, masters of sports, international FIDE judges and
coaches, grandmasters and long-time friends who once competed
with each other at different matches.
</p>
<p>
The Turkmen side was headed by Myratdurdy Hashayev, Chairman of
the National Chess Federation, while the Armenian side was
headed by the First Vice-President of the Chess Federation of
Armenia, Director of the Chess Academy Smbat Lputyan.
</p>
<p>
During the meeting that, despite its remote format, was held in
a very warm and friendly atmosphere, the issues related to the
educational processes, the training of chess teachers and
trainers, cooperation between the federations of the two
countries, as well as methods of online chess teaching were
discussed.
</p>
<p>
It is worth to note, in Armenia, since 2011, chess has been
included in the curriculum of the 2-4th grades of general
education schools as a compulsory subject. And the worlds first
Center of Chess Educational Research was established on the
basis of the Armenian State Pedagogical University named after
Khachatur Abovian (ASPU).
</p>
<div className="eventitem-img">
<img src={prizes} alt="" />
) : (
""
)}
{eventData ? (
<div className="eventitem-bottom">
<div className="eventitem-img">
<img src={eventData.image} alt="" />
</div>
<div
className="eventitem-content"
dangerouslySetInnerHTML={{ __html: eventData.content }}
></div>
</div>
<p>
According to the research of this center, this wise game serves
as a locomotive for various psychological processes, contributes
to the development of combinatorial and strategic thinking in
children, and sense of responsibility. Srbuhi Gevorgyan, Doctor
of Psychological Sciences, Professor, Vice-Rector for Academic
Affairs, ASPU, expressed the readiness to share with their
Turkmen colleagues the materials, research results, information
on the introduction of chess in the general educational process.
</p>
<p>
During the video session, the parties agreed to launch a new
format of cooperation online exchange of experience in the
field of teaching chess, holding open tournaments of the two
countries, etc. In addition, Armenian chess grandmaster Samvel
Ter-Sahakyan shared some of his secrets.
</p>
<p>
In turn, Turkmen chess players told about the new Chess Academy
in Ashgabat, which is a gift from the head of state. The Academy
has two tournament halls for 100 and 200 persons, 10 computer
and 25 training classes, chess attributes store, library, rooms
for analyzing games, museum, and the office of the Chess
Federation of Turkmenistan.
</p>
<p>
At the end of the video bridge, organized with the assistance of
the Embassy of Turkmenistan in Yerevan, its participants
expressed their common desire to develop cooperation between the
chess communities of the two countries, using, among other ways,
the possibilities of Internet communication.
</p>
</div>
) : (
""
)}
</div>
<EventAside />
</div>

View File

@ -1,111 +1,129 @@
// Modules
import { useState, useEffect } from "react";
import { v4 as uuidv4 } from "uuid";
// Images
import competition from "../images/competition.jpg";
import competition2 from "../images/competition2.jpg";
import competition3 from "../images/competition3.jpg";
// Icons
import left from "../icons/arrow-left-white.svg";
import right from "../icons/arrow-right-white.svg";
// Components
import Event from "../components/global/Event";
import SectionTitle from "../components/global/SectionTitle";
import EventSkeleton from "../components/global/EventSkeleton";
// Types
import { eventProps } from "../types/eventProps";
import { eventType } from "../types/eventProps";
const eventsData: eventProps[] = [
{
image: competition,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition2,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition3,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition2,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition3,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition2,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition3,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition2,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
{
image: competition3,
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
time: "02:58",
date: "16.12.2021",
},
];
// Helpers
import { getAllPosts } from "../helpers/apiRequests";
const Events = () => {
// State
const [events, setEvents]: eventType = useState({
data: [
{
id: -1,
title: "",
published_at: "",
featured_images: [
{
id: -1,
path: "",
},
],
content_html: "",
},
],
links: {
prev: null,
next: null,
},
meta: {
current_page: -1,
total: -1,
},
loaded: false,
});
useEffect(() => {
getAllPosts(setEvents);
}, []);
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return (
<main className="events-page">
<div className="container">
<div className="event-page-wrapper">
<SectionTitle title={"События и новости"} />
<div className="events-page-inner">
{eventsData.map((evnt) => {
return (
<Event
key={uuidv4()}
image={evnt.image}
text={evnt.text}
time={evnt.time}
date={evnt.date}
/>
);
})}
{events.loaded
? events.data.map((evnt) => {
return (
<Event
key={uuidv4()}
image={evnt.featured_images[0].path}
title={evnt.title}
time={"00:00"}
date={evnt.published_at}
content={evnt.content_html}
/>
);
})
: [
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
].map(() => <EventSkeleton key={uuidv4()} />)}
</div>
<div className="events-page-bottom">
<div className="events-page-nav">
<div className="events-page-nav-left">
<button
type="button"
className="events-page-btn"
disabled={events.meta.current_page < 2 ? true : false}
>
<img src={left} alt="" />
</button>
<span className="event-page-number">
{events.meta.current_page}
</span>
<button
type="button"
className="events-page-btn"
disabled={
events.meta.current_page === events.meta.total - 1
? true
: false
}
>
<img src={right} alt="" />
</button>
</div>
<div className="events-page-nav-right">
<span>{`Всего ${events.meta.total - 1} ${
events.meta.total - 1 === 1
? "страница"
: events.meta.total - 1 < 5
? "страницы"
: "страниц"
}`}</span>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,4 +1,5 @@
// Modules
import { useEffect } from "react";
// Components
import MainSlider from "../components/main/MainSlider";
@ -7,6 +8,9 @@ import PlayerRating from "../components/main/PlayerRatingSection";
import Partners from "../components/main/PartnersSection";
const Main = () => {
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return (
<main className="main">
<MainSlider />

View File

@ -1,4 +1,5 @@
// Modules
import { useEffect } from "react";
// Images
import magnus from "../images/magnus.jpg";
@ -6,6 +7,9 @@ import magnus from "../images/magnus.jpg";
// Link: /profile
const Profile = () => {
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return (
<main className="profile">
<div className="container">

View File

@ -1,5 +1,6 @@
// Modules
import { Link } from "react-router-dom";
import { useEffect } from "react";
// Components
import SectionTitle from "../components/global/SectionTitle";
@ -12,6 +13,9 @@ import firouzja from "../images/firouzja.jpg";
import zhu from "../images/zhu.jpg";
const Rating = () => {
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return (
<main className="rating">
<div className="container">

View File

@ -1,4 +1,5 @@
// Modules
import { useEffect } from "react";
import { v4 as uuidv4 } from "uuid";
// Components
@ -50,6 +51,9 @@ const personData: personProps[] = [
// Link: /structure
const Structure = () => {
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return (
<main className="structure">
<div className="container">

View File

@ -6,12 +6,24 @@
border-bottom: 0.1rem solid $base-green;
max-width: 42rem;
overflow: hidden;
&.skeleton {
border-bottom: none;
p {
height: 2rem;
@include shineLoad;
}
}
}
.event-img {
max-width: 42rem;
max-height: 30rem;
min-height: 30rem;
width: 100%;
height: 100%;
overflow: hidden;
@include shineLoad;
img {
width: 100%;
height: 100%;

View File

@ -1,5 +1,4 @@
.events-page-inner {
padding-bottom: 16rem;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
column-gap: 7rem;
@ -11,7 +10,47 @@
}
.event-page-wrapper {
padding-bottom: 16rem;
display: flex;
flex-direction: column;
gap: 4.8rem;
}
.events-page-nav-left {
display: flex;
align-items: center;
gap: 4rem;
}
.events-page-btn {
@include button-std(0.5rem, 0rem, $scaled: true);
width: 5rem;
height: 5rem;
display: flex;
align-items: center;
justify-content: center;
img {
width: 1.3rem;
height: 1rem;
}
}
.event-page-number {
font-size: 1.8rem;
font-weight: bold;
}
.events-page-nav {
display: flex;
align-items: center;
justify-content: space-between;
gap: 4rem;
}
.events-page-nav-right {
span {
font-size: 1.8rem;
color: #7d7d7d;
}
}

View File

@ -148,3 +148,9 @@
gap: 4.8rem;
padding-bottom: 8rem;
}
.swiper-bg {
min-height: 140rem;
width: 100%;
@include shineLoad;
}

View File

@ -62,4 +62,24 @@ $hover-green: #0e654e;
background: $hover-green;
@include transition-std;
}
&:disabled {
transition: none;
transform: scale(1) !important;
background: #7d7d7d !important;
}
}
@mixin shineLoad {
backdrop-filter: blur(0.3rem);
background: #eee;
background: linear-gradient(110deg, #ececec 8%, #f5f5f5 18%, #ececec 33%);
border-radius: 5px;
background-size: 200% 100%;
animation: 1.5s animateBg linear infinite;
@keyframes animateBg {
to {
background-position-x: -200%;
}
}
}

1
src/types/contextType.ts Normal file
View File

@ -0,0 +1 @@
export type loaderType = any;

View File

@ -3,9 +3,43 @@ export interface eventTimeProps {
date: string;
}
export interface eventProps extends eventTimeProps {
interface eventFeaturedImages {
id: number;
path: string;
}
interface eventLinks {
prev: string | null;
next: string | null;
}
interface eventMeta {
current_page: number;
total: number;
}
interface eventData {
id: number;
title: string;
published_at: string;
featured_images: eventFeaturedImages[];
content_html: string;
}
export interface eventProps {
data: eventData[];
links: eventLinks;
meta: eventMeta;
loaded: boolean;
}
export type eventType = [eventProps, React.Dispatch<any>];
export interface eventProp {
image: string;
text: string;
title: string;
time: string;
date: string;
content: string;
}
// Used in EventsSection.tsx and its' child component Event.tsx