revert changes
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
'use server'
|
||||
|
||||
import { getSessionData, deleteSession } from '@/app/actions/session';
|
||||
import { testUserData, API_BASE_URL } from '@/app/actions/definitions';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
@@ -170,8 +170,6 @@ export async function registration(
|
||||
|
||||
const validatedFields = SignupFormSchema.safeParse(dataToValidate);
|
||||
|
||||
console.log(`account-type ${accountType}`)
|
||||
|
||||
if (!validatedFields.success) {
|
||||
const errors: Record<string, string> = {}
|
||||
JSON.parse(validatedFields.error.message).forEach((obj: {
|
||||
@@ -199,19 +197,6 @@ export async function registration(
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
return {
|
||||
previousState: {
|
||||
fullName,
|
||||
email,
|
||||
password,
|
||||
confirm_password,
|
||||
phone,
|
||||
agree,
|
||||
...(accountType === 'b2b' && { companyName })
|
||||
}
|
||||
}; */
|
||||
|
||||
try {
|
||||
const { fullName, email, password, phone } = validatedFields.data;
|
||||
const response = await fetch(`${API_BASE_URL}/api/v1/data`, {
|
||||
@@ -243,7 +228,6 @@ export async function registration(
|
||||
|
||||
if (parsed.message_desc === 'Operation successful') {
|
||||
await createSession(parsed.message_body.token, email as string);
|
||||
console.log('succes registration');
|
||||
} else {
|
||||
throw parsed;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@ interface ValidationConfig {
|
||||
|
||||
const defaultConfig = validationConfig as ValidationConfig;
|
||||
|
||||
let cachedSignupSchema: any = null;
|
||||
let schemaPromise: Promise<any> | null = null;
|
||||
|
||||
async function loadConfigFromBackend(accountType?: 'b2b' | 'b2c'): Promise<any> {
|
||||
try {
|
||||
const response = await fetch('/api/validation-config');
|
||||
@@ -48,16 +51,22 @@ async function loadConfigFromBackend(accountType?: 'b2b' | 'b2c'): Promise<any>
|
||||
}
|
||||
|
||||
export async function getSignupFormSchema(schemaType?: 'b2b' | 'b2c' | 'resetPassword') {
|
||||
let schemaPromise: Promise<any> | null = null;
|
||||
if (cachedSignupSchema) {
|
||||
return cachedSignupSchema;
|
||||
}
|
||||
|
||||
schemaPromise = (async () => {
|
||||
const config = await loadConfigFromBackend();
|
||||
if (schemaType === 'resetPassword') {
|
||||
return createValidationSchemaForPssword(config);
|
||||
} else {
|
||||
return createValidationSchema(config, schemaType);
|
||||
}
|
||||
})();
|
||||
if (!schemaPromise) {
|
||||
schemaPromise = (async () => {
|
||||
const config = await loadConfigFromBackend();
|
||||
if (schemaType === 'resetPassword') {
|
||||
cachedSignupSchema = createValidationSchemaForPssword(config);
|
||||
} else {
|
||||
cachedSignupSchema = createValidationSchema(config, schemaType);
|
||||
}
|
||||
|
||||
return cachedSignupSchema;
|
||||
})();
|
||||
}
|
||||
|
||||
return await schemaPromise;
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ export function createValidationSchema(config: ValidationConfig, accountType?: '
|
||||
.trim();
|
||||
}
|
||||
|
||||
// companyName
|
||||
if (config.companyName && accountType === 'b2b') {
|
||||
// fullName
|
||||
if (config.companyName && accountType !== 'b2c') {
|
||||
schema.companyName = z
|
||||
.string()
|
||||
.trim()
|
||||
|
||||
@@ -214,7 +214,6 @@
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
cursor: pointer;
|
||||
overflow: visible;
|
||||
max-width: 350px;
|
||||
|
||||
.plan-header {
|
||||
text-align: center;
|
||||
|
||||
@@ -84,7 +84,7 @@ export default function RegisterForm() {
|
||||
if (fieldName === 'phone') {
|
||||
return schema.safeParse(value.replace(/[-\(\)\s]/g, ''));
|
||||
}
|
||||
if (fieldName === 'companyName') {
|
||||
if (fieldName === 'companyName' && accountType === 'b2c') {
|
||||
return { success: true, data: value };
|
||||
}
|
||||
return schema.safeParse(value);
|
||||
|
||||
@@ -22,7 +22,8 @@ export default function UserMenuButton() {
|
||||
queryFn: () => {
|
||||
return getUserData();
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
useClickOutside(
|
||||
menuRef,
|
||||
|
||||
@@ -1,26 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { getUserData } from '@/app/actions/action';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { convertBytes } from '@/app/lib/convertBytes';
|
||||
|
||||
export default function PaymentTabTariffs() {
|
||||
const {
|
||||
data: userData,
|
||||
isLoading,
|
||||
isError,
|
||||
error
|
||||
} = useQuery({
|
||||
queryKey: ['userData'],
|
||||
queryFn: () => {
|
||||
return getUserData();
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="tab-content">
|
||||
<div className="billing-toggle" style={{ display: 'none' }}>
|
||||
<div className="billing-toggle">
|
||||
<div>
|
||||
<button className="billing-btn active">💳 Помесячно</button>
|
||||
<button className="billing-btn">
|
||||
@@ -30,57 +11,111 @@ export default function PaymentTabTariffs() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="subscription-grid">
|
||||
|
||||
{userData.tariffs?.map(((item: {
|
||||
id: number,
|
||||
name: string,
|
||||
price: number,
|
||||
tokens: number,
|
||||
maxFilesCount: number,
|
||||
diskSize: number
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
className="plan-card animate-card"
|
||||
key={item.id}
|
||||
>
|
||||
<div className="plan-header">
|
||||
<div className="plan-icon">🚀</div>
|
||||
<h3 className="plan-name">
|
||||
{item.name}
|
||||
</h3>
|
||||
<div className="plan-price">
|
||||
{item.price}
|
||||
</div>
|
||||
<div className="plan-period">в месяц</div>
|
||||
<div className="plan-tokens">
|
||||
{item.tokens} токенов включено</div>
|
||||
</div>
|
||||
<ul className="plan-features">
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
{item.maxFilesCount} файлов в месяц
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
{convertBytes(item.diskSize)} хранилища
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
Базовые модули защиты
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
Поддержка 24/7
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon not">✗</span>
|
||||
API доступ
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}))}
|
||||
<div className="plan-card animate-card">
|
||||
<div className="plan-header">
|
||||
<div className="plan-icon">🚀</div>
|
||||
<h3 className="plan-name">СТАРТ</h3>
|
||||
<div className="plan-price">900₽</div>
|
||||
<div className="plan-period">в месяц</div>
|
||||
<div className="plan-tokens">100 токенов включено</div>
|
||||
</div>
|
||||
<ul className="plan-features">
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
100 файлов в месяц
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
1 ГБ хранилища
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
До 10 МБ на файл
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
Базовые модули защиты
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
Поддержка 24/7
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon not">✗</span>
|
||||
API доступ
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="plan-card animate-card">
|
||||
<div className="plan-header">
|
||||
<div className="plan-icon">🚀</div>
|
||||
<h3 className="plan-name">ПРЕМИУМ</h3>
|
||||
<div className="plan-price">3500₽</div>
|
||||
<div className="plan-period">в месяц</div>
|
||||
<div className="plan-tokens">100 токенов включено</div>
|
||||
</div>
|
||||
<ul className="plan-features">
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
100 файлов в месяц
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
1 ГБ хранилища
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
До 10 МБ на файл
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
Базовые модули защиты
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
Поддержка 24/7
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon not">✗</span>
|
||||
API доступ
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="plan-card animate-card">
|
||||
<div className="plan-header">
|
||||
<div className="plan-icon">🚀</div>
|
||||
<h3 className="plan-name">ПРОФИ</h3>
|
||||
<div className="plan-price">9500₽</div>
|
||||
<div className="plan-period">в месяц</div>
|
||||
<div className="plan-tokens">100 токенов включено</div>
|
||||
</div>
|
||||
<ul className="plan-features">
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
100 файлов в месяц
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
1 ГБ хранилища
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
До 10 МБ на файл
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
Базовые модули защиты
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon">✓</span>
|
||||
Поддержка 24/7
|
||||
</li>
|
||||
<li className="plan-feature">
|
||||
<span className="feature-icon not">✗</span>
|
||||
API доступ
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,47 +1,28 @@
|
||||
'use client'
|
||||
|
||||
import { getUserData } from '@/app/actions/action';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useEffect } from 'react';
|
||||
import {convertBytes} from '@/app/lib/convertBytes';
|
||||
|
||||
export default function UserUsage() {
|
||||
const {
|
||||
data: userData,
|
||||
isLoading,
|
||||
isError,
|
||||
error
|
||||
} = useQuery({
|
||||
queryKey: ['userData'],
|
||||
queryFn: () => {
|
||||
return getUserData();
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="usage-stats">
|
||||
<h3>
|
||||
Ваше использование
|
||||
📊 Ваше использование
|
||||
</h3>
|
||||
<div className="stats-grid">
|
||||
<div className="stat-card">
|
||||
<div className="stat-value">0 / {userData?.tariffInfo?.tariff?.maxFilesCount}</div>
|
||||
<div className="stat-value">0 / 2,000</div>
|
||||
<div className="stat-label">Файлов в месяц</div>
|
||||
<div className="progress-bar">
|
||||
<div
|
||||
className="progress-fill"
|
||||
style={{ width: '0%' }}
|
||||
style={{ width: '50%' }}
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<div className="stat-value">0 / {convertBytes(userData?.tariffInfo?.tariff?.diskSize)}</div>
|
||||
<div className="stat-value">0 / 20 ГБ</div>
|
||||
<div className="stat-label">Объём хранилища</div>
|
||||
<div className="progress-bar">
|
||||
<div
|
||||
className="progress-fill"
|
||||
style={{ width: '0%' }}
|
||||
style={{ width: '50%' }}
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@@ -51,9 +32,7 @@ export default function UserUsage() {
|
||||
<div className="stat-label">Токенов на балансе</div>
|
||||
</div>
|
||||
<div className="stat-card">
|
||||
<div className="stat-value">
|
||||
{userData?.tariffInfo?.tariff?.name}
|
||||
</div>
|
||||
<div className="stat-value">ПРОФИ</div>
|
||||
<div className="stat-label">Текущий план</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useActionState, useState, useEffect } from 'react';
|
||||
import { getUserData } from '@/app/actions/action';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useActionState, useState } from 'react'
|
||||
|
||||
export default function PersonalDataSettings() {
|
||||
const [errorMessage, formAction, isPending] = useActionState(
|
||||
@@ -13,23 +11,6 @@ export default function PersonalDataSettings() {
|
||||
undefined
|
||||
);
|
||||
|
||||
const {
|
||||
data: userData,
|
||||
isLoading,
|
||||
isError,
|
||||
error
|
||||
} = useQuery({
|
||||
queryKey: ['userData'],
|
||||
queryFn: () => {
|
||||
return getUserData();
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
console.log('show => userData');
|
||||
console.log(userData);
|
||||
}, [])
|
||||
|
||||
const [selectedValue, setSelectedValue] = useState('male');
|
||||
|
||||
const t = useTranslations('Global');
|
||||
@@ -45,37 +26,19 @@ export default function PersonalDataSettings() {
|
||||
<label className="form-label">
|
||||
{t('full-name')}:
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="full_name"
|
||||
className="form-input"
|
||||
defaultValue={userData.fullName}
|
||||
/>
|
||||
<input type="text" name="full_name" className="form-input" />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="form-label">
|
||||
{t('company')}:
|
||||
</label>
|
||||
<input type="text" name="company" className="form-input" />
|
||||
</div>
|
||||
{userData.company && (
|
||||
<div className="form-group">
|
||||
<label className="form-label">
|
||||
{t('company')}:
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="company"
|
||||
className="form-input"
|
||||
defaultValue={userData.company}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="form-group">
|
||||
<label className="form-label">
|
||||
{t('email')}:
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="email"
|
||||
className="form-input"
|
||||
defaultValue={userData.email}
|
||||
disabled={true}
|
||||
/>
|
||||
<input type="text" name="email" className="form-input" disabled={true}/>
|
||||
<small>
|
||||
{t('email-cant-change')}
|
||||
</small>
|
||||
@@ -84,12 +47,7 @@ export default function PersonalDataSettings() {
|
||||
<label className="form-label">
|
||||
{t('phone')}:
|
||||
</label>
|
||||
<input
|
||||
type="phone"
|
||||
name="phone"
|
||||
className="form-input"
|
||||
defaultValue={userData.phone}
|
||||
/>
|
||||
<input type="phone" name="phone" className="form-input" />
|
||||
</div>
|
||||
<button type="submit" className="btn btn-primary">
|
||||
{t('save-changes')}
|
||||
|
||||
Reference in New Issue
Block a user