mirror of
https://github.com/ForFarmTeam/ForFarm.git
synced 2025-12-18 21:44:08 +01:00
feat: add fetchInventoryCategory API and integrate into inventory management
This commit is contained in:
parent
e7bdb5d6a1
commit
ba8f754d8d
@ -3,14 +3,15 @@ import type {
|
||||
InventoryItem,
|
||||
CreateInventoryItemInput,
|
||||
InventoryItemStatus,
|
||||
InventoryItemCategory,
|
||||
} from "@/types";
|
||||
|
||||
/**
|
||||
* Simulates an API call to fetch inventory items.
|
||||
* Waits for a simulated delay and then attempts an axios GET request.
|
||||
* If the request fails, returns fallback dummy data.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
export async function fetchInventoryStatus(): Promise<InventoryItemStatus[]> {
|
||||
try {
|
||||
@ -23,6 +24,19 @@ export async function fetchInventoryStatus(): Promise<InventoryItemStatus[]> {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
export async function fetchInventoryCategory(): Promise<
|
||||
InventoryItemCategory[]
|
||||
> {
|
||||
try {
|
||||
const response = await axiosInstance.get<InventoryItemCategory[]>(
|
||||
"/inventory/category"
|
||||
);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error("Error fetching inventory status:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchInventoryItems(): Promise<InventoryItem[]> {
|
||||
try {
|
||||
@ -34,52 +48,47 @@ export async function fetchInventoryItems(): Promise<InventoryItem[]> {
|
||||
{
|
||||
id: 1,
|
||||
name: "Tomato Seeds",
|
||||
category: "Seeds",
|
||||
type: "Plantation",
|
||||
category: "1",
|
||||
quantity: 500,
|
||||
unit: "packets",
|
||||
lastUpdated: "2023-03-01",
|
||||
status: "In Stock",
|
||||
status: "1",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "NPK Fertilizer",
|
||||
category: "Fertilizer",
|
||||
type: "Fertilizer",
|
||||
category: "3",
|
||||
quantity: 200,
|
||||
unit: "kg",
|
||||
lastUpdated: "2023-03-05",
|
||||
status: "Low Stock",
|
||||
status: "2",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Corn Seeds",
|
||||
category: "Seeds",
|
||||
type: "Plantation",
|
||||
category: "1",
|
||||
quantity: 300,
|
||||
unit: "packets",
|
||||
lastUpdated: "2023-03-10",
|
||||
status: "In Stock",
|
||||
status: "3",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Organic Compost",
|
||||
category: "Fertilizer",
|
||||
type: "Fertilizer",
|
||||
category: "3",
|
||||
quantity: 150,
|
||||
unit: "kg",
|
||||
lastUpdated: "2023-03-15",
|
||||
status: "Out Of Stock",
|
||||
status: "1",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "Wheat Seeds",
|
||||
category: "Seeds",
|
||||
type: "Plantation",
|
||||
category: "1",
|
||||
quantity: 250,
|
||||
unit: "packets",
|
||||
lastUpdated: "2023-03-20",
|
||||
status: "In Stock",
|
||||
status: "2",
|
||||
},
|
||||
];
|
||||
}
|
||||
@ -108,7 +117,6 @@ export async function createInventoryItem(
|
||||
id: Math.floor(Math.random() * 1000),
|
||||
name: item.name,
|
||||
category: item.category,
|
||||
type: item.type,
|
||||
quantity: item.quantity,
|
||||
unit: item.unit,
|
||||
lastUpdated: new Date().toISOString(),
|
||||
|
||||
@ -33,6 +33,7 @@ import {
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { InventoryItemStatus, InventoryItemCategory } from "@/types";
|
||||
// import { updateInventoryItem } from "@/api/inventory";
|
||||
// import type { UpdateInventoryItemInput } from "@/types";
|
||||
|
||||
@ -41,9 +42,10 @@ export interface EditInventoryItemProps {
|
||||
name: string;
|
||||
category: string;
|
||||
status: string;
|
||||
type: string;
|
||||
unit: string;
|
||||
quantity: number;
|
||||
fetchedInventoryStatus: InventoryItemStatus[];
|
||||
fetchedInventoryCategory: InventoryItemCategory[];
|
||||
}
|
||||
|
||||
export function EditInventoryItem({
|
||||
@ -51,13 +53,13 @@ export function EditInventoryItem({
|
||||
name,
|
||||
category,
|
||||
status,
|
||||
type,
|
||||
unit,
|
||||
quantity,
|
||||
fetchedInventoryStatus,
|
||||
fetchedInventoryCategory,
|
||||
}: EditInventoryItemProps) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [itemName, setItemName] = useState(name);
|
||||
const [itemType, setItemType] = useState(type);
|
||||
const [itemCategory, setItemCategory] = useState(category);
|
||||
const [itemQuantity, setItemQuantity] = useState(quantity);
|
||||
const [itemUnit, setItemUnit] = useState(unit);
|
||||
@ -119,17 +121,20 @@ export function EditInventoryItem({
|
||||
</div>
|
||||
<div className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor="type" className="text-right">
|
||||
Type
|
||||
Category
|
||||
</Label>
|
||||
<Select value={itemType.toLowerCase()} onValueChange={setItemType}>
|
||||
<Select value={itemCategory} onValueChange={setItemCategory}>
|
||||
<SelectTrigger className="col-span-3">
|
||||
<SelectValue placeholder="Select type" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectLabel>Type</SelectLabel>
|
||||
<SelectItem value="plantation">Plantation</SelectItem>
|
||||
<SelectItem value="fertilizer">Fertilizer</SelectItem>
|
||||
<SelectLabel>Category</SelectLabel>
|
||||
{fetchedInventoryCategory.map((categoryItem, _) => (
|
||||
<SelectItem key={categoryItem.id} value={categoryItem.name}>
|
||||
{categoryItem.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
@ -138,35 +143,22 @@ export function EditInventoryItem({
|
||||
<Label htmlFor="type" className="text-right">
|
||||
Status
|
||||
</Label>
|
||||
<Select
|
||||
value={itemStatus.toLowerCase()}
|
||||
onValueChange={setItemStatus}
|
||||
>
|
||||
<Select value={itemStatus} onValueChange={setItemStatus}>
|
||||
<SelectTrigger className="col-span-3">
|
||||
<SelectValue placeholder="Select status" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectLabel>Status</SelectLabel>
|
||||
<SelectItem value="in stock">In Stock</SelectItem>
|
||||
<SelectItem value="low stock">Low Stock</SelectItem>
|
||||
<SelectItem value="out of stock">Out Of Stock</SelectItem>
|
||||
{fetchedInventoryStatus.map((statusItem, _) => (
|
||||
<SelectItem key={statusItem.id} value={statusItem.name}>
|
||||
{statusItem.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor="category" className="text-right">
|
||||
Category
|
||||
</Label>
|
||||
<Input
|
||||
id="category"
|
||||
className="col-span-3"
|
||||
placeholder="e.g., Seeds, Organic"
|
||||
value={itemCategory}
|
||||
onChange={(e) => setItemCategory(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor="quantity" className="text-right">
|
||||
Quantity
|
||||
|
||||
@ -31,7 +31,11 @@ import { Search } from "lucide-react";
|
||||
import { FaSort, FaSortUp, FaSortDown } from "react-icons/fa";
|
||||
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { fetchInventoryItems, fetchInventoryStatus } from "@/api/inventory";
|
||||
import {
|
||||
fetchInventoryItems,
|
||||
fetchInventoryStatus,
|
||||
fetchInventoryCategory,
|
||||
} from "@/api/inventory";
|
||||
import { AddInventoryItem } from "./add-inventory-item";
|
||||
import {
|
||||
EditInventoryItem,
|
||||
@ -65,14 +69,33 @@ export default function InventoryPage() {
|
||||
queryFn: fetchInventoryStatus,
|
||||
staleTime: 60 * 1000,
|
||||
});
|
||||
const {
|
||||
data: inventoryCategory = [],
|
||||
isLoading: isLoadingCategory,
|
||||
isError: isErrorCategory,
|
||||
} = useQuery({
|
||||
queryKey: ["inventoryCategory"],
|
||||
queryFn: fetchInventoryCategory,
|
||||
staleTime: 60 * 1000,
|
||||
});
|
||||
// console.table(inventoryItems);
|
||||
console.table(inventoryStatus);
|
||||
// console.table(inventoryStatus);
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const filteredItems = useMemo(() => {
|
||||
return inventoryItems
|
||||
.map((item) => ({
|
||||
...item,
|
||||
id: String(item.id), // Convert `id` to string here
|
||||
status:
|
||||
inventoryStatus.find(
|
||||
(statusItem) => statusItem.id.toString() === item.status
|
||||
)?.name || "",
|
||||
category:
|
||||
inventoryCategory.find(
|
||||
(categoryItem) => categoryItem.id.toString() === item.category
|
||||
)?.name || "",
|
||||
fetchedInventoryStatus: inventoryStatus,
|
||||
fetchedInventoryCategory: inventoryCategory,
|
||||
id: String(item.id),
|
||||
}))
|
||||
.filter((item) =>
|
||||
item.name.toLowerCase().includes(searchTerm.toLowerCase())
|
||||
@ -110,7 +133,11 @@ export default function InventoryPage() {
|
||||
accessorKey: "edit",
|
||||
header: "Edit",
|
||||
cell: ({ row }: { row: { original: EditInventoryItemProps } }) => (
|
||||
<EditInventoryItem {...row.original} />
|
||||
<EditInventoryItem
|
||||
{...row.original}
|
||||
fetchedInventoryStatus={inventoryStatus}
|
||||
fetchedInventoryCategory={inventoryCategory}
|
||||
/>
|
||||
),
|
||||
enableSorting: false,
|
||||
},
|
||||
@ -133,13 +160,13 @@ export default function InventoryPage() {
|
||||
onPaginationChange: setPagination,
|
||||
});
|
||||
|
||||
if (isItemLoading || isLoadingStatus)
|
||||
if (isItemLoading || isLoadingStatus || isLoadingCategory)
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center">
|
||||
Loading...
|
||||
</div>
|
||||
);
|
||||
if (isItemError || isErrorStatus)
|
||||
if (isItemError || isErrorStatus || isErrorCategory)
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center">
|
||||
Error loading inventory data.
|
||||
|
||||
@ -63,7 +63,6 @@ export type InventoryItem = {
|
||||
id: number;
|
||||
name: string;
|
||||
category: string;
|
||||
type: string;
|
||||
quantity: number;
|
||||
unit: string;
|
||||
lastUpdated: string;
|
||||
@ -74,7 +73,15 @@ export type InventoryItemStatus = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type CreateInventoryItemInput = Omit<InventoryItem, "id" | "lastUpdated" | "status">;
|
||||
export type InventoryItemCategory = {
|
||||
id: number;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type CreateInventoryItemInput = Omit<
|
||||
InventoryItem,
|
||||
"id" | "lastUpdated" | "status"
|
||||
>;
|
||||
|
||||
export interface Blog {
|
||||
id: number;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user