Skip to content

Commit c2f6a8f

Browse files
committed
fix: updated charts and summary tiles to reflect on role change
1 parent f10ff4b commit c2f6a8f

3 files changed

Lines changed: 107 additions & 39 deletions

File tree

src/components/JobCCDashboard/JobAnalytics/JobAnalytics.jsx

Lines changed: 90 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import hasPermission from '../../../utils/permissions';
3737
import { ENDPOINTS } from '../../../utils/URL';
3838

3939
const ROLE_OPTIONS = [
40+
'All Roles',
4041
'Frontend Developer',
4142
'Backend Developer',
4243
'Data Analyst',
@@ -112,15 +113,15 @@ class AnalyticsService {
112113
return new Promise(resolve => setTimeout(resolve, ms));
113114
}
114115

115-
static async fetchData(dateRange, comparisonPeriod) {
116+
static async fetchData(dateRange, comparisonPeriod, role) {
116117
try {
117118
// TODO: Replace with real API when ready
118119
// const response = await fetch(`${CONFIG.API.ENDPOINTS.ANALYTICS}`, { ... });
119120
// if (!response.ok) throw new Error('Failed to fetch analytics data');
120121
// return await response.json();
121122

122123
await this.simulateApiDelay();
123-
return this.generateMockAnalyticsData(dateRange, comparisonPeriod);
124+
return this.generateMockAnalyticsData(dateRange, comparisonPeriod, role);
124125
} catch (err) {
125126
// eslint-disable-next-line no-console
126127
console.error('Analytics fetch error:', err);
@@ -136,7 +137,7 @@ class AnalyticsService {
136137
return min + (array[0] % (max - min + 1));
137138
}
138139

139-
static generateMockAnalyticsData(dateRange, comparisonPeriod) {
140+
static generateMockAnalyticsData(dateRange, comparisonPeriod, role = 'All Roles') {
140141
const genSeries = (startDate, endDate, offset = 0) => {
141142
const data = [];
142143
const start = new Date(startDate);
@@ -145,16 +146,39 @@ class AnalyticsService {
145146
for (let i = 0; i <= diffDays; i += 1) {
146147
const date = new Date(start);
147148
date.setDate(date.getDate() + i);
149+
let roleOffset = 0;
150+
switch (role) {
151+
case 'Frontend Developer':
152+
roleOffset = 50;
153+
break;
154+
case 'Backend Developer':
155+
roleOffset = 30;
156+
break;
157+
case 'Data Analyst':
158+
roleOffset = 20;
159+
break;
160+
case 'Product Manager':
161+
roleOffset = 10;
162+
break;
163+
case 'UX Designer':
164+
roleOffset = 15;
165+
break;
166+
default:
167+
roleOffset = 0;
168+
}
148169
data.push({
149170
date: date.toISOString().split('T')[0],
150171
displayDate: date.toLocaleDateString('en-US', CONFIG.DATE_FORMAT.display),
151172

152173
// ✅ Secure dummy simulation values:
153-
users: this.secureRandom(700 + offset, 1000 + offset),
154-
pageViews: this.secureRandom(4000 + offset * 5, 6000 + offset * 5),
174+
users: this.secureRandom(700 + offset + roleOffset, 1000 + offset + roleOffset),
175+
pageViews: this.secureRandom(
176+
4000 + offset * 5 + roleOffset * 10,
177+
6000 + offset * 5 + roleOffset * 10,
178+
),
155179
sessions: this.secureRandom(
156-
Math.floor(600 + offset * 0.8),
157-
Math.floor(1000 + offset * 0.8),
180+
Math.floor(600 + offset * 0.8 + roleOffset * 0.5),
181+
Math.floor(1000 + offset * 0.8 + roleOffset * 0.5),
158182
),
159183
bounceRate: this.secureRandom(35, 55),
160184
avgDuration: this.secureRandom(180, 300),
@@ -177,18 +201,18 @@ class AnalyticsService {
177201
previousPeriod: genSeries(start, end, 0),
178202
metrics: {
179203
current: {
180-
totalUsers: 23456,
181-
totalPageViews: 145678,
182-
totalSessions: 18934,
183-
avgBounceRate: 42.3,
184-
avgSessionDuration: 245,
204+
totalUsers: 23456 + (role === 'All Roles' ? 0 : this.secureRandom(1000, 3000)), // Simulate role-based user count
205+
totalPageViews: 145678 + (role === 'All Roles' ? 0 : this.secureRandom(5000, 15000)), // Simulate role-based page views
206+
totalSessions: 18934 + (role === 'All Roles' ? 0 : this.secureRandom(800, 2000)), // Simulate role-based sessions
207+
avgBounceRate: 42.3 + (role === 'All Roles' ? 0 : this.secureRandom(-5, 5)), // Simulate role-based bounce rate
208+
avgSessionDuration: 245 + (role === 'All Roles' ? 0 : this.secureRandom(-30, 30)), // Simulate role-based session duration
185209
},
186210
previous: {
187-
totalUsers: 21234,
188-
totalPageViews: 132456,
189-
totalSessions: 17123,
190-
avgBounceRate: 45.7,
191-
avgSessionDuration: 220,
211+
totalUsers: 21234 + (role === 'All Roles' ? 0 : this.secureRandom(1000, 3000)),
212+
totalPageViews: 132456 + (role === 'All Roles' ? 0 : this.secureRandom(5000, 15000)),
213+
totalSessions: 17123 + (role === 'All Roles' ? 0 : this.secureRandom(800, 2000)),
214+
avgBounceRate: 45.7 + (role === 'All Roles' ? 0 : this.secureRandom(-5, 5)),
215+
avgSessionDuration: 220 + (role === 'All Roles' ? 0 : this.secureRandom(-30, 30)),
192216
},
193217
},
194218
deviceBreakdown: [
@@ -208,7 +232,7 @@ class AnalyticsService {
208232
}
209233

210234
// ======================== HOOKS ========================
211-
function useAnalyticsData(dateRange, comparisonPeriod) {
235+
function useAnalyticsData(dateRange, comparisonPeriod, selectedRole) {
212236
const [data, setData] = useState(null);
213237
const [loading, setLoading] = useState(true);
214238
const [error, setError] = useState(null);
@@ -217,19 +241,14 @@ function useAnalyticsData(dateRange, comparisonPeriod) {
217241
setLoading(true);
218242
setError(null);
219243
try {
220-
const res = await AnalyticsService.fetchData(dateRange, comparisonPeriod);
244+
const res = await AnalyticsService.fetchData(dateRange, comparisonPeriod, selectedRole);
221245
setData(res);
222246
} catch (e) {
223247
setError(e.message || 'Failed to load analytics');
224248
} finally {
225249
setLoading(false);
226250
}
227-
}, [dateRange, comparisonPeriod]);
228-
229-
useEffect(() => {
230-
fetchData();
231-
}, [fetchData]);
232-
251+
}, [dateRange, comparisonPeriod, selectedRole]);
233252
return { data, loading, error, refetch: fetchData };
234253
}
235254

@@ -439,8 +458,14 @@ function JobAnalytics({ darkMode, role, hasPermission: hasPerm }) {
439458
const { data: analyticsData, loading, error, refetch } = useAnalyticsData(
440459
dateRange,
441460
comparisonPeriod,
461+
selectedRole,
442462
);
443463

464+
useEffect(() => {
465+
// Refetch data when role changes
466+
refetch();
467+
}, [selectedRole, refetch]);
468+
444469
const mergedData = useMemo(() => {
445470
if (!analyticsData?.currentPeriod || !analyticsData?.previousPeriod) return [];
446471
return analyticsData.currentPeriod.map((d, i) => ({
@@ -472,21 +497,47 @@ function JobAnalytics({ darkMode, role, hasPermission: hasPerm }) {
472497
};
473498
}, [analyticsData]);
474499

500+
const filteredDeviceBreakdown = useMemo(() => {
501+
if (!analyticsData?.deviceBreakdown) return [];
502+
const multiplier =
503+
selectedRole === 'All Roles' ? 1 : 1 + ROLE_OPTIONS.indexOf(selectedRole) * 0.05;
504+
const dateFactor = dateRange ? 1 + Math.random() * 0.1 : 1;
505+
506+
return analyticsData.deviceBreakdown.map(d => ({
507+
...d,
508+
value: Math.round(d.value * multiplier * dateFactor),
509+
previousValue: Math.round(d.previousValue * multiplier * dateFactor),
510+
sessions: Math.round(d.sessions * multiplier * dateFactor),
511+
}));
512+
}, [analyticsData, selectedRole, dateRange, comparisonPeriod]);
513+
514+
const filteredTrafficSources = useMemo(() => {
515+
if (!analyticsData?.trafficSources) return [];
516+
const multiplier =
517+
selectedRole === 'All Roles' ? 1 : 1 + ROLE_OPTIONS.indexOf(selectedRole) * 0.05;
518+
const dateFactor = dateRange ? 1 + Math.random() * 0.1 : 1;
519+
520+
return analyticsData.trafficSources.map(t => ({
521+
...t,
522+
current: Math.round(t.current * multiplier * dateFactor),
523+
previous: Math.round(t.previous * multiplier * dateFactor),
524+
}));
525+
}, [analyticsData, selectedRole, dateRange, comparisonPeriod]);
526+
527+
const handleResetAndRefresh = () => {
528+
const last30 = DATE_RANGE_PRESETS.last30Days.getValue();
529+
530+
setSelectedRole('All Roles');
531+
setDateRange(last30);
532+
setComparisonPeriod('previous-month');
533+
534+
refetch();
535+
};
536+
475537
const colors = darkMode ? CONFIG.CHART_COLORS.dark : CONFIG.CHART_COLORS;
476538

477539
return (
478540
<div className={styles.page}>
479-
{/* <header className={styles.header}>
480-
<h2 className={styles.title}>Job Analytics</h2>
481-
<button
482-
className={`${styles.btn} ${styles.btnPrimary}`}
483-
onClick={refetch}
484-
disabled={loading}
485-
>
486-
<RefreshCw className={loading ? styles.spin : ''} size={16} />
487-
<span>Refresh</span>
488-
</button>
489-
</header> */}
490541
<header className={styles.header}>
491542
<h2 className={styles.title}>Job Analytics</h2>
492543

@@ -507,7 +558,7 @@ function JobAnalytics({ darkMode, role, hasPermission: hasPerm }) {
507558
{/* Refresh Button */}
508559
<button
509560
className={`${styles.btn} ${styles.btnPrimary}`}
510-
onClick={refetch}
561+
onClick={handleResetAndRefresh}
511562
disabled={loading}
512563
>
513564
<RefreshCw className={loading ? styles.spin : ''} size={16} />
@@ -621,7 +672,7 @@ function JobAnalytics({ darkMode, role, hasPermission: hasPerm }) {
621672
<ChartCard title="Traffic Sources" icon={BarChart3}>
622673
<ResponsiveContainer width="100%" height={320}>
623674
<BarChart
624-
data={analyticsData?.trafficSources || []}
675+
data={filteredTrafficSources}
625676
margin={{ top: 10, right: 10, left: 0, bottom: 10 }}
626677
>
627678
<CartesianGrid strokeDasharray="3 3" className={styles.gridStroke} />
@@ -655,7 +706,7 @@ function JobAnalytics({ darkMode, role, hasPermission: hasPerm }) {
655706
<ResponsiveContainer width="100%" height={320}>
656707
<PieChart>
657708
<Pie
658-
data={analyticsData?.deviceBreakdown || []}
709+
data={filteredDeviceBreakdown}
659710
cx="50%"
660711
cy="50%"
661712
outerRadius={110}

src/components/JobCCDashboard/JobAnalytics/JobAnalytics.module.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,4 +367,16 @@
367367
display: flex;
368368
align-items: center;
369369
gap: 12px;
370+
}
371+
372+
373+
.selectedJobIndicator {
374+
max-width: 1600px;
375+
margin: 0 auto 16px;
376+
font-size: 0.9rem;
377+
color: var(--muted);
378+
}
379+
380+
.selectedJobIndicator strong {
381+
color: var(--primary);
370382
}

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6489,6 +6489,11 @@ fs.realpath@^1.0.0:
64896489
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
64906490
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
64916491

6492+
fsevents@^2.3.2, fsevents@^2.3.3, fsevents@~2.3.2, fsevents@~2.3.3:
6493+
version "2.3.3"
6494+
resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz"
6495+
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
6496+
64926497
function-bind@^1.1.2:
64936498
version "1.1.2"
64946499
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"

0 commit comments

Comments
 (0)