TP-63767 | Showing incentive on longhorn (#991)
* TP-63746|Kunal|PR clean up * TP-63767|Kunal| showing incentive earned on leaderboard and dashboard * TP-63767|Kunal| showing incentive earned on leaderboard and dashboard * TP-11|Kunal| created fixed height virtualization component * TP-11|Kunal| created fixed height virtualization component * TP-63767|Kunal|Showing incentive on longhorn * TP-63767|Kunal|Showing incentive on longhorn * TP-63767|Kunal|Showing incentive on longhorn * TP-63767|Kunal|resolved PR comments * TP-63767|Kunal|resolved PR comments * TP-63767|Kunal|resolved PR comments * TP-63767|Kunal|resolved PR comments * TP-111|Kunal|added handling for tele lite agents * Revert "TP-111|Kunal|added handling for tele lite agents" This reverts commit c21ebf17dec4a17cc09aa3a1ad7ea0b4b8581725.
This commit is contained in:
1
src/assets/images/incentive-note.svg
Normal file
1
src/assets/images/incentive-note.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="60" fill="none"><path fill="url(#a)" d="M0 0h150v60H0z"/><path stroke="#E6EFE7" stroke-width=".5" d="M2.25 2.25h145.5v55.5H2.25z"/><path fill="#C4E3C6" stroke="#3F6244" stroke-width=".5" d="M18.825 51.75A16.783 16.783 0 0 0 7.25 40.175v-20.35A16.783 16.783 0 0 0 18.825 8.25h112.75a16.784 16.784 0 0 0 11.575 11.575v20.35a16.784 16.784 0 0 0-11.575 11.575H18.825Z"/><defs><radialGradient id="a" cx="0" cy="0" r="1" gradientTransform="matrix(0 -49.5 128.409 0 75 30)" gradientUnits="userSpaceOnUse"><stop stop-color="#6C9D62"/><stop offset="1" stop-color="#AEE2B6"/></radialGradient></defs></svg>
|
||||
|
After Width: | Height: | Size: 655 B |
@@ -47,6 +47,7 @@
|
||||
--border: #e8e8e8;
|
||||
--border-warm: #e9e7e6;
|
||||
--border-cold: #e6e7e9;
|
||||
--border-cold-light: #e6efe7;
|
||||
--border-greyscale: #e7e7e7;
|
||||
|
||||
--white-smoke: #f3f3f3;
|
||||
@@ -107,6 +108,8 @@
|
||||
--pop-up-highlight: #fee5c4;
|
||||
--geolocation-stepper-ellipse-color: #67acfe;
|
||||
|
||||
--incentive-green: #2b5a2a;
|
||||
|
||||
// black base order
|
||||
--black-base: #1a1a1a;
|
||||
|
||||
@@ -159,6 +162,7 @@
|
||||
--z-index-ameyo-disconnect-btn: 99;
|
||||
--z-index-leaderboard-overlay: 99;
|
||||
--z-index-leaderboard: 100;
|
||||
--z-index-leaderboard-tooltip: 1200;
|
||||
--z-index-default-layout-open-cosmos-alert: 100;
|
||||
--z-index-ameyo-reallocation-loader: 100;
|
||||
--z-index-autocomplete-dropdown: 100;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import Highcharts from 'highcharts';
|
||||
import HighchartsReact from 'highcharts-react-official';
|
||||
import { ILeaderboard } from 'src/reducers/leaderboardSlice';
|
||||
import { ILeaderboard, IncentiveData } from 'src/reducers/leaderboardSlice';
|
||||
import styles from './Leaderboard.module.scss';
|
||||
import { dateFormat, monthNames } from 'src/utils/DateHelper';
|
||||
import { shortNumberNotationStartingWithLakhs } from 'src/utils/commonUtils';
|
||||
import { RightArrow } from 'src/assets/icons/RightArrowThin';
|
||||
import { dateFormat } from 'src/utils/DateHelper';
|
||||
import {
|
||||
getNumberFormat,
|
||||
shortNumberNotationStartingWithLakhs,
|
||||
shortNumberNotationWithoutTrailingZeroesAndRounding
|
||||
} from 'src/utils/commonUtils';
|
||||
import ToggleTabs from '../toggleTabs/ToggleTabs';
|
||||
import { ITabsOption, SelectPickerOptionProps } from '../interfaces';
|
||||
import cx from 'classnames';
|
||||
@@ -18,6 +21,16 @@ import { addClickstreamEvent } from '../../service/clickStreamEventService';
|
||||
import { CLICKSTREAM_EVENT_NAMES } from '../../service/clickStream.constant';
|
||||
import { Typography } from '@navi/web-ui/lib/primitives';
|
||||
import RadioGroup from '@navi/web-ui/lib/components/RadioGroup';
|
||||
import InfoIconOutlined from '@cp/assets/images/icons/InfoIconOutlined';
|
||||
import {
|
||||
Directions,
|
||||
Tooltip as TooltipV2,
|
||||
TooltipContent,
|
||||
TooltipTrigger
|
||||
} from '@cp/components/TooltipV2/TooltipV2';
|
||||
import { INCENTIVE_BUCKET_GROUP } from '@cp/components/leaderboard/leaderboardConstant';
|
||||
import Loader from '@cp/components/Loader/Loader';
|
||||
|
||||
interface CashEarnedChartHCProps extends ILeaderboard {
|
||||
titleContainerClass?: string;
|
||||
pieChartContainerClass?: string;
|
||||
@@ -102,22 +115,29 @@ const CashEarnedChartHC: React.FC<CashEarnedChartHCProps> = props => {
|
||||
pieChartContainerClass,
|
||||
animation = true,
|
||||
showDropdown = false,
|
||||
renderedOn
|
||||
renderedOn,
|
||||
incentiveData,
|
||||
prevMonthIncentiveData,
|
||||
monthlyIncentiveData
|
||||
} = props;
|
||||
const dispatch = useDispatch();
|
||||
const MONTH_OPTIONS = getMonthOptions();
|
||||
const referenceId = useSelector((state: RootState) => state.common.userData.referenceId);
|
||||
const leaderboardLoading = useSelector(
|
||||
(state: RootState) => state.leaderboard.leaderboardLoading
|
||||
);
|
||||
const [view, setView] = React.useState<'curr' | 'prev'>('curr');
|
||||
const [cashCollectedDropdownSelectedOption, setCashCollectedDropdownSelectedOption] = useState(
|
||||
MONTH_OPTIONS[MONTH_OPTIONS.length - 1]
|
||||
);
|
||||
const handleViewChange = () => setView(prev => (prev == 'curr' ? 'prev' : 'curr'));
|
||||
const buttonPosition = view == 'curr' ? { left: 16 } : { right: 16 };
|
||||
const DEFAULT_OPTION = 'Total';
|
||||
const [selectedRadioOption, setSelectedRadioOption] = useState(DEFAULT_OPTION);
|
||||
const DEFAULT_OPTION = INCENTIVE_BUCKET_GROUP.TOTAL;
|
||||
const [selectedRadioOption, setSelectedRadioOption] =
|
||||
useState<INCENTIVE_BUCKET_GROUP>(DEFAULT_OPTION);
|
||||
const handleRadioChange = (event: React.SyntheticEvent) => {
|
||||
const value = (event?.target as HTMLInputElement)?.value;
|
||||
setSelectedRadioOption(value);
|
||||
setSelectedRadioOption(value as INCENTIVE_BUCKET_GROUP);
|
||||
if (referenceId) {
|
||||
dispatch(
|
||||
getLeaderboardDetails(
|
||||
@@ -235,19 +255,19 @@ const CashEarnedChartHC: React.FC<CashEarnedChartHCProps> = props => {
|
||||
|
||||
const DEFAULT_OPTIONS = [
|
||||
{
|
||||
id: 'Total',
|
||||
value: 'Total',
|
||||
label: 'Total'
|
||||
id: INCENTIVE_BUCKET_GROUP.TOTAL,
|
||||
value: INCENTIVE_BUCKET_GROUP.TOTAL,
|
||||
label: INCENTIVE_BUCKET_GROUP.TOTAL
|
||||
},
|
||||
{
|
||||
id: '1-30',
|
||||
value: '1-30',
|
||||
label: '1-30'
|
||||
id: INCENTIVE_BUCKET_GROUP.DPD_1_TO_30,
|
||||
value: INCENTIVE_BUCKET_GROUP.DPD_1_TO_30,
|
||||
label: INCENTIVE_BUCKET_GROUP.DPD_1_TO_30
|
||||
},
|
||||
{
|
||||
id: '30+',
|
||||
value: '30+',
|
||||
label: '30+'
|
||||
id: INCENTIVE_BUCKET_GROUP.DPD_30_PLUS,
|
||||
value: INCENTIVE_BUCKET_GROUP.DPD_30_PLUS,
|
||||
label: INCENTIVE_BUCKET_GROUP.DPD_30_PLUS
|
||||
}
|
||||
];
|
||||
|
||||
@@ -263,6 +283,41 @@ const CashEarnedChartHC: React.FC<CashEarnedChartHCProps> = props => {
|
||||
}
|
||||
return noData;
|
||||
}, [data]);
|
||||
|
||||
const [selectedIncentiveData, setIncentiveData] = useState<IncentiveData | undefined>();
|
||||
const totalCashCollectedForSelectedRadioOption = useMemo(
|
||||
() =>
|
||||
selectedRadioOption === INCENTIVE_BUCKET_GROUP.DPD_1_TO_30
|
||||
? selectedIncentiveData?.total1To30DaysCashCollected
|
||||
: selectedRadioOption === INCENTIVE_BUCKET_GROUP.DPD_30_PLUS
|
||||
? selectedIncentiveData?.total30PlusDaysCashCollected
|
||||
: selectedIncentiveData?.thresholdForIncentive,
|
||||
[selectedRadioOption, selectedIncentiveData]
|
||||
);
|
||||
const totalIncentiveEarnedForSelectedRadioOption = useMemo(
|
||||
() =>
|
||||
selectedRadioOption === INCENTIVE_BUCKET_GROUP.DPD_1_TO_30
|
||||
? selectedIncentiveData?.total1To30DaysIncentiveEarned
|
||||
: selectedRadioOption === INCENTIVE_BUCKET_GROUP.DPD_30_PLUS
|
||||
? selectedIncentiveData?.total30PlusDaysIncentiveEarned
|
||||
: selectedIncentiveData?.incentiveEarned,
|
||||
[selectedRadioOption, selectedIncentiveData]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (showDropdown) {
|
||||
setIncentiveData(monthlyIncentiveData);
|
||||
}
|
||||
}, [monthlyIncentiveData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (view === 'curr') {
|
||||
setIncentiveData(incentiveData);
|
||||
} else {
|
||||
setIncentiveData(prevMonthIncentiveData);
|
||||
}
|
||||
}, [view]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.tabsContainer}>
|
||||
@@ -299,15 +354,67 @@ const CashEarnedChartHC: React.FC<CashEarnedChartHCProps> = props => {
|
||||
{getFirstDate()} - {getLastDate(view)}
|
||||
</b>
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className={cx(styles.titleContainer, titleContainerClass)}>
|
||||
{showDropdown ? (
|
||||
<>
|
||||
) : (
|
||||
<span className={styles.titleWithDropdown}>Cash Collection Breakup</span>
|
||||
</>
|
||||
) : null}
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.incentiveHeader}>
|
||||
<Typography variant="h4" className="font-bold">
|
||||
Incentive Earned
|
||||
</Typography>
|
||||
<TooltipV2 placement={showDropdown ? Directions.RIGHT : Directions.TOP}>
|
||||
<TooltipTrigger tooltipTriggerClassName="tooltipTriggerWrapper">
|
||||
<InfoIconOutlined fillColor="var(--blue-base)" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="p-[8px] bg-[var(--grayscale-1)] z-[var(--z-index-leaderboard-tooltip)] rounded-[4px] w-[360px]">
|
||||
{selectedRadioOption === INCENTIVE_BUCKET_GROUP.TOTAL ? (
|
||||
<div className="flex justify-between">
|
||||
<Typography color="var(--text-primary)" className="text-[13px]" variant="p4">
|
||||
Total Cash Collected (a)
|
||||
</Typography>
|
||||
<Typography color="var(--text-primary)" className="text-[13px]" variant="p4">
|
||||
{getNumberFormat(selectedIncentiveData?.totalCashCollected, 2) || `₹0`}
|
||||
</Typography>
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<div className={cx('flex justify-between', 'mb-[6px]')}>
|
||||
<Typography color="var(--text-primary)" className="text-[13px]" variant="p4">
|
||||
{selectedRadioOption !== INCENTIVE_BUCKET_GROUP.TOTAL
|
||||
? `Total ${selectedRadioOption} cash collected`
|
||||
: `Threshold for incentives (b)`}
|
||||
</Typography>
|
||||
<Typography color="var(--text-primary)" className="text-[13px]" variant="p4">
|
||||
{getNumberFormat(totalCashCollectedForSelectedRadioOption, 2) || `₹0`}
|
||||
</Typography>
|
||||
</div>
|
||||
{selectedRadioOption === INCENTIVE_BUCKET_GROUP.TOTAL ? (
|
||||
<div className={cx('py-[6px]', 'flex', 'justify-between', styles.tooltipBorder)}>
|
||||
<Typography color="var(--text-primary)" className="text-[13px]" variant="p4">
|
||||
Amount eligible for incentives (a-b)
|
||||
</Typography>
|
||||
<Typography color="var(--text-primary)" className="text-[13px]" variant="p4">
|
||||
{getNumberFormat(selectedIncentiveData?.amountEligibleForIncentive, 2) || `₹0`}
|
||||
</Typography>
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<div className="flex justify-between">
|
||||
<Typography color="var(--text-primary)" className="text-[13px]" variant="p4">
|
||||
{selectedRadioOption !== INCENTIVE_BUCKET_GROUP.TOTAL
|
||||
? `Incentive earned on ${selectedRadioOption} cases`
|
||||
: `Incentives earned (${selectedIncentiveData?.incentivePercentage}% of eligible
|
||||
amount)`}
|
||||
</Typography>
|
||||
<Typography color="var(--text-primary)" className="text-[13px]" variant="p4">
|
||||
{getNumberFormat(totalIncentiveEarnedForSelectedRadioOption, 2) || `₹0`}
|
||||
</Typography>
|
||||
</div>
|
||||
</TooltipContent>
|
||||
</TooltipV2>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={cx({
|
||||
@@ -317,12 +424,30 @@ const CashEarnedChartHC: React.FC<CashEarnedChartHCProps> = props => {
|
||||
})}
|
||||
>
|
||||
<div className={styles.pieChartContainer}>
|
||||
<HighchartsReact highcharts={Highcharts} options={options} />
|
||||
{noDataInPieChart && (
|
||||
<Typography className={styles.noDataText} variant="p5">
|
||||
No cash collected for 30+ cases
|
||||
</Typography>
|
||||
)}
|
||||
<div
|
||||
className={cx(styles.incentiveSectionContainer, 'mb-[50px]', {
|
||||
'w-[35%]': showDropdown,
|
||||
'w-[30%]': !showDropdown
|
||||
})}
|
||||
>
|
||||
<div className={styles.svgContainer}>
|
||||
{shortNumberNotationWithoutTrailingZeroesAndRounding(
|
||||
totalIncentiveEarnedForSelectedRadioOption,
|
||||
2,
|
||||
'',
|
||||
1e5,
|
||||
true
|
||||
) || `₹0`}
|
||||
</div>
|
||||
</div>
|
||||
<div className="pr-[10px]">
|
||||
<HighchartsReact highcharts={Highcharts} options={options} />
|
||||
{noDataInPieChart && (
|
||||
<Typography className={cx(styles.noDataText)} variant="p5">
|
||||
No cash collected for 30+ cases
|
||||
</Typography>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<RadioGroup
|
||||
className={styles.radioContainer}
|
||||
@@ -332,7 +457,11 @@ const CashEarnedChartHC: React.FC<CashEarnedChartHCProps> = props => {
|
||||
options={DEFAULT_OPTIONS}
|
||||
labelClassName=""
|
||||
/>
|
||||
<Typography variant="p5" className={cx(styles.incentiveDisclaimerText)}>
|
||||
*Subject to month end adjustments
|
||||
</Typography>
|
||||
</div>
|
||||
<Loader show={leaderboardLoading || false} className={styles.loadingState} animate={false} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
align-items: center;
|
||||
z-index: var(--z-index-leaderboard);
|
||||
box-sizing: border-box;
|
||||
max-width: 700px;
|
||||
min-width: 695px;
|
||||
max-width: 800px;
|
||||
|
||||
.header {
|
||||
height: 44px;
|
||||
@@ -24,8 +25,15 @@
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
justify-self: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
.separator {
|
||||
height: 24px;
|
||||
width: 1px;
|
||||
border-right: 1px solid var(--navigation-blue-c2);
|
||||
}
|
||||
}
|
||||
|
||||
&.leaderBoardActive {
|
||||
@@ -482,7 +490,28 @@
|
||||
.pieChartContainer {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.incentiveSectionContainer {
|
||||
border-right: 1px solid var(--light-grayscale-border);
|
||||
height: 132px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.svgContainer {
|
||||
height: 60px;
|
||||
width: 150px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: url('/src/assets/images/incentive-note.svg');
|
||||
color: var(--incentive-green);
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
line-height: 28px;
|
||||
letter-spacing: -0.4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pieChartDashboardWidth {
|
||||
@@ -613,8 +642,17 @@
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 3px 0 24px;
|
||||
padding: 0 10px 0 10px;
|
||||
background: var(--bg-primary);
|
||||
.incentiveHeader {
|
||||
width: 30%;
|
||||
text-align: left;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
.incentiveText {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.radioContainer {
|
||||
@@ -690,10 +728,32 @@
|
||||
}
|
||||
}
|
||||
|
||||
.incentiveDisclaimerText {
|
||||
color: var(--grayscale-2);
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.noDataText {
|
||||
color: var(--grayscale-3);
|
||||
padding-left: 20px;
|
||||
position: absolute;
|
||||
top: 180px;
|
||||
left: auto;
|
||||
left: 51.5%;
|
||||
}
|
||||
|
||||
.tooltipBorder {
|
||||
border-top: 1px dashed var(--grayscale-2);
|
||||
border-bottom: 1px dashed var(--grayscale-2);
|
||||
}
|
||||
|
||||
.loadingState {
|
||||
width: 100%;
|
||||
height: 120%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
background-color: rgba(255, 255, 255, 0.6);
|
||||
animation: fadeIn 120ms;
|
||||
}
|
||||
|
||||
@@ -128,12 +128,15 @@ const Leaderboard: React.FC<LeaderboardProps> = props => {
|
||||
})}
|
||||
>
|
||||
<GridRow onClick={handleOnClick} className={cx(styles.header)}>
|
||||
<div style={{ width: 'fit-content', marginRight: 12 }}>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<Typography variant="p5" className="flex items-center">
|
||||
<span title={name ?? ''} className={cx(styles.ellipsis, 'mr-[16px]')}>
|
||||
{name ? `${name}` : ''}
|
||||
</span>
|
||||
</Typography>
|
||||
<div className={styles.separator} />
|
||||
<div className="w-fit">
|
||||
<div className="flex">
|
||||
<Typography className={cx(styles.mr8)} variant="p5">
|
||||
<span title={name ?? ''} className={styles.ellipsis} style={{ marginRight: 16 }}>
|
||||
{name ? `${name}` : ''}
|
||||
</span>
|
||||
<span className={styles.headerTextWrapper}>
|
||||
{`Last ${leaderboard?.noOfDaysCashCollected} days cash collected`}
|
||||
<span className={styles.cashCollectedAmount}>
|
||||
@@ -160,6 +163,7 @@ const Leaderboard: React.FC<LeaderboardProps> = props => {
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.separator} />
|
||||
<div style={{ width: 'fit-content' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Typography className={cx(styles.mr8)} variant="p5">
|
||||
@@ -195,7 +199,7 @@ const Leaderboard: React.FC<LeaderboardProps> = props => {
|
||||
className={styles.content}
|
||||
style={{ justifyContent: 'right', flexDirection: 'column', padding: 0 }}
|
||||
>
|
||||
<GridRow style={{ display: 'flex', flexDirection: 'row' }}>
|
||||
<GridRow className="flex justify-center">
|
||||
{performanceData ? (
|
||||
<GridColumn className={styles.left} style={{ alignItems: 'left' }}>
|
||||
<Typography variant="p5" className={styles.graphHeading}>
|
||||
|
||||
@@ -2,3 +2,15 @@ export enum PERFORMANCE_CHART_TYPE {
|
||||
LAST_30_DAYS = 'LAST_30_DAYS',
|
||||
LAST_7_DAYS = 'LAST_7_DAYS'
|
||||
}
|
||||
|
||||
export enum INCENTIVE_BUCKET_GROUP {
|
||||
TOTAL = 'Total',
|
||||
DPD_1_TO_30 = '1-30',
|
||||
DPD_30_PLUS = '30+'
|
||||
}
|
||||
|
||||
export const INCENTIVE_MONTH_KEYS = {
|
||||
incentiveData: 'incentiveData',
|
||||
prevMonthIncentiveData: 'prevMonthIncentiveData',
|
||||
monthlyIncentiveData: 'monthlyIncentiveData'
|
||||
};
|
||||
|
||||
@@ -393,7 +393,7 @@ const DashBoard = () => {
|
||||
) : null}
|
||||
|
||||
<GridColumn md={6} className={cx(styles.paddingRight_12, styles.paddingBottom_16)}>
|
||||
<GridContainer className={cx(styles.cardShadow, styles.paddingTop_16)}>
|
||||
<GridContainer className={cx(styles.cardShadow, styles.paddingTop_16, 'px-0')}>
|
||||
<CashEarnedChartHC
|
||||
titleContainerClass={styles.cashEarnedChartHCtitleClass}
|
||||
pieChartContainerClass={styles.cashEarnedChartHCpieChartClass}
|
||||
|
||||
@@ -15,7 +15,8 @@ import {
|
||||
setMonthlyPerformance,
|
||||
setPercentCompletedCases,
|
||||
setPromiseCount,
|
||||
setWeeklyPerformance
|
||||
setWeeklyPerformance,
|
||||
showLoader
|
||||
} from '../../reducers/leaderboardSlice';
|
||||
import axiosInstance, {
|
||||
ApiKeys,
|
||||
@@ -357,6 +358,7 @@ export const getLeaderboardDetails = (
|
||||
const filterParam = `?filter=${params}`;
|
||||
const url = getApiUrl(ApiKeys.GET_LEADERBOARD_DETAILS, { agentReferenceId }) + filterParam;
|
||||
return async function (dispatch: (arg0: { payload: any; type: string }) => void) {
|
||||
dispatch(showLoader(true));
|
||||
await axiosInstance
|
||||
.get(encodeURI(url), {
|
||||
headers: { donotHandleError: true },
|
||||
@@ -366,6 +368,7 @@ export const getLeaderboardDetails = (
|
||||
dispatch(setLeaderboard(response?.data));
|
||||
})
|
||||
.catch(err => {
|
||||
dispatch(showLoader(false));
|
||||
logError(err, 'Getting error from getLeaderboardDetails :: ' + url);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -23,6 +23,10 @@ export interface ILeaderboard {
|
||||
totalCurrentMonthCashCollected: any;
|
||||
totalPrevMonthCashCollected: any;
|
||||
isExpanded: boolean;
|
||||
incentiveData?: IncentiveData;
|
||||
prevMonthIncentiveData?: IncentiveData;
|
||||
monthlyIncentiveData?: IncentiveData;
|
||||
leaderboardLoading: boolean;
|
||||
}
|
||||
|
||||
export interface IPromiseCount {
|
||||
@@ -65,6 +69,18 @@ export interface IDataSet {
|
||||
lowerLevelCashCollectedInLast30Days: string | null;
|
||||
}
|
||||
|
||||
export interface IncentiveData {
|
||||
totalCashCollected?: number;
|
||||
thresholdForIncentive?: number;
|
||||
amountEligibleForIncentive?: number;
|
||||
incentivePercentage?: number;
|
||||
incentiveEarned?: number;
|
||||
total1To30DaysCashCollected?: number;
|
||||
total30PlusDaysCashCollected?: number;
|
||||
total1To30DaysIncentiveEarned?: number;
|
||||
total30PlusDaysIncentiveEarned?: number;
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
agentLevelRanking: 0,
|
||||
maxLevel: 0,
|
||||
@@ -82,7 +98,8 @@ const initialState = {
|
||||
levelLowerLimit: 0
|
||||
}
|
||||
],
|
||||
isExpanded: false
|
||||
isExpanded: false,
|
||||
leaderboardLoading: false
|
||||
} as unknown as ILeaderboard;
|
||||
|
||||
const COLOR_MAPPING = {
|
||||
@@ -111,7 +128,10 @@ const notificationSlice = createSlice({
|
||||
totalPrevMonthCashCollected,
|
||||
todaysCashCollected,
|
||||
noOfDaysCashCollected,
|
||||
dateWhenRankingVisible
|
||||
dateWhenRankingVisible,
|
||||
incentiveData,
|
||||
prevMonthIncentiveData,
|
||||
monthlyIncentiveData
|
||||
} = action.payload;
|
||||
// todo make it action.payload
|
||||
state.agentLevelRanking = agentLevelRanking;
|
||||
@@ -140,6 +160,10 @@ const notificationSlice = createSlice({
|
||||
state.totalMonthlyCashCollected = monthlyCashCollected?.totalMonthlyCashCollected;
|
||||
state.totalCurrentMonthCashCollected = totalCurrentMonthCashCollected;
|
||||
state.totalPrevMonthCashCollected = totalPrevMonthCashCollected;
|
||||
state.incentiveData = incentiveData;
|
||||
state.prevMonthIncentiveData = prevMonthIncentiveData;
|
||||
state.monthlyIncentiveData = monthlyIncentiveData;
|
||||
state.leaderboardLoading = false;
|
||||
},
|
||||
setMonthlyPerformance(state, action) {
|
||||
// state.performance = payload;
|
||||
@@ -191,6 +215,9 @@ const notificationSlice = createSlice({
|
||||
},
|
||||
setIsExpanded(state, action) {
|
||||
state.isExpanded = action.payload;
|
||||
},
|
||||
showLoader(state, action) {
|
||||
state.leaderboardLoading = action.payload;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -202,7 +229,8 @@ export const {
|
||||
setPercentCompletedCases,
|
||||
setPromiseCount,
|
||||
setCallbridgeData,
|
||||
setIsExpanded
|
||||
setIsExpanded,
|
||||
showLoader
|
||||
} = notificationSlice.actions;
|
||||
|
||||
export default notificationSlice.reducer;
|
||||
|
||||
@@ -17,6 +17,7 @@ import { getMaxInputDate } from '../pages/LiveLocationTracker/utils';
|
||||
import { DateFormat } from './DateHelper';
|
||||
|
||||
export const casesPath = `/cases/details/lan/{accountNumber}/customer/{customerReferenceId}/tab/overview`;
|
||||
|
||||
export const isObjectEmpty = (object: any) => {
|
||||
for (const prop in object) {
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
@@ -30,7 +31,8 @@ export enum DEVICES {
|
||||
IOS = 'IOS'
|
||||
}
|
||||
|
||||
export const getNumberFormat = (value: number | bigint, fractionalDigits: number) => {
|
||||
export const getNumberFormat = (value: number | bigint | undefined, fractionalDigits: number) => {
|
||||
if (!value) return;
|
||||
return new Intl.NumberFormat('en-IN', {
|
||||
style: 'currency',
|
||||
maximumFractionDigits: fractionalDigits,
|
||||
@@ -126,18 +128,20 @@ export const toFixedWithoughtRoundOff = (value = 0, decimals = 2): string => {
|
||||
export const shortNumberNotationWithoutTrailingZeroesAndRounding = (
|
||||
value = 0,
|
||||
decimals = 2,
|
||||
separator = ''
|
||||
separator = '',
|
||||
minThreshold = 1e5,
|
||||
useNumberFormat = false
|
||||
) => {
|
||||
if (typeof value !== 'number') return '';
|
||||
const parsedValue = Number(value);
|
||||
if (parsedValue >= 1e7) {
|
||||
if (parsedValue >= 1e7 && minThreshold <= 1e7) {
|
||||
return '₹' + toFixedWithoughtRoundOff(parsedValue / 1e7, decimals) + `${separator}Cr`;
|
||||
} else if (parsedValue >= 1e5) {
|
||||
} else if (parsedValue >= 1e5 && minThreshold <= 1e5) {
|
||||
return '₹' + toFixedWithoughtRoundOff(parsedValue / 1e5, decimals) + `${separator}L`;
|
||||
} else if (parsedValue >= 1e3) {
|
||||
} else if (parsedValue >= 1e3 && minThreshold <= 1e3) {
|
||||
return '₹' + toFixedWithoughtRoundOff(parsedValue / 1e3, decimals) + `${separator}K`;
|
||||
}
|
||||
return '₹' + parsedValue;
|
||||
return useNumberFormat ? getNumberFormat(parsedValue, decimals) : '₹' + parsedValue;
|
||||
};
|
||||
|
||||
export const shortNumberNotationStartingWithLakhs = (
|
||||
|
||||
Reference in New Issue
Block a user