ручной рефакторинг

This commit is contained in:
2025-07-28 17:03:01 +03:00
parent d8e6dcd7d5
commit b98dfeef20
55 changed files with 844 additions and 1416 deletions

View File

@@ -0,0 +1,338 @@
export interface CreateTemplateInput {
name: string
description?: string
elements: Record<string, any>
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<string, any> | 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<string, any>
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<string, any> в 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<Template, 'id' | 'createdAt' | 'updatedAt'>
): CreateTemplateInput {
// Преобразуем элементы в Record<string, any>
const elements: Record<string, any> = {}
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<string, any> = {}
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<CreateTemplateOutput> {
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<GetTemplatesOutput> {
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<GetTemplateOutput> {
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<GetTemplateWithAttributesOutput> {
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<PatchTemplateOutput> {
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<PatchTemplateOutput> {
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<CopyTemplateOutput> {
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<DeleteTemplateOutput> {
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('Ошибка при удалении шаблона на сервере')
}
}