added some api

This commit is contained in:
Jelaletdin12
2025-11-13 21:56:30 +05:00
parent fdec9e4b0e
commit 21b9e88c5c
22 changed files with 2268 additions and 930 deletions

View File

@@ -1,16 +1,61 @@
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"
import { useQuery, useMutation, useQueryClient, UseQueryOptions } from "@tanstack/react-query"
import { apiClient } from "@/lib/api"
import type { Cart, CartItem } from "@/lib/types/api"
export function useCart() {
interface CartResponse {
message: string
data: CartItem[]
errorDetails?: string
}
// Transform response to handle HTML/malformed responses
function transformCartResponse(response: any): CartResponse {
if (
typeof response === "string" &&
(response.trim().startsWith("<!DOCTYPE") || response.trim().startsWith("<html"))
) {
console.error("Received HTML response instead of JSON:", response.substring(0, 100))
return {
message: "error",
data: [],
errorDetails: "Server returned HTML instead of JSON. The server might be down or experiencing issues.",
}
}
if (typeof response === "object") {
if (response.data) {
return response
}
return { message: "success", data: [] }
}
if (typeof response === "string") {
try {
const parsed = JSON.parse(response)
return parsed
} catch (error) {
console.error("Failed to parse response:", error)
return { message: "error", data: [] }
}
}
return { message: "unknown", data: [] }
}
export function useCart(options?: Partial<UseQueryOptions<CartResponse>>) {
return useQuery({
queryKey: ["cart"],
queryFn: async () => {
const response = await apiClient.get<Cart>("/api/v1/carts")
return response.data
const response = await apiClient.get("/carts")
return transformCartResponse(response.data)
},
staleTime: 0, // Always fetch fresh
refetchInterval: 5000, // Poll every 5 seconds like RTK
refetchOnMount: true,
refetchOnWindowFocus: false,
refetchOnReconnect: true,
staleTime: 0,
retry: 1,
...options,
})
}
@@ -19,17 +64,38 @@ export function useAddToCart() {
return useMutation({
mutationFn: async ({ productId, quantity = 1 }: { productId: number; quantity?: number }) => {
const response = await apiClient.post<Cart>("/api/v1/carts", {
product_id: productId,
quantity,
const params = new URLSearchParams({
product_id: String(productId),
product_quantity: String(quantity),
})
return response.data
const response = await apiClient.post("/carts", params.toString(), {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
})
if (typeof response.data === "object" && response.data.data) {
return response.data
}
if (typeof response.data === "string") {
try {
const parsed = JSON.parse(response.data)
return parsed
} catch (error) {
console.error("Failed to parse add to cart response:", error)
return { message: "success", data: "Added to cart" }
}
}
return { message: "success", data: "Added to cart" }
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["cart"] })
},
onError: (error: any) => {
console.error("[v0] Add to cart error:", error.response?.data?.message || error.message)
console.error("Add to cart error:", error.response?.data?.message || error.message)
},
})
}
@@ -38,8 +104,66 @@ export function useRemoveFromCart() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: async (itemId: number) => {
await apiClient.delete(`/api/v1/carts/${itemId}`)
mutationFn: async (productId: number) => {
const params = new URLSearchParams({ product_id: String(productId) })
const response = await apiClient.patch("/carts", params.toString(), {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
})
if (typeof response.data === "object" && response.data.data) {
return response.data.data
}
if (typeof response.data === "string") {
try {
const parsed = JSON.parse(response.data)
return parsed.data || []
} catch (error) {
console.error("Failed to parse cart response:", error)
return []
}
}
return []
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["cart"] })
},
onError: (error: any) => {
console.error("Remove from cart error:", error.response?.data?.message || error.message)
},
})
}
export function useCleanCart() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: async () => {
const response = await apiClient.delete("/carts", {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
})
if (typeof response.data === "object" && response.data.data) {
return response.data.data
}
if (typeof response.data === "string") {
try {
const parsed = JSON.parse(response.data)
return parsed.data || []
} catch (error) {
console.error("Failed to parse cart response:", error)
return []
}
}
return []
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["cart"] })
@@ -51,15 +175,40 @@ export function useUpdateCartItemQuantity() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: async ({ itemId, quantity }: { itemId: number; quantity: number }) => {
const response = await apiClient.patch<CartItem>(`/api/v1/carts/${itemId}`, {
quantity,
mutationFn: async ({ productId, quantity }: { productId: number; quantity: number }) => {
const params = new URLSearchParams({
product_id: String(productId),
product_quantity: String(quantity),
})
return response.data
const response = await apiClient.post("/carts", params.toString(), {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
})
if (typeof response.data === "object" && response.data.data) {
return response.data
}
if (typeof response.data === "string") {
try {
const parsed = JSON.parse(response.data)
return parsed
} catch (error) {
console.error("Failed to parse update cart response:", error)
return { message: "success", data: "Updated cart" }
}
}
return { message: "success", data: "Updated cart" }
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["cart"] })
},
onError: (error: any) => {
console.error("API update failed:", error.response?.data?.message || error.message)
},
})
}
@@ -86,7 +235,36 @@ export function useCreateOrder() {
queryClient.invalidateQueries({ queryKey: ["orders"] })
},
onError: (error: any) => {
console.error("[v0] Create order error:", error.response?.data?.message || error.message)
console.error("Create order error:", error.response?.data?.message || error.message)
},
})
}
import type { Region } from "@/lib/types/api"
export function useRegions() {
return useQuery({
queryKey: ["regions"],
queryFn: async () => {
const response = await apiClient.get<Region[]>("/api/v1/provinces")
return response.data
},
staleTime: 1000 * 60 * 60, // 1 hour
})
}
import type { Address } from "@/lib/types/api"
export function useAddresses() {
return useQuery({
queryKey: ["addresses"],
queryFn: async () => {
const response = await apiClient.get<Address[]>("/api/v1/addresses")
return response.data
},
staleTime: 1000 * 60 * 30, // 30 minutes
})
}