146 lines
5.0 KiB
TypeScript
146 lines
5.0 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
import { useQuery, useMutation } from "@apollo/client";
|
||
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,
|
||
GET_INCOMING_REQUESTS,
|
||
GET_OUTGOING_REQUESTS,
|
||
} from "@/graphql/queries";
|
||
import { SEND_COUNTERPARTY_REQUEST } from "@/graphql/mutations";
|
||
|
||
interface Organization {
|
||
id: string;
|
||
inn: string;
|
||
name?: string;
|
||
fullName?: string;
|
||
type: "FULFILLMENT" | "SELLER" | "LOGIST" | "WHOLESALE";
|
||
address?: string;
|
||
phones?: Array<{ value: string }>;
|
||
emails?: Array<{ value: string }>;
|
||
createdAt: string;
|
||
users?: Array<{ id: string; avatar?: string }>;
|
||
isCounterparty?: boolean;
|
||
isCurrentUser?: boolean;
|
||
hasOutgoingRequest?: boolean;
|
||
hasIncomingRequest?: boolean;
|
||
}
|
||
|
||
export function MarketSuppliers() {
|
||
const [searchTerm, setSearchTerm] = useState("");
|
||
|
||
const { data, loading, refetch } = useQuery(SEARCH_ORGANIZATIONS, {
|
||
variables: { type: "WHOLESALE", search: searchTerm || null },
|
||
});
|
||
|
||
const [sendRequest, { loading: sendingRequest }] = useMutation(
|
||
SEND_COUNTERPARTY_REQUEST,
|
||
{
|
||
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 = () => {
|
||
refetch({ type: "WHOLESALE", search: searchTerm || null });
|
||
};
|
||
|
||
const handleSendRequest = async (organizationId: string, message: string) => {
|
||
try {
|
||
await sendRequest({
|
||
variables: {
|
||
organizationId: organizationId,
|
||
message: message || "Заявка на добавление в контрагенты",
|
||
},
|
||
});
|
||
} catch (error) {
|
||
console.error("Ошибка отправки заявки:", error);
|
||
}
|
||
};
|
||
|
||
const organizations = data?.searchOrganizations || [];
|
||
|
||
return (
|
||
<div className="h-full flex flex-col space-y-4 overflow-hidden">
|
||
{/* Поиск */}
|
||
<div className="flex space-x-4 flex-shrink-0">
|
||
<div className="relative flex-1">
|
||
<Search className="absolute left-3 top-3 h-4 w-4 text-white/40" />
|
||
<Input
|
||
placeholder="Поиск поставщиков по названию или ИНН..."
|
||
value={searchTerm}
|
||
onChange={(e) => setSearchTerm(e.target.value)}
|
||
onKeyDown={(e) => e.key === "Enter" && handleSearch()}
|
||
className="pl-10 glass-input text-white placeholder:text-white/40 h-10"
|
||
/>
|
||
</div>
|
||
<Button
|
||
onClick={handleSearch}
|
||
className="bg-purple-500/20 hover:bg-purple-500/30 text-purple-300 border-purple-500/30 cursor-pointer"
|
||
>
|
||
<Search className="h-4 w-4 mr-2" />
|
||
Найти
|
||
</Button>
|
||
</div>
|
||
|
||
{/* Заголовок с иконкой */}
|
||
<div className="flex items-center space-x-3 flex-shrink-0 mb-4">
|
||
<Boxes className="h-6 w-6 text-purple-400" />
|
||
<div>
|
||
<h3 className="text-lg font-semibold text-white">Поставщики</h3>
|
||
<p className="text-white/60 text-sm">
|
||
Найдите и добавьте поставщиков в контрагенты
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Результаты поиска */}
|
||
<div className="flex-1 overflow-auto">
|
||
{loading ? (
|
||
<div className="flex items-center justify-center p-8">
|
||
<div className="text-white/60">Поиск...</div>
|
||
</div>
|
||
) : organizations.length === 0 ? (
|
||
<div className="glass-card p-8">
|
||
<div className="text-center">
|
||
<Boxes className="h-12 w-12 text-white/20 mx-auto mb-4" />
|
||
<p className="text-white/60">
|
||
{searchTerm
|
||
? "Поставщики не найдены"
|
||
: "Введите запрос для поиска поставщиков"}
|
||
</p>
|
||
<p className="text-white/40 text-sm mt-2">
|
||
Попробуйте изменить условия поиска
|
||
</p>
|
||
</div>
|
||
</div>
|
||
) : (
|
||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||
{organizations.map((organization: Organization) => (
|
||
<OrganizationCard
|
||
key={organization.id}
|
||
organization={organization}
|
||
onSendRequest={handleSendRequest}
|
||
actionButtonText="Добавить"
|
||
actionButtonColor="red"
|
||
requestSending={sendingRequest}
|
||
/>
|
||
))}
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|