mirror of
https://github.com/ForFarmTeam/ForFarm.git
synced 2025-12-18 21:44:08 +01:00
feat: add fetchHarvestUnits API and integrate into inventory management
This commit is contained in:
parent
ba8f754d8d
commit
bfeda8ce13
12
frontend/api/harvest.ts
Normal file
12
frontend/api/harvest.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import axiosInstance from "./config";
|
||||
import type { HarvestUnits } from "@/types";
|
||||
|
||||
export async function fetchHarvestUnits(): Promise<HarvestUnits[]> {
|
||||
try {
|
||||
const response = await axiosInstance.get<HarvestUnits[]>("/harvest/units");
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error("Error fetching inventory status:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
import axiosInstance from "./config";
|
||||
import type {
|
||||
InventoryItem,
|
||||
CreateInventoryItemInput,
|
||||
InventoryItemStatus,
|
||||
InventoryItemCategory,
|
||||
} from "@/types";
|
||||
@ -50,7 +49,7 @@ export async function fetchInventoryItems(): Promise<InventoryItem[]> {
|
||||
name: "Tomato Seeds",
|
||||
category: "1",
|
||||
quantity: 500,
|
||||
unit: "packets",
|
||||
unit: "1",
|
||||
lastUpdated: "2023-03-01",
|
||||
status: "1",
|
||||
},
|
||||
@ -59,7 +58,7 @@ export async function fetchInventoryItems(): Promise<InventoryItem[]> {
|
||||
name: "NPK Fertilizer",
|
||||
category: "3",
|
||||
quantity: 200,
|
||||
unit: "kg",
|
||||
unit: "2",
|
||||
lastUpdated: "2023-03-05",
|
||||
status: "2",
|
||||
},
|
||||
@ -68,7 +67,7 @@ export async function fetchInventoryItems(): Promise<InventoryItem[]> {
|
||||
name: "Corn Seeds",
|
||||
category: "1",
|
||||
quantity: 300,
|
||||
unit: "packets",
|
||||
unit: "1",
|
||||
lastUpdated: "2023-03-10",
|
||||
status: "3",
|
||||
},
|
||||
@ -77,7 +76,7 @@ export async function fetchInventoryItems(): Promise<InventoryItem[]> {
|
||||
name: "Organic Compost",
|
||||
category: "3",
|
||||
quantity: 150,
|
||||
unit: "kg",
|
||||
unit: "2",
|
||||
lastUpdated: "2023-03-15",
|
||||
status: "1",
|
||||
},
|
||||
@ -86,7 +85,7 @@ export async function fetchInventoryItems(): Promise<InventoryItem[]> {
|
||||
name: "Wheat Seeds",
|
||||
category: "1",
|
||||
quantity: 250,
|
||||
unit: "packets",
|
||||
unit: "2",
|
||||
lastUpdated: "2023-03-20",
|
||||
status: "2",
|
||||
},
|
||||
|
||||
@ -18,11 +18,6 @@ import {
|
||||
} from "@/components/ui/dialog";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
@ -32,8 +27,11 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { InventoryItemStatus, InventoryItemCategory } from "@/types";
|
||||
import {
|
||||
InventoryItemStatus,
|
||||
InventoryItemCategory,
|
||||
HarvestUnits,
|
||||
} from "@/types";
|
||||
// import { updateInventoryItem } from "@/api/inventory";
|
||||
// import type { UpdateInventoryItemInput } from "@/types";
|
||||
|
||||
@ -46,6 +44,7 @@ export interface EditInventoryItemProps {
|
||||
quantity: number;
|
||||
fetchedInventoryStatus: InventoryItemStatus[];
|
||||
fetchedInventoryCategory: InventoryItemCategory[];
|
||||
fetchedHarvestUnits: HarvestUnits[];
|
||||
}
|
||||
|
||||
export function EditInventoryItem({
|
||||
@ -57,6 +56,7 @@ export function EditInventoryItem({
|
||||
quantity,
|
||||
fetchedInventoryStatus,
|
||||
fetchedInventoryCategory,
|
||||
fetchedHarvestUnits,
|
||||
}: EditInventoryItemProps) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [itemName, setItemName] = useState(name);
|
||||
@ -172,16 +172,24 @@ export function EditInventoryItem({
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor="unit" className="text-right">
|
||||
<Label htmlFor="type" className="text-right">
|
||||
Unit
|
||||
</Label>
|
||||
<Input
|
||||
id="unit"
|
||||
className="col-span-3"
|
||||
placeholder="e.g., kg, packets"
|
||||
value={itemUnit}
|
||||
onChange={(e) => setItemUnit(e.target.value)}
|
||||
/>
|
||||
<Select value={itemUnit} onValueChange={setItemUnit}>
|
||||
<SelectTrigger className="col-span-3">
|
||||
<SelectValue placeholder="Select status" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectLabel>Unit</SelectLabel>
|
||||
{fetchedHarvestUnits.map((unit, _) => (
|
||||
<SelectItem key={unit.id} value={unit.name}>
|
||||
{unit.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
|
||||
@ -29,6 +29,7 @@ import {
|
||||
} from "@/components/ui/pagination";
|
||||
import { Search } from "lucide-react";
|
||||
import { FaSort, FaSortUp, FaSortDown } from "react-icons/fa";
|
||||
import { fetchHarvestUnits } from "@/api/harvest";
|
||||
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import {
|
||||
@ -49,7 +50,8 @@ export default function InventoryPage() {
|
||||
pageIndex: 0,
|
||||
pageSize: 10,
|
||||
});
|
||||
|
||||
//////////////////////////////
|
||||
// query the necessary data for edit and etc.
|
||||
const {
|
||||
data: inventoryItems = [],
|
||||
isLoading: isItemLoading,
|
||||
@ -78,6 +80,16 @@ export default function InventoryPage() {
|
||||
queryFn: fetchInventoryCategory,
|
||||
staleTime: 60 * 1000,
|
||||
});
|
||||
const {
|
||||
data: harvestUnits = [],
|
||||
isLoading: isLoadingHarvestUnits,
|
||||
isError: isErrorHarvestUnits,
|
||||
} = useQuery({
|
||||
queryKey: ["harvestUnits"],
|
||||
queryFn: fetchHarvestUnits,
|
||||
staleTime: 60 * 1000,
|
||||
});
|
||||
//////////////////////////////
|
||||
// console.table(inventoryItems);
|
||||
// console.table(inventoryStatus);
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
@ -93,8 +105,12 @@ export default function InventoryPage() {
|
||||
inventoryCategory.find(
|
||||
(categoryItem) => categoryItem.id.toString() === item.category
|
||||
)?.name || "",
|
||||
unit:
|
||||
harvestUnits.find((unit) => unit.id.toString() === item.unit)?.name ||
|
||||
"",
|
||||
fetchedInventoryStatus: inventoryStatus,
|
||||
fetchedInventoryCategory: inventoryCategory,
|
||||
fetchedHarvestUnits: harvestUnits,
|
||||
id: String(item.id),
|
||||
}))
|
||||
.filter((item) =>
|
||||
@ -102,6 +118,8 @@ export default function InventoryPage() {
|
||||
);
|
||||
}, [inventoryItems, searchTerm]);
|
||||
|
||||
// prepare columns for table
|
||||
|
||||
const columns = [
|
||||
{ accessorKey: "name", header: "Name" },
|
||||
{ accessorKey: "category", header: "Category" },
|
||||
@ -159,14 +177,29 @@ export default function InventoryPage() {
|
||||
onSortingChange: setSorting,
|
||||
onPaginationChange: setPagination,
|
||||
});
|
||||
const loadingStates = [
|
||||
isItemLoading,
|
||||
isLoadingStatus,
|
||||
isLoadingCategory,
|
||||
isLoadingHarvestUnits,
|
||||
];
|
||||
const errorStates = [
|
||||
isItemError,
|
||||
isErrorStatus,
|
||||
isErrorCategory,
|
||||
isErrorHarvestUnits,
|
||||
];
|
||||
|
||||
if (isItemLoading || isLoadingStatus || isLoadingCategory)
|
||||
const isLoading = loadingStates.some((loading) => loading);
|
||||
const isError = errorStates.some((error) => error);
|
||||
|
||||
if (isLoading)
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center">
|
||||
Loading...
|
||||
</div>
|
||||
);
|
||||
if (isItemError || isErrorStatus || isErrorCategory)
|
||||
if (isError)
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center">
|
||||
Error loading inventory data.
|
||||
|
||||
@ -77,6 +77,10 @@ export type InventoryItemCategory = {
|
||||
id: number;
|
||||
name: string;
|
||||
};
|
||||
export type HarvestUnits = {
|
||||
id: number;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type CreateInventoryItemInput = Omit<
|
||||
InventoryItem,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user