diff --git a/src/components/Expenses/CreateExpense.jsx b/src/components/Expenses/CreateExpense.jsx
new file mode 100644
index 00000000..927269a9
--- /dev/null
+++ b/src/components/Expenses/CreateExpense.jsx
@@ -0,0 +1,128 @@
+import { zodResolver } from "@hookform/resolvers/zod";
+import React from "react";
+import { useForm } from "react-hook-form";
+import { ExpenseSchema } from "./ExpenseSchema";
+
+const CreateExpense = () => {
+ const {} = useForm({
+ resolver: zodResolver(ExpenseSchema),
+ defaultValues: {
+ projectId: "",
+ expensesTypeId: "",
+ paymentModeId: "",
+ paidById: "",
+ transactionDate: "",
+ transactionId: "",
+ description: "",
+ location: "",
+ supplerName: "",
+ amount: "",
+ noOfPersons: "",
+ statusId: "",
+ billAttachments: [],
+ },
+ });
+ return (
+
+
+ );
+};
+
+export default CreateExpense;
diff --git a/src/components/Expenses/ExpenseList.jsx b/src/components/Expenses/ExpenseList.jsx
new file mode 100644
index 00000000..8fc54a7e
--- /dev/null
+++ b/src/components/Expenses/ExpenseList.jsx
@@ -0,0 +1,98 @@
+import React from 'react'
+
+const ExpenseList = () => {
+ return (
+
+
+
+
+
+
+
+ |
+ Date
+ |
+
+ Expense Type
+ |
+
+ Payment mode
+ |
+
+ Paid By
+ |
+
+
+ Status
+ |
+
+ Amount
+ |
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default ExpenseList
\ No newline at end of file
diff --git a/src/components/Expenses/ExpenseSchema.js b/src/components/Expenses/ExpenseSchema.js
new file mode 100644
index 00000000..1b5f4bb1
--- /dev/null
+++ b/src/components/Expenses/ExpenseSchema.js
@@ -0,0 +1,66 @@
+import { z } from 'zod';
+
+const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
+const ALLOWED_TYPES = [
+ 'application/pdf',
+ 'image/png',
+ 'image/jpg',
+ 'image/jpeg',
+];
+
+export const ExpenseSchema = z.object({
+ projectId: z.string().min(1, { message: "Project is required" }),
+ expensesTypeId: z.string().min(1, { message: "Expense type is required" }),
+ paymentModeId: z.string().min(1, { message: "Payment mode is required" }),
+ paidById: z.string().min(1, { message: "Employee name is required" }),
+ transactionDate: z.string().min(1, { message: "Date is required" }),
+ transactionId: z.string().optional(), // if optional, else use .min(1)
+ description: z.string().min(1, { message: "Description is required" }),
+ location: z.string().min(1, { message: "Location is required" }),
+ supplerName: z.string().min(1, { message: "Supplier name is required" }),
+ amount: z.number().min(1, { message: "Amount must be at least 1" }).max(10000, { message: "Amount must not exceed 10,000" }),
+ noOfPersons: z.number().min(1, { message: "1 Employee at least required" }),
+ statusId: z.string().min(1, { message: "Please select status" }),
+
+ billAttachments: z
+ .array(
+ z.object({
+ fileName: z.string().min(1, { message: "Filename is required" }),
+ base64Data: z.string().min(1, { message: "File data is required" }),
+ contentType: z.string().refine((val) => ALLOWED_TYPES.includes(val), {
+ message: "Only PDF, PNG, JPG, or JPEG files are allowed",
+ }),
+ fileSize: z.number().max(MAX_FILE_SIZE, {
+ message: "File size must be less than or equal to 5MB",
+ }),
+ description: z.string().optional(),
+ })
+ )
+ .nonempty({ message: "At least one file attachment is required" }),
+});
+
+
+let payload=
+{
+"projectId": "2618f2ef-2823-11f0-9d9e-bc241163f504",
+"expensesTypeId": "dd120bc4-ab0a-45ba-8450-5cd45ff221ca",
+"paymentModeId": "ed667353-8eea-4fd1-8750-719405932480",
+"paidById": "08dda7d8-014e-443f-858d-a55f4b484bc4",
+"transactionDate": "2025-07-12T09:56:54.122Z",
+"transactionId": "string",
+"description": "string",
+"location": "string",
+"supplerName": "string",
+"amount": 390,
+"noOfPersons": 0,
+"statusId": "297e0d8f-f668-41b5-bfea-e03b354251c8",
+"billAttachments": [
+{
+"fileName": "string",
+"base64Data": "string",
+"contentType": "string",
+"fileSize": 0,
+"description": "string"
+}
+]
+}
\ No newline at end of file
diff --git a/src/data/menuData.json b/src/data/menuData.json
index bbd37e2c..d4b2104d 100644
--- a/src/data/menuData.json
+++ b/src/data/menuData.json
@@ -66,6 +66,12 @@
"available": true,
"link": "/gallary"
},
+ {
+ "text": "Expense",
+ "icon": "bx bx-receipt",
+ "available": true,
+ "link": "/expenses"
+ },
{
"text": "Administration",
"icon": "bx bx-box",
diff --git a/src/hooks/useExpense.js b/src/hooks/useExpense.js
new file mode 100644
index 00000000..a2f72cc6
--- /dev/null
+++ b/src/hooks/useExpense.js
@@ -0,0 +1,30 @@
+import { useMutation } from "@tanstack/react-query"
+import ExpenseRepository from "../repositories/ExpsenseRepository"
+import showToast from "../services/toastService"
+
+
+
+// -------------------Query------------------------------------------------------
+export const useExpenseList = ()=>{
+
+}
+
+
+
+
+
+// ---------------------------Mutation---------------------------------------------
+
+export const useCreateExpnse =()=>{
+ return useMutation({
+ mutationFn:(payload)=>{
+ await ExpenseRepository.CreateExpense(payload)
+ },
+ onSuccess:(_,variables)=>{
+ showToast("Expense Created Successfully","success")
+ },
+ onError:(error)=>{
+ showToast(error.message || "Something went wrong please try again !","success")
+ }
+ })
+}
\ No newline at end of file
diff --git a/src/pages/Expense/ExpensePage.jsx b/src/pages/Expense/ExpensePage.jsx
new file mode 100644
index 00000000..136b2d2f
--- /dev/null
+++ b/src/pages/Expense/ExpensePage.jsx
@@ -0,0 +1,48 @@
+import React, { useState } from "react";
+import ExpenseList from "../../components/Expenses/ExpenseList";
+import Breadcrumb from "../../components/common/Breadcrumb";
+import GlobalModel from "../../components/common/GlobalModel";
+import CreateExpense from "../../components/Expenses/createExpense";
+
+const ExpensePage = () => {
+ const[IsNewExpen,setNewExpense] = useState(false)
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
setNewExpense(false)}>
+
+
+
+ );
+};
+
+export default ExpensePage;
diff --git a/src/repositories/ExpsenseRepository.jsx b/src/repositories/ExpsenseRepository.jsx
new file mode 100644
index 00000000..03199212
--- /dev/null
+++ b/src/repositories/ExpsenseRepository.jsx
@@ -0,0 +1,13 @@
+import { api } from "../utils/axiosClient";
+
+
+const ExpenseRepository = {
+ GetExpenseList:()=>api.get("/api/expanse/list"),
+ GetExpenseDetails:(id)=>api.get(`/api/Expanse/details/${id}`),
+ CreateExpense:(data)=>api.post("/api/Expanse/create",data),
+ UpdateExpense:(id)=>api.put(`/api/Expanse/edit/${id}`),
+ DeleteExpense:(id)=>api.delete(`/api/Expanse/edit/${id}`)
+
+}
+
+export default ExpenseRepository;
\ No newline at end of file
diff --git a/src/router/AppRoutes.jsx b/src/router/AppRoutes.jsx
index 5ce5b6d4..d89191d8 100644
--- a/src/router/AppRoutes.jsx
+++ b/src/router/AppRoutes.jsx
@@ -38,6 +38,7 @@ import LegalInfoCard from "../pages/TermsAndConditions/LegalInfoCard";
import ProtectedRoute from "./ProtectedRoute";
import Directory from "../pages/Directory/Directory";
import LoginWithOtp from "../pages/authentication/LoginWithOtp";
+import ExpensePage from "../pages/Expense/ExpensePage";
const router = createBrowserRouter(
[
@@ -76,6 +77,7 @@ const router = createBrowserRouter(
{ path: "/activities/task", element: },
{ path: "/activities/reports", element: },
{ path: "/gallary", element: },
+ { path: "/expenses", element: },
{ path: "/masters", element: },
{ path: "/help/support", element: },
{ path: "/help/docs", element: },