admin + loader fix

This commit is contained in:
иосиф брыков 2024-03-24 15:04:35 +05:00
parent 92fcf82a0c
commit 1e6ceaa4ad
54 changed files with 1600 additions and 1567 deletions

View File

@ -4,7 +4,7 @@
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",
"build": "set NODE_OPTIONS=--max-old-space-size=4096 && next build", "build": "next build",
"start": "next start -p 8080 -H 0.0.0.0", "start": "next start -p 8080 -H 0.0.0.0",
"lint": "next lint" "lint": "next lint"
}, },

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

View File

Before

Width:  |  Height:  |  Size: 490 KiB

After

Width:  |  Height:  |  Size: 490 KiB

View File

Before

Width:  |  Height:  |  Size: 216 KiB

After

Width:  |  Height:  |  Size: 216 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 707 B

After

Width:  |  Height:  |  Size: 707 B

View File

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

Before

Width:  |  Height:  |  Size: 686 B

After

Width:  |  Height:  |  Size: 686 B

View File

Before

Width:  |  Height:  |  Size: 674 B

After

Width:  |  Height:  |  Size: 674 B

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 643 B

After

Width:  |  Height:  |  Size: 643 B

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 663 B

After

Width:  |  Height:  |  Size: 663 B

View File

Before

Width:  |  Height:  |  Size: 783 B

After

Width:  |  Height:  |  Size: 783 B

View File

Before

Width:  |  Height:  |  Size: 708 B

After

Width:  |  Height:  |  Size: 708 B

View File

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 442 B

View File

Before

Width:  |  Height:  |  Size: 732 B

After

Width:  |  Height:  |  Size: 732 B

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 461 B

After

Width:  |  Height:  |  Size: 461 B

View File

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 422 B

After

Width:  |  Height:  |  Size: 422 B

View File

Before

Width:  |  Height:  |  Size: 446 B

After

Width:  |  Height:  |  Size: 446 B

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 881 B

After

Width:  |  Height:  |  Size: 881 B

View File

Before

Width:  |  Height:  |  Size: 678 B

After

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 457 KiB

After

Width:  |  Height:  |  Size: 327 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 373 KiB

After

Width:  |  Height:  |  Size: 612 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 801 KiB

After

Width:  |  Height:  |  Size: 612 KiB

View File

@ -1,10 +1,8 @@
import Auth from '@/components/screens/admin/auth/Auth' import Auth from "@/components/screens/admin/auth/Auth";
import React from 'react' import React from "react";
type Props = {} type Props = {};
export default function page({}: Props) { export default function page({}: Props) {
return ( return <Auth />;
<Auth />
)
} }

View File

@ -1,23 +1,24 @@
'use client' "use client";
import { useRouter } from 'next/navigation' import Auth from "@/components/screens/admin/auth/Auth";
import { useEffect } from 'react' import { useRouter } from "next/navigation";
import { useEffect } from "react";
type Props = {} type Props = {};
export default function page({}: Props) { export default function page({}: Props) {
const router = useRouter() const router = useRouter();
useEffect(() => { // useEffect(() => {
const hasCookie = document.cookie.includes('_identid') // const hasCookie = document.cookie.includes('_identid')
if (!hasCookie) { // if (!hasCookie) {
router.push('/admin/auth') // router.push('/admin/auth')
return // return
} // }
else { // else {
router.push('/admin/applications') // router.push('/admin/applications')
} // }
}, []) // }, [])
return <></> return <Auth />;
} }

View File

@ -31,9 +31,9 @@ export const LoadingSpinner = styled.div`
export default function Loader({}: Props) { export default function Loader({}: Props) {
return ( return (
<LoadingSpinner> <LoadingSpinner>
<img src='/loader_1.svg' alt='loader' /> <img src="/image/loader_1.svg" alt="loader" />
<img src='/loader_2.svg' alt='loader' /> <img src="/image/loader_2.svg" alt="loader" />
</LoadingSpinner> </LoadingSpinner>
) );
} }

View File

@ -1,185 +1,189 @@
import MainButton from '@/components/UI/button/MainButton' import MainButton from "@/components/UI/button/MainButton";
import FormInput from '@/components/UI/input/FormInput' import FormInput from "@/components/UI/input/FormInput";
import OrdersService from '@/services/order/ordersServices' import OrdersService from "@/services/order/ordersServices";
import { T_Product } from '@/services/product/type' import { T_Product } from "@/services/product/type";
import { ChangeEvent, FormEvent, useEffect, useState } from 'react' import { ChangeEvent, FormEvent, useEffect, useState } from "react";
import styled from 'styled-components' import styled from "styled-components";
import PhoneInput from '../UI/input/PhoneInput' import PhoneInput from "../UI/input/PhoneInput";
import Loader from '../UI/loader/Loader' import Loader from "../UI/loader/Loader";
const Container = styled.form` const Container = styled.form`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 20px; gap: 20px;
width: 500px; width: 500px;
${(props) => props.theme.mediaQueries.mobile} { ${(props) => props.theme.mediaQueries.mobile} {
width: 100%; width: 100%;
} }
` `;
const Notification = styled.div` const Notification = styled.div`
z-index: 5; z-index: 5;
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
height: 100%; height: 100%;
width: 100%; width: 100%;
border-radius: 12px; border-radius: 12px;
background: rgba(0, 0, 0, 0.5); background: rgba(0, 0, 0, 0.5);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
.container { .container {
padding: 20px; padding: 20px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
gap: 15px; gap: 15px;
min-height: 100px; min-height: 100px;
min-width: 100px; min-width: 100px;
border-radius: 12px; border-radius: 12px;
background: ${(props) => props.theme.colors.white}; background: ${(props) => props.theme.colors.white};
} }
` `;
type Props = { type Props = {
setModal: (param: boolean) => void setModal: (param: boolean) => void;
item?: T_Product item?: T_Product;
modal?: boolean modal?: boolean;
} };
export default function AddApplicationForm({ setModal, item, modal }: Props) { export default function AddApplicationForm({ setModal, item, modal }: Props) {
const [errorMessage, setErrorMessage] = useState('') const [errorMessage, setErrorMessage] = useState("");
const [errorState, setErrorState] = useState(false) const [errorState, setErrorState] = useState(false);
const [notificationModalState, setNotificationModalState] = useState(false) const [notificationModalState, setNotificationModalState] = useState(false);
const [loadingState, setLoadingState] = useState(false) const [loadingState, setLoadingState] = useState(false);
const [buttonDisabledState, setButtonDisabledState] = useState(true) const [buttonDisabledState, setButtonDisabledState] = useState(true);
const [newApp, setNewApp] = useState({ const [newApp, setNewApp] = useState({
email: '', email: "",
phone: '' phone: "",
}) });
useEffect(() => { useEffect(() => {
setNewApp({ setNewApp({
email: '', email: "",
phone: '' phone: "",
}) });
}, [modal]) }, [modal]);
useEffect(() => { useEffect(() => {
if (newApp.email === '' || newApp.phone === '') { if (newApp.email === "" || newApp.phone === "") {
setButtonDisabledState(true) setButtonDisabledState(true);
} else { } else {
setButtonDisabledState(false) setButtonDisabledState(false);
} }
}, [newApp]) }, [newApp]);
const createCallApp = async (e: FormEvent<HTMLFormElement>) => { const createCallApp = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault() e.preventDefault();
if (errorState) return if (errorState) return;
try { try {
const newAppData = { const newAppData = {
Phone: newApp.phone, Phone: newApp.phone,
Email: newApp.email Email: newApp.email,
} };
const response = await OrdersService.createCall(newAppData) const response = await OrdersService.createCall(newAppData);
if (response.status === 200) { if (response.status === 200) {
setNotificationModalState(true) setNotificationModalState(true);
} else { } else {
setErrorMessage(response.data) setErrorMessage(response.data);
setErrorState(true) setErrorState(true);
} }
} catch (error) { } catch (error) {
console.log(error) console.log(error);
} }
} };
const createApp = async (e: FormEvent<HTMLFormElement>) => { const createApp = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault() e.preventDefault();
if (errorState) return if (errorState) return;
setLoadingState(true) setLoadingState(true);
try { try {
const newAppData = { const newAppData = {
Phone: newApp.phone, Phone: newApp.phone,
Email: newApp.email, Email: newApp.email,
Positions: item ? [{ Id: item.Id, Count: 1 }] : [] Positions: item ? [{ Id: item.Id, Count: 1 }] : [],
} };
const response = await (item const response = await (item
? OrdersService.create(newAppData) ? OrdersService.create(newAppData)
: OrdersService.createCall(newAppData)) : OrdersService.createCall(newAppData));
if (response.status === 200) { if (response.status === 200) {
setNotificationModalState(true) setNotificationModalState(true);
} else { } else if (response.status === 404) {
setErrorMessage(response.data) setErrorMessage("Сервер не доступен, повторите попытку позже.");
setErrorState(true) setErrorState(true);
} } else {
} catch (error) { setErrorMessage(response.data);
console.log(error) setErrorState(true);
} }
setLoadingState(false) } catch (error) {
} setErrorMessage("Сервер не доступен, повторите попытку позже.");
setErrorState(true);
}
setLoadingState(false);
};
const handlePhoneChange = (value: string) => { const handlePhoneChange = (value: string) => {
setNewApp({ ...newApp, phone: value }) setNewApp({ ...newApp, phone: value });
} };
const closeModal = () => { const closeModal = () => {
setModal(false) setModal(false);
setNotificationModalState(false) setNotificationModalState(false);
} };
return ( return (
<> <>
<Container onSubmit={createApp}> <Container onSubmit={createApp}>
<h2>Новая заявка</h2> <h2>Новая заявка</h2>
<FormInput <FormInput
value={newApp.email} value={newApp.email}
onChange={(e: ChangeEvent<HTMLInputElement>) => onChange={(e: ChangeEvent<HTMLInputElement>) =>
setNewApp({ ...newApp, email: e.target.value }) setNewApp({ ...newApp, email: e.target.value })
} }
placeholder='Ваш email' placeholder="Ваш email"
/> />
<PhoneInput value={newApp.phone} onChange={handlePhoneChange} /> <PhoneInput value={newApp.phone} onChange={handlePhoneChange} />
{item && <h3>Услуга: {item.Name}</h3>} {item && <h3>Услуга: {item.Name}</h3>}
<MainButton onClick={createApp} disabled={buttonDisabledState}> <MainButton onClick={createApp} disabled={buttonDisabledState}>
Оставить заявку Оставить заявку
</MainButton> </MainButton>
</Container> </Container>
{loadingState && ( {loadingState && (
<Notification> <Notification>
<div className='container'> <div className="container">
<Loader /> <Loader />
</div> </div>
</Notification> </Notification>
)} )}
{errorState && ( {errorState && (
<Notification> <Notification>
<div className='container'> <div className="container">
<h4>{errorMessage}</h4> <h4>{errorMessage}</h4>
<MainButton fullWidth={true} onClick={() => setErrorState(false)}> <MainButton fullWidth={true} onClick={() => setErrorState(false)}>
Закрыть Закрыть
</MainButton> </MainButton>
</div> </div>
</Notification> </Notification>
)} )}
{notificationModalState && ( {notificationModalState && (
<Notification> <Notification>
<div className='container'> <div className="container">
<h4>Заявка успешно отправлена</h4> <h4>Заявка успешно отправлена</h4>
<MainButton fullWidth={true} onClick={closeModal}> <MainButton fullWidth={true} onClick={closeModal}>
Закрыть Закрыть
</MainButton> </MainButton>
</div> </div>
</Notification> </Notification>
)} )}
</> </>
) );
} }

View File

@ -1,95 +1,89 @@
'use client' "use client";
import UserService from '@/services/user/userServices' import UserService from "@/services/user/userServices";
import Link from 'next/link' import Link from "next/link";
import { usePathname, useRouter } from 'next/navigation' import { usePathname, useRouter } from "next/navigation";
import { useEffect } from 'react' import { useEffect } from "react";
import styled from 'styled-components' import styled from "styled-components";
type Props = {} type Props = {};
const Container = styled.div` const Container = styled.div`
background: ${(props) => props.theme.colors.green}; background: ${(props) => props.theme.colors.green};
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 260px; width: 260px;
padding: 30px 40px; padding: 30px 40px;
gap: 20px; gap: 20px;
height: 100vh; height: 100vh;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
.menu { .menu {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 25px; gap: 25px;
.item { .item {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 15px; gap: 15px;
cursor: pointer; cursor: pointer;
padding: 5px; padding: 5px;
color: ${(props) => props.theme.colors.white}; color: ${(props) => props.theme.colors.white};
} }
} }
` `;
export default function AdminSideBar({}: Props) { export default function AdminSideBar({}: Props) {
const pathname = usePathname() const pathname = usePathname();
const router = useRouter() const router = useRouter();
useEffect(() => { // useEffect(() => {
const hasCookie = document.cookie.includes('_identid') // const hasCookie = document.cookie.includes("_identid");
if (!hasCookie && pathname.startsWith('/admin')) { // if (!hasCookie && pathname.startsWith("/admin")) {
router.push('/admin/auth') // router.push("/admin/auth");
return // return;
} // }
}, []) // }, []);
const logout = async () => { const logout = async () => {
try { try {
const response = await UserService.exit() const response = await UserService.exit();
if (response.status === 200) { if (response.status === 200) {
router.push('/admin/auth') router.push("/admin");
document.cookie = document.cookie =
'_identid=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;' "_identid=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
} }
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
} };
return pathname.startsWith('/admin') && return pathname.startsWith("/admin") &&
pathname !== '/admin/auth' && pathname !== "/admin/auth" &&
pathname !== '/admin' ? ( pathname !== "/admin" ? (
<Container> <Container>
<img src='/logo.svg' alt='' /> <img src="/image/logo.svg" alt="" />
<div className='menu'> <div className="menu">
<Link href='/admin/applications'> <Link href="/admin/applications">
<div className='item'> <div className="item">
<img src='/applications.svg' alt='' /> <img src="/image/applications.svg" alt="" />
<p>Заявки</p> <p>Заявки</p>
</div> </div>
</Link> </Link>
<Link href='/admin/services'> <Link href="/admin/services">
<div className='item'> <div className="item">
<img src='/services.svg' alt='' /> <img src="/image/services.svg" alt="" />
<p>Услуги</p> <p>Услуги</p>
</div> </div>
</Link> </Link>
{/* <Link href='/admin/virtualCemetery'> <div className="item" onClick={logout}>
<div className='item'> <img src="/image/log-out.svg" alt="" />
<img src='/grave.svg' alt='' /> <p>Выйти</p>
<p>Вечная память</p> </div>
</div> </div>
</Link> */} </Container>
<div className='item' onClick={logout}> ) : null;
<img src='/log-out.svg' alt='' />
<p>Выйти</p>
</div>
</div>
</Container>
) : null
} }

View File

@ -1,126 +1,143 @@
'use client' "use client";
import { Container } from '@/app/GlobalStyles' import { Container } from "@/app/GlobalStyles";
import Image from 'next/image' import Image from "next/image";
import Link from 'next/link' import Link from "next/link";
import { usePathname } from 'next/navigation' import { usePathname } from "next/navigation";
import { useEffect, useState } from 'react' import { useEffect, useState } from "react";
import LandingButton from '../../UI/button/LandingButton' import LandingButton from "../../UI/button/LandingButton";
import Modal from '../../UI/modal/Modal' import Modal from "../../UI/modal/Modal";
import { BurgerMenu, HeaderContainer } from './styles' import { BurgerMenu, HeaderContainer } from "./styles";
import AddApplicationForm from '@/components/blocks/AddApplicationForm' import AddApplicationForm from "@/components/blocks/AddApplicationForm";
type Props = {} type Props = {};
export default function Header({}: Props) { export default function Header({}: Props) {
const [modal, setModal] = useState(false) const [modal, setModal] = useState(false);
const [menuState, setMenuState] = useState(false) const [menuState, setMenuState] = useState(false);
const pathname = usePathname() const pathname = usePathname();
useEffect(() => { useEffect(() => {
setMenuState(false) setMenuState(false);
}, [pathname]) }, [pathname]);
return !pathname.startsWith('/admin') ? ( return !pathname.startsWith("/admin") ? (
<> <>
<HeaderContainer> <HeaderContainer>
<Container> <Container>
<div className='content'> <div className="content">
<div className='logo'> <div className="logo">
<img src='/logo.svg' alt='phone' /> <img src="/image/logo.svg" alt="phone" />
<span>Городская похоронная служба</span> <span>Городская похоронная служба</span>
</div> </div>
<div className='contact-block'> <div className="contact-block">
<div className='addresses'> <div className="addresses">
<span>ул. Курчатова, д. 4</span> <span>
<span>ул. Героев Танкограда, д.61а</span> <a href="https://yandex.ru/maps/56/chelyabinsk/house/ulitsa_kurchatova_4/YkgYdQ5mTUYBQFtvfX11dntgYw==/?ll=61.396436%2C55.147737&z=17.08">
</div> ул. Курчатова, д. 4
<div className='phones'> </a>
<div className='phone'> </span>
<Image src='/phone.svg' width={20} height={20} alt='phone' /> <span>
<p>+7 (951) 773-34-53</p> <a href="https://yandex.ru/maps/56/chelyabinsk/house/ulitsa_geroyev_tankograda_61a/YkgYcgJhT0IEQFtvfX12d31lZg==/?ll=61.451673%2C55.176162&z=17.08">
</div> ул. Героев Танкограда, д.61а
<div className='phone-all-time'> </a>
<div className='top'> </span>
<Image </div>
src='/phone.svg' <div className="phones">
width={20} <div className="phone">
height={20} <Image
alt='phone' src="/image/phone.svg"
/> width={20}
<p>+7 (932) 307-94-54</p> height={20}
</div> alt="phone"
<span>Круглосуточно</span> />
</div> <a href="tel:+79517733453">
</div> <p>+7 (951) 773-34-53</p>
</div> </a>
<LandingButton onClick={() => setModal(true)}> </div>
Заказать звонок <div className="phone-all-time">
</LandingButton> <div className="top">
</div> <Image
<div className='navbar'> src="/image/phone.svg"
<Link href='/'>Главная</Link> width={20}
<Link href='/services'>Услуги</Link> height={20}
<Link href='/aboutUs'>О нас</Link> alt="phone"
<Link href='/ourCemeteries'>Наши кладбища</Link> />
{/* <Link href='/everlastingMemory'>Вечная память</Link> */} <a href="tel:+79323079454">
</div> <p>+7 (932) 307-94-54</p>
</Container> </a>
<BurgerMenu state={menuState}> </div>
<div className='title'> <span>Круглосуточно</span>
<div className='logo-container'> </div>
<img src='/logo.svg' alt='' className='logo-image' /> </div>
</div> </div>
<div className='menu-icon-container'> <LandingButton onClick={() => setModal(true)}>
<img Заказать звонок
src='/burger-menu.svg' </LandingButton>
alt='' </div>
onClick={() => setMenuState(true)} <div className="navbar">
/> <Link href="/">Главная</Link>
</div> <Link href="/services">Услуги</Link>
</div> <Link href="/aboutUs">О нас</Link>
<div className='menu-container'> <Link href="/ourCemeteries">Наши кладбища</Link>
<div className='title-active'> {/* <Link href='/everlastingMemory'>Вечная память</Link> */}
<div className='contact'> </div>
<div className='addresses'> </Container>
<p>ул. Курчатова, д. 4</p> <BurgerMenu state={menuState}>
<p>ул. Героев Танкограда, д.61а</p> <div className="title">
</div> <div className="logo-container">
<div className='number'> <img src="/image/logo.svg" alt="" className="logo-image" />
<p>+7 (951) 773-34-53</p> </div>
<p>+7 (932) 307-94-54</p> <div className="menu-icon-container">
</div> <img
</div> src="/image/burger-menu.svg"
<img alt=""
src='/close-menu.svg' onClick={() => setMenuState(true)}
alt='' />
onClick={() => setMenuState(false)} </div>
/> </div>
</div> <div className="menu-container">
<div className='menu'> <div className="title-active">
<LandingButton <div className="contact">
onClick={() => { <div className="addresses">
setModal(true), setMenuState(false) <p>ул. Курчатова, д. 4</p>
}} <p>ул. Героев Танкограда, д.61а</p>
> </div>
Заказать звонок <div className="number">
</LandingButton> <p>+7 (951) 773-34-53</p>
<Link href='/'>Главная</Link> <p>+7 (932) 307-94-54</p>
<Link href='/services'>Услуги</Link> </div>
<Link href='/aboutUs'>О нас</Link> </div>
<Link href='/ourCemeteries'>Наши кладбища</Link> <img
{/* <Link href='/everlastingMemory'>Вечная память</Link> */} src="/image/close-menu.svg"
</div> alt=""
</div> onClick={() => setMenuState(false)}
</BurgerMenu> />
</HeaderContainer> </div>
<div className="menu">
<LandingButton
onClick={() => {
setModal(true), setMenuState(false);
}}
>
Заказать звонок
</LandingButton>
<Link href="/">Главная</Link>
<Link href="/services">Услуги</Link>
<Link href="/aboutUs">О нас</Link>
<Link href="/ourCemeteries">Наши кладбища</Link>
{/* <Link href='/everlastingMemory'>Вечная память</Link> */}
</div>
</div>
</BurgerMenu>
</HeaderContainer>
<Modal modal={modal} setModal={setModal}> <Modal modal={modal} setModal={setModal}>
<AddApplicationForm setModal={setModal} /> <AddApplicationForm setModal={setModal} />
</Modal> </Modal>
</> </>
) : null ) : null;
} }

View File

@ -1,207 +1,211 @@
import styled, { css } from 'styled-components' import styled, { css } from 'styled-components'
export const HeaderContainer = styled.div` export const HeaderContainer = styled.div`
background: ${(props) => props.theme.colors.green}; background: ${(props) => props.theme.colors.green};
color: ${(props) => props.theme.colors.white}; color: ${(props) => props.theme.colors.white};
.content { .content {
width: 100%; width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
} }
.contact-block { .contact-block {
display: flex; display: flex;
align-items: start; align-items: start;
gap: 30px; gap: 30px;
}
.logo { a {
display: flex; font-size: 18px;
flex-direction: column; }
gap: 10px; }
align-items: center;
padding: 15px;
span { .logo {
font-size: 16px; display: flex;
font-weight: 300; flex-direction: column;
} gap: 10px;
} align-items: center;
padding: 15px;
.addresses { span {
display: flex; font-size: 16px;
flex-direction: column; font-weight: 300;
gap: 10px; }
} }
.phones { .addresses {
display: flex; display: flex;
align-items: start; flex-direction: column;
gap: 20px; gap: 10px;
} }
.phone { .phones {
display: flex; display: flex;
align-items: center; align-items: start;
gap: 5px; gap: 20px;
} }
.phone-all-time { .phone {
display: flex; display: flex;
flex-direction: column; align-items: center;
align-items: center; gap: 5px;
gap: 5px; }
span { .phone-all-time {
font-size: 12px; display: flex;
} flex-direction: column;
align-items: center;
gap: 5px;
.top { span {
display: flex; font-size: 12px;
align-items: center; }
gap: 5px;
}
}
.navbar { .top {
display: flex; display: flex;
align-items: start; align-items: center;
justify-content: space-around; gap: 5px;
padding: 20px 0; }
} }
a { .navbar {
color: ${(props) => props.theme.colors.white}; display: flex;
width: 190px; align-items: start;
text-align: center; justify-content: space-around;
font-size: 24px; padding: 20px 0;
} }
${(props) => props.theme.mediaQueries.tabletLandscape} { a {
.contact-block { color: ${(props) => props.theme.colors.white};
flex-direction: column; width: 190px;
gap: 10px; text-align: center;
font-size: 24px;
}
.addresses { ${(props) => props.theme.mediaQueries.tabletLandscape} {
flex-direction: row; .contact-block {
width: 100%; flex-direction: column;
justify-content: space-between; gap: 10px;
}
}
.logo { .addresses {
width: 250px; flex-direction: row;
width: 100%;
justify-content: space-between;
}
}
img { .logo {
} width: 250px;
span { img {
font-size: 12px; }
}
}
.navbar { span {
a { font-size: 12px;
font-size: 18px; }
} }
}
.phones { .navbar {
width: 100%; a {
justify-content: space-between; font-size: 18px;
} }
}
.phone { .phones {
display: flex; width: 100%;
align-items: center; justify-content: space-between;
gap: 5px; }
font-size: 14px;
p { .phone {
font-size: 14px; display: flex;
} align-items: center;
} gap: 5px;
font-size: 14px;
.phone-all-time { p {
display: flex; font-size: 14px;
flex-direction: column; }
align-items: center; }
gap: 5px;
p { .phone-all-time {
font-size: 14px; display: flex;
} flex-direction: column;
align-items: center;
gap: 5px;
span { p {
font-size: 10px; font-size: 14px;
} }
.top { span {
font-size: 14px; font-size: 10px;
display: flex; }
align-items: center;
gap: 5px;
}
}
}
${(props) => props.theme.mediaQueries.tabletPortrait} { .top {
.content { font-size: 14px;
align-items: center; display: flex;
padding-top: 10px; align-items: center;
} gap: 5px;
}
}
}
.contact-block { ${(props) => props.theme.mediaQueries.tabletPortrait} {
flex-direction: row; .content {
align-items: center;
padding-top: 10px;
}
.addresses { .contact-block {
width: 100%; flex-direction: row;
justify-content: space-between;
flex-direction: column;
span { .addresses {
font-size: 14px; width: 100%;
} justify-content: space-between;
} flex-direction: column;
}
.logo { span {
span { font-size: 14px;
display: none; }
} }
} }
.phones { .logo {
flex-direction: column; span {
display: none;
}
}
img { .phones {
display: none; flex-direction: column;
}
}
.navbar { img {
a { display: none;
font-size: 16px; }
} }
}
}
${(props) => props.theme.mediaQueries.mobile} { .navbar {
.content { a {
display: none; font-size: 16px;
} }
}
}
.navbar { ${(props) => props.theme.mediaQueries.mobile} {
display: none; .content {
} display: none;
}
.menu-container { .navbar {
display: none; display: none;
} }
}
` .menu-container {
display: none;
}
}
`;
interface I_Menu { interface I_Menu {
state: boolean state: boolean

View File

@ -1,69 +1,77 @@
'use client' "use client";
import { Container } from '@/app/GlobalStyles' import { Container } from "@/app/GlobalStyles";
import AddApplicationForm from '@/components/blocks/AddApplicationForm' import AddApplicationForm from "@/components/blocks/AddApplicationForm";
import Link from 'next/link' import Link from "next/link";
import { usePathname } from 'next/navigation' import { usePathname } from "next/navigation";
import { useState } from 'react' import { useState } from "react";
import LandingButton from '../../UI/button/LandingButton' import LandingButton from "../../UI/button/LandingButton";
import Modal from '../../UI/modal/Modal' import Modal from "../../UI/modal/Modal";
import { import {
ContentContainer, ContentContainer,
ContentSection, ContentSection,
FooterContainer, FooterContainer,
FooterContent, FooterContent,
LogoSection LogoSection,
} from './styels' } from "./styels";
type Props = {} type Props = {};
export default function Footer({}: Props) { export default function Footer({}: Props) {
const [modal, setModal] = useState(false) const [modal, setModal] = useState(false);
const pathname = usePathname() const pathname = usePathname();
return !pathname.startsWith('/admin') ? ( return !pathname.startsWith("/admin") ? (
<> <>
<FooterContainer> <FooterContainer>
<Container> <Container>
<FooterContent> <FooterContent>
<ContentContainer> <ContentContainer>
<LogoSection> <LogoSection>
<img src='/logo.svg' alt='phone' /> <img src="/image/logo.svg" alt="phone" />
<span>Городская похоронная служба</span> <span>Городская похоронная служба</span>
<LandingButton onClick={() => setModal(true)}> <LandingButton onClick={() => setModal(true)}>
Заказать звонок Заказать звонок
</LandingButton> </LandingButton>
</LogoSection> </LogoSection>
<ContentSection> <ContentSection>
<h3>Наши контакты</h3> <h3>Наши контакты</h3>
<p>ул. Курчатова, д. 4</p> <a href="https://yandex.ru/maps/56/chelyabinsk/house/ulitsa_kurchatova_4/YkgYdQ5mTUYBQFtvfX11dntgYw==/?ll=61.396436%2C55.147737&z=17.08">
<p>ул. Героев Танкограда, д.61а</p> <p>ул. Курчатова, д. 4</p>
<p>+7 (951) 773-34-53</p> </a>
<p>+7 (932) 307-94-54</p> <a href="https://yandex.ru/maps/56/chelyabinsk/house/ulitsa_geroyev_tankograda_61a/YkgYcgJhT0IEQFtvfX12d31lZg==/?ll=61.451673%2C55.176162&z=17.08">
</ContentSection> <p>ул. Героев Танкограда, д.61а</p>
<ContentSection> </a>
<h3>Навигация</h3> <a href="tel:+79517733453">
<Link href='/'> <p>+7 (951) 773-34-53</p>
<p>На главную</p> </a>
</Link> <a href="tel:+79323079454">
<Link href='/aboutUs'> <p>+7 (932) 307-94-54</p>
<p>О нас</p> </a>
</Link> </ContentSection>
<Link href='/services'> <ContentSection>
<p>Услуги</p> <h3>Навигация</h3>
</Link> <Link href="/">
<Link href='/ourCemeteries'> <p>На главную</p>
<p>Наши кладбища</p> </Link>
</Link> <Link href="/aboutUs">
</ContentSection> <p>О нас</p>
</ContentContainer> </Link>
</FooterContent> <Link href="/services">
</Container> <p>Услуги</p>
</FooterContainer> </Link>
<Modal modal={modal} setModal={setModal}> <Link href="/ourCemeteries">
<AddApplicationForm setModal={setModal} /> <p>Наши кладбища</p>
</Modal> </Link>
</> </ContentSection>
) : null </ContentContainer>
</FooterContent>
</Container>
</FooterContainer>
<Modal modal={modal} setModal={setModal}>
<AddApplicationForm setModal={setModal} />
</Modal>
</>
) : null;
} }

View File

@ -105,7 +105,7 @@ export default function AboutUs({}: Props) {
потребностям и возможностям клиента. потребностям и возможностям клиента.
</p> </p>
</div> </div>
<img src='/image 6.png' alt='' className='item' /> <img src='/image/about_us_image.png' alt='' className='item' />
</div> </div>
<div className='bottom'> <div className='bottom'>
<h3>Принципы прозрачности и заботы о клиентах</h3> <h3>Принципы прозрачности и заботы о клиентах</h3>

View File

@ -11,33 +11,33 @@ import styled from 'styled-components'
type Props = {} type Props = {}
const Container = styled.div` const Container = styled.div`
width: 100%; width: 100%;
height: 100vh; height: 100vh;
background-image: url('/image 12.jpg'); background-image: url("/image/admin_login_bg.jpg");
background-position: center; background-position: center;
background-size: cover; background-size: cover;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
.form { .form {
width: 440px; width: 440px;
padding: 20px; padding: 20px;
text-align: center; text-align: center;
display: flex; display: flex;
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
gap: 20px; gap: 20px;
backdrop-filter: blur(4px); backdrop-filter: blur(4px);
background: rgba(129, 129, 129, 0.4); background: rgba(129, 129, 129, 0.4);
color: ${(props) => props.theme.colors.white}; color: ${(props) => props.theme.colors.white};
border-radius: 12px; border-radius: 12px;
} }
` `;
const NotificationContainer = styled.div` const NotificationContainer = styled.div`
position: absolute; position: absolute;

View File

@ -100,88 +100,88 @@ export default function Services({}: Props) {
}, []) }, [])
return ( return (
<> <>
{firstLoadingState ? ( {firstLoadingState ? (
<NotificationContainer> <NotificationContainer>
<Loader /> <Loader />
</NotificationContainer> </NotificationContainer>
) : ( ) : (
<> <>
{ConnectServerError ? ( {ConnectServerError ? (
<NotificationContainer> <NotificationContainer>
<h2>Сервер не доступен...</h2> <h2>Сервер не доступен...</h2>
</NotificationContainer> </NotificationContainer>
) : ( ) : (
<> <>
<AdminContainer> <AdminContainer>
<Container> <Container>
{!(services.length === 0 && searchQuery === '') ? ( {!(services.length === 0 && searchQuery === "") ? (
<> <>
<h1>Услуги</h1> <h1>Услуги</h1>
<div className='search-block'> <div className="search-block">
<div className='input-block'> <div className="input-block">
<FormInput <FormInput
value={searchQuery} value={searchQuery}
onChange={(e: ChangeEvent<HTMLInputElement>) => onChange={(e: ChangeEvent<HTMLInputElement>) =>
setSearchQuery(e.target.value) setSearchQuery(e.target.value)
} }
placeholder='Введите название услуги' placeholder="Введите название услуги"
/> />
<img src='/search.svg' alt='' /> <img src="/image/search.svg" alt="" />
</div> </div>
<MainButton <MainButton
fullWidth={true} fullWidth={true}
onClick={() => setModal(true)} onClick={() => setModal(true)}
> >
Добавить Добавить
</MainButton> </MainButton>
</div> </div>
{loadingState ? ( {loadingState ? (
<NotificationContainer> <NotificationContainer>
<Loader /> <Loader />
</NotificationContainer> </NotificationContainer>
) : services.length !== 0 ? ( ) : services.length !== 0 ? (
<div className='list'> <div className="list">
{services.map((item: T_Product, index) => ( {services.map((item: T_Product, index) => (
<ServiceItem <ServiceItem
item={item} item={item}
key={index} key={index}
getServices={getServices} getServices={getServices}
/> />
))} ))}
</div> </div>
) : ( ) : (
<NotificationContainer> <NotificationContainer>
<h3>Ничего не найдено</h3> <h3>Ничего не найдено</h3>
</NotificationContainer> </NotificationContainer>
)} )}
</> </>
) : ( ) : (
<NotificationContainer> <NotificationContainer>
<h2>Список товаров пуст</h2> <h2>Список товаров пуст</h2>
<MainButton <MainButton
fullWidth={true} fullWidth={true}
onClick={() => setModal(true)} onClick={() => setModal(true)}
> >
Добавить Добавить
</MainButton> </MainButton>
</NotificationContainer> </NotificationContainer>
)} )}
</Container> </Container>
</AdminContainer> </AdminContainer>
<AddServiceForm <AddServiceForm
getServices={getServices} getServices={getServices}
modal={modal} modal={modal}
setModal={setModal} setModal={setModal}
/> />
</> </>
)} )}
</> </>
)} )}
<Modal setModal={setErrorState} modal={errorState}> <Modal setModal={setErrorState} modal={errorState}>
<h3>{errorMessage}</h3> <h3>{errorMessage}</h3>
<MainButton>Закрыть</MainButton> <MainButton>Закрыть</MainButton>
</Modal> </Modal>
</> </>
) );
} }

View File

@ -1,88 +1,87 @@
import MainButton from '@/components/UI/button/MainButton' import MainButton from "@/components/UI/button/MainButton";
import ProductService from '@/services/product/productServeces' import ProductService from "@/services/product/productServeces";
import { useState } from 'react' import { useState } from "react";
import styled from 'styled-components' import styled from "styled-components";
import { T_Product } from '../../../../../services/product/type' import { T_Product } from "../../../../../services/product/type";
import UpdateServiceForm from './UpdateServiceForm' import UpdateServiceForm from "./UpdateServiceForm";
import { hostName } from '../../../../../../config'
const Cart = styled.div` const Cart = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: start; align-items: start;
width: 280px; width: 280px;
gap: 10px; gap: 10px;
position: relative; position: relative;
justify-content: space-between; justify-content: space-between;
border-radius: 12px 12px 0 0; border-radius: 12px 12px 0 0;
overflow: hidden; overflow: hidden;
text-align: justify; text-align: justify;
.delete-button { .delete-button {
position: absolute; position: absolute;
top: 10px; top: 10px;
right: 10px; right: 10px;
background: ${(props) => props.theme.colors.white}; background: ${(props) => props.theme.colors.white};
width: 30px; width: 30px;
height: 30px; height: 30px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
border-radius: 50px; border-radius: 50px;
cursor: pointer; cursor: pointer;
} }
.block { .block {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: start; align-items: start;
width: 280px; width: 280px;
gap: 10px; gap: 10px;
img { img {
width: 280px; width: 280px;
height: 200px; height: 200px;
object-fit: cover; object-fit: cover;
} }
} }
` `;
type Props = { type Props = {
item: T_Product item: T_Product;
getServices: () => void getServices: () => void;
} };
export default function ServiceItem({ item, getServices }: Props) { export default function ServiceItem({ item, getServices }: Props) {
const [modal, setModal] = useState(false) const [modal, setModal] = useState(false);
const deleteService = async () => { const deleteService = async () => {
await ProductService.delete(item.Id) await ProductService.delete(item.Id);
getServices() getServices();
} };
return ( return (
<> <>
<Cart> <Cart>
<div className='block'> <div className="block">
<img src={'/'+item.ImageUrls[0]} alt='' /> <img src={"/" + item.ImageUrls[0]} alt="" />
<h3>{item.Name}</h3> <h3>{item.Name}</h3>
<p>{item.FullDesc}</p> <p>{item.FullDesc}</p>
</div> </div>
<div className='block'> <div className="block">
<h2>От {item.OldPrice} руб.</h2> <h2>От {item.OldPrice} руб.</h2>
<MainButton onClick={() => setModal(true)}>Редактировать</MainButton> <MainButton onClick={() => setModal(true)}>Редактировать</MainButton>
</div> </div>
<div className='delete-button' onClick={deleteService}> <div className="delete-button" onClick={deleteService}>
<img src='/trash.svg' alt='' /> <img src="/image/trash.svg" alt="" />
</div> </div>
</Cart> </Cart>
<UpdateServiceForm <UpdateServiceForm
getServices={getServices} getServices={getServices}
modal={modal} modal={modal}
setModal={setModal} setModal={setModal}
item={item} item={item}
/> />
</> </>
) );
} }

View File

@ -34,25 +34,25 @@ type Props = {}
export default function AboutUs({}: Props) { export default function AboutUs({}: Props) {
return ( return (
<Container> <Container>
<IconContainer> <IconContainer>
<div className='item'> <div className="item">
<img src='/cemetery.svg' alt='' /> <img src="/image/cemetery.svg" alt="" />
<p>Разнообразные похоронные услуги для всех</p> <p>Разнообразные похоронные услуги для всех</p>
</div> </div>
<div className='item'> <div className="item">
<img src='/agreement.svg' alt='' /> <img src="/image/agreement.svg" alt="" />
<p>Четкие цены на все услуги</p> <p>Четкие цены на все услуги</p>
</div> </div>
<div className='item'> <div className="item">
<img src='/operator.svg' alt='' /> <img src="/image/operator.svg" alt="" />
<p>Круглосуточная поддержка специалистов</p> <p>Круглосуточная поддержка специалистов</p>
</div> </div>
<div className='item'> <div className="item">
<img src='/deal.svg' alt='' /> <img src="/image/deal.svg" alt="" />
<p>Договор без скрытых платежей</p> <p>Договор без скрытых платежей</p>
</div> </div>
</IconContainer> </IconContainer>
</Container> </Container>
) );
} }

View File

@ -1,47 +1,57 @@
import { Container } from '@/app/GlobalStyles' import { Container } from "@/app/GlobalStyles";
import React from 'react' import Modal from "@/components/UI/modal/Modal";
import styled from 'styled-components' import AddApplicationForm from "@/components/blocks/AddApplicationForm";
import React, { useState } from "react";
import styled from "styled-components";
const OrderContainer = styled.div` const OrderContainer = styled.div`
display: flex; display: flex;
align-items: center; align-items: center;
flex-direction: column; flex-direction: column;
gap: 30px; gap: 30px;
margin-top: 50px; margin-top: 50px;
.button { .button {
padding: 10px; padding: 10px;
border-radius: 12px; border-radius: 12px;
border: 3px solid ${(props) => props.theme.colors.green}; border: 3px solid ${(props) => props.theme.colors.green};
button { button {
background: ${(props) => props.theme.colors.green}; background: ${(props) => props.theme.colors.green};
color: ${(props) => props.theme.colors.white}; color: ${(props) => props.theme.colors.white};
padding: 30px 70px; padding: 30px 70px;
border-radius: 12px; border-radius: 12px;
border: none; border: none;
} cursor: pointer;
} }
}
h3 { h3 {
text-align: center; text-align: center;
} }
` `;
type Props = {} type Props = {};
export default function CreateOrder({}: Props) { export default function CreateOrder({}: Props) {
const [modal, setModal] = useState(false);
return ( return (
<Container> <>
<OrderContainer> <Container>
<h1>Закажи обратный звонок</h1> <OrderContainer>
<h3>Круглосуточно принимаем заказы любой сложности</h3> <h1>Закажи обратный звонок</h1>
<div className='button'> <h3>Круглосуточно принимаем заказы любой сложности</h3>
<button> <div className="button">
<h2>Оставить заявку</h2> <button onClick={() => setModal(true)}>
</button> <h2>Оставить заявку</h2>
</div> </button>
</OrderContainer> </div>
</Container> </OrderContainer>
) </Container>
<Modal modal={modal} setModal={setModal}>
<AddApplicationForm setModal={setModal} />
</Modal>
</>
);
} }

View File

@ -45,32 +45,32 @@ type Props = {}
export default function Instructions({}: Props) { export default function Instructions({}: Props) {
return ( return (
<Container> <Container>
<InstructionsContainer> <InstructionsContainer>
<h2>Порядок действий в случае смерти человека</h2> <h2>Порядок действий в случае смерти человека</h2>
<div className='list'> <div className="list">
<div className='item'> <div className="item">
<img src='/telephone.svg' alt='' /> <img src="/image/telephone.svg" alt="" />
<h3>Шаг 1: Обратитесь в нашу службу</h3> <h3>Шаг 1: Обратитесь в нашу службу</h3>
<p> <p>
Позвоните по номеру <span>+7 (932) 307-94-54</span>. Позвоните по номеру <span>+7 (932) 307-94-54</span>.
</p> </p>
</div> </div>
<div className='item'> <div className="item">
<img src='/ambulance.svg' alt='' /> <img src="/image/ambulance.svg" alt="" />
<h3>Шаг 2: Дождитесь полицию и скорую помощь</h3> <h3>Шаг 2: Дождитесь полицию и скорую помощь</h3>
<p>Дождитесь получения необходимого направления от полиции.</p> <p>Дождитесь получения необходимого направления от полиции.</p>
</div> </div>
<div className='item'> <div className="item">
<img src='/hospital.svg' alt='' /> <img src="/image/hospital.svg" alt="" />
<h3>Шаг 3: Дождитесь эвакуацию</h3> <h3>Шаг 3: Дождитесь эвакуацию</h3>
<p> <p>
Дождитесь прибытия службы эвакуации для транспортировки тела в Дождитесь прибытия службы эвакуации для транспортировки тела в
морг. морг.
</p> </p>
</div> </div>
</div> </div>
</InstructionsContainer> </InstructionsContainer>
</Container> </Container>
) );
} }

View File

@ -1,97 +1,105 @@
import React from 'react' import React from "react";
import { Map, Placemark, YMaps } from '@pbe/react-yandex-maps' import { Map, Placemark, YMaps } from "@pbe/react-yandex-maps";
import styled from 'styled-components' import styled from "styled-components";
const MapContainer = styled.div` const MapContainer = styled.div`
margin: 50px 0; margin: 50px 0;
position: relative; position: relative;
.content { .content {
padding: 15px; padding: 15px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
background: ${(props) => props.theme.colors.white}; background: ${(props) => props.theme.colors.white};
border-radius: 12px; border-radius: 12px;
position: absolute; position: absolute;
top: 50%; top: 50%;
left: 10%; left: 10%;
transform: translateY(-50%); transform: translateY(-50%);
z-index: 1; z-index: 1;
} }
.map { .map {
width: 100%; width: 100%;
height: 450px; height: 450px;
} }
${(props) => props.theme.mediaQueries.tabletLandscape} { ${(props) => props.theme.mediaQueries.tabletLandscape} {
.content { .content {
gap: 5px; gap: 5px;
left: 5%; left: 5%;
h3 { h3 {
font-size: 16px; font-size: 16px;
} }
p { p {
font-size: 14px; font-size: 14px;
} }
} }
} }
${(props) => props.theme.mediaQueries.tabletPortrait} { ${(props) => props.theme.mediaQueries.tabletPortrait} {
h3 { h3 {
display: none; display: none;
} }
.content { .content {
left: 0; left: 0;
right: 0; right: 0;
border-radius: 0; border-radius: 0;
position: relative; position: relative;
transform: translateY(0); transform: translateY(0);
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
p{ p {
max-width: 200px; max-width: 200px;
width: 100%; width: 100%;
} }
} }
} }
` `;
type Props = {} type Props = {};
export default function MapSection({}: Props) { export default function MapSection({}: Props) {
return ( return (
<MapContainer> <MapContainer>
<YMaps> <YMaps>
<Map <Map
className='map' className="map"
defaultState={{ defaultState={{
center: [55.159902, 61.402554], center: [55.159902, 61.402554],
zoom: 12 zoom: 12,
}} }}
options={{ options={{
yandexMapDisablePoiInteractivity: true, yandexMapDisablePoiInteractivity: true,
copyrightLogoVisible: true, copyrightLogoVisible: true,
copyrightProvidersVisible: true, copyrightProvidersVisible: true,
copyrightUaVisible: true copyrightUaVisible: true,
}} }}
> >
<Placemark geometry={[55.147737, 61.396436]} /> <Placemark geometry={[55.147737, 61.396436]} />
<Placemark geometry={[55.176162, 61.451673]} /> <Placemark geometry={[55.176162, 61.451673]} />
</Map> </Map>
</YMaps> </YMaps>
<div className='content'> <div className="content">
<h3>Наши контакты</h3> <h3>Наши контакты</h3>
<p>ул. Курчатова, д. 4</p> <a href="https://yandex.ru/maps/56/chelyabinsk/house/ulitsa_kurchatova_4/YkgYdQ5mTUYBQFtvfX11dntgYw==/?ll=61.396436%2C55.147737&z=17.08">
<p>ул. Героев Танкограда, д.61а</p> <p>ул. Курчатова, д. 4</p>
<p>+7 (951) 773-34-53</p> </a>
<p>+7 (932) 307-94-54 (Круглосуточно)</p> <a href="https://yandex.ru/maps/56/chelyabinsk/house/ulitsa_geroyev_tankograda_61a/YkgYcgJhT0IEQFtvfX12d31lZg==/?ll=61.451673%2C55.176162&z=17.08">
</div> <p>ул. Героев Танкограда, д.61а</p>
</MapContainer> </a>
) <a href="tel:+79517733453">
<p>+7 (951) 773-34-53</p>
</a>
<a href="tel:+79323079454">
<p>+7 (932) 307-94-54 (Круглосуточно)</p>
</a>
</div>
</MapContainer>
);
} }

View File

@ -1,289 +1,274 @@
import { useState } from 'react' import { useState } from "react";
import Slider from 'react-slick' import Slider from "react-slick";
import styled from 'styled-components' import styled from "styled-components";
export const ReviewsContainer = styled.div` export const ReviewsContainer = styled.div`
gap: 50px; gap: 50px;
width: 100%; width: 100%;
h2 { h2 {
margin: 50px 0; margin: 50px 0;
text-align: center; text-align: center;
} }
.item { .item {
padding: 25px; padding: 25px;
gap: 30px; gap: 30px;
background: ${(props) => props.theme.colors.black}; background: ${(props) => props.theme.colors.black};
max-width: 580px; max-width: 580px;
height: 190px; height: 190px;
border-radius: 12px; border-radius: 12px;
color: ${(props) => props.theme.colors.white}; color: ${(props) => props.theme.colors.white};
display: flex; display: flex;
img { img {
border-radius: 100px; border-radius: 100px;
height: 120px; height: 120px;
max-height: 120px; max-height: 120px;
width: 120px; width: 120px;
min-width: 120px; min-width: 120px;
object-fit: cover; object-fit: cover;
} }
} }
.slick-slide { .slick-slide {
display: flex; display: flex;
justify-content: center; justify-content: center;
padding: 0 10px; padding: 0 10px;
} }
${(props) => props.theme.mediaQueries.tabletLandscape} { ${(props) => props.theme.mediaQueries.tabletLandscape} {
display: none; display: none;
.item { .item {
h3 { h3 {
font-style: 14px; font-style: 14px;
} }
p { p {
font-size: 12px; font-size: 12px;
} }
img { img {
border-radius: 100px; border-radius: 100px;
height: 90px; height: 90px;
width: 90px; width: 90px;
} }
} }
} }
` `;
export const MobileReviewsContainer = styled.div` export const MobileReviewsContainer = styled.div`
display: none; display: none;
gap: 50px; gap: 50px;
h2 { h2 {
margin: 50px 0; margin: 50px 0;
text-align: center; text-align: center;
} }
.item { .item {
padding: 25px; padding: 25px;
gap: 30px; gap: 30px;
background: ${(props) => props.theme.colors.black}; background: ${(props) => props.theme.colors.black};
max-width: 580px; max-width: 580px;
border-radius: 12px; border-radius: 12px;
color: ${(props) => props.theme.colors.white}; color: ${(props) => props.theme.colors.white};
display: flex; display: flex;
img { img {
border-radius: 100px; border-radius: 100px;
} }
} }
.slick-slide { .slick-slide {
display: flex; display: flex;
justify-content: center; justify-content: center;
padding: 0 10px; padding: 0 10px;
} }
.mobile-item { .mobile-item {
display: none; display: none;
} }
${(props) => props.theme.mediaQueries.tabletLandscape} { ${(props) => props.theme.mediaQueries.tabletLandscape} {
display: block; display: block;
.item { .item {
h3 { h3 {
font-style: 14px; font-style: 14px;
} }
p { p {
font-size: 12px; font-size: 12px;
} }
img { img {
border-radius: 100px; border-radius: 100px;
height: 90px; height: 90px;
width: 90px; width: 90px;
} }
} }
} }
${(props) => props.theme.mediaQueries.mobile} { ${(props) => props.theme.mediaQueries.mobile} {
.item { .item {
display: none; display: none;
} }
.mobile-item { .mobile-item {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 15px; padding: 15px;
gap: 20px; gap: 20px;
background: ${(props) => props.theme.colors.black}; background: ${(props) => props.theme.colors.black};
border-radius: 12px; border-radius: 12px;
color: ${(props) => props.theme.colors.white}; color: ${(props) => props.theme.colors.white};
.content { .content {
display: flex; display: flex;
gap: 20px; gap: 20px;
align-items: center; align-items: center;
img { img {
border-radius: 100px; border-radius: 100px;
height: 80px; height: 80px;
width: 80px; width: 80px;
} }
h3 { h3 {
font-style: 14px; font-style: 14px;
} }
p { p {
font-size: 12px; font-size: 12px;
} }
} }
} }
} }
${(props) => props.theme.mediaQueries.slimMobile} { ${(props) => props.theme.mediaQueries.slimMobile} {
.mobile-item { .mobile-item {
.content { .content {
gap: 10px; gap: 10px;
img { img {
height: 60px; height: 60px;
width: 60px; width: 60px;
} }
h3 { h3 {
font-style: 10px; font-style: 10px;
} }
p { p {
font-size: 8px; font-size: 8px;
} }
} }
} }
} }
` `;
type Props = {} type Props = {};
export default function Review({}: Props) { export default function Review({}: Props) {
const settings = { const settings = {
autoplay: true, autoplay: true,
dots: true, dots: true,
autoplaySpeed: 4000, autoplaySpeed: 4000,
infinite: true, infinite: true,
slidesToShow: 3, slidesToShow: 3,
speed: 500, speed: 500,
arrows: false, arrows: false,
centerMode: true, centerMode: true,
centerPadding: '60px', centerPadding: "60px",
responsive: [ responsive: [
{ {
breakpoint: 1024, breakpoint: 1024,
settings: { settings: {
slidesToShow: 1, slidesToShow: 1,
slidesToScroll: 1, slidesToScroll: 1,
infinite: true, infinite: true,
dots: true, dots: true,
centerMode: true centerMode: true,
} },
}, },
{ {
breakpoint: 1550, breakpoint: 1550,
settings: { settings: {
slidesToShow: 2, slidesToShow: 2,
slidesToScroll: 1, slidesToScroll: 1,
infinite: true, infinite: true,
dots: true, dots: true,
centerMode: true centerMode: true,
} },
} },
] ],
} };
const [users, setUsers] = useState([ const [users, setUsers] = useState([
{ {
name: 'Анна Иванова', name: "Анна Иванова",
image: '/review/person_1.jpg', image: "/review/person_2.jpg",
review: review:
'Профессиональное и сочувственное обслуживание. Помогли организовать похороны без лишних хлопот. Благодарна за их поддержку в трудный момент.' "Профессиональное и сочувственное обслуживание. Помогли организовать похороны без лишних хлопот. Благодарна за их поддержку в трудный момент.",
}, },
{ {
name: 'Сергей Петров', name: "Сергей Петров",
image: '/review/person_2.jpg', image: "/review/person_1.jpg",
review: review:
'Отличное соотношение цены и качества услуг. Все выполнено аккуратно и в срок. Рекомендую это агентство в сложные времена.' "Отличное соотношение цены и качества услуг. Все выполнено аккуратно и в срок. Рекомендую это агентство в сложные времена.",
}, },
{ {
name: 'Елена Козлова', name: "Елена Козлова",
image: '/review/person_3.jpg', image: "/review/person_3.jpg",
review: review:
'Искренне признательна за заботу и профессионализм. Организация похорон прошла гладко, учли все наши пожелания. Спасибо за поддержку.' "Искренне признательна за заботу и профессионализм. Организация похорон прошла гладко, учли все наши пожелания. Спасибо за поддержку.",
}, },
{ {
name: 'Александр Смирнов', name: "Александр Смирнов",
image: '/review/person_4.jpg', image: "/review/person_4.jpg",
review: review:
'Эмпатичные сотрудники, готовые помочь в любое время суток. Сделали все возможное, чтобы облегчить бремя нашей утраты. Благодарим за помощь.' "Эмпатичные сотрудники, готовые помочь в любое время суток. Сделали все возможное, чтобы облегчить бремя нашей утраты. Благодарим за помощь.",
} },
]) ]);
return ( return (
<> <>
<ReviewsContainer> <ReviewsContainer>
<h2>Отзывы о проведенных церемониях</h2> <h2>Отзывы о проведенных церемониях</h2>
<div className='slider-container'> <div className="slider-container">
<Slider {...settings}> <Slider {...settings}>
{users.map((user, index) => ( {users.map((user, index) => (
<div key={index}> <div key={index}>
<div className='item'> <div className="item">
<img src={user.image} alt='' /> <img src={user.image} alt="" />
<div className='content'> <div className="content">
<h3>{user.name}</h3> <h3>{user.name}</h3>
<p>{user.review}</p> <p>{user.review}</p>
</div> </div>
</div> </div>
</div> </div>
))} ))}
</Slider> </Slider>
</div> </div>
</ReviewsContainer> </ReviewsContainer>
<MobileReviewsContainer> <MobileReviewsContainer>
<h2>Отзывы о проведенных церемониях</h2> <h2>Отзывы о проведенных церемониях</h2>
<div className='slider-container'> <div className="slider-container">
<Slider {...settings}> <Slider {...settings}>
{[...Array(4)].map((_, index) => ( {users.map((user, index) => (
<div> <div key={index}>
<div className='item'> <div className="item">
<img src='/image 4.png' alt='' /> <img src={user.image} alt="" />
<div className='content'> <div className="content">
<h3>Виктор Иванов</h3> <h3>{user.name}</h3>
<p> <p>{user.review}</p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, </div>
sed do eiusmod tempor incididunt ut labore et dolore magna </div>
aliqua. </div>
</p> ))}
</div> </Slider>
</div> </div>
<div className='mobile-item'> </MobileReviewsContainer>
<div className='content'> </>
<img src='/image 4.png' alt='' /> );
<h3>Виктор Иванов</h3>
</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna
aliqua.
</p>
</div>
</div>
))}
</Slider>
</div>
</MobileReviewsContainer>
</>
)
} }

View File

@ -1,264 +1,285 @@
'use client' "use client";
import { Container } from '@/app/GlobalStyles' import { Container } from "@/app/GlobalStyles";
import LandingButton from '@/components/UI/button/LandingButton' import LandingButton from "@/components/UI/button/LandingButton";
import { useState } from 'react' import Modal from "@/components/UI/modal/Modal";
import Slider from 'react-slick' import AddApplicationForm from "@/components/blocks/AddApplicationForm";
import 'slick-carousel/slick/slick-theme.css' import Link from "next/link";
import 'slick-carousel/slick/slick.css' import { useState } from "react";
import styled from 'styled-components' import Slider from "react-slick";
import "slick-carousel/slick/slick-theme.css";
import "slick-carousel/slick/slick.css";
import styled from "styled-components";
const Item = styled.div` const Item = styled.div`
position: relative; position: relative;
img { img {
width: 100%; width: 100%;
height: 400px; height: 400px;
object-fit: cover; object-fit: cover;
} }
.content { .content {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 400px; width: 400px;
height: 400px; height: 400px;
align-items: start; align-items: start;
padding: 30px 40px; padding: 30px 40px;
color: ${(props) => props.theme.colors.white}; color: ${(props) => props.theme.colors.white};
z-index: 2; z-index: 2;
background: rgba(53, 53, 53, 0.5); background: rgba(53, 53, 53, 0.5);
box-sizing: border-box; box-sizing: border-box;
h3 { h3 {
text-align: start; text-align: start;
display: none; display: none;
} }
h2 { h2 {
text-align: start; text-align: start;
margin-bottom: 20px; margin-bottom: 20px;
} }
h4 { h4 {
margin-bottom: 50px; margin-bottom: 50px;
} }
} }
${(props) => props.theme.mediaQueries.tabletLandscape} { ${(props) => props.theme.mediaQueries.tabletLandscape} {
.content { .content {
width: 400px; width: 400px;
height: 400px; height: 400px;
padding: 30px 40px; padding: 30px 40px;
h3 { h3 {
display: block; display: block;
margin-bottom: 20px; margin-bottom: 20px;
} }
h2 { h2 {
display: none; display: none;
} }
h4 { h4 {
margin-bottom: auto; margin-bottom: auto;
} }
} }
} }
${(props) => props.theme.mediaQueries.tabletPortrait} { ${(props) => props.theme.mediaQueries.tabletPortrait} {
height: 300px; height: 300px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
object-fit: cover; object-fit: cover;
} }
.content { .content {
height: 100%; height: 100%;
} }
} }
${(props) => props.theme.mediaQueries.mobile} { ${(props) => props.theme.mediaQueries.mobile} {
.content { .content {
width: 100%; width: 100%;
h3 { h3 {
font-size: 18px; font-size: 18px;
} }
h4 { h4 {
font-size: 14px; font-size: 14px;
} }
} }
} }
` `;
const RightArrow = styled.img` const RightArrow = styled.img`
position: absolute; position: absolute;
right: 0; right: 0;
top: 50%; top: 50%;
z-index: 1; z-index: 1;
transform: rotate(180deg) translateY(50%); transform: rotate(180deg) translateY(50%);
padding: 10px 5px; padding: 10px 5px;
background: ${(props) => props.theme.colors.black}; background: ${(props) => props.theme.colors.black};
border-radius: 0 12px 12px 0; border-radius: 0 12px 12px 0;
height: 45px; height: 45px;
width: 35px; width: 35px;
&:hover { &:hover {
background: ${(props) => props.theme.colors.black}; background: ${(props) => props.theme.colors.black};
} }
` `;
const LeftArrow = styled.img` const LeftArrow = styled.img`
position: absolute; position: absolute;
left: 0; left: 0;
z-index: 1; z-index: 1;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
padding: 10px 5px; padding: 10px 5px;
background: ${(props) => props.theme.colors.black}; background: ${(props) => props.theme.colors.black};
border-radius: 0 12px 12px 0; border-radius: 0 12px 12px 0;
height: 45px; height: 45px;
width: 35px; width: 35px;
&:hover { &:hover {
background: ${(props) => props.theme.colors.black}; background: ${(props) => props.theme.colors.black};
} }
${(props) => props.theme.mediaQueries.mobile} { ${(props) => props.theme.mediaQueries.mobile} {
display: none; display: none;
} }
` `;
const SliderContainer = styled.div` const SliderContainer = styled.div`
margin-top: 50px; margin-top: 50px;
overflow: hidden; overflow: hidden;
border-radius: 12px; border-radius: 12px;
height: 400px; height: 400px;
${(props) => props.theme.mediaQueries.tabletPortrait} { ${(props) => props.theme.mediaQueries.tabletPortrait} {
height: 300px; height: 300px;
} }
${(props) => props.theme.mediaQueries.mobile} { ${(props) => props.theme.mediaQueries.mobile} {
display: none; display: none;
} }
` `;
const MobileSliderContainer = styled.div` const MobileSliderContainer = styled.div`
display: none; display: none;
${(props) => props.theme.mediaQueries.mobile} { ${(props) => props.theme.mediaQueries.mobile} {
overflow: hidden; overflow: hidden;
display: block; display: block;
height: 300px; height: 300px;
} }
.slick-arrow { .slick-arrow {
${(props) => props.theme.mediaQueries.mobile} { ${(props) => props.theme.mediaQueries.mobile} {
display: none !important; display: none !important;
} }
} }
` `;
type Props = {} type Props = {};
export default function SliderSection({}: Props) { export default function SliderSection({}: Props) {
const settings = { const settings = {
infinite: true, infinite: true,
slidesToShow: 1, slidesToShow: 1,
slidesToScroll: 1, slidesToScroll: 1,
nextArrow: <RightArrow src='/left arrow.svg' alt='' />, nextArrow: <RightArrow src="/image/left arrow.svg" alt="" />,
prevArrow: <LeftArrow src='/left arrow.svg' alt='' />, prevArrow: <LeftArrow src="/image/left arrow.svg" alt="" />,
autoplay: true, autoplay: true,
speed: 2000, speed: 2000,
autoplaySpeed: 4000, autoplaySpeed: 4000,
responsive: [ responsive: [
{ {
breakpoint: 640, breakpoint: 640,
settings: { settings: {
dots: true dots: true,
} },
} },
] ],
} };
const [slides, setSlides] = useState([ const [slides, setSlides] = useState([
{ {
title: 'Мы принимаем заявки прямо сейчас', title: "Мы принимаем заявки прямо сейчас",
content: content:
'Просто оставьте заявку, и мы свяжемся с вами для уточнения деталей и предоставления всей необходимой информации.', "Просто оставьте заявку, и мы свяжемся с вами для уточнения деталей и предоставления всей необходимой информации.",
image: '/home_slider/slide_4.jpg', image: "/home_slider/slide_4.jpg",
link: '', link: "",
button: 'Оставить заявку' button: "Заказать звонок",
}, },
{ {
title: 'Мы предлагаем разнообразные услуги', title: "Мы предлагаем разнообразные услуги",
content: content:
'Широкий спектр услуг для достойного прощания и помощи в трудный момент. У нас вы найдете все необходимое для организации похоронных церемоний.', "Широкий спектр услуг для достойного прощания и помощи в трудный момент. У нас вы найдете все необходимое для организации похоронных церемоний.",
image: '/home_slider/slide_1.jpg', image: "/home_slider/slide_1.jpg",
link: '', link: "/services",
button: 'Узнать больше' button: "Узнать больше",
}, },
{ {
title: 'Мы работаем со всеми кладбищами в области', title: "Мы работаем со всеми кладбищами в области",
content: content:
'Наши услуги доступны на всех кладбищах в этой области для вашего удобства. Мы готовы помочь вам в любом месте и в любое время.', "Наши услуги доступны на всех кладбищах в этой области для вашего удобства. Мы готовы помочь вам в любом месте и в любое время.",
image: '/home_slider/slide_2.png', image: "/home_slider/slide_2.png",
link: '', link: "/ourCemeteries",
button: 'Смотреть кладбища' button: "Смотреть кладбища",
}, },
{ {
title: 'Мы работаем давно и многое можем предложить', title: "Мы работаем давно и многое можем предложить",
content: content:
'Наша команда специалистов - залог профессионализма и заботы. Мы основываемся на принципах честности, сочувствия и уважения.', "Наша команда специалистов - залог профессионализма и заботы. Мы основываемся на принципах честности, сочувствия и уважения.",
image: '/home_slider/slide_3.jpg', image: "/home_slider/slide_3.jpg",
link: '', link: "/aboutUs",
button: 'Подробнее о нас' button: "Подробнее о нас",
} },
]) ]);
return ( const [modal, setModal] = useState(false)
<>
<Container> return (
<SliderContainer> <>
<Slider {...settings}> <Container>
{slides.map((item, index) => ( <SliderContainer>
<Item key={index}> <Slider {...settings}>
<img src={item.image} alt='' /> {slides.map((item, index) => (
<div className='content'> <Item key={index}>
<h2>{item.title}</h2> <img src={item.image} alt="" />
<h3>{item.title}</h3> <div className="content">
<h4>{item.content}</h4> <h2>{item.title}</h2>
<LandingButton>{item.button}</LandingButton> <h3>{item.title}</h3>
</div> <h4>{item.content}</h4>
</Item> {item.link !== "" ? (
))} <Link href={item.link}>
</Slider> <LandingButton>{item.button}</LandingButton>
</SliderContainer> </Link>
</Container> ) : (
<MobileSliderContainer> <LandingButton onClick={() => setModal(true)}>
<Slider {...settings}> {item.button}
{[...Array(2)].map((_, index) => ( </LandingButton>
<Item> )}
<img src='/image 1.png' alt='' /> </div>
<div className='content'> </Item>
<h2>Предоставление похоронных услуг в Челябинске.</h2> ))}
<h3>Предоставление похоронных услуг в Челябинске.</h3> </Slider>
<h4> </SliderContainer>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed </Container>
do eiusmod tempor incididunt ut labore et dolore magna aliqua. <MobileSliderContainer>
</h4> <Slider {...settings}>
<LandingButton>Подробнее о нас</LandingButton> {slides.map((item, index) => (
</div> <Item key={index}>
</Item> <img src={item.image} alt="" />
))} <div className="content">
</Slider> <h2>{item.title}</h2>
</MobileSliderContainer> <h3>{item.title}</h3>
</> <h4>{item.content}</h4>
) {item.link !== "" ? (
<Link href={item.link}>
<LandingButton>{item.button}</LandingButton>
</Link>
) : (
<LandingButton onClick={() => setModal(true)}>
{item.button}
</LandingButton>
)}
</div>
</Item>
))}
</Slider>
</MobileSliderContainer>
<Modal modal={modal} setModal={setModal}>
<AddApplicationForm setModal={setModal} />
</Modal>
</>
);
} }

View File

@ -70,37 +70,17 @@ const MapContainer = styled.div`
export default function OurCemetery({}: Props) { export default function OurCemetery({}: Props) {
return ( return (
<MapContainer> <MapContainer>
<h1>Наши кладбища</h1> <h1>Наши кладбища</h1>
{/* <YMaps> <iframe
<Map src="https://yandex.ru/map-widget/v1/?um=constructor%3Aa53366eeae5cb98c21ef9f499da6647e293da5152591b651ff9474f6215833a0&amp;source=constructor"
className='map' width="100%"
defaultState={{ height="450"
center: [55.159897, 61.402554], ></iframe>
zoom: 6 <div className="content">
}} <h3>Наши Кладбища</h3>
> <p>Мы работаем по всей области</p>
<Circle </div>
geometry={[[55.159897, 61.402554], 10000]} </MapContainer>
options={{ );
draggable: true,
fillColor: '#DB709377',
strokeColor: '#990066',
strokeOpacity: 0.8,
strokeWidth: 5
}}
/>
</Map>
</YMaps> */}
<iframe
src='https://yandex.ru/map-widget/v1/?um=constructor%3Aa53366eeae5cb98c21ef9f499da6647e293da5152591b651ff9474f6215833a0&amp;source=constructor'
width='100%'
height='450'
></iframe>
<div className='content'>
<h3>Наши Кладбища</h3>
<p>Мы работаем по всей облачти</p>
</div>
</MapContainer>
)
} }

View File

@ -1,102 +1,106 @@
'use client' "use client";
import { Container } from '@/app/GlobalStyles' import { Container } from "@/app/GlobalStyles";
import MainButton from '@/components/UI/button/MainButton' import MainButton from "@/components/UI/button/MainButton";
import ProductService from '@/services/product/productServeces' import ProductService from "@/services/product/productServeces";
import { useEffect, useState } from 'react' import { useEffect, useState } from "react";
import styled from 'styled-components' import styled from "styled-components";
import ServiceItem from './ServiceItem' import ServiceItem from "./ServiceItem";
import Loader from '@/components/UI/loader/Loader' import Loader from "@/components/UI/loader/Loader";
type Props = {} type Props = {};
const ServicesContainer = styled.div` const ServicesContainer = styled.div`
display: flex; display: flex;
align-items: center; align-items: center;
flex-direction: column; flex-direction: column;
margin: 50px 0; margin: 50px 0;
gap: 50px; gap: 50px;
` `;
const List = styled.div` const List = styled.div`
display: grid; display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr 1fr;
justify-items: center; justify-items: center;
gap: 30px; gap: 30px;
${(props) => props.theme.mediaQueries.tabletLandscape} { ${(props) => props.theme.mediaQueries.tabletLandscape} {
grid-template-columns: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr;
} }
${(props) => props.theme.mediaQueries.tabletPortrait} { ${(props) => props.theme.mediaQueries.tabletPortrait} {
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
} }
${(props) => props.theme.mediaQueries.mobile} { ${(props) => props.theme.mediaQueries.mobile} {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
` `;
const MessageContainer = styled.div` const MessageContainer = styled.div`
position: absolute; position: absolute;
top: 50%; top: 50%;
left: 50%; left: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
padding: 20px; padding: 20px;
text-align: center; text-align: center;
${(props) => props.theme.mediaQueries.tabletPortrait} { ${(props) => props.theme.mediaQueries.tabletPortrait} {
position: relative; position: relative;
padding: 20px; padding: 20px;
margin-top: 30px; margin-top: 30px;
} }
` `;
export default function Services({}: Props) { export default function Services({}: Props) {
const [services, setServices] = useState([]) const [services, setServices] = useState([]);
const [loadingState, setLoadingState] = useState(true) const [loadingState, setLoadingState] = useState(true);
const [errorState, setErrorState] = useState(false) const [errorState, setErrorState] = useState(false);
const getServices = async () => { const getServices = async () => {
try { try {
const response = await ProductService.get('') const response = await ProductService.get("");
setServices(response.data.Data) if (response.status === 200) {
} catch (error) { setServices(response.data.Data);
setErrorState(true) } else {
} setErrorState(false);
setLoadingState(false) }
} } catch (error) {
setErrorState(true);
}
setLoadingState(false);
};
useEffect(() => { useEffect(() => {
getServices() getServices();
}, []) }, []);
return ( return (
<Container> <Container>
<ServicesContainer> <ServicesContainer>
<h1>Наши услуги</h1> <h1>Наши услуги</h1>
{loadingState ? ( {loadingState ? (
<> <>
<MessageContainer> <MessageContainer>
<Loader /> <Loader />
</MessageContainer> </MessageContainer>
</> </>
) : errorState ? ( ) : errorState ? (
<MessageContainer> <MessageContainer>
<h3>Ошибка, не удалось получить услуги, сервер не доступен.</h3> <h3>Ошибка, не удалось получить услуги, сервер не доступен.</h3>
</MessageContainer> </MessageContainer>
) : services.length === 0 ? ( ) : services.length === 0 ? (
<MessageContainer> <MessageContainer>
<h3>Услуг пока нет</h3> <h3>Услуг пока нет</h3>
</MessageContainer> </MessageContainer>
) : ( ) : (
<List> <List>
{services.map((item, index) => ( {services.map((item, index) => (
<ServiceItem item={item} key={index} /> <ServiceItem item={item} key={index} />
))} ))}
</List> </List>
)} )}
</ServicesContainer> </ServicesContainer>
</Container> </Container>
) );
} }