{result.tags.map((tag) => (
-
+
#{tag}
))}
@@ -89,6 +103,13 @@ const AiSearch = () => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
const [selectedResult, setSelectedResult] = useState(null);
+ const [hasSearched, setHasSearched] = useState(false);
+ const [filters, setFilters] = useState({
+ resultType: "all",
+ dateFrom: "",
+ dateTo: "",
+ sortBy: "relevance",
+ });
const handleSearch = async () => {
if (!query.trim()) {
@@ -99,12 +120,13 @@ const AiSearch = () => {
setLoading(true);
setError("");
setResults([]);
+ setHasSearched(true);
try {
const res = await fetch(`${backendUrl}/api/ai-search`, {
method: "POST",
headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ query }),
+ body: JSON.stringify({ query, filters }),
});
if (!res.ok) {
@@ -113,18 +135,32 @@ const AiSearch = () => {
}
const data = await res.json();
- // console.log("🔍 Search results from backend:", data);
- setResults(data.results || []);
- if (data.results?.length === 0) {
- setError("No matching meetings found. Try a different query.");
+ let sortedResults = data.results || [];
+
+ if (filters.sortBy === "date-desc") {
+ sortedResults.sort(
+ (a, b) => new Date(b.createdAt) - new Date(a.createdAt),
+ );
+ } else if (filters.sortBy === "date-asc") {
+ sortedResults.sort(
+ (a, b) => new Date(a.createdAt) - new Date(b.createdAt),
+ );
+ }
+
+ setResults(sortedResults);
+ if (sortedResults.length === 0) {
+ setError(
+ "No matching results found. Try a different query or adjust your filters.",
+ );
}
} catch (err) {
console.error("❌ Search error:", err);
-
- // Network error handling
+
if (err.message === "Failed to fetch") {
- setError("Unable to connect to the server. Please check your internet connection and try again.");
+ setError(
+ "Unable to connect to the server. Please check your internet connection and try again.",
+ );
} else if (err.message.includes("500")) {
setError("Server error. Please try again later.");
} else if (err.message.includes("404")) {
@@ -137,6 +173,33 @@ const AiSearch = () => {
}
};
+ const handleClear = () => {
+ setQuery("");
+ setResults([]);
+ setError("");
+ setHasSearched(false);
+ };
+
+ const handleViewDetails = (result) => {
+ setSelectedResult(result);
+ };
+
+ const handleOpenMeeting = (result) => {
+ window.open(`/meetings/${result.meetingId}`, "_blank");
+ };
+
+ const handleCopySummary = async (result) => {
+ const textToCopy = result.summary || result.transcript || "";
+ if (textToCopy) {
+ try {
+ await navigator.clipboard.writeText(textToCopy);
+ alert("Summary copied to clipboard!");
+ } catch (err) {
+ console.error("Failed to copy:", err);
+ }
+ }
+ };
+
return (
@@ -148,120 +211,59 @@ const AiSearch = () => {
Search across your meeting transcripts, policies, and{" "}
- AI summaries using natural language — powered by your intelligent semantic engine.
+ AI summaries using natural language — powered by your
+ intelligent semantic engine.