import { ConditionType, CreateDailyConditionInput, CreateDailyConditionOutput, DailyCondition, DailyConditionsFilters, GetDailyConditionOutput, GetDailyConditionsOutput, GetLaboratoriesOutput, GetLaboratoryOutput, Laboratory, UpdateDailyConditionInput, UpdateDailyConditionOutput, } from './types' // Базовый URL для API (может быть настроен через переменные окружения) const BASE_URL = import.meta.env.VITE_API_BASE_URL || '/api' // API для лабораторий export const laboratoriesApi = { // Получить все лаборатории getAll: async (): Promise => { const response = await fetch(`${BASE_URL}/laboratories/`) if (!response.ok) { throw new Error('Ошибка загрузки лабораторий') } const data: GetLaboratoriesOutput = await response.json() return data.laboratories }, // Получить лабораторию по ID getById: async (id: string): Promise => { const response = await fetch(`${BASE_URL}/laboratories/${id}`) if (!response.ok) { if (response.status === 404) { return null } throw new Error('Ошибка получения лаборатории') } const data: GetLaboratoryOutput = await response.json() return data.laboratory }, } // API для ежедневных условий export const dailyConditionsApi = { // Получить условия по фильтрам get: async ( filters: DailyConditionsFilters = {} ): Promise => { const searchParams = new URLSearchParams() if (filters.laboratory_id) { searchParams.append('laboratory_id', filters.laboratory_id) } if (filters.start_date) { searchParams.append('start_date', filters.start_date) } if (filters.end_date) { searchParams.append('end_date', filters.end_date) } const url = searchParams.toString() ? `${BASE_URL}/daily-conditions/?${searchParams}` : `${BASE_URL}/daily-conditions/` const response = await fetch(url) if (!response.ok) { throw new Error('Ошибка загрузки условий') } const data: GetDailyConditionsOutput = await response.json() return data.daily_conditions }, // Получить конкретное условие по ID getById: async (id: string): Promise => { const response = await fetch(`${BASE_URL}/daily-conditions/${id}`) if (!response.ok) { if (response.status === 404) { return null } throw new Error('Ошибка получения условия') } const data: GetDailyConditionOutput = await response.json() return data.daily_condition }, // Создать новые условия create: async (input: CreateDailyConditionInput): Promise => { const response = await fetch(`${BASE_URL}/daily-conditions/`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(input), }) if (!response.ok) { const error = await response .json() .catch(() => ({ message: 'Ошибка сохранения условий' })) throw new Error(error.message || 'Ошибка сохранения условий') } const data: CreateDailyConditionOutput = await response.json() return data.id }, // Обновить условия update: async ( id: string, input: UpdateDailyConditionInput ): Promise => { const response = await fetch(`${BASE_URL}/daily-conditions/${id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(input), }) if (!response.ok) { throw new Error('Ошибка обновления условий') } const data: UpdateDailyConditionOutput = await response.json() return data.id }, // Удалить условия delete: async (id: string): Promise => { const response = await fetch(`${BASE_URL}/daily-conditions/${id}`, { method: 'DELETE', }) if (!response.ok) { throw new Error('Ошибка удаления условий') } }, } // Комбинированный API для работы с элементом export const elementApi = { // Получить лабораторию с её типами условий getLaboratoryData: async ( laboratoryId: string ): Promise<{ laboratory: Laboratory conditionTypes: ConditionType[] }> => { const laboratory = await laboratoriesApi.getById(laboratoryId) if (!laboratory) { throw new Error('Лаборатория не найдена') } return { laboratory, conditionTypes: laboratory.condition_types, } }, // Получить ежедневные условия для конкретной лаборатории и даты getDailyConditions: async ( laboratoryId: string, date: string ): Promise => { const conditions = await dailyConditionsApi.get({ laboratory_id: laboratoryId, start_date: date, end_date: date, }) return conditions.length > 0 ? conditions[0] : null }, // Сохранить или обновить условия из элемента saveElementConditions: async (data: { laboratoryId: string date: string conditions: Record existingConditionId?: string }): Promise => { const input: CreateDailyConditionInput | UpdateDailyConditionInput = { laboratory_id: data.laboratoryId, measurement_date: data.date, conditions: data.conditions, } let conditionId: string if (data.existingConditionId) { // Обновляем существующие условия conditionId = await dailyConditionsApi.update( data.existingConditionId, input as UpdateDailyConditionInput ) } else { // Создаем новые условия conditionId = await dailyConditionsApi.create( input as CreateDailyConditionInput ) } // Получаем обновленные данные const savedCondition = await dailyConditionsApi.getById(conditionId) if (!savedCondition) { throw new Error('Ошибка получения сохраненных условий') } return savedCondition }, } // Вспомогательные функции export const verificationConditionsUtils = { // Валидация значения условия validateConditionValue: ( value: any, dataType: string = 'string', minValue?: number, maxValue?: number ): { isValid: boolean; error?: string } => { if (dataType === 'number') { const numValue = parseFloat(value) if (isNaN(numValue)) { return { isValid: false, error: 'Должно быть числом' } } if (minValue !== undefined && numValue < minValue) { return { isValid: false, error: `Минимальное значение: ${minValue}` } } if (maxValue !== undefined && numValue > maxValue) { return { isValid: false, error: `Максимальное значение: ${maxValue}` } } } return { isValid: true } }, // Форматирование значения с единицей измерения formatValueWithUnit: (value: any, unit?: string): string => { if (value === undefined || value === null || value === '') { return '-' } return unit ? `${value} ${unit}` : value.toString() }, // Получение ключа условия для хранения в conditions JSON (обычно используется ID типа условия) getConditionKey: (conditionTypeId: string): string => { return conditionTypeId }, // Генерация ключа на основе названия условия (для обратной совместимости) generateConditionKey: (conditionTypeName: string): string => { return conditionTypeName .toLowerCase() .replace(/\s+/g, '_') .replace(/[^\w]/g, '') }, // Проверка, является ли строка валидным UUID isValidUUID: (str: string): boolean => { const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i return uuidRegex.test(str) }, }