@@ -26,7 +26,9 @@ export default function TokenPoints() {
2626 const [ points , setPoints ] = useState < Record < string , number > > ( { } ) ;
2727 const [ levels , setLevels ] = useState < Record < string , number > > ( { } ) ;
2828 const [ attendancePoints , setAttendancePoints ] = useState ( 0 ) ;
29- const [ socialPoints , setSocialPoints ] = useState ( 0 ) ;
29+ // Social points default to 0 — RPC was dropped (20260219_drop_obsolete_social_points_rpc.sql)
30+ // TODO: Re-implement when feeds/social table is built
31+ const [ socialPoints ] = useState ( 0 ) ;
3032 const [ profilePoints , setProfilePoints ] = useState ( 0 ) ;
3133 const [ loading , setLoading ] = useState ( true ) ;
3234 const [ error , setError ] = useState < string | null > ( null ) ;
@@ -48,7 +50,7 @@ export default function TokenPoints() {
4850 setLoading ( true ) ;
4951 setError ( null ) ;
5052
51- // FIXED: Use getUser() instead of getSession()
53+ // Use getUser() instead of getSession() for secure auth check
5254 const {
5355 data : { user : authUser } ,
5456 error : authError ,
@@ -74,11 +76,12 @@ export default function TokenPoints() {
7476
7577 if ( categoriesError ) throw categoriesError ;
7678
79+ // Exclude PM from points overview
7780 const skillCategories = ( categories as SkillCategory [ ] ) . filter (
7881 ( category ) => category . name !== "Project Manager" ,
79- ) ; // Exclude PM from points overview
82+ ) ;
8083
81- // Fetch user's points
84+ // Fetch user's skill points
8285 const { data : pointsData , error : pointsError } = await supabase
8386 . from ( "codev_points" )
8487 . select ( "id, codev_id, skill_category_id, points" )
@@ -106,19 +109,16 @@ export default function TokenPoints() {
106109 setPoints ( pointsByCategory ) ;
107110 }
108111
109- // Fetch attendance points from separate table
112+ // Fetch attendance points — separate table from skill points
110113 const { data : attendanceData , error : attendanceError } = await supabase
111114 . from ( "attendance_points" )
112115 . select ( "points" )
113116 . eq ( "codev_id" , authUser . id )
114117 . single ( ) ;
115118
116- // If no attendance points record exists, create one
119+ // PGRST116 = no rows found — create the record if missing
117120 if ( attendanceError && attendanceError . code === "PGRST116" ) {
118- // Count actual attendance records
119121 const {
120- data : attendanceCount ,
121- error : countError ,
122122 count,
123123 } = await supabase
124124 . from ( "attendance" )
@@ -129,7 +129,6 @@ export default function TokenPoints() {
129129 const totalPoints = ( count || 0 ) * 2 ;
130130
131131 if ( totalPoints > 0 ) {
132- // Create attendance points record
133132 const { data : newAttendancePoints } = await supabase
134133 . from ( "attendance_points" )
135134 . insert ( {
@@ -159,7 +158,7 @@ export default function TokenPoints() {
159158 }
160159 }
161160
162- // Fetch profile points from the API
161+ // Fetch profile completion points via API route
163162 if ( user ?. id ) {
164163 try {
165164 const res = await fetch ( `/api/profile-points/${ user . id } ` ) ;
@@ -179,25 +178,7 @@ export default function TokenPoints() {
179178 }
180179 }
181180
182- // Fetch social points
183- if ( user ?. id ) {
184- try {
185- // Fetch user's points
186- const { data : pointsData , error : pointsError } = await supabase . rpc (
187- "calculate_social_points" ,
188- { codev_id : user . id } ,
189- ) ;
190-
191- if ( pointsError ) throw pointsError ;
192- if ( isMounted ) {
193- setSocialPoints ( pointsData ) ;
194- }
195- } catch ( error ) {
196- console . error ( "Failed to fetch social points:" , error ) ;
197- }
198- }
199-
200- // Fetch levels for all categories
181+ // Fetch levels for all skill categories
201182 const { data : levelsData , error : levelsError } = await supabase
202183 . from ( "levels" )
203184 . select ( "id, skill_category_id, level, min_points, max_points" )
@@ -209,7 +190,7 @@ export default function TokenPoints() {
209190
210191 const skillLevels = levelsData as Level [ ] ;
211192
212- // Map levels to categories
193+ // Map current level to each category based on point thresholds
213194 const levelsByCategory = skillCategories . reduce (
214195 ( acc , category ) => {
215196 const categoryPoints = pointsByCategory [ category . name ] || 0 ;
@@ -235,20 +216,19 @@ export default function TokenPoints() {
235216 setLevels ( levelsByCategory ) ;
236217 }
237218
219+ // Check if user qualifies for promotion
238220 if ( isMounted ) {
239221 if (
240222 user ?. role_id == 4 &&
241223 Object . values ( levelsByCategory ) . some ( ( value ) => value >= 2 ) &&
242- ! promotionAccepted // Don't show if promotion was already accepted
224+ ! promotionAccepted
243225 ) {
244226 setRoleToBePromoted ( "Codev" ) ;
245227 if ( ! user ?. promote_declined ) setIsModalOpen ( true ) ;
246- }
247- //Codev ready to be promoted to Mentor
248- else if (
228+ } else if (
249229 user ?. role_id == 10 &&
250230 Object . values ( levelsByCategory ) . some ( ( value ) => value >= 3 ) &&
251- ! promotionAccepted // Don't show if promotion was already accepted
231+ ! promotionAccepted
252232 ) {
253233 setUserLevel ( 2 ) ;
254234 setRoleToBePromoted ( "Mentor" ) ;
@@ -272,7 +252,7 @@ export default function TokenPoints() {
272252 return ( ) => {
273253 isMounted = false ;
274254 } ;
275- } , [ user , promotionAccepted ] ) ; // Add promotionAccepted to dependencies
255+ } , [ user , promotionAccepted ] ) ;
276256
277257 const handlePromotionAccepted = ( ) => {
278258 setPromotionAccepted ( true ) ;
@@ -283,12 +263,10 @@ export default function TokenPoints() {
283263 if ( loading ) {
284264 return (
285265 < Box className = "!before:absolute !before:inset-0 !before:bg-gradient-to-br !before:from-white/10 !before:to-transparent !before:pointer-events-none relative flex w-full flex-1 flex-col gap-6 overflow-hidden !border-white/10 !bg-white/5 !shadow-2xl !backdrop-blur-2xl dark:!border-slate-400/10 dark:!bg-slate-900/5" >
286- { /* Background decoration */ }
287266 < div className = "from-customBlue-50/30 dark:from-customBlue-950/10 absolute inset-0 bg-gradient-to-br to-purple-50/30 dark:to-purple-950/10" />
288267 < div className = "absolute -right-4 -top-4 h-32 w-32 rounded-full bg-gradient-to-br from-yellow-400/10 to-orange-400/10 blur-2xl" />
289268
290269 < div className = "relative" >
291- { /* Header skeleton */ }
292270 < div className = "mb-4 flex items-center gap-3" >
293271 < Skeleton className = "h-10 w-10 rounded-full" />
294272 < div className = "space-y-2" >
@@ -297,7 +275,6 @@ export default function TokenPoints() {
297275 </ div >
298276 </ div >
299277
300- { /* Cards skeleton */ }
301278 < div className = "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-1 xl:grid-cols-2" >
302279 { [ 1 , 2 , 3 , 4 , 5 , 6 ] . map ( ( i ) => (
303280 < div
@@ -358,8 +335,9 @@ export default function TokenPoints() {
358335 return colorMap [ category ] || "from-gray-500 to-gray-600" ;
359336 } ;
360337
338+ // Calculate progress percentage toward the next level (100 points per level)
361339 const getProgressToNextLevel = ( category : string , currentPoints : number ) => {
362- const nextLevelThreshold = ( levels [ category ] ?? 1 ) * 100 ; // Assuming 100 points per level, default to level 1 if undefined
340+ const nextLevelThreshold = ( levels [ category ] ?? 1 ) * 100 ;
363341 const progress = ( ( currentPoints % 100 ) / 100 ) * 100 ;
364342 return Math . min ( progress , 100 ) ;
365343 } ;
@@ -373,7 +351,6 @@ export default function TokenPoints() {
373351
374352 return (
375353 < Box className = "!before:absolute !before:inset-0 !before:bg-gradient-to-br !before:from-white/10 !before:to-transparent !before:pointer-events-none relative flex w-full flex-1 flex-col gap-6 overflow-hidden !border-white/10 !bg-white/5 !shadow-2xl !backdrop-blur-2xl dark:!border-slate-400/10 dark:!bg-slate-900/5" >
376- { /* Background decoration */ }
377354 < div className = "from-customBlue-50/30 dark:from-customBlue-950/10 absolute inset-0 bg-gradient-to-br to-purple-50/30 dark:to-purple-950/10" />
378355 < div className = "absolute -right-4 -top-4 h-32 w-32 rounded-full bg-gradient-to-br from-yellow-400/10 to-orange-400/10 blur-2xl" />
379356
@@ -497,7 +474,7 @@ export default function TokenPoints() {
497474 </ div >
498475 </ div >
499476
500- { /* Skill Points Cards */ }
477+ { /* Skill Points Cards — one per category */ }
501478 { Object . entries ( points ) . map ( ( [ category , point ] ) => {
502479 const currentLevel = levels [ category ] || 1 ;
503480 const progress = getProgressToNextLevel ( category , point ) ;
@@ -507,7 +484,6 @@ export default function TokenPoints() {
507484 key = { category }
508485 className = "dark:bg-white/3 group relative overflow-hidden rounded-xl border border-white/10 bg-white/5 p-4 shadow-sm backdrop-blur-sm transition-all duration-300 hover:scale-[1.02] hover:bg-white/10 hover:shadow-lg dark:border-white/5 dark:hover:bg-white/5"
509486 >
510- { /* Background gradient */ }
511487 < div
512488 className = { `absolute inset-0 bg-gradient-to-br ${ getCategoryColor ( category ) } opacity-5 transition-opacity group-hover:opacity-10` }
513489 />
@@ -537,7 +513,7 @@ export default function TokenPoints() {
537513 </ div >
538514 </ div >
539515
540- { /* Progress bar for next level */ }
516+ { /* Progress bar toward next level */ }
541517 < div className = "space-y-1" >
542518 < div className = "flex items-center justify-between" >
543519 < span className = "text-xs text-gray-500" >
@@ -555,7 +531,7 @@ export default function TokenPoints() {
555531 </ div >
556532 </ div >
557533
558- { /* Level badge */ }
534+ { /* Level badge — only shown at level 2+ */ }
559535 { currentLevel >= 2 && (
560536 < div className = "absolute -right-2 -top-2 animate-pulse rounded-full bg-gradient-to-r from-yellow-400 to-orange-500 px-2 py-1 text-xs font-bold text-white" >
561537 < ArrowUp className = "mr-1 inline h-3 w-3" />
@@ -568,6 +544,7 @@ export default function TokenPoints() {
568544 } ) }
569545 </ div >
570546 </ div >
547+
571548 { roleToBePromoted == "Codev" && ! promotionAccepted && (
572549 < div className = "relative" >
573550 < div className = "to-customBlue-500 absolute inset-0 rounded-lg bg-gradient-to-r from-green-400 opacity-75 blur-sm" > </ div >
@@ -586,6 +563,7 @@ export default function TokenPoints() {
586563 />
587564 </ div >
588565 ) }
566+
589567 { roleToBePromoted == "Mentor" && ! promotionAccepted && (
590568 < div className = "relative" >
591569 < div className = "absolute inset-0 rounded-lg bg-gradient-to-r from-purple-400 to-pink-500 opacity-75 blur-sm" > </ div >
@@ -606,4 +584,4 @@ export default function TokenPoints() {
606584 ) }
607585 </ Box >
608586 ) ;
609- }
587+ }
0 commit comments