Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
NUMBER_OF_OBJECTS_PER_PAGE,
USER_ROLES_OPTIONS,
} from '../constants/constants';
import { IGetObjects, IGetUser, IUser, User } from '../types/types';
import { IGetObjects, IGetUser, IGetVideoPreviewFilesSize, IUser, IUserSetting, User } from '../types/types';
import axiosClient from './axios';

export async function getStatus(): Promise<{
Expand Down Expand Up @@ -317,7 +317,7 @@ export async function downloadObjectsAsZip({
}): Promise<{ href: string; disposition: string }> {
const res = await axiosClient.post('/object/downloadZip', {
ObjectIds: objectIds,
},{
}, {
responseType: 'blob',
});

Expand Down Expand Up @@ -401,4 +401,33 @@ export const fetchFavoritesIds = async ({
params: { lastId: pageParam, PageSize: NUMBER_OF_OBJECTS_PER_PAGE },
});
return res.data;
};
};

export async function setАllowVideoConversion({
previewConversion
}: {
previewConversion: boolean;
}): Promise<void> {
const response = await axiosClient.put('user/allowvideoconversion/' + previewConversion);

return response.data;
}

export const useUserSettings = () =>
useQuery({
queryKey: ['userSettings'],
queryFn: async (): Promise<IUserSetting> => {
const res = await axiosClient.get('/users/me/settings');
return res.data;
},
});

export async function GetVideoPreviewFilesSize(): Promise<IGetVideoPreviewFilesSize> {
const response = await axiosClient.get('/user/getvideoconversationfilessize');
return response.data;
}

export async function DeleteVideoConversationFiles(): Promise<boolean> {
const response = await axiosClient.delete('/users/deletevideoconversationfiles');
return response.data;
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const ChangePassword = () => {
p: 2,
border: '1px solid rgb(0, 0, 0, 0.12)',
borderRadius: '10px',
maxWidth: '700px',
maxWidth: '1100px',
}}
>
<Accordion sx={{ boxShadow: 'none' }}>
Expand Down
123 changes: 123 additions & 0 deletions src/components/Users/ConversionActivity.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { Box, Button, LinearProgress, Stack, Typography } from '@mui/material';

interface ConversionActivityProps {
status?: 'idle' | 'processing' | 'paused' | 'completed';
userNumberOfFilesToConvert?: number;
userNumberOfPreviewFiles?: number;
progress?: number;
onPause?: () => void;
onCancel?: () => void;
isLoading?: boolean;
}

export const ConversionActivity = ({
status = 'idle',
userNumberOfFilesToConvert = 0,
userNumberOfPreviewFiles = 0,
progress = 0,
onPause,
onCancel,
isLoading = false,
}: ConversionActivityProps) => {
const isPaused = status === 'paused';
const isProcessing = status === 'processing';
const isCompleted = status === 'completed';

const getStatusLabel = () => {
if (isProcessing) return 'Processing';
``;
if (isPaused) return 'Paused';
if (isCompleted) return 'Completed';
return 'Idle';
};

const getStatusColor = () => {
if (isCompleted) return 'success.main';
if (isPaused) return 'warning.main';
return 'text.secondary';
};

return (
<Box sx={{ pt: 3, pb: 3, borderBottom: '1px solid rgb(0, 0, 0, 0.12)' }}>
<Typography variant="subtitle1" fontWeight={600} sx={{ mb: 2 }}>
Conversation Activity
</Typography>

<Typography variant="body2" sx={{ mb: 0.5 }}>
<Typography component="span" fontWeight={600}>
Status:{' '}
</Typography>
<Typography component="span" color={getStatusColor()}>
{getStatusLabel()}
</Typography>
</Typography>
{isProcessing && (
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
{userNumberOfPreviewFiles} out of {userNumberOfFilesToConvert} video
{userNumberOfFilesToConvert !== 1 ? 's are ' : 'is '} in queue
</Typography>
)}

{isCompleted && (
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
Processed {userNumberOfPreviewFiles} video file
{userNumberOfPreviewFiles !== 1 ? 's ' : ' '}
</Typography>
)}

{(isCompleted || isProcessing) && (
<Box sx={{ mb: 2 }}>
<Box
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
mb: 1,
}}
>
<LinearProgress
variant="determinate"
value={progress}
sx={{
flex: 1,
height: 8,
borderRadius: 4,
backgroundColor: 'rgba(0, 0, 0, 0.12)',
'& .MuiLinearProgress-bar': {
borderRadius: 4,
backgroundColor: 'primary.main',
},
}}
/>
<Typography
variant="body2"
fontWeight={600}
sx={{ ml: 2, minWidth: '45px' }}
>
{progress}%
</Typography>
</Box>
</Box>
)}
<Stack direction="row" spacing={2}>
{false && (<Button
variant="outlined"
onClick={onPause}
disabled={!isProcessing || isLoading}
>
{isPaused ? 'Resume' : 'Pause'}
</Button>
)}
{isProcessing && (<Button
variant="outlined"
color="error"
onClick={onCancel}
//disabled={(!isProcessing && !isPaused) || isLoading}
>
Cancel
</Button>
)}
</Stack>
</Box>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import React, { useState } from 'react';
import toast from 'react-hot-toast';
import { useNavigate } from 'react-router-dom';

import { deleteAccount } from '../api/api';
import { deleteAccount } from '../../api/api';

export const DeleteAccount = () => {
const [password, setPassword] = useState('');
Expand Down Expand Up @@ -49,7 +49,7 @@ export const DeleteAccount = () => {
p: 2,
border: '1px solid rgb(0, 0, 0, 0.12)',
borderRadius: '10px',
maxWidth: '700px',
maxWidth: '1100px',
mt: 4,
}}
>
Expand Down
119 changes: 119 additions & 0 deletions src/components/Users/Storage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { Box, Button, LinearProgress, Stack, Typography } from '@mui/material';

interface StorageProps {
userSize?: number;
userUsedQuota: number;
quotaTotal?: number;
userSizeOfFilesToConvert?: number;
onClearTemporaryFiles?: () => void;
toDeletePreviewFiles?: boolean;
}

const formatBytes = (bytes: number): string => {
if (isNaN(bytes)) return '--';

const units = ['B', 'KB', 'MB', 'GB'];
let size = Math.abs(bytes);
let unitIndex = 0;

while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024;
unitIndex++;
}

return `${size.toFixed(2)} ${units[unitIndex]}`;
};

export const Storage = ({
userSize = 0,
userUsedQuota,
quotaTotal = 1,
userSizeOfFilesToConvert = 0,
onClearTemporaryFiles,
toDeletePreviewFiles = false
}: StorageProps) => {
const progress = quotaTotal > 0
? parseInt(
(userSize / quotaTotal) * 100 + '',
10
)
: 0

return (
<Box sx={{ pt: 3 }}>
<Typography variant="subtitle1" fontWeight={600} sx={{ mb: 2 }}>
Storage
</Typography>

<Typography variant="body2" sx={{ mb: 1.5 }}>
<Typography component="span" fontWeight={600}>
Converted video usage:{' '}
</Typography>
<Typography component="span">
{formatBytes(userSize)} of {formatBytes(quotaTotal)}
</Typography>
</Typography>

<Box sx={{ mb: 2 }}>
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 1 }}>
<LinearProgress
variant="determinate"
value={progress}
sx={{
flex: 1,
height: 8,
borderRadius: 4,
backgroundColor: 'rgba(0, 0, 0, 0.12)',
'& .MuiLinearProgress-bar': {
borderRadius: 4,
backgroundColor: 'primary.main'
}
}}
/>
<Typography variant="body2" fontWeight={600} sx={{ ml: 2, minWidth: '45px' }}>
{progress}%
</Typography>
</Box>
</Box>

<Stack spacing={1} sx={{ mb: 2 }}>
<Box>
<Typography variant="body2" color="text.secondary" display="inline">
Original Videos:{' '}
</Typography>
<Typography variant="body2" display="inline" fontWeight={600}>
{formatBytes(userSizeOfFilesToConvert)}
</Typography>
</Box>
<Box>
<Typography variant="body2" color="text.secondary" display="inline">
Converted Videos:{' '}
</Typography>
<Typography variant="body2" display="inline" fontWeight={600}>
{formatBytes(userSize)}
</Typography>
</Box>
</Stack>

{false && toDeletePreviewFiles && (
<Button
variant="outlined"
onClick={onClearTemporaryFiles}
startIcon={
<Typography component="span" sx={{ mr: 0.5 }}>
🗑️
</Typography>
}
>
Clear temporary preview files
</Button>
)}

{userUsedQuota > quotaTotal && (
<Typography variant="body2" color="error.main">
Warning: You have exceeded your storage quota.
</Typography>
)}
</Box>
);
};
Loading
Loading