diff --git a/src/app/(dashboard)/campaigns/[id]/page.tsx b/src/app/(dashboard)/campaigns/[id]/page.tsx index 0cea105..0ca20a3 100644 --- a/src/app/(dashboard)/campaigns/[id]/page.tsx +++ b/src/app/(dashboard)/campaigns/[id]/page.tsx @@ -12,6 +12,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { ArrowLeft, Plus, Trash2, Send, Play, Pause, Users, Mail, Clock, } from "lucide-react" +import { toast } from "sonner" export default function CampaignDetailPage({ params }: { params: Promise<{ id: string }> }) { const { id } = use(params) @@ -29,7 +30,7 @@ export default function CampaignDetailPage({ params }: { params: Promise<{ id: s try { const res = await fetch(`/api/campaigns/${id}`) if (res.ok) setCampaign(await res.json()) - } catch { /* ignore */ } + } catch (e) { console.error("Failed to load campaign", e); toast.error("Failed to load campaign") } setLoading(false) } @@ -53,7 +54,7 @@ export default function CampaignDetailPage({ params }: { params: Promise<{ id: s }) setNewStep({ subject: "", bodyText: "", delayDays: 3 }) fetchCampaign() - } catch { /* ignore */ } + } catch (e) { console.error("Failed to add step", e); toast.error("Failed to add step") } setAddingStep(false) } @@ -68,7 +69,7 @@ export default function CampaignDetailPage({ params }: { params: Promise<{ id: s setLeadSearch("") setSearchResults([]) fetchCampaign() - } catch { /* ignore */ } + } catch (e) { console.error("Failed to subscribe leads", e); toast.error("Failed to subscribe leads") } setSubscribing(false) } @@ -78,7 +79,7 @@ export default function CampaignDetailPage({ params }: { params: Promise<{ id: s const res = await fetch(`/api/campaigns/${id}/send`, { method: "POST" }) const data = await res.json() if (data.sent > 0) fetchCampaign() - } catch { /* ignore */ } + } catch (e) { console.error("Failed to send campaign", e); toast.error("Failed to send campaign") } setSending(false) } diff --git a/src/app/(dashboard)/campaigns/new/page.tsx b/src/app/(dashboard)/campaigns/new/page.tsx index ebeb8fd..eef0aca 100644 --- a/src/app/(dashboard)/campaigns/new/page.tsx +++ b/src/app/(dashboard)/campaigns/new/page.tsx @@ -7,6 +7,7 @@ import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Card } from "@/components/ui/card" import { ArrowLeft } from "lucide-react" +import { toast } from "sonner" export default function NewCampaignPage() { const router = useRouter() @@ -25,7 +26,7 @@ export default function NewCampaignPage() { }) const data = await res.json() if (data.id) router.push(`/campaigns/${data.id}`) - } catch { /* ignore */ } + } catch (e) { console.error("Campaign create error:", e); toast.error("Failed to create campaign") } setSaving(false) } diff --git a/src/app/(dashboard)/campaigns/page.tsx b/src/app/(dashboard)/campaigns/page.tsx index db664ba..50eeedc 100644 --- a/src/app/(dashboard)/campaigns/page.tsx +++ b/src/app/(dashboard)/campaigns/page.tsx @@ -7,6 +7,7 @@ import { Button } from "@/components/ui/button" import { Card } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Plus, Mail, Users, Layers, Calendar } from "lucide-react" +import { toast } from "sonner" const statusColors: Record = { draft: "bg-zinc-100 text-zinc-700 border-zinc-300", @@ -24,7 +25,7 @@ export default function CampaignsPage() { fetch("/api/campaigns") .then(r => r.json()) .then(d => { if (Array.isArray(d)) setCampaigns(d); else setCampaigns([]) }) - .catch(() => setCampaigns([])) + .catch((e) => { console.error("Failed to load campaigns", e); toast.error("Failed to load campaigns"); setCampaigns([]) }) .finally(() => setLoading(false)) }, []) diff --git a/src/app/(dashboard)/leads/kanban/page.tsx b/src/app/(dashboard)/leads/kanban/page.tsx index 290ae05..27561b4 100644 --- a/src/app/(dashboard)/leads/kanban/page.tsx +++ b/src/app/(dashboard)/leads/kanban/page.tsx @@ -7,6 +7,7 @@ import { Button } from "@/components/ui/button" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { Card } from "@/components/ui/card" import { GripVertical, Plus, User, Building2, Mail, Phone, Hash } from "lucide-react" +import { toast } from "sonner" interface KanbanLead { id: string @@ -57,6 +58,7 @@ export default function KanbanPage() { const data = await res.json() setColumns(data) } catch (e) { + toast.error("Failed to load kanban data") console.error("Failed to load kanban", e) } finally { setLoading(false) @@ -98,6 +100,7 @@ export default function KanbanPage() { body: JSON.stringify({ status: toStatus }), }) } catch (e) { + toast.error("Failed to update lead status") console.error("Failed to update lead status", e) fetchKanban() } diff --git a/src/app/(dashboard)/leads/new/page.tsx b/src/app/(dashboard)/leads/new/page.tsx index b9abb62..41a9c3d 100644 --- a/src/app/(dashboard)/leads/new/page.tsx +++ b/src/app/(dashboard)/leads/new/page.tsx @@ -29,6 +29,7 @@ import { ArrowLeft } from "lucide-react" import { User } from "@/types" import { useNotifications } from "@/providers/notification-provider" import { LEAD_SOURCES, LEAD_STATUSES } from "@/lib/constants" +import { toast } from "sonner" const leadFormSchema = z.object({ companyName: z.string().min(1, "Company name is required"), @@ -53,7 +54,7 @@ export default function CreateLeadPage() { fetch("/api/users") .then((r) => r.json()) .then((data) => setUsers(data.users || [])) - .catch(() => {}) + .catch((e) => { console.error("Failed to load users", e); toast.error("Failed to load users") }) }, []) const form = useForm({ @@ -87,6 +88,7 @@ export default function CreateLeadPage() { addNotification("lead_created", "New Lead Created", `${values.companyName} — ${values.contactName}`, `/leads/${data.id}`) router.push("/leads") } catch (e) { + toast.error("Failed to create lead") console.error("Create lead error:", e) } finally { setSaving(false) diff --git a/src/app/(dashboard)/leads/page.tsx b/src/app/(dashboard)/leads/page.tsx index af0ac43..fb9a1f8 100644 --- a/src/app/(dashboard)/leads/page.tsx +++ b/src/app/(dashboard)/leads/page.tsx @@ -7,6 +7,7 @@ import { LeadsTable } from "@/components/leads/leads-table" import { LeadsTableToolbar } from "@/components/leads/leads-table-toolbar" import { Button } from "@/components/ui/button" import { Columns3 } from "lucide-react" +import { toast } from "sonner" import { Lead } from "@/types" export default function LeadsPage() { @@ -30,7 +31,7 @@ export default function LeadsPage() { setLeadsData(data) setLoading(false) }) - .catch(() => setLoading(false)) + .catch((e) => { console.error("Failed to load leads", e); toast.error("Failed to load leads"); setLoading(false) }) }, [search, statusFilter, periodFilter]) return ( diff --git a/src/app/(dashboard)/projects/[id]/page.tsx b/src/app/(dashboard)/projects/[id]/page.tsx index ecedb99..1b1e7aa 100644 --- a/src/app/(dashboard)/projects/[id]/page.tsx +++ b/src/app/(dashboard)/projects/[id]/page.tsx @@ -20,6 +20,7 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select" +import { toast } from "sonner" interface Milestone { id: string @@ -82,6 +83,7 @@ export default function ProjectDetailPage() { setMilestones(await mRes.json()) setStatuses(await sRes.json()) } catch (e) { + toast.error("Failed to load project") console.error("Failed to load project", e) } finally { setLoading(false) @@ -91,21 +93,31 @@ export default function ProjectDetailPage() { useEffect(() => { fetchProject() }, [fetchProject]) const updateProjectStatus = async (statusId: string) => { - await fetch(`/api/projects/${id}`, { - method: "PATCH", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ statusId }), - }) - fetchProject() + try { + await fetch(`/api/projects/${id}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ statusId }), + }) + fetchProject() + } catch (e) { + console.error("Failed to update project status", e) + toast.error("Failed to update project status") + } } const updateMilestoneStatus = async (milestoneId: string, status: string) => { - await fetch(`/api/milestones/${milestoneId}`, { - method: "PATCH", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ status }), - }) - fetchProject() + try { + await fetch(`/api/milestones/${milestoneId}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ status }), + }) + fetchProject() + } catch (e) { + console.error("Failed to update milestone status", e) + toast.error("Failed to update milestone status") + } } const addMilestone = async () => { @@ -119,6 +131,9 @@ export default function ProjectDetailPage() { }) setNewMilestoneName("") fetchProject() + } catch (e) { + console.error("Failed to add milestone", e) + toast.error("Failed to add milestone") } finally { setAddingMilestone(false) } @@ -140,6 +155,7 @@ export default function ProjectDetailPage() { setNewTaskInputs((prev) => ({ ...prev, [milestoneId]: "" })) fetchProject() } catch (e) { + toast.error("Failed to add task") console.error("Failed to add task", e) } } diff --git a/src/app/(dashboard)/projects/page.tsx b/src/app/(dashboard)/projects/page.tsx index 081eb73..c119fb4 100644 --- a/src/app/(dashboard)/projects/page.tsx +++ b/src/app/(dashboard)/projects/page.tsx @@ -22,6 +22,7 @@ import { DialogTitle, DialogTrigger, } from "@/components/ui/dialog" +import { toast } from "sonner" interface Project { id: string @@ -65,6 +66,7 @@ export default function ProjectsPage() { const data = res.ok ? await res.json() : [] setProjects(Array.isArray(data) ? data : []) } catch (e) { + toast.error("Failed to load projects") console.error("Failed to load projects", e) setProjects([]) } finally { @@ -75,7 +77,7 @@ export default function ProjectsPage() { useEffect(() => { fetchProjects() }, [search, statusFilter]) useEffect(() => { - fetch("/api/project-statuses").then(r => r.json()).then((d) => setStatuses(Array.isArray(d) ? d : [])).catch(() => {}) + fetch("/api/project-statuses").then(r => r.json()).then((d) => setStatuses(Array.isArray(d) ? d : [])).catch((e) => { console.error("Failed to load project statuses", e); toast.error("Failed to load project statuses") }) }, []) const formatDate = (d: string) => d ? new Date(d).toLocaleDateString() : "—" @@ -168,8 +170,8 @@ function NewProjectDialog({ statuses, onCreated }: { statuses: ProjectStatus[]; useEffect(() => { if (!open) return - fetch("/api/customers?limit=100").then(r => r.json()).then(d => setCustomers(Array.isArray(d) ? d : [])).catch(() => {}) - fetch("/api/users").then(r => r.json()).then(d => setUsers(d.users || [])).catch(() => {}) + fetch("/api/customers?limit=100").then(r => r.json()).then(d => setCustomers(Array.isArray(d) ? d : [])).catch((e) => { console.error("Failed to load customers", e); toast.error("Failed to load customers") }) + fetch("/api/users").then(r => r.json()).then(d => setUsers(d.users || [])).catch((e) => { console.error("Failed to load users", e); toast.error("Failed to load users") }) }, [open]) const handleSubmit = async () => { @@ -194,6 +196,9 @@ function NewProjectDialog({ statuses, onCreated }: { statuses: ProjectStatus[]; setName(""); setDescription(""); setCustomerId(""); setOwnerId(""); setStartDate(""); setTargetEndDate(""); setBudget("") onCreated() } + } catch (e) { + console.error("Failed to create project", e) + toast.error("Failed to create project") } finally { setSaving(false) } diff --git a/src/app/(dashboard)/proposals/[id]/page.tsx b/src/app/(dashboard)/proposals/[id]/page.tsx index 41c54cc..3a16354 100644 --- a/src/app/(dashboard)/proposals/[id]/page.tsx +++ b/src/app/(dashboard)/proposals/[id]/page.tsx @@ -15,6 +15,7 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select" +import { toast } from "sonner" export default function ProposalDetailPage() { const { id } = useParams<{ id: string }>() @@ -35,6 +36,7 @@ export default function ProposalDetailPage() { setProposal(await pRes.json()) setStatuses(await sRes.json()) } catch (e) { + toast.error("Failed to load proposal") console.error("Failed to load proposal", e) } finally { setLoading(false) @@ -44,12 +46,17 @@ export default function ProposalDetailPage() { useEffect(() => { fetchProposal() }, [fetchProposal]) const updateStatus = async (statusId: string) => { - await fetch(`/api/proposals/${id}`, { - method: "PATCH", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ statusId }), - }) - fetchProposal() + try { + await fetch(`/api/proposals/${id}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ statusId }), + }) + fetchProposal() + } catch (e) { + console.error("Failed to update proposal status", e) + toast.error("Failed to update proposal status") + } } const handleSign = async () => { @@ -62,6 +69,9 @@ export default function ProposalDetailPage() { body: JSON.stringify({ name: signName, email: signEmail }), }) if (res.ok) fetchProposal() + } catch (e) { + console.error("Failed to sign proposal", e) + toast.error("Failed to sign proposal") } finally { setSigning(false) } diff --git a/src/app/(dashboard)/proposals/new/page.tsx b/src/app/(dashboard)/proposals/new/page.tsx index 7f727c4..1155abe 100644 --- a/src/app/(dashboard)/proposals/new/page.tsx +++ b/src/app/(dashboard)/proposals/new/page.tsx @@ -14,6 +14,7 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select" +import { toast } from "sonner" interface LineItem { id: string @@ -39,8 +40,8 @@ export default function NewProposalPage() { const [saving, setSaving] = useState(false) useEffect(() => { - fetch("/api/leads?limit=100").then((r) => r.json()).then(setLeads).catch(() => {}) - fetch("/api/customers?limit=100").then((r) => r.json()).then(setCustomers).catch(() => {}) + fetch("/api/leads?limit=100").then((r) => r.json()).then(setLeads).catch((e) => { console.error("Failed to load leads", e); toast.error("Failed to load leads") }) + fetch("/api/customers?limit=100").then((r) => r.json()).then(setCustomers).catch((e) => { console.error("Failed to load customers", e); toast.error("Failed to load customers") }) }, []) const addItem = () => { @@ -107,6 +108,7 @@ export default function NewProposalPage() { router.push(`/proposals/${data.id}`) } catch (e) { + toast.error("Failed to create proposal") console.error("Failed to create proposal", e) } finally { setSaving(false) diff --git a/src/app/(dashboard)/proposals/page.tsx b/src/app/(dashboard)/proposals/page.tsx index edfa286..cb00b4a 100644 --- a/src/app/(dashboard)/proposals/page.tsx +++ b/src/app/(dashboard)/proposals/page.tsx @@ -15,6 +15,7 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select" +import { toast } from "sonner" export default function ProposalsPage() { const router = useRouter() @@ -31,12 +32,12 @@ export default function ProposalsPage() { fetch(`/api/proposals?${params}`) .then((r) => r.json()) .then(setProposals) - .catch(() => {}) + .catch((e) => { console.error("Failed to load proposals", e); toast.error("Failed to load proposals") }) .finally(() => setLoading(false)) }, [search, statusFilter]) useEffect(() => { - fetch("/api/proposal-statuses").then((r) => r.json()).then(setStatuses).catch(() => {}) + fetch("/api/proposal-statuses").then((r) => r.json()).then(setStatuses).catch((e) => { console.error("Failed to load proposal statuses", e); toast.error("Failed to load proposal statuses") }) }, []) const formatCurrency = (n: number) => n ? `R${Number(n).toLocaleString()}` : "R0" diff --git a/src/app/(dashboard)/resource-planning/page.tsx b/src/app/(dashboard)/resource-planning/page.tsx index 2751218..bb778c2 100644 --- a/src/app/(dashboard)/resource-planning/page.tsx +++ b/src/app/(dashboard)/resource-planning/page.tsx @@ -13,6 +13,7 @@ import { SelectValue, } from "@/components/ui/select" import { Users, Clock, Briefcase, AlertTriangle, TrendingUp } from "lucide-react" +import { toast } from "sonner" interface Member { id: string @@ -81,7 +82,7 @@ export default function ResourcePlanningPage() { fetch(`/api/resource-planning?period=${period}`) .then(r => r.json()) .then(d => { setMembers(d.members || []); setTotals(d.totals || null) }) - .catch(() => {}) + .catch((e) => { console.error("Failed to load resource data", e); toast.error("Failed to load resource data") }) .finally(() => setLoading(false)) }, [period]) diff --git a/src/app/(dashboard)/time-tracking/page.tsx b/src/app/(dashboard)/time-tracking/page.tsx index 25e9d35..1287057 100644 --- a/src/app/(dashboard)/time-tracking/page.tsx +++ b/src/app/(dashboard)/time-tracking/page.tsx @@ -7,6 +7,7 @@ import { Input } from "@/components/ui/input" import { Card } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Play, Square, Plus, Trash2, Clock, Briefcase, User, TrendingUp, DollarSign } from "lucide-react" +import { toast } from "sonner" interface TimeEntry { id: string @@ -59,6 +60,7 @@ export default function TimeTrackingPage() { setSummary(sData?.totals ? sData : null) setProjects(Array.isArray(pData) ? pData : []) } catch (e) { + toast.error("Failed to load time data") console.error("Failed to load time data", e) setEntries([]) setProjects([]) @@ -105,6 +107,7 @@ export default function TimeTrackingPage() { setTimerSeconds(0) fetchData() } catch (e) { + toast.error("Failed to save time entry") console.error("Failed to save time entry", e) } } @@ -135,14 +138,22 @@ export default function TimeTrackingPage() { setManualRate("") setShowManual(false) fetchData() + } catch (e) { + console.error("Failed to save time entry", e) + toast.error("Failed to save time entry") } finally { setSaving(false) } } const deleteEntry = async (id: string) => { - await fetch(`/api/time-entries?id=${id}`, { method: "DELETE" }) - fetchData() + try { + await fetch(`/api/time-entries?id=${id}`, { method: "DELETE" }) + fetchData() + } catch (e) { + console.error("Failed to delete time entry", e) + toast.error("Failed to delete time entry") + } } const formatDuration = (mins: number) => { diff --git a/src/app/api/auth/login/route.ts b/src/app/api/auth/login/route.ts index a3522e2..4e9debb 100644 --- a/src/app/api/auth/login/route.ts +++ b/src/app/api/auth/login/route.ts @@ -141,8 +141,9 @@ export async function POST(request: NextRequest) { return response } catch (error) { console.error("Login error:", error) + const message = error instanceof Error ? error.message : "Authentication service unavailable." return NextResponse.json( - { error: "Authentication service unavailable." }, + { error: message }, { status: 503 } ) } diff --git a/src/app/api/auth/logout/route.ts b/src/app/api/auth/logout/route.ts index 662f8c8..774a1a0 100644 --- a/src/app/api/auth/logout/route.ts +++ b/src/app/api/auth/logout/route.ts @@ -11,8 +11,9 @@ export async function POST() { }) } catch (error) { console.error("Logout error:", error) + const message = error instanceof Error ? error.message : "Logout failed." return new Response( - JSON.stringify({ error: "Logout failed." }), + JSON.stringify({ error: message }), { status: 500, headers: { "Content-Type": "application/json" } } ) } diff --git a/src/app/api/auth/me/route.ts b/src/app/api/auth/me/route.ts index a832e3c..87a63d3 100644 --- a/src/app/api/auth/me/route.ts +++ b/src/app/api/auth/me/route.ts @@ -10,8 +10,9 @@ export async function GET() { return NextResponse.json({ user }, { status: 200 }) } catch (error) { console.error("Auth me error:", error) + const message = error instanceof Error ? error.message : "Authentication service unavailable." return NextResponse.json( - { error: "Authentication service unavailable." }, + { error: message }, { status: 503 } ) } diff --git a/src/app/api/auth/recover/route.ts b/src/app/api/auth/recover/route.ts index b96711f..aeffe48 100644 --- a/src/app/api/auth/recover/route.ts +++ b/src/app/api/auth/recover/route.ts @@ -59,6 +59,7 @@ export async function POST(request: NextRequest) { }, { status: 200 }) } catch (error) { console.error("Password recovery error:", error) - return NextResponse.json({ error: "Recovery service unavailable." }, { status: 503 }) + const message = error instanceof Error ? error.message : "Recovery service unavailable." + return NextResponse.json({ error: message }, { status: 503 }) } } diff --git a/src/app/api/bug-reports/[id]/route.ts b/src/app/api/bug-reports/[id]/route.ts index b0e652f..69702c4 100644 --- a/src/app/api/bug-reports/[id]/route.ts +++ b/src/app/api/bug-reports/[id]/route.ts @@ -64,6 +64,7 @@ export async function PATCH(request: NextRequest, { params: routeParams }: { par return NextResponse.json({ success: true }, { status: 200 }) } catch (error) { console.error("Error updating bug report:", error) - return NextResponse.json({ error: "Failed to update bug report." }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to update bug report." + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/bug-reports/route.ts b/src/app/api/bug-reports/route.ts index b83315c..c54b742 100644 --- a/src/app/api/bug-reports/route.ts +++ b/src/app/api/bug-reports/route.ts @@ -34,7 +34,8 @@ export async function POST(request: NextRequest) { }, { status: 201 }) } catch (error) { console.error("Error creating bug report:", error) - return NextResponse.json({ error: "Failed to submit bug report." }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to submit bug report." + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -113,6 +114,7 @@ export async function GET(request: NextRequest) { return NextResponse.json({ reports }, { status: 200 }) } catch (error) { console.error("Error fetching bug reports:", error) - return NextResponse.json({ error: "Failed to fetch bug reports." }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to fetch bug reports." + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/campaigns/[id]/logs/route.ts b/src/app/api/campaigns/[id]/logs/route.ts index 426bd98..1906875 100644 --- a/src/app/api/campaigns/[id]/logs/route.ts +++ b/src/app/api/campaigns/[id]/logs/route.ts @@ -16,6 +16,8 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{ ) return NextResponse.json(result.rows) } catch (error) { - return NextResponse.json({ error: "Failed" }, { status: 500 }) + console.error("Campaign logs GET error:", error) + const message = error instanceof Error ? error.message : "Failed" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/campaigns/[id]/route.ts b/src/app/api/campaigns/[id]/route.ts index 4d3869c..cc02cc3 100644 --- a/src/app/api/campaigns/[id]/route.ts +++ b/src/app/api/campaigns/[id]/route.ts @@ -31,7 +31,9 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{ return NextResponse.json({ ...campaign.rows[0], steps: steps.rows, subscribers: subscribers.rows }) } catch (error) { - return NextResponse.json({ error: "Failed" }, { status: 500 }) + console.error("Campaign GET error:", error) + const message = error instanceof Error ? error.message : "Failed" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -55,7 +57,9 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise< await query(`UPDATE email_campaigns SET ${fields.join(", ")} WHERE id = $${idx}`, values) return NextResponse.json({ success: true }) } catch (error) { - return NextResponse.json({ error: "Failed" }, { status: 500 }) + console.error("Campaign PATCH error:", error) + const message = error instanceof Error ? error.message : "Failed" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -67,6 +71,8 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise await query("UPDATE email_campaigns SET deleted_at = NOW() WHERE id = $1", [id]) return NextResponse.json({ success: true }) } catch (error) { - return NextResponse.json({ error: "Failed" }, { status: 500 }) + console.error("Campaign DELETE error:", error) + const message = error instanceof Error ? error.message : "Failed" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/campaigns/[id]/send/route.ts b/src/app/api/campaigns/[id]/send/route.ts index 64e511b..2060ecb 100644 --- a/src/app/api/campaigns/[id]/send/route.ts +++ b/src/app/api/campaigns/[id]/send/route.ts @@ -46,7 +46,8 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{ return NextResponse.json({ success: true, sent }) } catch (error) { console.error("Campaign send error:", error) - return NextResponse.json({ error: "Failed to send" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to send" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/campaigns/[id]/steps/route.ts b/src/app/api/campaigns/[id]/steps/route.ts index 127b68b..8702b20 100644 --- a/src/app/api/campaigns/[id]/steps/route.ts +++ b/src/app/api/campaigns/[id]/steps/route.ts @@ -10,7 +10,9 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{ const result = await query("SELECT * FROM email_campaign_steps WHERE campaign_id = $1 ORDER BY step_order", [id]) return NextResponse.json(result.rows) } catch (error) { - return NextResponse.json({ error: "Failed" }, { status: 500 }) + console.error("Steps GET error:", error) + const message = error instanceof Error ? error.message : "Failed" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -31,6 +33,8 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{ ) return NextResponse.json({ success: true, id: result.rows[0].id }, { status: 201 }) } catch (error) { - return NextResponse.json({ error: "Failed" }, { status: 500 }) + console.error("Steps POST error:", error) + const message = error instanceof Error ? error.message : "Failed" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/campaigns/[id]/subscribe/route.ts b/src/app/api/campaigns/[id]/subscribe/route.ts index 8eb58a5..2c4e708 100644 --- a/src/app/api/campaigns/[id]/subscribe/route.ts +++ b/src/app/api/campaigns/[id]/subscribe/route.ts @@ -30,6 +30,8 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{ return NextResponse.json({ error: "leadIds array required" }, { status: 400 }) } catch (error) { - return NextResponse.json({ error: "Failed" }, { status: 500 }) + console.error("Campaign subscribe POST error:", error) + const message = error instanceof Error ? error.message : "Failed" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/campaigns/route.ts b/src/app/api/campaigns/route.ts index 93eadcc..ba9ead8 100644 --- a/src/app/api/campaigns/route.ts +++ b/src/app/api/campaigns/route.ts @@ -17,7 +17,9 @@ export async function GET() { ) return NextResponse.json(result.rows) } catch (error) { - return NextResponse.json({ error: "Failed to load campaigns" }, { status: 500 }) + console.error("Campaigns GET error:", error) + const message = error instanceof Error ? error.message : "Failed to load campaigns" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -33,6 +35,8 @@ export async function POST(request: NextRequest) { ) return NextResponse.json({ success: true, id: result.rows[0].id }, { status: 201 }) } catch (error) { - return NextResponse.json({ error: "Failed to create campaign" }, { status: 500 }) + console.error("Campaigns POST error:", error) + const message = error instanceof Error ? error.message : "Failed to create campaign" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/conversations/[id]/messages/[messageId]/route.ts b/src/app/api/conversations/[id]/messages/[messageId]/route.ts index 12b2f83..7c72b18 100644 --- a/src/app/api/conversations/[id]/messages/[messageId]/route.ts +++ b/src/app/api/conversations/[id]/messages/[messageId]/route.ts @@ -80,6 +80,7 @@ export async function DELETE( }) } catch (error) { console.error("[voice-delete] Error:", error) - return NextResponse.json({ error: "Unable to delete voice note. Please try again." }, { status: 500 }) + const message = error instanceof Error ? error.message : "Unable to delete voice note. Please try again." + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/conversations/[id]/messages/route.ts b/src/app/api/conversations/[id]/messages/route.ts index 4dcb550..0493496 100644 --- a/src/app/api/conversations/[id]/messages/route.ts +++ b/src/app/api/conversations/[id]/messages/route.ts @@ -76,7 +76,8 @@ export async function GET( return NextResponse.json({ messages }) } catch (error) { console.error("Messages error:", error) - return NextResponse.json({ error: "Failed to load messages" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load messages" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -160,7 +161,8 @@ export async function POST( }) } catch (error) { console.error("Send message error:", error) - return NextResponse.json({ error: "Failed to send message" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to send message" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -198,7 +200,8 @@ export async function DELETE( return NextResponse.json({ success: true }) } catch (error) { console.error("Delete message error:", error) - return NextResponse.json({ error: "Failed to delete message" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to delete message" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -229,6 +232,7 @@ export async function PATCH( return NextResponse.json({ success: true }) } catch (error) { console.error("Edit message error:", error) - return NextResponse.json({ error: "Failed to edit message" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to edit message" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/conversations/[id]/read/route.ts b/src/app/api/conversations/[id]/read/route.ts index e5357e8..8994d86 100644 --- a/src/app/api/conversations/[id]/read/route.ts +++ b/src/app/api/conversations/[id]/read/route.ts @@ -28,6 +28,7 @@ export async function POST( return NextResponse.json({ success: true }) } catch (error) { console.error("Mark read error:", error) - return NextResponse.json({ error: "Failed to mark as read" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to mark as read" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/conversations/route.ts b/src/app/api/conversations/route.ts index 9e7192b..8a6c214 100644 --- a/src/app/api/conversations/route.ts +++ b/src/app/api/conversations/route.ts @@ -50,7 +50,8 @@ export async function GET() { return NextResponse.json({ conversations }) } catch (error) { console.error("Conversations error:", error) - return NextResponse.json({ error: "Failed to load conversations" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load conversations" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -115,7 +116,8 @@ export async function POST(request: NextRequest) { }) } catch (error) { console.error("Create conversation error:", error) - return NextResponse.json({ error: "Failed to create conversation" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to create conversation" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/custom-fields/route.ts b/src/app/api/custom-fields/route.ts index a07241a..dccfaed 100644 --- a/src/app/api/custom-fields/route.ts +++ b/src/app/api/custom-fields/route.ts @@ -25,7 +25,8 @@ export async function GET(request: NextRequest) { return NextResponse.json(result.rows) } catch (error) { console.error("Custom fields API error:", error) - return NextResponse.json({ error: "Failed to load custom fields" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load custom fields" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -62,7 +63,8 @@ export async function POST(request: NextRequest) { return NextResponse.json({ error: "A field with this key already exists for this entity" }, { status: 409 }) } console.error("Custom fields POST error:", error) - return NextResponse.json({ error: "Failed to create custom field" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to create custom field" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -106,7 +108,8 @@ export async function PATCH(request: NextRequest) { return NextResponse.json({ success: true }) } catch (error) { console.error("Custom fields PATCH error:", error) - return NextResponse.json({ error: "Failed to update custom field" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to update custom field" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -120,6 +123,7 @@ export async function DELETE(request: NextRequest) { return NextResponse.json({ success: true }) } catch (error) { console.error("Custom fields DELETE error:", error) - return NextResponse.json({ error: "Failed to delete custom field" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to delete custom field" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/customers/route.ts b/src/app/api/customers/route.ts index 60e66d3..8aa8dfd 100644 --- a/src/app/api/customers/route.ts +++ b/src/app/api/customers/route.ts @@ -26,6 +26,7 @@ export async function GET(request: NextRequest) { return NextResponse.json(result.rows) } catch (error) { console.error("Customers API error:", error) - return NextResponse.json({ error: "Failed to load customers" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load customers" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/dashboard/route.ts b/src/app/api/dashboard/route.ts index 940b71b..5392ca5 100644 --- a/src/app/api/dashboard/route.ts +++ b/src/app/api/dashboard/route.ts @@ -208,6 +208,7 @@ export async function GET(request: NextRequest) { return NextResponse.json(stats) } catch (error) { console.error("Dashboard API error:", error) - return NextResponse.json({ error: "Failed to load dashboard stats" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load dashboard stats" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/emails/route.ts b/src/app/api/emails/route.ts index e31ed44..c40d36f 100644 --- a/src/app/api/emails/route.ts +++ b/src/app/api/emails/route.ts @@ -23,6 +23,7 @@ export async function GET() { })) }) } catch (error) { console.error("Emails GET error:", error) - return NextResponse.json({ error: "Failed to load sent emails" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load sent emails" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/event-users/route.ts b/src/app/api/event-users/route.ts index 7c0a315..80f98d9 100644 --- a/src/app/api/event-users/route.ts +++ b/src/app/api/event-users/route.ts @@ -28,6 +28,7 @@ export async function GET() { return NextResponse.json({ users }) } catch (error) { console.error("Event users error:", error) - return NextResponse.json({ error: "Failed to load users" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load users" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/events/[id]/ics/route.ts b/src/app/api/events/[id]/ics/route.ts index 3b99bbe..1855e4a 100644 --- a/src/app/api/events/[id]/ics/route.ts +++ b/src/app/api/events/[id]/ics/route.ts @@ -49,6 +49,7 @@ export async function GET(_request: NextRequest, { params }: { params: Promise<{ }) } catch (error) { console.error("ICS GET error:", error) - return NextResponse.json({ error: "Failed to generate calendar file" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to generate calendar file" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/events/[id]/route.ts b/src/app/api/events/[id]/route.ts index 6199c7e..c99ed76 100644 --- a/src/app/api/events/[id]/route.ts +++ b/src/app/api/events/[id]/route.ts @@ -159,7 +159,8 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise< }) } catch (error) { console.error("Events PATCH error:", error) - return NextResponse.json({ error: "Failed to update event" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to update event" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -189,6 +190,7 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise return NextResponse.json({ success: true }) } catch (error) { console.error("Events DELETE error:", error) - return NextResponse.json({ error: "Failed to delete event" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to delete event" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/events/route.ts b/src/app/api/events/route.ts index 90b6b48..be3e3fe 100644 --- a/src/app/api/events/route.ts +++ b/src/app/api/events/route.ts @@ -96,7 +96,8 @@ export async function GET(request: NextRequest) { return NextResponse.json({ events }) } catch (error) { console.error("Events GET error:", error) - return NextResponse.json({ error: "Failed to load events" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load events" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -241,6 +242,7 @@ export async function POST(request: NextRequest) { }, { status: 201 }) } catch (error) { console.error("Events POST error:", error) - return NextResponse.json({ error: "Failed to create event" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to create event" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/invite/generate/route.ts b/src/app/api/invite/generate/route.ts index 2b37995..2f86117 100644 --- a/src/app/api/invite/generate/route.ts +++ b/src/app/api/invite/generate/route.ts @@ -19,7 +19,9 @@ export async function POST(request: NextRequest) { const inviteUrl = `${origin}/join/${token}` return NextResponse.json({ token, inviteUrl }) - } catch { - return NextResponse.json({ error: "Failed to generate invite" }, { status: 500 }) + } catch (error) { + console.error("Invite generate error:", error) + const message = error instanceof Error ? error.message : "Failed to generate invite" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/leads/[id]/notes/route.ts b/src/app/api/leads/[id]/notes/route.ts index 06b7b88..3b2c865 100644 --- a/src/app/api/leads/[id]/notes/route.ts +++ b/src/app/api/leads/[id]/notes/route.ts @@ -39,7 +39,8 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{ return NextResponse.json({ success: true }) } catch (error) { console.error("Create note error:", error) - return NextResponse.json({ error: "Failed to create note" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to create note" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -81,6 +82,7 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{ return NextResponse.json(notes) } catch (error) { console.error("Lead notes API error:", error) - return NextResponse.json({ error: "Failed to load notes" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load notes" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/leads/[id]/route.ts b/src/app/api/leads/[id]/route.ts index 6165b75..39b3848 100644 --- a/src/app/api/leads/[id]/route.ts +++ b/src/app/api/leads/[id]/route.ts @@ -69,7 +69,8 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{ return NextResponse.json(lead) } catch (error) { console.error("Lead detail API error:", error) - return NextResponse.json({ error: "Failed to load lead" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load lead" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -160,6 +161,7 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise< return NextResponse.json({ success: true, id: result.rows[0].id }) } catch (error) { console.error("Lead PATCH error:", error) - return NextResponse.json({ error: "Failed to update lead" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to update lead" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/leads/kanban/route.ts b/src/app/api/leads/kanban/route.ts index 81384a2..e7bf26c 100644 --- a/src/app/api/leads/kanban/route.ts +++ b/src/app/api/leads/kanban/route.ts @@ -68,6 +68,7 @@ export async function GET(request: NextRequest) { return NextResponse.json(columns) } catch (error) { console.error("Kanban API error:", error) - return NextResponse.json({ error: "Failed to load kanban data" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load kanban data" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/leads/route.ts b/src/app/api/leads/route.ts index ddf16bb..af418dc 100644 --- a/src/app/api/leads/route.ts +++ b/src/app/api/leads/route.ts @@ -114,7 +114,8 @@ export async function GET(request: NextRequest) { return NextResponse.json(leads) } catch (error) { console.error("Leads API error:", error) - return NextResponse.json({ error: "Failed to load leads" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load leads" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -160,7 +161,8 @@ export async function POST(request: NextRequest) { return NextResponse.json({ success: true, id: result.rows[0].id }, { status: 201 }) } catch (error) { console.error("Leads POST error:", error) - return NextResponse.json({ error: "Failed to create lead" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to create lead" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -187,6 +189,7 @@ export async function DELETE(request: NextRequest) { return NextResponse.json({ success: true }) } catch (error) { console.error("Leads DELETE error:", error) - return NextResponse.json({ error: "Failed to delete lead" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to delete lead" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/leads/score/config/route.ts b/src/app/api/leads/score/config/route.ts index b0341d2..c09e47c 100644 --- a/src/app/api/leads/score/config/route.ts +++ b/src/app/api/leads/score/config/route.ts @@ -9,7 +9,9 @@ export async function GET() { const result = await query("SELECT * FROM lead_scoring_config WHERE is_active = true ORDER BY weight DESC") return NextResponse.json(result.rows) } catch (error) { - return NextResponse.json({ error: "Failed to load scoring config" }, { status: 500 }) + console.error("Scoring config GET error:", error) + const message = error instanceof Error ? error.message : "Failed to load scoring config" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -30,7 +32,9 @@ export async function POST(request: NextRequest) { if (error?.constraint === "lead_scoring_config_feature_name_key") { return NextResponse.json({ error: "Feature name already exists" }, { status: 409 }) } - return NextResponse.json({ error: "Failed to create feature" }, { status: 500 }) + console.error("Scoring config POST error:", error) + const message = error instanceof Error ? error.message : "Failed to create feature" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -56,7 +60,9 @@ export async function PATCH(request: NextRequest) { await query(`UPDATE lead_scoring_config SET ${fields.join(", ")} WHERE id = $${idx}`, values) return NextResponse.json({ success: true }) } catch (error) { - return NextResponse.json({ error: "Failed to update" }, { status: 500 }) + console.error("Scoring config PATCH error:", error) + const message = error instanceof Error ? error.message : "Failed to update" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -72,6 +78,8 @@ export async function DELETE(request: NextRequest) { await query("DELETE FROM lead_scoring_config WHERE id = $1", [id]) return NextResponse.json({ success: true }) } catch (error) { - return NextResponse.json({ error: "Failed to delete" }, { status: 500 }) + console.error("Scoring config DELETE error:", error) + const message = error instanceof Error ? error.message : "Failed to delete" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/leads/score/route.ts b/src/app/api/leads/score/route.ts index 8ccb159..c70a694 100644 --- a/src/app/api/leads/score/route.ts +++ b/src/app/api/leads/score/route.ts @@ -83,6 +83,7 @@ export async function POST(request: NextRequest) { return NextResponse.json({ success: true, scored }) } catch (error) { console.error("Lead scoring error:", error) - return NextResponse.json({ error: "Scoring failed" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Scoring failed" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/milestones/[id]/route.ts b/src/app/api/milestones/[id]/route.ts index 0b4f32b..ff4bc1f 100644 --- a/src/app/api/milestones/[id]/route.ts +++ b/src/app/api/milestones/[id]/route.ts @@ -41,7 +41,8 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise< return NextResponse.json({ success: true, id: result.rows[0].id }) } catch (error) { console.error("Milestone PATCH error:", error) - return NextResponse.json({ error: "Failed to update milestone" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to update milestone" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -55,6 +56,7 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise return NextResponse.json({ success: true }) } catch (error) { console.error("Milestone DELETE error:", error) - return NextResponse.json({ error: "Failed to delete milestone" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to delete milestone" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/notifications/[id]/route.ts b/src/app/api/notifications/[id]/route.ts index f6404f8..28195a0 100644 --- a/src/app/api/notifications/[id]/route.ts +++ b/src/app/api/notifications/[id]/route.ts @@ -21,7 +21,8 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise< return NextResponse.json({ success: true }) } catch (error) { console.error("Notification PATCH error:", error) - return NextResponse.json({ error: "Failed to mark notification as read" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to mark notification as read" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -44,6 +45,7 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise return NextResponse.json({ success: true }) } catch (error) { console.error("Notification DELETE error:", error) - return NextResponse.json({ error: "Failed to dismiss notification" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to dismiss notification" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/notifications/preferences/route.ts b/src/app/api/notifications/preferences/route.ts index dd1682a..c0c9af0 100644 --- a/src/app/api/notifications/preferences/route.ts +++ b/src/app/api/notifications/preferences/route.ts @@ -34,7 +34,8 @@ export async function GET() { }) } catch (error) { console.error("Preferences GET error:", error) - return NextResponse.json({ error: "Failed to load preferences" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load preferences" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -64,6 +65,7 @@ export async function PATCH(request: NextRequest) { return NextResponse.json({ success: true }) } catch (error) { console.error("Preferences PATCH error:", error) - return NextResponse.json({ error: "Failed to save preferences" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to save preferences" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/notifications/route.ts b/src/app/api/notifications/route.ts index c4ddd5c..ef3d019 100644 --- a/src/app/api/notifications/route.ts +++ b/src/app/api/notifications/route.ts @@ -39,7 +39,8 @@ export async function GET() { }) } catch (error) { console.error("Notifications GET error:", error) - return NextResponse.json({ error: "Failed to load notifications" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load notifications" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -71,7 +72,8 @@ export async function POST(request: NextRequest) { }, { status: 201 }) } catch (error) { console.error("Notifications POST error:", error) - return NextResponse.json({ error: "Failed to create notification" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to create notification" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -88,6 +90,7 @@ export async function PATCH() { return NextResponse.json({ success: true }) } catch (error) { console.error("Notifications PATCH error:", error) - return NextResponse.json({ error: "Failed to mark all as read" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to mark all as read" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/project-statuses/route.ts b/src/app/api/project-statuses/route.ts index 70a0202..65efb6e 100644 --- a/src/app/api/project-statuses/route.ts +++ b/src/app/api/project-statuses/route.ts @@ -13,6 +13,7 @@ export async function GET() { return NextResponse.json(result.rows) } catch (error) { console.error("Project statuses API error:", error) - return NextResponse.json({ error: "Failed to load statuses" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load statuses" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/projects/[id]/milestones/route.ts b/src/app/api/projects/[id]/milestones/route.ts index 2d0829e..faa5141 100644 --- a/src/app/api/projects/[id]/milestones/route.ts +++ b/src/app/api/projects/[id]/milestones/route.ts @@ -38,7 +38,8 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{ return NextResponse.json(result.rows) } catch (error) { console.error("Milestones API error:", error) - return NextResponse.json({ error: "Failed to load milestones" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load milestones" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -64,6 +65,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{ return NextResponse.json({ success: true, id: result.rows[0].id }, { status: 201 }) } catch (error) { console.error("Milestones POST error:", error) - return NextResponse.json({ error: "Failed to create milestone" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to create milestone" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/projects/[id]/route.ts b/src/app/api/projects/[id]/route.ts index f05ed9b..45deb5a 100644 --- a/src/app/api/projects/[id]/route.ts +++ b/src/app/api/projects/[id]/route.ts @@ -31,7 +31,8 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{ return NextResponse.json(result.rows[0]) } catch (error) { console.error("Project detail API error:", error) - return NextResponse.json({ error: "Failed to load project" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load project" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -74,6 +75,7 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise< return NextResponse.json({ success: true, id: result.rows[0].id }) } catch (error) { console.error("Project PATCH error:", error) - return NextResponse.json({ error: "Failed to update project" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to update project" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/projects/route.ts b/src/app/api/projects/route.ts index 44c5d3d..745f6f8 100644 --- a/src/app/api/projects/route.ts +++ b/src/app/api/projects/route.ts @@ -49,7 +49,8 @@ export async function GET(request: NextRequest) { return NextResponse.json(result.rows) } catch (error) { console.error("Projects API error:", error) - return NextResponse.json({ error: "Failed to load projects" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load projects" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -81,7 +82,8 @@ export async function POST(request: NextRequest) { return NextResponse.json({ success: true, id: result.rows[0].id }, { status: 201 }) } catch (error) { console.error("Projects POST error:", error) - return NextResponse.json({ error: "Failed to create project" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to create project" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -98,6 +100,7 @@ export async function DELETE(request: NextRequest) { return NextResponse.json({ success: true }) } catch (error) { console.error("Projects DELETE error:", error) - return NextResponse.json({ error: "Failed to delete project" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to delete project" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/proposal-statuses/route.ts b/src/app/api/proposal-statuses/route.ts index 42b7c78..4e48665 100644 --- a/src/app/api/proposal-statuses/route.ts +++ b/src/app/api/proposal-statuses/route.ts @@ -11,6 +11,7 @@ export async function GET() { return NextResponse.json(result.rows) } catch (error) { console.error("Proposal statuses API error:", error) - return NextResponse.json({ error: "Failed to load statuses" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load statuses" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/proposals/[id]/items/route.ts b/src/app/api/proposals/[id]/items/route.ts index c6c653c..59cb22f 100644 --- a/src/app/api/proposals/[id]/items/route.ts +++ b/src/app/api/proposals/[id]/items/route.ts @@ -31,7 +31,8 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{ return NextResponse.json({ success: true, id: result.rows[0].id }, { status: 201 }) } catch (error) { console.error("Proposal items POST error:", error) - return NextResponse.json({ error: "Failed to add item" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to add item" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -49,7 +50,8 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise return NextResponse.json({ success: true }) } catch (error) { console.error("Proposal items DELETE error:", error) - return NextResponse.json({ error: "Failed to delete item" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to delete item" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/proposals/[id]/route.ts b/src/app/api/proposals/[id]/route.ts index e1db572..f64af47 100644 --- a/src/app/api/proposals/[id]/route.ts +++ b/src/app/api/proposals/[id]/route.ts @@ -47,7 +47,8 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{ }) } catch (error) { console.error("Proposal detail API error:", error) - return NextResponse.json({ error: "Failed to load proposal" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load proposal" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -101,7 +102,8 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise< return NextResponse.json({ success: true }) } catch (error) { console.error("Proposal PATCH error:", error) - return NextResponse.json({ error: "Failed to update proposal" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to update proposal" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -113,6 +115,7 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise return NextResponse.json({ success: true }) } catch (error) { console.error("Proposal DELETE error:", error) - return NextResponse.json({ error: "Failed to delete proposal" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to delete proposal" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/proposals/[id]/sign/route.ts b/src/app/api/proposals/[id]/sign/route.ts index ec10566..2065166 100644 --- a/src/app/api/proposals/[id]/sign/route.ts +++ b/src/app/api/proposals/[id]/sign/route.ts @@ -29,6 +29,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{ return NextResponse.json({ success: true, id: signature.rows[0].id }) } catch (error) { console.error("Proposal sign error:", error) - return NextResponse.json({ error: "Failed to sign proposal" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to sign proposal" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/proposals/route.ts b/src/app/api/proposals/route.ts index ef7a806..74c8cb0 100644 --- a/src/app/api/proposals/route.ts +++ b/src/app/api/proposals/route.ts @@ -39,7 +39,8 @@ export async function GET(request: NextRequest) { return NextResponse.json(result.rows) } catch (error) { console.error("Proposals API error:", error) - return NextResponse.json({ error: "Failed to load proposals" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load proposals" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -80,6 +81,7 @@ export async function POST(request: NextRequest) { return NextResponse.json({ success: true, id: result.rows[0].id, proposalNumber }, { status: 201 }) } catch (error) { console.error("Proposals POST error:", error) - return NextResponse.json({ error: "Failed to create proposal" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to create proposal" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/resource-planning/route.ts b/src/app/api/resource-planning/route.ts index fb342a3..fe2bb81 100644 --- a/src/app/api/resource-planning/route.ts +++ b/src/app/api/resource-planning/route.ts @@ -96,6 +96,7 @@ export async function GET(request: NextRequest) { return NextResponse.json({ members, totals, period }) } catch (error) { console.error("Resource planning API error:", error) - return NextResponse.json({ error: "Failed to load resource data" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load resource data" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/settings/company/route.ts b/src/app/api/settings/company/route.ts index 87aa37c..732ab4b 100644 --- a/src/app/api/settings/company/route.ts +++ b/src/app/api/settings/company/route.ts @@ -32,7 +32,8 @@ export async function GET() { }) } catch (error) { console.error("Company settings GET error:", error) - return NextResponse.json({ error: "Failed to load company settings" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load company settings" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -79,6 +80,7 @@ export async function PATCH(request: NextRequest) { return NextResponse.json({ success: true }) } catch (error) { console.error("Company settings PATCH error:", error) - return NextResponse.json({ error: "Failed to save company settings" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to save company settings" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/settings/facebook/accounts/[id]/route.ts b/src/app/api/settings/facebook/accounts/[id]/route.ts index a4954ce..0bad439 100644 --- a/src/app/api/settings/facebook/accounts/[id]/route.ts +++ b/src/app/api/settings/facebook/accounts/[id]/route.ts @@ -56,6 +56,7 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise< return NextResponse.json(updated.rows[0] || { success: true }) } catch (error) { console.error("Facebook accounts PATCH error:", error) - return NextResponse.json({ error: "Failed to update Facebook account" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to update Facebook account" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/settings/facebook/accounts/route.ts b/src/app/api/settings/facebook/accounts/route.ts index e5f0005..4352193 100644 --- a/src/app/api/settings/facebook/accounts/route.ts +++ b/src/app/api/settings/facebook/accounts/route.ts @@ -33,7 +33,8 @@ export async function GET() { return NextResponse.json(accounts.rows) } catch (error) { console.error("Facebook accounts GET error:", error) - return NextResponse.json({ error: "Failed to load Facebook accounts" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load Facebook accounts" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -61,6 +62,7 @@ export async function POST(request: NextRequest) { return NextResponse.json(result.rows[0], { status: 201 }) } catch (error) { console.error("Facebook accounts POST error:", error) - return NextResponse.json({ error: "Failed to create Facebook account" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to create Facebook account" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/settings/facebook/logs/route.ts b/src/app/api/settings/facebook/logs/route.ts index 7f10470..550bc30 100644 --- a/src/app/api/settings/facebook/logs/route.ts +++ b/src/app/api/settings/facebook/logs/route.ts @@ -36,6 +36,7 @@ export async function GET(request: NextRequest) { return NextResponse.json(result.rows) } catch (error) { console.error("Facebook scrape logs GET error:", error) - return NextResponse.json({ error: "Failed to load scrape logs" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load scrape logs" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/settings/preferences/route.ts b/src/app/api/settings/preferences/route.ts index 6a7da54..066f6a4 100644 --- a/src/app/api/settings/preferences/route.ts +++ b/src/app/api/settings/preferences/route.ts @@ -28,7 +28,8 @@ export async function GET() { }) } catch (error) { console.error("Preferences GET error:", error) - return NextResponse.json({ error: "Failed to load preferences" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load preferences" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -55,6 +56,7 @@ export async function PATCH(request: NextRequest) { return NextResponse.json({ success: true }) } catch (error) { console.error("Preferences PATCH error:", error) - return NextResponse.json({ error: "Failed to save preferences" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to save preferences" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/settings/website-theme/route.ts b/src/app/api/settings/website-theme/route.ts index b67875f..2ee1424 100644 --- a/src/app/api/settings/website-theme/route.ts +++ b/src/app/api/settings/website-theme/route.ts @@ -16,7 +16,8 @@ export async function GET() { return NextResponse.json({ websiteTheme }) } catch (error) { console.error("Website theme GET error:", error) - return NextResponse.json({ error: "Failed to load website theme" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load website theme" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -36,6 +37,7 @@ export async function PUT(request: NextRequest) { return NextResponse.json({ success: true, websiteTheme: theme }) } catch (error) { console.error("Website theme PUT error:", error) - return NextResponse.json({ error: "Failed to save website theme" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to save website theme" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/tasks/route.ts b/src/app/api/tasks/route.ts index 650cc1b..37661b0 100644 --- a/src/app/api/tasks/route.ts +++ b/src/app/api/tasks/route.ts @@ -25,7 +25,8 @@ export async function POST(request: NextRequest) { return NextResponse.json({ success: true, id: result.rows[0].id }, { status: 201 }) } catch (error) { console.error("Tasks POST error:", error) - return NextResponse.json({ error: "Failed to create task" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to create task" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -66,6 +67,7 @@ export async function PATCH(request: NextRequest) { return NextResponse.json({ success: true }) } catch (error) { console.error("Tasks PATCH error:", error) - return NextResponse.json({ error: "Failed to update task" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to update task" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/time-entries/route.ts b/src/app/api/time-entries/route.ts index 4882d99..3069a73 100644 --- a/src/app/api/time-entries/route.ts +++ b/src/app/api/time-entries/route.ts @@ -44,7 +44,8 @@ export async function GET(request: NextRequest) { return NextResponse.json(result.rows) } catch (error) { console.error("Time entries API error:", error) - return NextResponse.json({ error: "Failed to load time entries" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load time entries" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -81,7 +82,8 @@ export async function POST(request: NextRequest) { return NextResponse.json({ success: true, id: result.rows[0].id }, { status: 201 }) } catch (error) { console.error("Time entries POST error:", error) - return NextResponse.json({ error: "Failed to create time entry" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to create time entry" + return NextResponse.json({ error: message }, { status: 500 }) } } @@ -95,6 +97,7 @@ export async function DELETE(request: NextRequest) { return NextResponse.json({ success: true }) } catch (error) { console.error("Time entries DELETE error:", error) - return NextResponse.json({ error: "Failed to delete entry" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to delete entry" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/time-entries/summary/route.ts b/src/app/api/time-entries/summary/route.ts index 0b4f411..53a74fc 100644 --- a/src/app/api/time-entries/summary/route.ts +++ b/src/app/api/time-entries/summary/route.ts @@ -53,6 +53,7 @@ export async function GET() { }) } catch (error) { console.error("Time summary API error:", error) - return NextResponse.json({ error: "Failed to load summary" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to load summary" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/upload/voice/route.ts b/src/app/api/upload/voice/route.ts index d379c9e..0b8ad63 100644 --- a/src/app/api/upload/voice/route.ts +++ b/src/app/api/upload/voice/route.ts @@ -24,6 +24,7 @@ export async function POST(request: NextRequest) { return NextResponse.json({ url: `/uploads/voice/${filename}`, duration }) } catch (error) { console.error("Voice upload error:", error) - return NextResponse.json({ error: "Upload failed" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Upload failed" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/users/[id]/route.ts b/src/app/api/users/[id]/route.ts index b816bc5..0dfd5b0 100644 --- a/src/app/api/users/[id]/route.ts +++ b/src/app/api/users/[id]/route.ts @@ -26,6 +26,7 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise return NextResponse.json({ success: true }, { status: 200 }) } catch (error) { console.error("Error deleting user:", error) - return NextResponse.json({ error: "Failed to delete user" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to delete user" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/users/avatar/route.ts b/src/app/api/users/avatar/route.ts index f05f18b..a14c83c 100644 --- a/src/app/api/users/avatar/route.ts +++ b/src/app/api/users/avatar/route.ts @@ -35,6 +35,7 @@ export async function POST(request: NextRequest) { return NextResponse.json({ avatar }) } catch (error) { console.error("Avatar upload error:", error) - return NextResponse.json({ error: "Failed to update avatar" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to update avatar" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/users/route.ts b/src/app/api/users/route.ts index fd4b2ca..9ed03cc 100644 --- a/src/app/api/users/route.ts +++ b/src/app/api/users/route.ts @@ -39,7 +39,8 @@ export async function GET(request: NextRequest) { return NextResponse.json({ users }, { status: 200 }) } catch (error) { console.error("Error fetching users:", error) - return NextResponse.json({ error: "Failed to fetch users" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Failed to fetch users" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/app/api/users/search/route.ts b/src/app/api/users/search/route.ts index 77fcb87..18f4e76 100644 --- a/src/app/api/users/search/route.ts +++ b/src/app/api/users/search/route.ts @@ -39,6 +39,7 @@ export async function GET(request: NextRequest) { return NextResponse.json({ users }) } catch (error) { console.error("User search error:", error) - return NextResponse.json({ error: "Search failed" }, { status: 500 }) + const message = error instanceof Error ? error.message : "Search failed" + return NextResponse.json({ error: message }, { status: 500 }) } } diff --git a/src/components/leads/lead-form-dialog.tsx b/src/components/leads/lead-form-dialog.tsx index 71986b2..35cfe61 100644 --- a/src/components/leads/lead-form-dialog.tsx +++ b/src/components/leads/lead-form-dialog.tsx @@ -33,6 +33,7 @@ import { import { Lead, LeadStatus, User } from "@/types" import { LEAD_SOURCES, LEAD_STATUSES } from "@/lib/constants" import { useNotifications } from "@/providers/notification-provider" +import { toast } from "sonner" const leadFormSchema = z.object({ companyName: z.string().min(1, "Company name is required"), @@ -64,7 +65,7 @@ export function LeadFormDialog({ open, onOpenChange, lead, onSuccess }: LeadForm fetch("/api/users") .then((r) => r.json()) .then((data) => setUsers(data.users || [])) - .catch(() => {}) + .catch((e) => { console.error("Failed to load users", e); toast.error("Failed to load users") }) }, []) const form = useForm({ @@ -134,6 +135,7 @@ export function LeadFormDialog({ open, onOpenChange, lead, onSuccess }: LeadForm onOpenChange(false) onSuccess?.() } catch (e) { + toast.error("Failed to save lead") console.error("Lead save error:", e) } finally { setSaving(false) diff --git a/src/components/settings/facebook-accounts-dialog.tsx b/src/components/settings/facebook-accounts-dialog.tsx index ae116f3..795e3c7 100644 --- a/src/components/settings/facebook-accounts-dialog.tsx +++ b/src/components/settings/facebook-accounts-dialog.tsx @@ -6,6 +6,7 @@ import { Badge } from "@/components/ui/badge" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { ShieldAlert, RefreshCw } from "lucide-react" import { Button } from "@/components/ui/button" +import { toast } from "sonner" interface Account { id: string @@ -36,7 +37,7 @@ export function FacebookAccountsDialog({ open, onOpenChange }: { open: boolean; if (res.ok) { setAccounts(await res.json()) } - } catch {} + } catch (e) { console.error("Failed to load Facebook accounts", e); toast.error("Failed to load Facebook accounts") } setLoading(false) } diff --git a/src/components/settings/lead-scoring-settings.tsx b/src/components/settings/lead-scoring-settings.tsx index c6dd1ab..4a4fa20 100644 --- a/src/components/settings/lead-scoring-settings.tsx +++ b/src/components/settings/lead-scoring-settings.tsx @@ -6,6 +6,7 @@ import { Input } from "@/components/ui/input" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Plus, Trash2, RefreshCw, Gauge } from "lucide-react" +import { toast } from "sonner" interface ScoringFeature { id: string @@ -33,26 +34,41 @@ export function LeadScoringSettings() { const addFeature = async () => { if (!newFeature.featureName) return - const res = await fetch("/api/leads/score/config", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(newFeature), - }) - if (res.ok) { setNewFeature({ featureName: "", fieldRef: "", featureType: "keyword", weight: 5 }); loadFeatures() } + try { + const res = await fetch("/api/leads/score/config", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(newFeature), + }) + if (res.ok) { setNewFeature({ featureName: "", fieldRef: "", featureType: "keyword", weight: 5 }); loadFeatures() } + } catch (e) { + console.error("Failed to add scoring feature", e) + toast.error("Failed to add scoring feature") + } } const deleteFeature = async (id: string) => { - await fetch(`/api/leads/score/config?id=${id}`, { method: "DELETE" }) - loadFeatures() + try { + await fetch(`/api/leads/score/config?id=${id}`, { method: "DELETE" }) + loadFeatures() + } catch (e) { + console.error("Failed to delete scoring feature", e) + toast.error("Failed to delete scoring feature") + } } const toggleFeature = async (f: ScoringFeature) => { - await fetch("/api/leads/score/config", { - method: "PATCH", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ id: f.id, isActive: !f.is_active }), - }) - loadFeatures() + try { + await fetch("/api/leads/score/config", { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ id: f.id, isActive: !f.is_active }), + }) + loadFeatures() + } catch (e) { + console.error("Failed to toggle scoring feature", e) + toast.error("Failed to toggle scoring feature") + } } const runScoring = async () => { diff --git a/src/components/shared/custom-fields-section.tsx b/src/components/shared/custom-fields-section.tsx index edbaa08..026973c 100644 --- a/src/components/shared/custom-fields-section.tsx +++ b/src/components/shared/custom-fields-section.tsx @@ -14,6 +14,7 @@ import { SelectValue, } from "@/components/ui/select" import { Check, X, Pencil, Save } from "lucide-react" +import { toast } from "sonner" interface FieldDef { id: string @@ -48,7 +49,7 @@ export function CustomFieldsSection({ entityType, customFields = {}, entityId, a try { const res = await fetch(`/api/custom-fields?entityType=${entityType}`) if (res.ok) setDefinitions(await res.json()) - } catch { /* ignore */ } + } catch (e) { console.error("Failed to load custom fields", e); toast.error("Failed to load custom fields") } setLoading(false) }, [entityType]) @@ -73,7 +74,7 @@ export function CustomFieldsSection({ entityType, customFields = {}, entityId, a body: JSON.stringify({ customFields: values }), }) setEditing(false) - } catch { /* ignore */ } + } catch (e) { console.error("Failed to save custom fields", e); toast.error("Failed to save custom fields") } setSaving(false) }