diff --git a/client/src/app/layout/MainLayout.tsx b/client/src/app/layout/MainLayout.tsx index 439f8a0..95e2bdd 100644 --- a/client/src/app/layout/MainLayout.tsx +++ b/client/src/app/layout/MainLayout.tsx @@ -41,6 +41,9 @@ export function MainLayout({ children }: PropsWithChildren) { Каталог + + Политика конфиденциальности + Изделия ручной работы: вещи с характером и вниманием к деталям. @@ -60,9 +63,6 @@ export function MainLayout({ children }: PropsWithChildren) { О нас - - Политика конфиденциальности - diff --git a/client/src/entities/product/ui/ProductCard.tsx b/client/src/entities/product/ui/ProductCard.tsx index 6752d95..ff08d76 100644 --- a/client/src/entities/product/ui/ProductCard.tsx +++ b/client/src/entities/product/ui/ProductCard.tsx @@ -1,14 +1,13 @@ import type { ReactNode } from 'react' -import { useMemo, useRef } from 'react' +import { useCallback, useMemo, useRef } from 'react' import Box from '@mui/material/Box' import Card from '@mui/material/Card' import CardContent from '@mui/material/CardContent' import CardMedia from '@mui/material/CardMedia' import Chip from '@mui/material/Chip' -import Link from '@mui/material/Link' import Stack from '@mui/material/Stack' import Typography from '@mui/material/Typography' -import { Link as RouterLink } from 'react-router-dom' +import { useNavigate } from 'react-router-dom' import { Swiper, SwiperSlide } from 'swiper/react' import 'swiper/css' import type { Product } from '@/entities/product/model/types' @@ -18,6 +17,7 @@ import type { Swiper as SwiperType } from 'swiper/types' type Props = { product: Product; mediaHeight?: number; actions?: ReactNode } export function ProductCard({ product, mediaHeight = 200, actions }: Props) { + const navigate = useNavigate() const swiperRef = useRef(null) const imageUrls = useMemo(() => { const fromImages = (product.images ?? []) @@ -40,6 +40,10 @@ export function ProductCard({ product, mediaHeight = 200, actions }: Props) { swiperRef.current.slideTo(idx, 0) } + const goToProduct = useCallback(() => { + navigate(`/products/${product.id}`) + }, [navigate, product.id]) + const stockLabel = product.inStock && product.quantity === 0 ? { label: 'Нет в наличии', color: 'default' as const } @@ -49,7 +53,9 @@ export function ProductCard({ product, mediaHeight = 200, actions }: Props) { return ( - + {imageUrls.length ? ( )} - + @@ -159,15 +160,13 @@ export function ProductCard({ product, mediaHeight = 200, actions }: Props) { {product.title} diff --git a/client/src/pages/privacy-policy/ui/PrivacyPolicyPage.tsx b/client/src/pages/privacy-policy/ui/PrivacyPolicyPage.tsx index ef52da4..00bd227 100644 --- a/client/src/pages/privacy-policy/ui/PrivacyPolicyPage.tsx +++ b/client/src/pages/privacy-policy/ui/PrivacyPolicyPage.tsx @@ -1,22 +1,146 @@ import Box from '@mui/material/Box' +import Paper from '@mui/material/Paper' import Typography from '@mui/material/Typography' -import { STORE_EMAIL, STORE_PUBLIC_SITE_URL } from '@/shared/config' -import template from '../content/privacy-policy.template.txt?raw' +import { STORE_EMAIL } from '@/shared/config' + +const OP_NAME = 'Индивидуальный предприниматель Новоселова Наталия Владимировна' +const OP_INN = '402900832341' +const OP_OGRN = '305402922700051' +const OP_ADDR = '248000, Россия, г. Калуга, ул. Никитина, д. 12А' +const SITE_URL = window.location.origin + +const sections = [ + { + title: '1. Общие положения', + items: [ + `1.1. Настоящая Политика конфиденциальности (далее — Политика) действует в отношении всех персональных данных, которые ${OP_NAME} (далее — Оператор) может получить от Пользователя во время использования сайта ${SITE_URL}.`, + `1.2. ИНН Оператора: ${OP_INN}`, + `1.3. ОГРН/ОГРНИП Оператора: ${OP_OGRN}`, + `1.4. Адрес Оператора: ${OP_ADDR}`, + `1.5. Контактный email: ${STORE_EMAIL}`, + ], + }, + { + title: '2. Персональные данные, которые обрабатывает Оператор', + items: [ + '2.1. Оператор обрабатывает следующие персональные данные Пользователей:', + '— фамилия, имя, отчество;', + '— адрес электронной почты;', + '— номер телефона;', + '— данные файлов cookie;', + '— данные о действиях на сайте (аналитика);', + '— адрес доставки и геолокационные координаты.', + ], + }, + { + title: '3. Цели обработки персональных данных', + items: [ + '3.1. Оператор обрабатывает персональные данные в следующих целях:', + '— идентификация Пользователя;', + '— оказание услуг / продажа товаров;', + '— направление уведомлений и информационных сообщений;', + '— улучшение качества работы сайта;', + '— построение персонализированных предложений и рекомендаций.', + ], + }, + { + title: '4. Правовые основания обработки', + items: [ + '4.1. Оператор обрабатывает персональные данные на основании:', + '— Федерального закона от 27.07.2006 № 152-ФЗ «О персональных данных»;', + '— согласия субъекта персональных данных;', + '— договора, стороной которого является субъект;', + '— договорных отношений с контрагентами и исполнителями услуг (доставка, платёжные сервисы).', + ], + }, + { + title: '5. Порядок и условия обработки', + items: [ + '5.1. Обработка осуществляется путём сбора, записи, систематизации, накопления, хранения, уточнения, извлечения, использования, передачи, обезличивания, блокирования, удаления и уничтожения персональных данных.', + '5.2. Обработка осуществляется автоматизированным и неавтоматизированным способами.', + '5.3. Срок хранения персональных данных: не более 7 лет с момента последнего обращения Пользователя либо до момента отзыва согласия на обработку.', + ], + }, + { + title: '6. Передача персональных данных третьим лицам', + items: [ + '6.1. Оператор может передать персональные данные третьим лицам в следующих случаях:', + '— с согласия субъекта;', + '— по требованию законодательства РФ;', + '— для выполнения договорных обязательств (перечень третьих лиц): службы доставки, платёжные агрегаторы, сервисы аналитики (Яндекс.Метрика).', + ], + }, + { + title: '7. Права субъекта персональных данных', + items: [ + '7.1. Пользователь имеет право на доступ к своим данным, их уточнение, блокирование или уничтожение.', + '7.2. Для реализации своих прав Пользователь может направить запрос на электронный адрес: ' + STORE_EMAIL, + ], + }, +] export function PrivacyPolicyPage() { - const body = template.replaceAll('{{SITE_URL}}', STORE_PUBLIC_SITE_URL).replaceAll('{{STORE_EMAIL}}', STORE_EMAIL) - return ( - - + + Политика конфиденциальности - + + Политика в отношении обработки персональных данных. - - {body} - + + + {sections.map((section) => ( + + + {section.title} + + + + {section.items.map((item, idx) => ( + + {item} + + ))} + + + ))} + ) }