diff --git a/src/components/HGNHelpSkillsDashboard/SkillsOverviewPage.jsx b/src/components/HGNHelpSkillsDashboard/SkillsOverviewPage.jsx
index 191480bc0d2..e6e3cc341a2 100644
--- a/src/components/HGNHelpSkillsDashboard/SkillsOverviewPage.jsx
+++ b/src/components/HGNHelpSkillsDashboard/SkillsOverviewPage.jsx
@@ -1,5 +1,9 @@
-import { useState } from 'react';
+import jwtDecode from 'jwt-decode';
+import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
+import config from '~/config.json';
+import httpService from '~/services/httpService';
+import { ENDPOINTS } from '~/utils/URL';
import RadarChart from '../HGNSkillsDashboard/SkillsProfilePage/components/RadarChart';
import Accordion from './Accordion';
import { PreferenceFilterButtons, SkillFilterButtons } from './FilterButtons';
@@ -12,11 +16,48 @@ function SkillsOverviewPage() {
const [selectedPreferences, setSelectedPreferences] = useState([]);
const [searchQuery, setSearchQuery] = useState('');
const darkMode = useSelector(state => state.theme.darkMode);
- const userProfile = useSelector(state => state.userProfile);
+ const [profileData, setProfileData] = useState(null);
+ const [loadingProfile, setLoadingProfile] = useState(true);
+
+ // The skills survey lives behind its own endpoint and is not part of state.userProfile,
+ // so this page has to fetch it itself rather than read it from the store.
+ useEffect(() => {
+ const token = localStorage.getItem(config.tokenKey);
+ let userId;
+ try {
+ userId = token ? jwtDecode(token)?.userid : undefined;
+ } catch (_) {
+ userId = undefined;
+ }
+
+ if (!userId) {
+ setLoadingProfile(false);
+ return;
+ }
+
+ httpService.setjwt(token);
+ httpService
+ .get(ENDPOINTS.SKILLS_PROFILE(userId))
+ // isPlaceholder means the user has not filled in the survey yet
+ .then(({ data }) => setProfileData(data?.isPlaceholder ? null : data))
+ .catch(() => setProfileData(null))
+ .finally(() => setLoadingProfile(false));
+ }, []);
const hasFilters =
selectedSkills.length > 0 || selectedPreferences.length > 0 || searchQuery.trim().length > 0;
+ let radarContent;
+ if (loadingProfile) {
+ radarContent =
Loading your skills radar...
;
+ } else if (profileData?.skillInfo) {
+ radarContent = Complete the skills survey to view your radar chart.
+ );
+ }
+
return (
Skills Overview
@@ -24,13 +65,7 @@ function SkillsOverviewPage() {
{/* Radar Chart for logged-in user */}
Your Skills Radar
-
- {userProfile?.skillInfo ? (
-
- ) : (
-
Complete the skills survey to view your radar chart.
- )}
-
+
{radarContent}
{/* Search Bar */}
diff --git a/src/components/HGNSkillsDashboard/SkillsProfilePage/components/RadarChart.jsx b/src/components/HGNSkillsDashboard/SkillsProfilePage/components/RadarChart.jsx
index 29ad3f0b503..d2b3248c67d 100644
--- a/src/components/HGNSkillsDashboard/SkillsProfilePage/components/RadarChart.jsx
+++ b/src/components/HGNSkillsDashboard/SkillsProfilePage/components/RadarChart.jsx
@@ -24,6 +24,7 @@ const SKILL_MAPPINGS = [
},
{
label: 'Leadership Skills',
+ shortLabel: 'Leadership Skl',
value: (general, frontend, backend) => general?.leadership_skills || 0,
description: 'Skills in team leadership and management',
},
@@ -153,6 +154,7 @@ const SKILL_MAPPINGS = [
},
{
label: 'Markdown & Graphs',
+ shortLabel: 'Markdown/Graphs',
value: (general, frontend, backend) => frontend?.Documentation || general?.markdown_graphs || 0,
description: 'Markdown writing and data visualization',
},
@@ -234,7 +236,10 @@ function RadarChart({ profileData, compact = true, onSkillsDataReady }) {
const { general = {}, frontend = {}, backend = {} } = profileData?.skillInfo || {};
const chartData = {
- labels: skillsData.map(skill => (compact ? skill.shortLabel || skill.label : skill.label)),
+ // Always prefer the abbreviated label: with 28 dimensions, the wrap-around
+ // labels at the top (last <-> first) sit within a ~26deg arc and collide
+ // regardless of chart size, so shortening text is what actually buys room.
+ labels: skillsData.map(skill => skill.shortLabel || skill.label),
datasets: [
{
label: 'Skills',
@@ -300,6 +305,7 @@ function RadarChart({ profileData, compact = true, onSkillsDataReady }) {
},
pointLabels: {
+ centerPointLabels: true,
font: {
size: function(context) {
const w = context.chart.width;
@@ -321,7 +327,9 @@ function RadarChart({ profileData, compact = true, onSkillsDataReady }) {
},
ticks: {
stepSize: 2,
- display: compact ? false : true,
+ // Always shown: the radial scale numbers are information, not chrome,
+ // so (like labels above) they shouldn't be gated behind compact.
+ display: true,
color: darkMode ? '#dcdcdc' : '#666',
font: { size: 10 },
backdropColor: darkMode ? '#1f1f1f' : '#ffffff',
diff --git a/src/components/HGNSkillsDashboard/SkillsProfilePage/components/__tests__/RadarChart.test.jsx b/src/components/HGNSkillsDashboard/SkillsProfilePage/components/__tests__/RadarChart.test.jsx
new file mode 100644
index 00000000000..8a05d2d18ed
--- /dev/null
+++ b/src/components/HGNSkillsDashboard/SkillsProfilePage/components/__tests__/RadarChart.test.jsx
@@ -0,0 +1,55 @@
+import { render } from '@testing-library/react';
+import { Provider } from 'react-redux';
+import configureMockStore from 'redux-mock-store';
+import RadarChart from '../RadarChart';
+
+// react-chartjs-2 renders to a real