Добавлены модели и функциональность для работы с избранными товарами, включая мутации и запросы в GraphQL. Обновлены компоненты для отображения и управления избранным, улучшен интерфейс взаимодействия с пользователем. Реализована логика добавления и удаления товаров из избранного.
This commit is contained in:
@ -817,4 +817,61 @@ export const CLEAR_CART = gql`
|
||||
mutation ClearCart {
|
||||
clearCart
|
||||
}
|
||||
`
|
||||
|
||||
// Мутации для избранного
|
||||
export const ADD_TO_FAVORITES = gql`
|
||||
mutation AddToFavorites($productId: ID!) {
|
||||
addToFavorites(productId: $productId) {
|
||||
success
|
||||
message
|
||||
favorites {
|
||||
id
|
||||
name
|
||||
article
|
||||
price
|
||||
quantity
|
||||
images
|
||||
mainImage
|
||||
category {
|
||||
id
|
||||
name
|
||||
}
|
||||
organization {
|
||||
id
|
||||
name
|
||||
fullName
|
||||
inn
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const REMOVE_FROM_FAVORITES = gql`
|
||||
mutation RemoveFromFavorites($productId: ID!) {
|
||||
removeFromFavorites(productId: $productId) {
|
||||
success
|
||||
message
|
||||
favorites {
|
||||
id
|
||||
name
|
||||
article
|
||||
price
|
||||
quantity
|
||||
images
|
||||
mainImage
|
||||
category {
|
||||
id
|
||||
name
|
||||
}
|
||||
organization {
|
||||
id
|
||||
name
|
||||
fullName
|
||||
inn
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
@ -436,4 +436,44 @@ export const GET_MY_CART = gql`
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const GET_MY_FAVORITES = gql`
|
||||
query GetMyFavorites {
|
||||
myFavorites {
|
||||
id
|
||||
name
|
||||
article
|
||||
description
|
||||
price
|
||||
quantity
|
||||
brand
|
||||
color
|
||||
size
|
||||
images
|
||||
mainImage
|
||||
isActive
|
||||
createdAt
|
||||
updatedAt
|
||||
category {
|
||||
id
|
||||
name
|
||||
}
|
||||
organization {
|
||||
id
|
||||
inn
|
||||
name
|
||||
fullName
|
||||
type
|
||||
address
|
||||
phones
|
||||
emails
|
||||
users {
|
||||
id
|
||||
avatar
|
||||
managerName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
@ -638,6 +638,44 @@ export const resolvers = {
|
||||
}
|
||||
|
||||
return cart
|
||||
},
|
||||
|
||||
// Избранные товары пользователя
|
||||
myFavorites: async (_: unknown, __: unknown, context: Context) => {
|
||||
if (!context.user) {
|
||||
throw new GraphQLError('Требуется авторизация', {
|
||||
extensions: { code: 'UNAUTHENTICATED' }
|
||||
})
|
||||
}
|
||||
|
||||
const currentUser = await prisma.user.findUnique({
|
||||
where: { id: context.user.id },
|
||||
include: { organization: true }
|
||||
})
|
||||
|
||||
if (!currentUser?.organization) {
|
||||
throw new GraphQLError('У пользователя нет организации')
|
||||
}
|
||||
|
||||
// Получаем избранные товары
|
||||
const favorites = await prisma.favorites.findMany({
|
||||
where: { organizationId: currentUser.organization.id },
|
||||
include: {
|
||||
product: {
|
||||
include: {
|
||||
category: true,
|
||||
organization: {
|
||||
include: {
|
||||
users: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
orderBy: { createdAt: 'desc' }
|
||||
})
|
||||
|
||||
return favorites.map(favorite => favorite.product)
|
||||
}
|
||||
},
|
||||
|
||||
@ -2844,6 +2882,165 @@ export const resolvers = {
|
||||
console.error('Error clearing cart:', error)
|
||||
return false
|
||||
}
|
||||
},
|
||||
|
||||
// Добавить товар в избранное
|
||||
addToFavorites: async (_: unknown, args: { productId: string }, context: Context) => {
|
||||
if (!context.user) {
|
||||
throw new GraphQLError('Требуется авторизация', {
|
||||
extensions: { code: 'UNAUTHENTICATED' }
|
||||
})
|
||||
}
|
||||
|
||||
const currentUser = await prisma.user.findUnique({
|
||||
where: { id: context.user.id },
|
||||
include: { organization: true }
|
||||
})
|
||||
|
||||
if (!currentUser?.organization) {
|
||||
throw new GraphQLError('У пользователя нет организации')
|
||||
}
|
||||
|
||||
// Проверяем, что товар существует и активен
|
||||
const product = await prisma.product.findFirst({
|
||||
where: {
|
||||
id: args.productId,
|
||||
isActive: true
|
||||
},
|
||||
include: {
|
||||
organization: true
|
||||
}
|
||||
})
|
||||
|
||||
if (!product) {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Товар не найден или неактивен'
|
||||
}
|
||||
}
|
||||
|
||||
// Проверяем, что пользователь не пытается добавить свой собственный товар
|
||||
if (product.organizationId === currentUser.organization.id) {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Нельзя добавлять собственные товары в избранное'
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Проверяем, есть ли уже такой товар в избранном
|
||||
const existingFavorite = await prisma.favorites.findUnique({
|
||||
where: {
|
||||
organizationId_productId: {
|
||||
organizationId: currentUser.organization.id,
|
||||
productId: args.productId
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (existingFavorite) {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Товар уже в избранном'
|
||||
}
|
||||
}
|
||||
|
||||
// Добавляем товар в избранное
|
||||
await prisma.favorites.create({
|
||||
data: {
|
||||
organizationId: currentUser.organization.id,
|
||||
productId: args.productId
|
||||
}
|
||||
})
|
||||
|
||||
// Возвращаем обновленный список избранного
|
||||
const favorites = await prisma.favorites.findMany({
|
||||
where: { organizationId: currentUser.organization.id },
|
||||
include: {
|
||||
product: {
|
||||
include: {
|
||||
category: true,
|
||||
organization: {
|
||||
include: {
|
||||
users: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
orderBy: { createdAt: 'desc' }
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Товар добавлен в избранное',
|
||||
favorites: favorites.map(favorite => favorite.product)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error adding to favorites:', error)
|
||||
return {
|
||||
success: false,
|
||||
message: 'Ошибка при добавлении в избранное'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Удалить товар из избранного
|
||||
removeFromFavorites: async (_: unknown, args: { productId: string }, context: Context) => {
|
||||
if (!context.user) {
|
||||
throw new GraphQLError('Требуется авторизация', {
|
||||
extensions: { code: 'UNAUTHENTICATED' }
|
||||
})
|
||||
}
|
||||
|
||||
const currentUser = await prisma.user.findUnique({
|
||||
where: { id: context.user.id },
|
||||
include: { organization: true }
|
||||
})
|
||||
|
||||
if (!currentUser?.organization) {
|
||||
throw new GraphQLError('У пользователя нет организации')
|
||||
}
|
||||
|
||||
try {
|
||||
// Удаляем товар из избранного
|
||||
await prisma.favorites.deleteMany({
|
||||
where: {
|
||||
organizationId: currentUser.organization.id,
|
||||
productId: args.productId
|
||||
}
|
||||
})
|
||||
|
||||
// Возвращаем обновленный список избранного
|
||||
const favorites = await prisma.favorites.findMany({
|
||||
where: { organizationId: currentUser.organization.id },
|
||||
include: {
|
||||
product: {
|
||||
include: {
|
||||
category: true,
|
||||
organization: {
|
||||
include: {
|
||||
users: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
orderBy: { createdAt: 'desc' }
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Товар удален из избранного',
|
||||
favorites: favorites.map(favorite => favorite.product)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error removing from favorites:', error)
|
||||
return {
|
||||
success: false,
|
||||
message: 'Ошибка при удалении из избранного'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -40,6 +40,9 @@ export const typeDefs = gql`
|
||||
|
||||
# Корзина пользователя
|
||||
myCart: Cart
|
||||
|
||||
# Избранные товары пользователя
|
||||
myFavorites: [Product!]!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
@ -100,6 +103,10 @@ export const typeDefs = gql`
|
||||
updateCartItem(productId: ID!, quantity: Int!): CartResponse!
|
||||
removeFromCart(productId: ID!): CartResponse!
|
||||
clearCart: Boolean!
|
||||
|
||||
# Работа с избранным
|
||||
addToFavorites(productId: ID!): FavoritesResponse!
|
||||
removeFromFavorites(productId: ID!): FavoritesResponse!
|
||||
}
|
||||
|
||||
# Типы данных
|
||||
@ -456,6 +463,13 @@ export const typeDefs = gql`
|
||||
cart: Cart
|
||||
}
|
||||
|
||||
# Типы для избранного
|
||||
type FavoritesResponse {
|
||||
success: Boolean!
|
||||
message: String!
|
||||
favorites: [Product!]
|
||||
}
|
||||
|
||||
# JSON скаляр
|
||||
scalar JSON
|
||||
`
|
Reference in New Issue
Block a user