Добавлены новые зависимости для работы с эмодзи и улучшена структура базы данных. Реализована модель сообщений и обновлены компоненты для поддержки новых функций мессенджера. Обновлены запросы и мутации для работы с сообщениями и чатом.
This commit is contained in:
@ -2,21 +2,18 @@
|
||||
|
||||
import { useState } from 'react'
|
||||
import { useQuery, useMutation } from '@apollo/client'
|
||||
import { Card } from '@/components/ui/card'
|
||||
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||
import {
|
||||
Users,
|
||||
Clock,
|
||||
Send,
|
||||
CheckCircle,
|
||||
XCircle,
|
||||
ArrowUpCircle,
|
||||
ArrowDownCircle
|
||||
} from 'lucide-react'
|
||||
import { OrganizationCard } from './organization-card'
|
||||
import { GET_MY_COUNTERPARTIES, GET_INCOMING_REQUESTS, GET_OUTGOING_REQUESTS } from '@/graphql/queries'
|
||||
import { OrganizationAvatar } from './organization-avatar'
|
||||
import { GET_MY_COUNTERPARTIES, GET_INCOMING_REQUESTS, GET_OUTGOING_REQUESTS, SEARCH_ORGANIZATIONS } from '@/graphql/queries'
|
||||
import { RESPOND_TO_COUNTERPARTY_REQUEST, CANCEL_COUNTERPARTY_REQUEST, REMOVE_COUNTERPARTY } from '@/graphql/mutations'
|
||||
|
||||
interface Organization {
|
||||
@ -47,28 +44,43 @@ export function MarketCounterparties() {
|
||||
const { data: outgoingData, loading: outgoingLoading, refetch: refetchOutgoing } = useQuery(GET_OUTGOING_REQUESTS)
|
||||
|
||||
const [respondToRequest] = useMutation(RESPOND_TO_COUNTERPARTY_REQUEST, {
|
||||
onCompleted: () => {
|
||||
refetchIncoming()
|
||||
refetchCounterparties()
|
||||
}
|
||||
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
|
||||
})
|
||||
|
||||
const [cancelRequest] = useMutation(CANCEL_COUNTERPARTY_REQUEST, {
|
||||
onCompleted: () => {
|
||||
refetchOutgoing()
|
||||
}
|
||||
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 [removeCounterparty] = useMutation(REMOVE_COUNTERPARTY, {
|
||||
onCompleted: () => {
|
||||
refetchCounterparties()
|
||||
}
|
||||
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
|
||||
})
|
||||
|
||||
const handleAcceptRequest = async (requestId: string) => {
|
||||
try {
|
||||
await respondToRequest({
|
||||
variables: { requestId, response: 'ACCEPTED' }
|
||||
variables: { requestId, accept: true }
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Ошибка при принятии заявки:', error)
|
||||
@ -78,7 +90,7 @@ export function MarketCounterparties() {
|
||||
const handleRejectRequest = async (requestId: string) => {
|
||||
try {
|
||||
await respondToRequest({
|
||||
variables: { requestId, response: 'REJECTED' }
|
||||
variables: { requestId, accept: false }
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Ошибка при отклонении заявки:', error)
|
||||
@ -207,50 +219,72 @@ export function MarketCounterparties() {
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{incomingRequests.map((request: CounterpartyRequest) => (
|
||||
<Card key={request.id} className="glass-card p-4">
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex items-start space-x-3 flex-1">
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="w-10 h-10 rounded-full bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center text-white font-semibold">
|
||||
{(request.sender.name || request.sender.fullName || 'O').charAt(0).toUpperCase()}
|
||||
</div>
|
||||
</div>
|
||||
<div key={request.id} className="glass-card p-4 w-full">
|
||||
<div className="flex flex-col space-y-4">
|
||||
<div className="flex items-start space-x-3">
|
||||
<OrganizationAvatar organization={request.sender} size="md" />
|
||||
<div className="flex-1 min-w-0">
|
||||
<h4 className="text-white font-medium">
|
||||
{request.sender.name || request.sender.fullName}
|
||||
</h4>
|
||||
<p className="text-white/60 text-sm">ИНН: {request.sender.inn}</p>
|
||||
{request.message && (
|
||||
<p className="text-white/80 text-sm mt-2 italic">"{request.message}"</p>
|
||||
)}
|
||||
<div className="flex items-center space-x-2 mt-2">
|
||||
<Clock className="h-3 w-3 text-white/40" />
|
||||
<span className="text-white/40 text-xs">{formatDate(request.createdAt)}</span>
|
||||
<div className="flex flex-col space-y-2 mb-3">
|
||||
<h4 className="text-white font-medium text-lg leading-tight">
|
||||
{request.sender.name || request.sender.fullName}
|
||||
</h4>
|
||||
<div className="flex items-center space-x-3">
|
||||
<Badge className={
|
||||
request.sender.type === 'FULFILLMENT' ? 'bg-blue-500/20 text-blue-300 border-blue-500/30' :
|
||||
request.sender.type === 'SELLER' ? 'bg-green-500/20 text-green-300 border-green-500/30' :
|
||||
request.sender.type === 'LOGIST' ? 'bg-orange-500/20 text-orange-300 border-orange-500/30' :
|
||||
request.sender.type === 'WHOLESALE' ? 'bg-purple-500/20 text-purple-300 border-purple-500/30' :
|
||||
'bg-gray-500/20 text-gray-300 border-gray-500/30'
|
||||
}>
|
||||
{request.sender.type === 'FULFILLMENT' ? 'Фулфилмент' :
|
||||
request.sender.type === 'SELLER' ? 'Селлер' :
|
||||
request.sender.type === 'LOGIST' ? 'Логистика' :
|
||||
request.sender.type === 'WHOLESALE' ? 'Оптовик' :
|
||||
request.sender.type}
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<p className="text-white/60 text-sm">ИНН: {request.sender.inn}</p>
|
||||
{request.sender.address && (
|
||||
<div className="flex items-center text-white/60 text-sm">
|
||||
<span className="truncate">{request.sender.address}</span>
|
||||
</div>
|
||||
)}
|
||||
{request.message && (
|
||||
<div className="p-2 bg-white/5 rounded border border-white/10">
|
||||
<p className="text-white/80 text-sm italic">"{request.message}"</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex items-center text-white/40 text-xs">
|
||||
<span>Заявка от {formatDate(request.createdAt)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex space-x-2 ml-4">
|
||||
<div className="flex space-x-2">
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={() => handleAcceptRequest(request.id)}
|
||||
className="bg-green-500/20 hover:bg-green-500/30 text-green-300 border-green-500/30 cursor-pointer"
|
||||
className="bg-green-500/20 hover:bg-green-500/30 text-green-300 border-green-500/30 cursor-pointer flex-1"
|
||||
>
|
||||
<CheckCircle className="h-4 w-4" />
|
||||
Принять
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handleRejectRequest(request.id)}
|
||||
className="bg-red-500/20 hover:bg-red-500/30 text-red-300 border-red-500/30 cursor-pointer"
|
||||
className="bg-red-500/20 hover:bg-red-500/30 text-red-300 border-red-500/30 cursor-pointer flex-1"
|
||||
>
|
||||
<XCircle className="h-4 w-4" />
|
||||
Отклонить
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
@ -269,36 +303,56 @@ export function MarketCounterparties() {
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{outgoingRequests.map((request: CounterpartyRequest) => (
|
||||
<Card key={request.id} className="glass-card p-4">
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex items-start space-x-3 flex-1">
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="w-10 h-10 rounded-full bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center text-white font-semibold">
|
||||
{(request.receiver.name || request.receiver.fullName || 'O').charAt(0).toUpperCase()}
|
||||
</div>
|
||||
</div>
|
||||
<div key={request.id} className="glass-card p-4 w-full">
|
||||
<div className="flex flex-col space-y-4">
|
||||
<div className="flex items-start space-x-3">
|
||||
<OrganizationAvatar organization={request.receiver} size="md" />
|
||||
<div className="flex-1 min-w-0">
|
||||
<h4 className="text-white font-medium">
|
||||
{request.receiver.name || request.receiver.fullName}
|
||||
</h4>
|
||||
<p className="text-white/60 text-sm">ИНН: {request.receiver.inn}</p>
|
||||
{request.message && (
|
||||
<p className="text-white/80 text-sm mt-2 italic">"{request.message}"</p>
|
||||
)}
|
||||
<div className="flex items-center space-x-4 mt-2">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Clock className="h-3 w-3 text-white/40" />
|
||||
<span className="text-white/40 text-xs">{formatDate(request.createdAt)}</span>
|
||||
<div className="flex flex-col space-y-2 mb-3">
|
||||
<h4 className="text-white font-medium text-lg leading-tight">
|
||||
{request.receiver.name || request.receiver.fullName}
|
||||
</h4>
|
||||
<div className="flex items-center space-x-3">
|
||||
<Badge className={
|
||||
request.receiver.type === 'FULFILLMENT' ? 'bg-blue-500/20 text-blue-300 border-blue-500/30' :
|
||||
request.receiver.type === 'SELLER' ? 'bg-green-500/20 text-green-300 border-green-500/30' :
|
||||
request.receiver.type === 'LOGIST' ? 'bg-orange-500/20 text-orange-300 border-orange-500/30' :
|
||||
request.receiver.type === 'WHOLESALE' ? 'bg-purple-500/20 text-purple-300 border-purple-500/30' :
|
||||
'bg-gray-500/20 text-gray-300 border-gray-500/30'
|
||||
}>
|
||||
{request.receiver.type === 'FULFILLMENT' ? 'Фулфилмент' :
|
||||
request.receiver.type === 'SELLER' ? 'Селлер' :
|
||||
request.receiver.type === 'LOGIST' ? 'Логистика' :
|
||||
request.receiver.type === 'WHOLESALE' ? 'Оптовик' :
|
||||
request.receiver.type}
|
||||
</Badge>
|
||||
<Badge className={
|
||||
request.status === 'PENDING' ? 'bg-yellow-500/20 text-yellow-300 border-yellow-500/30' :
|
||||
request.status === 'REJECTED' ? 'bg-red-500/20 text-red-300 border-red-500/30' :
|
||||
'bg-gray-500/20 text-gray-300 border-gray-500/30'
|
||||
}>
|
||||
{request.status === 'PENDING' ? 'Ожидает ответа' : request.status === 'REJECTED' ? 'Отклонено' : request.status}
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<p className="text-white/60 text-sm">ИНН: {request.receiver.inn}</p>
|
||||
{request.receiver.address && (
|
||||
<div className="flex items-center text-white/60 text-sm">
|
||||
<span className="truncate">{request.receiver.address}</span>
|
||||
</div>
|
||||
)}
|
||||
{request.message && (
|
||||
<div className="p-2 bg-white/5 rounded border border-white/10">
|
||||
<p className="text-white/80 text-sm italic">"{request.message}"</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex items-center text-white/40 text-xs">
|
||||
<span>Отправлено {formatDate(request.createdAt)}</span>
|
||||
</div>
|
||||
<Badge className={
|
||||
request.status === 'PENDING' ? 'bg-yellow-500/20 text-yellow-300 border-yellow-500/30' :
|
||||
request.status === 'REJECTED' ? 'bg-red-500/20 text-red-300 border-red-500/30' :
|
||||
'bg-gray-500/20 text-gray-300 border-gray-500/30'
|
||||
}>
|
||||
{request.status === 'PENDING' ? 'Ожидает' : request.status === 'REJECTED' ? 'Отклонено' : request.status}
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -308,13 +362,13 @@ export function MarketCounterparties() {
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handleCancelRequest(request.id)}
|
||||
className="bg-red-500/20 hover:bg-red-500/30 text-red-300 border-red-500/30 cursor-pointer ml-4"
|
||||
className="bg-red-500/20 hover:bg-red-500/30 text-red-300 border-red-500/30 cursor-pointer w-full"
|
||||
>
|
||||
<XCircle className="h-4 w-4" />
|
||||
Отменить заявку
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
@ -6,7 +6,7 @@ import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Search, Package } from 'lucide-react'
|
||||
import { OrganizationCard } from './organization-card'
|
||||
import { SEARCH_ORGANIZATIONS } from '@/graphql/queries'
|
||||
import { SEARCH_ORGANIZATIONS, GET_INCOMING_REQUESTS, GET_OUTGOING_REQUESTS } from '@/graphql/queries'
|
||||
import { SEND_COUNTERPARTY_REQUEST } from '@/graphql/mutations'
|
||||
|
||||
interface Organization {
|
||||
@ -21,6 +21,9 @@ interface Organization {
|
||||
createdAt: string
|
||||
users?: Array<{ id: string, avatar?: string }>
|
||||
isCounterparty?: boolean
|
||||
isCurrentUser?: boolean
|
||||
hasOutgoingRequest?: boolean
|
||||
hasIncomingRequest?: boolean
|
||||
}
|
||||
|
||||
export function MarketFulfillment() {
|
||||
@ -31,9 +34,15 @@ export function MarketFulfillment() {
|
||||
})
|
||||
|
||||
const [sendRequest, { loading: sendingRequest }] = useMutation(SEND_COUNTERPARTY_REQUEST, {
|
||||
onCompleted: () => {
|
||||
refetch()
|
||||
}
|
||||
refetchQueries: [
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'SELLER' } },
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'FULFILLMENT' } },
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'LOGIST' } },
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'WHOLESALE' } },
|
||||
{ query: GET_OUTGOING_REQUESTS },
|
||||
{ query: GET_INCOMING_REQUESTS }
|
||||
],
|
||||
awaitRefetchQueries: true
|
||||
})
|
||||
|
||||
const handleSearch = () => {
|
||||
@ -44,7 +53,7 @@ export function MarketFulfillment() {
|
||||
try {
|
||||
await sendRequest({
|
||||
variables: {
|
||||
receiverId: organizationId,
|
||||
organizationId: organizationId,
|
||||
message: message || 'Заявка на добавление в контрагенты'
|
||||
}
|
||||
})
|
||||
|
@ -6,7 +6,7 @@ import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Search, Truck } from 'lucide-react'
|
||||
import { OrganizationCard } from './organization-card'
|
||||
import { SEARCH_ORGANIZATIONS } from '@/graphql/queries'
|
||||
import { SEARCH_ORGANIZATIONS, GET_INCOMING_REQUESTS, GET_OUTGOING_REQUESTS } from '@/graphql/queries'
|
||||
import { SEND_COUNTERPARTY_REQUEST } from '@/graphql/mutations'
|
||||
|
||||
interface Organization {
|
||||
@ -21,6 +21,9 @@ interface Organization {
|
||||
createdAt: string
|
||||
users?: Array<{ id: string, avatar?: string }>
|
||||
isCounterparty?: boolean
|
||||
isCurrentUser?: boolean
|
||||
hasOutgoingRequest?: boolean
|
||||
hasIncomingRequest?: boolean
|
||||
}
|
||||
|
||||
export function MarketLogistics() {
|
||||
@ -31,9 +34,15 @@ export function MarketLogistics() {
|
||||
})
|
||||
|
||||
const [sendRequest, { loading: sendingRequest }] = useMutation(SEND_COUNTERPARTY_REQUEST, {
|
||||
onCompleted: () => {
|
||||
refetch()
|
||||
}
|
||||
refetchQueries: [
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'SELLER' } },
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'FULFILLMENT' } },
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'LOGIST' } },
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'WHOLESALE' } },
|
||||
{ query: GET_OUTGOING_REQUESTS },
|
||||
{ query: GET_INCOMING_REQUESTS }
|
||||
],
|
||||
awaitRefetchQueries: true
|
||||
})
|
||||
|
||||
const handleSearch = () => {
|
||||
@ -44,7 +53,7 @@ export function MarketLogistics() {
|
||||
try {
|
||||
await sendRequest({
|
||||
variables: {
|
||||
receiverId: organizationId,
|
||||
organizationId: organizationId,
|
||||
message: message || 'Заявка на добавление в контрагенты'
|
||||
}
|
||||
})
|
||||
|
@ -6,7 +6,7 @@ import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Search, ShoppingCart } from 'lucide-react'
|
||||
import { OrganizationCard } from './organization-card'
|
||||
import { SEARCH_ORGANIZATIONS } from '@/graphql/queries'
|
||||
import { SEARCH_ORGANIZATIONS, GET_INCOMING_REQUESTS, GET_OUTGOING_REQUESTS } from '@/graphql/queries'
|
||||
import { SEND_COUNTERPARTY_REQUEST } from '@/graphql/mutations'
|
||||
|
||||
interface Organization {
|
||||
@ -21,6 +21,9 @@ interface Organization {
|
||||
createdAt: string
|
||||
users?: Array<{ id: string, avatar?: string }>
|
||||
isCounterparty?: boolean
|
||||
isCurrentUser?: boolean
|
||||
hasOutgoingRequest?: boolean
|
||||
hasIncomingRequest?: boolean
|
||||
}
|
||||
|
||||
export function MarketSellers() {
|
||||
@ -31,9 +34,15 @@ export function MarketSellers() {
|
||||
})
|
||||
|
||||
const [sendRequest, { loading: sendingRequest }] = useMutation(SEND_COUNTERPARTY_REQUEST, {
|
||||
onCompleted: () => {
|
||||
refetch()
|
||||
}
|
||||
refetchQueries: [
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'SELLER' } },
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'FULFILLMENT' } },
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'LOGIST' } },
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'WHOLESALE' } },
|
||||
{ query: GET_OUTGOING_REQUESTS },
|
||||
{ query: GET_INCOMING_REQUESTS }
|
||||
],
|
||||
awaitRefetchQueries: true
|
||||
})
|
||||
|
||||
const handleSearch = () => {
|
||||
@ -44,7 +53,7 @@ export function MarketSellers() {
|
||||
try {
|
||||
await sendRequest({
|
||||
variables: {
|
||||
receiverId: organizationId,
|
||||
organizationId: organizationId,
|
||||
message: message || 'Заявка на добавление в контрагенты'
|
||||
}
|
||||
})
|
||||
|
@ -6,7 +6,7 @@ import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Search, Boxes } from 'lucide-react'
|
||||
import { OrganizationCard } from './organization-card'
|
||||
import { SEARCH_ORGANIZATIONS } from '@/graphql/queries'
|
||||
import { SEARCH_ORGANIZATIONS, GET_INCOMING_REQUESTS, GET_OUTGOING_REQUESTS } from '@/graphql/queries'
|
||||
import { SEND_COUNTERPARTY_REQUEST } from '@/graphql/mutations'
|
||||
|
||||
interface Organization {
|
||||
@ -21,6 +21,9 @@ interface Organization {
|
||||
createdAt: string
|
||||
users?: Array<{ id: string, avatar?: string }>
|
||||
isCounterparty?: boolean
|
||||
isCurrentUser?: boolean
|
||||
hasOutgoingRequest?: boolean
|
||||
hasIncomingRequest?: boolean
|
||||
}
|
||||
|
||||
export function MarketWholesale() {
|
||||
@ -31,9 +34,15 @@ export function MarketWholesale() {
|
||||
})
|
||||
|
||||
const [sendRequest, { loading: sendingRequest }] = useMutation(SEND_COUNTERPARTY_REQUEST, {
|
||||
onCompleted: () => {
|
||||
refetch()
|
||||
}
|
||||
refetchQueries: [
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'SELLER' } },
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'FULFILLMENT' } },
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'LOGIST' } },
|
||||
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'WHOLESALE' } },
|
||||
{ query: GET_OUTGOING_REQUESTS },
|
||||
{ query: GET_INCOMING_REQUESTS }
|
||||
],
|
||||
awaitRefetchQueries: true
|
||||
})
|
||||
|
||||
const handleSearch = () => {
|
||||
@ -44,7 +53,7 @@ export function MarketWholesale() {
|
||||
try {
|
||||
await sendRequest({
|
||||
variables: {
|
||||
receiverId: organizationId,
|
||||
organizationId: organizationId,
|
||||
message: message || 'Заявка на добавление в контрагенты'
|
||||
}
|
||||
})
|
||||
|
@ -11,7 +11,8 @@ import {
|
||||
Calendar,
|
||||
Plus,
|
||||
Send,
|
||||
Trash2
|
||||
Trash2,
|
||||
User
|
||||
} from 'lucide-react'
|
||||
import { OrganizationAvatar } from './organization-avatar'
|
||||
import { useState } from 'react'
|
||||
@ -28,6 +29,9 @@ interface Organization {
|
||||
createdAt: string
|
||||
users?: Array<{ id: string, avatar?: string }>
|
||||
isCounterparty?: boolean
|
||||
isCurrentUser?: boolean
|
||||
hasOutgoingRequest?: boolean
|
||||
hasIncomingRequest?: boolean
|
||||
}
|
||||
|
||||
interface OrganizationCardProps {
|
||||
@ -144,7 +148,12 @@ export function OrganizationCard({
|
||||
<Badge className={getTypeColor(organization.type)}>
|
||||
{getTypeLabel(organization.type)}
|
||||
</Badge>
|
||||
{organization.isCounterparty && (
|
||||
{organization.isCurrentUser && (
|
||||
<Badge className="bg-blue-500/20 text-blue-300 border-blue-500/30">
|
||||
Это вы
|
||||
</Badge>
|
||||
)}
|
||||
{organization.isCounterparty && !organization.isCurrentUser && (
|
||||
<Badge className="bg-green-500/20 text-green-300 border-green-500/30">
|
||||
Уже добавлен
|
||||
</Badge>
|
||||
@ -190,16 +199,29 @@ export function OrganizationCard({
|
||||
<Trash2 className="h-4 w-4 mr-2" />
|
||||
Удалить из контрагентов
|
||||
</Button>
|
||||
) : organization.isCurrentUser ? (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
disabled
|
||||
className="bg-blue-500/10 text-blue-300 border-blue-500/30 w-full opacity-50"
|
||||
>
|
||||
<User className="h-4 w-4 mr-2" />
|
||||
Ваша организация
|
||||
</Button>
|
||||
) : (
|
||||
<Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
|
||||
<DialogTrigger asChild>
|
||||
<Button
|
||||
size="sm"
|
||||
disabled={organization.isCounterparty}
|
||||
className={`${getActionButtonColor(actionButtonColor, !!organization.isCounterparty)} w-full cursor-pointer`}
|
||||
disabled={organization.isCounterparty || organization.hasOutgoingRequest || organization.hasIncomingRequest}
|
||||
className={`${getActionButtonColor(actionButtonColor, !!organization.isCounterparty || !!organization.hasOutgoingRequest || !!organization.hasIncomingRequest)} w-full cursor-pointer`}
|
||||
>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
{organization.isCounterparty ? 'Уже добавлен' : actionButtonText}
|
||||
{organization.isCounterparty ? 'Уже добавлен' :
|
||||
organization.hasOutgoingRequest ? 'Заявка отправлена' :
|
||||
organization.hasIncomingRequest ? 'Уже подал заявку' :
|
||||
actionButtonText}
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
|
||||
|
Reference in New Issue
Block a user