Remove VS screen; fix cropper + sports edit save + headshot/logo mapping

- Remove VS intro from player and thumbnail VS card from match video cards.
  All references (`msb-vs*`, `initVsIntro`, `setVsImg`, `HAS_VS`, `$vs`,
  `$msbThumbVs`, `$hasMatchMeta`) are stripped from scoreboard partials,
  video-card component, and scoreboard script. Related CSS keyframes
  (`msbFadeIn/Out`, `msbDriftA/B`, `msbSweep`) removed.

- Image cropper (resources/views/components/image-cropper.blade.php):
  replace unreliable third-party Cropme integration with a DIY cropper.
  Pan/zoom/rotate wired directly with pointer + wheel events; on save,
  the visible viewport is rendered to an offscreen canvas at the configured
  output-width (with circular clip for `shape="circle"`). Also reparent the
  overlay to <body> on open to escape any transformed Bootstrap-modal
  ancestor's stacking context that clipped it.

- Sports match modal (resources/views/layouts/partials/sports-match-modal.blade.php):
  set fighter photo croppers to 3:4 portrait (285x380) to match the VS
  card's 228x304 frame; club logos + referee stay 1:1 square.

- SportsMatchController::fillFromRequest (line 174): coerce
  `$this->clean($request->input('media', []))` to `[]` when it returns null
  so array_merge doesn't crash under PHP 8's stricter types.

- SportsMatch::headerData(): read fighter headshots + club logos from the
  canonical media.* keys (participant1_photo / participant2_photo /
  club1_logo / club2_logo) that the uploader modal actually saves, with the
  older p1_* / p2_* names kept as a secondary fallback.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
ghassanandClaude Opus 4.7 committed 2026-08-09 23:47:59 +03:00
1 parent 19741f489b
commit 2b5e480c9a
9 files changed
+235 -323

No files matched your search

@@ -166,7 +166,9 @@ class SportsMatchController extends Controller
// Media text fields (caption/alt/credit/public). Preserve existing image
// paths already on the record; handleImages() overwrites any replaced ones.
$existingMedia = $match->media ?? [];
$mediaText = $this->clean($request->input('media', []));
// clean() returns null when the array is entirely empty — coerce back to []
// so array_merge() doesn't blow up on PHP 8's stricter type checking.
$mediaText = $this->clean($request->input('media', [])) ?? [];
if (isset($mediaText['public'])) {
$mediaText['public'] = filter_var($mediaText['public'], FILTER_VALIDATE_BOOLEAN);
}