Merge branch 'OnFieldWork_V1' of https://git.marcoaiot.com/admin/marco.pms.web into OnFieldWork_V1
This commit is contained in:
commit
b53e6284b9
@ -71,10 +71,10 @@ const { labels, series, total } = useMemo(() => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="card-header d-flex justify-content-between align-items-center ">
|
<div className="card-header d-flex justify-content-between mt-2 align-items-center ">
|
||||||
<div>
|
<div>
|
||||||
<h5 className="mb-1 card-title">Expense Breakdown</h5>
|
<h5 className="mb-1 fw-bold text-start">Expense Breakdown</h5>
|
||||||
<p className="card-subtitle me-3">Detailed project expenses</p>
|
<p className="card-subtitle">Category Wise Expense Breakdown</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-end">
|
<div className="text-end">
|
||||||
|
@ -108,6 +108,23 @@ const ExpenseByProject = () => {
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Range Buttons + Expense Dropdown */}
|
||||||
|
<div className="d-flex align-items-center flex-wrap">
|
||||||
|
{["1M", "3M", "6M", "12M", "All"].map((item) => (
|
||||||
|
<button
|
||||||
|
key={item}
|
||||||
|
className={`border-0 px-2 py-1 text-sm rounded ${range === item
|
||||||
|
? "text-white bg-primary"
|
||||||
|
: "text-body bg-transparent"
|
||||||
|
}`}
|
||||||
|
style={{ cursor: "pointer", transition: "all 0.2s ease" }}
|
||||||
|
onClick={() => setRange(item)}
|
||||||
|
>
|
||||||
|
{item}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
{viewMode === "Category" && (
|
{viewMode === "Category" && (
|
||||||
<select
|
<select
|
||||||
className="form-select form-select-sm ms-auto mb-3"
|
className="form-select form-select-sm ms-auto mb-3"
|
||||||
@ -126,22 +143,6 @@ const ExpenseByProject = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Range Buttons + Expense Dropdown */}
|
|
||||||
<div className="d-flex gap-2 align-items-center flex-wrap">
|
|
||||||
{["1M", "3M", "6M", "12M", "All"].map((item) => (
|
|
||||||
<button
|
|
||||||
key={item}
|
|
||||||
className={`border-0 px-2 py-1 text-sm rounded ${range === item
|
|
||||||
? "text-white bg-primary"
|
|
||||||
: "text-body bg-transparent"
|
|
||||||
}`}
|
|
||||||
style={{ cursor: "pointer", transition: "all 0.2s ease" }}
|
|
||||||
onClick={() => setRange(item)}
|
|
||||||
>
|
|
||||||
{item}
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Chart */}
|
{/* Chart */}
|
||||||
|
@ -46,6 +46,7 @@ const ExpenseFilterPanel = ({ onApply, handleGroupBy }) => {
|
|||||||
projectIds: project ? [project] : defaultFilter.projectIds || [],
|
projectIds: project ? [project] : defaultFilter.projectIds || [],
|
||||||
createdByIds: defaultFilter.createdByIds || [],
|
createdByIds: defaultFilter.createdByIds || [],
|
||||||
paidById: defaultFilter.paidById || [],
|
paidById: defaultFilter.paidById || [],
|
||||||
|
ExpenseTypeIds: defaultFilter.ExpenseTypeIds || [],
|
||||||
isTransactionDate: defaultFilter.isTransactionDate ?? true,
|
isTransactionDate: defaultFilter.isTransactionDate ?? true,
|
||||||
startDate: defaultFilter.startDate,
|
startDate: defaultFilter.startDate,
|
||||||
endDate: defaultFilter.endDate,
|
endDate: defaultFilter.endDate,
|
||||||
@ -106,8 +107,8 @@ const ExpenseFilterPanel = ({ onApply, handleGroupBy }) => {
|
|||||||
...dynamicDefaultFilter,
|
...dynamicDefaultFilter,
|
||||||
startDate: dynamicDefaultFilter.startDate
|
startDate: dynamicDefaultFilter.startDate
|
||||||
? moment
|
? moment
|
||||||
.utc(dynamicDefaultFilter.startDate, "DD-MM-YYYY")
|
.utc(dynamicDefaultFilter.startDate, "DD-MM-YYYY")
|
||||||
.toISOString()
|
.toISOString()
|
||||||
: undefined,
|
: undefined,
|
||||||
endDate: dynamicDefaultFilter.endDate
|
endDate: dynamicDefaultFilter.endDate
|
||||||
? moment.utc(dynamicDefaultFilter.endDate, "DD-MM-YYYY").toISOString()
|
? moment.utc(dynamicDefaultFilter.endDate, "DD-MM-YYYY").toISOString()
|
||||||
@ -143,18 +144,16 @@ const ExpenseFilterPanel = ({ onApply, handleGroupBy }) => {
|
|||||||
<div className="d-inline-flex border rounded-pill mb-1 overflow-hidden shadow-none">
|
<div className="d-inline-flex border rounded-pill mb-1 overflow-hidden shadow-none">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`btn px-2 py-1 rounded-0 text-tiny ${
|
className={`btn px-2 py-1 rounded-0 text-tiny ${isTransactionDate ? "active btn-primary text-white" : ""
|
||||||
isTransactionDate ? "active btn-primary text-white" : ""
|
}`}
|
||||||
}`}
|
|
||||||
onClick={() => setValue("isTransactionDate", true)}
|
onClick={() => setValue("isTransactionDate", true)}
|
||||||
>
|
>
|
||||||
Transaction Date
|
Transaction Date
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`btn px-2 py-1 rounded-0 text-tiny ${
|
className={`btn px-2 py-1 rounded-0 text-tiny ${!isTransactionDate ? "active btn-primary text-white" : ""
|
||||||
!isTransactionDate ? "active btn-primary text-white" : ""
|
}`}
|
||||||
}`}
|
|
||||||
onClick={() => setValue("isTransactionDate", false)}
|
onClick={() => setValue("isTransactionDate", false)}
|
||||||
>
|
>
|
||||||
Submitted Date
|
Submitted Date
|
||||||
@ -194,6 +193,13 @@ const ExpenseFilterPanel = ({ onApply, handleGroupBy }) => {
|
|||||||
labelKey={(item) => item.name}
|
labelKey={(item) => item.name}
|
||||||
valueKey="id"
|
valueKey="id"
|
||||||
/>
|
/>
|
||||||
|
<SelectMultiple
|
||||||
|
name="ExpenseTypeIds"
|
||||||
|
label="Category :"
|
||||||
|
options={data.expensesType}
|
||||||
|
labelKey={(item) => item.name}
|
||||||
|
valueKey="id"
|
||||||
|
/>
|
||||||
|
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label className="form-label">Status :</label>
|
<label className="form-label">Status :</label>
|
||||||
|
@ -159,6 +159,7 @@ export const SearchSchema = z.object({
|
|||||||
statusIds: z.array(z.string()).optional(),
|
statusIds: z.array(z.string()).optional(),
|
||||||
createdByIds: z.array(z.string()).optional(),
|
createdByIds: z.array(z.string()).optional(),
|
||||||
paidById: z.array(z.string()).optional(),
|
paidById: z.array(z.string()).optional(),
|
||||||
|
ExpenseTypeIds: z.array(z.string()).optional(),
|
||||||
startDate: z.string().optional(),
|
startDate: z.string().optional(),
|
||||||
endDate: z.string().optional(),
|
endDate: z.string().optional(),
|
||||||
isTransactionDate: z.boolean().default(true),
|
isTransactionDate: z.boolean().default(true),
|
||||||
@ -169,6 +170,7 @@ export const defaultFilter = {
|
|||||||
statusIds: [],
|
statusIds: [],
|
||||||
createdByIds: [],
|
createdByIds: [],
|
||||||
paidById: [],
|
paidById: [],
|
||||||
|
ExpenseTypeIds: [],
|
||||||
isTransactionDate: true,
|
isTransactionDate: true,
|
||||||
startDate: null,
|
startDate: null,
|
||||||
endDate: null,
|
endDate: null,
|
||||||
|
@ -10,7 +10,7 @@ import moment from "moment";
|
|||||||
const cleanFilter = (filter) => {
|
const cleanFilter = (filter) => {
|
||||||
const cleaned = { ...filter };
|
const cleaned = { ...filter };
|
||||||
|
|
||||||
["projectIds", "statusIds", "createdByIds", "paidById"].forEach((key) => {
|
["projectIds", "statusIds", "createdByIds", "paidById","ExpenseTypeIds"].forEach((key) => {
|
||||||
if (Array.isArray(cleaned[key]) && cleaned[key].length === 0) {
|
if (Array.isArray(cleaned[key]) && cleaned[key].length === 0) {
|
||||||
delete cleaned[key];
|
delete cleaned[key];
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user