2 окна и настройка элементов
This commit is contained in:
3
src/pages/ElementsCreation/index.ts
Normal file
3
src/pages/ElementsCreation/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { ElementsCreation } from "./ui/Page";
|
||||
|
||||
export { ElementsCreation };
|
||||
166
src/pages/ElementsCreation/ui/Page/Page.tsx
Normal file
166
src/pages/ElementsCreation/ui/Page/Page.tsx
Normal file
@@ -0,0 +1,166 @@
|
||||
import { Plus, Wrench } from 'lucide-react';
|
||||
import { FC, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { ElementConstructor } from '../../../../components/TemplateManager/ElementConstructor';
|
||||
import { Button } from '../../../../components/ui/button';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../../../../components/ui/card';
|
||||
import { useTemplateContext } from '../../../../contexts/TemplateContext';
|
||||
import { Template, TemplateElement } from '../../../../types/template';
|
||||
|
||||
export const ElementsCreation: FC = () => {
|
||||
const navigate = useNavigate();
|
||||
const { templates, updateTemplate } = useTemplateContext();
|
||||
const [selectedTemplate, setSelectedTemplate] = useState<Template | null>(null);
|
||||
const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);
|
||||
|
||||
const handleTemplateSelect = (template: Template) => {
|
||||
setSelectedTemplate(template);
|
||||
};
|
||||
|
||||
const handleElementAdd = (element: TemplateElement) => {
|
||||
if (!selectedTemplate) return;
|
||||
|
||||
const updatedTemplate = {
|
||||
...selectedTemplate,
|
||||
elements: [...selectedTemplate.elements, element],
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
updateTemplate(updatedTemplate);
|
||||
setSelectedTemplate(updatedTemplate);
|
||||
};
|
||||
|
||||
const handleElementUpdate = (elementId: string, updates: Partial<TemplateElement>) => {
|
||||
if (!selectedTemplate) return;
|
||||
|
||||
const updatedTemplate = {
|
||||
...selectedTemplate,
|
||||
elements: selectedTemplate.elements.map(el =>
|
||||
el.id === elementId ? { ...el, ...updates } : el
|
||||
),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
updateTemplate(updatedTemplate);
|
||||
setSelectedTemplate(updatedTemplate);
|
||||
};
|
||||
|
||||
const handleElementDelete = (elementId: string) => {
|
||||
if (!selectedTemplate) return;
|
||||
|
||||
const updatedTemplate = {
|
||||
...selectedTemplate,
|
||||
elements: selectedTemplate.elements.filter(el => el.id !== elementId),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
updateTemplate(updatedTemplate);
|
||||
setSelectedTemplate(updatedTemplate);
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
setSelectedTemplate(null);
|
||||
};
|
||||
|
||||
if (selectedTemplate) {
|
||||
return (
|
||||
<div className="h-full bg-gray-50">
|
||||
<div className="bg-white border-b border-gray-200 p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-4">
|
||||
<Button variant="ghost" onClick={handleBack}>
|
||||
← Назад
|
||||
</Button>
|
||||
<div>
|
||||
<h1 className="text-xl font-semibold text-gray-800">
|
||||
Создание элементов: {selectedTemplate.name}
|
||||
</h1>
|
||||
<p className="text-sm text-gray-600 mt-1">
|
||||
Создайте элементы формы для связи с ячейками шаблона
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Button onClick={() => navigate('/templates')} variant="outline">
|
||||
Перейти к шаблонам
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 bg-blue-50">
|
||||
<ElementConstructor
|
||||
elements={selectedTemplate.elements}
|
||||
onElementAdd={handleElementAdd}
|
||||
onElementUpdate={handleElementUpdate}
|
||||
onElementDelete={handleElementDelete}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="p-6 max-w-7xl mx-auto">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold text-gray-900">Создание элементов</h1>
|
||||
<p className="text-gray-600 mt-2">Выберите шаблон для создания элементов интерфейса</p>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => navigate('/templates')}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
Создать шаблон
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{templates.length === 0 ? (
|
||||
<div className="text-center py-12">
|
||||
<Wrench className="h-16 w-16 text-gray-400 mx-auto mb-4" />
|
||||
<h3 className="text-lg font-medium text-gray-900 mb-2">Нет доступных шаблонов</h3>
|
||||
<p className="text-gray-600 mb-6">Создайте шаблон для начала работы с элементами</p>
|
||||
<Button onClick={() => navigate('/templates')}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Создать шаблон
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{templates.map((template) => (
|
||||
<Card key={template.id} className="hover:shadow-lg transition-shadow cursor-pointer">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-lg">{template.name}</CardTitle>
|
||||
{template.description && (
|
||||
<CardDescription className="mt-1">
|
||||
{template.description}
|
||||
</CardDescription>
|
||||
)}
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-2 text-sm text-gray-600">
|
||||
<div className="flex items-center gap-2">
|
||||
<Wrench className="h-4 w-4" />
|
||||
<span>{template.elements.length} элементов создано</span>
|
||||
</div>
|
||||
<div className="text-xs text-gray-500 mt-2">
|
||||
Обновлен: {template.updatedAt.toLocaleDateString()}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<Button
|
||||
className="w-full"
|
||||
onClick={() => handleTemplateSelect(template)}
|
||||
>
|
||||
Создать элементы
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
1
src/pages/ElementsCreation/ui/Page/index.ts
Normal file
1
src/pages/ElementsCreation/ui/Page/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { ElementsCreation } from './Page';
|
||||
1
src/pages/ProtocolCreation/index.ts
Normal file
1
src/pages/ProtocolCreation/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { ProtocolCreation } from './ui/Page/Page';
|
||||
105
src/pages/ProtocolCreation/ui/Page/Page.tsx
Normal file
105
src/pages/ProtocolCreation/ui/Page/Page.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
import { FileText, Plus } from 'lucide-react';
|
||||
import { FC, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { TemplateRenderer } from '../../../../components/TemplateManager/TemplateRenderer';
|
||||
import { Button } from '../../../../components/ui/button';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../../../../components/ui/card';
|
||||
import { useTemplateContext } from '../../../../contexts/TemplateContext';
|
||||
import { Template } from '../../../../types/template';
|
||||
|
||||
export const ProtocolCreation: FC = () => {
|
||||
const navigate = useNavigate();
|
||||
const { templates } = useTemplateContext();
|
||||
const [selectedTemplate, setSelectedTemplate] = useState<Template | null>(null);
|
||||
|
||||
const handleTemplateSelect = (template: Template) => {
|
||||
setSelectedTemplate(template);
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
setSelectedTemplate(null);
|
||||
};
|
||||
|
||||
const handleEdit = () => {
|
||||
// Переходим на страницу редактирования шаблона
|
||||
navigate('/templates');
|
||||
};
|
||||
|
||||
if (selectedTemplate) {
|
||||
return (
|
||||
<TemplateRenderer
|
||||
template={selectedTemplate}
|
||||
onBack={handleBack}
|
||||
onEdit={handleEdit}
|
||||
hideSpreadsheet={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="p-6 max-w-7xl mx-auto">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold text-gray-900">Создание протокола</h1>
|
||||
<p className="text-gray-600 mt-2">Выберите шаблон для создания нового протокола</p>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => navigate('/templates')}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
Создать шаблон
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{templates.length === 0 ? (
|
||||
<div className="text-center py-12">
|
||||
<FileText className="h-16 w-16 text-gray-400 mx-auto mb-4" />
|
||||
<h3 className="text-lg font-medium text-gray-900 mb-2">Нет доступных шаблонов</h3>
|
||||
<p className="text-gray-600 mb-6">Создайте шаблон протокола для начала работы</p>
|
||||
<Button onClick={() => navigate('/templates')}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Создать шаблон
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{templates.map((template) => (
|
||||
<Card key={template.id} className="hover:shadow-lg transition-shadow cursor-pointer">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-lg">{template.name}</CardTitle>
|
||||
{template.description && (
|
||||
<CardDescription className="mt-1">
|
||||
{template.description}
|
||||
</CardDescription>
|
||||
)}
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-2 text-sm text-gray-600">
|
||||
<div className="flex items-center gap-2">
|
||||
<FileText className="h-4 w-4" />
|
||||
<span>{template.elements.length} элементов для заполнения</span>
|
||||
</div>
|
||||
<div className="text-xs text-gray-500 mt-2">
|
||||
Создан: {template.createdAt.toLocaleDateString()}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<Button
|
||||
className="w-full"
|
||||
onClick={() => handleTemplateSelect(template)}
|
||||
disabled={!template.excelFile}
|
||||
>
|
||||
{template.excelFile ? 'Создать протокол' : 'Шаблон не настроен'}
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
1
src/pages/TemplateSetup/index.ts
Normal file
1
src/pages/TemplateSetup/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { TemplateSetup } from './ui/Page/Page';
|
||||
6
src/pages/TemplateSetup/ui/Page/Page.tsx
Normal file
6
src/pages/TemplateSetup/ui/Page/Page.tsx
Normal file
@@ -0,0 +1,6 @@
|
||||
import { FC } from 'react';
|
||||
import { TemplateManager } from '../../../../components/TemplateManager/TemplateManager';
|
||||
|
||||
export const TemplateSetup: FC = () => {
|
||||
return <TemplateManager />;
|
||||
};
|
||||
@@ -1,4 +1,8 @@
|
||||
import { ElementsCreation } from "./ElementsCreation";
|
||||
import { Home } from "./Home";
|
||||
import { NoMatch } from "./NoMatch";
|
||||
import { ProtocolCreation } from "./ProtocolCreation";
|
||||
import { TemplateSetup } from "./TemplateSetup";
|
||||
|
||||
export { ElementsCreation, Home, NoMatch, ProtocolCreation, TemplateSetup };
|
||||
|
||||
export { Home, NoMatch };
|
||||
|
||||
Reference in New Issue
Block a user