Refactor API calls to use apiRequest instead of clientFetch

Replaces all usages of clientFetch with the new apiRequest utility across dashboard pages, modal components, and the profit analytics service. This standardizes API interaction and improves consistency in request handling.
This commit is contained in:
g
2025-12-12 20:05:26 +00:00
parent fd5440c4da
commit 07dcaf55c0
7 changed files with 26 additions and 37 deletions

View File

@@ -23,7 +23,7 @@ import {
AlertDialogHeader, AlertDialogHeader,
AlertDialogTitle, AlertDialogTitle,
} from "@/components/ui/alert-dialog"; } from "@/components/ui/alert-dialog";
import { clientFetch } from "@/lib/api"; import { apiRequest } from "@/lib/api";
import type { Category } from "@/models/categories"; import type { Category } from "@/models/categories";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
@@ -67,7 +67,7 @@ export default function CategoriesPage() {
const fetchCategories = async () => { const fetchCategories = async () => {
try { try {
const fetchedCategories = await clientFetch("/categories"); const fetchedCategories = await apiRequest("/categories", "GET");
setCategories(fetchedCategories); setCategories(fetchedCategories);
} catch (error) { } catch (error) {
toast.error("Failed to fetch categories"); toast.error("Failed to fetch categories");
@@ -89,13 +89,10 @@ export default function CategoriesPage() {
const maxOrder = siblings.reduce((max, cat) => const maxOrder = siblings.reduce((max, cat) =>
Math.max(max, cat.order || 0), 0); Math.max(max, cat.order || 0), 0);
const response = await clientFetch("/categories", { const response = await apiRequest("/categories", "POST", {
method: "POST", name: newCategoryName,
body: JSON.stringify({ parentId: selectedParentId || undefined,
name: newCategoryName, order: maxOrder + 1,
parentId: selectedParentId || undefined,
order: maxOrder + 1,
}),
}); });
setCategories([...categories, response]); setCategories([...categories, response]);
@@ -109,11 +106,8 @@ export default function CategoriesPage() {
const handleUpdateCategory = async (categoryId: string, newName: string) => { const handleUpdateCategory = async (categoryId: string, newName: string) => {
try { try {
const response = await clientFetch(`/categories/${categoryId}`, { const response = await apiRequest(`/categories/${categoryId}`, "PUT", {
method: "PUT", name: newName,
body: JSON.stringify({
name: newName,
}),
}); });
setCategories(categories.map(cat => setCategories(categories.map(cat =>
@@ -130,9 +124,7 @@ export default function CategoriesPage() {
if (!categoryToDelete) return; if (!categoryToDelete) return;
try { try {
await clientFetch(`/categories/${categoryToDelete._id}`, { await apiRequest(`/categories/${categoryToDelete._id}`, "DELETE");
method: "DELETE",
});
setCategories(categories.filter(cat => cat._id !== categoryToDelete._id)); setCategories(categories.filter(cat => cat._id !== categoryToDelete._id));
toast.success("Category deleted successfully"); toast.success("Category deleted successfully");
setCategoryToDelete(null); setCategoryToDelete(null);
@@ -195,11 +187,8 @@ export default function CategoriesPage() {
order: cat.order order: cat.order
})); }));
await clientFetch("/categories/bulk-order", { await apiRequest("/categories/bulk-order", "PUT", {
method: "PUT", categories: categoriesToUpdate
body: JSON.stringify({
categories: categoriesToUpdate
}),
}); });
} catch (error) { } catch (error) {
toast.error("Failed to update category order"); toast.error("Failed to update category order");

View File

@@ -7,7 +7,7 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea"; import { Textarea } from "@/components/ui/textarea";
import { Save, Send, Key, MessageSquare, Shield, Globe, Wallet } from "lucide-react"; import { Save, Send, Key, MessageSquare, Shield, Globe, Wallet } from "lucide-react";
import { clientFetch } from "@/lib/api"; import { apiRequest } from "@/lib/api";
import { toast } from "sonner"; import { toast } from "sonner";
import BroadcastDialog from "@/components/modals/broadcast-dialog"; import BroadcastDialog from "@/components/modals/broadcast-dialog";
import Dashboard from "@/components/dashboard/dashboard"; import Dashboard from "@/components/dashboard/dashboard";
@@ -115,7 +115,7 @@ export default function StorefrontPage() {
const fetchStorefront = async () => { const fetchStorefront = async () => {
try { try {
setLoading(true); setLoading(true);
const data = await clientFetch("/storefront"); const data = await apiRequest("/storefront");
setStorefront({ setStorefront({
pgpKey: data.pgpKey || "", pgpKey: data.pgpKey || "",
welcomeMessage: data.welcomeMessage || "", welcomeMessage: data.welcomeMessage || "",
@@ -154,10 +154,7 @@ export default function StorefrontPage() {
const saveStorefront = async () => { const saveStorefront = async () => {
try { try {
setSaving(true); setSaving(true);
await clientFetch("/storefront", { await apiRequest("/storefront", "PUT", storefront);
method: "PUT",
body: JSON.stringify(storefront),
});
toast.success("Storefront updated successfully!"); toast.success("Storefront updated successfully!");
} catch (error) { } catch (error) {
toast.error("Failed to update storefront."); toast.error("Failed to update storefront.");

View File

@@ -5,7 +5,7 @@ import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
import { Send, Bold, Italic, Code, Link as LinkIcon, Image as ImageIcon, X, Eye, EyeOff, Package } from "lucide-react"; import { Send, Bold, Italic, Code, Link as LinkIcon, Image as ImageIcon, X, Eye, EyeOff, Package } from "lucide-react";
import { toast } from "sonner"; import { toast } from "sonner";
import { apiRequest } from "@/lib/api"; import { clientFetch } from "@/lib/api";
import { Textarea } from "@/components/ui/textarea"; import { Textarea } from "@/components/ui/textarea";
import ReactMarkdown from 'react-markdown'; import ReactMarkdown from 'react-markdown';
import ProductSelector from "./product-selector"; import ProductSelector from "./product-selector";
@@ -137,6 +137,9 @@ export default function BroadcastDialog({ open, setOpen }: BroadcastDialogProps)
message: broadcastMessage, message: broadcastMessage,
productIds: selectedProducts productIds: selectedProducts
}), }),
headers: {
'Content-Type': 'application/json'
}
}); });
} }

View File

@@ -20,7 +20,7 @@ import type { ProductModalProps, ProductData } from "@/lib/types";
import { toast } from "sonner"; import { toast } from "sonner";
import type React from "react"; import type React from "react";
import { Plus } from "lucide-react"; import { Plus } from "lucide-react";
import { clientFetch } from "@/lib/api"; import { apiRequest } from "@/lib/api";
import { Switch } from "@/components/ui/switch"; import { Switch } from "@/components/ui/switch";
type CategorySelectProps = { type CategorySelectProps = {

View File

@@ -6,7 +6,7 @@ import { Input } from "@/components/ui/input";
import { Checkbox } from "@/components/ui/checkbox"; import { Checkbox } from "@/components/ui/checkbox";
import { ScrollArea } from "@/components/ui/scroll-area"; import { ScrollArea } from "@/components/ui/scroll-area";
import { Search, Package } from "lucide-react"; import { Search, Package } from "lucide-react";
import { clientFetch } from "@/lib/api"; import { apiRequest } from "@/lib/api";
interface Product { interface Product {
_id: string; _id: string;
@@ -30,7 +30,7 @@ export default function ProductSelector({ selectedProducts, onSelectionChange }:
useEffect(() => { useEffect(() => {
const fetchProducts = async () => { const fetchProducts = async () => {
try { try {
const fetchedProducts = await clientFetch('/products/for-selection'); const fetchedProducts = await apiRequest('/products/for-selection', 'GET');
setProducts(fetchedProducts); setProducts(fetchedProducts);
} catch (error) { } catch (error) {
console.error('Error fetching products:', error); console.error('Error fetching products:', error);

View File

@@ -7,7 +7,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { TrendingUp, TrendingDown, Calculator, DollarSign } from "lucide-react"; import { TrendingUp, TrendingDown, Calculator, DollarSign } from "lucide-react";
import { toast } from "sonner"; import { toast } from "sonner";
import { clientFetch } from "@/lib/api"; import { apiRequest } from "@/lib/api";
interface ProfitAnalysisModalProps { interface ProfitAnalysisModalProps {
open: boolean; open: boolean;
@@ -57,7 +57,7 @@ export const ProfitAnalysisModal: React.FC<ProfitAnalysisModalProps> = ({
const fetchProfitAnalysis = async () => { const fetchProfitAnalysis = async () => {
try { try {
setLoading(true); setLoading(true);
const response = await clientFetch(`/products/${productId}/profit-analysis`); const response = await apiRequest(`/products/${productId}/profit-analysis`);
setProfitData(response); setProfitData(response);
} catch (error) { } catch (error) {
console.error("Error fetching profit analysis:", error); console.error("Error fetching profit analysis:", error);

View File

@@ -1,4 +1,4 @@
import { clientFetch } from '../api'; import { apiRequest } from '../api';
export interface ProfitOverview { export interface ProfitOverview {
period: string; period: string;
@@ -63,7 +63,7 @@ export const getProfitOverview = async (
url += `?period=${period}`; url += `?period=${period}`;
} }
return clientFetch(url); return apiRequest(url);
}; };
export const getProfitTrends = async ( export const getProfitTrends = async (
@@ -82,5 +82,5 @@ export const getProfitTrends = async (
url += `?period=${period}`; url += `?period=${period}`;
} }
return clientFetch(url); return apiRequest(url);
}; };