docs: обновление архитектурной документации и модульного рефакторинга
- Обновлен CLAUDE.md с новыми правилами системы - Дополнен workflow-catalog.md с процессами - Обновлены interaction-integrity-rules.md - Завершен модульный рефакторинг create-suppliers компонента - Добавлен модульный user-settings с блочной архитектурой - Система готова к следующему этапу архитектурных улучшений 🚀 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,123 @@
|
||||
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'
|
Reference in New Issue
Block a user