Create a new Weidget for Expense in Dashboard. #449
@ -17,6 +17,7 @@ import AttendanceOverview from "./AttendanceOverview";
|
|||||||
import { useSelectedProject } from "../../slices/apiDataManager";
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
import { useProjectName } from "../../hooks/useProjects";
|
import { useProjectName } from "../../hooks/useProjects";
|
||||||
import ExpenseAnalysis from "./ExpenseAnalysis";
|
import ExpenseAnalysis from "./ExpenseAnalysis";
|
||||||
|
import ExpenseByProject from "./ExpenseByProject";
|
||||||
import ExpenseStatus from "./ExpenseStatus";
|
import ExpenseStatus from "./ExpenseStatus";
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Dashboard = () => {
|
||||||
@ -53,6 +54,9 @@ const Dashboard = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="col-xxl-6 col-lg-6">
|
||||||
|
<ExpenseByProject />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
164
src/components/Dashboard/ExpenseByProject.jsx
Normal file
164
src/components/Dashboard/ExpenseByProject.jsx
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import Chart from "react-apexcharts";
|
||||||
|
import { useExpenseType } from "../../hooks/masterHook/useMaster";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import { useExpenseDataByProject } from "../../hooks/useDashboard_Data";
|
||||||
|
import { formatCurrency } from "../../utils/appUtils";
|
||||||
|
import { formatDate_DayMonth } from "../../utils/dateUtils";
|
||||||
|
|
||||||
|
const ExpenseByProject = () => {
|
||||||
|
const projectId = useSelector((store) => store.localVariables.projectId);
|
||||||
|
const [range, setRange] = useState("12M");
|
||||||
|
const [selectedType, setSelectedType] = useState("");
|
||||||
|
const [viewMode, setViewMode] = useState("Category");
|
||||||
|
const [chartData, setChartData] = useState({ categories: [], data: [] });
|
||||||
|
|
||||||
|
const { ExpenseTypes, loading: typeLoading } = useExpenseType();
|
||||||
|
|
||||||
|
const { data: expenseApiData, isLoading } = useExpenseDataByProject(
|
||||||
|
projectId,
|
||||||
|
selectedType,
|
||||||
|
range === "All" ? null : parseInt(range)
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (expenseApiData) {
|
||||||
|
const categories = expenseApiData.map(
|
||||||
|
(item) => formatDate_DayMonth(item.monthName, item.year)
|
||||||
|
);
|
||||||
|
const data = expenseApiData.map((item) => item.total);
|
||||||
|
setChartData({ categories, data });
|
||||||
|
} else {
|
||||||
|
setChartData({ categories: [], data: [] });
|
||||||
|
}
|
||||||
|
}, [expenseApiData]);
|
||||||
|
|
||||||
|
const getSelectedTypeName = () => {
|
||||||
|
if (!selectedType) return "All Types";
|
||||||
|
const found = ExpenseTypes.find((t) => t.id === selectedType);
|
||||||
|
return found ? found.name : "All Types";
|
||||||
|
};
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
chart: { type: "bar", toolbar: { show: false } },
|
||||||
|
plotOptions: { bar: { horizontal: false, columnWidth: "55%", borderRadius: 4 } },
|
||||||
|
dataLabels: { enabled: true, formatter: (val) => formatCurrency(val) },
|
||||||
|
xaxis: {
|
||||||
|
categories: chartData.categories,
|
||||||
|
labels: { style: { fontSize: "12px" }, rotate: -45 },
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
y: {
|
||||||
|
formatter: (val) => `${formatCurrency(val)} (${getSelectedTypeName()})`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
annotations: { xaxis: [{ x: 0, strokeDashArray: 0, }] },
|
||||||
|
fill: { opacity: 1 },
|
||||||
|
colors: ["#2196f3"],
|
||||||
|
};
|
||||||
|
|
||||||
|
const series = [
|
||||||
|
{
|
||||||
|
name: getSelectedTypeName(),
|
||||||
|
data: chartData.data,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="card shadow-sm ">
|
||||||
|
{/* Header */}
|
||||||
|
<div className="card-header">
|
||||||
|
<div className="d-flex justify-content-start align-items-center mb-3 mt-3">
|
||||||
|
<div>
|
||||||
|
<h5 className="mb-1 me-6 fw-bold">Monthly Expense -</h5>
|
||||||
|
<p className="card-subtitle me-5 mb-0">Detailed project expenses</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* View Mode Dropdown → same style as Header */}
|
||||||
|
<div className="btn-group mb-4 ms-n8">
|
||||||
|
<button
|
||||||
|
className="btn btn-sm dropdown-toggle fs-5"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
{viewMode}
|
||||||
|
</button>
|
||||||
|
<ul className="dropdown-menu dropdown-menu-end ">
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
className="dropdown-item"
|
||||||
|
onClick={() => {
|
||||||
|
setViewMode("Category");
|
||||||
|
setSelectedType("");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Category
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
className="dropdown-item"
|
||||||
|
onClick={() => {
|
||||||
|
setViewMode("Project");
|
||||||
|
setSelectedType("");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Project
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{viewMode === "Category" && (
|
||||||
|
<select
|
||||||
|
className="form-select form-select-sm ms-auto mb-3"
|
||||||
|
value={selectedType}
|
||||||
|
onChange={(e) => setSelectedType(e.target.value)}
|
||||||
|
disabled={typeLoading}
|
||||||
|
style={{ maxWidth: "200px" }}
|
||||||
|
>
|
||||||
|
<option value="">All Types</option>
|
||||||
|
{ExpenseTypes.map((type) => (
|
||||||
|
<option key={type.id} value={type.id}>
|
||||||
|
{type.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
)}
|
||||||
|
</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>
|
||||||
|
|
||||||
|
{/* Chart */}
|
||||||
|
<div
|
||||||
|
className="card-body bg-white text-dark p-3"
|
||||||
|
style={{ minHeight: "440px" }}
|
||||||
|
>
|
||||||
|
{isLoading ? (
|
||||||
|
<p>Loading chart...</p>
|
||||||
|
) : (
|
||||||
|
<Chart options={options} series={series} type="bar" height={400} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ExpenseByProject;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { useCallback, useEffect, useState,useMemo } from "react";
|
import { useCallback, useEffect, useState, useMemo } from "react";
|
||||||
import getGreetingMessage from "../../utils/greetingHandler";
|
import getGreetingMessage from "../../utils/greetingHandler";
|
||||||
import {
|
import {
|
||||||
cacheData,
|
cacheData,
|
||||||
@ -22,7 +22,7 @@ import { ALLOW_PROJECTSTATUS_ID, MANAGE_PROJECT, UUID_REGEX } from "../../utils/
|
|||||||
import { useAuthModal, useLogout } from "../../hooks/useAuth";
|
import { useAuthModal, useLogout } from "../../hooks/useAuth";
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
const { profile } = useProfile();
|
const { profile } = useProfile();
|
||||||
const { data: masterData } = useMaster();
|
const { data: masterData } = useMaster();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@ -57,8 +57,8 @@ const Header = () => {
|
|||||||
isDashboardPath
|
isDashboardPath
|
||||||
? projectNames
|
? projectNames
|
||||||
: projectNames?.filter((project) =>
|
: projectNames?.filter((project) =>
|
||||||
ALLOW_PROJECTSTATUS_ID.includes(project.projectStatusId)
|
ALLOW_PROJECTSTATUS_ID.includes(project.projectStatusId)
|
||||||
),
|
),
|
||||||
[projectNames, isDashboardPath]
|
[projectNames, isDashboardPath]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -66,11 +66,11 @@ const Header = () => {
|
|||||||
if (projectLoading) return "Loading...";
|
if (projectLoading) return "Loading...";
|
||||||
if (!projectNames?.length) return "No Projects Assigned";
|
if (!projectNames?.length) return "No Projects Assigned";
|
||||||
if (projectNames.length === 1) return projectNames[0].name;
|
if (projectNames.length === 1) return projectNames[0].name;
|
||||||
if (selectedProject === null) return "All Projects";
|
if (selectedProject === null) return "All Projects";
|
||||||
const selectedObj = projectNames.find((p) => p.id === selectedProject);
|
const selectedObj = projectNames.find((p) => p.id === selectedProject);
|
||||||
return selectedObj
|
return selectedObj
|
||||||
? selectedObj.name
|
? selectedObj.name
|
||||||
: projectNames[0]?.name || "No Projects Assigned";
|
: projectNames[0]?.name || "No Projects Assigned";
|
||||||
}, [projectLoading, projectNames, selectedProject]);
|
}, [projectLoading, projectNames, selectedProject]);
|
||||||
|
|
||||||
// ===== Role Helper =====
|
// ===== Role Helper =====
|
||||||
@ -199,13 +199,13 @@ const Header = () => {
|
|||||||
style={{ overflow: "auto", maxHeight: "300px" }}
|
style={{ overflow: "auto", maxHeight: "300px" }}
|
||||||
>
|
>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<button
|
<button
|
||||||
className="dropdown-item"
|
className="dropdown-item"
|
||||||
onClick={() => handleProjectChange(null)}
|
onClick={() => handleProjectChange(null)}
|
||||||
>All Project</button>
|
>All Project</button>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{[...projectsForDropdown]
|
{[...projectsForDropdown]
|
||||||
.sort((a, b) => a?.name?.localeCompare(b.name))
|
.sort((a, b) => a?.name?.localeCompare(b.name))
|
||||||
.map((project) => (
|
.map((project) => (
|
||||||
|
|||||||
@ -200,63 +200,63 @@ export const useDashboard_Data = ({ days, FromDate, projectId }) => {
|
|||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
|
|
||||||
export const useDashboard_AttendanceData = (date,projectId)=>{
|
export const useDashboard_AttendanceData = (date, projectId) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey:["dashboardAttendances",date,projectId],
|
queryKey: ["dashboardAttendances", date, projectId],
|
||||||
queryFn:async()=> {
|
queryFn: async () => {
|
||||||
|
|
||||||
const resp = await await GlobalRepository.getDashboardAttendanceData(date, projectId)
|
const resp = await await GlobalRepository.getDashboardAttendanceData(date, projectId)
|
||||||
return resp.data;
|
return resp.data;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useDashboardTeamsCardData =(projectId)=>{
|
export const useDashboardTeamsCardData = (projectId) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey:["dashboardTeams",projectId],
|
queryKey: ["dashboardTeams", projectId],
|
||||||
queryFn:async()=> {
|
queryFn: async () => {
|
||||||
|
|
||||||
const resp = await GlobalRepository.getDashboardTeamsCardData(projectId)
|
const resp = await GlobalRepository.getDashboardTeamsCardData(projectId)
|
||||||
return resp.data;
|
return resp.data;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useDashboardTasksCardData = (projectId) => {
|
export const useDashboardTasksCardData = (projectId) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey:["dashboardTasks",projectId],
|
queryKey: ["dashboardTasks", projectId],
|
||||||
queryFn:async()=> {
|
queryFn: async () => {
|
||||||
|
|
||||||
const resp = await GlobalRepository.getDashboardTasksCardData(projectId)
|
const resp = await GlobalRepository.getDashboardTasksCardData(projectId)
|
||||||
return resp.data;
|
return resp.data;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
export const useAttendanceOverviewData = (projectId, days) => {
|
export const useAttendanceOverviewData = (projectId, days) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey:["dashboardAttendanceOverView",projectId,days],
|
queryKey: ["dashboardAttendanceOverView", projectId, days],
|
||||||
queryFn:async()=> {
|
queryFn: async () => {
|
||||||
|
|
||||||
const resp = await GlobalRepository.getAttendanceOverview(projectId, days);
|
const resp = await GlobalRepository.getAttendanceOverview(projectId, days);
|
||||||
return resp.data;
|
return resp.data;
|
||||||
},
|
},
|
||||||
enabled:!!projectId
|
enabled: !!projectId
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useDashboardProjectsCardData = () => {
|
export const useDashboardProjectsCardData = () => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey:["dashboardProjects"],
|
queryKey: ["dashboardProjects"],
|
||||||
queryFn:async()=> {
|
queryFn: async () => {
|
||||||
|
|
||||||
const resp = await GlobalRepository.getDashboardProjectsCardData();
|
const resp = await GlobalRepository.getDashboardProjectsCardData();
|
||||||
return resp.data;
|
return resp.data;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useExpenseAnalysis = (projectId, startDate, endDate) => {
|
export const useExpenseAnalysis = (projectId, startDate, endDate) => {
|
||||||
const hasBothDates = !!startDate && !!endDate;
|
const hasBothDates = !!startDate && !!endDate;
|
||||||
const noDatesSelected = !startDate && !endDate;
|
const noDatesSelected = !startDate && !endDate;
|
||||||
|
|
||||||
const shouldFetch =
|
const shouldFetch =
|
||||||
@ -266,9 +266,20 @@ export const useExpenseAnalysis = (projectId, startDate, endDate) => {
|
|||||||
queryKey: ["expenseAnalysis", projectId, startDate, endDate],
|
queryKey: ["expenseAnalysis", projectId, startDate, endDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const resp = await GlobalRepository.getExpenseData(projectId, startDate, endDate);
|
const resp = await GlobalRepository.getExpenseData(projectId, startDate, endDate);
|
||||||
return resp.data;
|
return resp.data;
|
||||||
},
|
},
|
||||||
enabled:shouldFetch
|
enabled: shouldFetch
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useExpenseDataByProject = (projectId, categoryId, months) => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ["expenseByProject", projectId, categoryId, months],
|
||||||
|
queryFn: async () => {
|
||||||
|
const resp = await GlobalRepository.getExpenseDataByProject(projectId, categoryId, months);
|
||||||
|
return resp.data;
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const useExpenseStatus = (projectId)=>{
|
export const useExpenseStatus = (projectId)=>{
|
||||||
|
|||||||
@ -3,12 +3,12 @@ import { api } from "../utils/axiosClient";
|
|||||||
const GlobalRepository = {
|
const GlobalRepository = {
|
||||||
getDashboardProgressionData: ({ days = '', FromDate = '', projectId = '' }) => {
|
getDashboardProgressionData: ({ days = '', FromDate = '', projectId = '' }) => {
|
||||||
let params;
|
let params;
|
||||||
if(projectId == null){
|
if (projectId == null) {
|
||||||
params = new URLSearchParams({
|
params = new URLSearchParams({
|
||||||
days: days.toString(),
|
days: days.toString(),
|
||||||
FromDate,
|
FromDate,
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
params = new URLSearchParams({
|
params = new URLSearchParams({
|
||||||
days: days.toString(),
|
days: days.toString(),
|
||||||
FromDate,
|
FromDate,
|
||||||
@ -19,35 +19,35 @@ const GlobalRepository = {
|
|||||||
return api.get(`/api/Dashboard/Progression?${params.toString()}`);
|
return api.get(`/api/Dashboard/Progression?${params.toString()}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
getDashboardAttendanceData: ( date,projectId ) => {
|
getDashboardAttendanceData: (date, projectId) => {
|
||||||
|
|
||||||
return api.get(`/api/Dashboard/project-attendance/${projectId}?date=${date}`);
|
return api.get(`/api/Dashboard/project-attendance/${projectId}?date=${date}`);
|
||||||
},
|
},
|
||||||
getDashboardProjectsCardData: () => {
|
getDashboardProjectsCardData: () => {
|
||||||
return api.get(`/api/Dashboard/projects`);
|
return api.get(`/api/Dashboard/projects`);
|
||||||
},
|
},
|
||||||
|
|
||||||
getDashboardTeamsCardData: (projectId) => {
|
getDashboardTeamsCardData: (projectId) => {
|
||||||
const url = projectId
|
const url = projectId
|
||||||
? `/api/Dashboard/teams?projectId=${projectId}`
|
? `/api/Dashboard/teams?projectId=${projectId}`
|
||||||
: `/api/Dashboard/teams`;
|
: `/api/Dashboard/teams`;
|
||||||
return api.get(url);
|
return api.get(url);
|
||||||
},
|
},
|
||||||
|
|
||||||
getDashboardTasksCardData: (projectId) => {
|
getDashboardTasksCardData: (projectId) => {
|
||||||
const url = projectId
|
const url = projectId
|
||||||
? `/api/Dashboard/tasks?projectId=${projectId}`
|
? `/api/Dashboard/tasks?projectId=${projectId}`
|
||||||
: `/api/Dashboard/tasks`;
|
: `/api/Dashboard/tasks`;
|
||||||
return api.get(url);
|
return api.get(url);
|
||||||
},
|
},
|
||||||
|
|
||||||
getAttendanceOverview:(projectId,days)=>api.get(`/api/dashboard/attendance-overview/${projectId}?days=${days}`),
|
getAttendanceOverview: (projectId, days) => api.get(`/api/dashboard/attendance-overview/${projectId}?days=${days}`),
|
||||||
|
|
||||||
|
|
||||||
getExpenseData: (projectId, startDate, endDate) => {
|
getExpenseData: (projectId, startDate, endDate) => {
|
||||||
let url = `api/Dashboard/expense/type`
|
let url = `api/Dashboard/expense/type`
|
||||||
|
|
||||||
const queryParams = [];
|
const queryParams = [];
|
||||||
|
|
||||||
if (projectId) {
|
if (projectId) {
|
||||||
queryParams.push(`projectId=${projectId}`);
|
queryParams.push(`projectId=${projectId}`);
|
||||||
@ -56,7 +56,7 @@ const GlobalRepository = {
|
|||||||
if (startDate) {
|
if (startDate) {
|
||||||
queryParams.push(`startDate=${startDate}`);
|
queryParams.push(`startDate=${startDate}`);
|
||||||
}
|
}
|
||||||
if (endDate) {
|
if (endDate) {
|
||||||
queryParams.push(`endDate=${endDate}`);
|
queryParams.push(`endDate=${endDate}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +64,31 @@ const GlobalRepository = {
|
|||||||
url += `?${queryParams.join("&")}`;
|
url += `?${queryParams.join("&")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return api.get(url );
|
return api.get(url);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
getExpenseDataByProject: (projectId, categoryId, months) => {
|
||||||
|
let url = `api/Dashboard/expense/monthly`
|
||||||
|
|
||||||
|
const queryParams = [];
|
||||||
|
|
||||||
|
if (projectId) {
|
||||||
|
queryParams.push(`projectId=${projectId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (categoryId) {
|
||||||
|
queryParams.push(`categoryId=${categoryId}`);
|
||||||
|
}
|
||||||
|
if (months) {
|
||||||
|
queryParams.push(`months=${months}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryParams.length > 0) {
|
||||||
|
url += `?${queryParams.join("&")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api.get(url);
|
||||||
},
|
},
|
||||||
|
|
||||||
getExpenseStatus:(projectId)=>api.get(`/api/Dashboard/expense/pendings${projectId ? `?projectId=${projectId}`:""}`)
|
getExpenseStatus:(projectId)=>api.get(`/api/Dashboard/expense/pendings${projectId ? `?projectId=${projectId}`:""}`)
|
||||||
|
|||||||
@ -94,10 +94,21 @@ export const getCompletionPercentage = (completedWork, plannedWork)=> {
|
|||||||
return clamped.toFixed(2);
|
return clamped.toFixed(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const formatDate_DayMonth = (dateInput)=>{
|
// export const formatDate_DayMonth = (dateInput)=>{
|
||||||
const date = new Date(dateInput);
|
// const date = new Date(dateInput);
|
||||||
return format(date, "d MMM");
|
// return format(date, "d MMM");
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
export const formatDate_DayMonth = (monthName, year) => {
|
||||||
|
if (!monthName || !year) return "";
|
||||||
|
try {
|
||||||
|
const shortMonth = monthName.substring(0, 3);
|
||||||
|
return `${shortMonth} ${year}`;
|
||||||
|
} catch {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export const getTenantStatus =(statusId)=>{
|
export const getTenantStatus =(statusId)=>{
|
||||||
return ActiveTenant === statusId ? " bg-label-success":"bg-label-secondary"
|
return ActiveTenant === statusId ? " bg-label-success":"bg-label-secondary"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user