From 2ef5e171b1dd4e867b8fe28a468af3e3f3a39842 Mon Sep 17 00:00:00 2001 From: smanylov Date: Mon, 1 Dec 2025 15:21:56 +0700 Subject: [PATCH] add settings layout --- src/app/pages/settings/page.tsx | 24 ++ src/app/styles/global-styles.scss | 29 ++ src/app/styles/settings.scss | 281 ++++++++++++++++++ src/app/ui/header/headerPanel.tsx | 2 +- src/app/ui/header/notificationsButton.tsx | 2 +- src/app/ui/nav-links.tsx | 2 +- src/app/ui/register-form.tsx | 4 +- src/app/ui/settings/api-settings.tsx | 38 +++ src/app/ui/settings/danger-zone.tsx | 25 ++ .../ui/settings/last-activity-settings.tsx | 14 + .../notifications-monitoring-settings.tsx | 97 ++++++ .../ui/settings/personal-data-settings.tsx | 71 +++++ src/app/ui/settings/safety-settings.tsx | 36 +++ src/app/ui/settings/subscription-settings.tsx | 50 ++++ 14 files changed, 670 insertions(+), 5 deletions(-) create mode 100644 src/app/pages/settings/page.tsx create mode 100644 src/app/styles/settings.scss create mode 100644 src/app/ui/settings/api-settings.tsx create mode 100644 src/app/ui/settings/danger-zone.tsx create mode 100644 src/app/ui/settings/last-activity-settings.tsx create mode 100644 src/app/ui/settings/notifications-monitoring-settings.tsx create mode 100644 src/app/ui/settings/personal-data-settings.tsx create mode 100644 src/app/ui/settings/safety-settings.tsx create mode 100644 src/app/ui/settings/subscription-settings.tsx diff --git a/src/app/pages/settings/page.tsx b/src/app/pages/settings/page.tsx new file mode 100644 index 0000000..952867f --- /dev/null +++ b/src/app/pages/settings/page.tsx @@ -0,0 +1,24 @@ +import PersonalDataSettings from '@/app/ui/settings/personal-data-settings' +import NotificationsMonitoringSettings from '@/app/ui/settings/notifications-monitoring-settings'; +import SafetySetting from '@/app/ui/settings/safety-settings'; +import SubscriptionSettings from '@/app/ui/settings/subscription-settings'; +import APISettings from '@/app/ui/settings/api-settings'; +import LastActivitySettings from '@/app/ui/settings/last-activity-settings'; +import DangerZone from '@/app/ui/settings/danger-zone'; + +export default function Home() { + return ( + <> +

⚙️ Настройки аккаунта

+
+ + + + + + +
+ + + ) +} \ No newline at end of file diff --git a/src/app/styles/global-styles.scss b/src/app/styles/global-styles.scss index 9197429..726d045 100644 --- a/src/app/styles/global-styles.scss +++ b/src/app/styles/global-styles.scss @@ -1,5 +1,6 @@ @use './header.scss'; @use './dashboard.scss'; +@use './settings.scss'; .btn { padding: 12px 24px; @@ -26,6 +27,27 @@ } } +.btn-secondary { + background: #f3f4f6; + color: #374151; + border: 2px solid transparent; + + &:hover { + background: #e5e7eb; + } +} + +.btn-outline { + background: transparent; + border: 2px solid #6366f1; + color: #6366f1; + + &:hover { + background: #6366f1; + color: white; + } +} + .divider { text-align: center; margin: 20px 0; @@ -48,4 +70,11 @@ padding: 0 15px; position: relative; } +} + +.settings-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); + gap: 30px; + margin-bottom: 30px; } \ No newline at end of file diff --git a/src/app/styles/settings.scss b/src/app/styles/settings.scss new file mode 100644 index 0000000..f1c1ffb --- /dev/null +++ b/src/app/styles/settings.scss @@ -0,0 +1,281 @@ +.settings-form { + background: white; + border-radius: 20px; + padding: 0; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); + border: 1px solid #e2e8f0; + transition: all 0.3s ease; + overflow: hidden; +} + +.form-section { + padding: 30px; + margin-bottom: 30px; + + &-title { + font-size: 18px; + font-weight: 600; + margin-bottom: 20px; + color: #1e293b; + display: flex; + align-items: center; + gap: 10px; + border-bottom: 2px solid #f3f4f6; + padding-bottom: 10px; + } + + .form-group { + margin-bottom: 20px; + + small { + color: #6b7280; + font-size: 12px; + } + } + + .form-label { + display: block; + margin-bottom: 8px; + font-weight: 500; + color: #374151; + font-size: 14px; + + &:has(.toggle-switch) { + display: flex; + align-items: center; + justify-content: space-between; + cursor: pointer; + } + } + + .toggle-switch { + position: relative; + display: inline-block; + width: 50px; + height: 24px; + + input { + opacity: 0; + width: 0; + height: 0; + } + } + + input:checked+.toggle-slider { + background-color: #6366f1; + + &::before { + transform: translateX(26px); + } + } + + .toggle-slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + transition: .4s; + border-radius: 24px; + + &::before { + position: absolute; + content: ""; + height: 18px; + width: 18px; + left: 3px; + bottom: 3px; + background-color: white; + transition: .4s; + border-radius: 50%; + } + } + + .form-input, + .form-select, + .form-textarea { + width: 100%; + padding: 12px 16px; + border: 2px solid #e5e7eb; + border-radius: 10px; + font-size: 14px; + transition: all 0.3s; + background: #f9fafb; + + &:focus { + outline: none; + border-color: #6366f1; + background: white; + box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1); + } + } + + .subscription-info { + background: #f0fdf4; + border-radius: 15px; + padding: 20px; + margin-bottom: 20px; + border-left: 4px solid #10b981; + + .subscription-info-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 15px; + + p { + color: #047857; + font-size: 14px; + } + } + + .subscription-info-title { + color: #065f46; + font-size: 18px; + margin-bottom: 5px; + font-weight: 700; + } + + .subscription-info-main { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); + gap: 15px; + font-size: 13px; + } + + .subscription-info-item { + div { + color: #047857; + font-weight: 600; + } + + span { + color: #065f46; + } + } + } + + .subscription-info-footer { + display: flex; + gap: 10px; + flex-wrap: wrap; + } + + .api-key-info { + display: flex; + gap: 10px; + margin-bottom: 15px; + + .form-input { + font-family: monospace; + background: #f9fafb; + } + } + + .api-key-info-wrapper { + .btn-outline { + display: inline; + } + + small { + color: #6b7280; + font-size: 12px; + display: block; + margin-top: 10px; + } + + .api-key-info-documentation { + background: #f0f9ff; + border-radius: 10px; + padding: 15px; + margin-top: 15px; + + h4 { + color: #1e40af; + margin-bottom: 10px; + font-size: 14px; + font-weight: bold; + } + + p { + color: #1e3a8a; + font-size: 13px; + line-height: 1.5; + } + + a { + color: #2563eb; + text-decoration: underline; + } + } + } + + .last-activiti-wrapper { + .no-activiti { + text-align: center; + color: #64748b; + padding: 20px; + } + } +} + +.danger-zone { + background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%); + border: 2px solid #ef4444; + border-radius: 15px; + padding: 25px; + margin-top: 20px; + + &-remove-account { + background: #fef2f2; + border: 1px solid #fecaca; + border-radius: 10px; + padding: 20px; + margin-bottom: 20px; + + .btn { + background: #dc2626; + color: white; + border: 2px solid #dc2626; + } + } + + &-reset-settings { + background: #fef3c7; + border: 1px solid #fbbf24; + border-radius: 10px; + padding: 20px; + + .btn { + background: transparent; + color: #f59e0b; + border: 2px solid #f59e0b; + + &:hover { + background: #f59e0b; + color: #fef3c7; + } + } + } + + h3 { + color: #dc2626; + margin-bottom: 15px; + font-weight: bold; + font-size: 1.17em; + } + + h4 { + color: #991b1b; + margin-bottom: 10px; + font-weight: bold; + } + + p { + color: #7f1d1d; + font-size: 14px; + margin-bottom: 15px; + } +} \ No newline at end of file diff --git a/src/app/ui/header/headerPanel.tsx b/src/app/ui/header/headerPanel.tsx index 3cc3e3e..a7106dc 100644 --- a/src/app/ui/header/headerPanel.tsx +++ b/src/app/ui/header/headerPanel.tsx @@ -25,7 +25,7 @@ export default function HeaderPanel() { diff --git a/src/app/ui/header/notificationsButton.tsx b/src/app/ui/header/notificationsButton.tsx index 0238da8..e7ba067 100644 --- a/src/app/ui/header/notificationsButton.tsx +++ b/src/app/ui/header/notificationsButton.tsx @@ -76,7 +76,7 @@ export default function NotificationsButton() {

Нет данных

)}
- Посмотреть все + Посмотреть все
)} diff --git a/src/app/ui/nav-links.tsx b/src/app/ui/nav-links.tsx index 8a04abe..1033703 100644 --- a/src/app/ui/nav-links.tsx +++ b/src/app/ui/nav-links.tsx @@ -16,7 +16,7 @@ const links = [ }, { name: 'Настройка', - href: '/pages/page2', + href: '/pages/settings', img: 'M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.82,11.69,4.82,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z' }, { diff --git a/src/app/ui/register-form.tsx b/src/app/ui/register-form.tsx index e34f2d6..7d2a9d6 100644 --- a/src/app/ui/register-form.tsx +++ b/src/app/ui/register-form.tsx @@ -24,7 +24,7 @@ export default function RegisterForm() { > Полное имя - + {errorMessage?.full_name && (

{errorMessage!.full_name}

)} @@ -48,7 +48,7 @@ export default function RegisterForm() { > Компания - +
diff --git a/src/app/ui/settings/api-settings.tsx b/src/app/ui/settings/api-settings.tsx new file mode 100644 index 0000000..88e36fc --- /dev/null +++ b/src/app/ui/settings/api-settings.tsx @@ -0,0 +1,38 @@ +import Link from 'next/link'; + +export default function APISettings() { + return ( +
+
+

🔌 API настройки

+
+ +
+
+ + +
+ + + ⚠️ Используйте этот ключ для доступа к API. Не передавайте его третьим лицам. + +
+

+ 📚 Документация API +

+

+ Полная документация API доступна по ссылке: +
+ api.no-copy.ru/docs +

+
+
+
+
+
+ ) +} \ No newline at end of file diff --git a/src/app/ui/settings/danger-zone.tsx b/src/app/ui/settings/danger-zone.tsx new file mode 100644 index 0000000..0ccb89d --- /dev/null +++ b/src/app/ui/settings/danger-zone.tsx @@ -0,0 +1,25 @@ +export default function DangerZone() { + return ( +
+

⚠️ Опасная зона

+
+

+ 🗑️ Удаление аккаунта +

+

+ ⚠️ Удаление аккаунта приведет к безвозвратной потере всех данных, включая загруженный контент, отчеты и настройки. Это действие нельзя отменить. +

+ +
+
+

+ 🔄 Сброс всех настроек +

+

+ 🔧 Восстановить все настройки аккаунта к значениям по умолчанию. +

+ +
+
+ ) +} \ No newline at end of file diff --git a/src/app/ui/settings/last-activity-settings.tsx b/src/app/ui/settings/last-activity-settings.tsx new file mode 100644 index 0000000..44247c1 --- /dev/null +++ b/src/app/ui/settings/last-activity-settings.tsx @@ -0,0 +1,14 @@ +export default function LastActivitySettings() { + return ( +
+
+

🕒 Последняя активность

+
+
+ 📝 Пока нет записей о активности +
+
+
+
+ ) +} \ No newline at end of file diff --git a/src/app/ui/settings/notifications-monitoring-settings.tsx b/src/app/ui/settings/notifications-monitoring-settings.tsx new file mode 100644 index 0000000..39a3a7a --- /dev/null +++ b/src/app/ui/settings/notifications-monitoring-settings.tsx @@ -0,0 +1,97 @@ +'use client' + +import { useActionState, useState } from 'react'; + +export default function NotificationsMonitoringSettings() { + const [errorMessage, formAction, isPending] = useActionState( + (state: void | undefined, formData: FormData) => { + console.log(formData); + }, + undefined + ); + + const [selectedMonitoringValue, setSelectedMonitoringValue] = useState('weekly'); + const [selectedWatermarkValue, setSelectedWatermarkValue] = useState('high'); + + return ( +
+
+

🔔 Уведомления и мониторинг

+
+
+ + Получать уведомления о нарушениях на email +
+
+ + Критически важные уведомления по SMS +
+
+ + Автоматическая проверка контента в интернете +
+ +
+ + +
+ +
+ + +
+ + +
+
+
+ ) +} \ No newline at end of file diff --git a/src/app/ui/settings/personal-data-settings.tsx b/src/app/ui/settings/personal-data-settings.tsx new file mode 100644 index 0000000..e150141 --- /dev/null +++ b/src/app/ui/settings/personal-data-settings.tsx @@ -0,0 +1,71 @@ +'use client' + +import { useActionState, useState } from 'react' + +export default function PersonalDataSettings() { + const [errorMessage, formAction, isPending] = useActionState( + (state: void | undefined, formData: FormData) => { + console.log(formData); + }, + undefined + ); + + const [selectedValue, setSelectedValue] = useState('male'); + + return ( +
+
+

👤 Персональные данные

+
+
+ + +
+
+ + +
+
+ + + + Email нельзя изменить. Обратитесь в поддержку. + +
+
+ + +
+
+ + +
+
+ + + + Используется для отправки поздравления + +
+
+ + + + Заполняется автоматически из даты рождения + +
+ + +
+
+
+ ) +} \ No newline at end of file diff --git a/src/app/ui/settings/safety-settings.tsx b/src/app/ui/settings/safety-settings.tsx new file mode 100644 index 0000000..8695e07 --- /dev/null +++ b/src/app/ui/settings/safety-settings.tsx @@ -0,0 +1,36 @@ +'use client' + +import { useActionState, useState } from 'react'; + +export default function SafetySetting() { + const [errorMessage, formAction, isPending] = useActionState( + (state: void | undefined, formData: FormData) => { + console.log(formData); + }, + undefined + ); + + return ( +
+
+

🔐 Безопасность

+
+
+ + +
+
+ + + Минимум 6 символов +
+
+ + +
+ +
+
+
+ ) +} \ No newline at end of file diff --git a/src/app/ui/settings/subscription-settings.tsx b/src/app/ui/settings/subscription-settings.tsx new file mode 100644 index 0000000..2d0689a --- /dev/null +++ b/src/app/ui/settings/subscription-settings.tsx @@ -0,0 +1,50 @@ +export default function SubscriptionSettings() { + return ( +
+
+

💎 Подписка

+
+
+
+

🎯 Подписка "ПРОФИ"

+

📅 Активна до 10.06.2028

+
+
+
2,000
+

файлов в месяц

+
+
+
+
+
💾 Хранилище
+ 20 ГБ +
+
+
🔌 API доступ
+ Включен +
+
+
🎧 Поддержка
+ 24/7 +
+
+
+ +
+ + + + +
+
+
+ ) +} \ No newline at end of file