add translate and make refactor
This commit is contained in:
@@ -1,12 +1,15 @@
|
|||||||
import ProtectionSummary from '@/app/ui/marking-page/protection-summary';
|
import ProtectionSummary from '@/app/ui/marking-page/protection-summary';
|
||||||
import TestSection from '@/app/ui/marking-page/test-section';
|
import TestSection from '@/app/ui/marking-page/test-section';
|
||||||
import FilesTable from '@/app/ui/dashboard/files-table';
|
import FilesTable from '@/app/ui/dashboard/files-table';
|
||||||
|
import {useTranslations} from 'next-intl';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
|
const t = useTranslations('Global');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="page-title">
|
<div className="page-title">
|
||||||
<h1 >Защита аудио</h1>
|
<h1>{t('audio-protection')}</h1>
|
||||||
</div>
|
</div>
|
||||||
<ProtectionSummary />
|
<ProtectionSummary />
|
||||||
{/* <TestSection /> */}
|
{/* <TestSection /> */}
|
||||||
|
|||||||
@@ -2,13 +2,16 @@ import ProtectionSummary from '@/app/ui/marking-page/protection-summary';
|
|||||||
import TestSection from '@/app/ui/marking-page/test-section';
|
import TestSection from '@/app/ui/marking-page/test-section';
|
||||||
import UploadSectionVideo from '@/app/ui/marking-page/upload-section-video';
|
import UploadSectionVideo from '@/app/ui/marking-page/upload-section-video';
|
||||||
import FilesTable from '@/app/ui/dashboard/files-table';
|
import FilesTable from '@/app/ui/dashboard/files-table';
|
||||||
|
import {useTranslations} from 'next-intl';
|
||||||
|
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
|
const t = useTranslations('Global');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="page-title">
|
<div className="page-title">
|
||||||
<h1 >Защита видео</h1>
|
<h1>{t('video-protection')}</h1>
|
||||||
</div>
|
</div>
|
||||||
<ProtectionSummary />
|
<ProtectionSummary />
|
||||||
<UploadSectionVideo />
|
<UploadSectionVideo />
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
SortingState,
|
SortingState,
|
||||||
ColumnFiltersState,
|
ColumnFiltersState,
|
||||||
} from '@tanstack/react-table';
|
} from '@tanstack/react-table';
|
||||||
import { IconImageFile, IconVideoFile, IconAudioFile, IconEye, IconDownload, IconShield, DoubleArrowRight, ArrowRight, DoubleArrowLeft, ArrowLeft, ArrowUp, ArrowDown, Filter } from '@/app/ui/icons/icons';
|
import { IconImageFile, IconVideoFile, IconAudioFile, IconEye, IconDownload, IconShield, IconDoubleArrowRight, IconArrowRight, IconDoubleArrowLeft, IconArrowLeft, IconArrowUp, IconArrowDown, IconFilter } from '@/app/ui/icons/icons';
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import DropDownList from '@/app/components/dropDownList';
|
import DropDownList from '@/app/components/dropDownList';
|
||||||
|
|
||||||
@@ -101,14 +101,14 @@ export default function TanstakFilesTable() {
|
|||||||
{
|
{
|
||||||
column.getIsSorted() === 'asc' ?
|
column.getIsSorted() === 'asc' ?
|
||||||
<span>
|
<span>
|
||||||
<ArrowUp />
|
<IconArrowUp />
|
||||||
</span>
|
</span>
|
||||||
: column.getIsSorted() === 'desc' ?
|
: column.getIsSorted() === 'desc' ?
|
||||||
<span>
|
<span>
|
||||||
<ArrowDown />
|
<IconArrowDown />
|
||||||
</span>
|
</span>
|
||||||
: <span>
|
: <span>
|
||||||
<Filter />
|
<IconFilter />
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
</button>
|
</button>
|
||||||
@@ -138,14 +138,14 @@ export default function TanstakFilesTable() {
|
|||||||
{
|
{
|
||||||
column.getIsSorted() === 'asc' ?
|
column.getIsSorted() === 'asc' ?
|
||||||
<span>
|
<span>
|
||||||
<ArrowUp />
|
<IconArrowUp />
|
||||||
</span>
|
</span>
|
||||||
: column.getIsSorted() === 'desc' ?
|
: column.getIsSorted() === 'desc' ?
|
||||||
<span>
|
<span>
|
||||||
<ArrowDown />
|
<IconArrowDown />
|
||||||
</span>
|
</span>
|
||||||
: <span>
|
: <span>
|
||||||
<Filter />
|
<IconFilter />
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
</button>
|
</button>
|
||||||
@@ -171,14 +171,14 @@ export default function TanstakFilesTable() {
|
|||||||
{
|
{
|
||||||
column.getIsSorted() === 'asc' ?
|
column.getIsSorted() === 'asc' ?
|
||||||
<span>
|
<span>
|
||||||
<ArrowUp />
|
<IconArrowUp />
|
||||||
</span>
|
</span>
|
||||||
: column.getIsSorted() === 'desc' ?
|
: column.getIsSorted() === 'desc' ?
|
||||||
<span>
|
<span>
|
||||||
<ArrowDown />
|
<IconArrowDown />
|
||||||
</span>
|
</span>
|
||||||
: <span>
|
: <span>
|
||||||
<Filter />
|
<IconFilter />
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
</button>
|
</button>
|
||||||
@@ -204,14 +204,14 @@ export default function TanstakFilesTable() {
|
|||||||
{
|
{
|
||||||
column.getIsSorted() === 'asc' ?
|
column.getIsSorted() === 'asc' ?
|
||||||
<span>
|
<span>
|
||||||
<ArrowUp />
|
<IconArrowUp />
|
||||||
</span>
|
</span>
|
||||||
: column.getIsSorted() === 'desc' ?
|
: column.getIsSorted() === 'desc' ?
|
||||||
<span>
|
<span>
|
||||||
<ArrowDown />
|
<IconArrowDown />
|
||||||
</span>
|
</span>
|
||||||
: <span>
|
: <span>
|
||||||
<Filter />
|
<IconFilter />
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
</button>
|
</button>
|
||||||
@@ -493,14 +493,14 @@ export default function TanstakFilesTable() {
|
|||||||
onClick={() => table.firstPage()}
|
onClick={() => table.firstPage()}
|
||||||
disabled={!table.getCanPreviousPage()}
|
disabled={!table.getCanPreviousPage()}
|
||||||
>
|
>
|
||||||
<DoubleArrowLeft />
|
<IconDoubleArrowLeft />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="px-2 py-1 border rounded-md hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed"
|
className="px-2 py-1 border rounded-md hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
onClick={() => table.previousPage()}
|
onClick={() => table.previousPage()}
|
||||||
disabled={!table.getCanPreviousPage()}
|
disabled={!table.getCanPreviousPage()}
|
||||||
>
|
>
|
||||||
<ArrowLeft />
|
<IconArrowLeft />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
@@ -536,14 +536,14 @@ export default function TanstakFilesTable() {
|
|||||||
onClick={() => table.nextPage()}
|
onClick={() => table.nextPage()}
|
||||||
disabled={!table.getCanNextPage()}
|
disabled={!table.getCanNextPage()}
|
||||||
>
|
>
|
||||||
<ArrowRight />
|
<IconArrowRight />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="px-2 py-1 border rounded-md hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed"
|
className="px-2 py-1 border rounded-md hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
onClick={() => table.lastPage()}
|
onClick={() => table.lastPage()}
|
||||||
disabled={!table.getCanNextPage()}
|
disabled={!table.getCanNextPage()}
|
||||||
>
|
>
|
||||||
<DoubleArrowRight />
|
<IconDoubleArrowRight />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
import { useState, useRef } from 'react';
|
import { useState, useRef } from 'react';
|
||||||
import { fetchFruits } from '@/app/actions/action';
|
import { fetchFruits } from '@/app/actions/action';
|
||||||
import { useClickOutside } from '@/app/hooks/useClickOutside';
|
import { useClickOutside } from '@/app/hooks/useClickOutside';
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import {IconNotification} from '@/app/ui/icons/icons';
|
||||||
|
|
||||||
export default function NotificationsButton() {
|
export default function NotificationsButton() {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
@@ -11,6 +13,7 @@ export default function NotificationsButton() {
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const menuRef = useRef<HTMLDivElement | null>(null);
|
const menuRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
const t = useTranslations('Global');
|
||||||
|
|
||||||
useClickOutside(menuRef, () => {
|
useClickOutside(menuRef, () => {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
@@ -57,26 +60,38 @@ export default function NotificationsButton() {
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className='notification-header'>
|
<div className='notification-header'>
|
||||||
<h4>Уведомления</h4>
|
<h4>
|
||||||
<span className="notification-count">Нет новых</span>
|
{t('notifications')}
|
||||||
|
</h4>
|
||||||
|
<span className="notification-count">
|
||||||
|
{t('no-new')}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{data ? (
|
{data ? (
|
||||||
<div className="notification-list">
|
<div className="notification-list">
|
||||||
<div className="notification-item">
|
<div className="notification-item">
|
||||||
<div className="notification-icon">✅</div>
|
<div className="notification-icon">
|
||||||
|
<IconNotification/>
|
||||||
|
</div>
|
||||||
<div className="notification-content">
|
<div className="notification-content">
|
||||||
<div className="notification-title">Токены добавлены</div>
|
<div className="notification-title">
|
||||||
<div className="notification-text">На ваш баланс добавлено 100 токенов. Теперь вы можете защитить ещё больше файлов!</div>
|
{t('tokens-added')}
|
||||||
<div className="notification-time">4 дн назад</div>
|
</div>
|
||||||
|
<div className="notification-text">{t('added')} 100 {t('tokens')}.</div>
|
||||||
|
<div className="notification-time">4 {t('days-ago')}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{JSON.stringify(data)}
|
{JSON.stringify(data)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<p>Нет данных</p>
|
<p>
|
||||||
|
{t('no-data')}
|
||||||
|
</p>
|
||||||
)}
|
)}
|
||||||
<div className="notification-footer">
|
<div className="notification-footer">
|
||||||
<Link href="/pages/notifications" className="notification-link">Посмотреть все</Link>
|
<Link href="/pages/notifications" className="notification-link">
|
||||||
|
{t('view-all')}
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
+20
-14
@@ -56,45 +56,51 @@ export function IconEye() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DoubleArrowRight() {
|
export function IconDoubleArrowRight() {
|
||||||
return (
|
return (
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M6.41 6L5 7.41L9.58 12L5 16.59L6.41 18l6-6z" /><path fill="currentColor" d="m13 6l-1.41 1.41L16.17 12l-4.58 4.59L13 18l6-6z" /></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="icon"><path fill="currentColor" d="M6.41 6L5 7.41L9.58 12L5 16.59L6.41 18l6-6z" /><path fill="currentColor" d="m13 6l-1.41 1.41L16.17 12l-4.58 4.59L13 18l6-6z" /></svg>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DoubleArrowLeft() {
|
export function IconDoubleArrowLeft() {
|
||||||
return (
|
return (
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M17.59 18L19 16.59L14.42 12L19 7.41L17.59 6l-6 6z" /><path fill="currentColor" d="m11 18l1.41-1.41L7.83 12l4.58-4.59L11 6l-6 6z" /></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="icon"><path fill="currentColor" d="M17.59 18L19 16.59L14.42 12L19 7.41L17.59 6l-6 6z" /><path fill="currentColor" d="m11 18l1.41-1.41L7.83 12l4.58-4.59L11 6l-6 6z" /></svg>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ArrowRight() {
|
export function IconArrowRight() {
|
||||||
return (
|
return (
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M8.59 16.59L13.17 12L8.59 7.41L10 6l6 6l-6 6z" /></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="icon"><path fill="currentColor" d="M8.59 16.59L13.17 12L8.59 7.41L10 6l6 6l-6 6z" /></svg>
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ArrowLeft() {
|
export function IconArrowLeft() {
|
||||||
return (
|
return (
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6l6 6z" /></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="icon"><path fill="currentColor" d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6l6 6z" /></svg>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ArrowUp() {
|
export function IconArrowUp() {
|
||||||
return (
|
return (
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="m7 14l5-5l5 5z" /></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="icon"><path fill="currentColor" d="m7 14l5-5l5 5z" /></svg>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ArrowDown() {
|
export function IconArrowDown() {
|
||||||
return (
|
return (
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="m7 10l5 5l5-5z" /></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="icon"><path fill="currentColor" d="m7 10l5 5l5-5z" /></svg>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Filter() {
|
export function IconFilter() {
|
||||||
return (
|
return (
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M11 18h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1M3 7c0 .55.45 1 1 1h16c.55 0 1-.45 1-1s-.45-1-1-1H4c-.55 0-1 .45-1 1m4 6h10c.55 0 1-.45 1-1s-.45-1-1-1H7c-.55 0-1 .45-1 1s.45 1 1 1" /></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="icon"><path fill="currentColor" d="M11 18h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1M3 7c0 .55.45 1 1 1h16c.55 0 1-.45 1-1s-.45-1-1-1H4c-.55 0-1 .45-1 1m4 6h10c.55 0 1-.45 1-1s-.45-1-1-1H7c-.55 0-1 .45-1 1s.45 1 1 1" /></svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function IconNotification() {
|
||||||
|
return (
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="icon"><g fill="none"><path d="m12.594 23.258l-.012.002l-.071.035l-.02.004l-.014-.004l-.071-.036q-.016-.004-.024.006l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.016-.018m.264-.113l-.014.002l-.184.093l-.01.01l-.003.011l.018.43l.005.012l.008.008l.201.092q.019.005.029-.008l.004-.014l-.034-.614q-.005-.019-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.003-.011l.018-.43l-.003-.012l-.01-.01z" /><path fill="currentColor" d="M12 2a7 7 0 0 0-7 7v3.528a1 1 0 0 1-.105.447l-1.717 3.433A1.1 1.1 0 0 0 4.162 18h15.676a1.1 1.1 0 0 0 .984-1.592l-1.716-3.433a1 1 0 0 1-.106-.447V9a7 7 0 0 0-7-7m0 19a3 3 0 0 1-2.83-2h5.66A3 3 0 0 1 12 21" /></g></svg>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,31 +1,38 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
|
||||||
export default function APISettings() {
|
export default function APISettings() {
|
||||||
|
const t = useTranslations('Global');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="settings-form">
|
<div className="settings-form">
|
||||||
<div className="form-section">
|
<div className="form-section">
|
||||||
<h3 className="form-section-title">🔌 API настройки</h3>
|
<h3 className="form-section-title">
|
||||||
|
{t('api-settings')}
|
||||||
|
</h3>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="form-label">🔑 Ваш API ключ:</label>
|
<label className="form-label">
|
||||||
|
{t('your-api-key')}:
|
||||||
|
</label>
|
||||||
<div className="api-key-info-wrapper">
|
<div className="api-key-info-wrapper">
|
||||||
<div className="api-key-info">
|
<div className="api-key-info">
|
||||||
<input readOnly className="form-input" value="testkey" id="api-key-input"></input>
|
<input readOnly className="form-input" value="testkey" id="api-key-input"></input>
|
||||||
<button type="button" className="btn btn-outline">
|
<button type="button" className="btn btn-outline">
|
||||||
📋 Копировать
|
{t('copy')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" className="btn btn-secondary">
|
<button type="submit" className="btn btn-secondary">
|
||||||
🔄 Обновить ключ
|
🔄 {t('update-key')}
|
||||||
</button>
|
</button>
|
||||||
<small>
|
<small>
|
||||||
⚠️ Используйте этот ключ для доступа к API. Не передавайте его третьим лицам.
|
{t('use-this-key-for-api-access')}
|
||||||
</small>
|
</small>
|
||||||
<div className="api-key-info-documentation">
|
<div className="api-key-info-documentation">
|
||||||
<h4>
|
<h4>
|
||||||
📚 Документация API
|
{t('api-documentation')}
|
||||||
</h4>
|
</h4>
|
||||||
<p>
|
<p>
|
||||||
Полная документация API доступна по ссылке:
|
{t('full-api-documentation-available-at-link')}:
|
||||||
<br />
|
<br />
|
||||||
<Link href={'api.no-copy.ru/docs'}>api.no-copy.ru/docs</Link>
|
<Link href={'api.no-copy.ru/docs'}>api.no-copy.ru/docs</Link>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,24 +1,34 @@
|
|||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
|
||||||
export default function DangerZone() {
|
export default function DangerZone() {
|
||||||
|
const t = useTranslations('Global');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="danger-zone">
|
<div className="danger-zone">
|
||||||
<h3>⚠️ Опасная зона</h3>
|
<h3>
|
||||||
|
{t('danger-zone')}
|
||||||
|
</h3>
|
||||||
<div className="danger-zone-remove-account">
|
<div className="danger-zone-remove-account">
|
||||||
<h4>
|
<h4>
|
||||||
🗑️ Удаление аккаунта
|
{t('account-deletion')}
|
||||||
</h4>
|
</h4>
|
||||||
<p>
|
<p>
|
||||||
⚠️ Удаление аккаунта приведет к безвозвратной потере всех данных, включая загруженный контент, отчеты и настройки. Это действие нельзя отменить.
|
{t('account-deletion-warning')}
|
||||||
</p>
|
</p>
|
||||||
<button className="btn">🗑️ Удалить аккаунт</button>
|
<button className="btn">
|
||||||
|
{t('delete-account')}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="danger-zone-reset-settings">
|
<div className="danger-zone-reset-settings">
|
||||||
<h4>
|
<h4>
|
||||||
🔄 Сброс всех настроек
|
{t('reset-all-settings')}
|
||||||
</h4>
|
</h4>
|
||||||
<p>
|
<p>
|
||||||
🔧 Восстановить все настройки аккаунта к значениям по умолчанию.
|
{t('reset-settings-description')}
|
||||||
</p>
|
</p>
|
||||||
<button className="btn">🔄 Сбросить настройки</button>
|
<button className="btn">
|
||||||
|
{t('reset-settings')}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
|
||||||
export default function LastActivitySettings() {
|
export default function LastActivitySettings() {
|
||||||
|
const t = useTranslations('Global');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="settings-form">
|
<div className="settings-form">
|
||||||
<div className="form-section">
|
<div className="form-section">
|
||||||
<h3 className="form-section-title">🕒 Последняя активность</h3>
|
<h3 className="form-section-title">
|
||||||
|
{t('last-activity')}
|
||||||
|
</h3>
|
||||||
<div className="last-activiti-wrapper">
|
<div className="last-activiti-wrapper">
|
||||||
<div className="no-activiti">
|
<div className="no-activiti">
|
||||||
📝 Пока нет записей о активности
|
{t('no-activity-records-yet')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
import { useActionState, useState } from 'react';
|
import { useActionState, useState } from 'react';
|
||||||
|
|
||||||
export default function NotificationsMonitoringSettings() {
|
export default function NotificationsMonitoringSettings() {
|
||||||
@@ -12,35 +13,48 @@ export default function NotificationsMonitoringSettings() {
|
|||||||
|
|
||||||
const [selectedMonitoringValue, setSelectedMonitoringValue] = useState('weekly');
|
const [selectedMonitoringValue, setSelectedMonitoringValue] = useState('weekly');
|
||||||
const [selectedWatermarkValue, setSelectedWatermarkValue] = useState('high');
|
const [selectedWatermarkValue, setSelectedWatermarkValue] = useState('high');
|
||||||
|
const t = useTranslations('Global');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="settings-form">
|
<div className="settings-form">
|
||||||
<div className="form-section">
|
<div className="form-section">
|
||||||
<h3 className="form-section-title">🔔 Уведомления и мониторинг</h3>
|
<h3 className="form-section-title">
|
||||||
|
{t('notifications-and-monitoring')}
|
||||||
|
</h3>
|
||||||
<form action={formAction}>
|
<form action={formAction}>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="form-label">
|
<label className="form-label">
|
||||||
<span>📧 Email уведомления</span>
|
<span>
|
||||||
|
{t('email-notifications')}
|
||||||
|
</span>
|
||||||
<span className="toggle-switch">
|
<span className="toggle-switch">
|
||||||
<input type="checkbox" name="notification_email" />
|
<input type="checkbox" name="notification_email" />
|
||||||
<span className="toggle-slider"></span>
|
<span className="toggle-slider"></span>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<small>Получать уведомления о нарушениях на email</small>
|
<small>
|
||||||
|
{t('receive-violation-notifications-on-email')}
|
||||||
|
</small>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="form-label">
|
<label className="form-label">
|
||||||
<span>🤖 Автоматический мониторинг</span>
|
<span>
|
||||||
|
{t('automatic-monitoring')}
|
||||||
|
</span>
|
||||||
<span className="toggle-switch">
|
<span className="toggle-switch">
|
||||||
<input type="checkbox" name="auto_monitoring" />
|
<input type="checkbox" name="auto_monitoring" />
|
||||||
<span className="toggle-slider"></span>
|
<span className="toggle-slider"></span>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<small>Автоматическая проверка контента в интернете</small>
|
<small>
|
||||||
|
{t('automatic-content-check-on-internet')}
|
||||||
|
</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="form-label">⏱️ Частота мониторинга:</label>
|
<label className="form-label">
|
||||||
|
{t('monitoring-frequency')}:
|
||||||
|
</label>
|
||||||
<select
|
<select
|
||||||
name="monitoring_frequency"
|
name="monitoring_frequency"
|
||||||
className="form-input"
|
className="form-input"
|
||||||
@@ -48,19 +62,21 @@ export default function NotificationsMonitoringSettings() {
|
|||||||
onChange={(e) => setSelectedMonitoringValue(e.target.value)}
|
onChange={(e) => setSelectedMonitoringValue(e.target.value)}
|
||||||
>
|
>
|
||||||
<option value="daily">
|
<option value="daily">
|
||||||
Ежедневно
|
{t('daily')}
|
||||||
</option>
|
</option>
|
||||||
<option value="weekly">
|
<option value="weekly">
|
||||||
Еженедельно
|
{t('weekly')}
|
||||||
</option>
|
</option>
|
||||||
<option value="monthly">
|
<option value="monthly">
|
||||||
Ежемесячно
|
{t('monthly')}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="form-label">💧 Интенсивность водяного знака:</label>
|
<label className="form-label">
|
||||||
|
{t('watermark-intensity')}:
|
||||||
|
</label>
|
||||||
<select
|
<select
|
||||||
name="watermark_intensity"
|
name="watermark_intensity"
|
||||||
className="form-input"
|
className="form-input"
|
||||||
@@ -68,18 +84,20 @@ export default function NotificationsMonitoringSettings() {
|
|||||||
onChange={(e) => setSelectedWatermarkValue(e.target.value)}
|
onChange={(e) => setSelectedWatermarkValue(e.target.value)}
|
||||||
>
|
>
|
||||||
<option value="low">
|
<option value="low">
|
||||||
Низкая (незаметный)
|
{t('low')}
|
||||||
</option>
|
</option>
|
||||||
<option value="medium">
|
<option value="medium">
|
||||||
Средняя (рекомендуется)
|
{t('medium')}
|
||||||
</option>
|
</option>
|
||||||
<option value="high">
|
<option value="high">
|
||||||
Высокая (максимальная защита)
|
{t('high')}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" className="btn btn-primary">💾 Сохранить изменения</button>
|
<button type="submit" className="btn btn-primary">
|
||||||
|
{t('save-changes')}
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useActionState, useState } from 'react';
|
import { useActionState, useState } from 'react';
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
|
||||||
export default function SafetySetting() {
|
export default function SafetySetting() {
|
||||||
const [errorMessage, formAction, isPending] = useActionState(
|
const [errorMessage, formAction, isPending] = useActionState(
|
||||||
@@ -9,26 +10,39 @@ export default function SafetySetting() {
|
|||||||
},
|
},
|
||||||
undefined
|
undefined
|
||||||
);
|
);
|
||||||
|
const t = useTranslations('Global');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="settings-form">
|
<div className="settings-form">
|
||||||
<div className="form-section">
|
<div className="form-section">
|
||||||
<h3 className="form-section-title">🔐 Безопасность</h3>
|
<h3 className="form-section-title">
|
||||||
|
{t('security')}
|
||||||
|
</h3>
|
||||||
<form action={formAction}>
|
<form action={formAction}>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="form-label">🔓 Текущий пароль:</label>
|
<label className="form-label">
|
||||||
|
{t('current-password')}:
|
||||||
|
</label>
|
||||||
<input type="password" name="current_password" className="form-input" />
|
<input type="password" name="current_password" className="form-input" />
|
||||||
</div>
|
</div>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="form-label">🔓 Новый пароль:</label>
|
<label className="form-label">
|
||||||
|
{t('new-password')}:
|
||||||
|
</label>
|
||||||
<input type="password" name="new_password" className="form-input" />
|
<input type="password" name="new_password" className="form-input" />
|
||||||
<small>Минимум 6 символов</small>
|
<small>
|
||||||
|
{t('minimum-8-characters')}
|
||||||
|
</small>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="form-label">✅ Подтвердите пароль:</label>
|
<label className="form-label">
|
||||||
|
{t('confirm-password')}:
|
||||||
|
</label>
|
||||||
<input type="password" name="confirm_password" className="form-input" />
|
<input type="password" name="confirm_password" className="form-input" />
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" className="btn btn-primary">🔐 Изменить пароль</button>
|
<button type="submit" className="btn btn-primary">
|
||||||
|
{t('change-password')}
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
|
||||||
export default function SubscriptionSettings() {
|
export default function SubscriptionSettings() {
|
||||||
|
const t = useTranslations('Global');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="settings-form">
|
<div className="settings-form">
|
||||||
<div className="form-section">
|
<div className="form-section">
|
||||||
<h3 className="form-section-title">💎 Подписка</h3>
|
<h3 className="form-section-title">
|
||||||
|
{t('subscription')}
|
||||||
|
</h3>
|
||||||
<div className="subscription-info">
|
<div className="subscription-info">
|
||||||
<div className="subscription-info-header">
|
<div className="subscription-info-header">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
"type-filter": "Type filter",
|
"type-filter": "Type filter",
|
||||||
"items-per-page": "Items per page",
|
"items-per-page": "Items per page",
|
||||||
"email": "Email",
|
"email": "Email",
|
||||||
"image-protection": "Защита изображений",
|
"image-protection": "Image protection",
|
||||||
"account-settings": "Account settings",
|
"account-settings": "Account settings",
|
||||||
"personal-data": "Personal data",
|
"personal-data": "Personal data",
|
||||||
"full-name": "Full name",
|
"full-name": "Full name",
|
||||||
@@ -69,7 +69,52 @@
|
|||||||
"female": "Female",
|
"female": "Female",
|
||||||
"used-to-send-congratulations": "Used to send congratulations",
|
"used-to-send-congratulations": "Used to send congratulations",
|
||||||
"automatically-filled-in-based-on-date-of-birth": "Automatically filled in based on date of birth",
|
"automatically-filled-in-based-on-date-of-birth": "Automatically filled in based on date of birth",
|
||||||
"save-changes": "Save changes"
|
"save-changes": "Save changes",
|
||||||
|
"video-protection": "Video protection",
|
||||||
|
"audio-protection": "Audio protection",
|
||||||
|
"notifications-and-monitoring": "Notifications and Monitoring",
|
||||||
|
"email-notifications": "Email Notifications",
|
||||||
|
"receive-violation-notifications-on-email": "Receive violation notifications via email",
|
||||||
|
"automatic-monitoring": "Automatic Monitoring",
|
||||||
|
"automatic-content-check-on-internet": "Automatic content check on the internet",
|
||||||
|
"monitoring-frequency": "Monitoring Frequency",
|
||||||
|
"daily": "Daily",
|
||||||
|
"weekly": "Weekly",
|
||||||
|
"monthly": "Monthly",
|
||||||
|
"watermark-intensity": "Watermark Intensity",
|
||||||
|
"low": "Low",
|
||||||
|
"medium": "Medium",
|
||||||
|
"high": "High",
|
||||||
|
"security": "Security",
|
||||||
|
"current-password": "Current Password",
|
||||||
|
"new-password": "New Password",
|
||||||
|
"minimum-8-characters": "Minimum 8 characters",
|
||||||
|
"confirm-password": "Confirm Password",
|
||||||
|
"change-password": "Change Password",
|
||||||
|
"subscription": "Subscription",
|
||||||
|
"api-settings": "API Settings",
|
||||||
|
"your-api-key": "Your API Key",
|
||||||
|
"copy": "Copy",
|
||||||
|
"update-key": "Update Key",
|
||||||
|
"api-documentation": "API Documentation",
|
||||||
|
"full-api-documentation-available-at-link": "Full API documentation available at the link",
|
||||||
|
"last-activity": "Last Activity",
|
||||||
|
"no-activity-records-yet": "No activity records yet",
|
||||||
|
"use-this-key-for-api-access": "Use this key for API access. Do not share it with third parties.",
|
||||||
|
"danger-zone": "Danger Zone",
|
||||||
|
"account-deletion": "Account Deletion",
|
||||||
|
"account-deletion-warning": "Account deletion will lead to irreversible loss of all data, including uploaded content, reports and settings. This action cannot be undone.",
|
||||||
|
"delete-account": "Delete Account",
|
||||||
|
"reset-all-settings": "Reset All Settings",
|
||||||
|
"reset-settings-description": "Restore all account settings to default values.",
|
||||||
|
"reset-settings": "Reset Settings",
|
||||||
|
"notifications": "Notifications",
|
||||||
|
"no-new": "No new",
|
||||||
|
"tokens-added": "Tokens added",
|
||||||
|
"added": "Added",
|
||||||
|
"no-data": "No data",
|
||||||
|
"view-all": "View all",
|
||||||
|
"days-ago": "days ago"
|
||||||
},
|
},
|
||||||
"Login-register-form": {
|
"Login-register-form": {
|
||||||
"and": "and",
|
"and": "and",
|
||||||
|
|||||||
@@ -69,7 +69,52 @@
|
|||||||
"female": "Женский",
|
"female": "Женский",
|
||||||
"used-to-send-congratulations": "Используется для отправки поздравления",
|
"used-to-send-congratulations": "Используется для отправки поздравления",
|
||||||
"automatically-filled-in-based-on-date-of-birth": "Заполняется автоматически исходя из даты рождения",
|
"automatically-filled-in-based-on-date-of-birth": "Заполняется автоматически исходя из даты рождения",
|
||||||
"save-changes": "Сохранить изменения"
|
"save-changes": "Сохранить изменения",
|
||||||
|
"video-protection": "Защита видео",
|
||||||
|
"audio-protection": "Защита аудио",
|
||||||
|
"notifications-and-monitoring": "Уведомления и мониторинг",
|
||||||
|
"email-notifications": "Email уведомления",
|
||||||
|
"receive-violation-notifications-on-email": "Получать уведомления о нарушениях на email",
|
||||||
|
"automatic-monitoring": "Автоматический мониторинг",
|
||||||
|
"automatic-content-check-on-internet": "Автоматическая проверка контента в интернете",
|
||||||
|
"monitoring-frequency": "Частота мониторинга",
|
||||||
|
"daily": "Ежедневно",
|
||||||
|
"weekly": "Еженедельно",
|
||||||
|
"monthly": "Ежемесячно",
|
||||||
|
"watermark-intensity": "Интенсивность водяного знака",
|
||||||
|
"low": "Низкая",
|
||||||
|
"medium": "Средняя",
|
||||||
|
"high": "Высокая",
|
||||||
|
"security": "Безопасность",
|
||||||
|
"current-password": "Текущий пароль",
|
||||||
|
"new-password": "Новый пароль",
|
||||||
|
"minimum-8-characters": "Минимум 8 символов",
|
||||||
|
"confirm-password": "Подтвердите пароль",
|
||||||
|
"change-password": "Изменить пароль",
|
||||||
|
"subscription": "Подписка",
|
||||||
|
"api-settings": "API настройки",
|
||||||
|
"your-api-key": "Ваш API ключ",
|
||||||
|
"copy": "Копировать",
|
||||||
|
"update-key": "Обновить ключ",
|
||||||
|
"api-documentation": "Документация API",
|
||||||
|
"full-api-documentation-available-at-link": "Полная документация API доступна по ссылке",
|
||||||
|
"last-activity": "Последняя активность",
|
||||||
|
"no-activity-records-yet": "Пока нет записей о активности",
|
||||||
|
"use-this-key-for-api-access": "Используйте этот ключ для доступа к API. Не передавайте его третьим лицам.",
|
||||||
|
"danger-zone": "Опасная зона",
|
||||||
|
"account-deletion": "Удаление аккаунта",
|
||||||
|
"account-deletion-warning": "Удаление аккаунта приведет к безвозвратной потере всех данных, включая загруженный контент, отчеты и настройки. Это действие нельзя отменить.",
|
||||||
|
"delete-account": "Удалить аккаунт",
|
||||||
|
"reset-all-settings": "Сброс всех настроек",
|
||||||
|
"reset-settings-description": "Восстановить все настройки аккаунта к значениям по умолчанию.",
|
||||||
|
"reset-settings": "Сбросить настройки",
|
||||||
|
"notifications": "Уведомления",
|
||||||
|
"no-new": "Нет новых",
|
||||||
|
"tokens-added": "Токены добавлены",
|
||||||
|
"added": "Добавлено",
|
||||||
|
"no-data": "Нет данных",
|
||||||
|
"view-all": "Посмотреть все",
|
||||||
|
"days-ago": "дней назад"
|
||||||
},
|
},
|
||||||
"Login-register-form": {
|
"Login-register-form": {
|
||||||
"and": "и",
|
"and": "и",
|
||||||
|
|||||||
Reference in New Issue
Block a user