Удален файл с тестовым заданием по системе управления сотрудниками. Обновлены зависимости в package.json и package-lock.json, добавлен новый пакет react-resizable-panels. Внесены изменения в компоненты для улучшения работы боковой панели и отображения дат. Добавлены новые функции для обработки дат в формате DateTime в GraphQL.

This commit is contained in:
Bivekich
2025-07-20 22:50:21 +03:00
parent 8d57fcd748
commit cc1f9d8473
16 changed files with 354 additions and 696 deletions

View File

@ -137,6 +137,30 @@ const JSONScalar = new GraphQLScalarType({
}
})
// Скалярный тип для DateTime
const DateTimeScalar = new GraphQLScalarType({
name: 'DateTime',
description: 'DateTime custom scalar type',
serialize(value: unknown) {
if (value instanceof Date) {
return value.toISOString() // значение отправляется клиенту как ISO строка
}
return value
},
parseValue(value: unknown) {
if (typeof value === 'string') {
return new Date(value) // значение получено от клиента, парсим как дату
}
return value
},
parseLiteral(ast) {
if (ast.kind === Kind.STRING) {
return new Date(ast.value) // AST значение как дата
}
return null
}
})
function parseLiteral(ast: unknown): unknown {
const astNode = ast as { kind: string; value?: unknown; fields?: unknown[]; values?: unknown[] }
@ -166,6 +190,7 @@ function parseLiteral(ast: unknown): unknown {
export const resolvers = {
JSON: JSONScalar,
DateTime: DateTimeScalar,
Query: {
me: async (_: unknown, __: unknown, context: Context) => {
@ -643,7 +668,7 @@ export const resolvers = {
// Все категории
categories: async (_: unknown, __: unknown, context: Context) => {
if (!context.user) {
if (!context.user && !context.admin) {
throw new GraphQLError('Требуется авторизация', {
extensions: { code: 'UNAUTHENTICATED' }
})
@ -2735,7 +2760,7 @@ export const resolvers = {
// Создать категорию
createCategory: async (_: unknown, args: { input: { name: string } }, context: Context) => {
if (!context.user) {
if (!context.user && !context.admin) {
throw new GraphQLError('Требуется авторизация', {
extensions: { code: 'UNAUTHENTICATED' }
})
@ -2776,7 +2801,7 @@ export const resolvers = {
// Обновить категорию
updateCategory: async (_: unknown, args: { id: string; input: { name: string } }, context: Context) => {
if (!context.user) {
if (!context.user && !context.admin) {
throw new GraphQLError('Требуется авторизация', {
extensions: { code: 'UNAUTHENTICATED' }
})
@ -2832,7 +2857,7 @@ export const resolvers = {
// Удалить категорию
deleteCategory: async (_: unknown, args: { id: string }, context: Context) => {
if (!context.user) {
if (!context.user && !context.admin) {
throw new GraphQLError('Требуется авторизация', {
extensions: { code: 'UNAUTHENTICATED' }
})

View File

@ -1,6 +1,8 @@
import { gql } from 'graphql-tag'
export const typeDefs = gql`
scalar DateTime
type Query {
me: User
organization(id: ID!): Organization
@ -150,8 +152,8 @@ export const typeDefs = gql`
avatar: String
managerName: String
organization: Organization
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
}
type Organization {
@ -163,12 +165,12 @@ export const typeDefs = gql`
address: String
addressFull: String
ogrn: String
ogrnDate: String
ogrnDate: DateTime
type: OrganizationType!
status: String
actualityDate: String
registrationDate: String
liquidationDate: String
actualityDate: DateTime
registrationDate: DateTime
liquidationDate: DateTime
managementName: String
managementPost: String
opfCode: String
@ -189,8 +191,8 @@ export const typeDefs = gql`
isCurrentUser: Boolean
hasOutgoingRequest: Boolean
hasIncomingRequest: Boolean
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
}
type ApiKey {
@ -198,8 +200,8 @@ export const typeDefs = gql`
marketplace: MarketplaceType!
isActive: Boolean!
validationData: JSON
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
}
# Входные типы для мутаций
@ -312,8 +314,8 @@ export const typeDefs = gql`
message: String
sender: Organization!
receiver: Organization!
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
}
type CounterpartyRequestResponse {
@ -337,8 +339,8 @@ export const typeDefs = gql`
senderOrganization: Organization!
receiverOrganization: Organization!
isRead: Boolean!
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
}
enum MessageType {
@ -353,7 +355,7 @@ export const typeDefs = gql`
counterparty: Organization!
lastMessage: Message
unreadCount: Int!
updatedAt: String!
updatedAt: DateTime!
}
type MessageResponse {
@ -369,8 +371,8 @@ export const typeDefs = gql`
description: String
price: Float!
imageUrl: String
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
organization: Organization!
}
@ -394,8 +396,8 @@ export const typeDefs = gql`
description: String
price: Float!
imageUrl: String
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
organization: Organization!
}
@ -420,8 +422,8 @@ export const typeDefs = gql`
priceUnder1m3: Float!
priceOver1m3: Float!
description: String
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
organization: Organization!
}
@ -443,8 +445,8 @@ export const typeDefs = gql`
type Category {
id: ID!
name: String!
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
}
# Типы для товаров оптовика
@ -465,8 +467,8 @@ export const typeDefs = gql`
images: [String!]!
mainImage: String
isActive: Boolean!
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
organization: Organization!
}
@ -510,8 +512,8 @@ export const typeDefs = gql`
items: [CartItem!]!
totalPrice: Float!
totalItems: Int!
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
organization: Organization!
}
@ -522,8 +524,8 @@ export const typeDefs = gql`
totalPrice: Float!
isAvailable: Boolean!
availableQuantity: Int!
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
}
type CartResponse {
@ -545,17 +547,17 @@ export const typeDefs = gql`
firstName: String!
lastName: String!
middleName: String
birthDate: String
birthDate: DateTime
avatar: String
passportPhoto: String
passportSeries: String
passportNumber: String
passportIssued: String
passportDate: String
passportDate: DateTime
address: String
position: String!
department: String
hireDate: String!
hireDate: DateTime!
salary: Float
status: EmployeeStatus!
phone: String!
@ -566,8 +568,8 @@ export const typeDefs = gql`
emergencyPhone: String
scheduleRecords: [EmployeeSchedule!]!
organization: Organization!
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
}
enum EmployeeStatus {
@ -579,13 +581,13 @@ export const typeDefs = gql`
type EmployeeSchedule {
id: ID!
date: String!
date: DateTime!
status: ScheduleStatus!
hoursWorked: Float
notes: String
employee: Employee!
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
}
enum ScheduleStatus {
@ -600,17 +602,17 @@ export const typeDefs = gql`
firstName: String!
lastName: String!
middleName: String
birthDate: String
birthDate: DateTime
avatar: String
passportPhoto: String
passportSeries: String
passportNumber: String
passportIssued: String
passportDate: String
passportDate: DateTime
address: String
position: String!
department: String
hireDate: String!
hireDate: DateTime!
salary: Float
phone: String!
email: String
@ -624,17 +626,17 @@ export const typeDefs = gql`
firstName: String
lastName: String
middleName: String
birthDate: String
birthDate: DateTime
avatar: String
passportPhoto: String
passportSeries: String
passportNumber: String
passportIssued: String
passportDate: String
passportDate: DateTime
address: String
position: String
department: String
hireDate: String
hireDate: DateTime
salary: Float
status: EmployeeStatus
phone: String
@ -647,7 +649,7 @@ export const typeDefs = gql`
input UpdateScheduleInput {
employeeId: ID!
date: String!
date: DateTime!
status: ScheduleStatus!
hoursWorked: Float
notes: String
@ -675,8 +677,8 @@ export const typeDefs = gql`
email: String
isActive: Boolean!
lastLogin: String
createdAt: String!
updatedAt: String!
createdAt: DateTime!
updatedAt: DateTime!
}
type AdminAuthResponse {