update token life extension
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
'use server'
|
'use server'
|
||||||
import { getSessionData } 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 {tokenLifeExtension} from '@/app/actions/auth';
|
import { tokenLifeExtension } from '@/app/actions/auth';
|
||||||
|
import { redirect } from 'next/navigation';
|
||||||
|
|
||||||
export async function getUserData() {
|
export async function getUserData() {
|
||||||
const userEmail = await getSessionData('email');
|
const userEmail = await getSessionData('email');
|
||||||
@@ -55,6 +56,8 @@ export async function getUserFilesInfo() {
|
|||||||
const parsed = await response.json();
|
const parsed = await response.json();
|
||||||
if (parsed.message_code === 0) {
|
if (parsed.message_code === 0) {
|
||||||
return parsed.message_body;
|
return parsed.message_body;
|
||||||
|
} else if (parsed.message_code === 2) {
|
||||||
|
await deleteSession();
|
||||||
} else {
|
} else {
|
||||||
throw parsed.message_code;
|
throw parsed.message_code;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ export async function logout() {
|
|||||||
throw error;
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
await deleteSession();
|
await deleteSession();
|
||||||
redirect('/login');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,11 +315,12 @@ export async function tokenLifeExtension() {
|
|||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const parsed = await response.json();
|
const parsed = await response.json();
|
||||||
await updateSession();
|
if (parsed.message_code === 0) {
|
||||||
|
await updateSession(parsed.message_body.token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await deleteSession();
|
await deleteSession();
|
||||||
redirect('/login');
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-10
@@ -3,6 +3,7 @@
|
|||||||
/* import 'server-only'; */
|
/* import 'server-only'; */
|
||||||
import { cookies } from 'next/headers'
|
import { cookies } from 'next/headers'
|
||||||
import { SignJWT, jwtVerify } from 'jose'
|
import { SignJWT, jwtVerify } from 'jose'
|
||||||
|
import { redirect } from 'next/navigation';
|
||||||
|
|
||||||
/* const secretKey = process.env.SESSION_SECRET */
|
/* const secretKey = process.env.SESSION_SECRET */
|
||||||
const secretKey = 'AAA+sq1yKte/gMgUUu/B/OyXqr45/LMYplPVOlWc+uo='
|
const secretKey = 'AAA+sq1yKte/gMgUUu/B/OyXqr45/LMYplPVOlWc+uo='
|
||||||
@@ -28,7 +29,7 @@ export async function decrypt(session: string | undefined = '') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function createSession(token: string, email: string) {
|
export async function createSession(token: string, email: string) {
|
||||||
const expiresAt = new Date(Date.now() + 60 * 60 * 1000);
|
const expiresAt = new Date(Date.now() + 50 * 60 * 1000);
|
||||||
const session = await encrypt({
|
const session = await encrypt({
|
||||||
token,
|
token,
|
||||||
email,
|
email,
|
||||||
@@ -45,21 +46,32 @@ export async function createSession(token: string, email: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateSession() {
|
export async function updateSession(newToken: string) {
|
||||||
const session = (await cookies()).get('session')?.value
|
const cookieStore = await cookies();
|
||||||
const payload = await decrypt(session)
|
const session = cookieStore.get('session')?.value;
|
||||||
|
|
||||||
if (!session || !payload) {
|
if (!session) {
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const expiresAt = new Date(Date.now() + 60 * 60 * 1000);
|
const payload = await decrypt(session);
|
||||||
|
|
||||||
const cookieStore = await cookies()
|
if (!payload) {
|
||||||
cookieStore.set('session', session, {
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedPayload = {
|
||||||
|
...payload,
|
||||||
|
token: newToken,
|
||||||
|
expiresAt: new Date(Date.now() + 50 * 60 * 1000)
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedSession = await encrypt(updatedPayload);
|
||||||
|
|
||||||
|
cookieStore.set('session', updatedSession, {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
secure: false,
|
secure: false,
|
||||||
expires: expiresAt,
|
expires: updatedPayload.expiresAt,
|
||||||
sameSite: 'lax',
|
sameSite: 'lax',
|
||||||
path: '/',
|
path: '/',
|
||||||
});
|
});
|
||||||
@@ -84,6 +96,8 @@ export async function getSessionData(type: 'token' | 'email'): Promise<string |
|
|||||||
|
|
||||||
|
|
||||||
export async function deleteSession() {
|
export async function deleteSession() {
|
||||||
|
console.log('delete session')
|
||||||
const cookieStore = await cookies()
|
const cookieStore = await cookies()
|
||||||
cookieStore.delete('session');
|
cookieStore.delete('session');
|
||||||
|
redirect('/login');
|
||||||
}
|
}
|
||||||
@@ -251,6 +251,7 @@
|
|||||||
height: 100vh;
|
height: 100vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
|
border-radius: 0 30px 30px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link {
|
.nav-link {
|
||||||
|
|||||||
@@ -24,20 +24,20 @@ export default function DashboardFilesInfo() {
|
|||||||
<div className="stat-type">
|
<div className="stat-type">
|
||||||
{t('images')}
|
{t('images')}
|
||||||
</div>
|
</div>
|
||||||
<div className="stat-value">{filesInfo.images_quantity ? filesInfo.images_quantity : 0}</div>
|
<div className="stat-value">{filesInfo?.images_quantity ? filesInfo?.images_quantity : 0}</div>
|
||||||
<div className="stat-label">{t('your-image')}</div>
|
<div className="stat-label">{t('your-image')}</div>
|
||||||
<div className="type-card-stats">
|
<div className="type-card-stats">
|
||||||
<div className="type-card-stat-row">
|
<div className="type-card-stat-row">
|
||||||
<span className="type-card-stat-label">{t('size')}</span>
|
<span className="type-card-stat-label">{t('size')}</span>
|
||||||
<span className="type-card-stat-value">{filesInfo.images_size ? convertBytes(filesInfo.images_size) : 0}</span>
|
<span className="type-card-stat-value">{filesInfo?.images_size ? convertBytes(filesInfo?.images_size) : 0}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="type-card-stat-row">
|
<div className="type-card-stat-row">
|
||||||
<span className="type-card-stat-label">{t('checks')}</span>
|
<span className="type-card-stat-label">{t('checks')}</span>
|
||||||
<span className="type-card-stat-value">{filesInfo.images_check ? filesInfo.images_check : 0}</span>
|
<span className="type-card-stat-value">{filesInfo?.images_check ? filesInfo?.images_check : 0}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="type-card-stat-row">
|
<div className="type-card-stat-row">
|
||||||
<span className="type-card-stat-label">{t('violations')}</span>
|
<span className="type-card-stat-label">{t('violations')}</span>
|
||||||
<span className="type-card-stat-value">{filesInfo.images_violations ? filesInfo.images_violations : 0}</span>
|
<span className="type-card-stat-value">{filesInfo?.images_violations ? filesInfo?.images_violations : 0}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -46,20 +46,20 @@ export default function DashboardFilesInfo() {
|
|||||||
<div className="stat-type">
|
<div className="stat-type">
|
||||||
{t('videos')}
|
{t('videos')}
|
||||||
</div>
|
</div>
|
||||||
<div className="stat-value">{filesInfo.videos_quantity ? filesInfo.videos_quantity : 0}</div>
|
<div className="stat-value">{filesInfo?.videos_quantity ? filesInfo?.videos_quantity : 0}</div>
|
||||||
<div className="stat-label">{t('your-videos')}</div>
|
<div className="stat-label">{t('your-videos')}</div>
|
||||||
<div className="type-card-stats">
|
<div className="type-card-stats">
|
||||||
<div className="type-card-stat-row">
|
<div className="type-card-stat-row">
|
||||||
<span className="type-card-stat-label">{t('size')}</span>
|
<span className="type-card-stat-label">{t('size')}</span>
|
||||||
<span className="type-card-stat-value">{filesInfo.videos_size ? convertBytes(filesInfo.videos_size) : 0}</span>
|
<span className="type-card-stat-value">{filesInfo?.videos_size ? convertBytes(filesInfo?.videos_size) : 0}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="type-card-stat-row">
|
<div className="type-card-stat-row">
|
||||||
<span className="type-card-stat-label">{t('checks')}</span>
|
<span className="type-card-stat-label">{t('checks')}</span>
|
||||||
<span className="type-card-stat-value">{filesInfo.videos_check ? filesInfo.videos_check : 0}</span>
|
<span className="type-card-stat-value">{filesInfo?.videos_check ? filesInfo?.videos_check : 0}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="type-card-stat-row">
|
<div className="type-card-stat-row">
|
||||||
<span className="type-card-stat-label">{t('violations')}</span>
|
<span className="type-card-stat-label">{t('violations')}</span>
|
||||||
<span className="type-card-stat-value">{filesInfo.videos_violations ? filesInfo.videos_violations : 0}</span>
|
<span className="type-card-stat-value">{filesInfo?.videos_violations ? filesInfo?.videos_violations : 0}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -68,20 +68,20 @@ export default function DashboardFilesInfo() {
|
|||||||
<div className="stat-type">
|
<div className="stat-type">
|
||||||
{t('audios')}
|
{t('audios')}
|
||||||
</div>
|
</div>
|
||||||
<div className="stat-value">{filesInfo.audios_quantity ? filesInfo.audios_quantity : 0}</div>
|
<div className="stat-value">{filesInfo?.audios_quantity ? filesInfo?.audios_quantity : 0}</div>
|
||||||
<div className="stat-label">{t('your-audios')}</div>
|
<div className="stat-label">{t('your-audios')}</div>
|
||||||
<div className="type-card-stats">
|
<div className="type-card-stats">
|
||||||
<div className="type-card-stat-row">
|
<div className="type-card-stat-row">
|
||||||
<span className="type-card-stat-label">{t('size')}</span>
|
<span className="type-card-stat-label">{t('size')}</span>
|
||||||
<span className="type-card-stat-value">{filesInfo.audios_size ? convertBytes(filesInfo.audios_size) : 0}</span>
|
<span className="type-card-stat-value">{filesInfo?.audios_size ? convertBytes(filesInfo?.audios_size) : 0}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="type-card-stat-row">
|
<div className="type-card-stat-row">
|
||||||
<span className="type-card-stat-label">{t('checks')}</span>
|
<span className="type-card-stat-label">{t('checks')}</span>
|
||||||
<span className="type-card-stat-value">{filesInfo.audios_check ? filesInfo.audios_check : 0}</span>
|
<span className="type-card-stat-value">{filesInfo?.audios_check ? filesInfo?.audios_check : 0}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="type-card-stat-row">
|
<div className="type-card-stat-row">
|
||||||
<span className="type-card-stat-label">{t('violations')}</span>
|
<span className="type-card-stat-label">{t('violations')}</span>
|
||||||
<span className="type-card-stat-value">{filesInfo.audios_violations ? filesInfo.audios_violations : 0}</span>
|
<span className="type-card-stat-value">{filesInfo?.audios_violations ? filesInfo?.audios_violations : 0}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -90,20 +90,20 @@ export default function DashboardFilesInfo() {
|
|||||||
<div className="stat-type">
|
<div className="stat-type">
|
||||||
{t('documents')}
|
{t('documents')}
|
||||||
</div>
|
</div>
|
||||||
<div className="stat-value">{filesInfo.documents_quantity ? filesInfo.documents_quantity : 0}</div>
|
<div className="stat-value">{filesInfo?.documents_quantity ? filesInfo?.documents_quantity : 0}</div>
|
||||||
<div className="stat-label">{t('your-documents')}</div>
|
<div className="stat-label">{t('your-documents')}</div>
|
||||||
<div className="type-card-stats">
|
<div className="type-card-stats">
|
||||||
<div className="type-card-stat-row">
|
<div className="type-card-stat-row">
|
||||||
<span className="type-card-stat-label">{t('size')}</span>
|
<span className="type-card-stat-label">{t('size')}</span>
|
||||||
<span className="type-card-stat-value">{filesInfo.documents_check ? convertBytes(filesInfo.documents_check) : 0}</span>
|
<span className="type-card-stat-value">{filesInfo?.documents_check ? convertBytes(filesInfo?.documents_check) : 0}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="type-card-stat-row">
|
<div className="type-card-stat-row">
|
||||||
<span className="type-card-stat-label">{t('checks')}</span>
|
<span className="type-card-stat-label">{t('checks')}</span>
|
||||||
<span className="type-card-stat-value">{filesInfo.documents_check ? filesInfo.documents_check : 0}</span>
|
<span className="type-card-stat-value">{filesInfo?.documents_check ? filesInfo?.documents_check : 0}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="type-card-stat-row">
|
<div className="type-card-stat-row">
|
||||||
<span className="type-card-stat-label">{t('violations')}</span>
|
<span className="type-card-stat-label">{t('violations')}</span>
|
||||||
<span className="type-card-stat-value">{filesInfo.documents_violations ? filesInfo.documents_violations : 0}</span>
|
<span className="type-card-stat-value">{filesInfo?.documents_violations ? filesInfo?.documents_violations : 0}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export default function DashboardUserStats() {
|
|||||||
|
|
||||||
<div className="stat-card violations">
|
<div className="stat-card violations">
|
||||||
<div className="stat-type">НАРУШЕНИЯ</div>
|
<div className="stat-type">НАРУШЕНИЯ</div>
|
||||||
<div className="stat-value">{filesInfo.all_files_violations ? filesInfo.all_files_violations : 0}</div>
|
<div className="stat-value">{filesInfo?.all_files_violations ? filesInfo?.all_files_violations : 0}</div>
|
||||||
<div className="stat-label">Требуют внимания</div>
|
<div className="stat-label">Требуют внимания</div>
|
||||||
<div className="stat-icon">⚠️</div>
|
<div className="stat-icon">⚠️</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -45,7 +45,7 @@ export default function DashboardUserStats() {
|
|||||||
<div className="stat-card storage">
|
<div className="stat-card storage">
|
||||||
<div className="stat-type">ХРАНИЛИЩЕ</div>
|
<div className="stat-type">ХРАНИЛИЩЕ</div>
|
||||||
<div className="stat-value">
|
<div className="stat-value">
|
||||||
{filesInfo.all_files_size ? convertBytes(filesInfo.all_files_size) : 0}
|
{filesInfo?.all_files_size ? convertBytes(filesInfo?.all_files_size) : 0}
|
||||||
</div>
|
</div>
|
||||||
<div className="stat-label">Использовано места</div>
|
<div className="stat-label">Использовано места</div>
|
||||||
<div className="stat-icon">💾</div>
|
<div className="stat-icon">💾</div>
|
||||||
|
|||||||
@@ -46,10 +46,10 @@ export default function StatsGrid() {
|
|||||||
{t('images')}
|
{t('images')}
|
||||||
</div>
|
</div>
|
||||||
<div className="stats-item second-row">
|
<div className="stats-item second-row">
|
||||||
{filesInfo.images_quantity ? filesInfo.images_quantity : 0}
|
{filesInfo?.images_quantity ? filesInfo?.images_quantity : 0}
|
||||||
</div>
|
</div>
|
||||||
<div className="stats-item second-row">
|
<div className="stats-item second-row">
|
||||||
{filesInfo.images_size ? convertBytes(filesInfo.images_size) : 0}
|
{filesInfo?.images_size ? convertBytes(filesInfo?.images_size) : 0}
|
||||||
</div>
|
</div>
|
||||||
<div className="stats-item second-row">
|
<div className="stats-item second-row">
|
||||||
0
|
0
|
||||||
@@ -63,10 +63,10 @@ export default function StatsGrid() {
|
|||||||
{t('videos')}
|
{t('videos')}
|
||||||
</div>
|
</div>
|
||||||
<div className="stats-item">
|
<div className="stats-item">
|
||||||
{filesInfo.videos_quantity ? filesInfo.videos_quantity : 0}
|
{filesInfo?.videos_quantity ? filesInfo?.videos_quantity : 0}
|
||||||
</div>
|
</div>
|
||||||
<div className="stats-item">
|
<div className="stats-item">
|
||||||
{filesInfo.videos_size ? convertBytes(filesInfo.videos_size) : 0}
|
{filesInfo?.videos_size ? convertBytes(filesInfo?.videos_size) : 0}
|
||||||
</div>
|
</div>
|
||||||
<div className="stats-item">
|
<div className="stats-item">
|
||||||
0
|
0
|
||||||
@@ -80,10 +80,10 @@ export default function StatsGrid() {
|
|||||||
{t('audios')}
|
{t('audios')}
|
||||||
</div>
|
</div>
|
||||||
<div className="stats-item last-row">
|
<div className="stats-item last-row">
|
||||||
{filesInfo.audios_quantity ? filesInfo.audios_quantity : 0}
|
{filesInfo?.audios_quantity ? filesInfo?.audios_quantity : 0}
|
||||||
</div>
|
</div>
|
||||||
<div className="stats-item last-row">
|
<div className="stats-item last-row">
|
||||||
{filesInfo.audios_size ? convertBytes(filesInfo.audios_size) : 0}
|
{filesInfo?.audios_size ? convertBytes(filesInfo?.audios_size) : 0}
|
||||||
</div>
|
</div>
|
||||||
<div className="stats-item last-row">
|
<div className="stats-item last-row">
|
||||||
0
|
0
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ export default function MyContentInfoBlock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sizes = {
|
const sizes = {
|
||||||
images: filesInfo.images_size || 0,
|
images: filesInfo?.images_size || 0,
|
||||||
videos: filesInfo.videos_size || 0,
|
videos: filesInfo?.videos_size || 0,
|
||||||
audios: filesInfo.audios_size || 0,
|
audios: filesInfo?.audios_size || 0,
|
||||||
documents: filesInfo.documents_size || 0,
|
documents: filesInfo?.documents_size || 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const total = filesInfo.all_files_size;
|
const total = filesInfo?.all_files_size;
|
||||||
|
|
||||||
const rawPercents = {
|
const rawPercents = {
|
||||||
images: (sizes.images / total) * 100,
|
images: (sizes.images / total) * 100,
|
||||||
@@ -90,10 +90,10 @@ export default function MyContentInfoBlock() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="file-stat-details">
|
<div className="file-stat-details">
|
||||||
<span className="file-stat-count">
|
<span className="file-stat-count">
|
||||||
{filesInfo.images_quantity || 0} {pluralizeFiles(filesInfo.images_quantity || 0)}
|
{filesInfo?.images_quantity || 0} {pluralizeFiles(filesInfo?.images_quantity || 0)}
|
||||||
</span>
|
</span>
|
||||||
<span className="file-stat-size">
|
<span className="file-stat-size">
|
||||||
{filesInfo.images_size ? convertBytes(filesInfo.images_size) : 0}
|
{filesInfo?.images_size ? convertBytes(filesInfo?.images_size) : 0}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -110,10 +110,10 @@ export default function MyContentInfoBlock() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="file-stat-details">
|
<div className="file-stat-details">
|
||||||
<span className="file-stat-count">
|
<span className="file-stat-count">
|
||||||
{filesInfo.videos_quantity || 0} {pluralizeFiles(filesInfo.videos_quantity || 0)}
|
{filesInfo?.videos_quantity || 0} {pluralizeFiles(filesInfo?.videos_quantity || 0)}
|
||||||
</span>
|
</span>
|
||||||
<span className="file-stat-size">
|
<span className="file-stat-size">
|
||||||
{filesInfo.videos_size ? convertBytes(filesInfo.videos_size) : 0}
|
{filesInfo?.videos_size ? convertBytes(filesInfo?.videos_size) : 0}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -130,10 +130,10 @@ export default function MyContentInfoBlock() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="file-stat-details">
|
<div className="file-stat-details">
|
||||||
<span className="file-stat-count">
|
<span className="file-stat-count">
|
||||||
{filesInfo.audios_quantity || 0} {pluralizeFiles(filesInfo.audios_quantity || 0)}
|
{filesInfo?.audios_quantity || 0} {pluralizeFiles(filesInfo?.audios_quantity || 0)}
|
||||||
</span>
|
</span>
|
||||||
<span className="file-stat-size">
|
<span className="file-stat-size">
|
||||||
{filesInfo.audios_size ? convertBytes(filesInfo.audios_size) : 0}
|
{filesInfo?.audios_size ? convertBytes(filesInfo?.audios_size) : 0}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -150,10 +150,10 @@ export default function MyContentInfoBlock() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="file-stat-details">
|
<div className="file-stat-details">
|
||||||
<span className="file-stat-count">
|
<span className="file-stat-count">
|
||||||
{filesInfo.documents_quantity || 0} {pluralizeFiles(filesInfo.documents_quantity || 0)}
|
{filesInfo?.documents_quantity || 0} {pluralizeFiles(filesInfo?.documents_quantity || 0)}
|
||||||
</span>
|
</span>
|
||||||
<span className="file-stat-size">
|
<span className="file-stat-size">
|
||||||
{filesInfo.documents_size ? convertBytes(filesInfo.documents_size) : 0}
|
{filesInfo?.documents_size ? convertBytes(filesInfo?.documents_size) : 0}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export default function MyContentPageTitleColorFrame({ title, description }: { t
|
|||||||
</div>
|
</div>
|
||||||
<div className="header-stat-divider"></div>
|
<div className="header-stat-divider"></div>
|
||||||
<div className="header-stat-item">
|
<div className="header-stat-item">
|
||||||
<div className="header-stat-value">{filesInfo.all_files_size ? convertBytes(filesInfo.all_files_size) : 0}</div>
|
<div className="header-stat-value">{filesInfo?.all_files_size ? convertBytes(filesInfo?.all_files_size) : 0}</div>
|
||||||
<div className="header-stat-label">Хранилище</div>
|
<div className="header-stat-label">Хранилище</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export default function MyContentStatsOverview() {
|
|||||||
<div className="stat-icon">💾</div>
|
<div className="stat-icon">💾</div>
|
||||||
<div className="stat-trend">+0%</div>
|
<div className="stat-trend">+0%</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="stat-value">{filesInfo.all_files_size ? convertBytes(filesInfo.all_files_size) : 0}</div>
|
<div className="stat-value">{filesInfo?.all_files_size ? convertBytes(filesInfo?.all_files_size) : 0}</div>
|
||||||
<div className="stat-label">Хранилище</div>
|
<div className="stat-label">Хранилище</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user