export interface CreateTemplateInput { name: string description?: string elements: Record attributes?: Array<{ attribute_id: string value: string | null }> } export interface CreateTemplateOutput { id: string } export interface GetTemplatesOutput { templates: ApiTemplateWithAttributes[] } export interface GetTemplateOutput { template: ApiTemplate | null } export interface GetTemplateWithAttributesOutput { template: ApiTemplateWithAttributes | null } export interface PatchTemplateInput { name?: string | null description?: string | null elements?: Record | null attributes?: Array<{ attribute_id: string value: string | null }> | null } export interface PatchTemplateOutput { id: string } export interface ApiTemplate { id: string name: string description?: string | null elements: Record created_at: string updated_at: string deleted_at?: string | null } export interface ApiTemplateWithAttributes extends ApiTemplate { attributes: Array<{ attribute_id: string attribute_name: string is_required: boolean value: string | null created_at: string updated_at: string }> } // Импортируем типы для преобразования import { getDefaultLayoutSettings, migrateTemplateElement } from '@/lib/utils' import { Template, TemplateAttributeDetail, TemplateElement, } from '@/type/template' // Утилитарные функции для преобразования данных // Преобразование API шаблона в внутренний формат export function apiTemplateToTemplate(apiTemplate: ApiTemplate): Template { // Преобразуем elements из Record в TemplateElement[] const elements: TemplateElement[] = Object.values(apiTemplate.elements || {}) .map(el => migrateTemplateElement(el)) .sort((a, b) => (a.order || 0) - (b.order || 0)) return { id: apiTemplate.id, name: apiTemplate.name, description: apiTemplate.description || undefined, elements, layoutSettings: getDefaultLayoutSettings(), createdAt: new Date(apiTemplate.created_at), updatedAt: new Date(apiTemplate.updated_at), } } // Преобразование API шаблона с атрибутами в внутренний формат export function apiTemplateWithAttributesToTemplate( apiTemplate: ApiTemplateWithAttributes ): Template & { attributes: TemplateAttributeDetail[] } { const baseTemplate = apiTemplateToTemplate(apiTemplate) return { ...baseTemplate, attributes: apiTemplate.attributes.map(attr => ({ attribute_id: attr.attribute_id, attribute_name: attr.attribute_name, is_required: attr.is_required, value: attr.value, created_at: attr.created_at, updated_at: attr.updated_at, })), } } // Преобразование внутреннего шаблона в API формат для создания export function templateToCreateInput( template: Omit ): CreateTemplateInput { // Преобразуем элементы в Record const elements: Record = {} template.elements.forEach((element, index) => { elements[element.id] = element }) return { name: template.name, description: template.description, elements, } } // Преобразование внутреннего шаблона в API формат для обновления export function templateToPatchInput(template: Template): PatchTemplateInput { const elements: Record = {} template.elements.forEach(element => { elements[element.id] = element }) return { name: template.name, description: template.description, elements, // attributes будут добавлены отдельно в TemplateContext при необходимости } } // API создание шаблона export async function createTemplateApi( template: CreateTemplateInput ): Promise { try { const response = await fetch('/api/templates/', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(template), }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } const result: CreateTemplateOutput = await response.json() return result } catch (error) { console.error('Ошибка при создании шаблона:', error) throw new Error('Ошибка при создании шаблона на сервере') } } // API получение всех шаблонов export async function getTemplatesApi(): Promise { try { const response = await fetch('/api/templates/', { method: 'GET', headers: { 'Content-Type': 'application/json', }, }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } const result: GetTemplatesOutput = await response.json() return result } catch (error) { console.error('Ошибка при получении шаблонов:', error) throw new Error('Ошибка при получении шаблонов с сервера') } } // API получение конкретного шаблона export async function getTemplateApi( templateId: string ): Promise { try { const response = await fetch(`/api/templates/${templateId}`, { method: 'GET', headers: { 'Content-Type': 'application/json', }, }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } const result: GetTemplateOutput = await response.json() return result } catch (error) { console.error('Ошибка при получении шаблона:', error) throw new Error('Ошибка при получении шаблона с сервера') } } // API получение шаблона с атрибутами export async function getTemplateWithAttributesApi( templateId: string ): Promise { try { const response = await fetch(`/api/templates/${templateId}`, { method: 'GET', headers: { 'Content-Type': 'application/json', }, }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } const result: GetTemplateWithAttributesOutput = await response.json() return result } catch (error) { console.error('Ошибка при получении шаблона с атрибутами:', error) throw new Error('Ошибка при получении шаблона с атрибутами с сервера') } } // API обновление шаблона export async function patchTemplateApi( templateId: string, template: PatchTemplateInput ): Promise { try { const response = await fetch(`/api/templates/${templateId}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(template), }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } const result: PatchTemplateOutput = await response.json() return result } catch (error) { console.error('Ошибка при обновлении шаблона:', error) throw new Error('Ошибка при обновлении шаблона на сервере') } } // Алиас для удобства использования export async function updateTemplate( template: Template ): Promise { const patchInput = templateToPatchInput(template) return patchTemplateApi(template.id, patchInput) } // Интерфейсы для копирования шаблона export interface CopyTemplateInput { template_id: string new_name: string new_description?: string | null new_attributes?: Array<{ attribute_id: string value: string | null }> | null } export interface CopyTemplateOutput { new_template_id: string } // Интерфейсы для удаления шаблона export interface DeleteTemplateOutput { success: boolean template_id: string } // API копирование шаблона export async function copyTemplateApi( input: CopyTemplateInput ): Promise { try { const response = await fetch('/api/templates/copy', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(input), }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } const result: CopyTemplateOutput = await response.json() return result } catch (error) { console.error('Ошибка при копировании шаблона:', error) throw new Error('Ошибка при копировании шаблона на сервере') } } // API удаление шаблона export async function deleteTemplateApi( templateId: string ): Promise { try { const response = await fetch(`/api/templates/${templateId}`, { method: 'DELETE', headers: { 'Content-Type': 'application/json', }, }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } const result: DeleteTemplateOutput = await response.json() return result } catch (error) { console.error('Ошибка при удалении шаблона:', error) throw new Error('Ошибка при удалении шаблона на сервере') } }