Files
sfera-new/src/components/auth/inn-step.tsx

219 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"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>
)
}