plagiatcheck part complated base new request types
This commit is contained in:
213
src/widgets/plagiatCheck/ui/Plagiraismcheckform.tsx
Normal file
213
src/widgets/plagiatCheck/ui/Plagiraismcheckform.tsx
Normal file
@@ -0,0 +1,213 @@
|
||||
'use client';
|
||||
import React from 'react';
|
||||
import {
|
||||
FieldWrapper,
|
||||
TextInput,
|
||||
ReadonlyField,
|
||||
FileUploadField,
|
||||
CertificateCheckbox,
|
||||
SubmitButton,
|
||||
StatusBanner,
|
||||
} from './Plagiraismui';
|
||||
import { usePlagiarismForm } from '../lib/usePlagiraism';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { PaymentModal } from '@/features/modals/paymentModal/ui/Paymentmodal';
|
||||
import DocumentsTypes from './documentsType';
|
||||
|
||||
export const inputCls = `
|
||||
w-full px-3.5 py-3.5 text-[14px] text-slate-800
|
||||
bg-blue-50 border border-blue-200 rounded-xl
|
||||
placeholder:text-blue-400
|
||||
focus:outline-none focus:ring-2 focus:ring-blue-400/40 focus:border-blue-400
|
||||
hover:border-blue-300
|
||||
transition-all duration-150
|
||||
disabled:opacity-60 disabled:cursor-not-allowed
|
||||
`.trim();
|
||||
// ─── UserIcon (inline) ───────────────────────────────────────────────────────
|
||||
|
||||
function UserIcon() {
|
||||
return (
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
strokeWidth={1.5}
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Component ───────────────────────────────────────────────────────────────
|
||||
|
||||
export function PlagiarismCheckForm() {
|
||||
const t = useTranslations('PlagiarismCheck');
|
||||
|
||||
const {
|
||||
form,
|
||||
errors,
|
||||
submission,
|
||||
senderFullName,
|
||||
isLoading,
|
||||
setTopic,
|
||||
setFile,
|
||||
toggleCertificate,
|
||||
handleSubmit,
|
||||
resetSubmission,
|
||||
handleSubmitWithModal,
|
||||
isPaymentOpen,
|
||||
setOption,
|
||||
setIsPaymentOpen,
|
||||
prices,
|
||||
} = usePlagiarismForm();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className=" flex items-center justify-center p-4 font-['DM_Sans',sans-serif]">
|
||||
<div className="w-full max-w-4xl">
|
||||
{/* ── Header ────────────────────────────────────────────────────── */}
|
||||
<div className="mb-8">
|
||||
<div className="inline-flex items-center gap-2 bg-blue-100 text-blue-700 text-xs font-bold uppercase tracking-widest px-3 py-1.5 rounded-full mb-4">
|
||||
<span className="w-1.5 h-1.5 rounded-full bg-blue-500" />
|
||||
{t('badge')}
|
||||
</div>
|
||||
<h1 className="text-3xl font-black text-stone-900 leading-tight">
|
||||
{t('title')}
|
||||
</h1>
|
||||
<p className="text-stone-500 mt-2 text-sm leading-relaxed">
|
||||
{t('description')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* ── Card ──────────────────────────────────────────────────────── */}
|
||||
<div className="bg-white rounded-3xl shadow-xl shadow-stone-200/80 border border-stone-100 overflow-hidden">
|
||||
{/* Progress bar accent */}
|
||||
<div className="h-1 w-full bg-linear-to-r from-blue-400 via-blue-500 to-indigo-400" />
|
||||
|
||||
<form
|
||||
onSubmit={handleSubmitWithModal}
|
||||
noValidate
|
||||
className="p-7 flex md:flex-row flex-col gap-6"
|
||||
>
|
||||
{/* Status banners */}
|
||||
{submission.status === 'success' && (
|
||||
<StatusBanner
|
||||
status="success"
|
||||
message={t('submissionSuccess')}
|
||||
onDismiss={resetSubmission}
|
||||
dismissText={t('dismiss')}
|
||||
/>
|
||||
)}
|
||||
{submission.status === 'error' && submission.error && (
|
||||
<StatusBanner
|
||||
status="error"
|
||||
message={submission.error}
|
||||
onDismiss={resetSubmission}
|
||||
dismissText={t('dismiss')}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* left part */}
|
||||
<div className="flex flex-col gap-9 md:max-w-[50%] w-full">
|
||||
{/* Topic */}
|
||||
<FieldWrapper
|
||||
label={t('documentTopic')}
|
||||
htmlFor="title"
|
||||
error={errors.title}
|
||||
required
|
||||
>
|
||||
<TextInput
|
||||
id="title"
|
||||
type="text"
|
||||
placeholder={t('topicPlaceholder')}
|
||||
value={form.title}
|
||||
onChange={(e) => setTopic(e.target.value)}
|
||||
hasError={!!errors.title}
|
||||
maxLength={200}
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</FieldWrapper>
|
||||
|
||||
{/* Sender Full Name (read-only) */}
|
||||
<FieldWrapper label={t('senderFullName')}>
|
||||
<ReadonlyField
|
||||
value={senderFullName || t('notLoggedIn')}
|
||||
icon={<UserIcon />}
|
||||
autoFilledText={t('autoFilled')}
|
||||
/>
|
||||
</FieldWrapper>
|
||||
|
||||
{/* Certificate Option */}
|
||||
<div>
|
||||
<p className="text-sm font-semibold tracking-wide text-stone-700 uppercase mb-2">
|
||||
{t('certificateOption')}
|
||||
</p>
|
||||
<CertificateCheckbox
|
||||
checked={form.certificate}
|
||||
onChange={toggleCertificate}
|
||||
title={t('certificateTitle')}
|
||||
description={t('certificateDescription')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* right part */}
|
||||
<div className="flex flex-col gap-4 md:max-w-[50%] w-full">
|
||||
{/* File Upload */}
|
||||
<FieldWrapper
|
||||
label={t('documentFile')}
|
||||
error={errors.file}
|
||||
required
|
||||
>
|
||||
<FileUploadField
|
||||
file={form.file}
|
||||
onFileChange={setFile}
|
||||
hasError={!!errors.file}
|
||||
clickToUploadText={t('clickToUpload')}
|
||||
fileTypesText={t('fileTypes')}
|
||||
removeFileAriaLabel={t('removeFile')}
|
||||
/>
|
||||
</FieldWrapper>
|
||||
|
||||
{/* Divider */}
|
||||
<div className="border-t border-stone-100" />
|
||||
|
||||
{/* Document type */}
|
||||
<DocumentsTypes
|
||||
value={form.document_type}
|
||||
onChange={setOption}
|
||||
disabled={submission.status === 'success'}
|
||||
/>
|
||||
|
||||
{/* Submit */}
|
||||
<SubmitButton
|
||||
isLoading={isLoading}
|
||||
submittingText={t('submitting')}
|
||||
submitText={t('submitButton')}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{/* Footer note */}
|
||||
<p className="text-center text-xs text-stone-400 mt-5">
|
||||
{t('secureNote')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<PaymentModal
|
||||
isOpen={isPaymentOpen}
|
||||
onClose={() => setIsPaymentOpen(false)}
|
||||
price={prices}
|
||||
onConfirmPayment={handleSubmit}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user