@@ -7,10 +7,8 @@ import { useLeetcodeStore } from "@/store/LeetcodeStore/useLeetcodeStore";
77import { Card , CardContent , CardHeader } from "@/components/ui/card" ;
88import { Skeleton } from "@/components/ui/skeleton" ;
99import { Doughnut } from "react-chartjs-2" ;
10-
11- import CalendarHeatmap from "react-calendar-heatmap" ;
12- import "../styles/style.css" ;
13- import 'react-calendar-heatmap/dist/styles.css' ;
10+ import { Tooltip as MuiTooltip } from '@mui/material'
11+ import { ActivityCalendar } from 'react-activity-calendar'
1412
1513import {
1614 Chart as ChartJS ,
@@ -89,13 +87,23 @@ export default function Dashboard() {
8987
9088 const processLeetCodeData = ( submissionCalendar : string ) => {
9189 const parsedData = JSON . parse ( submissionCalendar ) ;
92-
93- return Object . entries ( parsedData ) . map ( ( [ timestamp , count ] ) => ( {
94- date : new Date ( Number ( timestamp ) * 1000 ) . toISOString ( ) . split ( "T" ) [ 0 ] ,
95- count : count as number
96- } ) ) ;
90+
91+ return Object . entries ( parsedData ) . map ( ( [ timestamp , count ] ) => {
92+ const contributionCount = count as number ;
93+ let level = 0 ;
94+ if ( contributionCount > 0 ) {
95+ level = Math . min ( Math . ceil ( contributionCount / 5 ) , 4 ) ;
96+ }
97+
98+ return {
99+ date : new Date ( Number ( timestamp ) * 1000 ) . toISOString ( ) . split ( "T" ) [ 0 ] ,
100+ count : contributionCount ,
101+ level : level
102+ } ;
103+ } ) ;
97104 } ;
98105
106+ console . log ( processLeetCodeData ( userDetails . submissionCalendar ) ) ;
99107 return (
100108 < div className = "w-full max-w-7xl mx-auto px-3 sm:px-4 md:px-6 lg:px-8 py-4 sm:py-6 md:py-8 space-y-4 sm:space-y-6 md:space-y-8" >
101109 { /* Profile Header Card */ }
@@ -124,19 +132,19 @@ export default function Dashboard() {
124132 </ div >
125133 </ div >
126134 < div className = "grid grid-cols-3 gap-2 sm:gap-4 w-full sm:w-auto mt-4 sm:mt-0" >
127- < QuickStat
135+ < QuickStat
128136 icon = { < Target /> }
129137 label = "Rating"
130138 value = { userContestRanking ?. rating || 0 }
131139 color = "blue"
132140 />
133- < QuickStat
141+ < QuickStat
134142 icon = { < Trophy /> }
135143 label = "Top"
136144 value = { `${ userContestRanking ?. topPercentage } %` }
137145 color = "yellow"
138146 />
139- < QuickStat
147+ < QuickStat
140148 icon = { < Award /> }
141149 label = "Rank"
142150 value = { userContestRanking ?. globalRanking || 0 }
@@ -162,17 +170,20 @@ export default function Dashboard() {
162170 </ div >
163171 </ CardHeader >
164172 < CardContent className = "p-2 sm:p-4 md:p-6 overflow-x-auto" >
165- < div className = "min-w-[600px]" >
166- < CalendarHeatmap
167- values = { processLeetCodeData ( userDetails . submissionCalendar ) }
168- startDate = { new Date ( new Date ( ) . setFullYear ( new Date ( ) . getFullYear ( ) - 1 ) ) }
169- endDate = { new Date ( ) }
170- classForValue = { ( value ) => {
171- if ( ! value ) {
172- return 'color-empty' ;
173- }
174- return `color-scale-${ ( value . count ) } ` ;
175- } }
173+ < div className = "h-[160px] transform scale-30 origin-center" >
174+ < ActivityCalendar
175+ theme = { { dark : [ '#020202' , '#058c42' , '#16DB65' , '#0D2818' , '#04471C' ] } }
176+ data = { processLeetCodeData ( userDetails . submissionCalendar ) }
177+ renderBlock = { ( block , activity ) => (
178+ < MuiTooltip title = { `${ activity . count } activities on ${ activity . date } ` } >
179+ { block }
180+ </ MuiTooltip >
181+ ) }
182+ renderColorLegend = { ( block , level ) => (
183+ < MuiTooltip title = { `Level: ${ level } ` } > { block } </ MuiTooltip >
184+ ) }
185+ weekStart = { 1 }
186+ ref = { ( ref ) => console . log ( ref ) }
176187 />
177188 </ div >
178189 </ CardContent >
@@ -211,9 +222,9 @@ export default function Dashboard() {
211222 < CardContent className = "p-0 overflow-y-auto h-[calc(350px-3rem)] sm:h-[calc(400px-4rem)]" >
212223 < div className = "divide-y" >
213224 { recentSubmissions . map ( ( submission , idx ) => (
214- < Link
225+ < Link
215226 href = { `https://leetcode.com/problems/${ submission . titleSlug } ` }
216- key = { idx }
227+ key = { idx }
217228 target = "_blank"
218229 className = "flex items-center p-3 sm:p-4 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors group"
219230 >
@@ -235,53 +246,53 @@ export default function Dashboard() {
235246 { /* Statistics Cards */ }
236247 < div className = "md:col-span-2 max-h-[400px] sm:max-h-[450px] lg:max-h-[500px] overflow-hidden" >
237248 < div className = "grid grid-cols-1 sm:grid-cols-2 gap-4 sm:gap-6" >
238- < DetailCard
249+ < DetailCard
239250 title = "Problem Solving Stats"
240251 icon = { < Star className = "w-4 h-4 sm:w-5 sm:h-5 text-yellow-600" /> }
241252 stats = { [
242- {
253+ {
243254 label : 'Total Solved' ,
244255 value : userDetails . submitStats . acSubmissionNum [ 0 ] . count ,
245256 icon : < CheckCircle className = "w-3 h-3 sm:w-4 sm:h-4 text-green-500" />
246257 } ,
247- {
258+ {
248259 label : 'Easy Problems' ,
249260 value : userDetails . submitStats . acSubmissionNum [ 1 ] . count ,
250261 icon : < Zap className = "w-3 h-3 sm:w-4 sm:h-4 text-green-500" />
251262 } ,
252- {
263+ {
253264 label : 'Medium Problems' ,
254265 value : userDetails . submitStats . acSubmissionNum [ 2 ] . count ,
255266 icon : < Zap className = "w-3 h-3 sm:w-4 sm:h-4 text-yellow-500" />
256267 } ,
257- {
268+ {
258269 label : 'Hard Problems' ,
259270 value : userDetails . submitStats . acSubmissionNum [ 3 ] . count ,
260271 icon : < Zap className = "w-3 h-3 sm:w-4 sm:h-4 text-red-500" />
261272 } ,
262273 ] }
263274 />
264- < DetailCard
275+ < DetailCard
265276 title = "Performance Metrics"
266277 icon = { < Timer className = "w-4 h-4 sm:w-5 sm:h-5 text-purple-600" /> }
267278 stats = { [
268- {
279+ {
269280 label : 'Acceptance Rate' ,
270- value : `${ ( userDetails . submitStats . acSubmissionNum [ 0 ] . count /
281+ value : `${ ( userDetails . submitStats . acSubmissionNum [ 0 ] . count /
271282 userDetails . submitStats . totalSubmissionNum [ 0 ] . count * 100 ) . toFixed ( 1 ) } %`,
272283 icon : < TrendingUp className = "w-3 h-3 sm:w-4 sm:h-4 text-blue-500" />
273284 } ,
274- {
285+ {
275286 label : 'Total Submissions' ,
276287 value : userDetails . submitStats . totalSubmissionNum [ 0 ] . count ,
277288 icon : < Code className = "w-3 h-3 sm:w-4 sm:h-4 text-green-500" />
278289 } ,
279- {
290+ {
280291 label : 'Contribution Points' ,
281292 value : userDetails . contributions . points ,
282293 icon : < Star className = "w-3 h-3 sm:w-4 sm:h-4 text-yellow-500" />
283294 } ,
284- {
295+ {
285296 label : 'Contest Count' ,
286297 value : userContestRanking ?. attendedContestsCount || 0 ,
287298 icon : < Trophy className = "w-3 h-3 sm:w-4 sm:h-4 text-orange-500" />
@@ -304,8 +315,8 @@ export default function Dashboard() {
304315 < CardContent className = "p-2 sm:p-4 flex justify-center items-center flex-1 overflow-hidden" >
305316 < div className = "h-full w-full flex items-center justify-center" >
306317 < div className = "h-48 w-48 sm:h-56 sm:w-56 md:h-64 md:w-64" >
307- < Doughnut
308- data = { difficultyData }
318+ < Doughnut
319+ data = { difficultyData }
309320 options = { {
310321 cutout : '65%' ,
311322 responsive : true ,
@@ -341,7 +352,7 @@ export default function Dashboard() {
341352 }
342353 }
343354 }
344- } }
355+ } }
345356 />
346357 </ div >
347358 </ div >
@@ -392,7 +403,7 @@ function DetailCard({ title, icon, stats }: { title: string; icon: React.ReactNo
392403 < CardContent className = "p-2 sm:p-4" >
393404 < div className = "grid grid-cols-2 gap-2 sm:gap-4" >
394405 { stats . map ( ( stat , idx ) => (
395- < div key = { idx }
406+ < div key = { idx }
396407 className = "bg-gray-100/80 dark:bg-gray-700/50 p-2 sm:p-4 rounded-lg hover:bg-gray-200/80 dark:hover:bg-gray-700/80 transition-colors flex flex-col justify-between h-full"
397408 >
398409 < div className = "flex items-center gap-1 sm:gap-2 mb-1 sm:mb-2" >
0 commit comments