1- import { useState } from "react" ;
1+ import { useState , useEffect } from "react" ;
22import { Skill , useSkills } from "@/hooks/useSkills" ;
33import { Dialog , DialogContent , DialogHeader , DialogTitle } from "@/components/ui/dialog" ;
44import { Button } from "@/components/ui/button" ;
55import { Input } from "@/components/ui/input" ;
66import { Textarea } from "@/components/ui/textarea" ;
7+ import { getSkillMetricContributions } from "@/lib/coreMetricCalculation" ;
8+ import { getDefaultMapping } from "@/lib/coreMetrics" ;
79
810interface EditSkillDialogProps {
911 skill : Skill ;
@@ -17,7 +19,14 @@ const EditSkillDialog = ({ skill, open, onOpenChange }: EditSkillDialogProps) =>
1719 const [ description , setDescription ] = useState ( skill . description || "" ) ;
1820 const [ area , setArea ] = useState ( skill . area || "" ) ;
1921 const [ coverImage , setCoverImage ] = useState ( skill . cover_image || "" ) ;
20- const [ xp , setXP ] = useState ( skill . xp . toString ( ) ) ;
22+
23+ // Reset form when skill changes
24+ useEffect ( ( ) => {
25+ setName ( skill . name ) ;
26+ setDescription ( skill . description || "" ) ;
27+ setArea ( skill . area || "" ) ;
28+ setCoverImage ( skill . cover_image || "" ) ;
29+ } , [ skill ] ) ;
2130
2231 const handleSubmit = ( e : React . FormEvent ) => {
2332 e . preventDefault ( ) ;
@@ -30,7 +39,7 @@ const EditSkillDialog = ({ skill, open, onOpenChange }: EditSkillDialogProps) =>
3039 description : description . trim ( ) || null ,
3140 area : area . trim ( ) || null ,
3241 cover_image : coverImage . trim ( ) || null ,
33- xp : parseInt ( xp ) || 0 ,
42+ // XP is computed from attendance records - not manually editable
3443 } ,
3544 {
3645 onSuccess : ( ) => {
@@ -40,6 +49,16 @@ const EditSkillDialog = ({ skill, open, onOpenChange }: EditSkillDialogProps) =>
4049 ) ;
4150 } ;
4251
52+ // Calculate which metrics this skill affects
53+ const skillContributionData = {
54+ id : skill . id ,
55+ name : skill . name ,
56+ xp : skill . xp ,
57+ area : skill . area ,
58+ contributesTo : skill . contributes_to || undefined ,
59+ } ;
60+ const metricContributions = getSkillMetricContributions ( skillContributionData ) ;
61+
4362 return (
4463 < Dialog open = { open } onOpenChange = { onOpenChange } >
4564 < DialogContent className = "system-panel max-w-2xl" >
@@ -93,36 +112,53 @@ const EditSkillDialog = ({ skill, open, onOpenChange }: EditSkillDialogProps) =>
93112 />
94113 </ div >
95114
96- < div className = "grid grid-cols-1 md:grid-cols-2 gap-4" >
97- { /* Cover Image URL */ }
98- < div >
99- < label className = "text-xs text-muted-foreground uppercase tracking-wider mb-2 block" >
100- Cover Image URL
101- </ label >
102- < Input
103- value = { coverImage }
104- onChange = { ( e ) => setCoverImage ( e . target . value ) }
105- placeholder = "https://..."
106- className = "bg-input border-border"
107- />
108- </ div >
115+ { /* Cover Image URL */ }
116+ < div >
117+ < label className = "text-xs text-muted-foreground uppercase tracking-wider mb-2 block" >
118+ Cover Image URL
119+ </ label >
120+ < Input
121+ value = { coverImage }
122+ onChange = { ( e ) => setCoverImage ( e . target . value ) }
123+ placeholder = "https://..."
124+ className = "bg-input border-border"
125+ />
126+ </ div >
109127
110- { /* XP */ }
111- < div >
112- < label className = "text-xs text-muted-foreground uppercase tracking-wider mb-2 block" >
113- XP
114- </ label >
115- < Input
116- type = "number"
117- value = { xp }
118- onChange = { ( e ) => setXP ( e . target . value ) }
119- placeholder = "0"
120- className = "bg-input border-border"
121- min = "0"
122- />
128+ { /* XP Display (Read-only) - Shows computed value */ }
129+ < div className = "border-t border-border/30 pt-4" >
130+ < div className = "flex items-center justify-between mb-3" >
131+ < span className = "text-xs text-muted-foreground uppercase tracking-wider" >
132+ Current XP (computed from attendance)
133+ </ span >
134+ < span className = "text-lg font-medium text-foreground" >
135+ { skill . xp } XP
136+ </ span >
123137 </ div >
124138 </ div >
125139
140+ { /* Metric Contributions Display - Bi-directional debugging */ }
141+ { metricContributions . length > 0 && (
142+ < div className = "border-t border-border/30 pt-4" >
143+ < h4 className = "text-xs text-muted-foreground uppercase tracking-wider mb-3" >
144+ Core Metrics Affected
145+ </ h4 >
146+ < div className = "grid grid-cols-2 gap-2" >
147+ { metricContributions . map ( ( contribution ) => (
148+ < div
149+ key = { contribution . metricName }
150+ className = "flex items-center justify-between p-2 bg-muted/50 rounded text-sm"
151+ >
152+ < span className = "text-foreground" > { contribution . metricName } </ span >
153+ < span className = "text-muted-foreground" >
154+ +{ contribution . contributedXp } XP ({ Math . round ( contribution . weight * 100 ) } %)
155+ </ span >
156+ </ div >
157+ ) ) }
158+ </ div >
159+ </ div >
160+ ) }
161+
126162 { /* Actions */ }
127163 < div className = "flex gap-3 pt-4" >
128164 < Button
0 commit comments