Merge pull request 'Kartik_Bug#1737 :- UI Implementation in Expense Weidget.' (#507) from Kartik_Bug#1737 into Service_Project_Managment
Reviewed-on: #507
This commit is contained in:
commit
a61e621ce2
@ -100,9 +100,9 @@ const AttendanceOverview = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-white p-4 rounded shadow d-flex flex-column h-100">
|
<div className="bg-white px-4 rounded shadow d-flex flex-column h-100">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="d-flex justify-content-between align-items-center mb-3">
|
<div className="d-flex mt-2 justify-content-between align-items-center mb-3">
|
||||||
<div className="card-title mb-0 text-start">
|
<div className="card-title mb-0 text-start">
|
||||||
<h5 className="mb-1 fw-bold">Attendance Overview</h5>
|
<h5 className="mb-1 fw-bold">Attendance Overview</h5>
|
||||||
<p className="card-subtitle">Role-wise present count</p>
|
<p className="card-subtitle">Role-wise present count</p>
|
||||||
@ -12,11 +12,11 @@ import Teams from "./Teams";
|
|||||||
import TasksCard from "./Tasks";
|
import TasksCard from "./Tasks";
|
||||||
import ProjectCompletionChart from "./ProjectCompletionChart";
|
import ProjectCompletionChart from "./ProjectCompletionChart";
|
||||||
import ProjectProgressChart from "./ProjectProgressChart";
|
import ProjectProgressChart from "./ProjectProgressChart";
|
||||||
import ProjectOverview from "../Project/ProjectOverview";
|
import AttendanceOverview from "./AttendanceOverview";
|
||||||
import AttendanceOverview from "./AttendanceChart";
|
|
||||||
import ExpenseAnalysis from "./ExpenseAnalysis";
|
import ExpenseAnalysis from "./ExpenseAnalysis";
|
||||||
import ExpenseStatus from "./ExpenseStatus";
|
import ExpenseStatus from "./ExpenseStatus";
|
||||||
import ExpenseByProject from "./ExpenseByProject";
|
import ExpenseByProject from "./ExpenseByProject";
|
||||||
|
import ProjectStatistics from "../Project/ProjectStatistics";
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Dashboard = () => {
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ const Dashboard = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={`${!isAllProjectsSelected ? "col-sm-6 col-lg-6" : "col-sm-6 col-lg-4"}`}>
|
<div className={`${!isAllProjectsSelected ? "col-sm-6 col-lg-6" : "col-sm-6 col-lg-4"}`}>
|
||||||
<TasksCard/>
|
<TasksCard />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isAllProjectsSelected && (
|
{isAllProjectsSelected && (
|
||||||
@ -46,32 +46,31 @@ const Dashboard = () => {
|
|||||||
<ProjectCompletionChart />
|
<ProjectCompletionChart />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!isAllProjectsSelected && (
|
|
||||||
<div className="col-xxl-6 col-lg-6">
|
|
||||||
<ProjectOverview />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="col-xxl-6 col-lg-6">
|
<div className="col-xxl-6 col-lg-6">
|
||||||
<ProjectProgressChart />
|
<ProjectProgressChart />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 col-xl-8">
|
|
||||||
<div className="card h-100">
|
|
||||||
<ExpenseAnalysis />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-12 col-xl-4 col-md-6">
|
|
||||||
<div className="card h-100">
|
|
||||||
<ExpenseStatus />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{!isAllProjectsSelected && (
|
{!isAllProjectsSelected && (
|
||||||
<div className="col-12 col-md-6 mb-sm-0 mb-4">
|
<div className="col-12 col-md-6 mb-sm-0 mb-4">
|
||||||
<AttendanceOverview />
|
<AttendanceOverview />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{!isAllProjectsSelected && (
|
||||||
|
<div className="col-xxl-4 col-lg-4">
|
||||||
|
<ProjectStatistics />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="col-12 col-xl-4 col-md-6">
|
||||||
|
<div className="card ">
|
||||||
|
<ExpenseStatus />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-12 col-xl-8">
|
||||||
|
<div className="card h-100">
|
||||||
|
<ExpenseAnalysis />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="col-12 col-md-6">
|
<div className="col-12 col-md-6">
|
||||||
<ExpenseByProject />
|
<ExpenseByProject />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -7,11 +7,12 @@ import { FormProvider, useForm } from "react-hook-form";
|
|||||||
import { formatCurrency, localToUtc } from "../../utils/appUtils";
|
import { formatCurrency, localToUtc } from "../../utils/appUtils";
|
||||||
import { useProjectName } from "../../hooks/useProjects";
|
import { useProjectName } from "../../hooks/useProjects";
|
||||||
import { SpinnerLoader } from "../common/Loader";
|
import { SpinnerLoader } from "../common/Loader";
|
||||||
|
import flatColors from "../Charts/flatColor";
|
||||||
|
|
||||||
const ExpenseAnalysis = () => {
|
const ExpenseAnalysis = () => {
|
||||||
const projectId = useSelectedProject();
|
const projectId = useSelectedProject();
|
||||||
const [projectName, setProjectName] = useState("All Project");
|
const [projectName, setProjectName] = useState("All Project");
|
||||||
const { projectNames, loading } = useProjectName();
|
const { projectNames } = useProjectName();
|
||||||
|
|
||||||
const methods = useForm({
|
const methods = useForm({
|
||||||
defaultValues: { startDate: "", endDate: "" },
|
defaultValues: { startDate: "", endDate: "" },
|
||||||
@ -50,7 +51,7 @@ const ExpenseAnalysis = () => {
|
|||||||
labels,
|
labels,
|
||||||
legend: { show: false },
|
legend: { show: false },
|
||||||
dataLabels: { enabled: true, formatter: (val) => `${val.toFixed(0)}%` },
|
dataLabels: { enabled: true, formatter: (val) => `${val.toFixed(0)}%` },
|
||||||
colors: ["#7367F0", "#28C76F", "#FF9F43", "#EA5455", "#00CFE8", "#FF78B8"],
|
colors: flatColors,
|
||||||
plotOptions: {
|
plotOptions: {
|
||||||
pie: {
|
pie: {
|
||||||
donut: {
|
donut: {
|
||||||
@ -79,22 +80,19 @@ const ExpenseAnalysis = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
<div className="card-header d-flex flex-column flex-sm-row justify-content-between align-items-start align-items-sm-center gap-2">
|
<div className="card-header d-flex flex-column flex-sm-row justify-content-between align-items-start align-items-sm-center gap-2">
|
||||||
<div className="text-start ">
|
<div className="text-start">
|
||||||
<h5 className="mb-1 card-title">Expense Breakdown</h5>
|
<h5 className="mb-1 card-title">Expense Breakdown</h5>
|
||||||
{/* <p className="card-subtitle mb-0">Category Wise Expense Breakdown</p> */}
|
|
||||||
<p className="card-subtitle m-0">{projectName}</p>
|
<p className="card-subtitle m-0">{projectName}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-end text-sm-end ">
|
<div className="text-end text-sm-end">
|
||||||
<FormProvider {...methods}>
|
<FormProvider {...methods}>
|
||||||
<DateRangePicker1 />
|
<DateRangePicker1 />
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Card body */}
|
|
||||||
<div className="card-body position-relative">
|
<div className="card-body position-relative">
|
||||||
{isLoading && (
|
{isLoading && (
|
||||||
<div
|
<div
|
||||||
@ -114,7 +112,6 @@ const ExpenseAnalysis = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
{!isLoading && report.length > 0 && (
|
{!isLoading && report.length > 0 && (
|
||||||
<>
|
<>
|
||||||
{isFetching && (
|
{isFetching && (
|
||||||
@ -123,50 +120,59 @@ const ExpenseAnalysis = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="d-flex justify-content-center mb-3">
|
<div className="row">
|
||||||
|
{/* Chart Column */}
|
||||||
|
<div className="col-12 col-lg-6 d-flex justify-content-center mt-5 mb-3 mb-lg-0">
|
||||||
<Chart
|
<Chart
|
||||||
options={donutOptions}
|
options={donutOptions}
|
||||||
series={series}
|
series={series}
|
||||||
type="donut"
|
type="donut"
|
||||||
width="100%"
|
width="70%"
|
||||||
height={320}
|
height={320}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mb-2 w-100">
|
{/* Data/Legend Column */}
|
||||||
<div className="row g-2">
|
<div className="col-12 mt-6 col-lg-6">
|
||||||
|
<div className="row g-4">
|
||||||
{report.map((item, idx) => (
|
{report.map((item, idx) => (
|
||||||
<div
|
<div
|
||||||
className="col-12 col-sm-6 d-flex align-items-start"
|
className="col-6"
|
||||||
key={idx}
|
key={idx}
|
||||||
>
|
|
||||||
<div className="avatar me-2">
|
|
||||||
<span
|
|
||||||
className="avatar-initial rounded-2"
|
|
||||||
style={{
|
style={{
|
||||||
backgroundColor:
|
borderLeft: `3px solid ${flatColors[idx % flatColors.length]}`,
|
||||||
donutOptions.colors[idx % donutOptions.colors.length],
|
}}
|
||||||
|
>
|
||||||
|
<div className="d-flex flex-column text-start">
|
||||||
|
<small
|
||||||
|
className="fw-semibold text-wrap text-dark"
|
||||||
|
style={{
|
||||||
|
fontSize: "0.8rem",
|
||||||
|
whiteSpace: "normal",
|
||||||
|
wordBreak: "break-word",
|
||||||
|
lineHeight: "1.2",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{item.projectName}
|
||||||
|
</small>
|
||||||
|
<span
|
||||||
|
className="fw-semibold text-muted"
|
||||||
|
style={{
|
||||||
|
fontSize: "0.75rem",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<i className="bx bx-receipt fs-4"></i>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="d-flex flex-column gap-1 text-start">
|
|
||||||
<small className="fw-semibold">{item.projectName}</small>
|
|
||||||
<span className="fw-semibold text-muted ms-1">
|
|
||||||
{formatCurrency(item.totalApprovedAmount)}
|
{formatCurrency(item.totalApprovedAmount)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Header */}
|
|
||||||
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -92,7 +92,7 @@ const ExpenseByProject = () => {
|
|||||||
<div className="card shadow-sm h-100 rounded ">
|
<div className="card shadow-sm h-100 rounded ">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="card-header">
|
<div className="card-header">
|
||||||
<div className="d-flex justify-content-start align-items-center mb-1 mt-1">
|
<div className="d-flex justify-content-between align-items-center mb-1 mt-1">
|
||||||
<div className="text-start">
|
<div className="text-start">
|
||||||
<h5 className="mb-1 me-6 card-title">Monthly Expense -</h5>
|
<h5 className="mb-1 me-6 card-title">Monthly Expense -</h5>
|
||||||
<p className="card-subtitle m-0">{projectName}</p>
|
<p className="card-subtitle m-0">{projectName}</p>
|
||||||
|
|||||||
@ -103,7 +103,7 @@ const ExpenseStatus = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<small
|
<small
|
||||||
className={`text-royalblue ${countDigit(item?.count || 0) >= 3 ? "text-xl" : "text-2xl"
|
className={`text-royalblue ${countDigit(item?.count || 0) >= 3 ? "text-xl" : "text-xl"
|
||||||
} text-gray-500`}
|
} text-gray-500`}
|
||||||
>
|
>
|
||||||
{item?.count || 0}
|
{item?.count || 0}
|
||||||
@ -137,7 +137,7 @@ const ExpenseStatus = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="d-flex align-items-center gap-2">
|
<div className="d-flex align-items-center gap-2">
|
||||||
<span
|
<span
|
||||||
className={`text-end text-royalblue ${countDigit(data?.totalAmount || 0) > 3 ? "text-" : "text-3xl"
|
className={`text-end text-royalblue ${countDigit(data?.totalAmount || 0) > 3 ? "text-xl" : "text-3xl"
|
||||||
} text-md`}
|
} text-md`}
|
||||||
>
|
>
|
||||||
{formatCurrency(data?.totalAmount || 0)}
|
{formatCurrency(data?.totalAmount || 0)}
|
||||||
|
|||||||
@ -1,11 +1,14 @@
|
|||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import HorizontalBarChart from "../Charts/HorizontalBarChart";
|
import HorizontalBarChart from "../Charts/HorizontalBarChart";
|
||||||
import { useProjects } from "../../hooks/useProjects";
|
import { useProjects } from "../../hooks/useProjects";
|
||||||
|
import { ITEMS_PER_PAGE } from "../../utils/constants";
|
||||||
|
|
||||||
const ProjectCompletionChart = () => {
|
const ProjectCompletionChart = () => {
|
||||||
const { data: projects = [], isLoading: loading, isError, error } = useProjects();
|
|
||||||
|
|
||||||
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const { data: projects, isLoading: loading, isError, error } = useProjects(currentPage, ITEMS_PER_PAGE);
|
||||||
|
|
||||||
|
console.log("Kartik", projects)
|
||||||
// Bar chart logic
|
// Bar chart logic
|
||||||
const projectNames = projects?.map((p) => p.name) || [];
|
const projectNames = projects?.map((p) => p.name) || [];
|
||||||
const projectProgress =
|
const projectProgress =
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import {
|
|||||||
import ReactApexChart from "react-apexcharts";
|
import ReactApexChart from "react-apexcharts";
|
||||||
import Chart from "react-apexcharts";
|
import Chart from "react-apexcharts";
|
||||||
|
|
||||||
const ProjectOverview = ({ project }) => {
|
const ProjectStatistics = ({ project }) => {
|
||||||
const { data } = useProjects();
|
const { data } = useProjects();
|
||||||
const [current_project, setCurrentProject] = useState(
|
const [current_project, setCurrentProject] = useState(
|
||||||
data?.find((pro) => pro.id == project)
|
data?.find((pro) => pro.id == project)
|
||||||
@ -165,7 +165,7 @@ const ProjectOverview = ({ project }) => {
|
|||||||
}, [selectedProject]);
|
}, [selectedProject]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card" style={{ minHeight: "490px" }}>
|
<div className="card h-100">
|
||||||
<div className="card-header text-start">
|
<div className="card-header text-start">
|
||||||
<h5 className="card-action-title mb-0">
|
<h5 className="card-action-title mb-0">
|
||||||
{" "}
|
{" "}
|
||||||
@ -241,10 +241,10 @@ const ProjectOverview = ({ project }) => {
|
|||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ProjectOverview;
|
export default ProjectStatistics;
|
||||||
@ -72,7 +72,7 @@ const AddPayment = ({ onClose }) => {
|
|||||||
|
|
||||||
<div className="col-12 col-md-6 mb-2">
|
<div className="col-12 col-md-6 mb-2">
|
||||||
<Label required>Transaction Date </Label>
|
<Label required>Transaction Date </Label>
|
||||||
<DatePicker
|
<DatePicker className="w-100"
|
||||||
name="paymentReceivedDate"
|
name="paymentReceivedDate"
|
||||||
control={control}
|
control={control}
|
||||||
minDate={
|
minDate={
|
||||||
|
|||||||
@ -20,13 +20,13 @@ export const useCurrentService = () => {
|
|||||||
|
|
||||||
// ------------------------------Query-------------------
|
// ------------------------------Query-------------------
|
||||||
|
|
||||||
export const useProjects = (pageSize,pageNumber) => {
|
export const useProjects = (pageNumber,pageSize) => {
|
||||||
const loggedUser = useSelector((store) => store.globalVariables.loginUser);
|
const loggedUser = useSelector((store) => store.globalVariables.loginUser);
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ["ProjectsList",pageSize,pageNumber],
|
queryKey: ["ProjectsList",pageNumber,pageSize],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const response = await ProjectRepository.getProjectList(pageSize,pageNumber);
|
const response = await ProjectRepository.getProjectList(pageNumber,pageSize);
|
||||||
return response.data;
|
return response?.data?.data;
|
||||||
},
|
},
|
||||||
enabled: !!loggedUser,
|
enabled: !!loggedUser,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import React, { useState, useEffect, useCallback } from "react";
|
|||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import ProjectOverview from "../../components/Project/ProjectOverview";
|
import ProjectOverview from "../../components/Project/ProjectStatistics";
|
||||||
import AboutProject from "../../components/Project/AboutProject";
|
import AboutProject from "../../components/Project/AboutProject";
|
||||||
import ProjectNav from "../../components/Project/ProjectNav";
|
import ProjectNav from "../../components/Project/ProjectNav";
|
||||||
import Teams from "../../components/Project/Team/Teams";
|
import Teams from "../../components/Project/Team/Teams";
|
||||||
@ -15,7 +15,7 @@ import { useProjectDetails, useProjectName } from "../../hooks/useProjects";
|
|||||||
import { ComingSoonPage } from "../Misc/ComingSoonPage";
|
import { ComingSoonPage } from "../Misc/ComingSoonPage";
|
||||||
import eventBus from "../../services/eventBus";
|
import eventBus from "../../services/eventBus";
|
||||||
import ProjectProgressChart from "../../components/Dashboard/ProjectProgressChart";
|
import ProjectProgressChart from "../../components/Dashboard/ProjectProgressChart";
|
||||||
import AttendanceOverview from "../../components/Dashboard/AttendanceChart";
|
import AttendanceOverview from "../../components/Dashboard/AttendanceOverview";
|
||||||
import { setProjectId } from "../../slices/localVariablesSlice";
|
import { setProjectId } from "../../slices/localVariablesSlice";
|
||||||
import ProjectDocuments from "../../components/Project/ProjectDocuments";
|
import ProjectDocuments from "../../components/Project/ProjectDocuments";
|
||||||
import ProjectSetting from "../../components/Project/ProjectSetting";
|
import ProjectSetting from "../../components/Project/ProjectSetting";
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { api } from "../utils/axiosClient";
|
import { api } from "../utils/axiosClient";
|
||||||
|
|
||||||
const ProjectRepository = {
|
const ProjectRepository = {
|
||||||
getProjectList: (pageSize,pageNumber) => api.get(`/api/project/list?pageSize=${pageSize}&pageNumber=${pageNumber}`),
|
getProjectList: (pageNumber,pageSize) => api.get(`/api/project/list?&pageNumber=${pageNumber}&pageSize=${pageSize}`),
|
||||||
getProjectByprojectId: (projetid) =>
|
getProjectByprojectId: (projetid) =>
|
||||||
api.get(`/api/project/details/${projetid}`),
|
api.get(`/api/project/details/${projetid}`),
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user