403Webshell
Server IP : 217.154.3.148  /  Your IP : 216.73.216.90
Web Server : Apache
System : Linux blissful-wright.217-154-3-148.plesk.page 6.8.0-124-generic #124-Ubuntu SMP PREEMPT_DYNAMIC Tue May 26 13:00:45 UTC 2026 x86_64
User : gracious-boyd_hfhh1h8vo9n ( 10000)
PHP Version : 8.3.31
Disable Function : opcache_get_status
MySQL : OFF  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /var/www/vhosts/gracious-boyd.217-154-3-148.plesk.page/nextjs/src/components/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/vhosts/gracious-boyd.217-154-3-148.plesk.page/nextjs/src/components/ScenePreview.tsx
'use client';

import React, { useMemo } from 'react';
import type { TileScene, TileAssignment, TileDesign } from '@/src/types/tiles';
import { getTileVariation, tileKey } from '@/src/utils/tiles';

type ScenePreviewProps = {
  scene: TileScene;
  assignments: TileAssignment[];
  designsById: Record<number, TileDesign>;
  selectedTiles: Set<string>;
  onToggleTile: (row: number, col: number) => void;
};

export default function ScenePreview({
  scene,
  assignments,
  designsById,
  selectedTiles,
  onToggleTile,
}: ScenePreviewProps) {
  const overlayWidth = scene.tileWidthPx * scene.cols;
  const overlayHeight = scene.tileHeightPx * scene.rows;
  const groutColor = scene.groutColor ?? 'rgba(255,255,255,0.75)';

  const sortedAssignments = useMemo(
    () => [...assignments].sort((a, b) => (a.row === b.row ? a.col - b.col : a.row - b.row)),
    [assignments],
  );

  return (
    <div
      style={{
        position: 'relative',
        width: '100%',
        borderRadius: 12,
        overflow: 'hidden',
        border: '1px solid #e5e7eb',
        backgroundColor: '#111827',
      }}
    >
      <img
        src={scene.imageUrl}
        alt={scene.label}
        style={{ width: '100%', display: 'block', objectFit: 'cover' }}
      />
      <div
        style={{
          position: 'absolute',
          inset: 0,
          background: 'radial-gradient(circle at center, transparent 40%, rgba(0,0,0,0.18))',
          pointerEvents: 'none',
        }}
      />
      <div
        style={{
          position: 'absolute',
          left: scene.offsetX ?? 0,
          top: scene.offsetY ?? 0,
          width: overlayWidth,
          height: overlayHeight,
          display: 'grid',
          gridTemplateColumns: `repeat(${scene.cols}, ${scene.tileWidthPx}px)`,
          gridTemplateRows: `repeat(${scene.rows}, ${scene.tileHeightPx}px)`,
          boxShadow: '0 16px 30px rgba(0,0,0,0.22)',
          pointerEvents: 'none',
          transform: scene.perspectiveTransform ?? 'none',
          transformOrigin: 'center center',
          filter: scene.overlayFilter ?? 'none',
          overflow: 'visible',
        }}
      >
        {sortedAssignments.map((tile) => {
          const design = tile.designId ? designsById[tile.designId] : null;
          const key = tileKey(tile.row, tile.col);
          const isSelected = selectedTiles.has(key);
          const { rotateDeg, scale } = getTileVariation(tile.row, tile.col);
          return (
            <button
              key={`${tile.row}-${tile.col}`}
              type="button"
              onClick={(e) => {
                e.stopPropagation();
                onToggleTile(tile.row, tile.col);
              }}
              style={{
                backgroundImage: design ? `url(${design.imageUrl})` : 'none',
                backgroundSize: 'cover',
                backgroundPosition: 'center',
                border: `1px solid ${groutColor}`,
                cursor: 'pointer',
                boxShadow: `${isSelected ? '0 0 0 2px #2563eb inset, ' : ''} inset 0 0 4px rgba(0,0,0,0.12)`,
                outline: isSelected ? '1px solid rgba(37,99,235,0.8)' : undefined,
                backgroundColor: isSelected ? 'rgba(255,255,255,0.08)' : undefined,
                pointerEvents: 'auto',
                position: 'relative',
                boxSizing: 'border-box',
                transform: `scale(${scale}) rotate(${rotateDeg}deg)`,
                transformOrigin: 'center center',
              }}
            >
              {isSelected ? (
                <div
                  style={{
                    position: 'absolute',
                    inset: 0,
                    background: 'radial-gradient(circle at center, rgba(37,99,235,0.18), transparent 60%)',
                    pointerEvents: 'none',
                  }}
                />
              ) : null}
            </button>
          );
        })}
        <div
          style={{
            position: 'absolute',
            inset: 0,
            pointerEvents: 'none',
            background: 'linear-gradient(to bottom, rgba(255,255,255,0.18), rgba(0,0,0,0.12))',
            mixBlendMode: 'soft-light',
          }}
        />
      </div>
    </div>
  );
}

Youez - 2016 - github.com/yon3zu
LinuXploit