Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
9a9a33c
BM Dashboard: restore Financials Tracking (auth via httpService), fix…
shashankm9 Oct 10, 2025
4bbf2a5
Merge branch 'development' into fix/bm-expenditure-charts
shashankm9 Oct 10, 2025
3f1f847
Toggle Bio Request Issues Solved
Amalesh-A Jan 6, 2026
b747e1c
Toggle Bio Request Issues Solved
Amalesh-A Jan 6, 2026
3d8bdf7
Toggle Bio Request Issues Solved
Amalesh-A Jan 7, 2026
cd10dc9
Toggle Bio Request Issues Solved
Amalesh-A Jan 7, 2026
b89f37f
Merge branch 'development' into Amalesh-togglebio
Amalesh-A Jan 7, 2026
ece2ad2
Merge branch 'development' into Amalesh-togglebio
Amalesh-A Jan 12, 2026
b750a58
fix: remove comments
ShravyaKudlu Jan 25, 2026
af0682a
fix: module.css
ShravyaKudlu Jan 29, 2026
3409447
fix: routing.css
ShravyaKudlu Jan 29, 2026
3cbc36b
fix: routes
ShravyaKudlu Feb 8, 2026
71fdb26
fix: lintErrorsAgain
ShravyaKudlu Feb 8, 2026
0ef344f
Merge remote-tracking branch 'origin' into shravya/bugfix/resourceman…
ShravyaKudlu Feb 8, 2026
0165073
Add BM Dashboard Expenditure Pie Charts with mock data
shashankm9 Feb 9, 2026
9bca7ea
Remove duplicate imports in routes
shashankm9 Feb 9, 2026
d118b13
Fix unsaved changes prompt after template save
Neeraj-Kondaveeti Feb 9, 2026
63b282e
fix: resolve merge conflicts in WeeklyProjectSummary - remove misplac…
shashankm9 Feb 10, 2026
6908806
Fix prettier formatting - add trailing newline
shashankm9 Feb 11, 2026
828a62c
Fix dark mode text visibility and increase font sizes in cost charts
shashankm9 Feb 11, 2026
9ac68ec
Deduplicate chart styles and markers
shashankm9 Feb 13, 2026
98574e6
Sayali - Add: Real-Time Profile Filtering System
sayali-2308 Feb 13, 2026
55e6c6e
Fix: Center align filter bar and content (Test Case 5)
sayali-2308 Feb 17, 2026
451dc55
Sayali: add search functionality to community members page
sayali-2308 Feb 19, 2026
09050f1
fix: add PropTypes and eslint disable for SonarCloud
sayali-2308 Feb 19, 2026
d51d2a9
fix: center align no results message and fix filter bar layout
sayali-2308 Feb 21, 2026
2184b78
Resolving merge conflicts
Amalesh-A Feb 23, 2026
9e34895
Resolving merge conflicts
Amalesh-A Feb 23, 2026
e54b7fd
style: add dark mode and mobile responsive styles for profile filtering
sayali-2308 Feb 23, 2026
c84cdea
Resolved the broken logic
Amalesh-A Feb 24, 2026
9d6eb93
Merge remote-tracking branch 'origin/development' into fix/bm-expendi…
shashankm9 Feb 25, 2026
5bf8f19
Fix Hiring Analytics chart rendering and improve layout styling
Neeraj-Kondaveeti Feb 25, 2026
e34cd77
fix: fix dark mode score colors and pagination visibility in MemberList
sayali-2308 Mar 2, 2026
99b5f97
fix(faq): make unanswered question feedback persistent and show backe…
linh2020 Mar 3, 2026
d545160
chore(frontend): sync yarn.lock with package.json
linh2020 Mar 3, 2026
8e714b8
feat: add search reviewers feature to weekly PR grading screen
sayali-2308 Mar 4, 2026
09560bd
fix(orgSummaryEmail): Fixed Total Org Weekly Summary Email Flow
DiyaWadhwani Mar 6, 2026
2ad6f87
Merge pull request #4953 from OneCommunityGlobal/Diya_Fix_TotalOrg_We…
one-community Mar 7, 2026
c88a7aa
Merge pull request #4817 from OneCommunityGlobal/Neeraj_Hotfix_JobBui…
one-community Mar 7, 2026
e1eb951
Merge pull request #4896 from OneCommunityGlobal/Neeraj_Fix_HiringAna…
one-community Mar 7, 2026
3501877
Merge branch 'fix/bm-expenditure-charts' of https://github.com/OneCom…
shashankm9 Mar 7, 2026
4d825ff
fix: correct .stylelintrc syntax broken by merge conflict
shashankm9 Mar 7, 2026
91b26ba
fix: restore side-by-side layout for Financials Tracking charts
shashankm9 Mar 7, 2026
cd0c6b4
Merge branch 'development' into fix/bm-expenditure-charts
shashankm9 Mar 7, 2026
465b56f
Merge origin/development into shravya/bugfix/resourcemangement-3399
ShravyaKudlu Mar 7, 2026
a03ec39
Merge pull request #4193 from OneCommunityGlobal/fix/bm-expenditure-c…
one-community Mar 7, 2026
f66beab
Venkataramanan fix: timer shadow and countdown text size
Mar 7, 2026
cb63a3e
Venkataramanan fix: progress bar colors in team member tasks
Mar 7, 2026
8e45f93
Merge pull request #4936 from OneCommunityGlobal/Sayali_PR_Grading_Se…
one-community Mar 7, 2026
d65a38b
Merge pull request #4837 from OneCommunityGlobal/Sayali_Real_Time_Pro…
one-community Mar 7, 2026
2f2d11e
Merge pull request #4867 from OneCommunityGlobal/Sayali_Add_Search_To…
one-community Mar 7, 2026
0c50c29
Merge pull request #4931 from OneCommunityGlobal/linh_fix_faq_log_que…
one-community Mar 7, 2026
e9087d3
chore(deps): bump dompurify from 3.3.1 to 3.3.2
dependabot[bot] Mar 7, 2026
3f30e39
chore(deps): bump immutable from 5.1.4 to 5.1.5
dependabot[bot] Mar 7, 2026
42f0e92
Merge pull request #4946 from OneCommunityGlobal/dependabot/npm_and_y…
EvianTan Mar 7, 2026
78ed0eb
Merge pull request #4940 from OneCommunityGlobal/dependabot/npm_and_y…
EvianTan Mar 7, 2026
159e522
Merge pull request #4957 from OneCommunityGlobal/venkataramanan_fix_p…
one-community Mar 8, 2026
dbb0202
Merge pull request #4956 from OneCommunityGlobal/venkataramanan_fix_t…
one-community Mar 8, 2026
d98e58d
Merge pull request #4768 from OneCommunityGlobal/shravya/bugfix/resou…
one-community Mar 8, 2026
e79cb9a
Merge pull request #4679 from OneCommunityGlobal/Amalesh-togglebio
one-community Mar 8, 2026
4472611
Venkataramanan fix: Assign Team and Projects Popup formatting
Mar 10, 2026
9a8d1e5
Venkataramanan fix: Assign Team and Projects Popup formatting
Mar 10, 2026
88828ef
Venkataramanan fix: Assign Team and Projects Popup formatting
Mar 10, 2026
f6ff81c
fix: sonarqube errors
Mar 10, 2026
d836c69
fix: sonarqube errors
Mar 10, 2026
0d2670b
Venkataramanan fix: quick setup team code issue
Mar 11, 2026
b1bc4c0
Venkataramanan fix: confirm button height
Mar 11, 2026
a077404
Merge pull request #4976 from OneCommunityGlobal/venkataramanan_fix_q…
one-community Mar 11, 2026
565d0ae
Merge pull request #4969 from OneCommunityGlobal/venkataramanan_fix_a…
one-community Mar 11, 2026
70506d1
fix(dashboard): Fix Dashboard + Leaderboard UI
DiyaWadhwani Mar 12, 2026
806a04f
chore(test): fix failing test
DiyaWadhwani Mar 12, 2026
9b08ab4
chore(test): fix failing test
DiyaWadhwani Mar 12, 2026
84e8526
Merge pull request #4979 from OneCommunityGlobal/Diya_Fix_Dashboard_UI
one-community Mar 12, 2026
8ea0ec8
fix(UI): Fixed Task Page UI
DiyaWadhwani Mar 12, 2026
2b37d22
Merge pull request #4980 from OneCommunityGlobal/Diya_Fix_TaskUI
one-community Mar 12, 2026
5e388be
fix(UI): Fixed People Report UI
DiyaWadhwani Mar 12, 2026
7f15d6e
Merge pull request #4981 from OneCommunityGlobal/Diya_Fix_PeopleReportUI
one-community Mar 12, 2026
496df81
Venkataramanan fix: Countdown formatting
Mar 12, 2026
964b58b
Venkataramanan fix: Countdown formatting
Mar 12, 2026
48ad605
Merge pull request #4984 from OneCommunityGlobal/venkataramanan_fix_c…
one-community Mar 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"date-fns-tz": "^2.0.1",
"dayjs": "^1.11.13",
"diff": "^8.0.3",
"dompurify": "^3.2.5",
"dompurify": "^3.3.2",
"elliptic": "^6.6.1",
"font-awesome": "^4.7.0",
"fs-extra": "^11.3.0",
Expand Down Expand Up @@ -129,7 +129,9 @@
},
"resolutions": {
"react": "18.3.1",
"react-dom": "18.3.1"
"react-dom": "18.3.1",
"mdn-data": "2.12.2",
"ansi-escapes": "7.1.1"
},
"packageManager": "yarn@1.22.22",
"scripts": {
Expand Down
167 changes: 126 additions & 41 deletions src/components/ApplicantVolunteerRatio/ApplicantVolunteerRatio.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,47 @@ import 'react-datepicker/dist/react-datepicker.css';

function ApplicantVolunteerRatio() {
const darkMode = useSelector(state => state.theme.darkMode);

const [data, setData] = useState([]);
const [allRoles, setAllRoles] = useState([]); // Store all available roles
const [allRoles, setAllRoles] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [selectedRoles, setSelectedRoles] = useState([]);
const [startDate, setStartDate] = useState(null);
const [endDate, setEndDate] = useState(null);
const [validationError, setValidationError] = useState('');
const [viewMode, setViewMode] = useState('count');

// Fetch all available roles (without filtering)
// Fetch all available roles
useEffect(() => {
const fetchAllRoles = async () => {
try {
const response = await getAllApplicantVolunteerRatios({});
const apiData = response.data;

// Get all unique roles
const uniqueRoles = [...new Set(apiData.map(item => item.role))];
const roleOptions = uniqueRoles.map(role => ({ label: role, value: role }));

setAllRoles(roleOptions);

// Set all roles as selected by default
setSelectedRoles(roleOptions);
} catch (err) {
// Error fetching all roles
setError('Failed to load roles. Please try again.');
}
};

fetchAllRoles();
}, []);

// Fetch filtered data based on selected roles and date range
// Fetch filtered data
useEffect(() => {
const fetchFilteredData = async () => {
// Validate date range: start must be before or equal to end
if (startDate && endDate && startDate > endDate) {
setValidationError('Start date must be earlier than or equal to End date.');
setData([]);
setLoading(false);
return;
}

// clear previous validation error when dates are valid
if (validationError) setValidationError('');

if (selectedRoles.length === 0) {
Expand All @@ -64,22 +60,16 @@ function ApplicantVolunteerRatio() {
try {
setLoading(true);

// Prepare filters
const filters = {};
if (startDate) {
filters.startDate = startDate.toISOString().split('T')[0]; // Format as YYYY-MM-DD
}
if (endDate) {
filters.endDate = endDate.toISOString().split('T')[0]; // Format as YYYY-MM-DD
}
if (startDate) filters.startDate = startDate.toISOString().split('T')[0];
if (endDate) filters.endDate = endDate.toISOString().split('T')[0];
if (selectedRoles.length > 0) {
filters.roles = selectedRoles.map(role => role.value).join(',');
}

const response = await getAllApplicantVolunteerRatios(filters);
const apiData = response.data;

// Transform API data to match chart format
const transformedData = apiData.map(item => ({
role: item.role,
applicants: item.totalApplicants,
Expand All @@ -88,23 +78,35 @@ function ApplicantVolunteerRatio() {

setData(transformedData);
} catch (err) {
// Error fetching applicant volunteer ratio data
setError('Failed to load data. Please try again.');
} finally {
setLoading(false);
}
};

fetchFilteredData();
}, [startDate, endDate, selectedRoles]); // Re-fetch when date range or selected roles change
}, [startDate, endDate, selectedRoles]);

// Filter and transform data for chart
const chartData = useMemo(
() => data.filter(d => selectedRoles.map(r => r.value).includes(d.role)),
[data, selectedRoles],
);
// Prepare chart data
const chartData = useMemo(() => {
const filtered = data.filter(d => selectedRoles.map(r => r.value).includes(d.role));

if (viewMode === 'percentage') {
return filtered.map(item => {
const percentage =
item.applicants > 0 ? Number(((item.hired / item.applicants) * 100).toFixed(1)) : 0;

// Apply dark mode to document body
return {
...item,
hiredPercentage: percentage,
};
});
}

return filtered;
}, [data, selectedRoles, viewMode]);

// Apply dark mode
useEffect(() => {
if (darkMode) {
document.body.classList.add('dark-mode-body');
Expand Down Expand Up @@ -138,10 +140,12 @@ function ApplicantVolunteerRatio() {
return (
<div className={`${styles.page} ${darkMode ? styles.dark : ''}`}>
<h2 className={styles.heading}>Number of People Hired vs. Total Applications</h2>

{/* Filters */}
<div className={styles.filters}>
<div className={styles.filterGroup}>
<label htmlFor="start-date" className={styles.label}>
Date Range:{' '}
Date Range:
</label>
<div className={styles.dateInputWrapper}>
<DatePicker
Expand Down Expand Up @@ -173,9 +177,10 @@ function ApplicantVolunteerRatio() {
</div>
)}
</div>

<div className={styles.filterGroupInline}>
<label htmlFor="role-select" className={styles.label}>
Role:{' '}
Role:
</label>
<Select
id="role-select"
Expand All @@ -189,39 +194,119 @@ function ApplicantVolunteerRatio() {
/>
</div>
</div>

{/* Toggle Buttons */}
<div style={{ marginBottom: '12px', display: 'flex', gap: '8px' }}>
<button
type="button"
onClick={() => setViewMode('count')}
style={{
padding: '6px 12px',
cursor: 'pointer',
backgroundColor: viewMode === 'count' ? '#1976d2' : '#e0e0e0',
color: viewMode === 'count' ? '#fff' : '#000',
border: 'none',
borderRadius: '4px',
}}
>
Count View
</button>

<button
type="button"
onClick={() => setViewMode('percentage')}
style={{
padding: '6px 12px',
cursor: 'pointer',
backgroundColor: viewMode === 'percentage' ? '#1976d2' : '#e0e0e0',
color: viewMode === 'percentage' ? '#fff' : '#000',
border: 'none',
borderRadius: '4px',
}}
>
Percentage View
</button>
</div>

{chartData.length > 0 ? (
<div className={styles.chartContainer}>
<ResponsiveContainer width="100%" height={400}>
<ResponsiveContainer width="100%" height={350}>
<BarChart
data={chartData}
layout="vertical"
margin={{ top: 20, right: 40, left: 80, bottom: 20 }}
barCategoryGap={24}
barSize={16}
>
<XAxis
type="number"
label={{
value: 'Percentage of People Hired vs. Total Applications',
position: 'insideBottom',
offset: -5,
}}
allowDecimals={false}
domain={viewMode === 'percentage' ? [0, 100] : ['auto', 'auto']}
allowDecimals={viewMode === 'percentage'}
/>

<YAxis
dataKey="role"
type="category"
width={180}
label={{ value: 'Name of Role', angle: -90, position: 'insideLeft' }}
label={{ value: 'Role', angle: -90, position: 'insideLeft' }}
/>

<Tooltip />
<Bar dataKey="applicants" fill="#1976d2" name="Total Applicants">
<LabelList dataKey="applicants" position="right" />
</Bar>
<Bar dataKey="hired" fill="#43a047" name="Total Hired">
<LabelList dataKey="hired" position="right" />
</Bar>

{viewMode === 'count' ? (
<>
<Bar dataKey="applicants" fill="#1976d2">
<LabelList dataKey="applicants" position="right" />
</Bar>

<Bar dataKey="hired" fill="#43a047">
<LabelList dataKey="hired" position="right" />
</Bar>
</>
) : (
<Bar dataKey="hiredPercentage" fill="#43a047">
<LabelList
dataKey="hiredPercentage"
position="right"
formatter={value => `${value}%`}
/>
</Bar>
)}
</BarChart>
</ResponsiveContainer>

{/* Manual Legend */}
<div
style={{
display: 'flex',
justifyContent: 'center',
gap: '16px',
marginTop: '12px',
fontWeight: 500,
}}
>
{viewMode === 'count' ? (
<>
<span style={{ color: '#1976d2' }}>■ Total Applications</span>
<span style={{ color: '#43a047' }}>■ People Hired</span>
</>
) : (
<span style={{ color: '#43a047' }}>■ People Hired (%)</span>
)}
</div>

{/* Axis Title */}
<div
style={{
textAlign: 'center',
marginTop: '10px',
fontWeight: 500,
}}
>
{viewMode === 'percentage'
? 'Percentage of People Hired (%)'
: 'Number of Applications / Hires'}
</div>
</div>
) : (
<div className={styles.noData}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Container */
.page {
max-width: 900px;
max-width: 1200px;
margin: 0 auto;
padding: 24px;
}
Expand Down Expand Up @@ -74,7 +74,7 @@
/* Chart Container */
.chartContainer {
width: 100%;
height: 400px;
height: auto;
}

/* No Data */
Expand Down
Loading
Loading