1 Commits
Author SHA1 Message Date
Vladislav Khorev a86d1adc57 prepare for uat 2024-02-04 13:53:49 +00:00
274 changed files with 6161 additions and 9049 deletions

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
NEXTAUTH_SECRET=";sadmfxflpdk"
NEXTAUTH_URL="http://localhost:3000"
-1
View File
@@ -5,7 +5,6 @@
/.pnp /.pnp
.pnp.js .pnp.js
.yarn/install-state.gz .yarn/install-state.gz
.env
# testing # testing
/coverage /coverage
File renamed without changes.
+3
View File
@@ -0,0 +1,3 @@
import RootLayout from "@/app/App";
export default RootLayout;
+3
View File
@@ -0,0 +1,3 @@
import Home from "@/pages/Home/Home";
export default Home;
+7
View File
@@ -0,0 +1,7 @@
import React from "react";
const page = () => {
return <div>page</div>;
};
export default page;
+7
View File
@@ -0,0 +1,7 @@
import React from "react";
const page = () => {
return <div>page</div>;
};
export default page;
+1 -2
View File
@@ -4,7 +4,6 @@ declare module "next-auth" {
interface Session { interface Session {
refresh_token: string; refresh_token: string;
access_token: string; access_token: string;
expires_in: string;
} }
} }
@@ -14,6 +13,6 @@ declare module "next-auth/jwt" {
interface JWT { interface JWT {
refresh_token: string; refresh_token: string;
access_token: string; access_token: string;
expires_in: string; exp: number;
} }
} }
-1
View File
@@ -1,6 +1,5 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
distDir: "build",
images: { images: {
remotePatterns: [ remotePatterns: [
{ {
+4497
View File
File diff suppressed because it is too large. Load diff
+3 -6
View File
@@ -5,27 +5,24 @@
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",
"build": "next build", "build": "next build",
"start": "next start -p 8003", "start": "next start -p 8004",
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
"@next/third-parties": "^14.1.0",
"axios": "^1.6.5", "axios": "^1.6.5",
"dotenv": "^16.4.1",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"next": "^14.1.0", "next": "14.1.0",
"next-auth": "^4.24.5", "next-auth": "^4.24.5",
"react": "^18", "react": "^18",
"react-dom": "^18", "react-dom": "^18",
"react-leaflet": "^4.2.1", "react-leaflet": "^4.2.1",
"sass": "^1.70.0", "sass": "^1.70.0",
"sharp": "^0.33.2",
"use-debounce": "^10.0.0", "use-debounce": "^10.0.0",
"zustand": "^4.5.0" "zustand": "^4.5.0"
}, },
"devDependencies": { "devDependencies": {
"@types/leaflet": "^1.9.8", "@types/leaflet": "^1.9.8",
"@types/node": "^20.11.16", "@types/node": "^20",
"@types/react": "^18", "@types/react": "^18",
"@types/react-dom": "^18", "@types/react-dom": "^18",
"@types/react-leaflet": "^3.0.0", "@types/react-leaflet": "^3.0.0",
File renamed without changes.
+21
View File
@@ -0,0 +1,21 @@
import "./globals.scss";
import "./fonts.scss";
import "./App.scss";
import Footer from "@/widgets/Footer/Footer";
import Navbar from "@/widgets/Navbar/Navbar";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body>
<Navbar />
<div className="app">{children}</div>
<Footer />
</body>
</html>
);
}
+9
View File
@@ -0,0 +1,9 @@
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;500;600;700;800;900&display=swap");
@import url("https://fonts.cdnfonts.com/css/arial");
@import url("../shared/fonts/TildaSans.css");
* {
font-family: Tilda Sans;
}
+25
View File
@@ -0,0 +1,25 @@
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
button,
a {
cursor: pointer;
color: black;
display: flex;
align-items: center;
justify-content: center;
border: none;
background-color: transparent;
text-decoration: none;
font-size: 16px;
}
ul,
ol,
li {
list-style-type: none;
list-style: none;
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,47 @@
.section-header {
margin-bottom: 52px;
display: flex;
flex-direction: column;
align-items: center;
gap: 24px;
text-align: center;
h3 {
font-size: 42px;
font-weight: 500;
line-height: 50px;
}
p {
font-size: 24px;
font-weight: 300;
line-height: 29px;
}
}
@media screen and (max-width: 768px) {
.section-header {
margin-bottom: 42px;
h3 {
font-size: 36px;
line-height: 43px;
}
}
}
@media screen and (max-width: 550px) {
.section-header {
margin-bottom: 42px;
h3 {
font-size: 24px;
line-height: 29px;
}
p {
font-size: 18px;
line-height: 22px;
}
}
}
@@ -0,0 +1,22 @@
import "./SectionHeader.scss";
interface ISectionHeaderProps {
title: string;
description?: string;
style?: object;
}
const SectionHeader: React.FC<ISectionHeaderProps> = ({
title,
description,
style,
}: ISectionHeaderProps) => {
return (
<div style={style} className="section-header">
<h3>{title}</h3>
{description && <p>{description}</p>}
</div>
);
};
export default SectionHeader;
+2
View File
@@ -0,0 +1,2 @@
export const baseAPI =
"https://api.kgroaduat.fishrungames.com/api/v1";
File renamed without changes.
@@ -5,5 +5,4 @@
url("TildaSans-Black.woff2") format("woff2"), url("TildaSans-Black.woff2") format("woff2"),
url("TildaSans-Black.woff") format("woff"); url("TildaSans-Black.woff") format("woff");
font-weight: 900; font-weight: 900;
font-style: normal;
} }
@@ -5,5 +5,4 @@
url("TildaSans-Regular.woff2") format("woff2"), url("TildaSans-Regular.woff2") format("woff2"),
url("TildaSans-Regular.woff") format("woff"); url("TildaSans-Regular.woff") format("woff");
font-weight: 400; font-weight: 400;
font-style: normal;
} }
@@ -3,5 +3,5 @@
@import "./TildaSans-Medium/TildaSans-Medium.css"; @import "./TildaSans-Medium/TildaSans-Medium.css";
@import "./TildaSans-Semibold/TildaSans-Semibold.css"; @import "./TildaSans-Semibold/TildaSans-Semibold.css";
@import "./TildaSans-Bold/TildaSans-Bold.css"; @import "./TildaSans-Bold/TildaSans-Bold.css";
@import "./TildaSans-Extrabold/TildaSans-Extrabold.css"; @import "./TildaSans-ExtraBold/TildaSans-ExtraBold.css";
@import "./TildaSans-Black/TildaSans-Black.css"; @import "./TildaSans-Black/TildaSans-Black.css";
@@ -1,5 +1,5 @@
export interface IFetch { export interface IFetch {
error: string; error: string;
data?: any; data: any;
isLoading: boolean; isLoading: boolean;
} }
@@ -1,5 +1,5 @@
export interface IList { export interface IList {
count: number | null; count: number | null;
previous: string | null; previous: number | null;
next: string | null; next: number | null;
} }
@@ -1,5 +1,3 @@
import { IList } from "./list-type";
export interface INews { export interface INews {
id: number; id: number;
image: string; image: string;
@@ -10,7 +8,3 @@ export interface INews {
updated_at: string; updated_at: string;
count_reviews: number; count_reviews: number;
} }
export interface INewsList extends IList {
results: INews[];
}
+32
View File
@@ -0,0 +1,32 @@
export interface IAuthor {
id: number;
first_name: string;
last_name: string;
govern_status: unknown;
}
export interface ILocation {
id: 4;
latitude: number;
longitude: number;
address: string;
}
export interface IReportImage {
id: number;
image: string;
}
export interface IReport {
results: any;
id: number;
image: IReportImage[];
description: string;
author: IAuthor;
created_at: string;
updated_at: string;
location: ILocation[];
category: number;
total_likes: number;
count_reviews: number;
}
@@ -6,5 +6,4 @@ $light-green: rgb(74, 192, 63);
$gray-300: #d0d5dd; $gray-300: #d0d5dd;
$gray-500: #667085; $gray-500: #667085;
$gray-700: #344054; $gray-700: #344054;
$gray-900: rgb(16, 24, 40);
$black: rgb(50, 48, 58); $black: rgb(50, 48, 58);
File renamed without changes.
File renamed without changes.
@@ -10,7 +10,7 @@
height: fit-content; height: fit-content;
color: white; color: white;
justify-content: flex-start; justify-content: flex-start;
font-family: "Inter", sans-serif; font-family: "Inter";
font-size: 16px; font-size: 16px;
} }
@@ -8,7 +8,6 @@ import facebook from "./icons/facebook.svg";
import instagram from "./icons/instagram.svg"; import instagram from "./icons/instagram.svg";
import app_store_btn from "./icons/app-store-btn.svg"; import app_store_btn from "./icons/app-store-btn.svg";
import play_market_btn from "./icons/play-market-btn.svg"; import play_market_btn from "./icons/play-market-btn.svg";
import NetKgTracker from "@/widgets/NetKgTracker/NetKgTracker";
const Footer = () => { const Footer = () => {
return ( return (
@@ -20,45 +19,40 @@ const Footer = () => {
<h4>Навигация</h4> <h4>Навигация</h4>
<ul> <ul>
{LINKS.map((link) => ( {LINKS.map((link) => (
<li key={link.id}> <li>
<Link href={link.pathname} key={link.id}> <Link href={link.pathname} key={link.id}>
{link.pagename} {link.pagename}
</Link> </Link>
</li> </li>
))} ))}
</ul> </ul>
<NetKgTracker />
</div> </div>
<div className="footer__contacts"> <div className="footer__contacts">
<h4>Контакты</h4> <h4>Контакты</h4>
<ul> <ul>
<li>admin@kgroad.org</li> <li>namename@gmail.com</li>
<li>+9960312394038</li> <li>+09646895467</li>
{/*
<li> <li>
{[youtube, facebook, instagram].map((net, i) => ( {[youtube, facebook, instagram].map((net) => (
<Link key={i} href="#"> <Link href="#">
<Image src={net} alt="Net Icon" key={net} /> <Image src={net} alt="Net Icon" key={net} />
</Link> </Link>
))} ))}
</li> </li>
*/}
</ul> </ul>
<p className="text-white">Photo By ThomasG, CC BY-SA 3.0</p>
</div> </div>
{/*
<div className="footer__apps"> <div className="footer__apps">
<h4>Скачивай наше приложение</h4> <h4>Скачивай наше приложение</h4>
<div className="footer__apps-btns"> <div className="footer__apps-btns">
{[app_store_btn, play_market_btn].map((app, i) => ( {[app_store_btn, play_market_btn].map((app) => (
<Link key={i} href="#"> <Link href="#">
<Image src={app} alt="App Button" key={app} /> <Image src={app} alt="App Button" key={app} />
</Link> </Link>
))} ))}
</div> </div>
</div> </div>
*/}
</footer> </footer>
); );
}; };
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -13,10 +13,10 @@ const Header = () => {
/> />
<div className="header__text"> <div className="header__text">
<h1> <h1>
Дороги Кыргызстана Borem ipsum dolor sit amet, consectetur adipiscing elit.
</h1> </h1>
<p> <p>
Сделаем дороги безопасными! Актуальная информация о состоянии дорог. Borem ipsum dolor sit amet, consectetur adipiscing elit.
</p> </p>
</div> </div>
@@ -7,9 +7,6 @@
font-size: 20px; font-size: 20px;
font-weight: 500; font-weight: 500;
line-height: 24px; line-height: 24px;
display: flex;
justify-content: center;
align-items: center;
gap: 30px; gap: 30px;
border-radius: 15px; border-radius: 15px;
background-color: #fff; background-color: #fff;
@@ -0,0 +1,88 @@
"use client";
import "./HomeMap.scss";
import "leaflet/dist/leaflet.css";
import {
MapContainer,
Marker,
Popup,
TileLayer,
} from "react-leaflet";
import geo_green_icon from "./icons/geo-green.svg";
import geo_orange_icon from "./icons/geo-orange.svg";
import geo_pink_icon from "./icons/geo-pink.svg";
import geo_purple_icon from "./icons/geo-purple.svg";
import geo_red_icon from "./icons/geo-red.svg";
import geo_yellow_icon from "./icons/geo-yellow.svg";
import { DivIcon, Icon, LatLngTuple } from "leaflet";
import { StaticImageData } from "next/image";
import Link from "next/link";
import { ILocation } from "@/shared/types/report-type";
interface IData {
id: number;
location: ILocation[];
category: number;
}
interface IHomeMapProps {
data: IData[] | undefined;
}
const HomeMap: React.FC<IHomeMapProps> = ({
data,
}: IHomeMapProps) => {
const createCustomIcon = (icon: StaticImageData) => {
const customIcon = new Icon({
iconUrl: icon.src,
iconSize: [32, 32],
});
return customIcon;
};
const icons: Record<string, DivIcon> = {
1: createCustomIcon(geo_red_icon),
2: createCustomIcon(geo_pink_icon),
3: createCustomIcon(geo_purple_icon),
4: createCustomIcon(geo_orange_icon),
5: createCustomIcon(geo_green_icon),
6: createCustomIcon(geo_yellow_icon),
};
const position = [42.8746, 74.606];
return (
<MapContainer
center={position as LatLngTuple}
zoom={14}
scrollWheelZoom={false}
className="home-map"
>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{data?.map((marker) => (
<Marker
key={marker.id}
icon={icons[marker.category]}
position={
[
+marker.location[0].latitude,
+marker.location[0].longitude,
] as LatLngTuple
}
>
<Popup>
<Link href={`/report/${marker.location[0].id}`}>
{marker.location[0].address}
</Link>
</Popup>
</Marker>
))}
</MapContainer>
);
};
export default HomeMap;
@@ -0,0 +1,5 @@
<svg width="38" height="50" viewBox="0 0 38 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19 0C8.52334 0 0 8.74812 0 19.501C0 32.8456 17.0031 48.5901 17.7271 49.4175C18.407 50.1948 19.5942 50.1935 20.2729 49.4175C20.9969 48.5901 38 32.8456 38 19.501C37.9998 8.74812 29.4766 0 19 0Z" fill="#3998E8" fill-opacity="0.7"/>
<ellipse cx="18.7867" cy="19" rx="9.88775" ry="10" fill="white"/>
<circle cx="18.5" cy="18.5" r="7.5" fill="#8FDE6A"/>
</svg>

After

Width:  |  Height:  |  Size: 461 B

@@ -0,0 +1,5 @@
<svg width="38" height="50" viewBox="0 0 38 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19 0C8.52334 0 0 8.74812 0 19.501C0 32.8456 17.0031 48.5901 17.7271 49.4175C18.407 50.1948 19.5942 50.1935 20.2729 49.4175C20.9969 48.5901 38 32.8456 38 19.501C37.9998 8.74812 29.4766 0 19 0Z" fill="#3998E8" fill-opacity="0.7"/>
<ellipse cx="18.7867" cy="19" rx="9.88775" ry="10" fill="white"/>
<circle cx="18.5" cy="18.5" r="7.5" fill="#FFAC33"/>
</svg>

After

Width:  |  Height:  |  Size: 461 B

@@ -0,0 +1,5 @@
<svg width="38" height="50" viewBox="0 0 38 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19 0C8.52334 0 0 8.74812 0 19.501C0 32.8456 17.0031 48.5901 17.7271 49.4175C18.407 50.1948 19.5942 50.1935 20.2729 49.4175C20.9969 48.5901 38 32.8456 38 19.501C37.9998 8.74812 29.4766 0 19 0Z" fill="#3998E8" fill-opacity="0.7"/>
<ellipse cx="18.7867" cy="19" rx="9.88775" ry="10" fill="white"/>
<circle cx="18.5" cy="18.5" r="7.5" fill="#C288E2"/>
</svg>

After

Width:  |  Height:  |  Size: 461 B

@@ -0,0 +1,5 @@
<svg width="38" height="50" viewBox="0 0 38 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19 0C8.52334 0 0 8.74812 0 19.501C0 32.8456 17.0031 48.5901 17.7271 49.4175C18.407 50.1948 19.5942 50.1935 20.2729 49.4175C20.9969 48.5901 38 32.8456 38 19.501C37.9998 8.74812 29.4766 0 19 0Z" fill="#3998E8" fill-opacity="0.7"/>
<ellipse cx="18.7867" cy="19" rx="9.88775" ry="10" fill="white"/>
<circle cx="18.5" cy="18.5" r="7.5" fill="#87289D"/>
</svg>

After

Width:  |  Height:  |  Size: 461 B

@@ -0,0 +1,5 @@
<svg width="38" height="50" viewBox="0 0 38 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19 0C8.52334 0 0 8.74812 0 19.501C0 32.8456 17.0031 48.5901 17.7271 49.4175C18.407 50.1948 19.5942 50.1935 20.2729 49.4175C20.9969 48.5901 38 32.8456 38 19.501C37.9998 8.74812 29.4766 0 19 0Z" fill="#3998E8" fill-opacity="0.7"/>
<ellipse cx="18.7867" cy="19" rx="9.88775" ry="10" fill="white"/>
<circle cx="18.5" cy="18.5" r="7.5" fill="#E64452"/>
</svg>

After

Width:  |  Height:  |  Size: 461 B

@@ -0,0 +1,5 @@
<svg width="38" height="50" viewBox="0 0 38 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19 0C8.52334 0 0 8.74812 0 19.501C0 32.8456 17.0031 48.5901 17.7271 49.4175C18.407 50.1948 19.5942 50.1935 20.2729 49.4175C20.9969 48.5901 38 32.8456 38 19.501C37.9998 8.74812 29.4766 0 19 0Z" fill="#3998E8" fill-opacity="0.7"/>
<ellipse cx="18.7867" cy="19" rx="9.88775" ry="10" fill="white"/>
<circle cx="18.5" cy="18.5" r="7.5" fill="#FED363"/>
</svg>

After

Width:  |  Height:  |  Size: 461 B

@@ -4,15 +4,6 @@
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
&__header {
margin-bottom: 50px;
text-align: center;
display: flex;
align-items: center;
flex-direction: column;
gap: 24px;
}
&__categories { &__categories {
margin-bottom: 60px; margin-bottom: 60px;
display: flex; display: flex;
@@ -37,13 +28,9 @@
@media screen and (max-width: 768px) { @media screen and (max-width: 768px) {
.map-section { .map-section {
&__header {
margin-bottom: 40px;
gap: 20px;
}
&__categories { &__categories {
margin-bottom: 40px; margin-bottom: 40px;
gap: 25px; gap: 25px;
} }
} }
@@ -51,13 +38,9 @@
@media screen and (max-width: 550px) { @media screen and (max-width: 550px) {
.map-section { .map-section {
&__header {
margin-bottom: 25px;
gap: 16px;
}
&__categories { &__categories {
margin-bottom: 25px; margin-bottom: 25px;
padding: 0 16px; padding: 0 16px;
width: 100%; width: 100%;
align-items: flex-start; align-items: flex-start;
+123
View File
@@ -0,0 +1,123 @@
"use client";
import "./MapSection.scss";
import SearchForm from "@/features/SearchBar/SearchForm";
import { useEffect, useState } from "react";
import SectionHeader from "@/entities/SectionHeader/SectionHeader";
import {
ROAD_TYPES,
ROAD_TYPES_COLORS,
} from "@/shared/variables/road-types";
import HomeMap from "./HomeMap/HomeMap";
import { useRouter } from "next/navigation";
import { useMapStore } from "./mapSectionStore";
import Switch from "./Switch/Switch";
import { useShallow } from "zustand/react/shallow";
interface IMapSectionProps {
[key: string]: string;
}
const MapSection: React.FC<IMapSectionProps> = ({
categories = "1,2,3,4,5,6",
queryMap,
queryRating,
}: IMapSectionProps) => {
const [mapSearch, setMapSearch] = useState<string>(queryMap || "");
const data = useMapStore(useShallow((state) => state.data));
const getReports = useMapStore(
useShallow((state) => state.getReports)
);
const router = useRouter();
useEffect(() => {
getReports(categories);
}, [categories]);
const handleSubmit: React.FormEventHandler<
HTMLFormElement
> = async (e) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
setMapSearch(formData.get("map-search") as string);
router.push(
`/?тип-дороги=${categories}${
mapSearch ? `&поиск-на-карте=${mapSearch}` : ""
}${queryRating ? `&поиск-рейтинг=${queryRating}` : ""}`,
{
scroll: false,
}
);
};
const setSearchParams = (category: string) => {
const availableCategories = ["1", "2", "3", "4", "5", "6"];
if (!categories || !availableCategories.includes(category))
return categories;
if (categories?.includes(category)) {
const updatedCategories = categories
?.replace(category + ",", "")
.replace("," + category, "")
.replace(category, "");
return updatedCategories;
} else {
const newValue = category + ",";
const updatedCategories = newValue + categories;
return updatedCategories;
}
};
return (
<section className="map-section">
<SectionHeader
title="Карта дорог"
description="Будьте в курсе последних новостей о дорожном движении, строительствах и мероприятиях!"
/>
<SearchForm
onChange={(e) => setMapSearch(e.target.value)}
name="map-search"
value={mapSearch}
placeholder="Введите город, село или регион"
handleSubmit={handleSubmit}
/>
<div className="map-section__categories">
<ul className="map-section__categories_left">
{[1, 2, 3].map((sw) => (
<li key={sw}>
<Switch
href={`/?тип-дороги=${setSearchParams(
sw.toString()
)}`}
color={ROAD_TYPES_COLORS[sw]}
defaultState={categories.includes(sw.toString())}
/>
<label>{ROAD_TYPES[sw]}</label>
</li>
))}
</ul>
<ul className="map-section__categories_right">
{[4, 5, 6].map((sw) => (
<li key={sw}>
<Switch
href={`/?тип-дороги=${setSearchParams(
sw.toString()
)}`}
color={ROAD_TYPES_COLORS[sw]}
defaultState={categories.includes(sw.toString())}
/>
<label>{ROAD_TYPES[sw]}</label>
</li>
))}
</ul>
</div>
<HomeMap data={data?.results} />
</section>
);
};
export default MapSection;
@@ -5,7 +5,7 @@ import "./Switch.scss";
import Link from "next/link"; import Link from "next/link";
interface ISwitchProps { interface ISwitchProps {
defaultState: boolean; defaultState?: boolean;
color?: string; color?: string;
href: string; href: string;
} }
@@ -25,7 +25,7 @@ const Switch: React.FC<ISwitchProps> = ({
onClick={() => setToggleSwitch((prev) => !prev)} onClick={() => setToggleSwitch((prev) => !prev)}
style={{ style={{
backgroundColor: !toggleSwitch backgroundColor: !toggleSwitch
? "rgb(71, 85, 105)" ? "rgb(50, 48, 58)"
: color : color
? color ? color
: "rgb(230, 68, 82)", : "rgb(230, 68, 82)",
+41
View File
@@ -0,0 +1,41 @@
import { baseAPI } from "@/shared/api/baseAPI";
import { IFetch } from "@/shared/types/fetch-type";
import { IList } from "@/shared/types/list-type";
import { IReport } from "@/shared/types/report-type";
import axios from "axios";
import { create } from "zustand";
interface IFetchReports extends IList {
results: IReport[];
}
interface IMapStore extends IFetch {
data: IFetchReports;
getReports: (categories: string) => Promise<void>;
}
export const useMapStore = create<IMapStore>((set) => ({
data: {
count: 0,
previous: null,
next: null,
results: [],
},
isLoading: false,
error: "",
getReports: async (categories: string = "1,2,3,4,5,6") => {
try {
set({ isLoading: true });
const response = await axios.get<IFetchReports>(
`${baseAPI}/report/?category=${categories}`
);
set({ data: response.data });
} catch (error: any) {
set({ error: error.message });
} finally {
set({ isLoading: false });
}
},
}));
@@ -1,26 +1,21 @@
import Link from "next/link"; import Link from "next/link";
import "./NavAuth.scss"; import "./NavAuth.scss";
import { usePathname } from "next/navigation"; import { usePathname } from "next/navigation";
import { useSession } from "next-auth/react";
interface INavAuthProps { interface INavAuthProps {
responsible?: boolean; responsible?: boolean;
setOpenMenu: (boolean: boolean) => void;
} }
const NavAuth: React.FC<INavAuthProps> = ({ const NavAuth: React.FC<INavAuthProps> = ({
responsible, responsible,
setOpenMenu,
}: INavAuthProps) => { }: INavAuthProps) => {
const session = useSession(); const auth = false;
const auth = session.status === "authenticated" ? true : false;
const pathname = usePathname(); const pathname = usePathname();
return ( return (
<> <>
{auth ? ( {auth ? (
<Link <Link
onClick={() => setOpenMenu(false)} href="/profile"
href="/profile/personal"
className={`nav-auth-profile-${ className={`nav-auth-profile-${
responsible responsible
? `sm${pathname === "/profile" ? "_active" : ""}` ? `sm${pathname === "/profile" ? "_active" : ""}`
@@ -31,7 +26,6 @@ const NavAuth: React.FC<INavAuthProps> = ({
</Link> </Link>
) : ( ) : (
<Link <Link
onClick={() => setOpenMenu(false)}
href="/sign-in" href="/sign-in"
className={`nav-auth-signin-${ className={`nav-auth-signin-${
responsible responsible
@@ -14,17 +14,14 @@
&__option, &__option,
&__option_active { &__option_active {
padding: 10px 14px;
width: 100%; width: 100%;
display: flex; padding: 10px 14px;
font-weight: 900; font-weight: 900;
justify-content: flex-start; justify-content: flex-start;
background-color: #fff;
} }
&__option_active { &__option_active {
background-color: rgb(249, 250, 251); background-color: rgb(249, 250, 251);
align-items: center;
justify-content: space-between; justify-content: space-between;
} }
@@ -4,19 +4,13 @@ import Link from "next/link";
import { usePathname } from "next/navigation"; import { usePathname } from "next/navigation";
import NavAuth from "../NavAuth/NavAuth"; import NavAuth from "../NavAuth/NavAuth";
interface INavMenuProps { const NavMenu = () => {
setOpenMenu: (boolean: boolean) => void; const auth = false;
}
const NavMenu: React.FC<INavMenuProps> = ({
setOpenMenu,
}: INavMenuProps) => {
const pathname = usePathname(); const pathname = usePathname();
return ( return (
<nav className="nav-menu"> <nav className="nav-menu">
{LINKS.map((link) => ( {LINKS.map((link) => (
<Link <Link
onClick={() => setOpenMenu(false)}
className={`nav-menu__link${ className={`nav-menu__link${
pathname === link.pathname ? "_active" : "" pathname === link.pathname ? "_active" : ""
}`} }`}
@@ -27,7 +21,7 @@ const NavMenu: React.FC<INavMenuProps> = ({
</Link> </Link>
))} ))}
<NavAuth setOpenMenu={setOpenMenu} responsible /> <NavAuth responsible />
</nav> </nav>
); );
}; };
@@ -5,14 +5,14 @@
width: 100%; width: 100%;
height: 78px; height: 78px;
position: fixed; position: fixed;
z-index: 10005; z-index: 10000;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
background-color: #fff; background-color: #fff;
&__links { &__links {
height: 40%; height: 60%;
display: flex; display: flex;
gap: 60px; gap: 60px;
} }
@@ -40,7 +40,7 @@ const Navbar = () => {
<div className="navbar__lang-and-auth"> <div className="navbar__lang-and-auth">
<NavLanguage /> <NavLanguage />
<NavAuth setOpenMenu={setOpenMenu} /> <NavAuth />
</div> </div>
<button <button
@@ -50,7 +50,7 @@ const Navbar = () => {
<Image src={openMenu ? cross : menu} alt="menu icon" /> <Image src={openMenu ? cross : menu} alt="menu icon" />
</button> </button>
{openMenu && <NavMenu setOpenMenu={setOpenMenu} />} {openMenu && <NavMenu />}
</section> </section>
); );
}; };
File renamed without changes.
File renamed without changes.
@@ -4,11 +4,6 @@
padding: 60px 90px 100px 90px; padding: 60px 90px 100px 90px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
h3 {
margin-bottom: 24px;
}
&__list { &__list {
margin-bottom: 40px; margin-bottom: 40px;
display: grid; display: grid;
@@ -2,15 +2,15 @@ import "./NewsSection.scss";
import Image from "next/image"; import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
import { getNews } from "./newsSectionStore"; import { getNews } from "./newsSectionStore";
import SectionHeader from "@/entities/SectionHeader/SectionHeader";
import arrow_icon from "./icons/arrow-right.svg"; import arrow_icon from "./icons/arrow-right.svg";
import NewsCard from "@/entities/NewsCard/NewsCard"; import NewsCard from "@/entities/NewsCard/NewsCard";
import Typography from "@/shared/ui/components/Typography/Typography";
const NewsSection = async () => { const NewsSection = async () => {
const news = await getNews(); const news = await getNews();
return ( return (
<section className="news-section"> <section className="news-section">
<Typography element="h3">Новости</Typography> <SectionHeader title="Новости" />
<ul className="news-section__list"> <ul className="news-section__list">
{news?.map((article) => ( {news?.map((article) => (
<li key={article.id} className="news-section__card"> <li key={article.id} className="news-section__card">
Loaded 100 of 274 files, more files were not shown because too many files have changed in this diff. Show more