This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

claude's attempt to fix userprofile responsiveness

+601 -404
+458 -378
src/components/UserProfile/UserProfile.css
··· 2 2 3 3 /* Container for the profile page */ 4 4 .user-profile { 5 - margin: auto; 6 - max-width: 1200px; 7 - margin-top: 40px; 5 + margin: auto; 6 + max-width: 1200px; 7 + margin-top: 40px; 8 + } 9 + 10 + 11 + .user-profile h1 { 12 + margin: 0px; 13 + } 14 + 15 + /* Media query for responsiveness (optional, handled by react-grid-layout) */ 16 + @media (max-width: 1200px) { 17 + .layout { 18 + width: 100%; 8 19 } 20 + } 9 21 22 + .user-profile { 23 + margin: auto; 24 + max-width: 1200px; 25 + opacity: 0; /* Initially hidden */ 26 + transform: translateY(20px); 27 + transition: opacity 1s ease, transform 1s ease; 28 + } 10 29 11 - .user-profile h1 { 12 - margin: 0px; 13 - } 14 - 15 - /* Media query for responsiveness (optional, handled by react-grid-layout) */ 16 - @media (max-width: 1200px) { 17 - .layout { 18 - width: 100%; 19 - } 20 - } 30 + .user-profile.fade-in { 31 + opacity: 1; 32 + transform: translateY(0); 33 + } 34 + 35 + .user-profile.hidden { 36 + display: none; 37 + } 38 + 39 + .user-profile.loading-container { 40 + opacity: 1; 41 + transition: opacity 1s ease; 42 + } 43 + 44 + .user-profile.loading-container.fade-out { 45 + opacity: 0; 46 + pointer-events: none; 47 + } 21 48 22 - .user-profile { 23 - margin: auto; 24 - max-width: 1200px; 25 - opacity: 0; /* Initially hidden */ 26 - transform: translateY(20px); 27 - transition: opacity 1s ease, transform 1s ease; 28 - } 29 - 30 - .user-profile.fade-in { 31 - opacity: 1; 32 - transform: translateY(0); 33 - } 34 - 35 - .user-profile.hidden { 36 - display: none; 37 - } 38 - 39 - .user-profile.loading-container { 40 - opacity: 1; 41 - transition: opacity 1s ease; 42 - } 43 - 44 - .user-profile.loading-container.fade-out { 45 - opacity: 0; 46 - pointer-events: none; 47 - } 48 - 49 - .user-profile-header { 50 - text-align: center; 51 - } 49 + .user-profile-header { 50 + text-align: center; 51 + } 52 52 53 - .react-grid-item.react-grid-placeholder { 54 - background: #3B9AF8 !important; 55 - border-radius: 8px; 56 - opacity: 0.2; 57 - transition-duration: 100ms; 58 - z-index: 2; 59 - -webkit-user-select: none; 60 - -moz-user-select: none; 61 - -ms-user-select: none; 62 - -o-user-select: none; 63 - user-select: none; 64 - } 53 + .react-grid-item.react-grid-placeholder { 54 + background: #3B9AF8 !important; 55 + border-radius: 8px; 56 + opacity: 0.2; 57 + transition-duration: 100ms; 58 + z-index: 2; 59 + -webkit-user-select: none; 60 + -moz-user-select: none; 61 + -ms-user-select: none; 62 + -o-user-select: none; 63 + user-select: none; 64 + } 65 65 66 - .react-grid-item.react-grid-placeholder.placeholder-resizing { 67 - transition: none; 68 - } 66 + .react-grid-item.react-grid-placeholder.placeholder-resizing { 67 + transition: none; 68 + } 69 69 70 - .react-grid-layout { 71 - margin-bottom: 40px; 72 - } 70 + .react-grid-layout { 71 + margin-bottom: 40px; 72 + } 73 73 74 - /* src/components/UserProfile/UserProfile.css */ 74 + /* src/components/UserProfile/UserProfile.css */ 75 75 76 - .user-profile-header { 77 - display: inline-grid; 78 - column-gap: 50px; 79 - row-gap: 22px; 80 - justify-content: center; 81 - text-align: center; 82 - grid-auto-flow: column; 83 - margin-left: 36.5px; 84 - } 76 + .user-profile-header { 77 + display: inline-grid; 78 + column-gap: 50px; 79 + row-gap: 22px; 80 + justify-content: center; 81 + text-align: center; 82 + grid-auto-flow: column; 83 + margin-left: 36.5px; 84 + } 85 85 86 86 87 87 .toggle-button { 88 - padding: 10px 20px; 89 - margin: 0 5px; 90 - border: none; 91 - background-color: #a9a9a9; 92 - cursor: pointer; 93 - border-radius: 6px; 94 - transition: background-color 0.3s; 88 + padding: 10px 20px; 89 + margin: 0 5px; 90 + border: none; 91 + background-color: #a9a9a9; 92 + cursor: pointer; 93 + border-radius: 6px; 94 + transition: background-color 0.3s; 95 95 } 96 96 97 97 .toggle-button.active { 98 - background-color: #3B9AF8; 99 - color: white; 98 + background-color: #3B9AF8; 99 + color: white; 100 100 } 101 101 102 102 .toggle-button:hover { 103 - background-color: #ccc; 103 + background-color: #ccc; 104 104 } 105 105 106 106 .user-profile-header p { 107 - margin-bottom: 0px; 108 - margin-top: 0px; 107 + margin-bottom: 0px; 108 + margin-top: 0px; 109 109 } 110 110 111 111 .user-profile-header h2 { 112 - font-size: 1.2em; 113 - margin: 0px; 112 + font-size: 1.2em; 113 + margin: 0px; 114 114 } 115 115 116 116 .user-profile-header h1 { 117 - margin-bottom: 0px; 118 - line-height: 0.9em; 117 + margin-bottom: 0px; 118 + line-height: 0.9em; 119 119 } 120 120 121 121 .text-center.font-semibold.mt-2 { 122 - font-size: 1.2em; 123 - font-weight: 600; 124 - color: var(--text); 125 - margin-top: -10.5px; 126 - margin-left: 11.5px; 127 - display: flex; 128 - gap: 8.5px; 122 + font-size: 1.2em; 123 + font-weight: 600; 124 + color: var(--text); 125 + margin-top: -10.5px; 126 + margin-left: 11.5px; 127 + display: flex; 128 + gap: 8.5px; 129 129 } 130 130 131 131 .user-profile-header-main { 132 - display: flex; 133 - flex-direction: column; 134 - gap: 20px; 135 - align-content: center; 136 - justify-content: center; 132 + display: flex; 133 + flex-direction: column; 134 + gap: 20px; 135 + align-content: center; 136 + justify-content: center; 137 137 } 138 138 139 139 .user-profile-data { 140 - display: flex; 141 - flex-direction: column; 140 + display: flex; 141 + flex-direction: column; 142 142 } 143 143 144 144 .user-profile-data { 145 - justify-content: center; 146 - gap: 35px; 145 + justify-content: center; 146 + gap: 35px; 147 147 } 148 148 149 149 .circular-badge { 150 - margin-bottom: -10px; 151 - margin-top: -10px; 150 + margin-bottom: -10px; 151 + margin-top: -10px; 152 152 } 153 153 154 154 .user-profile-name { 155 - gap: 7px; 156 - display: flex; 157 - flex-direction: column; 155 + gap: 7px; 156 + display: flex; 157 + flex-direction: column; 158 158 } 159 159 160 160 .loading-container-1 { 161 - min-height: 0 !important; 162 - margin-bottom: 50px; 163 - margin-top: 30px; 161 + min-height: 0 !important; 162 + margin-bottom: 50px; 163 + margin-top: 30px; 164 164 } 165 165 166 + /* Make grid items responsive and flexible */ 166 167 .grid-item { 167 - overflow: clip; 168 + overflow: hidden; 169 + transition: all 0.3s ease; 170 + display: flex; 171 + flex-direction: column; 168 172 } 169 173 170 174 .react-grid-item { 171 - transition: all 200ms ease; 172 - transition-property: left, top; 175 + transition: all 200ms ease; 176 + transition-property: left, top, width, height; 173 177 } 174 178 175 179 .narrative-card p:first-letter { 176 - text-transform: capitalize; 180 + text-transform: capitalize; 177 181 } 178 182 179 183 .user-profile-badges h3 { 180 - margin: 0px; 181 - font-size: 0.8em; 182 - font-weight: 500; 183 - margin-bottom: 4px; 184 + margin: 0px; 185 + font-size: 0.8em; 186 + font-weight: 500; 187 + margin-bottom: 4px; 184 188 } 185 189 186 190 .circular-badge { 187 - position: relative; 188 - display: inline-block; 189 - grid-row: 1; 190 - grid-column: 1; 191 - margin-left: -9px; 192 - margin-right: -18px; 191 + position: relative; 192 + display: inline-block; 193 + grid-row: 1; 194 + grid-column: 1; 195 + margin-left: -9px; 196 + margin-right: -18px; 193 197 } 194 198 195 199 /* Light mode styles */ 196 200 .circular-logo-text { 197 - fill: var(--circular-logo-text, #004f84); 198 - transition: fill 0.3s ease; 201 + fill: var(--circular-logo-text, #004f84); 202 + transition: fill 0.3s ease; 199 203 } 200 204 201 205 .user-profile .recharts-responsive-container { 202 - max-width: 100%; 206 + max-width: 100%; 203 207 } 204 208 205 209 .share-button-container { 206 - align-content: center; 207 - grid-column: 3; 208 - grid-row: 2; 209 - display: flex; 210 - flex-direction: column; 211 - gap: 5px; 212 - font-size: 0.8em; 210 + align-content: center; 211 + grid-column: 3; 212 + grid-row: 2; 213 + display: flex; 214 + flex-direction: column; 215 + gap: 5px; 216 + font-size: 0.8em; 213 217 } 214 218 215 219 .toggle-switch { 216 - display: none; 220 + display: none; 217 221 } 218 222 219 223 .user-profile-activity { 220 - text-transform: capitalize; 221 - align-content: center; 222 - justify-content: center; 223 - display: flex; 224 - flex-direction: column; 225 - padding: 8px 0px; 224 + text-transform: capitalize; 225 + align-content: center; 226 + justify-content: center; 227 + display: flex; 228 + flex-direction: column; 229 + padding: 8px 0px; 226 230 } 227 231 228 232 tspan { 229 - font-family: articulat-cf; 233 + font-family: articulat-cf; 230 234 } 231 235 232 236 .dark-mode tspan { 233 - fill: white; 234 - opacity: 0.5; 237 + fill: white; 238 + opacity: 0.5; 235 239 } 236 240 237 241 .user-profile-score { 238 - align-content: center; 239 - justify-content: center; 240 - display: flex; 241 - flex-direction: column; 242 + align-content: center; 243 + justify-content: center; 244 + display: flex; 245 + flex-direction: column; 242 246 } 243 247 244 248 .user-profile-data-group { 245 - display: flex; 246 - flex-direction: column; 247 - justify-content: center; 248 - grid-row: 2; 249 - grid-column: 2; 250 - font-size: 0.8em; 249 + display: flex; 250 + flex-direction: column; 251 + justify-content: center; 252 + grid-row: 2; 253 + grid-column: 2; 254 + font-size: 0.8em; 251 255 } 252 256 253 257 .dark-mode rect { 254 - stroke: #2c2c2c !important; 255 - stroke-width: 5px !important; 258 + stroke: #2c2c2c !important; 259 + stroke-width: 5px !important; 256 260 } 257 261 258 262 .recharts-surface { 259 - stroke-width: 0.3px; 263 + stroke-width: 0.3px; 260 264 } 261 265 262 266 .recharts-cartesian-axis-ticks { 263 - font-size: 0.7em; 267 + font-size: 0.7em; 264 268 } 265 269 266 270 .text-sm.text-gray-500.text-center.mt-4 { 267 - text-align: center; 268 - padding-top: 10px; 269 - font-size: 0.8em; 270 - opacity: 0.5; 271 + text-align: center; 272 + padding-top: 10px; 273 + font-size: 0.8em; 274 + opacity: 0.5; 271 275 } 272 276 273 277 .user-profile-header-rechart { 274 - align-items: center; 275 - display: flex; 276 - grid-row: 1; 277 - justify-content: center; 278 - margin: 0 auto; 279 - max-height: 130px; 280 - max-width: 200px; 281 - padding: 1rem; 282 - width: 100%; 283 - grid-column: 3; 284 - scale: 0.9; 278 + align-items: center; 279 + display: flex; 280 + grid-row: 1; 281 + justify-content: center; 282 + margin: 0 auto; 283 + max-height: 130px; 284 + max-width: 200px; 285 + padding: 1rem; 286 + width: 100%; 287 + grid-column: 3; 288 + scale: 0.9; 285 289 } 286 290 287 291 .score-gauge { 288 - margin-right: 10px !important; 292 + margin-right: 10px !important; 289 293 } 290 294 291 295 .user-profile-main { 292 - display: flex; 293 - flex-direction: column; 294 - grid-row: 1; 295 - justify-content: space-evenly; 296 - padding-top: 5px; 297 - grid-column: 2; 298 - max-width: 240px; 296 + display: flex; 297 + flex-direction: column; 298 + grid-row: 1; 299 + justify-content: space-evenly; 300 + padding-top: 5px; 301 + grid-column: 2; 302 + max-width: 240px; 299 303 } 300 304 301 305 .user-profile-container { 302 - text-align: center; 303 - margin: 55px 20px 40px; 306 + text-align: center; 307 + margin: 55px 20px 40px; 304 308 } 305 309 306 310 .user-profile-age h2 { 307 - font-size: 0.8em; 311 + font-size: 0.8em; 308 312 } 309 313 310 314 .compare-button-container { 311 - align-content: center; 312 - grid-row: 3; 315 + align-content: center; 316 + grid-row: 3; 313 317 } 314 318 315 319 .max-score { 316 - opacity: 0.5; 320 + opacity: 0.5; 317 321 } 318 322 319 323 .comparea-button-profile { 320 - background: gray; 324 + background: gray; 321 325 } 322 326 323 327 .user-profile-emoji-group { 324 - display: inline-grid; 325 - font-size: 1.8em; 326 - align-content: center; 327 - justify-content: center; 328 - row-gap: 10px; 329 - column-gap: 20px; 330 - margin-left: 10px; 331 - grid-column: 1; 332 - grid-row: 2; 328 + display: inline-grid; 329 + font-size: 1.8em; 330 + align-content: center; 331 + justify-content: center; 332 + row-gap: 10px; 333 + column-gap: 20px; 334 + margin-left: 10px; 335 + grid-column: 1; 336 + grid-row: 2; 333 337 } 334 338 335 339 .emoji-1 { 336 - grid-column: 1; 337 - grid-row: 1; 340 + grid-column: 1; 341 + grid-row: 1; 338 342 } 339 343 340 344 .emoji-2 { 341 - grid-column: 2; 342 - grid-row: 1; 345 + grid-column: 2; 346 + grid-row: 1; 343 347 } 344 348 345 349 .emoji-3 { 346 - grid-column: 1; 347 - grid-row: 2; 350 + grid-column: 1; 351 + grid-row: 2; 348 352 } 349 353 350 354 .emoji-4 { 351 - grid-column: 2; 352 - grid-row: 2; 355 + grid-column: 2; 356 + grid-row: 2; 353 357 } 354 358 355 359 .narrative-card { 356 - font-size: 0.9em; 360 + font-size: 0.9em; 357 361 } 358 362 359 363 .narrative-disclaimer { 360 - font-size: 0.8em; 361 - margin-top: 13.5px; 362 - opacity: 0.5; 364 + font-size: 0.8em; 365 + margin-top: 13.5px; 366 + opacity: 0.5; 363 367 } 364 368 365 369 .post-type-card .recharts-surface { 366 - margin-left: -15px; 370 + margin-left: -15px; 367 371 } 368 372 369 373 .score-breakdown-card .disclaimer { 370 - margin-left: 3px; 374 + margin-left: 3px; 371 375 } 372 376 373 377 .user-profile-container { 374 - margin: auto; 375 - margin-top: auto; 376 - margin-bottom: auto; 377 - width: 100%; 378 - margin-top: 60px; 379 - margin-bottom: 60px; 378 + margin: auto; 379 + margin-top: auto; 380 + margin-bottom: auto; 381 + width: 100%; 382 + margin-top: 60px; 383 + margin-bottom: 60px; 380 384 } 381 385 382 386 .profile-sections-wrapper { 383 - display: grid; 384 - grid-template-columns: 1fr 2fr 1fr; 385 - gap: 20px; 386 - align-items: start; 387 - max-width: 1200px; 388 - margin: 0 auto; 387 + display: grid; 388 + grid-template-columns: 1fr 2fr 1fr; 389 + gap: 20px; 390 + align-items: start; 391 + max-width: 1200px; 392 + margin: 0 auto; 389 393 } 390 394 391 395 /* Left Section */ 392 396 .profile-section.left-section { 393 - justify-self: start; 394 - margin-right: 31.1px; 395 - margin-top: 15.3px; 397 + justify-self: start; 398 + margin-right: 31.1px; 399 + margin-top: 15.3px; 396 400 } 397 401 398 402 /* Middle Section */ 399 403 .profile-section.middle-section { 400 - display: flex; 401 - flex-direction: column; 402 - align-items: center; 403 - gap: 17px; 404 - justify-self: center; 405 - margin-right: -31.3px; 406 - margin-top: 11.5px; 404 + display: flex; 405 + flex-direction: column; 406 + align-items: center; 407 + gap: 17px; 408 + justify-self: center; 409 + margin-right: -31.3px; 410 + margin-top: 11.5px; 407 411 } 408 412 409 413 .user-profile-header-rechart { 410 - margin: 0 auto; 411 - max-width: 200px; 412 - width: 100%; 413 - scale: 1.07; 414 - margin-top: 4px; 414 + margin: 0 auto; 415 + max-width: 200px; 416 + width: 100%; 417 + scale: 1.07; 418 + margin-top: 4px; 415 419 } 416 420 417 421 .user-profile-data-group { 418 - text-align: center; 419 - width: 100%; 420 - max-width: 300px; 421 - gap: 10px; 422 + text-align: center; 423 + width: 100%; 424 + max-width: 300px; 425 + gap: 10px; 422 426 } 423 427 424 428 .share-button-container { 425 - width: 100%; 426 - text-align: center; 427 - display: block; 429 + width: 100%; 430 + text-align: center; 431 + display: block; 428 432 } 429 433 430 434 .comparea-button-profile { 431 - margin-top: 10px; 435 + margin-top: 10px; 432 436 } 433 437 434 438 /* Right Section */ 435 439 .profile-section.right-section { 436 - justify-self: end; 437 - padding-left: 32.6px; 438 - scale: 0.9; 440 + justify-self: end; 441 + padding-left: 32.6px; 442 + scale: 0.9; 439 443 } 440 444 441 445 .user-profile-main { 442 - text-align: center; 443 - gap: 22.5px; 446 + text-align: center; 447 + gap: 22.5px; 444 448 } 445 449 446 450 .user-profile-activity { 447 - align-content: center; 448 - display: flex; 449 - flex-direction: column; 450 - justify-content: center; 451 - padding: 0px; 452 - text-transform: capitalize; 451 + align-content: center; 452 + display: flex; 453 + flex-direction: column; 454 + justify-content: center; 455 + padding: 0px; 456 + text-transform: capitalize; 453 457 } 454 458 455 459 .user-profile-badges { 456 - font-size: 1.2em; 457 - line-height: 1.2em; 460 + font-size: 1.2em; 461 + line-height: 1.2em; 458 462 } 459 463 460 464 .context-line p { 461 - margin: 0px; 462 - font-size: 0.7em; 463 - opacity: 0.5; 465 + margin: 0px; 466 + font-size: 0.7em; 467 + opacity: 0.5; 464 468 } 465 469 466 470 .bluesky-link { 467 - font-size: 0.8em; 468 - text-decoration: underline; 471 + font-size: 0.8em; 472 + text-decoration: underline; 469 473 } 470 474 471 475 .user-profile-data-group p { 472 - margin: 2px; 476 + margin: 2px; 473 477 } 474 478 475 479 .user-profile-name h2 { 476 - font-size: 1em; 477 - margin: 0px; 480 + font-size: 1em; 481 + margin: 0px; 478 482 } 479 483 480 484 .user-profile-age h2 { 481 - font-size: .8em; 482 - margin: 0px; 485 + font-size: .8em; 486 + margin: 0px; 483 487 } 484 488 485 489 .circular-badge { 486 - margin: 0px 490 + margin: 0px 487 491 } 488 492 489 493 .card .disclaimer { 490 - margin: 0px; 491 - margin-top: 0px; 492 - margin-top: 12.3px; 493 - max-width: 400px; 494 + margin: 0px; 495 + margin-top: 0px; 496 + margin-top: 12.3px; 497 + max-width: 400px; 494 498 } 495 499 496 500 .learn-more-text { 497 - font-size: 0.9em 501 + font-size: 0.9em 498 502 } 499 503 500 504 .score-breakdown-container .disclaimer { 501 - margin-left: 3px; 505 + margin-left: 3px; 506 + } 507 + 508 + /* Make card component fill grid item */ 509 + .grid-item > div { 510 + height: 100%; 511 + width: 100%; 512 + display: flex; 513 + flex-direction: column; 514 + } 515 + 516 + /* Make card content expand to fill available space */ 517 + .card-content { 518 + flex: 1; 519 + overflow: auto; 520 + } 521 + 522 + /* Style for resize handle */ 523 + .react-resizable-handle { 524 + background-color: rgba(0, 0, 0, 0.1); 525 + border-radius: 0 0 5px 0; 526 + z-index: 10; 527 + } 528 + 529 + .react-resizable-handle:hover { 530 + background-color: rgba(0, 0, 0, 0.2); 531 + } 532 + 533 + /* Custom styles for the Card component */ 534 + .card { 535 + display: flex; 536 + flex-direction: column; 537 + height: 100%; 538 + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); 539 + border-radius: 8px; 540 + background-color: white; 541 + overflow: hidden; 542 + } 543 + 544 + .card-header { 545 + padding: 12px 16px; 546 + background-color: #f8f9fa; 547 + border-bottom: 1px solid #eaeaea; 548 + cursor: move; 549 + display: flex; 550 + justify-content: space-between; 551 + align-items: center; 552 + } 553 + 554 + .card-content { 555 + padding: 16px; 556 + flex: 1; 557 + overflow: auto; 502 558 } 503 559 504 560 /* Responsive Adjustments for Cards */ 505 561 @media (max-width: 835px) { 506 562 507 - .user-profile-container { 508 - margin: 30px auto; 509 - margin-top: 30px; 510 - width: 100%; 511 - margin-top: 40px; 512 - } 563 + .user-profile-container { 564 + margin: 30px auto; 565 + margin-top: 30px; 566 + width: 100%; 567 + margin-top: 40px; 568 + } 513 569 514 - .profile-sections-wrapper { 515 - grid-template-columns: 1fr; 516 - grid-template-rows: auto auto auto; 517 - gap: 27px; 518 - } 570 + .profile-sections-wrapper { 571 + grid-template-columns: 1fr; 572 + grid-template-rows: auto auto auto; 573 + gap: 27px; 574 + } 519 575 520 - .profile-section.left-section { 521 - justify-self: center; 522 - padding-left: 0; 523 - scale: .7; 524 - grid-column: 1; 525 - grid-row: 1; 526 - } 576 + .profile-section.left-section { 577 + justify-self: center; 578 + padding-left: 0; 579 + scale: .7; 580 + grid-column: 1; 581 + grid-row: 1; 582 + } 583 + 584 + .profile-section.left-section { 585 + margin-right: 0px; 586 + } 527 587 528 - .profile-section.left-section { 529 - margin-right: 0px; 530 - } 588 + .profile-section.right-section { 589 + justify-self: center; 590 + padding-left: 0; 591 + grid-column: 1; 592 + grid-row: 3; 593 + margin-top: -10px; 594 + } 531 595 532 - .profile-section.right-section { 533 - justify-self: center; 534 - padding-left: 0; 535 - grid-column: 1; 536 - grid-row: 3; 537 - margin-top: -10px; 538 - } 596 + .user-profile-main { 597 + text-align: center; 598 + } 539 599 540 - .user-profile-main { 541 - text-align: center; 542 - } 600 + .circular-badge { 601 + grid-column: 1; 602 + grid-row: 1; 603 + margin-left: 0; 604 + margin-right: 1.5px; 605 + } 606 + .user-profile-emoji-group { 607 + grid-row: 1; 608 + grid-column: 1; 609 + display: none; 610 + } 611 + .user-profile-main { 612 + grid-row: 2; 613 + grid-column: 1; 614 + gap: 20.8px; 615 + } 616 + .user-profile-header-rechart { 617 + grid-row: 3; 618 + grid-column: 1; 619 + scale: 0.9; 620 + margin-bottom: 5px; 621 + } 543 622 544 - .circular-badge { 545 - grid-column: 1; 546 - grid-row: 1; 547 - margin-left: 0; 548 - margin-right: 1.5px; 549 - } 550 - .user-profile-emoji-group { 551 - grid-row: 1; 552 - grid-column: 1; 553 - display: none; 554 - } 555 - .user-profile-main { 556 - grid-row: 2; 557 - grid-column: 1; 558 - gap: 20.8px; 559 - } 560 - .user-profile-header-rechart { 561 - grid-row: 3; 562 - grid-column: 1; 563 - scale: 0.9; 564 - margin-bottom: 5px; 565 - } 623 + .user-profile-data-group { 624 + grid-row: 4; 625 + grid-column: 1; 626 + } 566 627 567 - .user-profile-data-group { 568 - grid-row: 4; 569 - grid-column: 1; 570 - } 628 + .share-button-container { 629 + gap: 10px; 630 + } 571 631 572 - .share-button-container { 573 - gap: 10px; 574 - } 632 + .user-profile-score { 633 + padding: 0px; 634 + } 575 635 576 - .user-profile-score { 577 - padding: 0px; 578 - } 636 + .share-button-container { 637 + grid-row: 5; 638 + grid-column: 1; 639 + text-align: center; 640 + } 579 641 580 - .share-button-container { 581 - grid-row: 5; 582 - grid-column: 1; 583 - text-align: center; 584 - } 642 + .user-profile-header { 643 + margin-left: 0px; 644 + row-gap: 10px; 645 + } 646 + .user-profile-data-group { 647 + text-align: center; 648 + } 585 649 586 - .user-profile-header { 587 - margin-left: 0px; 588 - row-gap: 10px; 589 - } 590 - .user-profile-data-group { 591 - text-align: center; 592 - } 650 + .share-button-container { 651 + text-align: center; 652 + } 593 653 594 - .share-button-container { 595 - text-align: center; 596 - } 654 + .profile-section.left-section { 655 + scale: 0.6; 656 + margin-top: -64.5px; 657 + } 597 658 598 - .profile-section.left-section { 599 - scale: 0.6; 600 - margin-top: -64.5px; 601 - } 659 + .profile-section.middle-section { 660 + margin-top: -85.7px; 661 + gap: 13.5px; 662 + grid-column: 1; 663 + grid-row: 2; 664 + margin-right: 0px; 665 + } 602 666 603 - .profile-section.middle-section { 604 - margin-top: -85.7px; 605 - gap: 13.5px; 606 - grid-column: 1; 607 - grid-row: 2; 608 - margin-right: 0px; 609 - } 667 + .user-profile-badges { 668 + margin-top: 0px; 669 + } 610 670 611 - .user-profile-badges { 612 - margin-top: 0px; 613 - } 671 + .text-center.font-semibold.mt-2 { 672 + font-size: 1.5em; 673 + } 614 674 615 - .text-center.font-semibold.mt-2 { 616 - font-size: 1.5em; 617 - } 675 + .react-grid-layout { 676 + margin: 10px; 677 + } 618 678 679 + .react-grid-item { 680 + margin-bottom: 15px; 681 + } 619 682 } 620 683 621 684 @media (max-width: 440px) { 622 - .score-breakdown-card .disclaimer { 623 - font-size: .7em !important; 624 - margin: 0px; 625 - margin-top: 0px; 626 - max-width: 300px; 627 - } 685 + .score-breakdown-card .disclaimer { 686 + font-size: .7em !important; 687 + margin: 0px; 688 + margin-top: 0px; 689 + max-width: 300px; 690 + } 691 + 692 + .react-resizable-handle { 693 + width: 20px; 694 + height: 20px; 695 + } 696 + 697 + /* Make the resizing handle more touch-friendly on small screens */ 698 + .react-resizable-handle::after { 699 + content: ''; 700 + position: absolute; 701 + width: 20px; 702 + height: 20px; 703 + bottom: 0; 704 + right: 0; 705 + background-color: rgba(0, 0, 0, 0.1); 706 + border-radius: 0 0 5px 0; 707 + } 628 708 }
+143 -26
src/components/UserProfile/UserProfile.js
··· 58 58 ], 59 59 xs: [ 60 60 { i: "ScoreBreakdownCard", x: 0, y: 8, w: 1, h: 6, static: false }, 61 - { i: "NarrativeCard", x: 1, y: 0, w: 1, h: 6, static: false }, 61 + { i: "NarrativeCard", x: 0, y: 0, w: 1, h: 6, static: false }, 62 62 { i: "ProfileCard", x: 0, y: 14, w: 1, h: 6, static: false }, 63 - { i: "PostTypeCard", x: 1, y: 22, w: 1, h: 6, static: false }, 63 + { i: "PostTypeCard", x: 0, y: 22, w: 1, h: 6, static: false }, 64 64 { i: "AltTextCard", x: 0, y: 26, w: 1, h: 6, static: false }, 65 - { i: "ActivityCard", x: 1, y: 30, w: 1, h: 6, static: false } 65 + { i: "ActivityCard", x: 0, y: 30, w: 1, h: 6, static: false } 66 66 ], 67 67 xxs: [ 68 68 { i: "ScoreBreakdownCard", x: 0, y: 8, w: 1, h: 6, static: false }, 69 - { i: "NarrativeCard", x: 1, y: 0, w: 1, h: 8, static: false }, 69 + { i: "NarrativeCard", x: 0, y: 0, w: 1, h: 8, static: false }, 70 70 { i: "ProfileCard", x: 0, y: 14, w: 1, h: 7, static: false }, 71 - { i: "PostTypeCard", x: 1, y: 22, w: 1, h: 6, static: false }, 71 + { i: "PostTypeCard", x: 0, y: 22, w: 1, h: 6, static: false }, 72 72 { i: "AltTextCard", x: 0, y: 26, w: 1, h: 6, static: false }, 73 - { i: "ActivityCard", x: 1, y: 30, w: 1, h: 6, static: false } 73 + { i: "ActivityCard", x: 0, y: 30, w: 1, h: 6, static: false } 74 74 ] 75 75 }); 76 76 77 - const layouts = createLayouts(); 78 - 79 77 // Memoized save function with debouncing 80 - // Update createDebouncedSave function in UserProfile.js 81 78 const createDebouncedSave = () => { 82 79 let timeout; 83 80 return async (userData) => { ··· 201 198 const [showContent, setShowContent] = useState(false); 202 199 const cardRefs = useRef({}); 203 200 const [cardHeights, setCardHeights] = useState({}); 201 + 202 + // Add state for saving and restoring layouts 203 + const [currentLayouts, setCurrentLayouts] = useState(() => { 204 + // Try to load saved layouts from localStorage 205 + const savedLayouts = localStorage.getItem('userProfileLayouts'); 206 + return savedLayouts ? JSON.parse(savedLayouts) : createLayouts(); 207 + }); 204 208 205 - // Memoize layout-related calculations 209 + // Function to handle layout changes 210 + const handleLayoutChange = (layout, allLayouts) => { 211 + if (allLayouts) { 212 + // Save to state 213 + setCurrentLayouts(allLayouts); 214 + 215 + // Save to localStorage 216 + localStorage.setItem('userProfileLayouts', JSON.stringify(allLayouts)); 217 + } 218 + 219 + // Update card heights after layout changes 220 + setTimeout(updateCardHeights, 100); 221 + }; 222 + 223 + // Improved card height calculation 206 224 const updateCardHeights = useMemo(() => { 207 225 return () => { 208 - const rowHeight = 50; 226 + const rowHeight = 50; // Same as your rowHeight prop 227 + const margin = 20; // Same as your margin prop 209 228 const newHeights = {}; 229 + const currentWidth = window.innerWidth; 230 + 231 + // Determine current breakpoint 232 + let currentBreakpoint = 'lg'; 233 + for (const [bp, width] of Object.entries(breakpoints)) { 234 + if (currentWidth <= width) { 235 + currentBreakpoint = bp; 236 + } 237 + } 238 + 239 + // Get the number of columns for the current breakpoint 240 + const numCols = cols[currentBreakpoint]; 241 + 242 + // Adjust calculations based on available width 243 + const containerWidth = document.querySelector('.user-profile')?.clientWidth || window.innerWidth; 244 + const availableWidth = (containerWidth - (margin * (numCols + 1))) / numCols; 210 245 211 246 Object.keys(cardRefs.current).forEach(key => { 212 247 const element = cardRefs.current[key]; 213 248 if (element) { 214 - const contentHeight = element.scrollHeight; 215 - const gridHeight = Math.ceil(contentHeight / rowHeight); 216 - newHeights[key] = Math.max(gridHeight, 6); 249 + // Get the content element (assuming each card has a .card-content) 250 + const contentElement = element.querySelector('.card-content') || element; 251 + 252 + // Clone the element to measure its natural height without constraints 253 + const clone = contentElement.cloneNode(true); 254 + clone.style.position = 'absolute'; 255 + clone.style.visibility = 'hidden'; 256 + clone.style.width = `${availableWidth}px`; 257 + clone.style.height = 'auto'; 258 + document.body.appendChild(clone); 259 + 260 + // Measure natural height 261 + const contentHeight = clone.scrollHeight; 262 + 263 + // Remove the clone 264 + document.body.removeChild(clone); 265 + 266 + // Calculate grid height based on content 267 + const gridHeight = Math.max(Math.ceil(contentHeight / rowHeight), 6); 268 + 269 + // Store the new height 270 + newHeights[key] = gridHeight; 217 271 } 218 272 }); 219 273 274 + // Update layout with new heights 275 + const updatedLayouts = {}; 276 + 277 + for (const [bp, layout] of Object.entries(currentLayouts)) { 278 + updatedLayouts[bp] = layout.map(item => { 279 + if (newHeights[item.i]) { 280 + return { ...item, h: newHeights[item.i] }; 281 + } 282 + return item; 283 + }); 284 + } 285 + 286 + // Only update if there are actual changes 287 + if (!_.isEqual(updatedLayouts, currentLayouts)) { 288 + setCurrentLayouts(updatedLayouts); 289 + localStorage.setItem('userProfileLayouts', JSON.stringify(updatedLayouts)); 290 + } 291 + 292 + // Update state with new heights 220 293 setCardHeights(newHeights); 221 294 }; 222 - }, []); 295 + }, [currentLayouts]); 296 + 297 + // Add a function to handle window resize events more effectively 298 + const handleWindowResize = useMemo(() => { 299 + return _.debounce(() => { 300 + // Update card heights and force layout refresh 301 + updateCardHeights(); 302 + 303 + // Force a layout recalculation 304 + const gridLayoutElement = document.querySelector('.react-grid-layout'); 305 + if (gridLayoutElement) { 306 + // This forces a reflow 307 + const temp = gridLayoutElement.offsetHeight; 308 + } 309 + }, 200); 310 + }, [updateCardHeights]); 223 311 224 312 // Optimized data fetching with DID support 225 313 useEffect(() => { ··· 283 371 fetchAccountData(); 284 372 }, [username, navigate, updateCardHeights]); 285 373 286 - // Memoized resize handler 374 + // Add effect to initialize the layout on first render 287 375 useEffect(() => { 288 - const handleResize = _.debounce(() => { 376 + // Small delay to ensure DOM is ready 377 + setTimeout(updateCardHeights, 300); 378 + 379 + // Add a resize observer to each card to handle content changes 380 + const resizeObserver = new ResizeObserver(_.debounce(() => { 289 381 updateCardHeights(); 290 - }, 250); 291 - 292 - window.addEventListener('resize', handleResize); 382 + }, 300)); 383 + 384 + Object.values(cardRefs.current).forEach(ref => { 385 + if (ref) { 386 + resizeObserver.observe(ref); 387 + } 388 + }); 389 + 293 390 return () => { 294 - window.removeEventListener('resize', handleResize); 295 - handleResize.cancel(); 391 + resizeObserver.disconnect(); 296 392 }; 297 393 }, [updateCardHeights]); 394 + 395 + // Memoized resize handler 396 + useEffect(() => { 397 + window.addEventListener('resize', handleWindowResize); 398 + return () => { 399 + window.removeEventListener('resize', handleWindowResize); 400 + handleWindowResize.cancel(); 401 + }; 402 + }, [handleWindowResize]); 298 403 299 404 if (loading) { 300 405 return ( ··· 396 501 397 502 <ResponsiveGridLayout 398 503 className="layout" 399 - layouts={layouts} 504 + layouts={currentLayouts} 400 505 breakpoints={breakpoints} 401 506 cols={cols} 402 507 rowHeight={50} 403 508 margin={[20, 20]} 404 - isDraggable={false} 405 - isResizable={false} 509 + isDraggable={true} 510 + isResizable={true} 406 511 useCSSTransforms={true} 407 - onLayoutChange={() => updateCardHeights()} 512 + onLayoutChange={handleLayoutChange} 408 513 draggableHandle=".card-header" 514 + resizeHandles={['se']} 515 + compactType="vertical" 516 + preventCollision={false} 517 + autoSize={true} 518 + onBreakpointChange={(newBreakpoint) => { 519 + // Recalculate heights when breakpoint changes 520 + setTimeout(updateCardHeights, 100); 521 + }} 522 + onWidthChange={(width, margin, cols) => { 523 + // Recalculate heights when width changes 524 + setTimeout(updateCardHeights, 100); 525 + }} 409 526 > 410 527 <div key="ScoreBreakdownCard" className="grid-item" ref={el => cardRefs.current.ScoreBreakdownCard = el}> 411 528 <Card title="Score Breakdown">