Files
ember-market-frontend/components/dashboard/NewChatForm.tsx
2025-03-03 23:21:09 +00:00

251 lines
8.4 KiB
TypeScript

"use client"
import React, { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { ArrowLeft, Send, RefreshCw } from "lucide-react";
import axios from "axios";
import { toast } from "sonner";
import { getCookie } from "@/lib/client-utils";
export default function NewChatForm() {
const router = useRouter();
const [buyerId, setBuyerId] = useState("");
const [initialMessage, setInitialMessage] = useState("");
const [loading, setLoading] = useState(false);
const [vendorStores, setVendorStores] = useState<{ _id: string, name: string }[]>([]);
const [selectedStore, setSelectedStore] = useState<string>("");
// Fetch vendor stores
useEffect(() => {
const fetchVendorStores = async () => {
try {
const authToken = getCookie("Authorization");
if (!authToken) {
toast.error("You must be logged in to start a chat");
router.push("/auth/login");
return;
}
const authAxios = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
headers: {
Authorization: `Bearer ${authToken}`
}
});
// Get vendor profile first
const vendorResponse = await authAxios.get('/auth/me');
console.log("Vendor auth response:", vendorResponse.data);
// Extract vendor ID properly
const vendorId = vendorResponse.data.vendor?._id;
if (!vendorId) {
console.error("Vendor ID not found in profile response:", vendorResponse.data);
toast.error("Could not retrieve vendor information");
return;
}
// Fetch store
const storeResponse = await authAxios.get(`/storefront`);
console.log("Store response:", storeResponse.data);
// Handle both array and single object responses
if (Array.isArray(storeResponse.data)) {
// If it's an array, use it as is
setVendorStores(storeResponse.data);
if (storeResponse.data.length > 0) {
setSelectedStore(storeResponse.data[0]._id);
}
} else if (storeResponse.data && typeof storeResponse.data === 'object' && storeResponse.data._id) {
// If it's a single store object, convert it to an array with one element
const singleStore = [storeResponse.data];
setVendorStores(singleStore);
setSelectedStore(storeResponse.data._id);
} else {
console.error("Expected store data but received:", storeResponse.data);
setVendorStores([]);
toast.error("Failed to load store data in expected format");
}
} catch (error) {
console.error("Error fetching store:", error);
toast.error("Failed to load store");
setVendorStores([]);
}
};
fetchVendorStores();
}, []);
const handleBackClick = () => {
router.push("/dashboard/chats");
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!buyerId || !selectedStore) {
toast.error("Please fill all required fields");
return;
}
setLoading(true);
try {
// Get auth token from cookies
const authToken = getCookie("Authorization");
if (!authToken) {
toast.error("You need to be logged in");
router.push("/auth/login");
return;
}
// Set up axios with the auth token
const authAxios = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
headers: {
Authorization: `Bearer ${authToken}`
}
});
const response = await authAxios.post("/api/chats/create", {
buyerId,
storeId: selectedStore,
initialMessage
});
if (response.data.chatId) {
toast.success("Chat created successfully!");
router.push(`/dashboard/chats/${response.data.chatId}`);
} else if (response.data.error === "Chat already exists") {
toast.info("Chat already exists, redirecting...");
router.push(`/dashboard/chats/${response.data.chatId}`);
}
} catch (error: any) {
console.error("Error creating chat:", error);
if (error.response?.status === 409) {
// Chat already exists
toast.info("Chat already exists, redirecting...");
router.push(`/dashboard/chats/${error.response.data.chatId}`);
} else {
toast.error("Failed to create chat");
}
} finally {
setLoading(false);
}
};
return (
<Card className="w-full">
<CardHeader>
<CardTitle className="flex items-center space-x-2">
<Button variant="ghost" size="icon" onClick={handleBackClick}>
<ArrowLeft className="h-5 w-5" />
</Button>
<span>Start a New Conversation</span>
</CardTitle>
<CardDescription>
Start a new conversation with a customer by their Telegram ID
</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-6">
<div className="space-y-2">
<Label htmlFor="buyerId">Customer Telegram ID</Label>
<Input
id="buyerId"
value={buyerId}
onChange={(e) => setBuyerId(e.target.value)}
placeholder="e.g. 123456789"
required
/>
<p className="text-sm text-muted-foreground">
This is the customer's Telegram ID. You can ask them to use the /myid command in your Telegram bot.
</p>
</div>
<div className="space-y-2">
<Label htmlFor="store">Store</Label>
{vendorStores.length === 0 ? (
<div>
<p className="text-sm text-muted-foreground p-2 border rounded-md">
No store available. Please create a store first.
</p>
</div>
) : vendorStores.length === 1 ? (
<div className="p-2 border rounded-md bg-muted/20">
<p className="text-sm font-medium">
{vendorStores[0].name}
</p>
<input
type="hidden"
value={vendorStores[0]._id}
name="storeId"
/>
</div>
) : (
<select
id="store"
value={selectedStore}
onChange={(e) => setSelectedStore(e.target.value)}
className="w-full rounded-md border border-input bg-background px-3 py-2"
required
>
<option value="" disabled>Select a store</option>
{vendorStores.map((store) => (
<option key={store._id} value={store._id}>
{store.name}
</option>
))}
</select>
)}
</div>
<div className="space-y-2">
<Label htmlFor="initialMessage">Initial Message (Optional)</Label>
<Textarea
id="initialMessage"
value={initialMessage}
onChange={(e) => setInitialMessage(e.target.value)}
placeholder="Hello! How can I help you today?"
rows={4}
/>
</div>
<div className="flex justify-end space-x-2">
<Button
type="button"
variant="outline"
onClick={handleBackClick}
disabled={loading}
>
Cancel
</Button>
<Button type="submit" disabled={loading || !buyerId || !selectedStore}>
{loading ? (
<>
<RefreshCw className="mr-2 h-4 w-4 animate-spin" />
Creating...
</>
) : (
<>
<Send className="mr-2 h-4 w-4" />
Start Conversation
</>
)}
</Button>
</div>
</form>
</CardContent>
</Card>
);
}