diff --git a/README.md b/README.md index 811f628..14d1b56 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ npm run dev ### Футер витрины (опционально) -В `client/.env` можно задать `VITE_STORE_EMAIL`, `VITE_STORE_PHONE`, `VITE_STORE_SOCIAL_NOTE` для блока контактов в подвале. +В `client/.env` можно задать `VITE_STORE_EMAIL`, `VITE_STORE_PHONE`, `VITE_STORE_SOCIAL_NOTE` для блока контактов в подвале. Для страницы «Политика конфиденциальности» задайте **`VITE_PUBLIC_SITE_URL`** (например `https://example.com`, без завершающего `/`) — иначе в dev подставится текущий origin; на проде лучше указать явно перед `npm run build`. ## API (кратко) diff --git a/client/src/app/App.tsx b/client/src/app/App.tsx index 1da7e99..bdbadb9 100644 --- a/client/src/app/App.tsx +++ b/client/src/app/App.tsx @@ -9,6 +9,7 @@ import { CheckoutPage } from '@/pages/checkout' import { HomePage } from '@/pages/home' import { InfoPage } from '@/pages/info' import { MeLayoutPage } from '@/pages/me' +import { PrivacyPolicyPage } from '@/pages/privacy-policy' import { ProductPage } from '@/pages/product' export function App() { @@ -25,6 +26,7 @@ export function App() { } /> } /> } /> + } /> } /> } /> } /> diff --git a/client/src/app/layout/MainLayout.tsx b/client/src/app/layout/MainLayout.tsx index b2e3185..439f8a0 100644 --- a/client/src/app/layout/MainLayout.tsx +++ b/client/src/app/layout/MainLayout.tsx @@ -42,10 +42,7 @@ export function MainLayout({ children }: PropsWithChildren) { Каталог - Изделия ручной работы: вещь с характером и вниманием к деталям. - - - Как заказать: добавьте позиции в корзину и оформите доставку или самовывоз на чек-ауте. + Изделия ручной работы: вещи с характером и вниманием к деталям. @@ -63,9 +60,9 @@ export function MainLayout({ children }: PropsWithChildren) { О нас - - Доставка и самовывоз: уточняются при оформлении заказа; по вопросам — контакты ниже. - + + Политика конфиденциальности + diff --git a/client/src/entities/product/ui/ProductCard.tsx b/client/src/entities/product/ui/ProductCard.tsx index b4777f3..f15ced1 100644 --- a/client/src/entities/product/ui/ProductCard.tsx +++ b/client/src/entities/product/ui/ProductCard.tsx @@ -6,7 +6,6 @@ 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 Rating from '@mui/material/Rating' import Stack from '@mui/material/Stack' import Typography from '@mui/material/Typography' import { Link as RouterLink } from 'react-router-dom' @@ -14,7 +13,6 @@ import { Swiper, SwiperSlide } from 'swiper/react' import 'swiper/css' import type { Product } from '@/entities/product/model/types' import { formatPriceRub } from '@/shared/lib/format-price' -import { reviewsCountRu } from '@/shared/lib/reviews-count-ru' import type { Swiper as SwiperType } from 'swiper/types' type Props = { product: Product; mediaHeight?: number; actions?: ReactNode } @@ -160,38 +158,6 @@ export function ProductCard({ product, mediaHeight = 200, actions }: Props) { {formatPriceRub(product.priceCents)} - {product.reviewsSummary && product.reviewsSummary.approvedReviewCount > 0 && ( - - - - - {reviewsCountRu(product.reviewsSummary.approvedReviewCount)} - - - {product.reviewsSummary.latestApprovedText ? ( - - «{product.reviewsSummary.latestApprovedText}» - - ) : null} - - )} {actions} diff --git a/client/src/pages/me/ui/sections/MessagesPage.tsx b/client/src/pages/me/ui/sections/MessagesPage.tsx index 541c422..a2b74ef 100644 --- a/client/src/pages/me/ui/sections/MessagesPage.tsx +++ b/client/src/pages/me/ui/sections/MessagesPage.tsx @@ -16,8 +16,8 @@ import { fetchMyConversations, markOrderMessagesRead } from '@/entities/user/api import { orderStatusLabelRu } from '@/shared/lib/order-status-labels' import { ChatMessageBubble } from '@/shared/ui/ChatMessageBubble' import { OrderMessageBody } from '@/shared/ui/OrderMessageBody' -import { RichTextMessageEditor } from '@/shared/ui/RichTextMessageEditor' import { RichTextMessageContent } from '@/shared/ui/RichTextMessageContent' +import { RichTextMessageEditor } from '@/shared/ui/RichTextMessageEditor' export function MessagesPage() { const qc = useQueryClient() diff --git a/client/src/pages/privacy-policy/content/privacy-policy.template.txt b/client/src/pages/privacy-policy/content/privacy-policy.template.txt new file mode 100644 index 0000000..0762015 --- /dev/null +++ b/client/src/pages/privacy-policy/content/privacy-policy.template.txt @@ -0,0 +1,106 @@ +Политика в отношении обработки персональных данных +1. Общие положения +Настоящая политика обработки персональных данных составлена в соответствии с требованиями Федерального закона от 27.07.2006. №152-ФЗ «О персональных данных» и определяет порядок обработки персональных данных и меры по обеспечению безопасности персональных данных, предпринимаемые индивидуальным предпринимателем Новоселовой Наталией Владимировной (далее – Оператор). + +1.1. Оператор ставит своей важнейшей целью и условием осуществления своей деятельности соблюдение прав и свобод человека и гражданина при обработке его персональных данных, в том числе защиты прав на неприкосновенность частной жизни, личную и семейную тайну. + +1.2. Настоящая политика Оператора в отношении обработки персональных данных (далее – Политика) применяется ко всей информации, которую Оператор может получить о посетителях веб-сайта {{SITE_URL}}. Оператор не контролирует и не несет ответственности за сайты третьих лиц, на которые Пользователь может перейти по ссылкам, доступным на {{SITE_URL}}. + +2. Основные понятия, используемые в Политике +2.1. Автоматизированная обработка персональных данных – обработка персональных данных с помощью средств вычислительной техники; + +2.2. Блокирование персональных данных – временное прекращение обработки персональных данных (за исключением случаев, если обработка необходима для уточнения персональных данных); + +2.3. Веб-сайт – совокупность графических и информационных материалов, а также программ для ЭВМ и баз данных, обеспечивающих их доступность в сети интернет по сетевому адресу {{SITE_URL}}; + +2.4. Информационная система персональных данных — совокупность содержащихся в базах данных персональных данных, и обеспечивающих их обработку информационных технологий и технических средств; + +2.5. Обезличивание персональных данных — действия, в результате которых невозможно определить без использования дополнительной информации принадлежность персональных данных конкретному Пользователю или иному субъекту персональных данных; + +2.6. Обработка персональных данных – любое действие (операция) или совокупность действий (операций), совершаемых с использованием средств автоматизации или без использования таких средств с персональными данными, включая сбор, запись, систематизацию, накопление, хранение, уточнение (обновление, изменение), извлечение, использование, передачу (распространение, предоставление, доступ), обезличивание, блокирование, удаление, уничтожение персональных данных; Оператор осуществляет обработку данных пользователя до момента подачи им заявления на отзыв согласия на обработку персональных данных + +2.7. Оператор – Администрация сайта, индивидуальный предприниматель Индивидуальный предприниматель Новоселова Наталия Владимировна + +ИНН 402900832341 + +ОГРНИП 305402922700051 + +Адрес: 248000, Россия, г. Калуга, ул. Никитина, д. 12А + +2.8. Персональные данные – любая информация, относящаяся прямо или косвенно к определенному или определяемому Пользователю веб-сайта {{SITE_URL}}; + +2.9. Пользователь – любой посетитель веб-сайта {{SITE_URL}}; + +2.10. Предоставление персональных данных – действия, направленные на раскрытие персональных данных определенному лицу или определенному кругу лиц; + +2.11. Распространение персональных данных – любые действия, направленные на раскрытие персональных данных неопределенному кругу лиц передача персональных данных или на ознакомление с персональными данными неограниченного круга лиц, в том числе обнародование персональных данных в средствах массовой информации, размещение в информационно-телекоммуникационных сетях или предоставление доступа к персональным данным каким-либо иным способом; + +2.12. Уничтожение персональных данных – любые действия, в результате которых персональные данные уничтожаются безвозвратно с невозможностью дальнейшего восстановления содержания персональных данных в информационной системе персональных данных и (или) уничтожаются материальные носители персональных данных. + +3. Оператор может обрабатывать следующие персональные данные Пользователя +3.1. Персональная информация, которую Пользователь предоставляет о себе самостоятельно при регистрации (создании учетной записи) или в процессе использования Сайта и его сервисов, включая персональные данные Пользователя. Обязательная для предоставления Сервисов информация помечена специальным образом. Иная информация предоставляется Пользователем на его усмотрение. + +3.2. Данные, которые автоматически передаются сервисам Сайта в процессе их использования с помощью установленного на устройстве Пользователя программного обеспечения (а именно программ Yandex.Metrika (предоставляется ООО “Яндекс”), в том числе IP-адрес, данные файлов cookie, информация о браузере Пользователя (или иной программе, с помощью которой осуществляется доступ к сервисам), технические характеристики оборудования и программного обеспечения, используемых Пользователем, дата и время доступа к сервисам, адреса запрашиваемых страниц, реферер (адрес предыдущей страницы) и иная подобная информация. + +4. Категории собираемых персональных данных и цели их обработки +4.1. Сайт собирает и хранит только ту персональную информацию, которая необходима для предоставления информации об услугах или исполнения соглашений и договоров с Пользователем, за исключением случаев, когда законодательством предусмотрено обязательное хранение персональной информации в течение определенного законом срока. + +4.2. Персональную информацию Пользователя Сайт обрабатывает в следующих целях: + +4.2.1. Установления с Пользователем обратной связи, включая направление уведомлений, запросов, касающихся использования Сайта, оказания услуг, обработку запросов и заявок от Пользователя. +Для достижения данной цели Оператор собирает и обрабатывает следующие категории персональных данных: имя, адрес электронной почты, контактный номер телефона. К субъектам, персональные данные которых обрабатываются для указанной цели, относятся: физические лица, заинтересованные в получении товаров/работ/услуг от Оператора, физические лица, состоящие в гражданско-правовых и иных договорных отношениях с Оператором, представители юридических лиц - контрагентов Оператора либо потенциально заинтересованных в установлении с ним гражданско-правовых отношений. Указанные персональные данные обрабатываются смешанным способом. Срок обработки и хранения персональных данных, собираемых в соответствии с настоящим пунктом, составляет не более 7 лет с момента получения последней заявки либо иного обращения от Пользователя. При получении Оператором заявления субъекта персональных данных с требованием о прекращении обработки персональных данных Оператор прекращает обработку персональных данных досрочно, а именно в срок, не превышающий десяти рабочих дней с даты получения соответствующего требования. Указанный срок может быть продлен, но не более чем на пять рабочих дней в случае направления оператором в адрес субъекта персональных данных мотивированного уведомления с указанием причин продления срока предоставления запрашиваемой информации. + +4.2.2. Идентификации Пользователя, зарегистрированного на Сайте, для формирования и исполнения персонализированных предложений и соглашений, а также предоставление Пользователю доступа к персонализированным ресурсам Сайта. + + Для достижения данной цели Оператор собирает и обрабатывает следующие категории персональных данных: имя, адрес электронной почты, контактный номер телефона, пользовательский ID, IP-адрес. К субъектам, персональные данные которых обрабатываются для указанной цели, относятся: физические лица, заинтересованные в получении товаров/работ/услуг от Оператора, физические лица, состоящие в гражданско-правовых и иных договорных отношениях с Оператором, представители юридических лиц - контрагентов Оператора либо потенциально заинтересованных в установлении с ним гражданско-правовых отношений. Указанные персональные данные обрабатываются смешанным способом. Срок обработки и хранения персональных данных, собираемых в соответствии с настоящим пунктом, составляет не более 7 лет с момента получения последней заявки либо иного обращения от Пользователя. При получении Оператором заявления субъекта персональных данных с требованием о прекращении обработки персональных данных Оператор прекращает обработку персональных данных досрочно, а именно в срок, не превышающий десяти рабочих дней с даты получения соответствующего требования. Указанный срок может быть продлен, но не более чем на пять рабочих дней в случае направления оператором в адрес субъекта персональных данных мотивированного уведомления с указанием причин продления срока предоставления запрашиваемой информации. + +4.2.3. Предоставления Пользователю эффективной клиентской и технической поддержки. + Для достижения данной цели Оператор собирает и обрабатывает следующие категории персональных данных: имя, адрес электронной почты, контактный номер телефона, пользовательский ID, IP-адрес. К субъектам, персональные данные которых обрабатываются для указанной цели, относятся: физические лица, заинтересованные в получении товаров/работ/услуг от Оператора, физические лица, состоящие в гражданско-правовых и иных договорных отношениях с Оператором, представители юридических лиц - контрагентов Оператора либо потенциально заинтересованных в установлении с ним гражданско-правовых отношений. Указанные персональные данные обрабатываются смешанным способом. Срок обработки и хранения персональных данных, собираемых в соответствии с настоящим пунктом составляет не более 7 лет с момента получения последней заявки либо иного обращения от Пользователя. При получении Оператором заявления субъекта персональных данных с требованием о прекращении обработки персональных данных Оператор прекращает обработку персональных данных досрочно, а именно в срок, не превышающий десяти рабочих дней с даты получения соответствующего требования. Указанный срок может быть продлен, но не более чем на пять рабочих дней в случае направления оператором в адрес субъекта персональных данных мотивированного уведомления с указанием причин продления срока предоставления запрашиваемой информации. +4.3. Обезличенные данные Пользователей, собираемые с помощью сервисов интернет-статистики (а именно с помощью программ Yandex.Metrika (предоставляется ООО “Яндекс”), служат для сбора информации о действиях Пользователей на сайте, улучшения качества сайта и его содержания. + +Для достижения данной цели Оператор собирает и обрабатывает следующие категории обезличенных данных: IP-адрес, данные файлов cookie, информация о браузере Пользователя (или иной программе, с помощью которой осуществляется доступ к сервисам), технические характеристики оборудования и программного обеспечения, используемых Пользователем, дата и время доступа к сервисам, адреса запрашиваемых страниц, реферер (адрес предыдущей страницы). Указанные данные обрабатываются машинным способом. Срок обработки и хранения обезличенных данных, собираемых в соответствии с настоящим пунктом, составляет не более 3 лет с момента последнего посещения Пользователем Сайта. + +5. Правовые основания обработки персональных данных +5.1. Оператор обрабатывает персональные данные Пользователя только в случае их заполнения и/или отправки Пользователем самостоятельно через специальные формы, расположенные на сайте {{SITE_URL}}. Заполняя соответствующие формы и/или отправляя свои персональные данные Оператору, Пользователь выражает свое согласие с данной Политикой. + +5.2. Оператор обрабатывает обезличенные данные о Пользователе в случае, если это разрешено в настройках браузера Пользователя (включено сохранение файлов «cookie» и использование технологии JavaScript). + +5.3. Обработка персональных данных осуществляется с согласия субъекта персональных данных на обработку его персональных данных; + + + 5.4 Обработка персональных данных необходима для исполнения договора, стороной которого либо выгодоприобретателем или поручителем по которому является субъект персональных данных, а также для заключения договора по инициативе субъекта персональных данных или договора, по которому субъект персональных данных будет являться выгодоприобретателем. + +6. Порядок сбора, хранения, передачи и других видов обработки персональных данных +6.1. Персональная информация Пользователей хранится на территории Российской Федерации с соблюдением всех требований, установленных действующим российским законодательством. + +6.2. В отношении персональной информации Пользователя сохраняется ее конфиденциальность, кроме случаев добровольного предоставления Пользователем информации о себе для общего доступа неограниченному кругу лиц (например, публикация отзывов). В таких случаях Пользователь соглашается с тем, что определенная часть его персональной информации становится общедоступной. + +6.3. Сайт вправе передать персональную информацию Пользователя третьим лицам в следующих случаях: + +6.3.1. Пользователь выразил согласие на такие действия и был проинформирован, какому конкретному третьему лицу и какой объем персональных данных будет передан. +6.3.2. Передача необходима для использования Пользователем определенного сервиса либо для исполнения определенного соглашения или договора с Пользователем. +6.3.3. Передача предусмотрена российским или иным применимым законодательством в рамках установленной законодательством процедуры. +6.4. Обработка персональных данных Пользователя осуществляется любым законным способом, в том числе в информационных системах персональных данных с использованием средств автоматизации или без использования таких средств. Обработка персональных данных Пользователей осуществляется в соответствии с Федеральным законом от 27.07.2006 N 152-ФЗ "О персональных данных". Срок обработки и хранения персональных данных, собираемых Оператором на сайте составляет не более 7 лет с момента получения последней заявки либо иного обращения от Пользователя. При получении Оператором заявления субъекта персональных данных с требованием о прекращении обработки персональных данных Оператор прекращает обработку персональных данных в срок, не превышающий десяти рабочих дней с даты получения соответствующего требования, за исключением случаев, предусмотренных пунктами 2 - 11 части 1 статьи 6 Федерального закона “О персональных данных”. Указанный срок может быть продлен, но не более чем на пять рабочих дней в случае направления оператором в адрес субъекта персональных данных мотивированного уведомления с указанием причин продления срока предоставления запрашиваемой информации. + +6.5. При утрате или разглашении персональных данных Администрация Сайта информирует Пользователя об утрате или разглашении персональных данных. + +6.6. Администрация Сайта принимает необходимые организационные и технические меры для защиты персональной информации Пользователя от неправомерного или случайного доступа, уничтожения, изменения, блокирования, копирования, распространения, а также от иных неправомерных действий третьих лиц. + +6.7. Администрация Сайта совместно с Пользователем принимает все необходимые меры по предотвращению убытков или иных отрицательных последствий, вызванных утратой или разглашением персональных данных Пользователя. + +7. Ответственность +7.1. Администрация Сайта, не исполнившая свои обязательства, несет ответственность за убытки, понесенные Пользователем в связи с неправомерным использованием персональных данных, в соответствии с законодательством Российской Федерации. + +7.2. В случае утраты или разглашения конфиденциальной информации Администрация Сайта не несет ответственности, если данная конфиденциальная информация: + +7.2.1. Стала публичным достоянием до ее утраты или разглашения. +7.2.2. Была получена от третьей стороны до момента ее получения Администрацией Сайта. +7.2.3. Была разглашена с согласия Пользователя. +8. Заключительные положения: +8.1. Администрация Сайта вправе вносить изменения в настоящую Политику конфиденциальности без согласия Пользователя. + +8.2. Новая Политика конфиденциальности вступает в силу с момента ее размещения на Сайте, если иное не предусмотрено новой редакцией Политики конфиденциальности. + +8.3. Все предложения или вопросы по настоящей Политике конфиденциальности следует сообщать на электронный адрес {{STORE_EMAIL}} + +8.4. Действующая Политика конфиденциальности размещена на странице по адресу: {{SITE_URL}}/privacy \ No newline at end of file diff --git a/client/src/pages/privacy-policy/index.ts b/client/src/pages/privacy-policy/index.ts new file mode 100644 index 0000000..a8a8bef --- /dev/null +++ b/client/src/pages/privacy-policy/index.ts @@ -0,0 +1 @@ +export { PrivacyPolicyPage } from './ui/PrivacyPolicyPage' diff --git a/client/src/pages/privacy-policy/ui/PrivacyPolicyPage.tsx b/client/src/pages/privacy-policy/ui/PrivacyPolicyPage.tsx new file mode 100644 index 0000000..ef52da4 --- /dev/null +++ b/client/src/pages/privacy-policy/ui/PrivacyPolicyPage.tsx @@ -0,0 +1,22 @@ +import Box from '@mui/material/Box' +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' + +export function PrivacyPolicyPage() { + const body = template.replaceAll('{{SITE_URL}}', STORE_PUBLIC_SITE_URL).replaceAll('{{STORE_EMAIL}}', STORE_EMAIL) + + return ( + + + Политика конфиденциальности + + + Политика в отношении обработки персональных данных. + + + {body} + + + ) +} diff --git a/client/src/shared/config/index.ts b/client/src/shared/config/index.ts index 8230b1a..2b88a50 100644 --- a/client/src/shared/config/index.ts +++ b/client/src/shared/config/index.ts @@ -3,6 +3,15 @@ export const apiBaseURL = import.meta.env.VITE_API_URL ?? '/api' export const STORE_NAME = 'Любимый Креатив' +/** Канонический URL сайта для политики конфиденциальности и т.п.; в dev без env — `window.location.origin`. */ +export const STORE_PUBLIC_SITE_URL = (() => { + const raw = + typeof import.meta.env.VITE_PUBLIC_SITE_URL === 'string' ? import.meta.env.VITE_PUBLIC_SITE_URL.trim() : '' + if (raw) return raw.replace(/\/$/, '') + if (typeof window !== 'undefined') return window.location.origin + return '' +})() + /** Демо-контакты для футера; при необходимости задайте через VITE_* в `.env`. */ export const STORE_EMAIL = import.meta.env.VITE_STORE_EMAIL ?? 'hello@example.com' export const STORE_PHONE = import.meta.env.VITE_STORE_PHONE ?? '+7 (900) 000-00-00' diff --git a/client/src/vite-env.d.ts b/client/src/vite-env.d.ts index 45624e3..327f37b 100644 --- a/client/src/vite-env.d.ts +++ b/client/src/vite-env.d.ts @@ -2,6 +2,8 @@ interface ImportMetaEnv { readonly VITE_API_URL?: string + /** Канонический URL витрины для юр. текстов (политика конфиденциальности). Прод: задать перед сборкой. */ + readonly VITE_PUBLIC_SITE_URL?: string readonly VITE_STORE_EMAIL?: string readonly VITE_STORE_PHONE?: string readonly VITE_STORE_SOCIAL_NOTE?: string @@ -13,3 +15,8 @@ interface ImportMeta { declare module 'swiper/css' declare module 'swiper/css/navigation' + +declare module '*?raw' { + const src: string + export default src +}