c7b76e086d
Combines SkillsAnalytics (496 LOC) and SkillMarketplace (346 LOC) into a single tabbed Skills Hub (770 LOC total, -9% code). New structure: - skills/shared.tsx: ProficiencyBadge, GapIndicator, constants (extracted) - skills/OverviewTab.tsx: KPI cards, top 10 table, distribution chart, export - skills/SearchTab.tsx: skill search + proficiency + availability filter - skills/GapsTab.tsx: supply vs demand table with gap indicators - skills/PeopleFinderTab.tsx: multi-rule AND/OR builder, chapter filter, export - SkillsHub.tsx: tabbed container with URL-persisted tab state (?tab=) Routing: - /analytics/skills renders SkillsHub (was SkillsAnalytics) - /analytics/skill-marketplace redirects to /analytics/skills?tab=search - Sidebar: "Skill Marketplace" removed, renamed to "Skills Hub" No API changes — reuses existing queries with conditional fetching per tab. Full dark theme support on all components. Co-Authored-By: claude-flow <ruv@ruv.net>
126 lines
6.3 KiB
Markdown
126 lines
6.3 KiB
Markdown
# Unified Skills Hub — Plan
|
|
|
|
## Anforderungsanalyse
|
|
|
|
**Was:** Die zwei getrennten Skill-Seiten (`/analytics/skills` = SkillsAnalytics, `/analytics/skill-marketplace` = SkillMarketplace) zu **einer einzigen, nutzerfreundlichen Skills-Hub-Seite** zusammenfuehren.
|
|
|
|
**Problem heute:**
|
|
- **SkillsAnalytics** (496 LOC): Skill-Tabelle mit Filtern, People Finder (AND/OR Suche), XLSX Export, Skill Distribution Chart, Skill Gap Alerts
|
|
- **SkillMarketplace** (346 LOC): Skill-Suche mit Verfuegbarkeitsfilter, Skill Gap Heat Map (Supply vs Demand), Skill Distribution Chart (dupliziert!)
|
|
- **Ueberlappung:** Beide haben `ProficiencyBadge`, `PROFICIENCY_CLASSES`, `SkillDistributionChart`, aehnliche Tabellen
|
|
- **Verwirrung:** User muss zwei Seiten besuchen fuer zusammenhaengende Informationen
|
|
- **Inkonsistenz:** Analytics hat kein Dark-Theme auf manchen Elementen, Marketplace hat es
|
|
|
|
**Ziel:** Eine Seite `/analytics/skills` mit Tab-basiertem Layout:
|
|
|
|
```
|
|
+-------------------------------------------------------------+
|
|
| Skills Hub [Export] |
|
|
| 125 resources . 47 distinct skills |
|
|
+----------+----------+----------+-------------+--------------+
|
|
| Overview | Search | Gaps | People | Distribution |
|
|
+----------+----------+----------+-------------+--------------+
|
|
| |
|
|
| [Tab content area] |
|
|
| |
|
|
+--------------------------------------------------------------+
|
|
```
|
|
|
|
### Betroffene Pakete & Dateien
|
|
|
|
| Paket | Dateien | Art der Aenderung |
|
|
|-------|---------|------------------|
|
|
| `apps/web` | `src/components/analytics/SkillsHub.tsx` | **create** — neue unified component |
|
|
| `apps/web` | `src/components/analytics/skills/OverviewTab.tsx` | **create** — KPI cards + distribution chart |
|
|
| `apps/web` | `src/components/analytics/skills/SearchTab.tsx` | **create** — skill search + availability (from Marketplace) |
|
|
| `apps/web` | `src/components/analytics/skills/GapsTab.tsx` | **create** — supply/demand gap analysis (from Marketplace) |
|
|
| `apps/web` | `src/components/analytics/skills/PeopleFinderTab.tsx` | **create** — AND/OR skill search (from Analytics) |
|
|
| `apps/web` | `src/components/analytics/skills/shared.tsx` | **create** — ProficiencyBadge, GapIndicator, constants |
|
|
| `apps/web` | `src/app/(app)/analytics/skills/page.tsx` | **edit** — render SkillsHub statt SkillsAnalytics |
|
|
| `apps/web` | `src/app/(app)/analytics/skill-marketplace/page.tsx` | **edit** — redirect to /analytics/skills |
|
|
| `apps/web` | `src/components/layout/AppShell.tsx` | **edit** — remove "Skill Marketplace" nav link |
|
|
| `packages/api` | `src/router/resource.ts` | **edit** — add unified getSkillsHub query |
|
|
|
|
### Task-Liste
|
|
|
|
- [ ] **Task 1:** Shared utilities extrahieren -> `skills/shared.tsx`
|
|
- `ProficiencyBadge`, `GapIndicator`, `PROFICIENCY_CLASSES`, `PROFICIENCY_LABELS`, `proficiencyClasses()`
|
|
- Einmal definieren, ueberall nutzen
|
|
|
|
- [ ] **Task 2:** API: neuen `getSkillsHub` Query -> `resource.ts`
|
|
- Kombiniert alle Daten in einem Call:
|
|
- `aggregated` (from getSkillsAnalytics)
|
|
- `searchResults` (from getSkillMarketplace)
|
|
- `gapData` (from getSkillMarketplace)
|
|
- `distribution` (from both, dedupliziert)
|
|
- `totalResources`, `totalSkillEntries`
|
|
- Alte Queries behalten (AI Assistant nutzt sie)
|
|
|
|
- [ ] **Task 3:** OverviewTab bauen -> `skills/OverviewTab.tsx`
|
|
- KPI Cards: Total Resources, Total Skills, Avg Proficiency, Skill Gaps Count
|
|
- Top 10 Skills Tabelle (sortierbar)
|
|
- Skill Distribution Chart (lazy-loaded)
|
|
- Quick filters: Category, Min Count
|
|
|
|
- [ ] **Task 4:** SearchTab bauen -> `skills/SearchTab.tsx`
|
|
- Skill name Suche (debounced)
|
|
- Min Proficiency Filter (1-5 Buttons)
|
|
- "Available in 30 days" Toggle
|
|
- Ergebnis-Tabelle: Resource, Chapter, Skill, Proficiency, Utilization, Available From
|
|
- Links zu `/resources/[id]`
|
|
|
|
- [ ] **Task 5:** GapsTab bauen -> `skills/GapsTab.tsx`
|
|
- Supply vs Demand Tabelle
|
|
- Supply/Demand Bar Visualisierung
|
|
- Gap Indicator (shortage/surplus/balanced)
|
|
- Sortierbar nach groesstem Gap
|
|
- Click auf Skill -> fuellt Search Tab
|
|
|
|
- [ ] **Task 6:** PeopleFinderTab bauen -> `skills/PeopleFinderTab.tsx`
|
|
- Multi-rule Builder: Skill + Min Proficiency pro Regel
|
|
- AND/OR Operator Toggle
|
|
- Chapter Filter
|
|
- Ergebnis-Tabelle mit Match Score
|
|
- XLSX Export Button
|
|
|
|
- [ ] **Task 7:** SkillsHub zusammenfuegen -> `SkillsHub.tsx`
|
|
- Tab Navigation (Overview, Search, Gaps, People Finder)
|
|
- Header mit KPI Summary + Export Button
|
|
- Tab State via URL search params
|
|
- Lazy-load Tabs fuer Performance
|
|
|
|
- [ ] **Task 8:** Routing + Navigation aktualisieren
|
|
- `/analytics/skills/page.tsx` -> rendert `<SkillsHub />`
|
|
- `/analytics/skill-marketplace/page.tsx` -> redirect zu `/analytics/skills?tab=search`
|
|
- AppShell: "Skill Marketplace" entfernen, "Skills Analytics" umbenennen zu "Skills Hub"
|
|
|
|
- [ ] **Task 9:** Dark Theme durchgaengig
|
|
- Alle Elemente mit `dark:` Varianten
|
|
- Konsistenz mit dem Rest der App
|
|
|
|
### Abhaengigkeiten
|
|
- Task 1 muss zuerst (shared utilities fuer alle Tabs)
|
|
- Task 2 kann parallel zu Task 1 (API aendern)
|
|
- Tasks 3-6 koennen parallel nach Task 1 (4 Tabs, unabhaengige Dateien)
|
|
- Task 7 benoetigt Tasks 3-6 (importiert alle Tabs)
|
|
- Task 8 benoetigt Task 7 (Routing zeigt auf neue Komponente)
|
|
- Task 9 kann parallel zu Task 8
|
|
|
|
### Akzeptanzkriterien
|
|
- [ ] `pnpm --filter @planarchy/web exec tsc --noEmit` — keine neuen Errors
|
|
- [ ] `/analytics/skills` zeigt die vereinte Seite mit 4 Tabs
|
|
- [ ] `/analytics/skill-marketplace` redirected zu `/analytics/skills?tab=search`
|
|
- [ ] Alle Features beider Seiten sind auf der neuen Seite verfuegbar
|
|
- [ ] Dark Theme funktioniert durchgehend
|
|
- [ ] Sidebar zeigt nur noch "Skills Hub" statt zwei Links
|
|
- [ ] XLSX Export funktioniert weiterhin
|
|
- [ ] People Finder AND/OR Suche funktioniert
|
|
- [ ] Skill Gap Heat Map mit Supply/Demand funktioniert
|
|
- [ ] Availability Filter (30 Tage) funktioniert
|
|
|
|
### Risiken & offene Fragen
|
|
- **API Performance:** Ein kombinierter Query koennte langsamer sein -> Loesung: Lazy-load per Tab, Query nur wenn Tab aktiv
|
|
- **URL State:** Aktiver Tab via `?tab=search` Query Param persistiert
|
|
- **Export:** Nur aktiver Tab exportierbar
|
|
- **Backwards-Kompatibilitaet:** AI Assistant Tools nutzen alte Queries -> behalten
|