add monitoring action button for tanstak-table
This commit is contained in:
@@ -2,18 +2,58 @@
|
||||
|
||||
import { YooCheckout, ICreatePayment } from '@a2seven/yoo-checkout';
|
||||
import { getSessionData } from '@/app/actions/session';
|
||||
import { API_BASE_URL } from '@/app/actions/definitions';
|
||||
|
||||
const checkout = new YooCheckout({ shopId: '1276731', secretKey: 'test_0Yns_0NHV5GJf6ypJ5HC4NSfnLO8SJkw-1PwrVWsDl4' });
|
||||
|
||||
const idempotenceKey = '02347fc4-a1f0-49db-807e-f0d67c2ed5a5';
|
||||
|
||||
export async function yooKasaCreatePayment(amount: number, tariff: string) {
|
||||
export async function makePaymentOperation(email: string, tariffId: number, operationUuid: string) {
|
||||
console.log('makePaymentOperation');
|
||||
console.log({
|
||||
email,
|
||||
tariffId: tariffId,
|
||||
operationType: 'TARIFF',
|
||||
operationUuid,
|
||||
});
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append('email', email);
|
||||
formData.append('tariffId', tariffId.toString());
|
||||
formData.append('operationType', 'TARIFF');
|
||||
formData.append('operationUuid', operationUuid);
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/api/payments/create`, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const parsed = await response.json()
|
||||
console.log(parsed);
|
||||
return true
|
||||
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
} catch (error) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export async function yooKasaCreatePayment(amount: number, tariff: number) {
|
||||
console.log(amount);
|
||||
console.log(tariff);
|
||||
/* return true; */
|
||||
|
||||
const userEmail = await getSessionData('email');
|
||||
|
||||
if (!userEmail) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const createPayload: ICreatePayment = {
|
||||
amount: {
|
||||
value: amount.toLocaleString(),
|
||||
@@ -34,10 +74,18 @@ export async function yooKasaCreatePayment(amount: number, tariff: string) {
|
||||
|
||||
try {
|
||||
const payment = await checkout.createPayment(createPayload, Date.now().toLocaleString());
|
||||
console.log(payment);
|
||||
return payment?.confirmation.confirmation_url;
|
||||
const response = await makePaymentOperation(userEmail, tariff, payment.id);
|
||||
console.log('yooKasaCreatePayment')
|
||||
console.log(response);
|
||||
if (response) {
|
||||
return payment?.confirmation.confirmation_url;
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
|
||||
/* return payment; */
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
SortingState,
|
||||
ColumnFiltersState,
|
||||
} from '@tanstack/react-table';
|
||||
import { IconEye, IconDoubleArrowRight, IconArrowRight, IconDoubleArrowLeft, IconArrowLeft, IconArrowUp, IconArrowDown, IconFilter, IconFileDownload, IconShieldExclamation } from '@/app/ui/icons/icons';
|
||||
import { IconEye, IconDoubleArrowRight, IconArrowRight, IconDoubleArrowLeft, IconArrowLeft, IconArrowUp, IconArrowDown, IconFilter, IconFileDownload, IconShieldExclamation, IconInfo } from '@/app/ui/icons/icons';
|
||||
import { useTranslations, useLocale } from 'next-intl';
|
||||
import DropDownList from '@/app/components/DropDownList';
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
@@ -21,6 +21,7 @@ import { toast } from 'sonner';
|
||||
import { pluralize } from '@/app/lib/pluralize';
|
||||
import { convertBytes } from '@/app/lib/convertBytes';
|
||||
import { FileInfoModalWindow } from '@/app/ui/modal-windows/file-info-modal-window';
|
||||
import { FileMonitoringModalWindow } from '@/app/ui/modal-windows/file-monitoring-modal-window';
|
||||
import { FileTypeIcon } from '@/app/components/FileTypeIcon';
|
||||
|
||||
type FileType = 'image' | 'video' | 'audio';
|
||||
@@ -404,12 +405,13 @@ export default function TanstakFilesTable({ fileType }: { fileType: string }) {
|
||||
},
|
||||
cell: ({ row }) => (
|
||||
<div className="actions">
|
||||
<div className="actions-group" style={{ display: "none" }}>
|
||||
<div className="actions-group">
|
||||
<button
|
||||
onClick={() => handleProtect(row.original)}
|
||||
onClick={() => handleMonitoring(row.original)}
|
||||
className="bg-violet-500 hover:bg-violet-600"
|
||||
title={t('monitoring')}
|
||||
>
|
||||
<IconShieldExclamation />
|
||||
<IconEye />
|
||||
</button>
|
||||
{/* <button
|
||||
onClick={() => handleOpenWindowForRemove(row.original)}
|
||||
@@ -427,11 +429,9 @@ export default function TanstakFilesTable({ fileType }: { fileType: string }) {
|
||||
onClick={() => handleDownload(row.original)}
|
||||
disabled={isFileLoading}
|
||||
className="table-action-download"
|
||||
title={t('download')}
|
||||
>
|
||||
<IconFileDownload />
|
||||
<span>
|
||||
{t('download')}
|
||||
</span>
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
@@ -439,11 +439,9 @@ export default function TanstakFilesTable({ fileType }: { fileType: string }) {
|
||||
handleView(row.original)
|
||||
}}
|
||||
className="table-action-view"
|
||||
title={t('make-check')}
|
||||
>
|
||||
<IconEye />
|
||||
<span>
|
||||
{t('make-check')}
|
||||
</span>
|
||||
<IconInfo />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -461,7 +459,6 @@ export default function TanstakFilesTable({ fileType }: { fileType: string }) {
|
||||
console.log(file);
|
||||
|
||||
const fileInfo = await viewFileInfo(file.id);
|
||||
console.log(fileInfo);
|
||||
|
||||
setOpenWindowChildren(() => {
|
||||
return (
|
||||
@@ -498,85 +495,19 @@ export default function TanstakFilesTable({ fileType }: { fileType: string }) {
|
||||
}
|
||||
};
|
||||
|
||||
const handleProtect = (file: FileItem) => {
|
||||
console.log(`Щиток: ${file.fileName}`);
|
||||
};
|
||||
const handleMonitoring = async (file: FileItem) => {
|
||||
console.log(`Мониторинг:`, file);
|
||||
|
||||
const handleOpenWindowForRemove = async (file: FileItem) => {
|
||||
const fileInfo = await viewFileInfo(file.id);
|
||||
|
||||
setOpenWindowChildren(() => {
|
||||
return (
|
||||
<div>
|
||||
<h3 className="text-2xl">
|
||||
{t('you-sure-you-want-to-delete')}
|
||||
</h3>
|
||||
<div className="mt-2 mb-8 text-center">{file.fileName}</div>
|
||||
<div className="flex justify-center gap-4">
|
||||
<button className="btn-primary btn-modal"
|
||||
onClick={() => {
|
||||
deleteMutation.mutate({
|
||||
fileId: file.id,
|
||||
removeParam: 1,
|
||||
})
|
||||
}}
|
||||
disabled={deleteMutation.isPending}
|
||||
>
|
||||
{deleteMutation.isPending ? '...' : t('yes')}
|
||||
</button>
|
||||
<button className="btn-primary btn-modal"
|
||||
onClick={() => {
|
||||
setOpenWindow(false);
|
||||
setOpenWindowChildren(null);
|
||||
}}
|
||||
>
|
||||
{t('no')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<FileMonitoringModalWindow file={fileInfo} setWindowClose={setOpenWindow} setWindowChildren={setOpenWindowChildren} />
|
||||
)
|
||||
})
|
||||
setOpenWindow(true);
|
||||
};
|
||||
|
||||
const deleteMutation = useMutation({
|
||||
mutationFn: ({ fileId, removeParam }: { fileId: string; removeParam: number }) =>
|
||||
removeUserFile(fileId, removeParam),
|
||||
|
||||
onMutate: async ({ fileId, removeParam }: { fileId: string; removeParam: number }) => {
|
||||
await queryClient.cancelQueries({ queryKey: ['userFilesData'] });
|
||||
|
||||
queryClient.setQueryData<ApiResponse>(['userFilesData'], (old) => {
|
||||
if (!old?.files) return old;
|
||||
return {
|
||||
...old,
|
||||
files: old.files.filter(file => file.id !== fileId)
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
onError: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['userFilesData'] });
|
||||
toast.error(t('error'));
|
||||
},
|
||||
|
||||
onSuccess: (response, { fileId }) => {
|
||||
if (response === fileId) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['userFilesData'],
|
||||
refetchType: 'active'
|
||||
});
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['userFilesInfo']
|
||||
});
|
||||
|
||||
setOpenWindow(false);
|
||||
setOpenWindowChildren(null);
|
||||
toast.success(t('file-has-been-deleted'));
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Фильтрация по типу файла и дате
|
||||
const filteredData = useMemo(() => {
|
||||
let result = tableData;
|
||||
@@ -693,7 +624,9 @@ export default function TanstakFilesTable({ fileType }: { fileType: string }) {
|
||||
}
|
||||
})()}
|
||||
</h3>
|
||||
<ModalWindow children={openWindowChildren} state={openWindow} callBack={setOpenWindow} />
|
||||
<ModalWindow state={openWindow} callBack={setOpenWindow}>
|
||||
{openWindowChildren}
|
||||
</ModalWindow>
|
||||
{/* Фильтры */}
|
||||
<div className="tanstak-table-filtres">
|
||||
<div className="table-filtres-wrapper">
|
||||
|
||||
@@ -4095,3 +4095,30 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.monitoring {
|
||||
|
||||
&-title {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
&-status {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
&-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 5px;
|
||||
|
||||
.btn-primary {
|
||||
width: 100%;
|
||||
color: v.$p-color;
|
||||
border: 2px solid v.$p-color;
|
||||
cursor: pointer;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,3 +182,9 @@ export function IconDiscet() {
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function IconInfo() {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="icon"><path fill="currentColor" d="M11 17h2v-6h-2zm1.713-8.287Q13 8.425 13 8t-.288-.712T12 7t-.712.288T11 8t.288.713T12 9t.713-.288M12 22q-2.075 0-3.9-.788t-3.175-2.137T2.788 15.9T2 12t.788-3.9t2.137-3.175T8.1 2.788T12 2t3.9.788t3.175 2.137T21.213 8.1T22 12t-.788 3.9t-2.137 3.175t-3.175 2.138T12 22m0-2q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m0-8" /></svg>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export function FileMonitoringModalWindow({ file, setWindowClose, setWindowChildren }: any) {
|
||||
const [status, setStatus] = useState('null');
|
||||
|
||||
function closeHandler() {
|
||||
setWindowChildren(null);
|
||||
setWindowClose(false);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log(file);
|
||||
}, [file])
|
||||
|
||||
return (
|
||||
<div
|
||||
className="monitoring-wrapper"
|
||||
>
|
||||
<h3 className="monitoring-title">
|
||||
Выберете интервал мониторинга<br />
|
||||
для файла - {file.fileName}
|
||||
</h3>
|
||||
<p className="monitoring-status">
|
||||
Текущий статус мониторинга - {status}
|
||||
</p>
|
||||
<ul
|
||||
className="monitoring-actions"
|
||||
>
|
||||
<li>
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
onClick={() => {
|
||||
closeHandler()
|
||||
}}
|
||||
>
|
||||
Без мониторинга
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
onClick={() => {
|
||||
closeHandler()
|
||||
}}
|
||||
>
|
||||
Каждый день
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
onClick={() => {
|
||||
closeHandler()
|
||||
}}
|
||||
>
|
||||
Каждую неделю
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
onClick={() => {
|
||||
closeHandler()
|
||||
}}
|
||||
>
|
||||
Каждый месяц
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -27,10 +27,11 @@ export default function PaymentTabTariffs() {
|
||||
value: number;
|
||||
tariff: string;
|
||||
tokens: number;
|
||||
tariffId: number
|
||||
} | null>(null);
|
||||
const [isProcessing, setIsProcessing] = useState<boolean>(false);
|
||||
|
||||
async function createPayment(value: number, tariff: string) {
|
||||
async function createPayment(value: number, tariff: number) {
|
||||
if (isProcessing) return;
|
||||
|
||||
setIsProcessing(true);
|
||||
@@ -48,8 +49,8 @@ export default function PaymentTabTariffs() {
|
||||
}
|
||||
}
|
||||
|
||||
function openPaymentWindow(value: number, tariff: string, tokens: number) {
|
||||
setSelectedTariff({ value, tariff, tokens });
|
||||
function openPaymentWindow(value: number, tariff: string, tokens: number, tariffId: number) {
|
||||
setSelectedTariff({ value, tariff, tokens, tariffId });
|
||||
setIsProcessing(false);
|
||||
setOpenWindow(true);
|
||||
}
|
||||
@@ -64,7 +65,7 @@ export default function PaymentTabTariffs() {
|
||||
if (!selectedTariff) return null;
|
||||
|
||||
const handleConfirm = () => {
|
||||
createPayment(selectedTariff.value, selectedTariff.tariff);
|
||||
createPayment(selectedTariff.value, selectedTariff.tariffId);
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
@@ -170,7 +171,7 @@ export default function PaymentTabTariffs() {
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
onClick={() => openPaymentWindow(item.price, item.name, item.tokens)}
|
||||
onClick={() => openPaymentWindow(item.price, item.name, item.tokens, item.id)}
|
||||
>
|
||||
Выбрать план
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user