last fix
This commit is contained in:
@@ -23,4 +23,5 @@ export interface PaymentModalProps {
|
|||||||
price: PriceCalculate;
|
price: PriceCalculate;
|
||||||
onConfirmPayment: () => void;
|
onConfirmPayment: () => void;
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
|
hasSertificate: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ export const PaymentModal: React.FC<PaymentModalProps> = ({
|
|||||||
price,
|
price,
|
||||||
onConfirmPayment,
|
onConfirmPayment,
|
||||||
isLoading,
|
isLoading,
|
||||||
|
hasSertificate,
|
||||||
}) => {
|
}) => {
|
||||||
const dialogRef = useRef<HTMLDivElement>(null);
|
const dialogRef = useRef<HTMLDivElement>(null);
|
||||||
const status = isLoading ? 'loading' : 'idle';
|
const status = isLoading ? 'loading' : 'idle';
|
||||||
@@ -144,18 +145,20 @@ export const PaymentModal: React.FC<PaymentModalProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Certificate badge */}
|
{/* Certificate badge */}
|
||||||
<div className="flex items-center gap-2 text-sm text-emerald-700 bg-emerald-50 border border-emerald-100 rounded-lg px-3.5 py-2.5">
|
{hasSertificate && (
|
||||||
<svg
|
<div className="flex items-center gap-2 text-sm text-emerald-700 bg-emerald-50 border border-emerald-100 rounded-lg px-3.5 py-2.5">
|
||||||
width="15"
|
<svg
|
||||||
height="15"
|
width="15"
|
||||||
viewBox="0 0 24 24"
|
height="15"
|
||||||
fill="currentColor"
|
viewBox="0 0 24 24"
|
||||||
className="shrink-0"
|
fill="currentColor"
|
||||||
>
|
className="shrink-0"
|
||||||
<path d="M12 1l2.753 5.527 6.247.907-4.5 4.385 1.063 6.181L12 15.027l-5.563 2.973 1.063-6.181L3 7.434l6.247-.907z" />
|
>
|
||||||
</svg>
|
<path d="M12 1l2.753 5.527 6.247.907-4.5 4.385 1.063 6.181L12 15.027l-5.563 2.973 1.063-6.181L3 7.434l6.247-.907z" />
|
||||||
<span>{t('certificateIncluded')}</span>
|
</svg>
|
||||||
</div>
|
<span>{t('certificateIncluded')}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Payment method label */}
|
{/* Payment method label */}
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ import { SEO_DATA, type SupportedLocale } from '../config/seo.config';
|
|||||||
|
|
||||||
// ─── Site-wide constants ───────────────────────────────────────────────────────
|
// ─── Site-wide constants ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
export const SERTIFICATE_PRICE = 20600;
|
||||||
|
export const PLAGIAT_SERVICE_FEE = 20600;
|
||||||
|
|
||||||
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? 'https://antiplagiat.uz';
|
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? 'https://antiplagiat.uz';
|
||||||
const OG_IMAGE_URL = `${SITE_URL}/og-image.png`; // 1200×630 px recommended
|
const OG_IMAGE_URL = `${SITE_URL}/og-image.png`; // 1200×630 px recommended
|
||||||
const TWITTER_HANDLE = '@antiplagiatuz'; // update or remove if unused
|
const TWITTER_HANDLE = '@antiplagiatuz'; // update or remove if unused
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
export const links = {
|
export const links = {
|
||||||
login: '/users/login/',
|
login: '/users/login/',
|
||||||
register: '/users/register/',
|
register: '/users/register/',
|
||||||
plagiarismCheck: '/shared/document/',
|
plagiarismCheck: '/shared/documents/',
|
||||||
history: '/shared/documents/list/',
|
history: '/shared/documents/list/',
|
||||||
detail: (id: number) => `/shared/documents/${id}/`,
|
detail: (id: number) => `/shared/documents/${id}/`,
|
||||||
payment: (order_id: number) => `/users/payme/link/${order_id}/`,
|
payment: (order_id: number) => `/users/payme/link/${order_id}/`,
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import { Clock, XCircle, ReceiptText } from 'lucide-react';
|
import { Clock, XCircle, ReceiptText } from 'lucide-react';
|
||||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import { apiRequest } from '@/shared/request/apiRequest';
|
import { apiRequest } from '@/shared/request/apiRequest';
|
||||||
import { links } from '@/shared/request/links';
|
import { links } from '@/shared/request/links';
|
||||||
import PaymentStatus from '@/widgets/detail/paidStatus';
|
import PaymentStatus from '@/widgets/detail/paidStatus';
|
||||||
import { toast } from 'react-toastify';
|
// import { toast } from 'react-toastify';
|
||||||
import { PaymentModal } from '@/features/modals/paymentModal/ui/Paymentmodal';
|
// import { PaymentModal } from '@/features/modals/paymentModal/ui/Paymentmodal';
|
||||||
|
|
||||||
// ─── Types ─────────────────────────────────────────────────────────────────────
|
// ─── Types ─────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ function formatPrice(price: string) {
|
|||||||
|
|
||||||
export function PaymentsTable() {
|
export function PaymentsTable() {
|
||||||
const t = useTranslations('Cabinet');
|
const t = useTranslations('Cabinet');
|
||||||
const [isPaymentOpen, setIsPaymentOpen] = useState(false);
|
// const [isPaymentOpen, setIsPaymentOpen] = useState(false);
|
||||||
const { data, isLoading } = useQuery({
|
const { data, isLoading } = useQuery({
|
||||||
queryKey: ['pay_history'],
|
queryKey: ['pay_history'],
|
||||||
queryFn: (): Promise<Inspection[]> =>
|
queryFn: (): Promise<Inspection[]> =>
|
||||||
@@ -47,29 +47,29 @@ export function PaymentsTable() {
|
|||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
const payment = useMutation({
|
// const payment = useMutation({
|
||||||
mutationKey: ['payload'],
|
// mutationKey: ['payload'],
|
||||||
mutationFn: ({ order_id }: { order_id: number }) =>
|
// mutationFn: ({ order_id }: { order_id: number }) =>
|
||||||
apiRequest<{ payment_link: string }>('POST', links.payment(order_id)),
|
// apiRequest<{ payment_link: string }>('POST', links.payment(order_id)),
|
||||||
onSuccess: (res) => {
|
// onSuccess: (res) => {
|
||||||
window.open(res.data.payment_link, '_self');
|
// window.open(res.data.payment_link, '_self');
|
||||||
setIsPaymentOpen(false);
|
// // setIsPaymentOpen(false);
|
||||||
},
|
// },
|
||||||
onError: (err) => {
|
// onError: (err) => {
|
||||||
const message =
|
// const message =
|
||||||
err instanceof Error ? err.message : 'An unexpected error occurred.';
|
// err instanceof Error ? err.message : 'An unexpected error occurred.';
|
||||||
toast.error(message);
|
// toast.error(message);
|
||||||
setIsPaymentOpen(false);
|
// // setIsPaymentOpen(false);
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
|
|
||||||
const handleSubmit = ({ document_id }: { document_id: number }) => {
|
// const handleSubmit = ({ document_id }: { document_id: number }) => {
|
||||||
if (document_id === 0) {
|
// if (document_id === 0) {
|
||||||
toast.error('Id not found');
|
// toast.error('Id not found');
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
payment.mutate({ order_id: document_id });
|
// payment.mutate({ order_id: document_id });
|
||||||
};
|
// };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -116,7 +116,7 @@ export function PaymentsTable() {
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-slate-50">
|
<tbody className="divide-y divide-slate-50">
|
||||||
{data.map((row) => {
|
{data.map((row) => {
|
||||||
const service_fee = row.total_price + row.discount;
|
// const service_fee = row.total_price + row.discount;
|
||||||
return (
|
return (
|
||||||
<tr
|
<tr
|
||||||
key={row.id}
|
key={row.id}
|
||||||
@@ -145,14 +145,7 @@ export function PaymentsTable() {
|
|||||||
</td>
|
</td>
|
||||||
<td className="px-5 py-3.5">
|
<td className="px-5 py-3.5">
|
||||||
{row.state ? (
|
{row.state ? (
|
||||||
<span
|
<span className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg text-xs font-medium text-emerald-600 bg-emerald-50">
|
||||||
onClick={() => {
|
|
||||||
if (row.state === 'unpaid') {
|
|
||||||
setIsPaymentOpen(true);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg text-xs font-medium text-emerald-600 bg-emerald-50"
|
|
||||||
>
|
|
||||||
<PaymentStatus status={row.state} />
|
<PaymentStatus status={row.state} />
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
@@ -162,7 +155,7 @@ export function PaymentsTable() {
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
<PaymentModal
|
{/* <PaymentModal
|
||||||
isOpen={isPaymentOpen}
|
isOpen={isPaymentOpen}
|
||||||
onClose={() => setIsPaymentOpen(false)}
|
onClose={() => setIsPaymentOpen(false)}
|
||||||
price={{
|
price={{
|
||||||
@@ -174,7 +167,7 @@ export function PaymentsTable() {
|
|||||||
handleSubmit({ document_id: 0 });
|
handleSubmit({ document_id: 0 });
|
||||||
}}
|
}}
|
||||||
isLoading={payment.isPending}
|
isLoading={payment.isPending}
|
||||||
/>
|
/> */}
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { apiRequest } from '@/shared/request/apiRequest';
|
|||||||
import { links } from '@/shared/request/links';
|
import { links } from '@/shared/request/links';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
import { PaymentModal } from '@/features/modals/paymentModal/ui/Paymentmodal';
|
import { PaymentModal } from '@/features/modals/paymentModal/ui/Paymentmodal';
|
||||||
|
import { PLAGIAT_SERVICE_FEE, SERTIFICATE_PRICE } from '@/shared/lib/metadata';
|
||||||
|
|
||||||
// ─── State badge ───────────────────────────────────────────────────────────────
|
// ─── State badge ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -60,8 +61,9 @@ export const HistoryTableRow: React.FC<
|
|||||||
});
|
});
|
||||||
|
|
||||||
const price = item.price_calculation ?? {
|
const price = item.price_calculation ?? {
|
||||||
service_fee: 41200,
|
service_fee: item.state === 'unpaid' ? PLAGIAT_SERVICE_FEE : 0,
|
||||||
discount: 0,
|
discount: 0,
|
||||||
|
certificate: item.certificate ? SERTIFICATE_PRICE : 0,
|
||||||
total_price: 41200,
|
total_price: 41200,
|
||||||
currency: 'UZS',
|
currency: 'UZS',
|
||||||
};
|
};
|
||||||
@@ -142,6 +144,7 @@ export const HistoryTableRow: React.FC<
|
|||||||
payment.mutate({ order_id: Number(item.order_id) })
|
payment.mutate({ order_id: Number(item.order_id) })
|
||||||
}
|
}
|
||||||
isLoading={payment.isPending}
|
isLoading={payment.isPending}
|
||||||
|
hasSertificate={item.certificate}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import { useMutation } from '@tanstack/react-query';
|
|||||||
import { links } from '@/shared/request/links';
|
import { links } from '@/shared/request/links';
|
||||||
import { apiRequest } from '@/shared/request/apiRequest';
|
import { apiRequest } from '@/shared/request/apiRequest';
|
||||||
import { PriceCalculate } from '@/features/modals/paymentModal/lib/types';
|
import { PriceCalculate } from '@/features/modals/paymentModal/lib/types';
|
||||||
|
import { SERTIFICATE_PRICE, PLAGIAT_SERVICE_FEE } from '@/shared/lib/metadata';
|
||||||
|
// import { fromTheme } from 'tailwind-merge';
|
||||||
|
|
||||||
// ─── Initial States ──────────────────────────────────────────────────────────
|
// ─── Initial States ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -25,7 +27,8 @@ const INITIAL_FORM: PlagiarismFormState = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const PRICE: PriceCalculate = {
|
const PRICE: PriceCalculate = {
|
||||||
service_fee: 0,
|
service_fee: PLAGIAT_SERVICE_FEE,
|
||||||
|
certificate: SERTIFICATE_PRICE,
|
||||||
discount: 0,
|
discount: 0,
|
||||||
total_price: 0,
|
total_price: 0,
|
||||||
};
|
};
|
||||||
@@ -71,8 +74,8 @@ export function usePlagiarismForm() {
|
|||||||
const priceInfo: PriceCalculate = {
|
const priceInfo: PriceCalculate = {
|
||||||
total_price: resdata?.total_price || 0,
|
total_price: resdata?.total_price || 0,
|
||||||
discount: resdata?.discount || 0,
|
discount: resdata?.discount || 0,
|
||||||
certificate: resdata?.certificate || 0,
|
certificate: form.certificate ? SERTIFICATE_PRICE : 0,
|
||||||
service_fee: resdata?.service_fee || 0,
|
service_fee: PLAGIAT_SERVICE_FEE,
|
||||||
};
|
};
|
||||||
setPrices(priceInfo);
|
setPrices(priceInfo);
|
||||||
console.log('order_id:', resdata.id);
|
console.log('order_id:', resdata.id);
|
||||||
|
|||||||
@@ -209,6 +209,7 @@ export function PlagiarismCheckForm() {
|
|||||||
price={prices}
|
price={prices}
|
||||||
onConfirmPayment={handleSubmit}
|
onConfirmPayment={handleSubmit}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
|
hasSertificate={!!form.certificate}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user