Ручные правки

This commit is contained in:
2025-07-20 06:35:39 +03:00
parent 30a5526de2
commit 339bb52840
22 changed files with 1616 additions and 373 deletions

View File

@@ -1,22 +1,33 @@
import { ArrowLeft, Save, Upload, Wrench } from 'lucide-react'
import {
AlignCenter,
AlignLeft,
AlignRight,
ArrowLeft,
Bold,
FileText,
Grid,
Italic,
Palette,
Type,
Underline,
Upload,
Wrench,
} from 'lucide-react'
import React, { useRef, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import * as XLSX from 'xlsx'
import { Template } from '../../types/template'
import DualSpreadsheet from '../DualSpreadsheet/DualSpreadsheet'
import { Button } from '../ui/button'
import { Separator } from '../ui/separator'
interface TemplateEditorProps {
template: Template
onSave: (template: Template) => void
onCancel: () => void
onBack: () => void
}
export const TemplateEditor: React.FC<TemplateEditorProps> = ({
template,
onSave,
onCancel,
onBack,
}) => {
const [editedTemplate, setEditedTemplate] = useState<Template>(template)
@@ -24,13 +35,17 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
template.excelData || {},
)
const [isLoading, setIsLoading] = useState(false)
const [dataVersion, setDataVersion] = useState(0) // Для принудительного обновления
const [dataVersion, setDataVersion] = useState(0) // Для принудительного
const fileInputRef = useRef<HTMLInputElement>(null)
const navigate = useNavigate()
const handleFileUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0]
if (!file) return
if (!file) {
console.log('No file selected')
return
}
setIsLoading(true)
const reader = new FileReader()
@@ -134,12 +149,8 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
reader.readAsArrayBuffer(file)
}
const handleSave = () => {
onSave(editedTemplate)
}
const handleCreateElements = () => {
navigate('/elements')
navigate(`/templates/${editedTemplate.id}/elements`)
}
return (
@@ -166,44 +177,74 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
className="flex items-center gap-2"
>
<Wrench className="h-3.5 w-3.5" />
Создать элементы
</Button>
<Button variant="outline" size="sm" onClick={onCancel}>
Отмена
Элементы интерфейса
</Button>
<Button
variant="outline"
size="sm"
onClick={handleSave}
onClick={() =>
navigate(`/templates/${editedTemplate.id}/protocols`)
}
className="flex items-center gap-2"
>
<Save className="h-3.5 w-3.5" />
Сохранить
<FileText className="h-3.5 w-3.5" />
Создать протокол
</Button>
</div>
</div>
</div>
{/* Панель загрузки Excel */}
{/* Компактная панель загрузки Excel и инструментов */}
<div className="flex-shrink-0 border-b bg-muted/30 px-4 py-2">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<span className="text-xs font-medium text-muted-foreground">
Excel шаблон:
</span>
{editedTemplate.excelFile ? (
<div className="flex items-center gap-2 rounded-md bg-emerald-50 px-2 py-1">
<Upload className="h-3 w-3 text-emerald-600" />
<span className="text-xs text-emerald-700">
{editedTemplate.excelFile.name}
</span>
</div>
) : (
<div className="text-xs text-muted-foreground">
Файл не загружен
</div>
)}
{/* Левая часть - панель инструментов стилизации */}
<div className="flex items-center gap-0.5 rounded-lg border bg-background p-0.5">
{/* Группа текстового форматирования */}
<div className="flex items-center">
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
<Bold className="h-3 w-3" />
</Button>
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
<Italic className="h-3 w-3" />
</Button>
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
<Underline className="h-3 w-3" />
</Button>
</div>
<Separator orientation="vertical" className="mx-0.5 h-4" />
{/* Группа выравнивания */}
<div className="flex items-center">
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
<AlignLeft className="h-3 w-3" />
</Button>
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
<AlignCenter className="h-3 w-3" />
</Button>
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
<AlignRight className="h-3 w-3" />
</Button>
</div>
<Separator orientation="vertical" className="mx-0.5 h-4" />
{/* Группа цвета и стилей */}
<div className="flex items-center">
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
<Palette className="h-3 w-3" />
</Button>
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
<Type className="h-3 w-3" />
</Button>
<Button variant="ghost" size="sm" className="h-6 w-6 rounded p-0">
<Grid className="h-3 w-3" />
</Button>
</div>
</div>
<div className="flex items-center gap-3">
{/* Правая часть - загрузка Excel */}
<div className="flex items-center gap-2">
<input
ref={fileInputRef}
type="file"
@@ -211,27 +252,47 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
onChange={handleFileUpload}
className="hidden"
/>
{/* Статус файла - всегда отображается */}
<div
className={`flex items-center gap-1.5 rounded-md border px-2 py-1 ${
editedTemplate.excelFile
? 'border-emerald-200 bg-emerald-50'
: 'border-gray-200 bg-gray-50'
}`}
>
<FileText
className={`h-3 w-3 ${
editedTemplate.excelFile
? 'text-emerald-600'
: 'text-gray-400'
}`}
/>
<span
className={`max-w-32 truncate text-xs font-medium ${
editedTemplate.excelFile
? 'text-emerald-700'
: 'text-gray-500'
}`}
>
{editedTemplate.excelFile
? editedTemplate.excelFile.name
: 'Файл не выбран'}
</span>
</div>
{/* Кнопка загрузки - всегда отображается */}
<Button
variant="outline"
size="sm"
onClick={() => fileInputRef.current?.click()}
className="flex h-7 items-center gap-2"
className="h-7 rounded-md px-2"
disabled={isLoading}
>
{isLoading ? (
<>
<div className="h-3 w-3 animate-spin rounded-full border-2 border-current border-t-transparent" />
<span className="text-xs">Загрузка...</span>
</>
<div className="h-3 w-3 animate-spin rounded-full border-2 border-current border-t-transparent" />
) : (
<>
<Upload className="h-3 w-3" />
<span className="text-xs">
{editedTemplate.excelFile
? 'Заменить файл'
: 'Загрузить Excel'}
</span>
</>
<Upload className="h-3 w-3" />
)}
</Button>
</div>
@@ -244,6 +305,7 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
key={dataVersion}
templateData={{ L: excelData }}
mergedCells={editedTemplate.mergedCells}
templateId={`template-${editedTemplate.id}`}
/>
</div>
</div>