add tarrifs #6
@@ -1,4 +1,5 @@
|
|||||||
'use server'
|
'use server'
|
||||||
|
|
||||||
import { getSessionData, deleteSession } from '@/app/actions/session';
|
import { getSessionData, deleteSession } from '@/app/actions/session';
|
||||||
import { testUserData, API_BASE_URL } from '@/app/actions/definitions';
|
import { testUserData, API_BASE_URL } from '@/app/actions/definitions';
|
||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
|
|||||||
@@ -214,6 +214,7 @@
|
|||||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
|
max-width: 350px;
|
||||||
|
|
||||||
.plan-header {
|
.plan-header {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
@@ -1,7 +1,25 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { getUserData } from '@/app/actions/action';
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import { convertBytes } from '@/app/lib/convertBytes';
|
||||||
|
|
||||||
export default function PaymentTabTariffs() {
|
export default function PaymentTabTariffs() {
|
||||||
|
const {
|
||||||
|
data: userData,
|
||||||
|
isLoading,
|
||||||
|
isError,
|
||||||
|
error
|
||||||
|
} = useQuery({
|
||||||
|
queryKey: ['userData'],
|
||||||
|
queryFn: () => {
|
||||||
|
return getUserData();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="tab-content">
|
<div className="tab-content">
|
||||||
<div className="billing-toggle">
|
<div className="billing-toggle" style={{ display: 'none' }}>
|
||||||
<div>
|
<div>
|
||||||
<button className="billing-btn active">💳 Помесячно</button>
|
<button className="billing-btn active">💳 Помесячно</button>
|
||||||
<button className="billing-btn">
|
<button className="billing-btn">
|
||||||
@@ -11,96 +29,40 @@ export default function PaymentTabTariffs() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="subscription-grid">
|
<div className="subscription-grid">
|
||||||
<div className="plan-card animate-card">
|
|
||||||
|
{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-header">
|
||||||
<div className="plan-icon">🚀</div>
|
<div className="plan-icon">🚀</div>
|
||||||
<h3 className="plan-name">СТАРТ</h3>
|
<h3 className="plan-name">
|
||||||
<div className="plan-price">900₽</div>
|
{item.name}
|
||||||
|
</h3>
|
||||||
|
<div className="plan-price">
|
||||||
|
{item.price}
|
||||||
|
</div>
|
||||||
<div className="plan-period">в месяц</div>
|
<div className="plan-period">в месяц</div>
|
||||||
<div className="plan-tokens">100 токенов включено</div>
|
<div className="plan-tokens">
|
||||||
|
{item.tokens} токенов включено</div>
|
||||||
</div>
|
</div>
|
||||||
<ul className="plan-features">
|
<ul className="plan-features">
|
||||||
<li className="plan-feature">
|
<li className="plan-feature">
|
||||||
<span className="feature-icon">✓</span>
|
<span className="feature-icon">✓</span>
|
||||||
100 файлов в месяц
|
{item.maxFilesCount} файлов в месяц
|
||||||
</li>
|
</li>
|
||||||
<li className="plan-feature">
|
<li className="plan-feature">
|
||||||
<span className="feature-icon">✓</span>
|
<span className="feature-icon">✓</span>
|
||||||
1 ГБ хранилища
|
{convertBytes(item.diskSize)} хранилища
|
||||||
</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>
|
||||||
<li className="plan-feature">
|
<li className="plan-feature">
|
||||||
<span className="feature-icon">✓</span>
|
<span className="feature-icon">✓</span>
|
||||||
@@ -116,6 +78,8 @@ export default function PaymentTabTariffs() {
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
)
|
||||||
|
}))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,28 +1,47 @@
|
|||||||
|
'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() {
|
export default function UserUsage() {
|
||||||
|
const {
|
||||||
|
data: userData,
|
||||||
|
isLoading,
|
||||||
|
isError,
|
||||||
|
error
|
||||||
|
} = useQuery({
|
||||||
|
queryKey: ['userData'],
|
||||||
|
queryFn: () => {
|
||||||
|
return getUserData();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="usage-stats">
|
<div className="usage-stats">
|
||||||
<h3>
|
<h3>
|
||||||
📊 Ваше использование
|
Ваше использование
|
||||||
</h3>
|
</h3>
|
||||||
<div className="stats-grid">
|
<div className="stats-grid">
|
||||||
<div className="stat-card">
|
<div className="stat-card">
|
||||||
<div className="stat-value">0 / 2,000</div>
|
<div className="stat-value">0 / {userData?.tariffInfo?.tariff?.maxFilesCount}</div>
|
||||||
<div className="stat-label">Файлов в месяц</div>
|
<div className="stat-label">Файлов в месяц</div>
|
||||||
<div className="progress-bar">
|
<div className="progress-bar">
|
||||||
<div
|
<div
|
||||||
className="progress-fill"
|
className="progress-fill"
|
||||||
style={{ width: '50%' }}
|
style={{ width: '0%' }}
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="stat-card">
|
<div className="stat-card">
|
||||||
<div className="stat-value">0 / 20 ГБ</div>
|
<div className="stat-value">0 / {convertBytes(userData?.tariffInfo?.tariff?.diskSize)}</div>
|
||||||
<div className="stat-label">Объём хранилища</div>
|
<div className="stat-label">Объём хранилища</div>
|
||||||
<div className="progress-bar">
|
<div className="progress-bar">
|
||||||
<div
|
<div
|
||||||
className="progress-fill"
|
className="progress-fill"
|
||||||
style={{ width: '50%' }}
|
style={{ width: '0%' }}
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -32,7 +51,9 @@ export default function UserUsage() {
|
|||||||
<div className="stat-label">Токенов на балансе</div>
|
<div className="stat-label">Токенов на балансе</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="stat-card">
|
<div className="stat-card">
|
||||||
<div className="stat-value">ПРОФИ</div>
|
<div className="stat-value">
|
||||||
|
{userData?.tariffInfo?.tariff?.name}
|
||||||
|
</div>
|
||||||
<div className="stat-label">Текущий план</div>
|
<div className="stat-label">Текущий план</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import { useActionState, useState } from 'react'
|
import { useActionState, useState, useEffect } from 'react';
|
||||||
|
import { getUserData } from '@/app/actions/action';
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
export default function PersonalDataSettings() {
|
export default function PersonalDataSettings() {
|
||||||
const [errorMessage, formAction, isPending] = useActionState(
|
const [errorMessage, formAction, isPending] = useActionState(
|
||||||
@@ -11,6 +13,23 @@ export default function PersonalDataSettings() {
|
|||||||
undefined
|
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 [selectedValue, setSelectedValue] = useState('male');
|
||||||
|
|
||||||
const t = useTranslations('Global');
|
const t = useTranslations('Global');
|
||||||
@@ -26,19 +45,37 @@ export default function PersonalDataSettings() {
|
|||||||
<label className="form-label">
|
<label className="form-label">
|
||||||
{t('full-name')}:
|
{t('full-name')}:
|
||||||
</label>
|
</label>
|
||||||
<input type="text" name="full_name" className="form-input" />
|
<input
|
||||||
|
type="text"
|
||||||
|
name="full_name"
|
||||||
|
className="form-input"
|
||||||
|
defaultValue={userData.fullName}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
{userData.company && (
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="form-label">
|
<label className="form-label">
|
||||||
{t('company')}:
|
{t('company')}:
|
||||||
</label>
|
</label>
|
||||||
<input type="text" name="company" className="form-input" />
|
<input
|
||||||
|
type="text"
|
||||||
|
name="company"
|
||||||
|
className="form-input"
|
||||||
|
defaultValue={userData.company}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="form-label">
|
<label className="form-label">
|
||||||
{t('email')}:
|
{t('email')}:
|
||||||
</label>
|
</label>
|
||||||
<input type="text" name="email" className="form-input" disabled={true}/>
|
<input
|
||||||
|
type="text"
|
||||||
|
name="email"
|
||||||
|
className="form-input"
|
||||||
|
defaultValue={userData.email}
|
||||||
|
disabled={true}
|
||||||
|
/>
|
||||||
<small>
|
<small>
|
||||||
{t('email-cant-change')}
|
{t('email-cant-change')}
|
||||||
</small>
|
</small>
|
||||||
@@ -47,7 +84,12 @@ export default function PersonalDataSettings() {
|
|||||||
<label className="form-label">
|
<label className="form-label">
|
||||||
{t('phone')}:
|
{t('phone')}:
|
||||||
</label>
|
</label>
|
||||||
<input type="phone" name="phone" className="form-input" />
|
<input
|
||||||
|
type="phone"
|
||||||
|
name="phone"
|
||||||
|
className="form-input"
|
||||||
|
defaultValue={userData.phone}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" className="btn btn-primary">
|
<button type="submit" className="btn btn-primary">
|
||||||
{t('save-changes')}
|
{t('save-changes')}
|
||||||
|
|||||||
Reference in New Issue
Block a user