
- Обновлен CLAUDE.md с новыми правилами системы - Дополнен workflow-catalog.md с процессами - Обновлены interaction-integrity-rules.md - Завершен модульный рефакторинг create-suppliers компонента - Добавлен модульный user-settings с блочной архитектурой - Система готова к следующему этапу архитектурных улучшений 🚀 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
124 lines
4.5 KiB
TypeScript
124 lines
4.5 KiB
TypeScript
import { Building2, RefreshCw, MapPin } from 'lucide-react'
|
||
import React, { memo } from 'react'
|
||
|
||
import { Button } from '@/components/ui/button'
|
||
import { Card } from '@/components/ui/card'
|
||
import { Input } from '@/components/ui/input'
|
||
import { Label } from '@/components/ui/label'
|
||
|
||
import type { OrganizationBlockProps } from '../types/user-settings.types'
|
||
|
||
export const OrganizationBlock = memo<OrganizationBlockProps>(
|
||
({ formData, setFormData, isEditing, onDaDataSearch }) => {
|
||
const handleInputChange = (field: keyof typeof formData, value: string) => {
|
||
setFormData({
|
||
...formData,
|
||
[field]: value,
|
||
})
|
||
}
|
||
|
||
const handleInnChange = (value: string) => {
|
||
// Удаляем все кроме цифр
|
||
const cleanInn = value.replace(/\D/g, '').slice(0, 12)
|
||
handleInputChange('inn', cleanInn)
|
||
}
|
||
|
||
const handleDaDataClick = async () => {
|
||
if (formData.inn && formData.inn.length >= 10) {
|
||
await onDaDataSearch(formData.inn)
|
||
}
|
||
}
|
||
|
||
const isDaDataAvailable = formData.inn && formData.inn.length >= 10
|
||
|
||
return (
|
||
<Card className="glass-card p-6">
|
||
<div className="flex items-center space-x-3 mb-6">
|
||
<div className="w-10 h-10 bg-green-500/20 rounded-lg flex items-center justify-center">
|
||
<Building2 className="w-5 h-5 text-green-500" />
|
||
</div>
|
||
<h3 className="text-lg font-semibold text-foreground">Данные организации</h3>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||
<div className="space-y-2">
|
||
<Label htmlFor="inn" className="text-sm font-medium text-foreground">
|
||
ИНН
|
||
</Label>
|
||
<div className="flex space-x-2">
|
||
<Input
|
||
id="inn"
|
||
type="text"
|
||
placeholder="1234567890"
|
||
value={formData.inn}
|
||
onChange={(e) => handleInnChange(e.target.value)}
|
||
disabled={!isEditing}
|
||
className="flex-1"
|
||
maxLength={12}
|
||
/>
|
||
{isEditing && isDaDataAvailable && (
|
||
<Button
|
||
type="button"
|
||
variant="outline"
|
||
size="sm"
|
||
onClick={handleDaDataClick}
|
||
className="px-3"
|
||
title="Заполнить данные из ИНН"
|
||
>
|
||
<RefreshCw className="w-4 h-4" />
|
||
</Button>
|
||
)}
|
||
</div>
|
||
{isEditing && formData.inn && formData.inn.length > 0 && formData.inn.length < 10 && (
|
||
<p className="text-xs text-muted-foreground">ИНН должен содержать от 10 до 12 цифр</p>
|
||
)}
|
||
</div>
|
||
|
||
<div className="space-y-2">
|
||
<Label htmlFor="orgName" className="text-sm font-medium text-foreground">
|
||
Название организации
|
||
</Label>
|
||
<Input
|
||
id="orgName"
|
||
type="text"
|
||
placeholder="ООО Название"
|
||
value={formData.orgName}
|
||
onChange={(e) => handleInputChange('orgName', e.target.value)}
|
||
disabled={!isEditing}
|
||
className="w-full"
|
||
/>
|
||
</div>
|
||
|
||
<div className="space-y-2 md:col-span-2">
|
||
<Label htmlFor="address" className="text-sm font-medium text-foreground">
|
||
<div className="flex items-center space-x-2">
|
||
<MapPin className="w-4 h-4" />
|
||
<span>Адрес</span>
|
||
</div>
|
||
</Label>
|
||
<Input
|
||
id="address"
|
||
type="text"
|
||
placeholder="г. Москва, ул. Примерная, д. 1"
|
||
value={formData.address}
|
||
onChange={(e) => handleInputChange('address', e.target.value)}
|
||
disabled={!isEditing}
|
||
className="w-full"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
{isEditing && isDaDataAvailable && (
|
||
<div className="mt-4 p-3 bg-blue-500/10 border border-blue-500/20 rounded-lg">
|
||
<p className="text-xs text-blue-600 dark:text-blue-400">
|
||
💡 Нажмите кнопку обновления рядом с ИНН, чтобы автоматически заполнить данные организации
|
||
</p>
|
||
</div>
|
||
)}
|
||
</Card>
|
||
)
|
||
},
|
||
)
|
||
|
||
OrganizationBlock.displayName = 'OrganizationBlock'
|