11import { useState , useMemo } from 'react' ;
22import { v4 as uuidv4 } from 'uuid' ;
3+ import { useSelector } from 'react-redux' ;
34import getJobAnalyticsData from './api' ;
45import styles from './jobAnalytics.module.css' ;
5- import { useSelector } from 'react-redux' ;
66
77function JobAnalytics ( ) {
88 const [ dateFilter , setDateFilter ] = useState ( 'all' ) ;
@@ -20,9 +20,7 @@ function JobAnalytics() {
2020
2121 switch ( dateFilter ) {
2222 case 'weekly' :
23- if ( daysAgo <= 7 ) {
24- return true ;
25- }
23+ if ( daysAgo <= 7 ) return true ;
2624 return false ;
2725 case 'monthly' :
2826 return daysAgo <= 30 ;
@@ -59,53 +57,75 @@ function JobAnalytics() {
5957
6058 const maxApplications = Math . max ( ...processedData . map ( item => item . applications ) , 10 ) ;
6159
60+ const xAxisTicks = useMemo ( ( ) => {
61+ const ticks = [ 0 ] ;
62+ let value = 5 ;
63+ while ( value < maxApplications ) {
64+ ticks . push ( value ) ;
65+ value += 5 ;
66+ }
67+ if ( maxApplications > 0 && ticks [ ticks . length - 1 ] !== maxApplications ) {
68+ ticks . push ( maxApplications ) ;
69+ }
70+ return ticks ;
71+ } , [ maxApplications ] ) ;
72+
6273 return (
63- < div className = { `${ darkMode ? styles . jobAnalyticsContainerDarkMode : '' } ` } >
64- < div className = { `${ styles . jobAnalyticsContainer } ` } >
65- < div className = { `${ styles . chartContainer } ` } >
66- < h2 className = { `${ styles . chartTitle } ` } > Least Popular Roles</ h2 >
67- < div className = { `${ styles . chartArea } ` } >
74+ < div className = { darkMode ? styles . jobAnalyticsContainerDarkMode : '' } >
75+ < div className = { styles . jobAnalyticsContainer } >
76+ < div className = { styles . chartContainer } >
77+ < h2 className = { styles . chartTitle } > Least Popular Roles</ h2 >
78+ < div
79+ className = { styles . chartArea }
80+ style = {
81+ processedData . length > 0
82+ ? { '--x-grid-divisions' : String ( Math . max ( 1 , xAxisTicks . length - 1 ) ) }
83+ : undefined
84+ }
85+ >
6886 { processedData . length > 0 ? (
6987 < >
70- < div className = { ` ${ styles . gridLines } ` } />
71- < div className = { ` ${ styles . yAxis } ` } >
88+ < div className = { styles . gridLines } />
89+ < div className = { styles . yAxis } >
7290 { processedData . map ( item => (
73- < div key = { uuidv4 ( ) } className = { ` ${ styles . yAxisLabel } ` } >
91+ < div key = { uuidv4 ( ) } className = { styles . yAxisLabel } >
7492 { item . role }
7593 </ div >
7694 ) ) }
7795 </ div >
78- < div className = { ` ${ styles . xAxis } ` } >
79- { [ 0 , 5 , 10 , 15 , 20 , 25 ] . map ( tick => (
96+ < div className = { styles . xAxis } >
97+ { xAxisTicks . map ( tick => (
8098 < div
8199 key = { tick }
82- className = { `{${ styles . xAxisTick } ` }
83- style = { { left : `${ ( tick / maxApplications ) * 100 } %` } }
100+ className = { styles . xAxisTick }
101+ style = { {
102+ left : `${ ( tick / maxApplications ) * 100 } %` ,
103+ transform : 'translateX(-50%)' ,
104+ } }
84105 >
85- { tick <= maxApplications ? tick : '' }
106+ { tick }
86107 </ div >
87108 ) ) }
88109 </ div >
89- < div className = { ` ${ styles . barsContainer } ` } >
110+ < div className = { styles . barsContainer } >
90111 { processedData . map ( ( item , index ) => (
91112 < div
92113 key = { uuidv4 ( ) }
93- className = { ` ${ styles . barRow } ` }
114+ className = { styles . barRow }
94115 onMouseEnter = { ( ) => setHoveredBar ( index ) }
95116 onMouseLeave = { ( ) => setHoveredBar ( null ) }
96117 >
97118 < div
98- className = { ` ${ styles . bar } ` }
119+ className = { styles . bar }
99120 style = { {
100121 width : `${ ( item . applications / maxApplications ) * 100 } %` ,
101122 } }
102123 >
103- < div className = { ` ${ styles . dataLabel } ` } > { item . applications } </ div >
124+ < div className = { styles . dataLabel } > { item . applications } </ div >
104125 </ div >
105-
106126 { hoveredBar === index && (
107- < div className = { ` ${ styles . tooltip } ` } >
108- < div className = { ` ${ styles . tooltipTitle } ` } >
127+ < div className = { styles . tooltip } >
128+ < div className = { styles . tooltipTitle } >
109129 < strong > { item . role } </ strong >
110130 </ div >
111131 < div > Applications: { item . applications } </ div >
@@ -114,15 +134,15 @@ function JobAnalytics() {
114134 ) }
115135 </ div >
116136 ) ) }
117- < div className = { `${ styles . xAxisLabel } ` } > Applications</ div >
118137 </ div >
138+ < div className = { styles . xAxisLabel } > Applications</ div >
119139 </ >
120140 ) : (
121- < div className = { ` ${ styles . noData } ` } > No data available for the selected filters</ div >
141+ < div className = { styles . noData } > No data available for the selected filters</ div >
122142 ) }
123143 </ div >
124144 { processedData . length > 0 && (
125- < div className = { ` ${ styles . summaryInfo } ` } >
145+ < div className = { styles . summaryInfo } >
126146 < div >
127147 < strong > Showing:</ strong > { processedData . length } role(s)
128148 </ div >
@@ -137,30 +157,26 @@ function JobAnalytics() {
137157 </ div >
138158 ) }
139159 </ div >
140- < div className = { ` ${ styles . filtersPanel } ` } >
141- < div className = { ` ${ styles . filterGroup } ` } >
142- < div className = { ` ${ styles . filterLabel } ` } > Dates</ div >
160+ < div className = { styles . filtersPanel } >
161+ < div className = { styles . filterGroup } >
162+ < div className = { styles . filterLabel } > Dates</ div >
143163 < select
144164 value = { dateFilter }
145- onChange = { e => {
146- setDateFilter ( e . target . value ) ;
147- } }
148- className = { `${ styles . filterSelectJobAnalytics } ` }
165+ onChange = { e => setDateFilter ( e . target . value ) }
166+ className = { styles . filterSelectJobAnalytics }
149167 >
150168 < option value = "all" > ALL</ option >
151169 < option value = "weekly" > Last 7 Days</ option >
152170 < option value = "monthly" > Last 30 Days</ option >
153171 < option value = "yearly" > Last Year</ option >
154172 </ select >
155173 </ div >
156- < div className = { ` ${ styles . filterGroup } ` } >
157- < div className = { ` ${ styles . filterLabel } ` } > Role</ div >
174+ < div className = { styles . filterGroup } >
175+ < div className = { styles . filterLabel } > Role</ div >
158176 < select
159177 value = { selectedRole }
160- onChange = { e => {
161- setSelectedRole ( e . target . value ) ;
162- } }
163- className = { `${ styles . filterSelectJobAnalytics } ` }
178+ onChange = { e => setSelectedRole ( e . target . value ) }
179+ className = { styles . filterSelectJobAnalytics }
164180 >
165181 { roles . map ( role => (
166182 < option key = { role } value = { role } >
0 commit comments