This commit is contained in:
2026-06-19 12:43:29 +03:00
parent 990f7c8544
commit 663f6dc268
54 changed files with 2884 additions and 2207 deletions

View File

@@ -0,0 +1,154 @@
# Страница конвертера (`/converter`)
Покупка/конвертация валюты. Маршрут `ROUTES.CONVERTER` (`/converter`), **защищён**
`ProtectedRoute` (только для авторизованных) и обёрнут в `WalletLayout footer center`
(см. `app/providers/RouterProvider.tsx`).
## Главная идея
`ConverterPage`**тонкий роутер по типу аккаунта**. Сам по себе он почти ничего не
рендерит: показывает заглушку / спиннер и выбирает один из двух виджетов-конвертеров.
Вся логика и презентация живут в виджетах и нижних слоях (`features/*`, `shared`).
Это результат рефакторинга под FSD (`app → pages → widgets → features → entities →
shared`; нижние слои не импортируют верхние).
```
ConverterPage
├─ PURCHASE_ENABLED === false → заглушка «Покупка временно недоступна»
├─ useMe() ещё грузится → <Spinner/>
└─ по account_type:
├─ legal (юрлицо) → <LegalConverterSection/> (@widgets/legal-converter)
└─ individual (физлицо)→ <ConverterSection/> (@widgets/converter-page)
```
> ⚠️ Сейчас `PURCHASE_ENABLED = false` в `ConverterPage.tsx` — оба конвертера
> скрыты заглушкой. Поставьте `true`, чтобы вернуть рабочий контент.
Развилка по аккаунту: `isLegal = data.account_type !== 'individual'`. Тот же критерий,
что `isLegalEntity()` в `features/auth/lib/profile.ts` (профиль). Здесь оставлен инлайн,
т.к. `ConverterPage` не импортирует профильные хелперы; при желании можно свести к
одному источнику.
## Карта файлов
```
pages/converter/
ui/ConverterPage.tsx ← роутер по account_type (заглушка/спиннер/виджет)
ui/ConverterPage.module.css ← стили только заглушки
index.ts ← export { ConverterPage }
README.md ← этот файл
widgets/legal-converter/ ← ВЕТКА ЮРЛИЦ: форма B2B-заявки
model/useLegalConverterForm.ts← вся логика формы (стейт, расчёт, submit)
ui/LegalConverterForm.tsx ← разметка (LegalConverterSection), без логики
ui/LegalConverterForm.module.css
index.ts ← export { LegalConverterSection }
widgets/converter-page/ ← ВЕТКА ФИЗЛИЦ: обычный конвертер (не трогался)
model/useConverterSection.ts
ui/ConverterSection.tsx
...
features/b2b/ ← домен B2B-заявок
lib/purchaseRequest.ts ← чистая доменная логика (без React) — см. ниже
hooks/useCreatePurchaseRequest.ts ← мутация POST /purchase-requests
hooks/useMyPurchaseRequests.ts ← список заявок аккаунта (queryKey b2b/purchase-requests)
api/b2bApi.ts ← fetch + типы B2bPurchaseRequest и т.д.
```
`LegalConverterForm.tsx` экспортирует компонент `LegalConverterSection` (имя
по аналогии с `ConverterSection` физлиц). Файл назван `*Form`, компонент — `*Section`.
## Ветка юрлиц: где что лежит
Раньше всё (стейт формы + доменная математика + разметка) жило одним файлом
`pages/converter/ui/LegalConverterPage.tsx`. После рефакторинга:
| Слой | Файл | Ответственность |
|---|---|---|
| `features/b2b/lib` | `purchaseRequest.ts` | **чистая** логика без React: расчёт комиссии, упаковка/парсинг comment, склонения, форматирование ₽ |
| `widgets/legal-converter/model` | `useLegalConverterForm.ts` | стейт полей формы, автозаполнение, submit-мутация, нотификация |
| `widgets/legal-converter/ui` | `LegalConverterForm.tsx` | только разметка, дёргает хук |
### `features/b2b/lib/purchaseRequest.ts`
| Экспорт | Что делает |
|---|---|
| `MIN_ORDER` | минимальный объём заявки (500 000 ₽) |
| `TERM_OPTIONS` | таблица «срок ожидания → ставка комиссии». Чем дольше ждать, тем ниже ставка (3 дня → 5 %, 14 дней → 1 %) |
| `termRate(days)` | ставка (доля) для срока; фоллбэк — первая строка таблицы |
| `calcQuote(amount, days)` | `{ rate, commission, total }`**расчёт комиссии и итога** |
| `buildPurchaseComment(parts)` | **упаковка** имени/контакта/срока/сумм в строку `comment` |
| `parseContactFromComment(comment)` | **парсинг** имени и контакта обратно из `comment` |
| `latestPurchaseRequest(items)` | последняя по `created_at` заявка аккаунта (или `null`) |
| `dayLabel(days)` | русское склонение: `1 день` / `2 дня` / `5 дней` |
| `formatRub(n)` | целое с разделителями групп: `500000 → "500 000"` |
## Ключевой нюанс: имя/контакт упакованы в `comment`
У API B2B-заявки (`B2bPurchaseRequest`, `api/b2bApi.ts`) **нет отдельных полей** под
имя, контакт, срок ожидания и суммы в ₽. Есть только `usdt_amount` и свободный
`comment`. Поэтому всё, что нужно менеджеру, кодируется в человекочитаемый `comment`:
```
Имя: Иван; Контакт: +7 900 000-00-00; Срок ожидания: 3 дня; Сумма: 500 000 ₽; Комиссия: ≈25 000 ₽; Итого: ≈525 000 ₽
```
- **Запись:** `buildPurchaseComment()` собирает строку при отправке.
- **Чтение:** `parseContactFromComment()` достаёт `Имя:`/`Контакт:` регулярками — это
обратная операция к записи. Используется для **автозаполнения** формы из последней
заявки аккаунта (один раз, по флагу `prefilled` в хуке).
> Связка хрупкая по контракту: меняете формат строки в `buildPurchaseComment` —
> синхронно правьте регулярки в `parseContactFromComment`, иначе автозаполнение
> молча перестанет находить поля.
## Поток данных (ветка юрлиц)
| Источник | Откуда | Что даёт |
|---|---|---|
| `useMe()` | `@features/auth` | `account_type` для выбора ветки (в `ConverterPage`) |
| `useMyPurchaseRequests()` | `@features/b2b` | список прошлых заявок → автозаполнение |
| `useCreatePurchaseRequest()` | `@features/b2b` | мутация создания заявки; на успех инвалидирует `['b2b','purchase-requests']` |
Числовая сумма берётся из строки ввода: `Number(amount.replace(/\D/g, ''))`. Поле
форматируется на лету (`onAmountChange``formatRub`), поэтому в стейте лежит
строка с пробелами, а в API уходит число `numAmount`.
## Правила при доработке
1. **Страница остаётся роутером.** Новый вид конвертера = новый виджет +
ветка в `ConverterPage`. Не тащите стейт/хуки данных в `ConverterPage.tsx`.
2. **Чистая доменная логика** (расчёты, упаковка/парсинг comment, форматирование) →
`features/b2b/lib/purchaseRequest.ts`. Без React, чтобы переиспользовать и тестировать.
3. **Стейт формы и мутации**`widgets/legal-converter/model`. UI-компонент только рендерит.
4. **`comment` пишется и читается одной парой функций** (`build*`/`parse*`) — не
разносите формат по разным местам.
5. Соблюдайте порядок слоёв: виджет импортирует из `features`/`shared`, не наоборот.
## Известные точки расширения / TODO
- `PURCHASE_ENABLED = false` — глобальный выключатель в `ConverterPage.tsx`. Пока `false`,
оба конвертера не показываются.
- `formatRub` живёт в `features/b2b/lib` (локально для домена). Если понадобится
форматирование ₽ в других местах — кандидат на переезд в `shared/lib/utils`
(рядом с `formatUsd`).
- Хрупкость `comment`-контракта (см. выше). При появлении в API нормальных полей под
имя/контакт/срок — `build/parseComment` можно выкинуть.
## Проверка
```bash
npm run build # tsc -b + vite build (тестов в проекте нет)
npm run lint
npm run dev # ручная проверка /converter (под legal-аккаунтом, PURCHASE_ENABLED=true)
```
Ручной чек-лист `/converter` (legal-аккаунт, `PURCHASE_ENABLED = true`):
- ввод объёма форматируется (`500000 → 500 000`); подсказка при объёме < 500 000 ₽;
- выбор срока меняет ставку комиссии и пересчитывает «Сумму комиссии» / «Итого»;
- кнопка неактивна при пустой/слишком малой сумме и во время отправки;
- успешная отправка → тост «Заявка отправлена», форма очищается;
- при повторном заходе имя/контакт подставляются из последней заявки;
- individual-аккаунт по тому же адресу видит обычный `ConverterSection`.
```

View File

@@ -1,7 +1,7 @@
import { useMe } from '@features/auth'
import { Spinner } from '@shared/ui'
import { ConverterSection } from '@widgets/converter-page'
import { LegalConverterPage } from './LegalConverterPage'
import { LegalConverterSection } from '@widgets/legal-converter'
import styles from './ConverterPage.module.css'
// Пока покупка валюты недоступна — показываем заглушку вместо конвертера.
@@ -28,5 +28,5 @@ export function ConverterPage() {
}
const isLegal = !!data && data.account_type !== 'individual'
return isLegal ? <LegalConverterPage /> : <ConverterSection />
return isLegal ? <LegalConverterSection /> : <ConverterSection />
}

View File

@@ -1,125 +0,0 @@
.wrap {
position: relative;
overflow: hidden;
width: 100%;
max-width: 900px;
background: var(--glass-bg);
border: 1px solid var(--glass-border);
border-radius: 24px;
padding: 40px;
}
.header {
margin-bottom: 40px;
}
.title {
font-size: clamp(32px, 4vw, 48px);
font-weight: 700;
}
.subtitle {
font-size: 15px;
line-height: 1.6;
color: var(--text-secondary);
margin-top: 12px;
max-width: 560px;
}
.body {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 48px;
}
.formCol {
display: flex;
flex-direction: column;
gap: 20px;
}
.hint {
font-size: 12px;
color: var(--highlight);
margin-top: -12px;
}
/* Панель условий / комиссии */
.infoCol {
display: flex;
flex-direction: column;
}
.infoTitle {
font-size: 16px;
font-weight: 600;
letter-spacing: 1px;
margin-bottom: 24px;
}
.infoRow {
display: flex;
justify-content: space-between;
align-items: center;
padding: 14px 18px;
background: rgba(255, 255, 255, 0.03);
border-radius: 10px;
border: 1px solid var(--glass-border);
margin-bottom: 12px;
}
.infoRow[data-accent] {
border-color: var(--grad-center);
background: rgba(91, 61, 184, 0.12);
}
.infoLabel {
font-size: 13px;
color: var(--text-secondary);
}
.infoValue {
font-family: var(--font-mono);
font-size: 16px;
font-weight: 600;
}
.note {
font-size: 12px;
line-height: 1.6;
color: var(--text-secondary);
margin-top: 12px;
}
.submitBtn {
width: 100%;
margin-top: 40px;
padding: 18px;
border-radius: 12px;
background: var(--grad-center);
color: var(--text-primary);
font-size: 16px;
font-weight: 600;
letter-spacing: 1px;
transition: opacity 0.2s;
}
.submitBtn:disabled {
opacity: 0.4;
cursor: not-allowed;
}
@media (max-width: 768px) {
.wrap {
padding: 28px 20px;
}
.body {
grid-template-columns: 1fr;
gap: 1.5rem;
}
.header {
margin-bottom: 1.5rem;
}
}

View File

@@ -1,221 +0,0 @@
import { useEffect, useState } from 'react'
import { useCreatePurchaseRequest, useMyPurchaseRequests } from '@features/b2b'
import type { B2bPurchaseRequest } from '@features/b2b'
import { FormField, Notification, Select } from '@shared/ui'
import styles from './LegalConverterPage.module.css'
const MIN_ORDER = 500_000
// Чем дольше пользователь готов ждать, тем ниже комиссия сервиса.
const TERM_OPTIONS = [
{ days: 3, rate: 0.05 },
{ days: 4, rate: 0.04636 },
{ days: 5, rate: 0.04273 },
{ days: 6, rate: 0.03909 },
{ days: 7, rate: 0.03545 },
{ days: 8, rate: 0.03182 },
{ days: 9, rate: 0.02818 },
{ days: 10, rate: 0.02455 },
{ days: 11, rate: 0.02091 },
{ days: 12, rate: 0.01727 },
{ days: 13, rate: 0.01364 },
{ days: 14, rate: 0.01 },
] as const
const ru = (n: number) => n.toLocaleString('ru-RU', { maximumFractionDigits: 0 })
// Имя и контакт у заявки отдельных полей не имеют — они упакованы в comment
// (см. handleSubmit). Достаём их обратно для автозаполнения формы.
const parseContactFromComment = (comment: string | null) => ({
name: comment?.match(/Имя:\s*([^;]+)/)?.[1]?.trim() ?? '',
contact: comment?.match(/Контакт:\s*([^;]+)/)?.[1]?.trim() ?? '',
})
// Последняя по времени создания заявка на аккаунте, либо null.
const latestRequest = (items: B2bPurchaseRequest[]): B2bPurchaseRequest | null =>
items.reduce<B2bPurchaseRequest | null>(
(latest, r) => (!latest || (r.created_at ?? '') > (latest.created_at ?? '') ? r : latest),
null,
)
const dayLabel = (days: number) => {
const mod10 = days % 10
const mod100 = days % 100
if (mod10 === 1 && mod100 !== 11) return `${days} день`
if (mod10 >= 2 && mod10 <= 4 && (mod100 < 10 || mod100 >= 20)) return `${days} дня`
return `${days} дней`
}
export function LegalConverterPage() {
const [amount, setAmount] = useState('')
const [name, setName] = useState('')
const [contact, setContact] = useState('')
const [days, setDays] = useState<number>(TERM_OPTIONS[0].days)
const [notice, setNotice] = useState<'success' | 'error' | null>(null)
const { mutate: submitRequest, isPending } = useCreatePurchaseRequest()
const { data: requests } = useMyPurchaseRequests()
// Автозаполнение имени и контакта из последней заявки аккаунта (один раз).
const [prefilled, setPrefilled] = useState(false)
useEffect(() => {
if (prefilled || !requests) return
const last = latestRequest(requests.items)
if (!last) return
const parsed = parseContactFromComment(last.comment)
if (parsed.name) setName(parsed.name)
if (parsed.contact) setContact(parsed.contact)
setPrefilled(true)
}, [prefilled, requests])
const numAmount = Number(amount.replace(/\D/g, '')) || 0
const belowMin = numAmount > 0 && numAmount < MIN_ORDER
const rate = TERM_OPTIONS.find((o) => o.days === days)?.rate ?? TERM_OPTIONS[0].rate
const commission = numAmount * rate
const total = numAmount + commission
const handleAmountChange = (value: string) => {
const digits = value.replace(/\D/g, '')
setAmount(digits ? ru(Number(digits)) : '')
}
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
if (numAmount === 0 || belowMin || isPending) return
// Отдельных полей под имя/контакт/срок/сумму в ₽ у API нет — всё уходит в comment.
const comment = [
name && `Имя: ${name}`,
contact && `Контакт: ${contact}`,
`Срок ожидания: ${dayLabel(days)}`,
`Сумма: ${ru(numAmount)}`,
`Комиссия: ≈${ru(commission)}`,
`Итого: ≈${ru(total)}`,
].filter(Boolean).join('; ')
submitRequest(
{ usdt_amount: numAmount, comment },
{
onSuccess: () => {
setNotice('success')
setAmount('')
setName('')
setContact('')
setDays(TERM_OPTIONS[0].days)
},
onError: () => setNotice('error'),
},
)
}
return (
<form className={styles.wrap} onSubmit={handleSubmit}>
<div className={styles.header}>
<h1 className={styles.title}>Оставить заявку</h1>
<p className={styles.subtitle}>
Конвертация крупных объёмов по индивидуальному курсу. Оставьте заявку
менеджер свяжется с вами, подтвердит актуальный курс и сопроводит сделку.
</p>
</div>
<div className={styles.body}>
<div className={styles.formCol}>
<FormField
label="Объём заявки, ₽"
type="text"
value={amount}
onChange={handleAmountChange}
placeholder="от 500 000"
/>
{belowMin && (
<p className={styles.hint}>
Минимальный объём заявки {ru(MIN_ORDER)}
</p>
)}
<Select
id="term"
label="Срок ожидания операции"
value={days}
onChange={setDays}
options={TERM_OPTIONS.map((o) => ({
value: o.days,
label: `${dayLabel(o.days)} — комиссия ${(o.rate * 100).toFixed(3)} %`,
}))}
/>
<FormField
label="Как к вам обращаться"
type="text"
value={name}
onChange={setName}
placeholder="Имя"
/>
<FormField
label="Email или телефон для связи"
type="text"
value={contact}
onChange={setContact}
placeholder="example@mail.ru / +7 900 000-00-00"
/>
</div>
<div className={styles.infoCol}>
<div className={styles.infoTitle}>УСЛОВИЯ</div>
<div className={styles.infoRow}>
<span className={styles.infoLabel}>Минимальный объём</span>
<span className={styles.infoValue}>{ru(MIN_ORDER)} </span>
</div>
<div className={styles.infoRow}>
<span className={styles.infoLabel}>Срок ожидания</span>
<span className={styles.infoValue}>{dayLabel(days)}</span>
</div>
<div className={styles.infoRow}>
<span className={styles.infoLabel}>Ставка комиссии</span>
<span className={styles.infoValue}>{(rate * 100).toFixed(3)} %</span>
</div>
<div className={styles.infoRow}>
<span className={styles.infoLabel}>Сумма комиссии</span>
<span className={styles.infoValue}>
{numAmount > 0 ? `${ru(commission)}` : '—'}
</span>
</div>
<div className={styles.infoRow} data-accent>
<span className={styles.infoLabel}>Итого к оплате</span>
<span className={styles.infoValue}>
{numAmount > 0 ? `${ru(total)}` : '—'}
</span>
</div>
<p className={styles.note}>
Итоговая комиссия рассчитывается индивидуально и зависит от объёма,
валюты и направления сделки.
</p>
</div>
</div>
<button
type="submit"
className={styles.submitBtn}
disabled={belowMin || numAmount === 0 || isPending}
>
{isPending ? 'Отправляем...' : 'Оставить заявку'}
</button>
{notice && (
<Notification
status={notice}
message={notice === 'success' ? 'Заявка отправлена' : 'Не удалось отправить заявку'}
onClose={() => setNotice(null)}
/>
)}
</form>
)
}

View File

@@ -0,0 +1,338 @@
import type { LegalDocData } from '@entities/legal-doc'
export const politikaCookieDoc: LegalDocData = {
title: 'ПОЛИТИКА ИСПОЛЬЗОВАНИЯ ФАЙЛОВ COOKIE',
sections: [
{
title: 'Общие положения и терминология',
blocks: [
{
kind: 'text',
text: 'Настоящая Политика использования файлов cookie устанавливает порядок обработки файлов cookie и содержащихся в них персональных данных ООО «БИТФОРС» при использовании пользователями интернет-ресурса https://bitforce-foundation.ru.',
},
{
kind: 'text',
text: 'Файлы cookie — это текстовые файлы небольшого размера, которые устанавливаются на пользовательское устройство при посещении интернет-ресурса или совершении на нем определенных действий. Файлы cookie остаются сохраненными на устройстве даже после покидания ресурса, что позволяет «узнавать» пользователя при последующих посещениях.',
},
{
kind: 'text',
text: 'К персональным данным относится не сам файл cookie, а его содержимое — уникальные идентификаторы, IP-адреса, информация о предпочтениях пользователя и другие данные, позволяющие прямо или косвенно идентифицировать физическое лицо.',
},
],
},
{
title: 'Оператор персональных данных',
blocks: [
{ kind: 'text', text: 'Оператором персональных данных, содержащихся в файлах cookie, является:' },
{
kind: 'infoBox',
lines: [
'ООО «БИТФОРС»',
'ИНН: 9810001062',
'ОГРН: 1257800060990',
'Юридический адрес: 196246, город Санкт-Петербург, Московское ш, д. 25 к. 1 литера В, помещ. 3-н',
],
},
{
kind: 'text',
text: 'Оператор определяет цели обработки персональных данных, их состав, а также действия с персональными данными, включая случаи использования сторонних файлов cookie.',
},
],
},
{
title: 'Категории файлов cookie и их назначение',
blocks: [
{ kind: 'subheading', text: '1. Строго необходимые (технические) файлы cookie' },
{
kind: 'text',
text: 'Данные файлы обеспечивают работу интернет-ресурса и предоставление необходимого уровня сервиса: авторизацию, навигацию, отображение контента в соответствии с параметрами устройства, обеспечение безопасности.',
},
{
kind: 'text',
text: 'Обработка таких файлов cookie осуществляется на основании п. 5 ч. 1 ст. 6 ФЗ № 152 (заключение и исполнение договора). Согласие на использование строго необходимых файлов cookie не требуется.',
},
{
kind: 'text',
variant: 'example',
text: 'Примеры: файлы сессий (PHPSESSID), настройки безопасности, файлы аутентификации.',
},
{ kind: 'subheading', text: '2. Функциональные файлы cookie' },
{
kind: 'text',
text: 'Используются для запоминания пользовательских предпочтений и персонализации взаимодействия с сайтом: сохранение выбранного языка, региона, настроек отображения, размера шрифта.',
},
{
kind: 'text',
text: 'Обработка осуществляется на основании согласия субъекта персональных данных, поскольку данная обработка не является строго необходимой для функционирования сайта.',
},
{
kind: 'text',
variant: 'example',
text: 'Примеры: настройки языка интерфейса, предпочтения отображения, настройки доступности.',
},
{ kind: 'subheading', text: '3. Аналитические файлы cookie' },
{
kind: 'text',
text: 'Собирают информацию о взаимодействии пользователей с интернет-ресурсом для анализа его использования, выявления популярных разделов, обнаружения ошибок и улучшения пользовательского опыта. Могут содержать персональные данные, включая IP-адреса пользователей.',
},
{ kind: 'text', text: 'Обработка осуществляется на основании согласия субъекта персональных данных.' },
{ kind: 'subheading', text: '4. Маркетинговые файлы cookie' },
{
kind: 'text',
text: 'Используются для отслеживания пользователей в целях персонализированной рекламы, анализа эффективности рекламных кампаний, ретаргетинга.',
},
{
kind: 'text',
text: 'Обработка осуществляется исключительно на основании согласия субъекта персональных данных.',
},
{
kind: 'text',
variant: 'example',
text: 'Примеры: пиксели социальных сетей, рекламные идентификаторы, файлы ретаргетинга.',
},
],
},
{
title: 'Правовые основания обработки персональных данных',
blocks: [
{
kind: 'text',
text: 'Обработка персональных данных, содержащихся в файлах cookie, осуществляется на следующих правовых основаниях:',
},
{
kind: 'list',
items: [
{
strong: 'Согласие субъекта персональных данных',
text: '— для функциональных, аналитических и маркетинговых файлов cookie',
},
{
strong: 'Заключение и исполнение договора',
text: '— для строго необходимых файлов cookie, обеспечивающих работу интернет-ресурса',
},
{
strong: 'Законные интересы оператора',
text: '— в исключительных случаях, когда отсутствуют иные основания',
},
],
},
],
},
{
title: 'Порядок получения согласия',
blocks: [
{ kind: 'subheading', text: 'Принципы получения согласия:' },
{
kind: 'list',
items: [
'Согласие должно быть получено до начала обработки персональных данных',
'Информация об использовании файлов cookie размещается на первом уровне интернет-ресурса',
'Предоставляется возможность выбора категорий файлов cookie',
'Используются активные формулировки вместо пассивных',
],
},
{ kind: 'subheading', text: 'Критерии действительного согласия:' },
{
kind: 'list',
items: [
{ strong: 'Добровольность', text: '— согласие дается по свободной воле субъекта' },
{ strong: 'Конкретность', text: '— четко определены цели обработки' },
{ strong: 'Информированность', text: '— предоставлена полная информация об обработке' },
{ strong: 'Однозначность', text: '— согласие выражено в недвусмысленной форме' },
],
},
],
},
{
title: 'Сторонние файлы cookie',
blocks: [
{ kind: 'subheading', text: 'Использование сторонних сервисов:' },
{ kind: 'text', text: 'Наш интернет-ресурс использует файлы cookie сторонних сервисов, включая:' },
{
kind: 'list',
items: ['Яндекс.Метрика (ООО «ЯНДЕКС», Россия)', 'Социальные сети и сервисы интеграции'],
},
{ kind: 'subheading', text: 'Обеспечение защиты:' },
{
kind: 'list',
items: [
'Получено согласие на передачу',
'Применяются дополнительные меры защиты данных',
'Контролируется соблюдение принципов обработки персональных данных получателями',
],
},
],
},
{
title: 'Сроки обработки и хранения',
blocks: [
{ kind: 'subheading', text: 'Категории по срокам хранения:' },
{
kind: 'list',
items: [
'Сеансовые cookie — удаляются автоматически при закрытии браузера',
'Постоянные cookie — хранятся установленный период или до удаления пользователем',
],
},
{ kind: 'subheading', text: 'Конкретные сроки:' },
{
kind: 'list',
items: [
'Необходимые файлы cookie — до 12 месяцев',
'Функциональные файлы cookie — до 12 месяцев',
'Аналитические файлы cookie — до 24 месяцев',
'Маркетинговые файлы cookie — до 24 месяцев',
],
},
{
kind: 'text',
text: 'По истечении установленных сроков файлы cookie удаляются автоматически. Пользователь может удалить файлы cookie досрочно через настройки браузера или отозвать согласие на их обработку.',
},
],
},
{
title: 'Права субъектов персональных данных',
blocks: [
{ kind: 'subheading', text: 'Право на информацию:' },
{
kind: 'list',
items: [
'Получение информации о обработке персональных данных',
'Сведения о правовых основаниях и целях обработки',
'Информация о сроках обработки и составе данных',
],
},
{ kind: 'subheading', text: 'Право на доступ:' },
{
kind: 'list',
items: [
'Получение подтверждения факта обработки',
'Ознакомление с обрабатываемыми персональными данными',
'Получение информации об источниках персональных данных',
],
},
{ kind: 'subheading', text: 'Право на уточнение, блокирование, удаление:' },
{
kind: 'list',
items: [
'Требование уточнения неточных данных',
'Блокирование недостоверных данных',
'Удаление незаконно полученных данных',
],
},
{ kind: 'subheading', text: 'Право на отзыв согласия:' },
{
kind: 'list',
items: [
'Отзыв согласия в любое время',
'Прекращение обработки после отзыва согласия',
'Сохранение права на обжалование действий оператора',
],
},
],
},
{
title: 'Способы управления файлами cookie',
blocks: [
{ kind: 'subheading', text: 'Управление через настройки сайта:' },
{
kind: 'list',
items: [
'Использование баннера согласия на файлы cookie',
'Изменение настроек в любое время через интерфейс сайта',
'Отзыв согласия на использование отдельных категорий файлов cookie',
],
},
{ kind: 'subheading', text: 'Управление через браузер:' },
{ kind: 'text', text: 'Большинство браузеров позволяют контролировать файлы cookie:' },
{
kind: 'list',
items: [
'Блокировка — запрет установки новых файлов cookie',
'Удаление — очистка существующих файлов cookie',
'Уведомления — получение предупреждений при установке файлов cookie',
'Селективная настройка — разрешение файлов cookie только для определенных сайтов',
],
},
{ kind: 'subheading', text: 'Инструкции для популярных браузеров:' },
{
kind: 'list',
items: [
'Google Chrome: Настройки → Конфиденциальность и безопасность → Файлы cookie',
'Mozilla Firefox: Настройки → Приватность и Защита → Файлы cookie',
'Safari: Настройки → Конфиденциальность → Файлы cookie',
'Microsoft Edge: Настройки → Файлы cookie и разрешения сайтов',
],
},
{
kind: 'text',
variant: 'warning',
text: 'Блокировка необходимых файлов cookie может привести к ограничению функциональности интернет-ресурса.',
},
],
},
{
title: 'Меры безопасности',
blocks: [
{
kind: 'text',
text: 'Оператор применяет правовые, организационные и технические меры для защиты персональных данных:',
},
{ kind: 'subheading', text: 'Правовые меры:' },
{
kind: 'list',
items: [
'Назначение ответственного за организацию обработки персональных данных',
'Ознакомление сотрудников с требованиями законодательства',
'Заключение соглашений о неразглашении персональных данных',
],
},
{ kind: 'subheading', text: 'Организационные меры:' },
{
kind: 'list',
items: [
'Определение перечня лиц, допущенных к обработке персональных данных',
'Установление правил доступа к персональным данным',
'Контроль за соблюдением требований по защите персональных данных',
],
},
{ kind: 'subheading', text: 'Технические меры:' },
{
kind: 'list',
items: [
'Использование средств защиты информации',
'Применение криптографических средств защиты',
'Обеспечение целостности и доступности персональных данных',
'Регулярное обновление систем защиты информации',
],
},
],
},
{
title: 'Контактная информация и обращения',
blocks: [
{ kind: 'text', text: 'Для реализации прав субъекта персональных данных обращайтесь к нам:' },
{
kind: 'infoBox',
lines: [
'ООО «БИТФОРС»',
'ИНН: 9810001062',
'ОГРН: 1257800060990',
'Юридический адрес: 196246, город Санкт-Петербург, Московское ш, д. 25 к. 1 литера В, помещ. 3-н',
'Email компании: company@bitforcefoundation.ru',
],
},
{ kind: 'subheading', text: 'Порядок рассмотрения обращений:' },
{
kind: 'list',
items: [
'Срок рассмотрения обращений — до 30 дней с момента получения',
'Обращения рассматриваются в письменной форме',
'Ответ направляется способом, указанным в обращении',
'При отказе в удовлетворении требований указываются мотивированные основания',
],
},
],
},
],
}

View File

@@ -1,115 +0,0 @@
.main {
padding: 40px 20px;
max-width: 1200px;
margin: 0 auto;
}
.container {
background: var(--bg-mid, #1b1547);
padding: 40px;
border-radius: 8px;
}
.title {
font-size: 28px;
font-weight: 700;
margin-bottom: 30px;
text-align: center;
color: var(--text-primary, #ffffff);
}
.section {
margin-bottom: 40px;
}
.sectionTitle {
font-size: 18px;
font-weight: 600;
margin-bottom: 15px;
color: var(--text-primary, #ffffff);
border-bottom: 2px solid var(--interactive, #4a6dff);
padding-bottom: 10px;
}
.subSectionTitle {
font-size: 16px;
font-weight: 600;
margin-top: 20px;
margin-bottom: 10px;
color: var(--text-primary, #ffffff);
}
.list {
list-style: disc;
margin-left: 20px;
line-height: 1.8;
color: var(--text-primary, #ffffff);
}
.list li {
margin-bottom: 8px;
}
.list strong {
color: var(--text-primary, #ffffff);
}
.info {
padding: 20px;
background: var(--glass-bg, rgba(255, 255, 255, 0.04));
border-left: 4px solid var(--interactive, #4a6dff);
border-radius: 4px;
margin: 15px 0;
line-height: 1.8;
}
.info p {
margin: 5px 0;
color: var(--text-primary, #ffffff);
}
.example {
padding: 10px 15px;
background: var(--glass-bg, rgba(255, 255, 255, 0.04));
border-left: 3px solid var(--interactive, #4a6dff);
border-radius: 4px;
font-style: italic;
color: var(--text-primary, #ffffff);
margin: 10px 0;
}
.warning {
padding: 15px;
background: #fff3cd;
border-left: 4px solid #ffc107;
border-radius: 4px;
color: var(--text-primary, #ffffff);
margin: 15px 0;
font-weight: 500;
}
@media (max-width: 768px) {
.container {
padding: 20px;
}
.title {
font-size: 22px;
}
.sectionTitle {
font-size: 16px;
}
.subSectionTitle {
font-size: 14px;
}
.list {
margin-left: 15px;
}
.info {
padding: 15px;
}
}

View File

@@ -1,273 +1,13 @@
import { LegalDoc } from '@entities/legal-doc'
import { Footer } from '@widgets/footer'
import { Header } from '@widgets/header'
import styles from './PolitikaCookiePage.module.css'
import { politikaCookieDoc } from '../model/content'
export function PolitikaCookiePage() {
return (
<>
<Header />
<main className={styles.main}>
<div className={styles.container}>
<h1 className={styles.title}>ПОЛИТИКА ИСПОЛЬЗОВАНИЯ ФАЙЛОВ COOKIE</h1>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Общие положения и терминология</h3>
<p>
Настоящая Политика использования файлов cookie устанавливает порядок обработки файлов cookie и содержащихся в них персональных данных ООО «БИТФОРС» при использовании пользователями интернет-ресурса https://bitforce-foundation.ru.
</p>
<p>
Файлы cookie это текстовые файлы небольшого размера, которые устанавливаются на пользовательское устройство при посещении интернет-ресурса или совершении на нем определенных действий. Файлы cookie остаются сохраненными на устройстве даже после покидания ресурса, что позволяет «узнавать» пользователя при последующих посещениях.
</p>
<p>
К персональным данным относится не сам файл cookie, а его содержимое уникальные идентификаторы, IP-адреса, информация о предпочтениях пользователя и другие данные, позволяющие прямо или косвенно идентифицировать физическое лицо.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Оператор персональных данных</h3>
<p>Оператором персональных данных, содержащихся в файлах cookie, является:</p>
<div className={styles.info}>
<p>ООО «БИТФОРС»</p>
<p>ИНН: 9810001062</p>
<p>ОГРН: 1257800060990</p>
<p>Юридический адрес: 196246, город Санкт-Петербург, Московское ш, д. 25 к. 1 литера В, помещ. 3-н</p>
</div>
<p>
Оператор определяет цели обработки персональных данных, их состав, а также действия с персональными данными, включая случаи использования сторонних файлов cookie.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Категории файлов cookie и их назначение</h3>
<h4 className={styles.subSectionTitle}>1. Строго необходимые (технические) файлы cookie</h4>
<p>
Данные файлы обеспечивают работу интернет-ресурса и предоставление необходимого уровня сервиса: авторизацию, навигацию, отображение контента в соответствии с параметрами устройства, обеспечение безопасности.
</p>
<p>
Обработка таких файлов cookie осуществляется на основании п. 5 ч. 1 ст. 6 ФЗ 152 (заключение и исполнение договора). Согласие на использование строго необходимых файлов cookie не требуется.
</p>
<p className={styles.example}>Примеры: файлы сессий (PHPSESSID), настройки безопасности, файлы аутентификации.</p>
<h4 className={styles.subSectionTitle}>2. Функциональные файлы cookie</h4>
<p>
Используются для запоминания пользовательских предпочтений и персонализации взаимодействия с сайтом: сохранение выбранного языка, региона, настроек отображения, размера шрифта.
</p>
<p>
Обработка осуществляется на основании согласия субъекта персональных данных, поскольку данная обработка не является строго необходимой для функционирования сайта.
</p>
<p className={styles.example}>Примеры: настройки языка интерфейса, предпочтения отображения, настройки доступности.</p>
<h4 className={styles.subSectionTitle}>3. Аналитические файлы cookie</h4>
<p>
Собирают информацию о взаимодействии пользователей с интернет-ресурсом для анализа его использования, выявления популярных разделов, обнаружения ошибок и улучшения пользовательского опыта. Могут содержать персональные данные, включая IP-адреса пользователей.
</p>
<p>
Обработка осуществляется на основании согласия субъекта персональных данных.
</p>
<h4 className={styles.subSectionTitle}>4. Маркетинговые файлы cookie</h4>
<p>
Используются для отслеживания пользователей в целях персонализированной рекламы, анализа эффективности рекламных кампаний, ретаргетинга.
</p>
<p>
Обработка осуществляется исключительно на основании согласия субъекта персональных данных.
</p>
<p className={styles.example}>Примеры: пиксели социальных сетей, рекламные идентификаторы, файлы ретаргетинга.</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Правовые основания обработки персональных данных</h3>
<p>Обработка персональных данных, содержащихся в файлах cookie, осуществляется на следующих правовых основаниях:</p>
<ul className={styles.list}>
<li>
<strong>Согласие субъекта персональных данных</strong> для функциональных, аналитических и маркетинговых файлов cookie
</li>
<li>
<strong>Заключение и исполнение договора</strong> для строго необходимых файлов cookie, обеспечивающих работу интернет-ресурса
</li>
<li>
<strong>Законные интересы оператора</strong> в исключительных случаях, когда отсутствуют иные основания
</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Порядок получения согласия</h3>
<h4 className={styles.subSectionTitle}>Принципы получения согласия:</h4>
<ul className={styles.list}>
<li>Согласие должно быть получено до начала обработки персональных данных</li>
<li>Информация об использовании файлов cookie размещается на первом уровне интернет-ресурса</li>
<li>Предоставляется возможность выбора категорий файлов cookie</li>
<li>Используются активные формулировки вместо пассивных</li>
</ul>
<h4 className={styles.subSectionTitle}>Критерии действительного согласия:</h4>
<ul className={styles.list}>
<li>
<strong>Добровольность</strong> согласие дается по свободной воле субъекта
</li>
<li>
<strong>Конкретность</strong> четко определены цели обработки
</li>
<li>
<strong>Информированность</strong> предоставлена полная информация об обработке
</li>
<li>
<strong>Однозначность</strong> согласие выражено в недвусмысленной форме
</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Сторонние файлы cookie</h3>
<h4 className={styles.subSectionTitle}>Использование сторонних сервисов:</h4>
<p>Наш интернет-ресурс использует файлы cookie сторонних сервисов, включая:</p>
<ul className={styles.list}>
<li>Яндекс.Метрика (ООО «ЯНДЕКС», Россия)</li>
<li>Социальные сети и сервисы интеграции</li>
</ul>
<h4 className={styles.subSectionTitle}>Обеспечение защиты:</h4>
<ul className={styles.list}>
<li>Получено согласие на передачу</li>
<li>Применяются дополнительные меры защиты данных</li>
<li>Контролируется соблюдение принципов обработки персональных данных получателями</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Сроки обработки и хранения</h3>
<h4 className={styles.subSectionTitle}>Категории по срокам хранения:</h4>
<ul className={styles.list}>
<li>Сеансовые cookie удаляются автоматически при закрытии браузера</li>
<li>Постоянные cookie хранятся установленный период или до удаления пользователем</li>
</ul>
<h4 className={styles.subSectionTitle}>Конкретные сроки:</h4>
<ul className={styles.list}>
<li>Необходимые файлы cookie до 12 месяцев</li>
<li>Функциональные файлы cookie до 12 месяцев</li>
<li>Аналитические файлы cookie до 24 месяцев</li>
<li>Маркетинговые файлы cookie до 24 месяцев</li>
</ul>
<p>
По истечении установленных сроков файлы cookie удаляются автоматически. Пользователь может удалить файлы cookie досрочно через настройки браузера или отозвать согласие на их обработку.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Права субъектов персональных данных</h3>
<h4 className={styles.subSectionTitle}>Право на информацию:</h4>
<ul className={styles.list}>
<li>Получение информации о обработке персональных данных</li>
<li>Сведения о правовых основаниях и целях обработки</li>
<li>Информация о сроках обработки и составе данных</li>
</ul>
<h4 className={styles.subSectionTitle}>Право на доступ:</h4>
<ul className={styles.list}>
<li>Получение подтверждения факта обработки</li>
<li>Ознакомление с обрабатываемыми персональными данными</li>
<li>Получение информации об источниках персональных данных</li>
</ul>
<h4 className={styles.subSectionTitle}>Право на уточнение, блокирование, удаление:</h4>
<ul className={styles.list}>
<li>Требование уточнения неточных данных</li>
<li>Блокирование недостоверных данных</li>
<li>Удаление незаконно полученных данных</li>
</ul>
<h4 className={styles.subSectionTitle}>Право на отзыв согласия:</h4>
<ul className={styles.list}>
<li>Отзыв согласия в любое время</li>
<li>Прекращение обработки после отзыва согласия</li>
<li>Сохранение права на обжалование действий оператора</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Способы управления файлами cookie</h3>
<h4 className={styles.subSectionTitle}>Управление через настройки сайта:</h4>
<ul className={styles.list}>
<li>Использование баннера согласия на файлы cookie</li>
<li>Изменение настроек в любое время через интерфейс сайта</li>
<li>Отзыв согласия на использование отдельных категорий файлов cookie</li>
</ul>
<h4 className={styles.subSectionTitle}>Управление через браузер:</h4>
<p>Большинство браузеров позволяют контролировать файлы cookie:</p>
<ul className={styles.list}>
<li>Блокировка запрет установки новых файлов cookie</li>
<li>Удаление очистка существующих файлов cookie</li>
<li>Уведомления получение предупреждений при установке файлов cookie</li>
<li>Селективная настройка разрешение файлов cookie только для определенных сайтов</li>
</ul>
<h4 className={styles.subSectionTitle}>Инструкции для популярных браузеров:</h4>
<ul className={styles.list}>
<li>Google Chrome: Настройки Конфиденциальность и безопасность Файлы cookie</li>
<li>Mozilla Firefox: Настройки Приватность и Защита Файлы cookie</li>
<li>Safari: Настройки Конфиденциальность Файлы cookie</li>
<li>Microsoft Edge: Настройки Файлы cookie и разрешения сайтов</li>
</ul>
<p className={styles.warning}>
Блокировка необходимых файлов cookie может привести к ограничению функциональности интернет-ресурса.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Меры безопасности</h3>
<p>
Оператор применяет правовые, организационные и технические меры для защиты персональных данных:
</p>
<h4 className={styles.subSectionTitle}>Правовые меры:</h4>
<ul className={styles.list}>
<li>Назначение ответственного за организацию обработки персональных данных</li>
<li>Ознакомление сотрудников с требованиями законодательства</li>
<li>Заключение соглашений о неразглашении персональных данных</li>
</ul>
<h4 className={styles.subSectionTitle}>Организационные меры:</h4>
<ul className={styles.list}>
<li>Определение перечня лиц, допущенных к обработке персональных данных</li>
<li>Установление правил доступа к персональным данным</li>
<li>Контроль за соблюдением требований по защите персональных данных</li>
</ul>
<h4 className={styles.subSectionTitle}>Технические меры:</h4>
<ul className={styles.list}>
<li>Использование средств защиты информации</li>
<li>Применение криптографических средств защиты</li>
<li>Обеспечение целостности и доступности персональных данных</li>
<li>Регулярное обновление систем защиты информации</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Контактная информация и обращения</h3>
<p>Для реализации прав субъекта персональных данных обращайтесь к нам:</p>
<div className={styles.info}>
<p>ООО «БИТФОРС»</p>
<p>ИНН: 9810001062</p>
<p>ОГРН: 1257800060990</p>
<p>Юридический адрес: 196246, город Санкт-Петербург, Московское ш, д. 25 к. 1 литера В, помещ. 3-н</p>
<p>Email компании: company@bitforcefoundation.ru</p>
</div>
<h4 className={styles.subSectionTitle}>Порядок рассмотрения обращений:</h4>
<ul className={styles.list}>
<li>Срок рассмотрения обращений до 30 дней с момента получения</li>
<li>Обращения рассматриваются в письменной форме</li>
<li>Ответ направляется способом, указанным в обращении</li>
<li>При отказе в удовлетворении требований указываются мотивированные основания</li>
</ul>
</section>
</div>
</main>
<LegalDoc doc={politikaCookieDoc} />
<Footer />
</>
)

View File

@@ -0,0 +1,361 @@
import type { LegalDocData } from '@entities/legal-doc'
export const politikaPersonalnyhDannyhDoc: LegalDocData = {
title: 'ПОЛИТИКА ОБРАБОТКИ ПЕРСОНАЛЬНЫХ ДАННЫХ',
subtitle: 'ООО «БИТФОРС»',
sections: [
{
title: '1. Общие положения',
blocks: [
{
kind: 'text',
text: 'Настоящая Политика обработки персональных данных разработана в соответствии с Федеральным законом от 27.07.2006 № 152-ФЗ «О персональных данных» и определяет порядок обработки персональных данных и меры по обеспечению безопасности персональных данных, предпринимаемые ООО «БИТФОРС».',
},
{
kind: 'text',
text: 'Оператор ставит своей важнейшей целью и условием осуществления своей деятельности соблюдение прав и свобод человека и гражданина при обработке его персональных данных, в том числе защиты права на неприкосновенность частной жизни, личную и семейную тайну.',
},
{
kind: 'text',
text: 'Настоящая Политика действует в отношении всех персональных данных, которые обрабатываются Оператором с использованием средств автоматизации и без использования таких средств.',
},
{ kind: 'subheading', text: '1.4. Основные понятия' },
{
kind: 'definitions',
items: [
{
term: 'Автоматизированная обработка персональных данных',
text: '— обработка персональных данных с помощью средств вычислительной техники.',
},
{
term: 'Обработка персональных данных',
text: '— любое действие или совокупность действий, совершаемых с использованием средств автоматизации или без использования таких средств с персональными данными, включая сбор, запись, систематизацию, накопление, хранение, уточнение, извлечение, использование, передачу, обезличивание, блокирование, удаление, уничтожение.',
},
{
term: 'Оператор',
text: '— юридическое или физическое лицо, организующие и осуществляющие обработку персональных данных.',
},
{
term: 'Персональные данные',
text: '— любая информация, относящаяся к прямо или косвенно определенному или определяемому физическому лицу.',
},
{
term: 'Пользователь',
text: '— любой посетитель веб-сайта https://bitforce-foundation.ru.',
},
],
},
],
},
{
title: '2. Сведения об операторе',
blocks: [
{
kind: 'list',
items: [
'Полное наименование: Общество с ограниченной ответственностью «БИТФОРС»',
'Сокращенное наименование: ООО «БИТФОРС»',
'ИНН: 9810001062',
'ОГРН: 1257800060990',
'Юридический адрес: 196246, город Санкт-Петербург, Московское шоссе, дом 25, корпус 1, литера В, помещение 3-н',
'Электронная почта: company@bitforcefoundation.ru',
'Веб-сайт: https://bitforce-foundation.ru',
],
},
],
},
{
title: '3. Общие цели обработки персональных данных',
blocks: [
{ kind: 'subheading', text: '3.1.1. Основная деятельность:' },
{
kind: 'list',
items: [
'Предоставление услуг по конвертации иного имущества',
'Осуществление операций на криптовалютных рынках',
'Предоставление услуг в области блокчейн технологий',
'Обеспечение функционирования интернет-платформы и мобильных приложений',
],
},
{ kind: 'subheading', text: '3.1.2. Обеспечение безопасности:' },
{
kind: 'list',
items: [
'Предотвращение мошенничества и отмывания денежных средств',
'Обеспечение безопасности платежных операций',
'Выполнение требований по противодействию легализации доходов',
'Идентификация и верификация клиентов',
],
},
{ kind: 'subheading', text: '3.1.3. Соблюдение законодательства:' },
{
kind: 'list',
items: [
'Исполнение требований российского и международного законодательства',
'Взаимодействие с контролирующими и правоохранительными органами',
'Ведение обязательной отчетности и документооборота',
'Соблюдение налогового законодательства',
],
},
],
},
{
title: '4. Цели сбора персональных данных',
blocks: [
{
kind: 'goals',
items: [
{
title: 'Регистрация и идентификация пользователей:',
items: [
'Создание учетной записи на веб-сайте',
'Верификация личности в соответствии с требованиями законодательства',
'Подтверждение права на осуществление операций',
],
},
{
title: 'Обработка платежей и финансовых операций:',
items: [
'Осуществление операций по конвертации криптовалют',
'Проведение расчетов и переводов денежных средств',
'Ведение учета и истории транзакций',
],
},
{
title: 'Коммуникация с клиентами:',
items: [
'Предоставление технической поддержки',
'Уведомления о состоянии операций и счетов',
'Информирование об изменениях в условиях предоставления услуг',
],
},
],
},
],
},
{
title: '5. Правовые основания обработки персональных данных',
blocks: [
{ kind: 'subheading', text: '5.1.1. Согласие субъекта персональных данных:' },
{
kind: 'list',
items: [
'Обработка персональных данных в маркетинговых целях',
'Использование файлов cookie и метрик',
'Персонализация сервисов и предложений',
],
},
{ kind: 'subheading', text: '5.1.2. Необходимость исполнения договора:' },
{
kind: 'list',
items: [
'Регистрация и ведение учетных записей пользователей',
'Осуществление финансовых операций и переводов',
'Предоставление доступа к платформе и сервисам',
'Техническая поддержка и обслуживание клиентов',
],
},
{ kind: 'subheading', text: '5.1.3. Соблюдение правовой обязанности:' },
{
kind: 'list',
items: [
'Выполнение требований валютного законодательства',
'Противодействие легализации доходов, полученных преступным путем',
'Соблюдение требований по налоговому учету и отчетности',
],
},
],
},
{
title: '6. Объем и категории обрабатываемых персональных данных',
blocks: [
{ kind: 'subheading', text: '6.1.1. Пользователи веб-сайта и мобильного приложения:' },
{
kind: 'list',
items: [
'Зарегистрированные пользователи',
'Посетители сайта без регистрации',
'Потенциальные клиенты',
'Бывшие клиенты',
],
},
{ kind: 'subheading', text: '6.2.1. Идентификационные данные:' },
{ kind: 'list', items: ['Фамилия, имя, отчество', 'Дата рождения', 'Гражданство'] },
{ kind: 'subheading', text: '6.2.3. Контактная информация:' },
{
kind: 'list',
items: ['Номера телефонов (мобильный, домашний, рабочий)', 'Адреса электронной почты'],
},
{ kind: 'subheading', text: '6.2.4. Финансовая информация:' },
{
kind: 'list',
items: [
'Номера банковских счетов и карт',
'Реквизиты кошельков криптовалют',
'История операций и транзакций',
'Данные о доходах и источниках средств',
],
},
{ kind: 'subheading', text: '6.2.5. Техническая информация:' },
{
kind: 'list',
items: [
'IP-адреса устройств',
'Данные о браузере и операционной системе',
'Файлы cookie и локальное хранилище',
'Логи действий на сайте',
],
},
],
},
{
title: '7. Порядок и условия обработки персональных данных',
blocks: [
{ kind: 'subheading', text: '7.1. Принципы обработки персональных данных:' },
{
kind: 'list',
items: [
'Обработка осуществляется на законной и справедливой основе',
'Обработка ограничивается достижением конкретных, заранее определенных целей',
'Содержание и объем данных соответствуют заявленным целям',
'Обрабатываемые персональные данные являются точными и актуальными',
],
},
{ kind: 'subheading', text: '7.4. Сроки обработки персональных данных:' },
{
kind: 'list',
items: [
'Персональные данные обрабатываются в течение времени, необходимого для достижения целей',
'После достижения целей персональные данные подлежат уничтожению или обезличиванию',
'Сроки хранения определяются требованиями законодательства',
],
},
{ kind: 'subheading', text: '7.5. Места обработки персональных данных:' },
{
kind: 'list',
items: [
'Основные серверы и хранилища данных расположены на территории Российской Федерации',
'Резервные копии могут храниться в дата-центрах на территории РФ',
],
},
],
},
{
title: '8. Актуализация, исправление, удаление и уничтожение персональных данных',
blocks: [
{ kind: 'subheading', text: '8.2.2. Процедура исправления:' },
{
kind: 'list',
items: [
'Рассмотрение запроса в течение 30 дней',
'Проверка обоснованности требования об исправлении',
'Внесение изменений во все информационные системы',
'Уведомление субъекта о проведенных исправлениях',
],
},
{ kind: 'subheading', text: '8.3.2. Процедура удаления:' },
{
kind: 'list',
items: [
'Проверка наличия законных оснований для продолжения обработки',
'Удаление из всех информационных систем и баз данных',
'Удаление резервных копий (кроме архивных)',
'Уведомление субъекта о выполненном удалении',
],
},
],
},
{
title: '9. Ответы на запросы субъектов персональных данных',
blocks: [
{ kind: 'subheading', text: '9.1.1. Право на информацию:' },
{
kind: 'list',
items: [
'Подтверждение факта обработки персональных данных',
'Правовые основания и цели обработки',
'Применяемые способы обработки',
'Наименование и местонахождение оператора',
'Лица, имеющие доступ к персональным данным',
],
},
{ kind: 'subheading', text: '9.2.2. Сроки рассмотрения:' },
{
kind: 'list',
items: [
'Срок рассмотрения запроса составляет 30 дней с момента получения',
'Срок может быть продлен на 30 дней при большом объеме информации',
'О продлении срока субъект уведомляется в течение 30 дней',
],
},
{ kind: 'subheading', text: '9.4. Плата за предоставление информации:' },
{
kind: 'list',
items: [
'Первый запрос в течение года обрабатывается бесплатно',
'За повторные запросы может взиматься плата в размере расходов',
'Субъект уведомляется о размере платы до предоставления информации',
],
},
],
},
{
title: '10. Обеспечение безопасности персональных данных',
blocks: [
{ kind: 'subheading', text: '10.1. Правовые меры:' },
{
kind: 'list',
items: [
'Назначение ответственного за организацию обработки персональных данных',
'Принятие локальных актов по вопросам обработки персональных данных',
'Ознакомление работников с требованиями законодательства',
'Применение мер ответственности за нарушение требований',
],
},
{ kind: 'subheading', text: '10.3. Технические меры:' },
{
kind: 'list',
items: [
'Предотвращение несанкционированного доступа к персональным данным',
'Своевременное обнаружение фактов несанкционированного доступа',
'Возможность незамедлительного восстановления персональных данных',
'Постоянный контроль за обеспечением уровня защищенности',
],
},
{ kind: 'subheading', text: '10.4. Конкретные технические решения:' },
{
kind: 'list',
items: [
'Использование сертифицированных средств защиты информации',
'Шифрование персональных данных при передаче и хранении',
'Применение межсетевых экранов и систем обнаружения вторжений',
'Резервное копирование и обеспечение отказоустойчивости',
'Антивирусная защита и обновление программного обеспечения',
],
},
],
},
{
title: '12. Заключительные положения',
blocks: [
{ kind: 'subheading', text: '12.2. Жалобы и обращения:' },
{
kind: 'list',
items: [
'Субъекты персональных данных могут обратиться к Оператору по вопросам обработки',
'Жалобы рассматриваются в установленном законом порядке',
'При неурегулировании разногласий возможно обращение в Роскомнадзор или суд',
],
},
{ kind: 'subheading', text: '12.4. Контактная информация для обращений:' },
{
kind: 'infoBox',
lines: [
'Почтовый адрес: 196246, г. Санкт-Петербург, Московское ш., д. 25, к. 1, лит. В, пом. 3-н',
'Электронная почта: company@bitforcefoundation.ru',
],
},
],
},
],
}

View File

@@ -1,138 +0,0 @@
.main {
padding: 40px 20px;
max-width: 1200px;
margin: 0 auto;
}
.container {
background: var(--bg-mid, #1b1547);
padding: 40px;
border-radius: 8px;
}
.title {
font-size: 28px;
font-weight: 700;
margin-bottom: 20px;
text-align: center;
color: var(--text-primary, #ffffff);
}
.subtitle {
font-size: 22px;
font-weight: 600;
margin-bottom: 30px;
text-align: center;
color: var(--text-secondary, #b5b0cc);
}
.section {
margin-bottom: 40px;
}
.sectionTitle {
font-size: 18px;
font-weight: 600;
margin-bottom: 15px;
color: var(--text-primary, #ffffff);
border-bottom: 2px solid var(--interactive, #4a6dff);
padding-bottom: 10px;
}
.subSectionTitle {
font-size: 16px;
font-weight: 600;
margin-top: 20px;
margin-bottom: 10px;
color: var(--text-primary, #ffffff);
}
.definitions {
display: flex;
flex-direction: column;
gap: 15px;
}
.definition {
padding: 15px;
background: var(--glass-bg, rgba(255, 255, 255, 0.04));
border-left: 4px solid var(--interactive, #4a6dff);
border-radius: 4px;
line-height: 1.6;
}
.list {
list-style: disc;
margin-left: 20px;
line-height: 1.8;
color: var(--text-primary, #ffffff);
}
.list li {
margin-bottom: 8px;
}
.goalsList {
display: flex;
flex-direction: column;
gap: 20px;
}
.goal {
padding: 15px;
background: var(--glass-bg, rgba(255, 255, 255, 0.04));
border-left: 4px solid var(--interactive, #4a6dff);
border-radius: 4px;
}
.goal strong {
display: block;
margin-bottom: 10px;
color: var(--text-primary, #ffffff);
}
.goal ul {
list-style: disc;
margin-left: 20px;
line-height: 1.6;
}
.goal li {
margin-bottom: 6px;
color: var(--text-primary, #ffffff);
}
.contacts {
padding: 20px;
background: var(--glass-bg, rgba(255, 255, 255, 0.04));
border-radius: 4px;
border: 1px solid var(--glass-border, rgba(255, 255, 255, 0.08));
line-height: 1.8;
color: var(--text-primary, #ffffff);
}
@media (max-width: 768px) {
.container {
padding: 20px;
}
.title {
font-size: 22px;
}
.subtitle {
font-size: 18px;
}
.sectionTitle {
font-size: 16px;
}
.subSectionTitle {
font-size: 14px;
}
.list {
margin-left: 15px;
}
}

View File

@@ -1,299 +1,13 @@
import { LegalDoc } from '@entities/legal-doc'
import { Footer } from '@widgets/footer'
import { Header } from '@widgets/header'
import styles from './PolitikaPage.module.css'
import { politikaPersonalnyhDannyhDoc } from '../model/content'
export function PolitikaPage() {
return (
<>
<Header />
<main className={styles.main}>
<div className={styles.container}>
<h1 className={styles.title}>ПОЛИТИКА ОБРАБОТКИ ПЕРСОНАЛЬНЫХ ДАННЫХ</h1>
<h2 className={styles.subtitle}>ООО «БИТФОРС»</h2>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>1. Общие положения</h3>
<p>
Настоящая Политика обработки персональных данных разработана в соответствии с Федеральным законом от 27.07.2006 152-ФЗ «О персональных данных» и определяет порядок обработки персональных данных и меры по обеспечению безопасности персональных данных, предпринимаемые ООО «БИТФОРС».
</p>
<p>
Оператор ставит своей важнейшей целью и условием осуществления своей деятельности соблюдение прав и свобод человека и гражданина при обработке его персональных данных, в том числе защиты права на неприкосновенность частной жизни, личную и семейную тайну.
</p>
<p>
Настоящая Политика действует в отношении всех персональных данных, которые обрабатываются Оператором с использованием средств автоматизации и без использования таких средств.
</p>
<h4 className={styles.subSectionTitle}>1.4. Основные понятия</h4>
<div className={styles.definitions}>
<div className={styles.definition}>
<strong>Автоматизированная обработка персональных данных</strong> обработка персональных данных с помощью средств вычислительной техники.
</div>
<div className={styles.definition}>
<strong>Обработка персональных данных</strong> любое действие или совокупность действий, совершаемых с использованием средств автоматизации или без использования таких средств с персональными данными, включая сбор, запись, систематизацию, накопление, хранение, уточнение, извлечение, использование, передачу, обезличивание, блокирование, удаление, уничтожение.
</div>
<div className={styles.definition}>
<strong>Оператор</strong> юридическое или физическое лицо, организующие и осуществляющие обработку персональных данных.
</div>
<div className={styles.definition}>
<strong>Персональные данные</strong> любая информация, относящаяся к прямо или косвенно определенному или определяемому физическому лицу.
</div>
<div className={styles.definition}>
<strong>Пользователь</strong> любой посетитель веб-сайта https://bitforce-foundation.ru.
</div>
</div>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>2. Сведения об операторе</h3>
<ul className={styles.list}>
<li>Полное наименование: Общество с ограниченной ответственностью «БИТФОРС»</li>
<li>Сокращенное наименование: ООО «БИТФОРС»</li>
<li>ИНН: 9810001062</li>
<li>ОГРН: 1257800060990</li>
<li>Юридический адрес: 196246, город Санкт-Петербург, Московское шоссе, дом 25, корпус 1, литера В, помещение 3-н</li>
<li>Электронная почта: company@bitforcefoundation.ru</li>
<li>Веб-сайт: https://bitforce-foundation.ru</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>3. Общие цели обработки персональных данных</h3>
<h4 className={styles.subSectionTitle}>3.1.1. Основная деятельность:</h4>
<ul className={styles.list}>
<li>Предоставление услуг по конвертации иного имущества</li>
<li>Осуществление операций на криптовалютных рынках</li>
<li>Предоставление услуг в области блокчейн технологий</li>
<li>Обеспечение функционирования интернет-платформы и мобильных приложений</li>
</ul>
<h4 className={styles.subSectionTitle}>3.1.2. Обеспечение безопасности:</h4>
<ul className={styles.list}>
<li>Предотвращение мошенничества и отмывания денежных средств</li>
<li>Обеспечение безопасности платежных операций</li>
<li>Выполнение требований по противодействию легализации доходов</li>
<li>Идентификация и верификация клиентов</li>
</ul>
<h4 className={styles.subSectionTitle}>3.1.3. Соблюдение законодательства:</h4>
<ul className={styles.list}>
<li>Исполнение требований российского и международного законодательства</li>
<li>Взаимодействие с контролирующими и правоохранительными органами</li>
<li>Ведение обязательной отчетности и документооборота</li>
<li>Соблюдение налогового законодательства</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>4. Цели сбора персональных данных</h3>
<div className={styles.goalsList}>
<div className={styles.goal}>
<strong>Регистрация и идентификация пользователей:</strong>
<ul>
<li>Создание учетной записи на веб-сайте</li>
<li>Верификация личности в соответствии с требованиями законодательства</li>
<li>Подтверждение права на осуществление операций</li>
</ul>
</div>
<div className={styles.goal}>
<strong>Обработка платежей и финансовых операций:</strong>
<ul>
<li>Осуществление операций по конвертации криптовалют</li>
<li>Проведение расчетов и переводов денежных средств</li>
<li>Ведение учета и истории транзакций</li>
</ul>
</div>
<div className={styles.goal}>
<strong>Коммуникация с клиентами:</strong>
<ul>
<li>Предоставление технической поддержки</li>
<li>Уведомления о состоянии операций и счетов</li>
<li>Информирование об изменениях в условиях предоставления услуг</li>
</ul>
</div>
</div>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>5. Правовые основания обработки персональных данных</h3>
<h4 className={styles.subSectionTitle}>5.1.1. Согласие субъекта персональных данных:</h4>
<ul className={styles.list}>
<li>Обработка персональных данных в маркетинговых целях</li>
<li>Использование файлов cookie и метрик</li>
<li>Персонализация сервисов и предложений</li>
</ul>
<h4 className={styles.subSectionTitle}>5.1.2. Необходимость исполнения договора:</h4>
<ul className={styles.list}>
<li>Регистрация и ведение учетных записей пользователей</li>
<li>Осуществление финансовых операций и переводов</li>
<li>Предоставление доступа к платформе и сервисам</li>
<li>Техническая поддержка и обслуживание клиентов</li>
</ul>
<h4 className={styles.subSectionTitle}>5.1.3. Соблюдение правовой обязанности:</h4>
<ul className={styles.list}>
<li>Выполнение требований валютного законодательства</li>
<li>Противодействие легализации доходов, полученных преступным путем</li>
<li>Соблюдение требований по налоговому учету и отчетности</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>6. Объем и категории обрабатываемых персональных данных</h3>
<h4 className={styles.subSectionTitle}>6.1.1. Пользователи веб-сайта и мобильного приложения:</h4>
<ul className={styles.list}>
<li>Зарегистрированные пользователи</li>
<li>Посетители сайта без регистрации</li>
<li>Потенциальные клиенты</li>
<li>Бывшие клиенты</li>
</ul>
<h4 className={styles.subSectionTitle}>6.2.1. Идентификационные данные:</h4>
<ul className={styles.list}>
<li>Фамилия, имя, отчество</li>
<li>Дата рождения</li>
<li>Гражданство</li>
</ul>
<h4 className={styles.subSectionTitle}>6.2.3. Контактная информация:</h4>
<ul className={styles.list}>
<li>Номера телефонов (мобильный, домашний, рабочий)</li>
<li>Адреса электронной почты</li>
</ul>
<h4 className={styles.subSectionTitle}>6.2.4. Финансовая информация:</h4>
<ul className={styles.list}>
<li>Номера банковских счетов и карт</li>
<li>Реквизиты кошельков криптовалют</li>
<li>История операций и транзакций</li>
<li>Данные о доходах и источниках средств</li>
</ul>
<h4 className={styles.subSectionTitle}>6.2.5. Техническая информация:</h4>
<ul className={styles.list}>
<li>IP-адреса устройств</li>
<li>Данные о браузере и операционной системе</li>
<li>Файлы cookie и локальное хранилище</li>
<li>Логи действий на сайте</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>7. Порядок и условия обработки персональных данных</h3>
<h4 className={styles.subSectionTitle}>7.1. Принципы обработки персональных данных:</h4>
<ul className={styles.list}>
<li>Обработка осуществляется на законной и справедливой основе</li>
<li>Обработка ограничивается достижением конкретных, заранее определенных целей</li>
<li>Содержание и объем данных соответствуют заявленным целям</li>
<li>Обрабатываемые персональные данные являются точными и актуальными</li>
</ul>
<h4 className={styles.subSectionTitle}>7.4. Сроки обработки персональных данных:</h4>
<ul className={styles.list}>
<li>Персональные данные обрабатываются в течение времени, необходимого для достижения целей</li>
<li>После достижения целей персональные данные подлежат уничтожению или обезличиванию</li>
<li>Сроки хранения определяются требованиями законодательства</li>
</ul>
<h4 className={styles.subSectionTitle}>7.5. Места обработки персональных данных:</h4>
<ul className={styles.list}>
<li>Основные серверы и хранилища данных расположены на территории Российской Федерации</li>
<li>Резервные копии могут храниться в дата-центрах на территории РФ</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>8. Актуализация, исправление, удаление и уничтожение персональных данных</h3>
<h4 className={styles.subSectionTitle}>8.2.2. Процедура исправления:</h4>
<ul className={styles.list}>
<li>Рассмотрение запроса в течение 30 дней</li>
<li>Проверка обоснованности требования об исправлении</li>
<li>Внесение изменений во все информационные системы</li>
<li>Уведомление субъекта о проведенных исправлениях</li>
</ul>
<h4 className={styles.subSectionTitle}>8.3.2. Процедура удаления:</h4>
<ul className={styles.list}>
<li>Проверка наличия законных оснований для продолжения обработки</li>
<li>Удаление из всех информационных систем и баз данных</li>
<li>Удаление резервных копий (кроме архивных)</li>
<li>Уведомление субъекта о выполненном удалении</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>9. Ответы на запросы субъектов персональных данных</h3>
<h4 className={styles.subSectionTitle}>9.1.1. Право на информацию:</h4>
<ul className={styles.list}>
<li>Подтверждение факта обработки персональных данных</li>
<li>Правовые основания и цели обработки</li>
<li>Применяемые способы обработки</li>
<li>Наименование и местонахождение оператора</li>
<li>Лица, имеющие доступ к персональным данным</li>
</ul>
<h4 className={styles.subSectionTitle}>9.2.2. Сроки рассмотрения:</h4>
<ul className={styles.list}>
<li>Срок рассмотрения запроса составляет 30 дней с момента получения</li>
<li>Срок может быть продлен на 30 дней при большом объеме информации</li>
<li>О продлении срока субъект уведомляется в течение 30 дней</li>
</ul>
<h4 className={styles.subSectionTitle}>9.4. Плата за предоставление информации:</h4>
<ul className={styles.list}>
<li>Первый запрос в течение года обрабатывается бесплатно</li>
<li>За повторные запросы может взиматься плата в размере расходов</li>
<li>Субъект уведомляется о размере платы до предоставления информации</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>10. Обеспечение безопасности персональных данных</h3>
<h4 className={styles.subSectionTitle}>10.1. Правовые меры:</h4>
<ul className={styles.list}>
<li>Назначение ответственного за организацию обработки персональных данных</li>
<li>Принятие локальных актов по вопросам обработки персональных данных</li>
<li>Ознакомление работников с требованиями законодательства</li>
<li>Применение мер ответственности за нарушение требований</li>
</ul>
<h4 className={styles.subSectionTitle}>10.3. Технические меры:</h4>
<ul className={styles.list}>
<li>Предотвращение несанкционированного доступа к персональным данным</li>
<li>Своевременное обнаружение фактов несанкционированного доступа</li>
<li>Возможность незамедлительного восстановления персональных данных</li>
<li>Постоянный контроль за обеспечением уровня защищенности</li>
</ul>
<h4 className={styles.subSectionTitle}>10.4. Конкретные технические решения:</h4>
<ul className={styles.list}>
<li>Использование сертифицированных средств защиты информации</li>
<li>Шифрование персональных данных при передаче и хранении</li>
<li>Применение межсетевых экранов и систем обнаружения вторжений</li>
<li>Резервное копирование и обеспечение отказоустойчивости</li>
<li>Антивирусная защита и обновление программного обеспечения</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>12. Заключительные положения</h3>
<h4 className={styles.subSectionTitle}>12.2. Жалобы и обращения:</h4>
<ul className={styles.list}>
<li>Субъекты персональных данных могут обратиться к Оператору по вопросам обработки</li>
<li>Жалобы рассматриваются в установленном законом порядке</li>
<li>При неурегулировании разногласий возможно обращение в Роскомнадзор или суд</li>
</ul>
<h4 className={styles.subSectionTitle}>12.4. Контактная информация для обращений:</h4>
<p className={styles.contacts}>
Почтовый адрес: 196246, г. Санкт-Петербург, Московское ш., д. 25, к. 1, лит. В, пом. 3-н<br />
Электронная почта: company@bitforcefoundation.ru
</p>
</section>
</div>
</main>
<LegalDoc doc={politikaPersonalnyhDannyhDoc} />
<Footer />
</>
)

137
src/pages/profile/README.md Normal file
View File

@@ -0,0 +1,137 @@
# Страница профиля (`/profile`)
Личный кабинет пользователя: показывает данные аккаунта, баланс, адреса кошельков
и даёт доступ к мнемонике. Маршрут `ROUTES.PROFILE` (`/profile`), защищён
`ProtectedRoute` (только для авторизованных).
## Главная идея
Страница — **тонкая композиция виджетов**. В `ProfilePage.tsx` нет ни хуков данных,
ни стейта, ни дериваций — только разметка. Вся логика и презентация живут в слайсе
`widgets/profile` и в нижних слоях (`features/auth`, `features/wallet`, `shared`).
Это сознательный результат рефакторинга под FSD (`app → pages → widgets → features →
entities → shared`; нижние слои не импортируют верхние).
Ключевой приём: **каждый под-виджет сам тянет свои данные** через хуки. Прокидывать
`data` пропсами со страницы не нужно — `useMe` использует `queryKey: ['me']` со
`staleTime/gcTime: Infinity`, поэтому вызов `useMe()` в нескольких компонентах
дедуплицируется в один сетевой запрос. Та же логика, что в `WalletPage`.
## Карта файлов
```
pages/profile/
ui/ProfilePage.tsx ← композиция (без логики)
ui/ProfilePage.module.css ← только внешний каркас: .page .main .sections
index.ts ← export { ProfilePage }
README.md ← этот файл
widgets/profile/ ← ВСЁ содержимое страницы живёт здесь
model/usePhoneField.ts ← логика редактирования телефона + стейт нотификации
ui/
ProfileSummary.tsx ← аватар + имя + баланс (self-fetch: useMe, usePortfolio)
ProfileDetails.tsx ← выбирает ветку individual/legal (self-fetch: useMe)
IndividualFields.tsx ← поля физлица; зовёт usePhoneField + рендерит Notification
LegalEntityFields.tsx ← поля юрлица (read-only, из data.legal_entity)
SecuritySection.tsx ← адреса кошельков (self-fetch: useWalletAddresses)
MnemonicSection.tsx ← кнопка → ROUTES.SEED_PHRASE
KycBanner.tsx ← баннер, если !kyc_verified (self-fetch: useMe)
ProfileAvatar.tsx ← загрузка/кроп аватара (был раньше)
AvatarCropModal.tsx ← модалка кропа (был раньше)
ProfileSection.tsx ← обёртка-карточка: title + children + actions (был раньше)
fieldsGrid.module.css ← общие .grid2/.grid1 (для Individual/Legal/Security)
*.module.css ← по одному на компонент с собственными стилями
index.ts ← барель: экспортит верхнеуровневые компоненты
features/auth/lib/profile.ts ← getFullName / getDisplayName / isLegalEntity (над MeResponse)
shared/lib/utils/formatUsd.ts← formatUsd(value) → "$1,234.56" | "$—"
```
`IndividualFields` и `LegalEntityFields`**внутренние** для виджета: в барель
(`widgets/profile/index.ts`) не выносятся, их использует только `ProfileDetails`
относительным импортом.
## Поток данных
| Источник | Откуда | Что даёт |
|---|---|---|
| `useMe()` | `@features/auth` | `MeResponse`: ФИО, email, паспорт, ИНН, `account_type`, `kyc_verified`, `legal_entity` |
| `usePortfolio()` | `@features/wallet` | `portfolio.totalUsd` для баланса |
| `useWalletAddresses()` | `@features/wallet` | массив `{ chain, address }` |
| `useUpdatePhone()` | `@features/auth` | мутация сохранения телефона (внутри `usePhoneField`) |
`MeResponse` определён в `features/auth/api/profileApi.ts`. Намеренно **не** перенесён
в пустой `entities/user` — это была бы отдельная миграция (затрагивает все импорты
типа). Если когда-нибудь будете наполнять `entities/user`, тип и хелперы из
`features/auth/lib/profile.ts` — первые кандидаты на переезд вниз.
## Развилка individual / legal
`ProfileDetails` решает по `isLegalEntity(data)` (`account_type !== 'individual'`):
- **individual** → `IndividualFields`: ФИО/email/паспорт/телефон + ИНН/ID. Телефон
**редактируемый**.
- **legal** → `LegalEntityFields`: данные организации/адреса/контакты из
`data.legal_entity` (если `legal_entity` пуст → рендерит `null`). Всё **read-only**
данные юрлица управляются на стороне админа.
## Логика телефона (`usePhoneField`)
Единственная нетривиальная логика на странице, живёт в `widgets/profile/model/usePhoneField.ts`
(по образцу `widgets/login-form/model/useLoginForm.ts`). Хук владеет:
- локальным `phone`, синхронизируемым с серверным значением через `useEffect`;
- санитизацией ввода (`onPhoneChange` — regex оставляет только `\d + пробел () -`);
- сохранением **по blur** (`onPhoneBlur`) с guard'ами: не сохраняет, если значение не
менялось или мутация уже в полёте;
- стейтом нотификации (успех/ошибка) — она побочный эффект мутации, вне хука смысла нет.
Рендер `<Notification>` — в `IndividualFields` (хук владеет стейтом, компонент —
рендером). Это тост из `@shared/ui`, позиционируется фиксированно.
## CSS
- `ProfilePage.module.css` — только внешний каркас страницы (flex-колонка, центрирование
`.main`, отступы, брейкпоинты 1023/639px для паддингов).
- Стили секций — рядом со своими компонентами в `widgets/profile/ui/*.module.css`.
- `fieldsGrid.module.css` — единственный осознанно общий стиль (`.grid2` 2 колонки →
1 колонка на <640px; `.grid1`), импортится из Individual/Legal/Security. Лежит
**внутри виджета**, поэтому ни один компонент не лезет в стиль страницы.
- Брейкпоинты по проекту: 1023 (десктоп→планшет), 649/639 (телефон), 549 (узкий телефон).
## Правила при доработке
1. **Страница остаётся тонкой.** Новый блок профиля = новый компонент в
`widgets/profile/ui/` + экспорт в барель + вставка в `ProfilePage.tsx`. Не тащите
хуки/стейт обратно в страницу.
2. **Данные — через self-fetch хуки**, не через пропсы со страницы (дедуп по queryKey).
3. **Деривации над `MeResponse`**`features/auth/lib/profile.ts` (там же тип). Не
дублируйте форматирование имени/`isLegal` в компонентах.
4. **Форматирование `$`-сумм**`formatUsd` из `@shared/lib/utils/formatUsd`.
5. Соблюдайте порядок слоёв: виджеты импортируют из features/shared, не наоборот.
## Известные точки расширения / TODO
- `ProfileSummary`: закомментирован рублёвый баланс (`.userBalanceRub`, «≈ … ₽») —
ждёт реального источника курса.
- `SecuritySection`: кнопки «⚠️ Посмотреть приватный ключ» и «СОХРАНИТЬ» сейчас
**без обработчиков** (заглушки из исходной вёрстки). При реализации навесить логику.
- `formatUsd` дублируется инлайном ещё в 5 местах (BalanceCard, WalletHeader,
TokenTable, useChainTokenRows, PoolsTable) — отдельная задача на дедупликацию.
Внимание: часть из них использует вариант с 46 знаками, а не фиксированные 2 —
при миграции, возможно, понадобится расширить `formatUsd` опциями точности.
## Проверка
```bash
npm run build # tsc -b + vite build (тестов в проекте нет)
npm run lint
npm run dev # ручная проверка /profile
```
Ручной чек-лист `/profile`:
- individual: поля видны; ввод телефона санитизируется; по blur сохраняется и
появляется тост «Номер телефона обновлён» (и тост ошибки при сбое);
- legal: секции организации/адресов/контактов; телефон read-only;
- баланс через `formatUsd``$—` при загрузке);
- KYC-баннер виден только при `!kyc_verified`;
- «Мнемоника» ведёт на `ROUTES.SEED_PHRASE`;
- адаптив на брейкпоинтах 1023/649/639/549 не сломан.

View File

@@ -1,34 +0,0 @@
import type { MeResponse } from '@features/auth'
import { FormField } from '@shared/ui'
import { ProfileSection } from '@widgets/profile'
import styles from './ProfilePage.module.css'
interface Props {
data: MeResponse
fullName: string
phone: string
onPhoneChange: (value: string) => void
onPhoneBlur: () => void
}
export function IndividualFields({ data, fullName, phone, onPhoneChange, onPhoneBlur }: Props) {
return (
<>
<ProfileSection title="Личные данные">
<div className={styles.grid2}>
<FormField label="Полное ФИО" value={fullName} placeholder="Например: Иванов Иван Иванович" readOnly />
<FormField label="Адрес электронной почты" value={data.email ?? ''} type="email" icon="check" placeholder="example@mail.ru" readOnly />
<FormField label="Серия и номер паспорта" value={data.passport_data ?? ''} placeholder="0000 000000" readOnly />
<FormField label="Номер телефона" value={phone} onChange={onPhoneChange} onBlur={onPhoneBlur} type="tel" placeholder="+7 (999) 000-00-00" />
</div>
</ProfileSection>
<ProfileSection title="Верификация">
<div className={styles.grid2}>
<FormField label="ИНН" value={data.inn ?? ''} readOnly icon="lock" placeholder="000000000000" />
<FormField label="ID аккаунта" value={data.id ?? ''} readOnly icon="lock" placeholder="ECSA-00000000" />
</div>
</ProfileSection>
</>
)
}

View File

@@ -1,47 +0,0 @@
import type { MeResponse } from '@features/auth'
import { FormField } from '@shared/ui'
import { ProfileSection } from '@widgets/profile'
import styles from './ProfilePage.module.css'
interface Props {
data: MeResponse
}
// Legal-account fields. Organization data lives in the nested `legal_entity`
// object; person-level fields are null on these accounts.
// All read-only — organization data is managed admin-side, not by the user.
export function LegalEntityFields({ data }: Props) {
const le = data.legal_entity
if (!le) return null
return (
<>
<ProfileSection title="Данные организации">
<div className={styles.grid2}>
<FormField label="Наименование" value={le.name ?? ''} placeholder="ООО «Ромашка»" readOnly />
<FormField label="Краткое наименование" value={le.short_name ?? ''} placeholder="Ромашка" readOnly />
<FormField label="ИНН" value={le.inn ?? ''} readOnly icon="lock" placeholder="000000000000" />
<FormField label="ОГРН" value={le.ogrn ?? ''} placeholder="1027700132195" readOnly />
<FormField label="КПП" value={le.kpp ?? ''} placeholder="770801001" readOnly />
<FormField label="Адрес электронной почты" value={data.email ?? ''} type="email" icon="check" placeholder="org@mail.ru" readOnly />
</div>
</ProfileSection>
<ProfileSection title="Адреса">
<div className={styles.grid2}>
<FormField label="Юридический адрес" value={le.legal_address ?? ''} placeholder="г. Москва, ул. Тверская, д. 1" readOnly />
<FormField label="Фактический адрес" value={le.actual_address ?? ''} placeholder="г. Москва, ул. Тверская, д. 1" readOnly />
</div>
</ProfileSection>
<ProfileSection title="Контакты и верификация">
<div className={styles.grid2}>
<FormField label="Контактное лицо" value={le.contact_person ?? ''} placeholder="Иванов Иван Иванович" readOnly />
<FormField label="Контактный телефон" value={le.contact_phone ?? ''} type="tel" placeholder="+7 (999) 000-00-00" readOnly />
<FormField label="Статус" value={le.status ?? ''} placeholder="active" readOnly />
<FormField label="ID аккаунта" value={data.id ?? ''} readOnly icon="lock" placeholder="ECSA-00000000" />
</div>
</ProfileSection>
</>
)
}

View File

@@ -5,17 +5,6 @@
background: var(--bg-deep);
}
.kycBanner {
width: 100%;
padding: 10px 24px;
background: var(--error, #ff4466);
color: #fff;
font-size: 13px;
font-weight: 500;
text-align: center;
line-height: 1.4;
}
.main {
max-width: 1024px;
width: 100%;
@@ -25,15 +14,6 @@
gap: 32px;
}
/* Desktop: avatar is left column, sections grow right */
.profileTop {
flex-shrink: 0;
}
.userInfo {
display: none;
}
.sections {
flex: 1;
display: flex;
@@ -41,127 +21,18 @@
gap: 16px;
}
.grid2 {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
.grid1 {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
}
.mnemonicRow {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 16px;
}
.mnemonicInfo {
display: flex;
align-items: center;
gap: 12px;
}
.mnemonicIcon {
font-size: 16px;
}
.mnemonicText {
color: var(--text-secondary);
font-size: 14px;
font-weight: 400;
}
/* < 1024px: column layout, avatar + userInfo side by side at top */
/* < 1024px: avatar + sections stack into a single column */
@media (max-width: 1023px) {
.main {
flex-direction: column;
padding: 24px 20px 40px;
gap: 24px;
}
.grid2 {
gap: 12px;
}
.profileTop {
display: flex;
flex-direction: row;
align-items: flex-start;
gap: 24px;
}
.userInfo {
display: flex;
flex-direction: column;
gap: 6px;
justify-content: center;
}
.userName {
font-size: 28px;
font-weight: 700;
color: var(--text-primary);
line-height: 1.2;
}
.userBalance {
font-size: 32px;
font-weight: 800;
color: var(--text-primary);
}
.userBalanceRub {
font-size: 13px;
color: var(--text-secondary);
}
}
/* < 650px: card padding 16px (в ProfileSection.module.css),
кнопка мнемоники — 100% ширины */
@media (max-width: 649px) {
.mnemonicRow {
flex-direction: column;
align-items: stretch;
gap: 16px;
}
}
/* < 640px: инпуты в колонку */
/* < 640px: tighter page padding */
@media (max-width: 639px) {
.main {
padding: 16px 16px 40px;
}
.grid2 {
grid-template-columns: 1fr;
}
}
/* < 550px: меньше текст и аватар */
@media (max-width: 549px) {
.profileTop {
gap: 16px;
}
.userInfo {
padding-top: 8px;
}
.userName {
font-size: 18px;
}
.userBalance {
font-size: 22px;
margin-top: 4px;
}
.userBalanceRub {
font-size: 12px;
}
}

View File

@@ -1,136 +1,20 @@
import { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { useMe, useUpdatePhone } from '@features/auth'
import { usePortfolio, useWalletAddresses } from '@features/wallet'
import { ROUTES } from '@shared/config/routes'
import { Button, FormField, Notification } from '@shared/ui'
import { WalletHeader } from '@widgets/wallet-header'
import { ProfileAvatar, ProfileSection } from '@widgets/profile'
import { IndividualFields } from './IndividualFields'
import { LegalEntityFields } from './LegalEntityFields'
import { KycBanner, ProfileSummary, ProfileDetails, SecuritySection, MnemonicSection } from '@widgets/profile'
import styles from './ProfilePage.module.css'
export function ProfilePage() {
const { data } = useMe()
const { data: portfolio, isLoading: isPortfolioLoading } = usePortfolio()
const { data: walletAddresses } = useWalletAddresses()
const updatePhone = useUpdatePhone()
const navigate = useNavigate()
const [phone, setPhone] = useState('')
const [savedPhone, setSavedPhone] = useState('')
const [notification, setNotification] = useState<{ message: string; status: 'success' | 'error' } | null>(null)
useEffect(() => {
if (data?.phone != null) {
setPhone(data.phone)
setSavedPhone(data.phone)
}
}, [data?.phone])
function handlePhoneChange(value: string) {
setPhone(value.replace(/[^\d+\s()-]/g, ''))
}
function handlePhoneBlur() {
const next = phone.trim()
if (next === savedPhone || updatePhone.isPending) return
updatePhone.mutate(next, {
onSuccess: () => {
setSavedPhone(next)
setNotification({ status: 'success', message: 'Номер телефона обновлён' })
},
onError: () => {
setNotification({ status: 'error', message: 'Не удалось обновить номер телефона' })
},
})
}
const capitalize = (s: string | null) => (s ? s[0].toUpperCase() + s.slice(1).toLowerCase() : '')
const fullName = data
? [data.last_name, data.first_name, data.middle_name].filter(Boolean).map(capitalize).join(' ')
: ''
const isLegal = !!data && data.account_type !== 'individual'
const displayName = isLegal ? (data?.legal_entity?.name ?? '') : fullName
const userBalance =
isPortfolioLoading || !portfolio || portfolio.totalUsd == null
? '$—'
: `$${portfolio.totalUsd.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
return (
<div className={styles.page}>
<WalletHeader />
{data && !data.kyc_verified && (
<div className={styles.kycBanner}>
Для полного доступа к платформе необходимо пройти верификацию личности (KYC)
</div>
)}
<KycBanner />
<main className={styles.main}>
<div className={styles.profileTop}>
<ProfileAvatar />
<div className={styles.userInfo}>
<span className={styles.userName}>{displayName}</span>
<span className={styles.userBalance}>{userBalance}</span>
{/* <span className={styles.userBalanceRub}>≈ 22 340,50 ₽</span> */}
</div>
</div>
<ProfileSummary />
<div className={styles.sections}>
{data && (isLegal ? (
<LegalEntityFields data={data} />
) : (
<IndividualFields
data={data}
fullName={fullName}
phone={phone}
onPhoneChange={handlePhoneChange}
onPhoneBlur={handlePhoneBlur}
/>
))}
<ProfileSection
title="Безопасность"
actions={
<>
<Button variant="danger"> Посмотреть приватный ключ</Button>
<Button variant="primary">СОХРАНИТЬ</Button>
</>
}
>
<div className={styles.grid1}>
{walletAddresses?.map(({ chain, address }) => (
<FormField
key={chain}
label={`Адрес ${chain}`}
readOnly
icon="lock"
value={address}
placeholder="—"
/>
))}
</div>
</ProfileSection>
<ProfileSection title="Мнемоника">
<div className={styles.mnemonicRow}>
<div className={styles.mnemonicInfo}>
<span className={styles.mnemonicIcon}>🔑</span>
<span className={styles.mnemonicText}>Сид-фраза из 12 слов для восстановления кошелька</span>
</div>
<Button variant="danger" onClick={() => navigate(ROUTES.SEED_PHRASE)}> Показать мнемонику</Button>
</div>
</ProfileSection>
<ProfileDetails />
<SecuritySection />
<MnemonicSection />
</div>
</main>
{notification && (
<Notification
status={notification.status}
message={notification.message}
onClose={() => setNotification(null)}
/>
)}
</div>
)
}

View File

@@ -0,0 +1,240 @@
import type { LegalDocData } from '@entities/legal-doc'
export const publichnayaOfertaDoc: LegalDocData = {
title: 'ПУБЛИЧНЫЙ ДОГОВОР ОФЕРТЫ',
subtitle: 'ООО БИТФОРС',
sections: [
{
title: 'Агентский договор',
blocks: [
{
kind: 'text',
text: 'Настоящая оферта на заключение агентского договора (далее Оферта, Договор) является публичным предложением Общества с ограниченной ответственностью «БИТФОРС», заключить договор на условиях и в порядке, определенных настоящей Офертой.',
},
{
kind: 'text',
text: 'Акцепт оферты производится в соответствии с пунктом 2 статьи 437 Гражданского кодекса Российской Федерации и равносилен заключению агентского договора в письменной форме.',
},
],
},
{
title: 'Основные понятия и определения действующего договора',
blocks: [
{
kind: 'definitions',
items: [
{
term: 'Агент',
text: ' юридическое лицо или индивидуальный предприниматель, зарегистрированный на территории Российской Федерации, в установленном действующим законодательством порядке.',
},
{
term: 'Принципал',
text: ' сторона агентского договора, по поручению которой агент осуществляет юридические и иные действия от своего имени, но за счет принципала либо от имени и за счет принципала.',
},
{
term: 'Агентский договор',
text: ' соглашение, по которому агент обязуется за вознаграждение совершать по поручению принципала юридические и иные действия от своего имени, но за счет принципала либо от имени и за счет принципала в соответствии с п. 1 ст. 1005 Гражданского Кодекса Российской Федерации.',
},
{
term: 'Личный кабинета Агента',
text: ' ресурс, размещенный на сайте Принципала, предназначенный для взаимодействия Агента и Принципала.',
},
{
term: 'Отчетный период',
text: ' период для взаиморасчетов с Агентом, равный одному календарному кварталу с даты активации любой из услуг, предоставляемой Принципалу.',
},
{
term: 'Отчет о сумме начислений (Отчет)',
text: ' отчет, формируемый в Личном кабинете Агента на основании данных систем учета Принципала.',
},
{
term: 'Оферта (Договор)',
text: ' настоящий документ, который отражает предложение и намерение ООО «БИТФОРС» считать заключенным договор с лицом, которым будет принято предложение на условиях, изложенных ниже.',
},
],
},
],
},
{
title: '1. Акцепт оферты и заключение агентского договора',
blocks: [
{
kind: 'text',
text: 'Акцепт настоящей Оферты и заключение Агентского договора осуществляется Принципалом в процессе регистрации в Личном кабинете Принципала (на сайте Агента), при прочтении текста настоящей Оферты, путем проставления специальной отметки (галочки) напротив фразы «Я ознакомился с Офертой и принимаю ее условия» и нажатия кнопки «Подписать».',
},
{
kind: 'text',
text: 'Особый порядок принятия условий Оферты путем проставления специальной отметки (галочки) определяется интерфейсом Личного кабинета Принципала. Принципал не может зарегистрироваться в Личном кабинете и получить к нему доступ без подтверждения принятия условий Оферты.',
},
{
kind: 'text',
text: 'Принимая Оферту, Принципал подтверждает, что прочел и полностью согласен с документами, размещенными на сайте в разделе, предназначенном для Принципала, которые являются неотъемлемой частью настоящей Оферты (Договора) и обязательны для исполнения Сторонами.',
},
],
},
{
title: '2. Общие положения',
blocks: [
{
kind: 'text',
text: 'Публикуемые на сайте Агента документы (формы, требования, правила и т.п.), устанавливающие порядок и условия выполнения действий, предусмотренных настоящим Договором, являются неотъемлемой частью настоящего Договора и обязательны для исполнения Сторонами. Принципал обязан использовать формы документов, утвержденных Агентом, и не вправе вносить в них какие-либо изменения или дополнения.',
},
{
kind: 'text',
text: 'Агент обязуется уведомлять Принципала обо всех изменениях в документах, связанных с исполнением настоящего Договора, путем направления электронных сообщений (через Личный кабинет или на электронную почту Принципала) или размещением уведомлений об изменениях на сайте Агентов в разделе, предназначенном для размещения объявлений.',
},
],
},
{
title: '3. Предмет договора',
blocks: [
{
kind: 'text',
text: 'По настоящему Договору Принципал поручает, а Агент принимает на себя обязательство совершать от имени и за счет Принципала указанные действия, а Принципал обязуется выплатить Агенту вознаграждение за совершенные действия.',
},
{ kind: 'text', text: 'По настоящему Договору Агент совершает следующие действия:' },
{
kind: 'list',
items: [
'Консультирование Принципала об услугах Агента, включая, помимо прочего, порядок активации и оказания услуг, работу в Личном кабинете Принципала и иные дополнительные услуги, оказываемые Агентом;',
'Совершение сделок и иных юридических действий Агентом от своего имени, но за счёт Принципала.',
],
},
{ kind: 'text', text: 'Настоящий Договор действует на территории Российской Федерации и иного иностранного государства.' },
{
kind: 'text',
text: 'Права и обязанности по сделкам, совершенным Агентом во исполнение настоящего Договора, возникают непосредственно у Принципала.',
},
],
},
{
title: '4. Права и обязанности сторон',
blocks: [
{
kind: 'text',
text: 'Агент обязуется совершать действия, составляющие предмет настоящего Договора, в соответствии с законными интересами Принципала, сообщать Принципалу по его требованию все сведения о ходе исполнения настоящего Договора, передавать Принципалу в течение 7 рабочих дней имущество, полученное по сделкам.',
},
{
kind: 'text',
text: 'Агент несет ответственность за сохранность документов и персональных данных, переданных ему Принципалом для исполнения настоящего Договора.',
},
{
kind: 'text',
text: 'Принципал обязан без промедления принять отчет Агента, все предоставленные им документы, обеспечить Агента документами и материалами, необходимыми для выполнения настоящего Договора, возместить Агенту понесенные расходы и выплатить обусловленное Договором агентское вознаграждение.',
},
],
},
{
title: '5. Агентское вознаграждение и порядок оплаты',
blocks: [
{ kind: 'text', text: 'Сумма вознаграждения Агента по настоящему Договору составляет:' },
{
kind: 'list',
items: [
'8% от 5 000 до 30 000 рублей',
'6% от 30 000 до 100 000 рублей',
'4% от 100 000 до 600 000 рублей',
],
},
{
kind: 'text',
text: 'Вознаграждение выплачивается Агенту с момента подписания настоящего Договора об исполнении поручения Агентом от своего имени, но за счет Принципала.',
},
{
kind: 'text',
text: 'Принципал возмещает следующие расходы Агента в сумме не более 30 000 рублей на оплату банковских услуг и иных комиссий.',
},
],
},
{
title: '6. Ответственность сторон',
blocks: [
{
kind: 'text',
text: 'В случае нарушения Агентом сроков, установленных Договором для передачи Принципалу полученного имущества, Принципал вправе предъявить требование об уплате неустойки в размере 0,1% от непереданной суммы за каждый день просрочки.',
},
{
kind: 'text',
text: 'В случае нарушения Принципалом сроков уплаты вознаграждения или возмещения расходов, Агент вправе предъявить требование об уплате неустойки в размере 0,1% от не уплаченной в срок суммы за каждый день просрочки.',
},
],
},
{
title: '7. Форс-мажор',
blocks: [
{
kind: 'text',
text: 'Стороны освобождаются от ответственности за частичное или полное неисполнение обязательств по настоящему Договору, если это неисполнение явилось следствием возникших после заключения настоящего Договора обстоятельств непреодолимой силы.',
},
{
kind: 'text',
text: 'При наступлении форс-мажорных обстоятельств каждая Сторона должна без промедления известить о них в письменном виде другую Сторону с указанием характера обстоятельств и их влияния на исполнение обязательств.',
},
],
},
{
title: '8. Конфиденциальность',
blocks: [
{
kind: 'text',
text: 'Стороны принимают все необходимые меры для того, чтобы их сотрудники, агенты, правопреемники без предварительного согласия другой Стороны не информировали третьих лиц о конфиденциальной информации и персональных данных Сторон настоящего Договора.',
},
],
},
{
title: '9. Изменение и прекращение договора',
blocks: [
{
kind: 'text',
text: 'Настоящий договор вступает в силу с момента его подписания и действует до момента исполнения сторонами своих обязательств по настоящему договору.',
},
{
kind: 'text',
text: 'Настоящий Договор может быть изменен или прекращен по письменному соглашению Сторон, а также в других случаях, предусмотренных законодательством Российской Федерации.',
},
{
kind: 'text',
text: 'Принципал вправе в любое время отказаться от исполнения настоящего Договора путем направления письменного уведомления Агенту за 3 рабочих дня.',
},
],
},
{
title: '10. Заключительные положения',
blocks: [
{
kind: 'text',
text: 'Ни одна из сторон не вправе передавать свои права и обязанности по настоящему договору третьим лицам без согласия другой стороны.',
},
{
kind: 'text',
text: 'Сообщения Стороны могут направлять по факсу, электронной почте или другим способом связи при условии, что он позволяет достоверно установить, от кого исходило сообщение и кому оно адресовано.',
},
{
kind: 'text',
text: 'Споры, вытекающие из настоящего Договора, разрешаются в досудебном порядке. При неурегулировании возникших разногласий спор разрешается в Арбитражном суде г. Санкт–Петербурга и Ленинградской области с обязательным соблюдением претензионного порядка.',
},
],
},
{
title: 'Реквизиты сторон',
blocks: [
{
kind: 'infoBox',
lines: [
'Общество с ограниченной ответственностью «БИТФОРС»',
'196246, г. Санкт-Петербург, Московский р-н, Московское шоссе, д.25к1 литера в, помещ. 3-Н',
'ИНН / КПП: 9810001062 / 781001001',
'ОГРН: 1257800060990',
'ОКПО / ОКАТО / ОКТМО: 68342261 / 40284000000 / 40377000000',
'Руководитель: Кленин Михаил Васильевич',
'Электронная почта: company@bitforcefoundation.ru',
'Наименование банка: ФИЛИАЛ "САНКТ-ПЕТЕРБУРГСКИЙ" АО "АЛЬФА-БАНК"',
'Корреспондентский счет: 30101810600000000786',
'БИК: 044030786',
'Расчетный счет: 40702810632250004861',
],
},
],
},
],
}

View File

@@ -1,89 +0,0 @@
.main {
padding: 40px 20px;
max-width: 1200px;
margin: 0 auto;
}
.container {
background: var(--bg-mid, #1b1547);
padding: 40px;
border-radius: 8px;
}
.title {
font-size: 28px;
font-weight: 700;
margin-bottom: 20px;
text-align: center;
color: var(--text-primary, #ffffff);
}
.subtitle {
font-size: 22px;
font-weight: 600;
margin-bottom: 30px;
text-align: center;
color: var(--text-secondary, #b5b0cc);
}
.section {
margin-bottom: 40px;
}
.sectionTitle {
font-size: 18px;
font-weight: 600;
margin-bottom: 15px;
color: var(--text-primary, #ffffff);
border-bottom: 2px solid var(--interactive, #4a6dff);
padding-bottom: 10px;
}
.definitions {
display: flex;
flex-direction: column;
gap: 15px;
}
.definition {
padding: 15px;
background: var(--glass-bg, rgba(255, 255, 255, 0.04));
border-left: 4px solid var(--interactive, #4a6dff);
border-radius: 4px;
line-height: 1.6;
}
.requisites {
padding: 20px;
background: var(--glass-bg, rgba(255, 255, 255, 0.04));
border-radius: 4px;
border: 1px solid var(--glass-border, rgba(255, 255, 255, 0.08));
line-height: 1.8;
}
.requisites p {
margin: 5px 0;
color: var(--text-primary, #ffffff);
}
@media (max-width: 768px) {
.container {
padding: 20px;
}
.title {
font-size: 22px;
}
.subtitle {
font-size: 18px;
}
.sectionTitle {
font-size: 16px;
}
.requisites {
padding: 15px;
}
}

View File

@@ -1,199 +1,13 @@
import { LegalDoc } from '@entities/legal-doc'
import { Footer } from '@widgets/footer'
import { Header } from '@widgets/header'
import styles from './PublichnayaOfertaPage.module.css'
import { publichnayaOfertaDoc } from '../model/content'
export function PublichnayaOfertaPage() {
return (
<>
<Header />
<main className={styles.main}>
<div className={styles.container}>
<h1 className={styles.title}>ПУБЛИЧНЫЙ ДОГОВОР ОФЕРТЫ</h1>
<h2 className={styles.subtitle}>ООО БИТФОРС</h2>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Агентский договор</h3>
<p>
Настоящая оферта на заключение агентского договора (далее Оферта, Договор) является публичным предложением Общества с ограниченной ответственностью «БИТФОРС», заключить договор на условиях и в порядке, определенных настоящей Офертой.
</p>
<p>
Акцепт оферты производится в соответствии с пунктом 2 статьи 437 Гражданского кодекса Российской Федерации и равносилен заключению агентского договора в письменной форме.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Основные понятия и определения действующего договора</h3>
<div className={styles.definitions}>
<div className={styles.definition}>
<strong>Агент</strong> юридическое лицо или индивидуальный предприниматель, зарегистрированный на территории Российской Федерации, в установленном действующим законодательством порядке.
</div>
<div className={styles.definition}>
<strong>Принципал</strong> сторона агентского договора, по поручению которой агент осуществляет юридические и иные действия от своего имени, но за счет принципала либо от имени и за счет принципала.
</div>
<div className={styles.definition}>
<strong>Агентский договор</strong> соглашение, по которому агент обязуется за вознаграждение совершать по поручению принципала юридические и иные действия от своего имени, но за счет принципала либо от имени и за счет принципала в соответствии с п. 1 ст. 1005 Гражданского Кодекса Российской Федерации.
</div>
<div className={styles.definition}>
<strong>Личный кабинета Агента</strong> ресурс, размещенный на сайте Принципала, предназначенный для взаимодействия Агента и Принципала.
</div>
<div className={styles.definition}>
<strong>Отчетный период</strong> период для взаиморасчетов с Агентом, равный одному календарному кварталу с даты активации любой из услуг, предоставляемой Принципалу.
</div>
<div className={styles.definition}>
<strong>Отчет о сумме начислений (Отчет)</strong> отчет, формируемый в Личном кабинете Агента на основании данных систем учета Принципала.
</div>
<div className={styles.definition}>
<strong>Оферта (Договор)</strong> настоящий документ, который отражает предложение и намерение ООО «БИТФОРС» считать заключенным договор с лицом, которым будет принято предложение на условиях, изложенных ниже.
</div>
</div>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>1. Акцепт оферты и заключение агентского договора</h3>
<p>
Акцепт настоящей Оферты и заключение Агентского договора осуществляется Принципалом в процессе регистрации в Личном кабинете Принципала (на сайте Агента), при прочтении текста настоящей Оферты, путем проставления специальной отметки (галочки) напротив фразы «Я ознакомился с Офертой и принимаю ее условия» и нажатия кнопки «Подписать».
</p>
<p>
Особый порядок принятия условий Оферты путем проставления специальной отметки (галочки) определяется интерфейсом Личного кабинета Принципала. Принципал не может зарегистрироваться в Личном кабинете и получить к нему доступ без подтверждения принятия условий Оферты.
</p>
<p>
Принимая Оферту, Принципал подтверждает, что прочел и полностью согласен с документами, размещенными на сайте в разделе, предназначенном для Принципала, которые являются неотъемлемой частью настоящей Оферты (Договора) и обязательны для исполнения Сторонами.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>2. Общие положения</h3>
<p>
Публикуемые на сайте Агента документы (формы, требования, правила и т.п.), устанавливающие порядок и условия выполнения действий, предусмотренных настоящим Договором, являются неотъемлемой частью настоящего Договора и обязательны для исполнения Сторонами. Принципал обязан использовать формы документов, утвержденных Агентом, и не вправе вносить в них какие-либо изменения или дополнения.
</p>
<p>
Агент обязуется уведомлять Принципала обо всех изменениях в документах, связанных с исполнением настоящего Договора, путем направления электронных сообщений (через Личный кабинет или на электронную почту Принципала) или размещением уведомлений об изменениях на сайте Агентов в разделе, предназначенном для размещения объявлений.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>3. Предмет договора</h3>
<p>
По настоящему Договору Принципал поручает, а Агент принимает на себя обязательство совершать от имени и за счет Принципала указанные действия, а Принципал обязуется выплатить Агенту вознаграждение за совершенные действия.
</p>
<p>
По настоящему Договору Агент совершает следующие действия:
</p>
<ul>
<li>Консультирование Принципала об услугах Агента, включая, помимо прочего, порядок активации и оказания услуг, работу в Личном кабинете Принципала и иные дополнительные услуги, оказываемые Агентом;</li>
<li>Совершение сделок и иных юридических действий Агентом от своего имени, но за счёт Принципала.</li>
</ul>
<p>
Настоящий Договор действует на территории Российской Федерации и иного иностранного государства.
</p>
<p>
Права и обязанности по сделкам, совершенным Агентом во исполнение настоящего Договора, возникают непосредственно у Принципала.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>4. Права и обязанности сторон</h3>
<p>
Агент обязуется совершать действия, составляющие предмет настоящего Договора, в соответствии с законными интересами Принципала, сообщать Принципалу по его требованию все сведения о ходе исполнения настоящего Договора, передавать Принципалу в течение 7 рабочих дней имущество, полученное по сделкам.
</p>
<p>
Агент несет ответственность за сохранность документов и персональных данных, переданных ему Принципалом для исполнения настоящего Договора.
</p>
<p>
Принципал обязан без промедления принять отчет Агента, все предоставленные им документы, обеспечить Агента документами и материалами, необходимыми для выполнения настоящего Договора, возместить Агенту понесенные расходы и выплатить обусловленное Договором агентское вознаграждение.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>5. Агентское вознаграждение и порядок оплаты</h3>
<p>
Сумма вознаграждения Агента по настоящему Договору составляет:
</p>
<ul>
<li>8% от 5 000 до 30 000 рублей</li>
<li>6% от 30 000 до 100 000 рублей</li>
<li>4% от 100 000 до 600 000 рублей</li>
</ul>
<p>
Вознаграждение выплачивается Агенту с момента подписания настоящего Договора об исполнении поручения Агентом от своего имени, но за счет Принципала.
</p>
<p>
Принципал возмещает следующие расходы Агента в сумме не более 30 000 рублей на оплату банковских услуг и иных комиссий.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>6. Ответственность сторон</h3>
<p>
В случае нарушения Агентом сроков, установленных Договором для передачи Принципалу полученного имущества, Принципал вправе предъявить требование об уплате неустойки в размере 0,1% от непереданной суммы за каждый день просрочки.
</p>
<p>
В случае нарушения Принципалом сроков уплаты вознаграждения или возмещения расходов, Агент вправе предъявить требование об уплате неустойки в размере 0,1% от не уплаченной в срок суммы за каждый день просрочки.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>7. Форс-мажор</h3>
<p>
Стороны освобождаются от ответственности за частичное или полное неисполнение обязательств по настоящему Договору, если это неисполнение явилось следствием возникших после заключения настоящего Договора обстоятельств непреодолимой силы.
</p>
<p>
При наступлении форс-мажорных обстоятельств каждая Сторона должна без промедления известить о них в письменном виде другую Сторону с указанием характера обстоятельств и их влияния на исполнение обязательств.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>8. Конфиденциальность</h3>
<p>
Стороны принимают все необходимые меры для того, чтобы их сотрудники, агенты, правопреемники без предварительного согласия другой Стороны не информировали третьих лиц о конфиденциальной информации и персональных данных Сторон настоящего Договора.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>9. Изменение и прекращение договора</h3>
<p>
Настоящий договор вступает в силу с момента его подписания и действует до момента исполнения сторонами своих обязательств по настоящему договору.
</p>
<p>
Настоящий Договор может быть изменен или прекращен по письменному соглашению Сторон, а также в других случаях, предусмотренных законодательством Российской Федерации.
</p>
<p>
Принципал вправе в любое время отказаться от исполнения настоящего Договора путем направления письменного уведомления Агенту за 3 рабочих дня.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>10. Заключительные положения</h3>
<p>
Ни одна из сторон не вправе передавать свои права и обязанности по настоящему договору третьим лицам без согласия другой стороны.
</p>
<p>
Сообщения Стороны могут направлять по факсу, электронной почте или другим способом связи при условии, что он позволяет достоверно установить, от кого исходило сообщение и кому оно адресовано.
</p>
<p>
Споры, вытекающие из настоящего Договора, разрешаются в досудебном порядке. При неурегулировании возникших разногласий спор разрешается в Арбитражном суде г. СанктПетербурга и Ленинградской области с обязательным соблюдением претензионного порядка.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Реквизиты сторон</h3>
<div className={styles.requisites}>
<p>Общество с ограниченной ответственностью «БИТФОРС»</p>
<p>196246, г. Санкт-Петербург, Московский р-н, Московское шоссе, д.25к1 литера в, помещ. 3-Н</p>
<p>ИНН / КПП: 9810001062 / 781001001</p>
<p>ОГРН: 1257800060990</p>
<p>ОКПО / ОКАТО / ОКТМО: 68342261 / 40284000000 / 40377000000</p>
<p>Руководитель: Кленин Михаил Васильевич</p>
<p>Электронная почта: company@bitforcefoundation.ru</p>
<p>Наименование банка: ФИЛИАЛ "САНКТ-ПЕТЕРБУРГСКИЙ" АО "АЛЬФА-БАНК"</p>
<p>Корреспондентский счет: 30101810600000000786</p>
<p>БИК: 044030786</p>
<p>Расчетный счет: 40702810632250004861</p>
</div>
</section>
</div>
</main>
<LegalDoc doc={publichnayaOfertaDoc} />
<Footer />
</>
)

View File

@@ -0,0 +1,60 @@
import type { LegalDocData } from '@entities/legal-doc'
export const reestrDoc: LegalDocData = {
title: 'Реестр операторов персональных данных',
subtitle: 'ООО «БИТФОРС»',
sections: [
{
blocks: [
{
kind: 'text',
text: 'Информация об операторе персональных данных размещена в реестре операторов персональных данных Федеральной службы по надзору в сфере связи, информационных технологий и массовых коммуникаций (Роскомнадзор).',
},
{
kind: 'text',
text: 'Вы можете просмотреть информацию об операторе в реестре Роскомнадзора, перейдя по ссылке ниже:',
},
{
kind: 'link',
href: 'https://pd.rkn.gov.ru/operators-registry/operators-list/?act=search&name_full=%D0%91%D0%B8%D1%82%D1%84%D0%BE%D1%80%D1%81&inn=9810001062&regn=',
text: 'Открыть реестр Роскомнадзора',
},
{
kind: 'text',
text: 'Реестр содержит информацию об операторах персональных данных, включая сведения о целях и методах обработки персональных данных, а также меры по обеспечению безопасности персональных данных.',
},
],
},
{
title: 'Информация об операторе',
blocks: [
{
kind: 'infoBox',
lines: [
{ strong: 'Наименование:', text: 'ООО «БИТФОРС»' },
{ strong: 'ИНН:', text: '9810001062' },
{ strong: 'ОГРН:', text: '1257800060990' },
{
strong: 'Юридический адрес:',
text: '196246, город Санкт-Петербург, Московское шоссе, дом 25, корпус 1, литера В, помещение 3-н',
},
{ strong: 'Контактная информация:', text: 'company@bitforcefoundation.ru' },
],
},
],
},
{
title: 'О Роскомнадзоре',
blocks: [
{
kind: 'text',
text: 'Федеральная служба по надзору в сфере связи, информационных технологий и массовых коммуникаций (Роскомнадзор) — это федеральный орган исполнительной власти, осуществляющий функции по контролю и надзору в области персональных данных.',
},
{
kind: 'text',
text: 'Роскомнадзор ведет реестр операторов персональных данных в соответствии с требованиями Федерального закона «О персональных данных». Реестр является открытой информационной системой и доступен всем заинтересованным лицам.',
},
],
},
],
}

View File

@@ -1,115 +0,0 @@
.main {
padding: 40px 20px;
max-width: 1200px;
margin: 0 auto;
}
.container {
background: var(--bg-mid, #1b1547);
padding: 40px;
border-radius: 8px;
}
.title {
font-size: 28px;
font-weight: 700;
margin-bottom: 20px;
text-align: center;
color: var(--text-primary, #ffffff);
}
.subtitle {
font-size: 22px;
font-weight: 600;
margin-bottom: 30px;
text-align: center;
color: var(--text-secondary, #b5b0cc);
}
.section {
margin-bottom: 40px;
}
.sectionTitle {
font-size: 18px;
font-weight: 600;
margin-bottom: 15px;
color: var(--text-primary, #ffffff);
border-bottom: 2px solid var(--interactive, #4a6dff);
padding-bottom: 10px;
}
.description {
font-size: 16px;
line-height: 1.8;
color: var(--text-primary, #ffffff);
margin-bottom: 20px;
}
.info {
font-size: 16px;
line-height: 1.8;
color: var(--text-primary, #ffffff);
margin: 15px 0;
}
.linkBlock {
text-align: center;
padding: 30px;
background: var(--glass-bg, rgba(255, 255, 255, 0.04));
border-radius: 8px;
margin: 30px 0;
}
.button {
display: inline-block;
padding: 15px 40px;
background: var(--interactive, #4a6dff);
color: #fff;
text-decoration: none;
border-radius: 6px;
font-weight: 600;
transition: all 0.3s ease;
border: 2px solid var(--interactive, #4a6dff);
}
.button:hover {
background: transparent;
color: var(--interactive, #4a6dff);
}
.operatorInfo {
padding: 20px;
background: var(--glass-bg, rgba(255, 255, 255, 0.04));
border-left: 4px solid var(--interactive, #4a6dff);
border-radius: 4px;
line-height: 1.8;
}
.operatorInfo p {
margin: 10px 0;
color: var(--text-primary, #ffffff);
}
@media (max-width: 768px) {
.container {
padding: 20px;
}
.title {
font-size: 22px;
}
.subtitle {
font-size: 18px;
}
.linkBlock {
padding: 20px;
}
.button {
padding: 12px 30px;
font-size: 14px;
}
}

View File

@@ -1,73 +1,13 @@
import { LegalDoc } from '@entities/legal-doc'
import { Footer } from '@widgets/footer'
import { Header } from '@widgets/header'
import styles from './ReestryPage.module.css'
import { reestrDoc } from '../model/content'
export function ReestryPage() {
return (
<>
<Header />
<main className={styles.main}>
<div className={styles.container}>
<h1 className={styles.title}>Реестр операторов персональных данных</h1>
<h2 className={styles.subtitle}>ООО «БИТФОРС»</h2>
<section className={styles.section}>
<p className={styles.description}>
Информация об операторе персональных данных размещена в реестре операторов персональных данных Федеральной службы по надзору в сфере связи, информационных технологий и массовых коммуникаций (Роскомнадзор).
</p>
<p className={styles.info}>
Вы можете просмотреть информацию об операторе в реестре Роскомнадзора, перейдя по ссылке ниже:
</p>
<div className={styles.linkBlock}>
<a
href="https://pd.rkn.gov.ru/operators-registry/operators-list/?act=search&name_full=%D0%91%D0%B8%D1%82%D1%84%D0%BE%D1%80%D1%81&inn=9810001062&regn="
target="_blank"
rel="noopener noreferrer"
className={styles.button}
>
Открыть реестр Роскомнадзора
</a>
</div>
<p className={styles.info}>
Реестр содержит информацию об операторах персональных данных, включая сведения о целях и методах обработки персональных данных, а также меры по обеспечению безопасности персональных данных.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Информация об операторе</h3>
<div className={styles.operatorInfo}>
<p>
<strong>Наименование:</strong> ООО «БИТФОРС»
</p>
<p>
<strong>ИНН:</strong> 9810001062
</p>
<p>
<strong>ОГРН:</strong> 1257800060990
</p>
<p>
<strong>Юридический адрес:</strong> 196246, город Санкт-Петербург, Московское шоссе, дом 25, корпус 1, литера В, помещение 3-н
</p>
<p>
<strong>Контактная информация:</strong> company@bitforcefoundation.ru
</p>
</div>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>О Роскомнадзоре</h3>
<p>
Федеральная служба по надзору в сфере связи, информационных технологий и массовых коммуникаций (Роскомнадзор) это федеральный орган исполнительной власти, осуществляющий функции по контролю и надзору в области персональных данных.
</p>
<p>
Роскомнадзор ведет реестр операторов персональных данных в соответствии с требованиями Федерального закона «О персональных данных». Реестр является открытой информационной системой и доступен всем заинтересованным лицам.
</p>
</section>
</div>
</main>
<LegalDoc doc={reestrDoc} />
<Footer />
</>
)

View File

@@ -0,0 +1,346 @@
import type { LegalDocData } from '@entities/legal-doc'
export const soglasieDoc: LegalDocData = {
title: 'СОГЛАСИЕ НА ОБРАБОТКУ ПЕРСОНАЛЬНЫХ ДАННЫХ',
subtitle: 'ООО «БИТФОРС»',
sections: [
{
title: 'Преамбула',
blocks: [
{
kind: 'text',
text: 'Я, субъект персональных данных, действуя своей волей и в своем интересе, в соответствии с требованиями Федерального закона от 27.07.2006 № 152-ФЗ «О персональных данных», предоставляю ООО «БИТФОРС» согласие на обработку моих персональных данных на условиях и для целей, определенных настоящим Согласием.',
},
],
},
{
title: '1. Сведения об операторе',
blocks: [
{
kind: 'infoBox',
lines: [
'Полное наименование: Общество с ограниченной ответственностью «БИТФОРС»',
'ИНН: 9810001062',
'ОГРН: 1257800060990',
'Юридический адрес: 196246, город Санкт-Петербург, Московское шоссе, дом 25, корпус 1, литера В, помещение 3-н',
'Электронная почта: company@bitforcefoundation.ru',
'Веб-сайт: https://bitforce-foundation.ru',
],
},
],
},
{
title: '2. Правовые основания обработки',
blocks: [
{
kind: 'text',
text: 'Настоящее согласие предоставляется на основании пункта 1 части 1 статьи 6 Федерального закона «О персональных данных» и является правовым основанием для обработки персональных данных Оператором.',
},
{ kind: 'text', text: 'Согласие дается добровольно, своей волей и в своих интересах.' },
{
kind: 'text',
text: 'Субъект персональных данных понимает последствия предоставления согласия, включая возможные риски, связанные с обработкой персональных данных.',
},
],
},
{
title: '3. Цели обработки персональных данных',
blocks: [
{ kind: 'subheading', text: '3.1. Основные цели:' },
{
kind: 'list',
items: [
'Регистрация и ведение учетной записи на веб-сайте и в мобильном приложении',
'Идентификация и верификация личности в соответствии с требованиями законодательства',
'Предоставление услуг по обмену криптовалют и электронных денежных средств',
'Проведение финансовых операций, переводов и расчетов',
'Ведение учета и истории операций',
],
},
{ kind: 'subheading', text: '3.2. Дополнительные цели:' },
{
kind: 'list',
items: [
'Обеспечение безопасности операций и предотвращение мошенничества',
'Выполнение требований по противодействию легализации доходов',
'Соблюдение требований валютного, налогового и иного применимого законодательства',
'Предоставление технической поддержки и клиентского сервиса',
'Рассылка уведомлений о состоянии операций и изменениях в условиях',
],
},
{ kind: 'subheading', text: '3.3. Маркетинговые цели (при дополнительном согласии):' },
{
kind: 'list',
items: [
'Направление информационных и рекламных материалов',
'Проведение маркетинговых исследований и опросов',
'Персонализация предложений и услуг',
'Анализ предпочтений и поведения для улучшения сервисов',
],
},
{ kind: 'subheading', text: '3.4. Аналитические цели:' },
{
kind: 'list',
items: [
'Анализ использования веб-сайта и мобильного приложения',
'Улучшение качества предоставляемых услуг',
'Разработка новых продуктов и сервисов',
'Создание статистических отчетов в обезличенном виде',
],
},
],
},
{
title: '4. Перечень персональных данных',
blocks: [
{ kind: 'subheading', text: '4.1. Идентификационные данные:' },
{ kind: 'list', items: ['Фамилия, имя, отчество', 'Дата рождения', 'Гражданство'] },
{ kind: 'subheading', text: '4.2. Документы, удостоверяющие личность:' },
{
kind: 'list',
items: [
'Серия и номер паспорта гражданина Российской Федерации',
'Дата выдачи и код подразделения',
'Адрес регистрации по месту жительства',
'Цифровые копии (сканы) документов',
],
},
{ kind: 'subheading', text: '4.3. Контактная информация:' },
{
kind: 'list',
items: [
'Номера телефонов (мобильный, домашний, рабочий)',
'Адреса электронной почты',
'Почтовые адреса (фактического проживания, для корреспонденции)',
],
},
{ kind: 'subheading', text: '4.4. Финансовая информация:' },
{
kind: 'list',
items: [
'Номера банковских счетов и реквизиты банковских карт',
'Реквизиты криптовалютных кошельков и адресов',
'Информация о доходах и источниках происхождения денежных средств',
'История финансовых операций и транзакций',
],
},
{ kind: 'subheading', text: '4.5. Техническая информация:' },
{
kind: 'list',
items: [
'IP-адреса устройств, с которых осуществляется доступ к сервисам',
'Информация о браузере, операционной системе и устройстве',
'Файлы cookie и данные локального хранилища',
'Логи действий и история использования сервисов',
],
},
{ kind: 'subheading', text: '4.6. Дополнительная информация:' },
{
kind: 'list',
items: [
'Фотографии для процедур верификации',
'Видеозаписи процедур видеоидентификации',
'Биометрические данные (при использовании соответствующих технологий)',
'Информация о семейном положении и профессиональной деятельности',
],
},
],
},
{
title: '5. Перечень действий с персональными данными',
blocks: [
{
kind: 'text',
text: 'Согласие распространяется на следующие действия (операции) с персональными данными:',
},
{
kind: 'list',
items: [
'Сбор, запись и первичная обработка персональных данных',
'Накопление и систематизация в базах данных',
'Создание резервных копий и архивирование',
'Извлечение, использование и анализ данных',
'Уточнение, обновление и актуализация информации',
'Передача данных третьим лицам',
'Обезличивание и удаление данных',
'Автоматизированная обработка и профилирование',
],
},
],
},
{
title: '6. Лица, которым могут быть переданы персональные данные',
blocks: [
{ kind: 'subheading', text: '6.1. Сотрудники Оператора:' },
{
kind: 'list',
items: [
'Уполномоченные сотрудники, непосредственно участвующие в обработке',
'Сотрудники службы безопасности и комплаенса',
'Сотрудники технической поддержки',
'Руководящий состав в рамках их полномочий',
],
},
{ kind: 'subheading', text: '6.2. Государственные и муниципальные органы:' },
{
kind: 'list',
items: [
'Федеральная служба по финансовому мониторингу',
'Федеральная налоговая служба',
'Правоохранительные органы (при наличии законных требований)',
'Суды и органы исполнения судебных решений',
],
},
{ kind: 'subheading', text: '6.3. Партнеры и контрагенты:' },
{
kind: 'list',
items: [
'Банки и платежные системы',
'Операторы электронных денежных средств',
'Поставщики технологических решений',
'Аудиторские и консалтинговые организации',
],
},
],
},
{
title: '7. Сроки обработки персональных данных',
blocks: [
{ kind: 'subheading', text: '7.1. Общие принципы:' },
{
kind: 'text',
text: 'Персональные данные обрабатываются в течение времени, необходимого для достижения целей обработки. После достижения целей данные подлежат уничтожению или обезличиванию.',
},
{ kind: 'subheading', text: '7.2. Конкретные сроки обработки:' },
{
kind: 'list',
items: [
{
strong: 'Данные активных клиентов:',
text: 'в течение всего периода отношений плюс 5 лет после прекращения',
},
{ strong: 'Данные для идентификации:', text: '5 лет с момента прекращения отношений' },
{ strong: 'Финансовая информация:', text: '5 лет с даты совершения операции' },
{ strong: 'Маркетинговые данные:', text: 'до отзыва согласия, но не более 3 лет' },
{ strong: 'Техническая информация:', text: '1 год для безопасности, 6 месяцев для логов' },
],
},
],
},
{
title: '8. Права субъекта персональных данных',
blocks: [
{ kind: 'subheading', text: '8.1. Право на информацию:' },
{
kind: 'list',
items: [
'Получение подтверждения факта обработки персональных данных',
'Получение информации о целях и способах обработки',
'Информация о сроках обработки и составе данных',
'Сведения о лицах, которым передаются данные',
],
},
{ kind: 'subheading', text: '8.2. Право на доступ:' },
{
kind: 'list',
items: [
'Получение копий обрабатываемых персональных данных',
'Ознакомление с историей обработки и изменений',
'Получение информации об источниках персональных данных',
],
},
{ kind: 'subheading', text: '8.3. Право на исправление и удаление:' },
{
kind: 'list',
items: [
'Требование исправления неточных или неполных данных',
'Требование удаления персональных данных при наличии оснований',
'Удаление данных после отзыва согласия',
],
},
{ kind: 'subheading', text: '8.4. Право на отзыв согласия:' },
{
kind: 'list',
items: [
'Согласие может быть отозвано в любое время',
'Отзыв оформляется в письменной форме',
'После отзыва обработка прекращается в разумные сроки',
],
},
{ kind: 'subheading', text: '8.5. Право на обжалование:' },
{
kind: 'list',
items: [
'Обращение к Оператору с жалобами на действия по обработке данных',
'Обращение в Роскомнадзор или его территориальные органы',
'Обращение в суд для защиты нарушенных прав',
],
},
{ kind: 'subheading', text: '8.6. Порядок реализации прав:' },
{
kind: 'list',
items: [
'Обращения направляются на адрес: company@bitforcefoundation.ru',
'Обращения рассматриваются в течение 30 дней',
'При необходимости срок может быть продлен на 30 дней',
],
},
],
},
{
title: '9. Заключительные положения',
blocks: [
{ kind: 'subheading', text: '9.1. Действие согласия:' },
{
kind: 'list',
items: [
'Согласие действует с момента его предоставления',
'Согласие действует до его отзыва или до достижения целей обработки',
'При существенных изменениях целей требуется новое согласие',
],
},
{ kind: 'subheading', text: '9.2. Форма предоставления согласия:' },
{
kind: 'list',
items: [
'Согласие может быть предоставлено в письменной форме',
'Согласие может быть предоставлено в электронной форме',
'Согласие может выражаться путем совершения конклюдентных действий',
],
},
{ kind: 'subheading', text: '9.3. Последствия непредоставления согласия:' },
{
kind: 'list',
items: [
'Отказ в предоставлении согласия может повлечь невозможность регистрации',
'Отказ может ограничить доступ к отдельным услугам',
'Отказ в согласии на маркетинг не влияет на основные услуги',
'Субъект вправе предоставить частичное согласие',
],
},
{ kind: 'subheading', text: '9.4. Контактная информация:' },
{
kind: 'infoBox',
lines: [
'Почтовый адрес: 196246, г. Санкт-Петербург, Московское ш., д. 25, к. 1, лит. В, пом. 3-н',
'Электронная почта: company@bitforcefoundation.ru',
'Ответственное лицо: Кленин Михаил Васильевич',
'Официальный сайт: https://bitforce-foundation.ru',
],
},
{ kind: 'subheading', text: '9.5. Подтверждение понимания:' },
{ kind: 'text', variant: 'emphasis', text: 'Предоставляя настоящее согласие, я подтверждаю, что:' },
{
kind: 'list',
items: [
'Ознакомлен с содержанием согласия и понимаю его значение',
'Понимаю цели и способы обработки моих персональных данных',
'Знаю о своих правах и способах их реализации',
'Согласие предоставляется добровольно и осознанно',
'Имею возможность отозвать согласие в любое время',
],
},
],
},
],
}

View File

@@ -1,127 +0,0 @@
.main {
padding: 40px 20px;
max-width: 1200px;
margin: 0 auto;
}
.container {
background: var(--bg-mid, #1b1547);
padding: 40px;
border-radius: 8px;
}
.title {
font-size: 28px;
font-weight: 700;
margin-bottom: 20px;
text-align: center;
color: var(--text-primary, #ffffff);
}
.subtitle {
font-size: 22px;
font-weight: 600;
margin-bottom: 30px;
text-align: center;
color: var(--text-secondary, #b5b0cc);
}
.section {
margin-bottom: 40px;
}
.sectionTitle {
font-size: 18px;
font-weight: 600;
margin-bottom: 15px;
color: var(--text-primary, #ffffff);
border-bottom: 2px solid var(--interactive, #4a6dff);
padding-bottom: 10px;
}
.subSectionTitle {
font-size: 16px;
font-weight: 600;
margin-top: 20px;
margin-bottom: 10px;
color: var(--text-primary, #ffffff);
}
.list {
list-style: disc;
margin-left: 20px;
line-height: 1.8;
color: var(--text-primary, #ffffff);
}
.list li {
margin-bottom: 8px;
}
.list strong {
color: var(--text-primary, #ffffff);
}
.info {
padding: 20px;
background: var(--glass-bg, rgba(255, 255, 255, 0.04));
border-left: 4px solid var(--interactive, #4a6dff);
border-radius: 4px;
margin: 15px 0;
line-height: 1.8;
}
.info p {
margin: 8px 0;
color: var(--text-primary, #ffffff);
}
.contacts {
padding: 20px;
background: var(--glass-bg, rgba(255, 255, 255, 0.04));
border-left: 4px solid var(--interactive, #4a6dff);
border-radius: 4px;
line-height: 1.8;
}
.contacts p {
margin: 8px 0;
color: var(--text-primary, #ffffff);
}
.confirmation {
padding: 10px 0;
color: var(--text-primary, #ffffff);
font-weight: 500;
}
@media (max-width: 768px) {
.container {
padding: 20px;
}
.title {
font-size: 22px;
}
.subtitle {
font-size: 18px;
}
.sectionTitle {
font-size: 16px;
}
.subSectionTitle {
font-size: 14px;
}
.list {
margin-left: 15px;
}
.info,
.contacts {
padding: 15px;
}
}

View File

@@ -1,299 +1,13 @@
import { LegalDoc } from '@entities/legal-doc'
import { Footer } from '@widgets/footer'
import { Header } from '@widgets/header'
import styles from './SoglasiePage.module.css'
import { soglasieDoc } from '../model/content'
export function SoglasiePage() {
return (
<>
<Header />
<main className={styles.main}>
<div className={styles.container}>
<h1 className={styles.title}>СОГЛАСИЕ НА ОБРАБОТКУ ПЕРСОНАЛЬНЫХ ДАННЫХ</h1>
<h2 className={styles.subtitle}>ООО «БИТФОРС»</h2>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>Преамбула</h3>
<p>
Я, субъект персональных данных, действуя своей волей и в своем интересе, в соответствии с требованиями Федерального закона от 27.07.2006 152-ФЗ «О персональных данных», предоставляю ООО «БИТФОРС» согласие на обработку моих персональных данных на условиях и для целей, определенных настоящим Согласием.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>1. Сведения об операторе</h3>
<div className={styles.info}>
<p>Полное наименование: Общество с ограниченной ответственностью «БИТФОРС»</p>
<p>ИНН: 9810001062</p>
<p>ОГРН: 1257800060990</p>
<p>Юридический адрес: 196246, город Санкт-Петербург, Московское шоссе, дом 25, корпус 1, литера В, помещение 3-н</p>
<p>Электронная почта: company@bitforcefoundation.ru</p>
<p>Веб-сайт: https://bitforce-foundation.ru</p>
</div>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>2. Правовые основания обработки</h3>
<p>
Настоящее согласие предоставляется на основании пункта 1 части 1 статьи 6 Федерального закона «О персональных данных» и является правовым основанием для обработки персональных данных Оператором.
</p>
<p>Согласие дается добровольно, своей волей и в своих интересах.</p>
<p>
Субъект персональных данных понимает последствия предоставления согласия, включая возможные риски, связанные с обработкой персональных данных.
</p>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>3. Цели обработки персональных данных</h3>
<h4 className={styles.subSectionTitle}>3.1. Основные цели:</h4>
<ul className={styles.list}>
<li>Регистрация и ведение учетной записи на веб-сайте и в мобильном приложении</li>
<li>Идентификация и верификация личности в соответствии с требованиями законодательства</li>
<li>Предоставление услуг по обмену криптовалют и электронных денежных средств</li>
<li>Проведение финансовых операций, переводов и расчетов</li>
<li>Ведение учета и истории операций</li>
</ul>
<h4 className={styles.subSectionTitle}>3.2. Дополнительные цели:</h4>
<ul className={styles.list}>
<li>Обеспечение безопасности операций и предотвращение мошенничества</li>
<li>Выполнение требований по противодействию легализации доходов</li>
<li>Соблюдение требований валютного, налогового и иного применимого законодательства</li>
<li>Предоставление технической поддержки и клиентского сервиса</li>
<li>Рассылка уведомлений о состоянии операций и изменениях в условиях</li>
</ul>
<h4 className={styles.subSectionTitle}>3.3. Маркетинговые цели (при дополнительном согласии):</h4>
<ul className={styles.list}>
<li>Направление информационных и рекламных материалов</li>
<li>Проведение маркетинговых исследований и опросов</li>
<li>Персонализация предложений и услуг</li>
<li>Анализ предпочтений и поведения для улучшения сервисов</li>
</ul>
<h4 className={styles.subSectionTitle}>3.4. Аналитические цели:</h4>
<ul className={styles.list}>
<li>Анализ использования веб-сайта и мобильного приложения</li>
<li>Улучшение качества предоставляемых услуг</li>
<li>Разработка новых продуктов и сервисов</li>
<li>Создание статистических отчетов в обезличенном виде</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>4. Перечень персональных данных</h3>
<h4 className={styles.subSectionTitle}>4.1. Идентификационные данные:</h4>
<ul className={styles.list}>
<li>Фамилия, имя, отчество</li>
<li>Дата рождения</li>
<li>Гражданство</li>
</ul>
<h4 className={styles.subSectionTitle}>4.2. Документы, удостоверяющие личность:</h4>
<ul className={styles.list}>
<li>Серия и номер паспорта гражданина Российской Федерации</li>
<li>Дата выдачи и код подразделения</li>
<li>Адрес регистрации по месту жительства</li>
<li>Цифровые копии (сканы) документов</li>
</ul>
<h4 className={styles.subSectionTitle}>4.3. Контактная информация:</h4>
<ul className={styles.list}>
<li>Номера телефонов (мобильный, домашний, рабочий)</li>
<li>Адреса электронной почты</li>
<li>Почтовые адреса (фактического проживания, для корреспонденции)</li>
</ul>
<h4 className={styles.subSectionTitle}>4.4. Финансовая информация:</h4>
<ul className={styles.list}>
<li>Номера банковских счетов и реквизиты банковских карт</li>
<li>Реквизиты криптовалютных кошельков и адресов</li>
<li>Информация о доходах и источниках происхождения денежных средств</li>
<li>История финансовых операций и транзакций</li>
</ul>
<h4 className={styles.subSectionTitle}>4.5. Техническая информация:</h4>
<ul className={styles.list}>
<li>IP-адреса устройств, с которых осуществляется доступ к сервисам</li>
<li>Информация о браузере, операционной системе и устройстве</li>
<li>Файлы cookie и данные локального хранилища</li>
<li>Логи действий и история использования сервисов</li>
</ul>
<h4 className={styles.subSectionTitle}>4.6. Дополнительная информация:</h4>
<ul className={styles.list}>
<li>Фотографии для процедур верификации</li>
<li>Видеозаписи процедур видеоидентификации</li>
<li>Биометрические данные (при использовании соответствующих технологий)</li>
<li>Информация о семейном положении и профессиональной деятельности</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>5. Перечень действий с персональными данными</h3>
<p>Согласие распространяется на следующие действия (операции) с персональными данными:</p>
<ul className={styles.list}>
<li>Сбор, запись и первичная обработка персональных данных</li>
<li>Накопление и систематизация в базах данных</li>
<li>Создание резервных копий и архивирование</li>
<li>Извлечение, использование и анализ данных</li>
<li>Уточнение, обновление и актуализация информации</li>
<li>Передача данных третьим лицам</li>
<li>Обезличивание и удаление данных</li>
<li>Автоматизированная обработка и профилирование</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>6. Лица, которым могут быть переданы персональные данные</h3>
<h4 className={styles.subSectionTitle}>6.1. Сотрудники Оператора:</h4>
<ul className={styles.list}>
<li>Уполномоченные сотрудники, непосредственно участвующие в обработке</li>
<li>Сотрудники службы безопасности и комплаенса</li>
<li>Сотрудники технической поддержки</li>
<li>Руководящий состав в рамках их полномочий</li>
</ul>
<h4 className={styles.subSectionTitle}>6.2. Государственные и муниципальные органы:</h4>
<ul className={styles.list}>
<li>Федеральная служба по финансовому мониторингу</li>
<li>Федеральная налоговая служба</li>
<li>Правоохранительные органы (при наличии законных требований)</li>
<li>Суды и органы исполнения судебных решений</li>
</ul>
<h4 className={styles.subSectionTitle}>6.3. Партнеры и контрагенты:</h4>
<ul className={styles.list}>
<li>Банки и платежные системы</li>
<li>Операторы электронных денежных средств</li>
<li>Поставщики технологических решений</li>
<li>Аудиторские и консалтинговые организации</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>7. Сроки обработки персональных данных</h3>
<h4 className={styles.subSectionTitle}>7.1. Общие принципы:</h4>
<p>
Персональные данные обрабатываются в течение времени, необходимого для достижения целей обработки. После достижения целей данные подлежат уничтожению или обезличиванию.
</p>
<h4 className={styles.subSectionTitle}>7.2. Конкретные сроки обработки:</h4>
<ul className={styles.list}>
<li>
<strong>Данные активных клиентов:</strong> в течение всего периода отношений плюс 5 лет после прекращения
</li>
<li>
<strong>Данные для идентификации:</strong> 5 лет с момента прекращения отношений
</li>
<li>
<strong>Финансовая информация:</strong> 5 лет с даты совершения операции
</li>
<li>
<strong>Маркетинговые данные:</strong> до отзыва согласия, но не более 3 лет
</li>
<li>
<strong>Техническая информация:</strong> 1 год для безопасности, 6 месяцев для логов
</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>8. Права субъекта персональных данных</h3>
<h4 className={styles.subSectionTitle}>8.1. Право на информацию:</h4>
<ul className={styles.list}>
<li>Получение подтверждения факта обработки персональных данных</li>
<li>Получение информации о целях и способах обработки</li>
<li>Информация о сроках обработки и составе данных</li>
<li>Сведения о лицах, которым передаются данные</li>
</ul>
<h4 className={styles.subSectionTitle}>8.2. Право на доступ:</h4>
<ul className={styles.list}>
<li>Получение копий обрабатываемых персональных данных</li>
<li>Ознакомление с историей обработки и изменений</li>
<li>Получение информации об источниках персональных данных</li>
</ul>
<h4 className={styles.subSectionTitle}>8.3. Право на исправление и удаление:</h4>
<ul className={styles.list}>
<li>Требование исправления неточных или неполных данных</li>
<li>Требование удаления персональных данных при наличии оснований</li>
<li>Удаление данных после отзыва согласия</li>
</ul>
<h4 className={styles.subSectionTitle}>8.4. Право на отзыв согласия:</h4>
<ul className={styles.list}>
<li>Согласие может быть отозвано в любое время</li>
<li>Отзыв оформляется в письменной форме</li>
<li>После отзыва обработка прекращается в разумные сроки</li>
</ul>
<h4 className={styles.subSectionTitle}>8.5. Право на обжалование:</h4>
<ul className={styles.list}>
<li>Обращение к Оператору с жалобами на действия по обработке данных</li>
<li>Обращение в Роскомнадзор или его территориальные органы</li>
<li>Обращение в суд для защиты нарушенных прав</li>
</ul>
<h4 className={styles.subSectionTitle}>8.6. Порядок реализации прав:</h4>
<ul className={styles.list}>
<li>Обращения направляются на адрес: company@bitforcefoundation.ru</li>
<li>Обращения рассматриваются в течение 30 дней</li>
<li>При необходимости срок может быть продлен на 30 дней</li>
</ul>
</section>
<section className={styles.section}>
<h3 className={styles.sectionTitle}>9. Заключительные положения</h3>
<h4 className={styles.subSectionTitle}>9.1. Действие согласия:</h4>
<ul className={styles.list}>
<li>Согласие действует с момента его предоставления</li>
<li>Согласие действует до его отзыва или до достижения целей обработки</li>
<li>При существенных изменениях целей требуется новое согласие</li>
</ul>
<h4 className={styles.subSectionTitle}>9.2. Форма предоставления согласия:</h4>
<ul className={styles.list}>
<li>Согласие может быть предоставлено в письменной форме</li>
<li>Согласие может быть предоставлено в электронной форме</li>
<li>Согласие может выражаться путем совершения конклюдентных действий</li>
</ul>
<h4 className={styles.subSectionTitle}>9.3. Последствия непредоставления согласия:</h4>
<ul className={styles.list}>
<li>Отказ в предоставлении согласия может повлечь невозможность регистрации</li>
<li>Отказ может ограничить доступ к отдельным услугам</li>
<li>Отказ в согласии на маркетинг не влияет на основные услуги</li>
<li>Субъект вправе предоставить частичное согласие</li>
</ul>
<h4 className={styles.subSectionTitle}>9.4. Контактная информация:</h4>
<div className={styles.contacts}>
<p>Почтовый адрес: 196246, г. Санкт-Петербург, Московское ш., д. 25, к. 1, лит. В, пом. 3-н</p>
<p>Электронная почта: company@bitforcefoundation.ru</p>
<p>Ответственное лицо: Кленин Михаил Васильевич</p>
<p>Официальный сайт: https://bitforce-foundation.ru</p>
</div>
<h4 className={styles.subSectionTitle}>9.5. Подтверждение понимания:</h4>
<p className={styles.confirmation}>
Предоставляя настоящее согласие, я подтверждаю, что:
</p>
<ul className={styles.list}>
<li>Ознакомлен с содержанием согласия и понимаю его значение</li>
<li>Понимаю цели и способы обработки моих персональных данных</li>
<li>Знаю о своих правах и способах их реализации</li>
<li>Согласие предоставляется добровольно и осознанно</li>
<li>Имею возможность отозвать согласие в любое время</li>
</ul>
</section>
</div>
</main>
<LegalDoc doc={soglasieDoc} />
<Footer />
</>
)