Добавлены модели и функциональность для управления логистикой, включая создание, обновление и удаление логистических маршрутов через GraphQL. Обновлены компоненты для отображения и управления логистикой, улучшен интерфейс взаимодействия с пользователем. Реализованы новые типы данных и интерфейсы для логистики, а также улучшена обработка ошибок.

This commit is contained in:
Bivekich
2025-07-18 15:40:12 +03:00
parent 7e7e4a9b4a
commit 93bb5827d2
20 changed files with 5015 additions and 667 deletions

111
src/lib/input-masks.ts Normal file
View File

@ -0,0 +1,111 @@
// Утилиты для масок ввода в формах сотрудников
// Маска для телефона в формате +7 (999) 123-45-67
export const formatPhoneInput = (value: string): string => {
const cleaned = value.replace(/\D/g, '')
if (cleaned.length === 0) return ''
if (cleaned.length <= 1) return cleaned.startsWith('7') ? '+7' : cleaned
if (cleaned.length <= 4) return `+7 (${cleaned.slice(1)}`
if (cleaned.length <= 7) return `+7 (${cleaned.slice(1, 4)}) ${cleaned.slice(4)}`
if (cleaned.length <= 9) return `+7 (${cleaned.slice(1, 4)}) ${cleaned.slice(4, 7)}-${cleaned.slice(7)}`
return `+7 (${cleaned.slice(1, 4)}) ${cleaned.slice(4, 7)}-${cleaned.slice(7, 9)}-${cleaned.slice(9, 11)}`
}
// Маска для серии паспорта (4 цифры)
export const formatPassportSeries = (value: string): string => {
const cleaned = value.replace(/\D/g, '')
return cleaned.slice(0, 4)
}
// Маска для номера паспорта (6 цифр)
export const formatPassportNumber = (value: string): string => {
const cleaned = value.replace(/\D/g, '')
return cleaned.slice(0, 6)
}
// Маска для зарплаты с разделителями тысяч
export const formatSalary = (value: string): string => {
const cleaned = value.replace(/\D/g, '')
if (!cleaned) return ''
return parseInt(cleaned).toLocaleString('ru-RU')
}
// Маска для имени, фамилии, отчества (только буквы, пробелы, дефисы)
export const formatNameInput = (value: string): string => {
return value.replace(/[^а-яёА-ЯЁa-zA-Z\s-]/g, '')
}
// Валидация email
export const isValidEmail = (email: string): boolean => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return emailRegex.test(email)
}
// Валидация телефона
export const isValidPhone = (phone: string): boolean => {
const phoneRegex = /^\+7\s\(\d{3}\)\s\d{3}-\d{2}-\d{2}$/
return phoneRegex.test(phone)
}
// Валидация серии паспорта
export const isValidPassportSeries = (series: string): boolean => {
return /^\d{4}$/.test(series)
}
// Валидация номера паспорта
export const isValidPassportNumber = (number: string): boolean => {
return /^\d{6}$/.test(number)
}
// Валидация возраста
export const isValidBirthDate = (birthDate: string): { valid: boolean; message?: string } => {
if (!birthDate) return { valid: true }
const birth = new Date(birthDate)
const today = new Date()
const age = today.getFullYear() - birth.getFullYear()
if (birth > today) {
return { valid: false, message: 'Дата рождения не может быть в будущем' }
}
if (age < 14) {
return { valid: false, message: 'Возраст должен быть не менее 14 лет' }
}
if (age > 100) {
return { valid: false, message: 'Проверьте корректность даты рождения' }
}
return { valid: true }
}
// Валидация даты приема на работу
export const isValidHireDate = (hireDate: string): { valid: boolean; message?: string } => {
if (!hireDate) return { valid: false, message: 'Дата приема на работу обязательна' }
const hire = new Date(hireDate)
const today = new Date()
if (hire > today) {
return { valid: false, message: 'Дата приема не может быть в будущем' }
}
return { valid: true }
}
// Валидация зарплаты
export const isValidSalary = (salary: number | undefined): { valid: boolean; message?: string } => {
if (salary === undefined || salary === null) return { valid: true }
if (salary < 0) {
return { valid: false, message: 'Зарплата не может быть отрицательной' }
}
if (salary > 10000000) {
return { valid: false, message: 'Слишком большая сумма зарплаты' }
}
return { valid: true }
}