@@ -1,3 +1,4 @@
+import { getContacts } from "@/src/shared/api/requests";
import RulesPageBlock from "@/src/shared/components/pages_components/rules_page/RulesPageBlock";
import FeedbackBlock from "@/src/shared/components/shared_components/FeedbackBlock/FeedbackBlock";
import Footer from "@/src/shared/components/shared_components/Footer/Footer";
@@ -7,7 +8,9 @@ import QuestionButton from "@/src/shared/components/shared_components/QuestionBu
import { contacts } from "@/src/shared/utils/staticMockData";
-export default function page() {
+export default async function page() {
+ const contacts = (await getContacts()).data
+
return (
@@ -18,7 +21,7 @@ export default function page() {
-
+
@@ -0,0 +1,44 @@
+'use client'; // обязательная директива для использования клиентских компонентов
+
+import { useEffect } from 'react';
+
+export default function Error({ error, reset }: {
+ error: Error & { digest?: string }
+ reset: () => void
+}) {
+ useEffect(() => {
+ // Сообщаем об ошибке в службу логирования, например, в Sentry
+ console.error(error);
+ }, [error]);
+
+ return (
+
+
+ 500
+
+
+
+
что-то пошло не так
+
Кажется, у нас что-то сломалось. Вы можете попробовать снова или вернуться на главную страницу.
+
+
+
{ reset() }} className="z-[1] block group w-full max-w-[335px] lg:max-w-[400px] mx-auto">
+
+
+ попробовать снова
+
+
+
+
+
+
+
+ вернуться на главную
+
+
+
+
+
+
+ );
+}
Binary files a/src/app/favicon.ico and b/src/app/favicon.ico differ
@@ -27,6 +27,14 @@ ol {
list-style-type: decimal;
}
+html {
+ scroll-behavior: smooth;
+}
+
+div {
+ scroll-margin-top: 40px;
+}
+
html,
body {
height: 100%;
@@ -4,7 +4,7 @@ import { nunitoSans } from '@/src/assets/fonts/fonts';
export const metadata: Metadata = {
title: "X-ESSENCE - шоурум-ателье",
- description: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Ex, vitae.",
+ description: "Индивидуальный пошив одежды любой сложности, от деловой одежды до роскошных вечерних костюмов,пошив малых партий для брендов и мероприятий, подгонка по фигуре и кастомизация",
};
export default function RootLayout({
@@ -14,8 +14,8 @@ export default function RootLayout({
}>) {
return (
-
- {children}
+
+ {children}
);
@@ -0,0 +1,42 @@
+import React from 'react'
+import QuestionButton from '../shared/components/shared_components/QuestionButton/QuestionButton'
+import UpperBlock from '../shared/components/shared_components/Header/UpperBlock'
+import Header from '../shared/components/shared_components/Header/Header'
+import Footer from '../shared/components/shared_components/Footer/Footer'
+import { getContacts } from '../shared/api/requests'
+
+export default async function notFound() {
+ const contacts = (await getContacts()).data
+
+ return (
+
+
+
+
+
+ 404
+
+
+
+
упс! кажется 404!
+
Кажется, такой страницы у нас нет. Либо вы могли перейти по не рабочей ссылке. Лучше всего нажать кнопочку ниже, и вернуться на главную страницу
+
+
+
+
+
+ вернуться на главную
+
+
+
+
+
+
+
+
+ )
+}
@@ -1,3 +1,5 @@
+import React from "react";
+
import Header from "@/src/shared/components/shared_components/Header/Header";
import UpperBlock from "@/src/shared/components/shared_components/Header/UpperBlock";
import WelcomeBlock from "@/src/shared/components/pages_components/main_page/WelcomeBlock";
@@ -6,32 +8,20 @@ import FeaturesBlock from "@/src/shared/components/pages_components/main_page/Fe
import ServicesBlock from "@/src/shared/components/pages_components/main_page/ServicesBlock";
import NewWayBlock from "@/src/shared/components/pages_components/main_page/NewWayBlock";
-import { contacts, products } from "@/src/shared/utils/staticMockData";
+import { products } from "@/src/shared/utils/staticMockData";
import ReadyImagesBlock from "@/src/shared/components/pages_components/main_page/ReadyImagesBlock";
import FaqBlock from "@/src/shared/components/shared_components/FaqBlock/FaqBlock";
import FeedbackBlock from "@/src/shared/components/shared_components/FeedbackBlock/FeedbackBlock";
import Footer from "@/src/shared/components/shared_components/Footer/Footer";
import QuestionButton from "@/src/shared/components/shared_components/QuestionButton/QuestionButton";
-import dynamic from 'next/dynamic';
-
-// const PortfolioBlock = dynamic(() => import('@/src/shared/components/pages_components/main_page/PortfolioBlock'), {
-// ssr: false, // Отключаем серверный рендеринг
-// });
-
-// const ReadyImagesBlock = dynamic(() => import('@/src/shared/components/pages_components/main_page/ReadyImagesBlock'), {
-// ssr: false, // Отключаем серверный рендеринг
-// });
+import { getContacts, getFaq, getPortfolio } from "../shared/api/requests";
-// const FaqBlock = dynamic(() => import('@/src/shared/components/shared_components/FaqBlock/FaqBlock'), {
-// ssr: false, // Отключаем серверный рендеринг
-// });
+export default async function Home() {
+ const contacts = (await getContacts()).data
+ const faqData = (await getFaq()).data
+ const portfolio = (await getPortfolio()).data
-// const FeedbackBlock = dynamic(() => import('@/src/shared/components/shared_components/FeedbackBlock/FeedbackBlock'), {
-// ssr: false, // Отключаем серверный рендеринг
-// });
-
-export default function Home() {
return (
<>
@@ -43,32 +33,17 @@ export default function Home() {
-
+
-
-
-
-
+
+
+
+
-
- {/*
-
-
-
-
-
-
-
-
-
-
-
-
*/}
-
>
);
}
@@ -0,0 +1,26 @@
+import axios from "axios"
+import { IContacts, IFaq, IFeedback, IPortfolioItem, IPriceListItem } from "../models/models"
+
+const DOMAIN = "http://91.222.237.164:8000"
+const url = `${DOMAIN}`
+
+
+export const getContacts = async () => {
+ return await axios.get
(url + "/tech/contacts/")
+}
+
+export const getProducts = async () => {
+ return await axios.get(url + "/products")
+}
+
+export const sendFeedback = async (data: IFeedback) => {
+ return await axios.post(url + "/orders/", data)
+}
+
+export const getFaq = async () => {
+ return await axios.get(url + "/tech/faq/")
+}
+
+export const getPortfolio = async () => {
+ return await axios.get(url + "/portfolio/")
+}
\ No newline at end of file
@@ -0,0 +1,112 @@
+'use client'
+
+import React from 'react'
+
+import ReCAPTCHA from "react-google-recaptcha";
+import InputMask from 'react-input-mask';
+import { useForm } from 'react-hook-form';
+import { yupResolver } from '@hookform/resolvers/yup';
+import * as yup from 'yup';
+import useWindowSize from "@/src/shared/utils/hooks/useWindowSize";
+import ThanksModal from "@/src/shared/components/shared_components/Modals/ThanksModal/ThanksModal"
+import { useRef, useState } from "react";
+import { IContacts, IFeedback } from "@/src/shared/models/models";
+import { sendFeedback } from '@/src/shared/api/requests';
+
+const schema = yup.object().shape({
+ name: yup.string().required('Введите имя'),
+ phone: yup.string().transform((value) => value.replace(/\D/g, '')).min(11, 'Неправильный формат номера телефона').required('Введите email'),
+ email: yup.string().email('Неправильный формат email').required('Введите email'),
+ comment: yup.string(),
+ captcha: yup.string().required()
+});
+
+export default function ContactsBlock({ contacts }: { contacts: IContacts }) {
+ const { register, handleSubmit, setValue, trigger, reset, formState: { errors, isValid } } = useForm({
+ resolver: yupResolver(schema),
+ mode: "onBlur"
+ });
+
+ const [isModalThanksOpened, setIsModalThanksOpened] = useState(false)
+ const recaptchaRef = useRef(null);
+
+ function onSubmit(data: any) {
+ console.log(data);
+
+ const dataToSend: IFeedback = {
+ name: data.name,
+ phonenumber: data.phone,
+ email: data.email,
+ comment: data.comment || ""
+ }
+
+ sendFeedback(dataToSend)
+ .then((res) => {
+ console.log(dataToSend);
+ setIsModalThanksOpened(true)
+ reset()
+ recaptchaRef.current?.reset();
+ }).catch((er) => {
+ // console.log(dataToSend);
+ })
+ }
+
+
+ return (
+
+
+
контакты и обратная связь
+
Если у Вас есть какие-либо вопросы или Вам нужна помощь, Вы можете связаться с нами.
+ Тел: +7 927 520 33 00 Мы доступны с 10 утра до 20 вечера.
+ Также Вы можете заполнить форму обратной связи ниже.
+ Ответ поступит на указанный e-mail.
+
+
+
+
+
+
+ отправить заявку
+
+
+
+
+ )
+}
@@ -1,13 +1,21 @@
-import { IProduct } from "@/src/shared/models/models"
+'use client'
+import { IContacts, IProduct } from "@/src/shared/models/models"
import ProductComponent from "../../shared_components/ProductComponent/ProductComponent"
+import { useState } from "react";
+import ModalFeedback from "../../shared_components/Modals/ModalFeedback/ModalFeedback";
+import Link from "next/link";
interface IProps {
- products: IProduct[]
+ products: IProduct[],
+ contacts: IContacts
}
-export default function NewWayBlock({ products }: IProps) {
+export default function NewWayBlock({ products, contacts }: IProps) {
+ const [isModalFeedbackOpened, setIsModalFeedbackOpened] = useState(false);
+
return (
+ {isModalFeedbackOpened &&
}
новый способ проявить себя
Наша главная цель - ваш идеальный образ, который будет говорить за себя. Тот имидж, который позволит не только привлечь больше внимания, но и придаст уверенности, где бы и с кем бы, вы не находились.
@@ -17,17 +25,20 @@ export default function NewWayBlock({ products }: IProps) {
key={item.id}
id={item.id}
title={item.title}
- desc={item.desc}
+ description={item.description}
period={item.period}
- price={item.price} />
+ price={item.price}
+ isModalFeedbackOpened={isModalFeedbackOpened}
+ setIsModalFeedbackOpened={setIsModalFeedbackOpened}
+ />
))}
-
+
весь прайс-лист
-
+
)
}
@@ -9,18 +9,24 @@ import '@/src/assets/styles/portfolioSliderStyles.css';
import PortfolioItem from '../../shared_components/PortfolioItem/PortfolioItem';
import { useState } from 'react';
import { portfolioItems } from '@/src/shared/utils/staticMockData';
-import ModalFeedback from '../../shared_components/Modals/ModalFeedback/ModalFeedback';
-import { IContacts } from '@/src/shared/models/models';
+import { IContacts, IPortfolioItem } from '@/src/shared/models/models';
import useWindowSize from '@/src/shared/utils/hooks/useWindowSize';
-interface IProps{
- contacts: IContacts
- }
+import dynamic from 'next/dynamic';
+const ModalFeedback = dynamic(() => import('@/src/shared/components/shared_components/Modals/ModalFeedback/ModalFeedback'));
-export default function PortfolioBlock({contacts}:IProps) {
+interface IProps {
+ contacts: IContacts,
+ portfolioItems: IPortfolioItem[]
+}
+
+export default function PortfolioBlock({ contacts, portfolioItems }: IProps) {
const [isModalFeedbackOpened, setIsModalFeedbackOpened] = useState(false);
const [hasPadding, setHasPadding] = useState(true); // Управляем padding только в начале
- const {height, width} = useWindowSize()
+ const { height, width } = useWindowSize()
+
+ console.log(portfolioItems);
+
// Убираем padding при любом изменении слайдов
const handleSlideChange = (swiper: SwiperClass) => {
@@ -38,7 +44,7 @@ export default function PortfolioBlock({contacts}:IProps) {
return (