performance improvments
This commit is contained in:
1 parent
912981e3f3
commit
02c9681aca
13 files changed
+805
-474
No files matched your search
@@ -1,86 +1,40 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { useUser } from "@clerk/nextjs";
|
||||
import log from "@/lib/logger";
|
||||
import { toast } from "@/lib/toast";
|
||||
|
||||
interface User {
|
||||
id: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
interface Recommendation {
|
||||
id: string;
|
||||
userId: string;
|
||||
content: string;
|
||||
recommendationText: string;
|
||||
activityPlan: string;
|
||||
dietPlan: string;
|
||||
status: string;
|
||||
createdAt: Date;
|
||||
}
|
||||
import {
|
||||
useUsers,
|
||||
useRecommendations,
|
||||
useGenerateRecommendations,
|
||||
useApproveRecommendation,
|
||||
useUpdateRecommendation,
|
||||
type Recommendation,
|
||||
} from "@/hooks/use-api";
|
||||
|
||||
export default function RecommendationsPage() {
|
||||
const { user } = useUser();
|
||||
const [users, setUsers] = useState<User[]>([]);
|
||||
const [pendingRecommendations, setPendingRecommendations] = useState<
|
||||
Recommendation[]
|
||||
>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [generating, setGenerating] = useState<string | null>(null);
|
||||
const [useExternalModel, setUseExternalModel] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
const { data: users = [], isLoading: usersLoading } = useUsers();
|
||||
const { data: allRecommendations = [], isLoading: recsLoading } =
|
||||
useRecommendations();
|
||||
const pendingRecommendations = allRecommendations.filter(
|
||||
(r) => r.status === "pending",
|
||||
);
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
// Fetch users - API returns { success: true, data: { users: [...] }, meta: {...} }
|
||||
const usersRes = await fetch("/api/users");
|
||||
const usersResult = await usersRes.json();
|
||||
const usersArray = usersResult.data?.users || usersResult.users || [];
|
||||
setUsers(usersArray);
|
||||
|
||||
// Fetch pending recommendations - API returns { success: true, data: { recommendations: [...] }, meta: {...} }
|
||||
const recsRes = await fetch("/api/recommendations");
|
||||
const recsResult = await recsRes.json();
|
||||
const allRecs =
|
||||
recsResult.data?.recommendations || recsResult.recommendations || [];
|
||||
setPendingRecommendations(
|
||||
allRecs.filter((r: Recommendation) => r.status === "pending"),
|
||||
);
|
||||
} catch (error) {
|
||||
log.error("Failed to fetch data", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
const generateRec = useGenerateRecommendations();
|
||||
const approveRec = useApproveRecommendation();
|
||||
const updateRec = useUpdateRecommendation();
|
||||
|
||||
const handleGenerate = async (userId: string) => {
|
||||
setGenerating(userId);
|
||||
try {
|
||||
const res = await fetch("/api/recommendations/generate", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ userId, useExternalModel }),
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const error = await res.json();
|
||||
toast.error(`Error: ${error.error}`);
|
||||
} else {
|
||||
toast.success("Recommendation generated successfully!");
|
||||
fetchData(); // Refresh data
|
||||
}
|
||||
await generateRec.mutateAsync(userId);
|
||||
toast.success("Recommendation generated successfully!");
|
||||
} catch (error) {
|
||||
log.error("Failed to generate recommendation", error);
|
||||
toast.error("Failed to generate recommendation.");
|
||||
} finally {
|
||||
setGenerating(null);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -89,25 +43,11 @@ export default function RecommendationsPage() {
|
||||
status: "approved" | "rejected",
|
||||
) => {
|
||||
try {
|
||||
const res = await fetch("/api/recommendations/approve", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
recommendationId,
|
||||
status,
|
||||
approvedBy: user?.id || "admin",
|
||||
}),
|
||||
await approveRec.mutateAsync({
|
||||
recommendationId,
|
||||
approved: status === "approved",
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const errorData = await res.json();
|
||||
toast.error(
|
||||
`Failed to update status: ${errorData.error || "Unknown error"}`,
|
||||
);
|
||||
} else {
|
||||
toast.success("Recommendation status updated");
|
||||
fetchData(); // Refresh data
|
||||
}
|
||||
toast.success("Recommendation status updated");
|
||||
} catch (error) {
|
||||
log.error("Failed to approve recommendation", error);
|
||||
toast.error("Error processing request");
|
||||
@@ -124,38 +64,24 @@ export default function RecommendationsPage() {
|
||||
newActivityPlan === null ||
|
||||
newDietPlan === null
|
||||
) {
|
||||
// User cancelled one of the prompts
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await fetch("/api/recommendations", {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
id: rec.id,
|
||||
content: newContent,
|
||||
activityPlan: newActivityPlan,
|
||||
dietPlan: newDietPlan,
|
||||
}),
|
||||
await updateRec.mutateAsync({
|
||||
id: rec.id,
|
||||
content: newContent,
|
||||
activityPlan: newActivityPlan,
|
||||
dietPlan: newDietPlan,
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const errorData = await res.json();
|
||||
toast.error(
|
||||
`Failed to update recommendation: ${errorData.error || "Unknown error"}`,
|
||||
);
|
||||
} else {
|
||||
toast.success("Recommendation updated successfully!");
|
||||
fetchData(); // Refresh data
|
||||
}
|
||||
toast.success("Recommendation updated successfully!");
|
||||
} catch (error) {
|
||||
log.error("Failed to update recommendation", error);
|
||||
toast.error("Failed to update recommendation.");
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
if (usersLoading || recsLoading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center h-screen">
|
||||
<div className="text-xl">Loading...</div>
|
||||
@@ -215,10 +141,10 @@ export default function RecommendationsPage() {
|
||||
</div>
|
||||
<button
|
||||
onClick={() => handleGenerate(user.id)}
|
||||
disabled={generating === user.id}
|
||||
disabled={generateRec.isPending}
|
||||
className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 disabled:opacity-50"
|
||||
>
|
||||
{generating === user.id ? "Generating..." : "Generate"}
|
||||
{generateRec.isPending ? "Generating..." : "Generate"}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
|
||||
Reference in new issue
Block a user