Skip to content

Commit

Permalink
Hooked the tiles and chart with actual data
Browse files Browse the repository at this point in the history
  • Loading branch information
vicwere committed Jan 22, 2025
1 parent 0e39893 commit 0c5d91d
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,31 @@ const ClaimSummaryHeader: React.FC<ClaimsSummaryHeaderProps> = ({ filters, onFil
const { t } = useTranslation();

const today = new Date();
const oneMonthAgo = new Date(today);
oneMonthAgo.setMonth(today.getMonth() - 1);
const sixMonthsAgo = new Date(today);
sixMonthsAgo.setMonth(today.getMonth() - 6);

useEffect(() => {
if (!filters.fromDate && !filters.toDate) {
onFilterChanged(() => ({
fromDate: oneMonthAgo,
fromDate: sixMonthsAgo,
toDate: today,
}));
}
}, [filters, onFilterChanged, oneMonthAgo, today]);
}, [filters, onFilterChanged, sixMonthsAgo, today]);

const handleDateChange = ([fromDate, toDate]: [Date, Date]) => {
onFilterChanged(() => ({
fromDate,
toDate,
}));
};

return (
<div className={styles.summaryContainer}>
<DatePicker
datePickerType="range"
value={[filters.fromDate, filters.toDate]}
onChange={([fromDate, toDate]) =>
onFilterChanged((currentFilters) => ({ ...currentFilters, fromDate, toDate }))
}
onChange={handleDateChange}
aria-label={t('datePicker.rangeLabel', 'Select date range')}>
<DatePickerInput
id="date-picker-input-id-start"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,66 +1,55 @@
import React, { useEffect, useState } from 'react';
import { BarChartOptions, GroupedBarChart, ScaleTypes } from '@carbon/charts-react';
import useClaimsAggregate from '../../../hooks/useClaimsAggregate';

const ClaimsSummaryChart = () => {
const [metrics, setMetrics] = useState({ summaryGraph: [] });

useEffect(() => {
setTimeout(() => {
// Simulating API data fetch
const data = {
summaryGraph: [
{ month: 'January', claimsA: 1200, claimsB: 1000 },
{ month: 'February', claimsA: 1000, claimsB: 1100 },
{ month: 'March', claimsA: 1400, claimsB: 1300 },
{ month: 'April', claimsA: 800, claimsB: 700 },
{ month: 'May', claimsA: 1100, claimsB: 1200 },
],
};

setMetrics(data);
}, 1000); // Simulating async fetch
}, []);
const { isLoading, summarizedData, error } = useClaimsAggregate();

if (!metrics.summaryGraph.length) {
if (isLoading) {
return <div>Loading data...</div>;
}

const transformClaimSummaryChartData = (data) => {
return data
.map((item) => [
{ group: item.month, value: item.claimsA },
{ group: item.month, value: item.claimsB },
])
.flat();
};
if (error) {
return <div>Error loading claims data</div>;
}

useEffect(() => {

Check failure on line 18 in packages/esm-billing-app/src/claims/claims-management/main/claims-summary-chart.component.tsx

View workflow job for this annotation

GitHub Actions / build

React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?
if (summarizedData.length) {
const transformedData = summarizedData.flatMap((item) => [
{ group: 'Claimed', month: item.month, value: item.claimedTotal },
{ group: 'Approved', month: item.month, value: item.approvedTotal },
]);

setMetrics({ summaryGraph: transformedData });
}
}, [summarizedData]);

const options: BarChartOptions = {
title: 'Claims Comparative Analysis',
title: 'Analysis of Claimed vs Approved Amount by Month',
legend: {
enabled: true,
},
axes: {
left: {
mapsTo: 'month',
title: 'Month',
mapsTo: 'group',
scaleType: ScaleTypes.LABELS,
},
bottom: {
title: 'Amount (Ksh)',
mapsTo: 'value',

title: 'Amount (Ksh)',
scaleType: ScaleTypes.LINEAR,
includeZero: true,
},
},
height: '400px',
};

const transformedData = transformClaimSummaryChartData(metrics.summaryGraph);

return (
<div style={{ padding: '2rem' }}>
<GroupedBarChart data={transformedData} options={options} />
<GroupedBarChart data={metrics.summaryGraph} options={options} />
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import styles from '../../metrics/metrics.scss';
import { ClaimsManagementHeader } from '../header/claims-header.component';
import ClaimsSummaryHeader from '../header/summary-header.component';
import { ClaimsSummaryFilter } from '../../../types';
import ClaimsSummaryChart from './claims-summary-chart.component';

import MetricsHeader from '../../metrics/metrics-header.component';
import MetricsCard from '../../metrics/metrics-card.component';
import { convertToCurrency } from '../../../helpers';
import useClaimsAggregate from '../../../hooks/useClaimsAggregate';

const MainMetrics = () => {
const [filters, setFilters] = useState({
Expand All @@ -19,40 +19,45 @@ const MainMetrics = () => {
setFilters(updateFn(filters));
};

const fromDate = filters.fromDate || new Date();
const toDate = filters.toDate || new Date();
// test data values declaration
const totalAmount = 1150000;
const claimedAmount = 120000;
const t = (key, fallback) => fallback;

const pendingAmount = 56000;
const { isLoading, summarizedData, error } = useClaimsAggregate();

const preApps = 300;
const preAppsApproved = 188;
if (error) {
return <div>Error loading claims data</div>;
}

const preAppsPending = 20;
if (isLoading) {
return <div>Loading claims data...</div>;
}

const t = (key, fallback) => fallback;
const totalClaimed = summarizedData.reduce((sum, item) => sum + item.claimedTotal, 0);
const totalApproved = summarizedData.reduce((sum, item) => sum + item.approvedTotal, 0);
const totalPending = totalClaimed - totalApproved;

const preApps = 0;
const preAppsApproved = 0;
const preAppsPending = 0;

return (
<div className={`omrs-main-content`}>
<ClaimsManagementHeader title={t('claims', 'Claims Summary')} />
<ClaimsSummaryHeader filters={filters} onFilterChanged={onFilterChanged} />{' '}
<ClaimsSummaryHeader filters={filters} onFilterChanged={onFilterChanged} />
<>
<div className={styles.cardContainer} data-testid="claims-metrics">
<MetricsCard
label={t('ksh', '')}
value={convertToCurrency(totalAmount)}
value={convertToCurrency(totalClaimed)}
headerLabel={t('claimsItems', 'Total Claimed')}
/>
<MetricsCard
label={t('ksh', '')}
value={convertToCurrency(claimedAmount)}
value={convertToCurrency(totalApproved)}
headerLabel={t('claimsItems', 'Total Approved')}
/>
<MetricsCard
label={t('ksh', '')}
value={convertToCurrency(pendingAmount)}
value={convertToCurrency(totalPending)}
headerLabel={t('claimsItems', 'Amount Pending')}
/>
</div>
Expand Down
Empty file.
66 changes: 66 additions & 0 deletions packages/esm-billing-app/src/hooks/useClaimsAggregate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { useMemo } from 'react';
import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
import useSWR from 'swr';

interface Claim {
uuid: string;
claimCode: string;
dateFrom: string | null;
dateTo: string | null;
claimedTotal: number;
approvedTotal: number;
status: string;
externalId?: string;
}

interface ClaimResponse {
results: Claim[];
}

const useClaimsAggregate = () => {
const { data, error, isValidating } = useSWR<ClaimResponse>(
`${restBaseUrl}/claim?v=custom:(uuid,claimCode,dateFrom,dateTo,claimedTotal,approvedTotal,status,externalId)`,
async (url) => {
const response = await openmrsFetch<ClaimResponse>(url);
return response.data;
},
);

const summarizedData = useMemo(() => {
if (!data || !data.results) {
return [];
}

const summary = data.results.reduce((acc, item) => {
const date = item.dateFrom || item.dateTo;
const month = new Date(date ?? '').toLocaleString('default', {
month: 'long',
year: 'numeric',
});

if (!acc[month]) {
acc[month] = { claimedTotal: 0, approvedTotal: 0 };
}

acc[month].claimedTotal += item.claimedTotal || 0;
acc[month].approvedTotal += item.approvedTotal || 0;

return acc;
}, {} as Record<string, { claimedTotal: number; approvedTotal: number }>);

return Object.entries(summary).map(([month, totals], index) => ({
id: `${index + 1}`,
month,
claimedTotal: totals.claimedTotal,
approvedTotal: totals.approvedTotal,
}));
}, [data]);

return {
isLoading: isValidating,
error,
summarizedData,
};
};

export default useClaimsAggregate;

0 comments on commit 0c5d91d

Please sign in to comment.