Created
April 29, 2025 05:24
-
-
Save RahulMajukar/abee0adb8387511e1ff7ec3247d0ed67 to your computer and use it in GitHub Desktop.
revenue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { Box, Grid, Paper, Tab } from '@mui/material'; | |
import RevenueOverview from './RevenueOverview'; | |
import RevenueChart from './RevenueChart'; | |
import ClientRevenueTable from './ClientRevenueTable'; | |
const Dashboard = () => { | |
return ( | |
<Box sx={{ flexGrow: 1, p: 3 }}> | |
<Grid container spacing={3}> | |
<Grid item xs={12}> | |
<Paper sx={{ p: 2 }}> | |
<RevenueOverview /> | |
</Paper> | |
<Paper sx={{ p: 2 }}> | |
<RevenueChart /> | |
</Paper> | |
<Paper sx={{ p: 2 }}> | |
<ClientRevenueTable /> | |
</Paper> | |
</Grid> | |
</Grid> | |
</Box> | |
); | |
}; | |
export default Dashboard | |
----------------------------------------- | |
import { Box, Grid, Typography } from '@mui/material'; | |
import React, { useEffect, useState } from 'react'; | |
const RevenueOverviewData = { | |
revenueForecastYTD: 8000000, | |
revenueTarget: 10000000, | |
revenueYTD: 5000000, | |
actualProgressVsTarget: 50, | |
actualPlusForecastVsTarget: 80, | |
}; | |
const RevenueOverview = () => { | |
const [revenueData, setRevenueData] = useState(null); | |
useEffect(() => { | |
const fetchData = async () => { | |
setRevenueData(RevenueOverviewData); | |
}; | |
fetchData(); | |
}, []); | |
if (!revenueData) return null; | |
const formatCurrency = (value) => `$${(value / 1000000).toFixed(1)}M`; | |
const formatPercentage = (value) => `${value.toFixed(2)}%`; | |
// KPI items array | |
const kpiItems = [ | |
{ | |
label: 'Revenue Forecast YTD', | |
value: formatCurrency(revenueData.revenueForecastYTD), | |
gridSize: 2, | |
}, | |
{ | |
label: 'Revenue Target', | |
value: formatCurrency(revenueData.revenueTarget), | |
gridSize: 2, | |
}, | |
{ | |
label: 'Revenue YTD', | |
value: formatCurrency(revenueData.revenueYTD), | |
gridSize: 2, | |
}, | |
{ | |
label: 'Actual Progress vs. Target', | |
value: formatPercentage(revenueData.actualProgressVsTarget), | |
gridSize: 3, | |
}, | |
{ | |
label: 'Actual + Forecast vs. Target', | |
value: formatPercentage(revenueData.actualPlusForecastVsTarget), | |
gridSize: 3, | |
}, | |
]; | |
return ( | |
<Grid container spacing={4} justifyContent="space-between"> | |
{kpiItems.map((item, index) => ( | |
<Grid item key={index} xs={12} md={item.gridSize}> | |
<Box p={2} sx={{ borderRadius: 2, boxShadow: 2, height: '100%' }}> | |
<Typography variant="subtitle1" color="text.secondary" gutterBottom> | |
{item.label} | |
</Typography> | |
<Typography variant="h4" color="#000d80"> | |
{item.value} | |
</Typography> | |
</Box> | |
</Grid> | |
))} | |
</Grid> | |
); | |
}; | |
export default RevenueOverview; | |
------------------------------------------ | |
import React, { useEffect, useState } from 'react'; | |
import Highcharts from 'highcharts/highstock'; | |
import HighchartsReact from 'highcharts-react-official'; | |
import 'highcharts/highcharts-more'; // For columnrange | |
import 'highcharts/modules/exporting'; // For chart menu (import only, no need to call) | |
const RevenueChart = () => { | |
const [options, setOptions] = useState({}); | |
useEffect(() => { | |
// Generate floating data for 24 months: Jan 2024 - Dec 2025 | |
const floatingData = []; | |
let startRevenue = 200; // Starting revenue (in Millions) | |
for (let year = 2024; year <= 2025; year++) { | |
for (let month = 0; month < 12; month++) { | |
const low = startRevenue + Math.random() * 5; | |
const high = low + Math.random() * 5; | |
floatingData.push({ | |
x: Date.UTC(year, month, 1), | |
low: parseFloat(low.toFixed(2)), | |
high: parseFloat(high.toFixed(2)), | |
}); | |
startRevenue += Math.random() * 2; | |
} | |
} | |
setOptions({ | |
chart: { | |
type: 'columnrange', | |
inverted: false, | |
}, | |
title: { | |
text: 'Revenue Forecast - 2024 to 2025', | |
}, | |
legend: { | |
enabled: true, | |
layout: 'horizontal', | |
align: 'center', | |
verticalAlign: 'bottom', | |
itemStyle: { | |
fontWeight: 'normal', | |
fontSize: '12px', | |
color: '#333', | |
}, | |
symbolRadius: 6, | |
symbolHeight: 10, | |
symbolWidth: 10, | |
itemMarginTop: 5, | |
itemMarginBottom: 5, | |
}, | |
exporting: { | |
enabled: true, // ✅ Enable Chart Menu (3 lines) | |
}, | |
credits: { | |
enabled: false, // ✅ Hide Highcharts watermark | |
}, | |
rangeSelector: { | |
selected: 4, | |
buttons: [ | |
{ type: 'month', count: 1, text: '1m' }, | |
{ type: 'month', count: 3, text: '3m' }, | |
{ type: 'month', count: 6, text: '6m' }, | |
{ type: 'ytd', text: 'YTD' }, | |
{ type: 'year', count: 1, text: '1y' }, | |
{ type: 'all', text: 'All' }, | |
], | |
}, | |
xAxis: { | |
type: 'datetime', | |
}, | |
yAxis: { | |
title: { | |
text: 'Revenue (in Millions)', | |
}, | |
}, | |
tooltip: { | |
useHTML: true, | |
backgroundColor: '#f8f9fa', | |
borderColor: '#dee2e6', | |
borderRadius: 4, | |
borderWidth: 1, | |
padding: 8, | |
shadow: false, | |
shared: true, | |
split: false, | |
formatter: function () { | |
const date = Highcharts.dateFormat('%B %Y', this.x); | |
const categories = [ | |
{ name: 'Servicing Fee', value: '5.1', color: '#3c5d99' }, | |
{ name: 'Markets Products', value: '9.6', color: '#5470c6' }, | |
{ name: 'Software & Other', value: '3.6', color: '#91cc75' }, | |
{ name: 'Nil', value: '2.9', color: '#66bb6a' }, | |
]; | |
const categoryList = categories.map(cat => ` | |
<div style="display: flex; justify-content: space-between; margin-bottom: 4px; font-size: 12px;"> | |
<div style="display: flex; align-items: center;"> | |
<div style="width: 10px; height: 10px; background-color: ${cat.color}; margin-right: 6px;"></div> | |
<span>${cat.name}</span> | |
</div> | |
<span>${cat.value}</span> | |
</div> | |
`).join(''); | |
const totalValue = this.points && this.points[0] ? (this.points[0].point.high || 0) : 0; | |
return ` | |
<div style="min-width: 180px;"> | |
<div style="display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #dee2e6; padding-bottom: 4px; margin-bottom: 8px;"> | |
<div style="font-size: 13px; font-weight: bold;">${date}</div> | |
<div style="font-size: 14px; font-weight: bold; color: #28a745;">$${totalValue.toFixed(1)}M</div> | |
</div> | |
<div style="margin-bottom: 8px;"> | |
${categoryList} | |
</div> | |
<div style="display: flex; justify-content: space-between; border-top: 1px solid #dee2e6; padding-top: 4px; margin-top: 4px; font-size: 11px; color: #666;"> | |
<div>Revenue Details Below</div> | |
<div>More Revenue Details</div> | |
</div> | |
</div> | |
`; | |
}, | |
}, | |
series: [ | |
{ | |
name: 'Revenue', | |
data: floatingData.map(item => [item.x, item.low, item.high]), | |
color: '#66bb6a', | |
dataLabels: { | |
enabled: false, | |
}, | |
}, | |
], | |
navigator: { | |
enabled: true, | |
height: 40, | |
}, | |
}); | |
}, []); | |
return ( | |
<div> | |
<HighchartsReact | |
highcharts={Highcharts} | |
constructorType={'stockChart'} | |
options={options} | |
/> | |
</div> | |
); | |
}; | |
export default RevenueChart; | |
-------------------------------------- | |
import React, { useState, useEffect } from 'react'; | |
import { Box, Typography } from '@mui/material'; | |
import { DataGrid } from '@mui/x-data-grid'; | |
const columns = [ | |
{ field: 'clientName', headerName: 'Client Name', flex: 2, minWidth: 200 }, | |
{ field: 'product', headerName: 'Product', flex: 2, minWidth: 180 }, | |
{ field: 'segment', headerName: 'Segment', flex: 1.5, minWidth: 150 }, | |
{ field: 'revenue', headerName: 'Revenue', type: 'number', flex: 1, minWidth: 130 }, | |
{ field: 'country', headerName: 'Country', flex: 1, minWidth: 120 }, | |
{ field: 'date', headerName: 'Date', flex: 1, minWidth: 120 }, | |
]; | |
// Example static data (you can later replace with an API call) | |
const rows = [ | |
{ id: 1, clientName: 'Lorem Ipsum Account AGI Alpha - MO', product: 'Data Solutions', segment: 'Asset Owner', revenue: 1891000, country: 'Austria', date: '3/17/2024' }, | |
{ id: 2, clientName: 'Lorem Ipsum Account Nam Alpha - MO', product: 'Data Solutions', segment: 'Asset Manager', revenue: 491000, country: 'Luxembourg', date: '2/3/2024' }, | |
{ id: 3, clientName: 'Lorem Ipsum Account AGI Alpha - MO', product: 'Data Solutions', segment: 'Alternatives', revenue: 510000, country: 'Italy', date: '1/25/2024' }, | |
{ id: 4, clientName: 'Lorem Ipsum Account Nam Alpha - MO', product: 'Global Markets', segment: 'Alternatives', revenue: 791000, country: 'Germany', date: '2/10/2024' }, | |
{ id: 5, clientName: 'SF_Account AGI Alpha - MO and BO impact', product: 'Performance & Analytics', segment: 'Alternatives', revenue: 991000, country: 'Brazil', date: '1/24/2024' }, | |
{ id: 6, clientName: 'SF_Account AGI Alpha - MO and BO impact', product: 'Custody', segment: 'Alternatives', revenue: 519000, country: 'Japan', date: '4/01/2024' }, | |
{ id: 7, clientName: 'SF_Account AGI Alpha - MO and BO impact', product: 'Custody', segment: 'Asset Manager', revenue: 481000, country: 'India', date: '4/2/2024' }, | |
]; | |
const ClientRevenueTable = () => { | |
const [data, setData] = useState([]); | |
useEffect(() => { | |
// Simulate fetching data | |
setData(rows); | |
}, []); | |
return ( | |
<Box> | |
<Typography variant="h5" gutterBottom> | |
April 2024 Client Revenue Report | |
</Typography> | |
<DataGrid | |
rows={data} | |
columns={columns} | |
pageSize={7} | |
rowsPerPageOptions={[7]} | |
disableSelectionOnClick | |
sx={{ | |
'& .MuiDataGrid-columnHeaders': { | |
backgroundColor: '#f5f5f5', | |
fontWeight: 'bold', | |
}, | |
}} | |
/> | |
</Box> | |
); | |
}; | |
export default ClientRevenueTable; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
npm install @mui/material @mui/x-data-grid highcharts highcharts-react-official