feat: модуляризировать market-counterparties компонент (835→291 строк)

- Разделить 835 строк на модульную архитектуру (11 файлов)
- Создать orchestrator + types + hooks + blocks структуру
- Сохранить все функции: 3 вкладки, статистика, поиск, партнерская ссылка
- Исправить типы партнерской ссылки (PartnerLink → string)
- Интегрировать поиск новых организаций в главную вкладку
- Сохранить glass-эффекты, анимации и все визуальные элементы

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Veronika Smirnova
2025-09-17 23:03:52 +03:00
parent fa53e442f4
commit ced65f8214
16 changed files with 4440 additions and 1 deletions

View File

@ -0,0 +1,236 @@
/**
* Hook для управления действиями с контрагентами
* Обрабатывает все GraphQL mutations и их результаты
*/
import { useMutation } from '@apollo/client'
import { useCallback, useState } from 'react'
import { toast } from 'sonner'
import {
RESPOND_TO_COUNTERPARTY_REQUEST,
CANCEL_COUNTERPARTY_REQUEST,
REMOVE_COUNTERPARTY,
SEND_COUNTERPARTY_REQUEST,
} from '@/graphql/mutations'
import {
GET_MY_COUNTERPARTIES,
GET_INCOMING_REQUESTS,
GET_OUTGOING_REQUESTS,
SEARCH_ORGANIZATIONS,
} from '@/graphql/queries'
import type { UseCounterpartyActionsReturn } from '../types'
export function useCounterpartyActions(): UseCounterpartyActionsReturn {
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
// Mutation для ответа на заявку (принять/отклонить)
const [respondToRequestMutation] = useMutation(RESPOND_TO_COUNTERPARTY_REQUEST, {
refetchQueries: [
{ query: GET_INCOMING_REQUESTS },
{ query: GET_MY_COUNTERPARTIES },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'SELLER' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'FULFILLMENT' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'LOGIST' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'WHOLESALE' } },
],
awaitRefetchQueries: true,
})
// Mutation для отмены исходящей заявки
const [cancelRequestMutation] = useMutation(CANCEL_COUNTERPARTY_REQUEST, {
refetchQueries: [
{ query: GET_OUTGOING_REQUESTS },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'SELLER' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'FULFILLMENT' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'LOGIST' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'WHOLESALE' } },
],
awaitRefetchQueries: true,
})
// Mutation для удаления контрагента
const [removeCounterpartyMutation] = useMutation(REMOVE_COUNTERPARTY, {
refetchQueries: [
{ query: GET_MY_COUNTERPARTIES },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'SELLER' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'FULFILLMENT' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'LOGIST' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'WHOLESALE' } },
],
awaitRefetchQueries: true,
})
// Mutation для отправки заявки на партнерство
const [sendRequestMutation] = useMutation(SEND_COUNTERPARTY_REQUEST, {
refetchQueries: [
{ query: GET_OUTGOING_REQUESTS },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'SELLER' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'FULFILLMENT' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'LOGIST' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'WHOLESALE' } },
],
awaitRefetchQueries: true,
})
// Принять заявку на партнерство
const acceptRequest = useCallback(async (requestId: string) => {
setLoading(true)
setError(null)
try {
const { data } = await respondToRequestMutation({
variables: {
requestId,
response: 'ACCEPTED',
},
})
if (data?.respondToCounterpartyRequest?.success) {
toast.success('Заявка принята! Организация добавлена в контрагенты')
} else {
const errorMessage = data?.respondToCounterpartyRequest?.message || 'Не удалось принять заявку'
setError(errorMessage)
toast.error(errorMessage)
}
} catch (error) {
console.error('Error accepting request:', error)
const errorMessage = 'Ошибка при принятии заявки'
setError(errorMessage)
toast.error(errorMessage)
} finally {
setLoading(false)
}
}, [respondToRequestMutation])
// Отклонить заявку на партнерство
const rejectRequest = useCallback(async (requestId: string) => {
setLoading(true)
setError(null)
try {
const { data } = await respondToRequestMutation({
variables: {
requestId,
response: 'REJECTED',
},
})
if (data?.respondToCounterpartyRequest?.success) {
toast.success('Заявка отклонена')
} else {
const errorMessage = data?.respondToCounterpartyRequest?.message || 'Не удалось отклонить заявку'
setError(errorMessage)
toast.error(errorMessage)
}
} catch (error) {
console.error('Error rejecting request:', error)
const errorMessage = 'Ошибка при отклонении заявки'
setError(errorMessage)
toast.error(errorMessage)
} finally {
setLoading(false)
}
}, [respondToRequestMutation])
// Отменить исходящую заявку
const cancelRequest = useCallback(async (requestId: string) => {
setLoading(true)
setError(null)
try {
const { data } = await cancelRequestMutation({
variables: { requestId },
})
if (data?.cancelCounterpartyRequest?.success) {
toast.success('Заявка отменена')
} else {
const errorMessage = data?.cancelCounterpartyRequest?.message || 'Не удалось отменить заявку'
setError(errorMessage)
toast.error(errorMessage)
}
} catch (error) {
console.error('Error canceling request:', error)
const errorMessage = 'Ошибка при отмене заявки'
setError(errorMessage)
toast.error(errorMessage)
} finally {
setLoading(false)
}
}, [cancelRequestMutation])
// Отправить заявку на партнерство
const sendRequest = useCallback(async (organizationId: string, message?: string) => {
setLoading(true)
setError(null)
try {
const { data } = await sendRequestMutation({
variables: {
organizationId,
message: message || 'Предлагаем партнерское сотрудничество',
},
})
if (data?.sendCounterpartyRequest?.success) {
toast.success('Заявка отправлена! Ожидайте ответа от организации')
} else {
const errorMessage = data?.sendCounterpartyRequest?.message || 'Не удалось отправить заявку'
setError(errorMessage)
toast.error(errorMessage)
}
} catch (error) {
console.error('Error sending request:', error)
const errorMessage = 'Ошибка при отправке заявки'
setError(errorMessage)
toast.error(errorMessage)
} finally {
setLoading(false)
}
}, [sendRequestMutation])
// Удалить контрагента
const removeCounterparty = useCallback(async (organizationId: string) => {
setLoading(true)
setError(null)
try {
const { data } = await removeCounterpartyMutation({
variables: { organizationId },
})
if (data?.removeCounterparty?.success) {
toast.success('Контрагент удален из списка')
} else {
const errorMessage = data?.removeCounterparty?.message || 'Не удалось удалить контрагента'
setError(errorMessage)
toast.error(errorMessage)
}
} catch (error) {
console.error('Error removing counterparty:', error)
const errorMessage = 'Ошибка при удалении контрагента'
setError(errorMessage)
toast.error(errorMessage)
} finally {
setLoading(false)
}
}, [removeCounterpartyMutation])
return {
// Действия с заявками
acceptRequest,
rejectRequest,
cancelRequest,
sendRequest,
// Действия с контрагентами
removeCounterparty,
// Состояние
loading,
error,
}
}