219 lines
7.2 KiB
TypeScript
219 lines
7.2 KiB
TypeScript
"use client"
|
||
|
||
import { useState } from "react"
|
||
import { Button } from "@/components/ui/button"
|
||
import { GlassInput } from "@/components/ui/input"
|
||
import { Label } from "@/components/ui/label"
|
||
import { Alert, AlertDescription } from "@/components/ui/alert"
|
||
import { AuthLayout } from "./auth-layout"
|
||
import { FileText, ArrowLeft, Building, Check, AlertTriangle } from "lucide-react"
|
||
import { Badge } from "@/components/ui/badge"
|
||
import { useMutation } from '@apollo/client'
|
||
import { VERIFY_INN } from '@/graphql/mutations'
|
||
|
||
interface InnStepProps {
|
||
onNext: (inn: string, organizationData?: OrganizationData) => void
|
||
onBack: () => void
|
||
}
|
||
|
||
interface OrganizationData {
|
||
name: string
|
||
address: string
|
||
isActive: boolean
|
||
}
|
||
|
||
export function InnStep({ onNext, onBack }: InnStepProps) {
|
||
const [inn, setInn] = useState("")
|
||
const [isLoading, setIsLoading] = useState(false)
|
||
const [error, setError] = useState<string | null>(null)
|
||
const [organizationData, setOrganizationData] = useState<OrganizationData | null>(null)
|
||
|
||
const [verifyInn] = useMutation(VERIFY_INN)
|
||
|
||
const formatInn = (value: string) => {
|
||
const numbers = value.replace(/\D/g, '')
|
||
return numbers.slice(0, 12) // Максимум 12 цифр для ИНН
|
||
}
|
||
|
||
const handleInnChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||
const formatted = formatInn(e.target.value)
|
||
setInn(formatted)
|
||
setError(null)
|
||
setOrganizationData(null)
|
||
}
|
||
|
||
const isValidInn = (inn: string) => {
|
||
return inn.length === 10 || inn.length === 12
|
||
}
|
||
|
||
const handleSubmit = async (e: React.FormEvent) => {
|
||
e.preventDefault()
|
||
|
||
if (!isValidInn(inn)) {
|
||
setError('ИНН должен содержать 10 или 12 цифр')
|
||
return
|
||
}
|
||
|
||
setIsLoading(true)
|
||
setError(null)
|
||
setOrganizationData(null)
|
||
|
||
try {
|
||
const { data } = await verifyInn({
|
||
variables: { inn }
|
||
})
|
||
|
||
if (data.verifyInn.success && data.verifyInn.organization) {
|
||
const org = data.verifyInn.organization
|
||
const newOrgData = {
|
||
name: org.name,
|
||
address: org.address,
|
||
isActive: org.isActive
|
||
}
|
||
setOrganizationData(newOrgData)
|
||
|
||
if (org.isActive) {
|
||
// Автоматически переходим дальше для активных организаций
|
||
setTimeout(() => {
|
||
onNext(inn, newOrgData)
|
||
}, 1500)
|
||
}
|
||
} else {
|
||
setError('Организация с таким ИНН не найдена')
|
||
}
|
||
} catch (error: unknown) {
|
||
console.error('INN verification error:', error)
|
||
setError('Ошибка проверки ИНН. Попробуйте позже.')
|
||
} finally {
|
||
setIsLoading(false)
|
||
}
|
||
}
|
||
|
||
const handleContinueInactive = () => {
|
||
if (organizationData && !organizationData.isActive) {
|
||
onNext(inn, organizationData)
|
||
}
|
||
}
|
||
|
||
return (
|
||
<AuthLayout
|
||
title="ИНН организации"
|
||
description="Укажите ИНН для проверки организации"
|
||
currentStep={4}
|
||
totalSteps={5}
|
||
stepName="ИНН"
|
||
>
|
||
<div className="space-y-4">
|
||
<Alert className="glass-secondary border-white/20">
|
||
<Building className="h-4 w-4 text-white" />
|
||
<AlertDescription className="text-white/80">
|
||
Фулфилмент кабинет - склады и логистика
|
||
</AlertDescription>
|
||
</Alert>
|
||
|
||
<form onSubmit={handleSubmit} className="space-y-4">
|
||
<div className="space-y-3">
|
||
<div className="flex items-center justify-between">
|
||
<Label htmlFor="inn" className="text-white text-sm font-medium flex items-center gap-2">
|
||
<FileText className="h-4 w-4" />
|
||
ИНН организации
|
||
</Label>
|
||
{organizationData && (
|
||
<Badge
|
||
variant="outline"
|
||
className={`glass-secondary flex items-center gap-1 ${
|
||
organizationData.isActive
|
||
? 'text-green-300 border-green-400/30'
|
||
: 'text-yellow-300 border-yellow-400/30'
|
||
}`}
|
||
>
|
||
{organizationData.isActive ? (
|
||
<>
|
||
<Check className="h-3 w-3" />
|
||
Активна
|
||
</>
|
||
) : (
|
||
<>
|
||
<AlertTriangle className="h-3 w-3" />
|
||
Неактивна
|
||
</>
|
||
)}
|
||
</Badge>
|
||
)}
|
||
</div>
|
||
|
||
<GlassInput
|
||
id="inn"
|
||
type="text"
|
||
inputMode="numeric"
|
||
placeholder="1234567890"
|
||
value={inn}
|
||
onChange={handleInnChange}
|
||
className={`h-12 text-center text-lg font-mono ${error ? 'border-red-400/50' : ''}`}
|
||
maxLength={12}
|
||
/>
|
||
|
||
{error && (
|
||
<p className="text-red-400 text-xs text-center">{error}</p>
|
||
)}
|
||
</div>
|
||
|
||
{organizationData && (
|
||
<div className="glass-card p-4 space-y-2">
|
||
<h4 className="text-white font-medium text-sm">{organizationData.name}</h4>
|
||
<p className="text-white/70 text-xs">{organizationData.address}</p>
|
||
|
||
{organizationData.isActive ? (
|
||
<div className="flex items-center gap-2 pt-2">
|
||
<Check className="h-4 w-4 text-green-300" />
|
||
<span className="text-green-300 text-sm">Организация активна</span>
|
||
</div>
|
||
) : (
|
||
<div className="flex items-center gap-2 pt-2">
|
||
<AlertTriangle className="h-4 w-4 text-yellow-300" />
|
||
<span className="text-yellow-300 text-sm">Организация неактивна</span>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)}
|
||
|
||
<div className="space-y-3">
|
||
{!organizationData && (
|
||
<Button
|
||
type="submit"
|
||
variant="glass"
|
||
size="lg"
|
||
className="w-full h-12"
|
||
disabled={!isValidInn(inn) || isLoading}
|
||
>
|
||
{isLoading ? "Проверка ИНН..." : "Проверить ИНН"}
|
||
</Button>
|
||
)}
|
||
|
||
{organizationData && !organizationData.isActive && (
|
||
<Button
|
||
type="button"
|
||
onClick={handleContinueInactive}
|
||
variant="glass"
|
||
size="lg"
|
||
className="w-full h-12"
|
||
>
|
||
Продолжить с неактивной организацией
|
||
</Button>
|
||
)}
|
||
|
||
<Button
|
||
type="button"
|
||
variant="glass-secondary"
|
||
onClick={onBack}
|
||
className="w-full flex items-center gap-2"
|
||
>
|
||
<ArrowLeft className="h-4 w-4" />
|
||
Назад
|
||
</Button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</AuthLayout>
|
||
)
|
||
}
|