feat: Set up RTK query for the statemanagement

This commit is contained in:
2025-03-25 17:48:15 +05:30
parent 7e204690d3
commit 914501036d
70 changed files with 141275 additions and 205 deletions
+21 -16
View File
@@ -1,24 +1,29 @@
import { useEffect, useState } from "react";
import Td from "./Td";
import Loader from "./Loader";
import { useGetFarmsQuery } from "../store/api/farmApi";
const FarmList = () => {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch("http://localhost:8000/api/v1/farm", {
credentials: "include",
method: "GET",
headers: { "Content-Type": "application/json" },
})
.then((response) => response.json())
.then((data) => setData(data))
.then(setLoading(false))
.catch((error) => console.error(error));
}, []);
// const [data, setData] = useState([]);
// const [loading, setLoading] = useState(true);
const { data: farms, error, isLoading } = useGetFarmsQuery();
console.log(farms);
// useEffect(() => {
// fetch("http://localhost:8000/api/v1/farm", {
// credentials: "include",
// method: "GET",
// headers: { "Content-Type": "application/json" },
// })
// .then((response) => response.json())
// .then((data) => setData(data))
// .then(setLoading(false))
// .catch((error) => console.error(error));
// }, []);
return (
<div className="relative overflow-x-auto shadow-md sm:rounded-lg">
{loading ? (
{isLoading ? (
<Loader></Loader>
) : (
<table className="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
@@ -42,8 +47,8 @@ const FarmList = () => {
</tr>
</thead>
<tbody>
{data.length > 0 ? (
data.map((item) => <Td key={item.id} children={item} />)
{farms && farms.length > 0 ? (
farms.map((item) => <Td key={item.id} children={item} />)
) : (
<tr>
<td colSpan={5} className="text-center">
+1 -7
View File
@@ -41,13 +41,7 @@ export const HeroSecn = () => {
<button
type="button"
className="text-black w-auto max-w-lg bg-white hover:bg-purple-200 font-medium rounded-full text-sm py-2 px-4 text-center"
>
{isLoggedIn ? (
<Link to={"/user/dashboard"}>Start Managing Your Farm</Link>
) : (
<Link to={"/user/login"}>Log In</Link>
)}
</button>
></button>
</div>
<div className="w-full md:w-4/5 object-contain flex justify-center items-center">
<img
+1 -1
View File
@@ -112,7 +112,7 @@ const Testimonial = () => {
symptoms.
</p>
<a
href="/predict"
href="/ai"
className="inline-flex font-medium items-center text-blue-600 hover:underline"
>
Check Out
+14 -8
View File
@@ -1,4 +1,5 @@
import React, { useState } from "react";
import { useCreateCropMutation } from "../../../store/api/cropApi";
const AddCrop = ({ farmId }) => {
const [isModalOpen, setIsModalOpen] = useState(false);
@@ -12,6 +13,7 @@ const AddCrop = ({ farmId }) => {
const [uploading, setUploading] = useState(false);
const [error, setError] = useState("");
const [success, setSuccess] = useState("");
const [createCrop] = useCreateCropMutation();
const handleSubmit = async (e) => {
e.preventDefault();
@@ -30,14 +32,17 @@ const AddCrop = ({ farmId }) => {
}
console.log(formData);
try {
const response = await fetch(`http://localhost:8000/api/v1/crop`, {
method: "POST",
credentials: "include",
body: formData,
});
if (!response.ok) {
throw new Error("Failed to create crop");
}
const response = await createCrop(formData);
// const response = await fetch(`http://localhost:8000/api/v1/crop`, {
// method: "POST",
// credentials: "include",
// body: formData,
// });
// if (!response.ok) {
// throw new Error("Failed to create crop");
// }
console.log(response);
setSuccess("Crop created successfully!");
// Reset form fields
setName("");
@@ -46,6 +51,7 @@ const AddCrop = ({ farmId }) => {
setGrowthStage("");
setHealthStatus("");
setImage(null);
setIsModalOpen(false);
} catch (err) {
setError(err.message);
} finally {
+7 -15
View File
@@ -1,5 +1,6 @@
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useCreateFarmMutation } from "../../../store/api/farmApi";
const AddFarm = () => {
const [isModalOpen, setIsModalOpen] = useState(false);
@@ -11,6 +12,8 @@ const AddFarm = () => {
const [error, setError] = useState(null);
const [success, setSuccess] = useState(false);
const navigator = useNavigate();
const [createFarm] = useCreateFarmMutation();
const handleSubmit = async (e) => {
e.preventDefault();
const farmData = {
@@ -24,27 +27,16 @@ const AddFarm = () => {
console.log(farmData);
try {
const response = await fetch("http://localhost:8000/api/v1/farm", {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(farmData),
});
const res = await createFarm(farmData);
console.log(res);
const data = await response.json();
console.log(data);
if (!response.ok) {
throw new Error("Failed to add farm");
if (res.error) {
return null;
}
navigator("farmpage");
setSuccess(true);
setError(null);
setIsModalOpen(false);
window.location.reload();
} catch (err) {
setError(err.message);
setSuccess(false);
@@ -1,42 +1,52 @@
import React, { useState } from "react";
import Loader from "../../../components/Loader";
import { useAddTransactionMutation } from "../../../store/api/financeApi";
const AddTransaction = ({ farmId }) => {
const AddTransaction = ({ farmId, financeId }) => {
const [modalOpen, setModalOpen] = useState(false);
const [type, setType] = useState("Expense");
const [amount, setAmount] = useState("");
const [description, setDescription] = useState("");
const [loading, setLoading] = useState(false);
const [message, setMessage] = useState("");
const [addTransaction] = useAddTransactionMutation();
const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
setMessage("");
const transactionData = {
type,
amount: parseFloat(amount),
description,
};
console.log("Transaction data:", transactionData);
try {
const response = await fetch(
`http://localhost:8000/api/v1/finance/${farmId}/transaction`,
{
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
type,
amount: parseFloat(amount),
description,
}),
}
);
const response = await addTransaction({ financeId, transactionData });
// const response = await fetch(
// `http://localhost:8000/api/v1/finance/${farmId}/transaction`,
// {
// method: "POST",
// credentials: "include",
// headers: {
// "Content-Type": "application/json",
// },
// body: JSON.stringify({
// type,
// amount: parseFloat(amount),
// description,
// }),
// }
// );
if (!response.ok) {
throw new Error("Failed to create transaction");
}
// if (!response.ok) {
// throw new Error("Failed to create transaction");
// }
const data = await response.json();
console.log("Transaction created:", data);
// const data = await response.json();
console.log("Transaction created:", response);
setMessage("Transaction created successfully!");
// Optionally clear the form
setType("Expense");
@@ -1,24 +1,30 @@
import React, { useState } from "react";
import Loader from "../../../components/Loader";
import { useParams } from "react-router-dom";
import { useCreateFinanceMutation } from "../../../store/api/financeApi";
const CreateFinance = () => {
const [loading, setLoading] = useState(false);
const [message, setMessage] = useState("");
// Hardcoded farm ID from your example
const farmId = "67b9e6829c4979463e64a0fc";
const { farmId } = useParams();
const [createFinance] = useCreateFinanceMutation();
const handleCreateFinance = async () => {
setLoading(true);
setMessage("");
try {
const response = await fetch("http://localhost:8000/api/v1/finance", {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ farm: farmId }),
});
const responce = await createFinance({ farm: farmId });
// const response = await fetch("http://localhost:8000/api/v1/finance", {
// method: "POST",
// credentials: "include",
// headers: {
// "Content-Type": "application/json",
// },
// body: JSON.stringify({ farm: farmId }),
// });
console.log("Trance opdien ", responce);
if (!response.ok) {
throw new Error("Failed to create finance");
}
@@ -39,7 +45,7 @@ const CreateFinance = () => {
disabled={loading}
className="mt-4 w-30 inline-flex items-center justify-center px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500"
>
{loading ? <Loader></Loader> : "Create Finance"}
Create Finance
</button>
);
};
+16 -27
View File
@@ -1,10 +1,20 @@
import React, { useState, useEffect } from "react";
import Loader from "../../../components/Loader";
import { Link } from "react-router-dom";
import { useGetCropsByFarmQuery } from "../../../store/api/cropApi";
const CropTable = ({ farmId }) => {
const [crops, setCrops] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const {
data: cropsData,
error: cropsError,
isLoading: cropsLoading,
} = useGetCropsByFarmQuery(farmId);
console.log("Crops data is :", cropsData);
const handleRemoveCrop = async (cropId) => {
try {
await fetch(`http://localhost:8000/api/v1/crop/${cropId}`, {
@@ -19,34 +29,13 @@ const CropTable = ({ farmId }) => {
setError(err.message);
}
};
useEffect(() => {
const fetchCrops = async () => {
try {
const response = await fetch(
`http://localhost:8000/api/v1/crop/farm/${farmId}`,
{
credentials: "include",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to fetch crops");
}
const data = await response.json();
setCrops(data || []);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchCrops();
}, []);
if (cropsData) {
setCrops(cropsData);
setLoading(false);
}
}, [cropsData]);
if (loading) {
return <Loader></Loader>;
+13 -10
View File
@@ -1,23 +1,26 @@
import React, { useState } from "react";
import { useDeleteFarmMutation } from "../../../store/api/farmApi";
const EditFarm = ({ _id, onDelete }) => {
const [modalOpen, setModalOpen] = useState(false);
const [deleteFarm] = useDeleteFarmMutation();
// This function will run when the "Yes, I'm sure" button is clicked.
const handleDeleteFarm = async () => {
try {
const response = await fetch(`http://localhost:8000/api/v1/farm/${_id}`, {
method: "DELETE",
credentials: "include",
});
const data = await response.json();
console.log("Delete response:", data);
if (data.success) {
// Notify the parent component to update its state
if (onDelete) onDelete(_id);
const res = await deleteFarm(_id);
// const response = await fetch(`http://localhost:8000/api/v1/farm/${_id}`, {
// method: "DELETE",
// credentials: "include",
// });
// const data = await response.json();
console.log("Delete response:", res);
if (!res) {
return null;
}
setModalOpen(false); // Close the modal after the operation
window.location.reload();
} catch (error) {
console.error("Error deleting farm:", error);
}
+49 -35
View File
@@ -9,49 +9,63 @@ import AddTransaction from "./AddTransactions";
import FinanceSummary from "./FinanceSummary";
import CreateTask from "./CreateTask";
import DisplayTast from "./DisplayTask";
import { useGetFarmByIdQuery } from "../../../store/api/farmApi";
export default function FarmPage() {
const { farmId } = useParams();
const navigate = useNavigate();
const [farmData, setFarmData] = useState(null);
const [farmData, setFarmData] = useState("");
const [loading, setLoading] = useState(true);
console.log("Farm id is : ", farmId);
const { data: farm, error, isLoading } = useGetFarmByIdQuery(farmId);
useEffect(() => {
async function fetchFarmData() {
try {
const response = await fetch(
`http://localhost:8000/api/v1/farm/${farmId}`,
{
method: "GET",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
}
);
const jsonData = await response.json();
console.log("Fetched farm data:", jsonData);
setFarmData(jsonData);
} catch (error) {
console.error("Error fetching farm data: ", error);
} finally {
setLoading(false);
}
if (!isLoading && !error && farm) {
setFarmData(farm);
setLoading(false);
}
fetchFarmData();
}, [farmId]);
}, [farm]);
if (loading) {
return <Loader />;
}
console.log("djoejwrru9", farmData);
if (!farmData) {
return (
<div className="w-full bg-white rounded-lg shadow p-4">
<p>No farm data found.</p>
</div>
);
}
// useEffect(() => {
// async function fetchFarmData() {
// try {
// const response = await fetch(
// `http://localhost:8000/api/v1/farm/${farmId}`,
// {
// method: "GET",
// credentials: "include",
// headers: {
// "Content-Type": "application/json",
// },
// }
// );
// const jsonData = await response.json();
// console.log("Fetched farm data:", jsonData);
// setFarmData(jsonData);
// } catch (error) {
// console.error("Error fetching farm data: ", error);
// } finally {
// setLoading(false);
// }
// }
// fetchFarmData();
// }, [farmId]);
// if (loading) {
// return <Loader />;
// }
// if (!farmData) {
// return (
// <div className="w-full bg-white rounded-lg shadow p-4">
// <p>No farm data found.</p>
// </div>
// );
// }
return (
<div className="w-full bg-white rounded-lg shadow p-4 space-y-8">
@@ -82,14 +96,14 @@ export default function FarmPage() {
{/* Add Transaction Modal Section */}
<section>
<div className="flex justify-end">
<AddTransaction farmId={farmId} />
<AddTransaction farmId={farmId} financeId={farmData?.finances?._id} />
</div>
</section>
{/* Finance Summary Section */}
<section>
<div className="flex justify-end">
<FinanceSummary farmId={farmId} />
<FinanceSummary farmId={farmId} financeId={farmData?.finances?._id} />
</div>
</section>
@@ -1,7 +1,7 @@
import React, { useState, useEffect } from "react";
import Loader from "../../../components/Loader";
const FinanceSummary = ({ farmId }) => {
const FinanceSummary = ({ farmId, financeId }) => {
const [summary, setSummary] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState("");
@@ -12,9 +12,10 @@ const FinanceSummary = ({ farmId }) => {
setError("");
try {
const response = await fetch(
`http://localhost:8000/api/v1/finance/summary/${farmId}`,
`http://localhost:8000/api/v1/finance/summary/${financeId}`,
{ credentials: "include" }
);
console.log("Summary response:", response);
if (!response.ok) {
throw new Error("Failed to fetch summary");
}
@@ -30,45 +31,45 @@ const FinanceSummary = ({ farmId }) => {
fetchSummary();
}, [farmId]);
if (loading) return <Loader />;
if (error) return <div className="p-4 text-center text-red-600">{error}</div>;
// if (loading) return <Loader />;
//if (error) return <div className="p-4 text-center text-red-600">{error}</div>;
// Extract only the important fields.
const { totalExpenses, totalRevenue, transactions } = summary;
const { totalExpenses, totalRevenue, transactions } = summary || {};
const transactionsCount = Array.isArray(transactions)
? transactions.length
: 0;
return (
<div className="max-w-md mx-auto p-8 bg-gray-50">
<div className="w-full mx-auto p-8 bg-gray-50">
<div className="bg-white rounded-lg shadow overflow-hidden">
<header className="bg-blue-600 px-6 py-4">
<h2 className="text-3xl font-bold text-white">Finance Summary</h2>
<h2 className="text-3xl font-bold text-white">
Transactions Summary
</h2>
</header>
<div className="p-6">
<table className="w-full table-auto">
<tbody className="divide-y divide-gray-200">
<tr className="hover:bg-gray-50">
<td className="px-6 py-4 font-medium text-gray-600">
Total Expenses
</td>
<td className="px-6 py-4 text-gray-800">{totalExpenses}</td>
</tr>
<tr className="hover:bg-gray-50">
<td className="px-6 py-4 font-medium text-gray-600">
Total Revenue
</td>
<td className="px-6 py-4 text-gray-800">{totalRevenue}</td>
</tr>
<tr className="hover:bg-gray-50">
<td className="px-6 py-4 font-medium text-gray-600">
Transactions
</td>
<td className="px-6 py-4 text-gray-800">{transactionsCount}</td>
</tr>
</tbody>
</table>
</div>
<table className="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th scope="col" className="px-6 py-3">
Farm name
</th>
<th scope="col" className="px-6 py-3">
Location
</th>
<th scope="col" className="px-6 py-3">
Type
</th>
<th scope="col" className="px-6 py-3">
Size (acres)
</th>
<th scope="col" className="px-6 py-3">
Action
</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
);
@@ -31,34 +31,22 @@ const Transactions = ({ farmId }) => {
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th scope="col" className="px-6 py-3">
Field
Total Expenses
</th>
<th scope="col" className="px-6 py-3">
Value
totalRevenue
</th>
</tr>
</thead>
<tbody>
{!Array.isArray(data) ? (
// Data is an object: show key-value pairs
Object.entries(data).map(([key, value]) => (
<tr key={key}>
<td className="px-6 py-3 font-bold">{key}</td>
<td className="px-6 py-3">
{typeof value === "object" ? JSON.stringify(value) : value}
</td>
</tr>
))
) : // Data is an array: render using your Td component
data.length > 0 ? (
data.map((item) => <Td key={item.id} children={item} />)
) : (
<tr>
<td colSpan={2} className="text-center">
No data available
</td>
</tr>
)}
<tr>
<td className="px-6 py-3">
{data.totalExpenses ? data.totalExpenses : "N/A"}
</td>
<td className="px-6 py-3">
{data.totalRevenue ? data.totalRevenue : "N/A"}
</td>
</tr>
</tbody>
</table>
)}
@@ -243,9 +243,12 @@ const MainUserPanel = () => {
{user.address == null && "Maharashtra, Pune"}
</p>
<div className="flex justify-center mt-4">
<button className="bg-gray-300 hover:bg-gray-400 text-gray-700 font-bold py-2 px-4 rounded mr-2">
<Link
to="/"
className="bg-gray-300 hover:bg-gray-400 text-gray-700 font-bold py-2 px-4 rounded mr-2"
>
<FaHome className="text-lg font-extrabold" />
</button>
</Link>
<button className="bg-gray-300 hover:bg-gray-400 text-gray-700 font-bold py-2 px-4 rounded mr-2">
<IoMdSettings className="text-lg font-extrabold" />
</button>
+91
View File
@@ -0,0 +1,91 @@
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const cropApi = createApi({
reducerPath: "cropApi",
baseQuery: fetchBaseQuery({
baseUrl: "http://localhost:8000/api/v1/crop",
credentials: "include", // Ensures credentials (cookies, tokens) are included
}),
tagTypes: ["Crops"],
endpoints: (builder) => ({
getCropsByFarm: builder.query({
query: (farmId) => `/farm/${farmId}`,
providesTags: ["Crops"],
}),
getCropById: builder.query({
query: (cropId) => `/${cropId}`,
providesTags: (result, error, cropId) => [{ type: "Crops", id: cropId }],
}),
createCrop: builder.mutation({
query: (formData) => ({
url: "/",
method: "POST",
body: formData,
}),
invalidatesTags: ["Crops"],
}),
updateCrop: builder.mutation({
query: ({ cropId, updatedCrop }) => ({
url: `/${cropId}`,
method: "PUT",
body: updatedCrop,
}),
invalidatesTags: (result, error, { cropId }) => [
{ type: "Crops", id: cropId },
],
}),
deleteCrop: builder.mutation({
query: (cropId) => ({
url: `/${cropId}`,
method: "DELETE",
}),
invalidatesTags: ["Crops"],
}),
updateHealthStatus: builder.mutation({
query: ({ cropId, healthStatus }) => ({
url: `/health/${cropId}`,
method: "PUT",
body: { healthStatus },
}),
invalidatesTags: (result, error, { cropId }) => [
{ type: "Crops", id: cropId },
],
}),
updateGrowthStage: builder.mutation({
query: ({ cropId, growthStage }) => ({
url: `/growth/${cropId}`,
method: "PUT",
body: { growthStage },
}),
invalidatesTags: (result, error, { cropId }) => [
{ type: "Crops", id: cropId },
],
}),
cropHarvest: builder.query({
query: (cropId) => `/harvest/${cropId}`,
}),
suggestNextCrop: builder.query({
query: (cropId) => `/nextCrop/${cropId}`,
}),
suggestPesticides: builder.query({
query: (cropId) => `/pesticides/${cropId}`,
}),
suggestFertilizers: builder.query({
query: (cropId) => `/fertilizers/${cropId}`,
}),
}),
});
export const {
useGetCropsByFarmQuery,
useGetCropByIdQuery,
useCreateCropMutation,
useUpdateCropMutation,
useDeleteCropMutation,
useUpdateHealthStatusMutation,
useUpdateGrowthStageMutation,
useCropHarvestQuery,
useSuggestNextCropQuery,
useSuggestPesticidesQuery,
useSuggestFertilizersQuery,
} = cropApi;
+56
View File
@@ -0,0 +1,56 @@
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const farmApi = createApi({
reducerPath: "farmApi",
baseQuery: fetchBaseQuery({
baseUrl: "http://localhost:8000/api/v1/farm",
credentials: "include",
}),
tagTypes: ["Farms"],
endpoints: (builder) => ({
getFarms: builder.query({
query: () => "/",
providesTags: ["Farms"],
}),
getFarmById: builder.query({
query: (farmId) => `/${farmId}`,
providesTags: ["Farms"],
}),
createFarm: builder.mutation({
query: (newFarm) => ({
url: "/",
method: "POST",
body: newFarm,
credentials: "include",
}),
invalidatesTags: ["Farms"],
}),
updateFarm: builder.mutation({
query: ({ farmId, updatedFarm }) => ({
url: `/${farmId}`,
method: "PUT",
body: updatedFarm,
credentials: "include",
}),
invalidatesTags: (result, error, { farmId }) => [
{ type: "Farms", id: farmId },
],
}),
deleteFarm: builder.mutation({
query: (farmId) => ({
url: `/${farmId}`,
method: "DELETE",
credentials: "include",
}),
invalidatesTags: ["Farms"],
}),
}),
});
export const {
useGetFarmsQuery,
useGetFarmByIdQuery,
useCreateFarmMutation,
useUpdateFarmMutation,
useDeleteFarmMutation,
} = farmApi;
+56
View File
@@ -0,0 +1,56 @@
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const financeApi = createApi({
reducerPath: "financeApi",
baseQuery: fetchBaseQuery({
baseUrl: "http://localhost:8000/api/v1/finance",
credentials: "include",
}),
tagTypes: ["Finance", "Transactions"],
endpoints: (builder) => ({
getFinanceByFarm: builder.query({
query: (farmId) => `/${farmId}`,
providesTags: ["Finance"],
}),
getTransactions: builder.query({
query: (financeId) => `/transactions/${financeId}`,
providesTags: ["Transactions"],
}),
getFinancialSummary: builder.query({
query: (financeId) => `/summary/${financeId}`,
providesTags: ["Finance"],
}),
createFinance: builder.mutation({
query: (financeData) => ({
url: "/",
method: "POST",
body: financeData,
}),
invalidatesTags: ["Finance"],
}),
deleteTransaction: builder.mutation({
query: (financeId) => ({
url: `/${financeId}`,
method: "DELETE",
}),
invalidatesTags: ["Transactions", "Finance"],
}),
addTransaction: builder.mutation({
query: ({ financeId, transactionData }) => ({
url: `/${financeId}/transaction`,
method: "POST",
body: transactionData,
}),
invalidatesTags: ["Transactions", "Finance"],
}),
}),
});
export const {
useGetFinanceByFarmQuery,
useGetTransactionsQuery,
useGetFinancialSummaryQuery,
useCreateFinanceMutation,
useDeleteTransactionMutation,
useAddTransactionMutation,
} = financeApi;
+64
View File
@@ -0,0 +1,64 @@
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const taskApi = createApi({
reducerPath: "taskApi",
baseQuery: fetchBaseQuery({
baseUrl: "http://localhost:8000/api/v1/task",
credentials: "include",
}),
tagTypes: ["Tasks"],
endpoints: (builder) => ({
getTasksByFarm: builder.query({
query: (farmId) => `/farm/${farmId}`,
providesTags: ["Tasks"],
}),
getTaskById: builder.query({
query: (taskId) => `/${taskId}`,
providesTags: (result, error, taskId) => [{ type: "Tasks", id: taskId }],
}),
createTask: builder.mutation({
query: (taskData) => ({
url: "/",
method: "POST",
body: taskData,
}),
invalidatesTags: ["Tasks"],
}),
updateTask: builder.mutation({
query: ({ taskId, updatedTask }) => ({
url: `/${taskId}`,
method: "PUT",
body: updatedTask,
}),
invalidatesTags: (result, error, { taskId }) => [
{ type: "Tasks", id: taskId },
],
}),
updateTaskStatus: builder.mutation({
query: ({ taskId, status }) => ({
url: `/${taskId}/status`,
method: "PATCH",
body: { status },
}),
invalidatesTags: (result, error, { taskId }) => [
{ type: "Tasks", id: taskId },
],
}),
deleteTask: builder.mutation({
query: (taskId) => ({
url: `/${taskId}`,
method: "DELETE",
}),
invalidatesTags: ["Tasks"],
}),
}),
});
export const {
useGetTasksByFarmQuery,
useGetTaskByIdQuery,
useCreateTaskMutation,
useUpdateTaskMutation,
useUpdateTaskStatusMutation,
useDeleteTaskMutation,
} = taskApi;
+14
View File
@@ -2,13 +2,27 @@ import { configureStore } from "@reduxjs/toolkit";
import userSlice from "./userSlice";
import messageSlice from "./messageSlice";
import loaderSlice from "./loaderSlice";
import { farmApi } from "./api/farmApi";
import { cropApi } from "./api/cropApi";
import { financeApi } from "./api/financeApi";
import { taskApi } from "./api/taskApi";
const MentifyStore = configureStore({
reducer: {
user: userSlice.reducer,
messages: messageSlice.reducer,
loader: loaderSlice.reducer,
[farmApi.reducerPath]: farmApi.reducer,
[cropApi.reducerPath]: cropApi.reducer,
[financeApi.reducerPath]: financeApi.reducer,
[taskApi.reducerPath]: taskApi.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware()
.concat(farmApi.middleware)
.concat(cropApi.middleware)
.concat(financeApi.middleware)
.concat(taskApi.middleware), // Add API middleware
});
export default MentifyStore;