added next-intl, composed next-auth and next-intl in middleware, fixed some bugs, completed details page, added google auth

This commit is contained in:
Alibek committed 2024-02-29 14:09:37 +06:00
1 parent 9cd7b2a67d
commit 6637ab4eae
172 files changed
+1772 -502

No files matched your search

+9
View File
@@ -0,0 +1,9 @@
.app {
padding-top: 78px;
}
@media screen and (max-width: 768px) {
.app {
padding-top: 72px;
}
}
+11
View File
@@ -0,0 +1,11 @@
"use client";
import { SessionProvider } from "next-auth/react";
export const Providers = ({
children,
}: {
children: React.ReactNode;
}) => {
return <SessionProvider>{children}</SessionProvider>;
};
+86
View File
@@ -0,0 +1,86 @@
.about-us {
display: flex;
flex-direction: column;
h2 {
margin-bottom: 40px;
width: fit-content;
}
img {
align-self: center;
margin-bottom: 65px;
border-radius: 12px;
max-width: 1072px;
width: 100%;
height: 598px;
object-fit: cover;
}
h3 {
margin-bottom: 10px;
font-size: 24px;
font-weight: 500;
line-height: 29px;
color: rgb(62, 50, 50);
}
&__descriptions {
display: flex;
flex-direction: column;
gap: 20px;
p {
font-size: 20px;
font-weight: 400;
line-height: 34px;
color: rgb(62, 50, 50);
}
}
}
@media screen and (max-width: 768px) {
.about-us {
h2 {
margin-bottom: 30px;
}
img {
margin-bottom: 30px;
height: 392px;
}
h3 {
font-size: 20px;
line-height: 24px;
}
&__descriptions {
gap: 16px;
p {
font-size: 18px;
line-height: 34px;
}
}
}
}
@media screen and (max-width: 550px) {
.about-us {
h2 {
margin-bottom: 20px;
}
img {
height: 231px;
}
&__descriptions {
p {
font-size: 16px;
line-height: 140%;
}
}
}
}
@@ -0,0 +1,12 @@
<svg width="1072.000000" height="598.000000" viewBox="0 0 1072 598" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>
Created with Pixso.
</desc>
<defs>
<pattern id="pattern_627_213000" patternContentUnits="objectBoundingBox" width="1.000000" height="1.000000">
<use xlink:href="#image627_21300_0" transform="matrix(0.002315,0,0,0.004149,-0.056678,0)"/>
</pattern>
<image id="image627_21300_0" width="481.000000" height="241.000000" xlink:href="data:image/png;base64,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 truncated
</defs>
<rect id="unsplash:NrN5Rvl89Lo" width="1072.000000" height="598.000000" fill="url(#pattern_627_213000)" fill-opacity="1.000000"/>
</svg>

After

Width:  |  Height:  |  Size: 332 KiB

+70
View File
@@ -0,0 +1,70 @@
import Typography from "@/shared/ui/components/Typography/Typography";
import "./AboutUs.scss";
import Image from "next/image";
import header from "./assets/header.svg";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "KG ROAD | О нас",
description:
'Страница "О Нас" Kyrgyzstan Transperency International',
};
const AboutUs = () => {
return (
<div className="about-us page-padding">
<Typography element="h2">О нас</Typography>
<Image src={header} alt="Header Image" />
<h3>Don’t wait. The purpose of our lives is to be happy!</h3>
<div className="about-us__descriptions">
<p>
arrival, your senses will be rewarded with the pleasant
scent of lemongrass oil used to clean the natural wood found
throughout the room, creating a relaxing atmosphere within
the space. A wonderful serenity has taken possession of my
entire soul, like these sweet mornings of spring which I
enjoy with my whole heart. I am alone, and feel the charm of
existence in this spot, which was created for the bliss of
souls like mine. I am so happy, my dear friend, so absorbed
in the exquisite.
</p>
<p>
When you are ready to indulge your sense of excitement,
check out the range of water- sports opportunities at the
resort’s on-site water-sports center. Want to leave your
stress on the water? The resort has kayaks, paddleboards, or
the low-key pedal boats. Snorkeling equipment is available
as well, so you can experience the ever-changing undersea
environment. Not only do visitors to a bed and breakfast get
a unique perspective on the place they are visiting, they
have options for special packages not available in other
hotel settings.{" "}
</p>
<p>
Bed and breakfasts can partner easily with local businesses
for a smoothly organized and highly personalized vacation
experience. The Fife and Drum Inn offers options such as the
Historic Triangle Package that includes three nights at the
Inn, breakfasts, and admissions to historic Williamsburg,
Jamestown, and Yorktown. Bed and breakfasts also lend
themselves to romance.
</p>
<p>
Part of the charm of a bed and breakfast is the uniqueness;
art, décor, and food are integrated to create a complete
experience. For example, the Fife and Drum retains the
colonial feel of the area in all its guest rooms. Special
features include antique furnishings, elegant four poster
beds in some guest rooms, as well folk art and artifacts
from the restoration period of the historic area available
for guests to enjoy.
</p>
</div>
</div>
);
};
export default AboutUs;
@@ -0,0 +1,20 @@
.create-report {
display: flex;
flex-direction: column;
gap: 40px;
h2 {
text-align: start;
}
}
@media screen and (max-width: 768px) {
.create-report {
gap: 30px;
}
}
@media screen and (max-width: 550px) {
.create-report {
gap: 20px;
}
}
+29
View File
@@ -0,0 +1,29 @@
import Typography from "@/shared/ui/components/Typography/Typography";
import "./CreateReport.scss";
import dynamic from "next/dynamic";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "KG ROAD | Написать обращение",
description:
"Написать обращение Kyrgyzstan Transperency International",
};
const DynamicForm = dynamic(
() => import("@/widgets/forms/ReportForm/ReportForm"),
{
ssr: false,
}
);
const CreateReport = () => {
return (
<div className="create-report page-padding">
<Typography element="h2">Написать обращение</Typography>
<DynamicForm />
</div>
);
};
export default CreateReport;
+60
View File
@@ -0,0 +1,60 @@
@import url("https://fonts.cdnfonts.com/css/inter");
* {
box-sizing: border-box;
padding: 0;
margin: 0;
font-family: system-ui, -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
"Helvetica Neue", sans-serif;
// font-family: "Tilda Sans";
}
button,
a,
input {
font-size: 16px;
}
button {
border: none;
background-color: transparent;
cursor: pointer;
}
a {
text-decoration: none;
color: black;
}
input {
border: none;
outline: none;
}
table {
width: 100%;
display: flex;
flex-direction: column;
}
ul,
ol {
list-style-type: none;
}
.page-padding {
padding: 40px 90px;
}
@media screen and (max-width: 1024px) {
.page-padding {
padding: 40px 30px;
}
}
@media screen and (max-width: 550px) {
.page-padding {
padding: 40px 16px;
}
}
+34
View File
@@ -0,0 +1,34 @@
import type { Metadata } from "next";
import "./globals.scss";
import "./App.scss";
// import "@/shared/fonts/fonts.scss";
import Navbar from "@/widgets/Navbar/Navbar";
import Footer from "@/widgets/Footer/Footer";
import { NextIntlClientProvider, useMessages } from "next-intl";
import { Providers } from "./Providers";
export default function LocaleLayout({
children,
params,
}: Readonly<{
children: React.ReactNode;
params: { locale: string };
}>) {
const messages = useMessages();
return (
<html lang={params.locale}>
<body>
<NextIntlClientProvider
locale={params.locale}
messages={messages}
>
<Providers>
<Navbar />
<div className="app">{children}</div>
<Footer />
</Providers>
</NextIntlClientProvider>
</body>
</html>
);
}
+21
View File
@@ -0,0 +1,21 @@
.news {
display: flex;
flex-direction: column;
gap: 40px;
h2 {
width: fit-content;
}
}
@media screen and (max-width: 768px) {
.news {
gap: 30px;
}
}
@media screen and (max-width: 550px) {
.news {
gap: 20px;
}
}
+104
View File
@@ -0,0 +1,104 @@
.news-details {
display: flex;
flex-direction: column;
gap: 40px;
&__img {
align-self: center;
#news-img {
margin-bottom: 30px;
width: 100%;
max-width: 1072px;
height: 598px;
border-radius: 12px;
object-fit: cover;
}
}
&__date-and-reviews {
display: flex;
align-items: center;
gap: 80px;
}
&__date,
&__reviews {
display: flex;
align-items: center;
gap: 6px;
p {
font-size: 15px;
font-weight: 500;
line-height: 20px;
color: rgba(62, 50, 50, 0.75);
}
}
&__text {
width: 100%;
max-width: 1072px;
align-self: center;
display: flex;
flex-direction: column;
gap: 10px;
color: rgb(62, 50, 50);
h3 {
font-size: 24px;
font-weight: 500;
line-height: 29px;
}
p {
font-size: 20px;
font-weight: 400;
line-height: 34px;
}
}
}
@media screen and (max-width: 768px) {
.news-details {
gap: 30px;
&__img {
#news-img {
margin-bottom: 25px;
height: 392px;
}
}
&__text {
h3 {
font-size: 20px;
line-height: 24px;
}
p {
font-size: 18px;
line-height: 34px;
}
}
}
}
@media screen and (max-width: 550px) {
.news-details {
gap: 20px;
&__img {
#news-img {
margin-bottom: 20px;
height: 231px;
}
}
&__text {
p {
font-size: 16px;
line-height: 140%;
}
}
}
}
@@ -0,0 +1,17 @@
<svg width="16.000000" height="16.000000" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>
Created with Pixso.
</desc>
<defs>
<clipPath id="clip2340_50999">
<rect id="calendar" width="16.000000" height="16.000000" fill="white" fill-opacity="0"/>
</clipPath>
</defs>
<rect id="calendar" width="16.000000" height="16.000000" fill="#FFFFFF" fill-opacity="0"/>
<g clip-path="url(#clip2340_50999)">
<path id="Vector" d="M12.666 2.66699C13.4023 2.66699 14 3.26367 14 4L14 13.334C14 14.0703 13.4023 14.667 12.666 14.667L3.33398 14.667C2.59766 14.667 2 14.0703 2 13.334L2 4C2 3.26367 2.59766 2.66699 3.33398 2.66699L12.666 2.66699Z" stroke="#6E6565" stroke-opacity="1.000000" stroke-width="1.000000" stroke-linejoin="round"/>
<path id="Vector" d="M10.666 1.33301L10.666 4" stroke="#6E6565" stroke-opacity="1.000000" stroke-width="1.000000" stroke-linejoin="round" stroke-linecap="round"/>
<path id="Vector" d="M5.33398 1.33301L5.33398 4" stroke="#6E6565" stroke-opacity="1.000000" stroke-width="1.000000" stroke-linejoin="round" stroke-linecap="round"/>
<path id="Vector" d="M2 6.66699L14 6.66699" stroke="#6E6565" stroke-opacity="1.000000" stroke-width="1.000000" stroke-linejoin="round" stroke-linecap="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1,14 @@
<svg width="16.000000" height="16.000000" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>
Created with Pixso.
</desc>
<defs>
<clipPath id="clip2340_51004">
<rect id="message-circle" width="16.000000" height="16.000000" fill="white" fill-opacity="0"/>
</clipPath>
</defs>
<rect id="message-circle" width="16.000000" height="16.000000" fill="#FFFFFF" fill-opacity="0"/>
<g clip-path="url(#clip2340_51004)">
<path id="Vector" d="M13.4004 10.2002C12.9297 11.1416 12.207 11.9326 11.3125 12.4863C10.416 13.04 9.38477 13.333 8.33398 13.333C7.45312 13.3359 6.58594 13.1299 5.80078 12.7334L2 14L3.26758 10.2002C2.86914 9.41504 2.66406 8.54688 2.66602 7.66699C2.66797 6.61426 2.96094 5.58301 3.51367 4.68848C4.06641 3.79395 4.85938 3.07031 5.80078 2.59961C6.58594 2.20312 7.45312 1.99805 8.33398 2L8.66602 2C10.0566 2.07715 11.3691 2.66309 12.3535 3.64746C13.3359 4.63086 13.9238 5.94336 14 7.33301L14 7.66699C14.002 8.54688 13.7969 9.41504 13.4004 10.2002Z" stroke="#6E6565" stroke-opacity="1.000000" stroke-width="1.000000" stroke-linejoin="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

+75
View File
@@ -0,0 +1,75 @@
import Typography from "@/shared/ui/components/Typography/Typography";
import "./NewsDetails.scss";
import { apiInstance } from "@/shared/config/apiConfig";
import { INews } from "@/shared/types/news-type";
import Image from "next/image";
import message from "./icons/message.svg";
import calendar from "./icons/calendar.svg";
import ReviewSection from "@/widgets/ReviewSection/ReviewSection";
const NewsDetails = async ({
params,
}: {
params: { id: string };
}) => {
const getNewsById = async () => {
const response = await apiInstance.get<INews>(
`/news/${params.id}/`
);
return response.data;
};
const data = await getNewsById();
const months: Record<string, string> = {
"01": "Январь",
"02": "Февраль",
"03": "Март",
"04": "Апрель",
"05": "Май",
"06": "Июнь",
"07": "Июль",
"08": "Август",
"09": "Сентябрь",
"10": "Октябрь",
"11": "Ноябрь",
"12": "Декабрь",
};
return (
<div className="news-details page-padding">
<Typography element="h2">{data.title}</Typography>
<div className="news-details__img">
<img id="news-img" src={data.image} alt="News Image" />
<div className="news-details__date-and-reviews">
<div className="news-details__date">
<Image src={calendar} alt="Calendar Icon" />
<p>
{months[data.created_at.slice(5, 7)]}{" "}
{data.created_at.slice(5, 7).slice(0, 1) === "0"
? data.created_at.slice(6, 7)
: data.created_at.slice(5, 7)}
, {data.created_at.slice(0, 4)}
</p>
</div>
<div className="news-details__reviews">
<Image src={message} alt="Message Icon" />
<p>Комментарии: {data.count_reviews}</p>
</div>
</div>
</div>
<div className="news-details__text">
<h3>{data.title}</h3>
<p>{data.description}</p>
</div>
<ReviewSection endpoint="news" id={data.id} />
</div>
);
};
export default NewsDetails;
+28
View File
@@ -0,0 +1,28 @@
import "./News.scss";
import Typography from "@/shared/ui/components/Typography/Typography";
import NewsList from "@/widgets/NewsList/NewsList";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "KG ROAD | Новости",
description:
"Страница новостей Kyrgyzstan Transperency International",
};
const News = ({
searchParams,
}: {
searchParams: {
["страница-новостей"]: string;
};
}) => {
return (
<div className="news page-padding">
<Typography element="h2">Новости</Typography>
<NewsList searchParams={searchParams} />
</div>
);
};
export default News;
+35
View File
@@ -0,0 +1,35 @@
import Header from "@/widgets/home/Header/Header";
import StatisticsSection from "@/widgets/home/StatisticsSection/StatisticsSection";
import RatingSection from "@/widgets/home/RatingSection/RatingSection";
import NewsSection from "@/widgets/home/NewsSection/NewsSection";
import MapSection from "@/widgets/home/MapSection/MapSection";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "KG ROAD | Главная",
description:
"Главная страница Kyrgyzstan Transperency International",
};
const Home = async ({
searchParams,
}: {
searchParams: {
["тип-дороги"]: string;
["поиск-на-карте"]: string;
["поиск-рейтинг"]: string;
["страница-рейтинга"]: string;
};
}) => {
return (
<div className="home">
<Header />
<StatisticsSection />
<MapSection searchParams={searchParams} />
<RatingSection searchParams={searchParams} />
<NewsSection />
</div>
);
};
export default Home;
+31
View File
@@ -0,0 +1,31 @@
"use client";
import { apiInstance } from "@/shared/config/apiConfig";
import { AxiosError } from "axios";
import { signOut, useSession } from "next-auth/react";
import { useEffect } from "react";
const AuthGuard = ({ children }: { children: React.ReactNode }) => {
const session = useSession();
const verifyToken = async () => {
try {
const data = {
token: session.data?.access_token,
};
await apiInstance.post("/token/verify/", data);
} catch (error: unknown) {
signOut({
callbackUrl: "/",
});
}
};
useEffect(() => {
if (session.status === "loading") return;
verifyToken();
}, [session.status]);
return <>{children}</>;
};
export default AuthGuard;
+8
View File
@@ -0,0 +1,8 @@
.profile {
display: flex;
flex-direction: column;
h2 {
margin-bottom: 50px;
}
}
+54
View File
@@ -0,0 +1,54 @@
import Typography from "@/shared/ui/components/Typography/Typography";
import "./Profile.scss";
import ProfileNav from "@/widgets/ProfileNav/ProfileNav";
import AuthGuard from "./AuthGuard";
import { AxiosError } from "axios";
import { apiInstance } from "@/shared/config/apiConfig";
import { getServerSession } from "next-auth";
import { authConfig } from "@/shared/config/authConfig";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "KG ROAD | Профиль",
description:
"Страница профиля Kyrgyzstan Transperency International",
};
const Profile = async ({
children,
}: Readonly<{
children: React.ReactNode;
}>) => {
const session = await getServerSession(authConfig);
const getProfile = async () => {
const Authorization = `Bearer ${session?.access_token}`;
const config = {
headers: {
Authorization,
},
};
try {
const response = await apiInstance.get<{
report_count: number;
}>("/users/profile/", config);
return response.data;
} catch (error: unknown) {
if (error instanceof AxiosError) console.log(error.message);
}
};
const data = await getProfile();
return (
<div className="profile page-padding">
<Typography element="h2">Личный кабинет</Typography>
<ProfileNav report_count={data?.report_count as number} />
<AuthGuard>{children}</AuthGuard>
</div>
);
};
export default Profile;
@@ -0,0 +1,16 @@
import ProfileTable from "@/widgets/tables/ProfileTable/ProfileTable";
import React from "react";
const MyReports = async ({
searchParams,
}: {
searchParams: { ["страница-обращений"]: string };
}) => {
return (
<div>
<ProfileTable searchParams={searchParams} />
</div>
);
};
export default MyReports;
+5
View File
@@ -0,0 +1,5 @@
const page = () => {
return <div>page</div>;
};
export default page;
@@ -0,0 +1,48 @@
"use server";
import ProfileAvatar from "@/features/ProfileAvatar/ProfileAvatar";
import { apiInstance } from "@/shared/config/apiConfig";
import { authConfig } from "@/shared/config/authConfig";
import { IProfile } from "@/shared/types/profile-type";
import ProfileForm from "@/widgets/forms/ProfileForm/ProfileForm";
import { AxiosError } from "axios";
import { getServerSession } from "next-auth";
import React from "react";
const Personal = async () => {
const session = await getServerSession(authConfig);
const getProfile = async () => {
const Authorization = `Bearer ${session?.access_token}`;
const config = {
headers: {
Authorization,
},
};
try {
const response = await apiInstance.get<IProfile>(
"/users/profile/",
config
);
return response.data;
} catch (error: unknown) {
if (error instanceof AxiosError) console.log(error.message);
}
};
const data = await getProfile();
return (
<div className="personal">
<ProfileAvatar img={data?.image as string} />
<ProfileForm
id={data?.id as number}
first_name={data?.first_name as string}
last_name={data?.last_name as string}
email={data?.email as string}
/>
</div>
);
};
export default Personal;
@@ -0,0 +1,37 @@
.report-details {
display: flex;
flex-direction: column;
gap: 75px;
&__container {
display: grid;
grid-template-columns: 1.05fr 1fr;
gap: 76px;
}
&__map {
grid-row: 2 / 3;
grid-column: 1 / 3;
}
}
@media screen and (max-width: 1024px) {
.report-details {
&__container {
grid-template-columns: 1fr;
gap: 45px;
}
&__map {
grid-row: 2 / 3;
grid-column: 1 / 2;
}
}
}
@media screen and (max-width: 550px) {
.report-details {
&__container {
gap: 40px;
}
}
}
@@ -0,0 +1,8 @@
<svg width="38.337891" height="38.336914" viewBox="0 0 38.3379 38.3369" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>
Created with Pixso.
</desc>
<defs/>
<path id="Icon" d="M15.7637 0.834961L22.5762 0.834961C24.8477 0.834961 26.6543 0.834961 28.1113 0.954102C29.6035 1.07617 30.877 1.33105 32.043 1.9248C33.9238 2.88379 35.4531 4.41309 36.4121 6.29492C37.0059 7.46094 37.2617 8.7334 37.3828 10.2256C37.502 11.6836 37.502 13.4902 37.502 15.7617L37.502 22.5752C37.502 24.8467 37.502 26.6533 37.3828 28.1104C37.2617 29.6035 37.0059 30.876 36.4121 32.042C35.4531 33.9229 33.9238 35.4531 32.043 36.4121C30.877 37.0059 29.6035 37.2607 28.1113 37.3828C26.6543 37.502 24.8477 37.502 22.5762 37.502L15.7617 37.502C13.4902 37.502 11.6836 37.502 10.2266 37.3828C8.73438 37.2607 7.46094 37.0059 6.29688 36.4121C4.41406 35.4531 2.88477 33.9229 1.92578 32.042C1.33203 30.876 1.07617 29.6035 0.955078 28.1104C0.835938 26.6533 0.835938 24.8467 0.835938 22.5742L0.835938 15.7617C0.835938 13.4902 0.835938 11.6836 0.955078 10.2256C1.07617 8.7334 1.33203 7.46094 1.92578 6.29492C2.88477 4.41309 4.41406 2.88379 6.29688 1.9248C7.46094 1.33105 8.73438 1.07617 10.2266 0.954102C11.6836 0.834961 13.4922 0.834961 15.7637 0.834961ZM10.498 4.27637C9.21094 4.38184 8.42578 4.58008 7.80859 4.89453C6.55469 5.53418 5.53516 6.55371 4.89648 7.80859C4.58203 8.42578 4.38281 9.21094 4.27734 10.4971C4.16992 11.8037 4.16992 13.4736 4.16992 15.835L4.16992 17.502L6.8125 14.8584C8.11328 13.5566 10.2246 13.5566 11.5254 14.8584L21.9141 25.2461C22.2383 25.5713 22.7656 25.5713 23.0918 25.2461L26.8125 21.5254C28.1133 20.2236 30.2246 20.2236 31.5254 21.5254L34.168 24.166C34.1699 23.6523 34.1699 23.0986 34.1699 22.502L34.1699 15.835C34.1699 13.4736 34.168 11.8037 34.0605 10.4971C33.957 9.21094 33.7578 8.42578 33.4434 7.80859C32.8027 6.55371 31.7832 5.53418 30.5293 4.89453C29.9121 4.58008 29.127 4.38184 27.8398 4.27637C26.5352 4.16992 24.8633 4.16797 22.502 4.16797L15.8359 4.16797C13.4746 4.16797 11.8047 4.16992 10.498 4.27637ZM23.3359 7.50195C21.0352 7.50195 19.1699 9.36719 19.1699 11.668C19.1699 13.9697 21.0352 15.835 23.3359 15.835C25.6367 15.835 27.502 13.9697 27.502 11.668C27.502 9.36719 25.6367 7.50195 23.3359 7.50195Z" fill="#7C8B9D" fill-opacity="1.000000" fill-rule="evenodd"/>
<path id="Icon" d="M23.3359 7.50195C25.6367 7.50195 27.502 9.36719 27.502 11.668C27.502 13.9697 25.6367 15.835 23.3359 15.835C21.0352 15.835 19.1699 13.9697 19.1699 11.668C19.1699 9.36719 21.0352 7.50195 23.3359 7.50195ZM10.2266 0.954102C8.73438 1.07617 7.46094 1.33105 6.29688 1.9248C4.41406 2.88379 2.88477 4.41309 1.92578 6.29492C1.33203 7.46094 1.07617 8.7334 0.955078 10.2256C0.835938 11.6836 0.835938 13.4902 0.835938 15.7617L0.835938 22.5742C0.835938 24.8467 0.835938 26.6533 0.955078 28.1104C1.07617 29.6035 1.33203 30.876 1.92578 32.042C2.88477 33.9229 4.41406 35.4531 6.29688 36.4121C7.46094 37.0059 8.73438 37.2607 10.2266 37.3828C11.6836 37.502 13.4902 37.502 15.7637 37.502L22.5762 37.502C24.8477 37.502 26.6543 37.502 28.1113 37.3828C29.6035 37.2607 30.877 37.0059 32.043 36.4121C33.9238 35.4531 35.4531 33.9229 36.4121 32.042C37.0059 30.876 37.2617 29.6035 37.3828 28.1104C37.502 26.6533 37.502 24.8467 37.502 22.5752L37.502 15.7617C37.502 13.4902 37.502 11.6836 37.3828 10.2256C37.2617 8.7334 37.0059 7.46094 36.4121 6.29492C35.4531 4.41309 33.9238 2.88379 32.043 1.9248C30.877 1.33105 29.6035 1.07617 28.1113 0.954102C26.6543 0.834961 24.8477 0.834961 22.5762 0.834961L15.7637 0.834961C13.4922 0.834961 11.6836 0.834961 10.2266 0.954102ZM10.498 4.27637C11.8047 4.16992 13.4746 4.16797 15.8359 4.16797L22.502 4.16797C24.8633 4.16797 26.5352 4.16992 27.8398 4.27637C29.127 4.38184 29.9121 4.58008 30.5293 4.89453C31.7832 5.53418 32.8027 6.55371 33.4434 7.80859C33.7578 8.42578 33.957 9.21094 34.0605 10.4971C34.168 11.8037 34.1699 13.4736 34.1699 15.835L34.1699 22.502C34.1699 23.0986 34.1699 23.6523 34.168 24.166L31.5254 21.5254C30.2246 20.2236 28.1133 20.2236 26.8125 21.5254L23.0918 25.2461C22.7656 25.5713 22.2383 25.5713 21.9141 25.2461L11.5254 14.8584C10.2246 13.5566 8.11328 13.5566 6.8125 14.8584L4.16992 17.502L4.16992 15.835C4.16992 13.4736 4.16992 11.8037 4.27734 10.4971C4.38281 9.21094 4.58203 8.42578 4.89648 7.80859C5.53516 6.55371 6.55469 5.53418 7.80859 4.89453C8.42578 4.58008 9.21094 4.38184 10.498 4.27637Z" stroke="#7C8B9D" stroke-opacity="1.000000" stroke-width="1.670000"/>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

+66
View File
@@ -0,0 +1,66 @@
import "./ReportDetails.scss";
import { IReport } from "@/shared/types/report-type";
import ReviewSection from "@/widgets/ReviewSection/ReviewSection";
import { Metadata } from "next";
import ReportInformation from "@/widgets/report-details/ReportInformation/ReportInformation";
import ReportImages from "@/widgets/report-details/ReportImages/ReportImages";
import dynamic from "next/dynamic";
import BreadCrumbs from "@/features/BreadCrumbs/BreadCrumbs";
const DynamicMap = dynamic(
() => import("@/widgets/report-details/ReportMap/ReportMap"),
{
ssr: false,
}
);
export const metadata: Metadata = {
title: "KG ROAD | Обращение",
description:
"Страница обращения Kyrgyzstan Transperency International",
};
const ReportDetails = async ({
params,
}: {
params: { id: string };
}) => {
const getReportDetails = async () => {
const res = await fetch(
`${process.env.NEXT_PUBLIC_BASE_API}/report/${params.id}/`,
{ cache: "no-store" }
);
return res.json();
};
const report: IReport = await getReportDetails();
return (
<div className="report-details page-padding">
<BreadCrumbs />
<div className="report-details__container">
<ReportInformation
id={report.id}
location={report.location[0]}
date={report.created_at}
description={report.description}
category={report.category}
total_likes={report.total_likes}
author={report.author}
/>
<div className="report-details__map">
<DynamicMap
location={report.location}
category={report.category}
/>
</div>
<ReportImages images={report.image} />
</div>
<ReviewSection endpoint="report" id={+params.id} />
</div>
);
};
export default ReportDetails;
@@ -0,0 +1,12 @@
import "@/shared/ui/auth-classes.scss";
import ForgotPasswordForm from "@/widgets/forms/ForgotPasswordForm/ForgotPasswordForm";
const ForgotPassword = () => {
return (
<div className="auth-page">
<ForgotPasswordForm />
</div>
);
};
export default ForgotPassword;
@@ -0,0 +1,14 @@
<svg width="24.000000" height="24.000000" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>
Created with Pixso.
</desc>
<defs>
<clipPath id="clip51_17162">
<rect id="log-in-04" width="24.000000" height="24.000000" fill="white" fill-opacity="0"/>
</clipPath>
</defs>
<rect id="log-in-04" width="24.000000" height="24.000000" fill="#FFFFFF" fill-opacity="0"/>
<g clip-path="url(#clip51_17162)">
<path id="Icon" d="M12 8L16 12L12 16M3 12L16 12M3.33789 7C5.06641 4.01074 8.29883 2 12 2C17.5225 2 22 6.47754 22 12C22 17.5225 17.5225 22 12 22C8.29883 22 5.06641 19.9893 3.33789 17" stroke="#000000" stroke-opacity="1.000000" stroke-width="2.000000" stroke-linejoin="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 768 B

+35
View File
@@ -0,0 +1,35 @@
import "@/shared/ui/auth-classes.scss";
import Image from "next/image";
import sign_in_icon from "./icons/sign-in_icon.svg";
import SignInForm from "@/widgets/forms/SignInForm/SignInForm";
import { Metadata } from "next";
import { Link } from "@/shared/config/navigation";
export const metadata: Metadata = {
title: "KG ROAD | Вход",
description: "Страница входа Kyrgyzstan Transperency International",
};
const SignIn = () => {
return (
<div className="auth-page">
<div className="auth-wrapper">
<div className="auth-icon">
<Image src={sign_in_icon} alt="Sign In Icon" />
</div>
<div className="auth-header">
<h2>Войдите в аккаунт</h2>
<p>Пожалуйста, введите свои данные</p>
</div>
<SignInForm />
<p className="auth-redirect">
Еще нет аккаунта?{" "}
<Link href="/sign-up">Зарегистрируйтесь</Link>
</p>
</div>
</div>
);
};
export default SignIn;
@@ -0,0 +1,14 @@
<svg width="24.000000" height="24.000000" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>
Created with Pixso.
</desc>
<defs>
<clipPath id="clip1668_53329">
<rect id="key" width="24.000000" height="24.000000" fill="white" fill-opacity="0"/>
</clipPath>
</defs>
<rect id="key" width="24.000000" height="24.000000" fill="#FFFFFF" fill-opacity="0"/>
<g clip-path="url(#clip1668_53329)">
<path id="Vector" d="M21 2L19 4L15.5 7.5L11.3906 11.6104L11.3896 11.6113C10.3516 10.6094 8.96289 10.0547 7.52051 10.0674C6.07812 10.0801 4.69922 10.6582 3.67969 11.6777C2.65918 12.6973 2.08105 14.0771 2.06836 15.5195C2.05566 16.9609 2.61035 18.3506 3.6123 19.3877C4.12207 19.9043 4.72852 20.3145 5.39746 20.5957C6.06543 20.877 6.7832 21.0225 7.50879 21.0254C8.23438 21.0273 8.95312 20.8867 9.62402 20.6104C10.2939 20.333 10.9033 19.9268 11.416 19.4141C11.9297 18.9014 12.3359 18.292 12.6123 17.6211C12.8887 16.9502 13.0293 16.2324 13.0273 15.5068C13.0244 14.7812 12.8789 14.0635 12.5977 13.3945C12.3174 12.7256 11.9062 12.1191 11.3906 11.6104M15.5 7.5L18.5 10.5L22 7L19 4" stroke="#489FE1" stroke-opacity="1.000000" stroke-width="2.000000" stroke-linejoin="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1,28 @@
import "@/shared/ui/auth-classes.scss";
import Image from "next/image";
import key from "./icons/key.svg";
import ResetCodeForm from "@/widgets/forms/ResetCodeForm/ResetCodeForm";
const ResetCode = () => {
return (
<div className="auth-page">
<div className="auth-wrapper">
<div className="auth-icon2">
<Image src={key} alt="Key Icon" />
</div>
<div className="auth-header">
<h2>Введите новый пароль</h2>
<p>
Пароль должен содерждать минимум 8 символов, 1 заглавная
буква и цифра
</p>
</div>
<ResetCodeForm />
</div>
</div>
);
};
export default ResetCode;
@@ -0,0 +1,14 @@
<svg width="24.000000" height="24.000000" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>
Created with Pixso.
</desc>
<defs>
<clipPath id="clip55_8430">
<rect id="mail" width="24.000000" height="24.000000" fill="white" fill-opacity="0"/>
</clipPath>
</defs>
<rect id="mail" width="24.000000" height="24.000000" fill="#FFFFFF" fill-opacity="0"/>
<g clip-path="url(#clip55_8430)">
<path id="Icon" d="M20 4C21.0996 4 22 4.90039 22 6L22 18C22 19.0996 21.0996 20 20 20L4 20C2.90039 20 2 19.0996 2 18L2 6C2 4.90039 2.90039 4 4 4L20 4ZM22 6L12 13L2 6" stroke="#489FE1" stroke-opacity="1.000000" stroke-width="2.000000" stroke-linejoin="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 739 B

@@ -0,0 +1,29 @@
import "@/shared/ui/auth-classes.scss";
import Image from "next/image";
import mail from "./icons/mail.svg";
import ConfirmEmailForm from "@/widgets/forms/ConfirmEmailForm/ConfirmEmailForm";
const ConfirmEmail = ({
searchParams,
}: {
searchParams: {
email: string;
};
}) => {
return (
<div className="auth-page">
<div className="auth-wrapper">
<div className="auth-icon2">
<Image src={mail} alt="Mail icon" width={56} height={56} />
</div>
<div className="auth-header">
<h2>Проверьте свою почту</h2>
<p>Мы отправили код на почту {searchParams.email}</p>
</div>
<ConfirmEmailForm email={searchParams.email} />
</div>
</div>
);
};
export default ConfirmEmail;
+7
View File
@@ -0,0 +1,7 @@
<svg width="20.317383" height="21.000977" viewBox="0 0 20.3174 21.001" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>
Created with Pixso.
</desc>
<defs/>
<path id="Icon" d="M12.2998 5.22266L18.2529 5.22266C18.7256 5.22266 18.9609 5.22266 19.0996 5.32129C19.2197 5.4082 19.2979 5.54102 19.3154 5.68848C19.335 5.85742 19.2207 6.06445 18.9912 6.47656L17.5703 9.03418C17.4873 9.18359 17.4453 9.25879 17.4297 9.33789C17.415 9.4082 17.415 9.48047 17.4297 9.55078C17.4453 9.62988 17.4873 9.70508 17.5703 9.85449L18.9912 12.4121C19.2207 12.8252 19.335 13.0312 19.3154 13.2002C19.2979 13.3477 19.2197 13.4805 19.0996 13.5674C18.9609 13.667 18.7256 13.667 18.2529 13.667L10.8213 13.667C10.2305 13.667 9.93457 13.667 9.70898 13.5518C9.51074 13.4502 9.34863 13.2891 9.24805 13.0898C9.13281 12.8643 9.13281 12.5693 9.13281 11.9775L9.13281 9.44434M10.6104 1C11.2021 1 11.4971 1 11.7227 1.11523C11.9219 1.21582 12.083 1.37793 12.1846 1.57617C12.2998 1.80176 12.2998 2.09766 12.2998 2.68848L12.2998 7.75586C12.2998 8.34668 12.2998 8.64258 12.1846 8.86816C12.083 9.06641 11.9219 9.22852 11.7227 9.3291C11.4971 9.44434 11.2021 9.44434 10.6104 9.44434L2.7998 9.44434L1.21289 3.09863C1.03418 2.38281 0.944336 2.02539 1.03125 1.74414C1.1084 1.49707 1.27246 1.28711 1.49316 1.15234C1.74512 1 2.11426 1 2.85156 1L10.6104 1ZM5.43848 20L1.21582 3.11133" stroke="#000000" stroke-opacity="1.000000" stroke-width="2.000000" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

+37
View File
@@ -0,0 +1,37 @@
import "@/shared/ui/auth-classes.scss";
import Image from "next/image";
import flag from "./icons/flag.svg";
import SignUpForm from "@/widgets/forms/SignUpForm/SignUpForm";
import { Metadata } from "next";
import { Link } from "@/shared/config/navigation";
export const metadata: Metadata = {
title: "KG ROAD | Регистрация",
description:
"Страница регистрации Kyrgyzstan Transperency International",
};
const SignUp = () => {
return (
<div className="auth-page">
<div className="auth-wrapper">
<div className="auth-icon">
<Image src={flag} alt="Flag Icon" />
</div>
<div className="auth-header">
<h2>Регистрация</h2>
<p>Пожалуйста, введите свои данные</p>
</div>
<SignUpForm />
<p className="auth-redirect">
Уже есть аккаунт?{" "}
<Link href="/sign-in">Войти в аккаунт</Link>
</p>
</div>
</div>
);
};
export default SignUp;
@@ -0,0 +1,21 @@
.statistics {
display: flex;
flex-direction: column;
gap: 40px;
h2 {
width: fit-content;
}
}
@media screen and (max-width: 768px) {
.statistics {
gap: 30px;
}
}
@media screen and (max-width: 550px) {
.statistics {
gap: 20px;
}
}
+25
View File
@@ -0,0 +1,25 @@
import Typography from "@/shared/ui/components/Typography/Typography";
import "./Statistics.scss";
import StatisticsTable from "@/widgets/tables/StatisticsTable/StatisticsTable";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "KG ROAD | Статистика",
description:
"Страница статистики Kyrgyzstan Transperency International",
};
const Statistics = ({
searchParams,
}: {
searchParams: { ["поиск-населенного-пункта"]: string };
}) => {
return (
<div className="statistics page-padding">
<Typography element="h2">Статистика</Typography>
<StatisticsTable searchParams={searchParams} />
</div>
);
};
export default Statistics;
@@ -0,0 +1,21 @@
.volunteers {
display: flex;
flex-direction: column;
gap: 40px;
h2 {
width: fit-content;
}
}
@media screen and (max-width: 768px) {
.volunteers {
gap: 30px;
}
}
@media screen and (max-width: 550px) {
.volunteers {
gap: 20px;
}
}
+21
View File
@@ -0,0 +1,21 @@
import Typography from "@/shared/ui/components/Typography/Typography";
import "./Volunteers.scss";
import VolunteersTable from "@/widgets/tables/VolunteersTable/VolunteersTable";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "KG ROAD | Волонтеры",
description:
"Страница волонтеров Kyrgyzstan Transperency International",
};
const Volunteers = () => {
return (
<div className="volunteers page-padding">
<Typography element="h2">Волонтеры</Typography>
<VolunteersTable />
</div>
);
};
export default Volunteers;