Newer
Older
clothes / index.php
@airebros airebros 1 day ago 25 KB a
<?php
session_name('d2c_session');
session_start();
require_once __DIR__ . '/config.php';

// Demo/mock project state
$project = [
    'title'       => 'ThreadVision SS26 Capsule',
    'description' => 'AI-assisted fashion mockup workflow for mapping 2D graphics onto 3D garment avatars. Focus: oversized tee and hoodie variants for portfolio-ready exports.',
];

// Scan existing uploads for this session
$sessionUploadDir = UPLOAD_DIR . (session_id() ?: 'demo') . '/';
$uploadedAssets   = [];
if (is_dir($sessionUploadDir)) {
    foreach (glob($sessionUploadDir . '*') as $f) {
        $ext = strtoupper(pathinfo($f, PATHINFO_EXTENSION));
        $uploadedAssets[] = [
            'name' => basename($f),
            'ext'  => $ext,
            'url'  => APP_BASE_PATH . '/media/uploads/' . session_id() . '/' . basename($f),
        ];
    }
}

// Predefined models
$predefinedModels = [
    ['id' => 'model_f_front',     'label' => 'Female — Front',   'icon' => 'fa-person-dress'],
    ['id' => 'model_f_3q',        'label' => 'Female — 3/4',     'icon' => 'fa-person-dress'],
    ['id' => 'model_m_front',     'label' => 'Male — Front',     'icon' => 'fa-person'],
    ['id' => 'model_m_3q',        'label' => 'Male — 3/4',       'icon' => 'fa-person'],
    ['id' => 'model_m_side',      'label' => 'Male — Side',      'icon' => 'fa-person'],
    ['id' => 'model_flat_tee',    'label' => 'Flat — Tee',       'icon' => 'fa-shirt'],
    ['id' => 'model_flat_hoodie', 'label' => 'Flat — Hoodie',    'icon' => 'fa-shirt'],
];
?>
<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Design2Clothes — AI Fashion Designer</title>
  <meta name="description" content="AI-powered fashion mockup designer. Upload your artwork, generate a model, apply your design and export in high resolution.">

  <!-- Bootstrap 5 -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
  <!-- Font Awesome 6 (local) -->
  <link rel="stylesheet" href="<?= APP_BASE_PATH ?>/css/all.min.css">
  <!-- Google Fonts: Inter -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
  <!-- App CSS -->
  <link rel="stylesheet" href="<?= APP_BASE_PATH ?>/css/style.css">
</head>
<body>

<div class="app-wrapper" id="appWrapper">

  <!-- ═══════════════════════════════════════════════════════
       TOPBAR / HEADER
  ═══════════════════════════════════════════════════════ -->
  <header class="app-header">
    <div class="app-brand">Design2Clothes</div>
    <div class="d-flex align-center gap-3">
      <!-- Step indicator -->
      <div class="step-indicator" id="stepIndicator">
        <span class="step-pip active" data-step="1" title="1. Upload">1</span>
        <span class="step-sep"><i class="fa-solid fa-chevron-right"></i></span>
        <span class="step-pip" data-step="2" title="2. Modelo">2</span>
        <span class="step-sep"><i class="fa-solid fa-chevron-right"></i></span>
        <span class="step-pip" data-step="3" title="3. Apply">3</span>
        <span class="step-sep"><i class="fa-solid fa-chevron-right"></i></span>
        <span class="step-pip" data-step="4" title="4. Export">4</span>
      </div>
      <button class="btn-d2c btn-orange btn-d2c--lg" id="btnNewProject">
        <i class="fa-solid fa-plus"></i> New Project
      </button>
    </div>
  </header>

  <!-- ═══════════════════════════════════════════════════════
       DASH ROW — Quick Access + Project Info
  ═══════════════════════════════════════════════════════ -->
  <div class="dash-row">

    <!-- Quick Access -->
    <div class="panel" style="width:288px;flex-shrink:0;">
      <div class="panel-title">Quick Access</div>
      <button class="btn-d2c btn-purple btn-d2c--md btn-d2c--full" id="btnAssetLib">
        <i class="fa-solid fa-images"></i> Asset Library
      </button>
      <button class="btn-d2c btn-dark btn-d2c--md btn-d2c--full" id="btnProjectsList">
        <i class="fa-solid fa-list"></i> Projects List
      </button>
    </div>

    <!-- Project Info -->
    <div class="panel flex-1">
      <div class="panel-label">Current Project</div>
      <div class="d-flex align-center justify-between">
        <div class="project-title" id="projectTitle"><?= htmlspecialchars($project['title']) ?></div>
        <button class="btn-icon" id="btnEditTitle" title="Edit title">
          <i class="fa-solid fa-pencil"></i>
        </button>
      </div>
      <div class="project-desc" id="projectDesc"><?= htmlspecialchars($project['description']) ?></div>
    </div>

  </div><!-- /dash-row -->

  <!-- ═══════════════════════════════════════════════════════
       CANVAS SHELL — 3 Columns
  ═══════════════════════════════════════════════════════ -->
  <div class="canvas-shell">

    <!-- ────────────────────────────────────────────────────
         LEFT PANEL — Assets + Inspector
    ──────────────────────────────────────────────────── -->
    <aside class="canvas-left">
      <div class="panel h-100">

        <!-- ── STEP 1: Assets ── -->
        <div class="panel-title d-flex align-center justify-between">
          Assets
          <span class="step-badge">Step 1</span>
        </div>

        <!-- Asset tabs -->
        <div class="tabs-d2c" id="assetTabs">
          <button class="tab-item active--purple" data-tab="tabUploads">Uploads</button>
          <button class="tab-item" data-tab="tabPatterns">Patterns</button>
          <button class="tab-item" data-tab="tabGraphics">Graphics</button>
        </div>

        <!-- Tab: Uploads -->
        <!-- fileInput is OUTSIDE uploadZone to prevent click() bubbling up into zone handler -->
        <input type="file" id="fileInput" accept=".png,.jpg,.jpeg,.svg" multiple style="display:none;position:absolute;">
        <div class="tab-pane active" id="tabUploads">
          <!-- Drop zone -->
          <div class="upload-zone" id="uploadZone">
            <i class="fa-solid fa-cloud-arrow-up"></i>
            <p>Drop .png .jpg .svg here</p>
            <button class="btn-d2c btn-dark btn-d2c--sm" type="button" id="btnBrowse">
              <i class="fa-solid fa-folder-open"></i> Browse
            </button>
          </div>
          <!-- Asset list -->
          <div class="asset-list" id="assetList">
            <?php foreach ($uploadedAssets as $asset): ?>
            <div class="asset-item" data-url="<?= htmlspecialchars($asset['url']) ?>" data-name="<?= htmlspecialchars($asset['name']) ?>">
              <div class="d-flex align-center gap-2">
                <i class="fa-solid fa-file-image" style="font-size:15px;color:var(--clr-accent-purple)"></i>
                <span class="asset-item__name"><?= htmlspecialchars($asset['name']) ?></span>
              </div>
              <span class="file-badge file-badge--<?= strtolower($asset['ext']) ?>"><?= $asset['ext'] ?></span>
            </div>
            <?php endforeach; ?>
          </div>
          <?php if (empty($uploadedAssets)): ?>
          <div class="empty-hint" id="emptyHint">
            <i class="fa-solid fa-inbox"></i>
            <span>No assets yet</span>
          </div>
          <?php endif; ?>
        </div>

        <!-- Tab: Patterns (placeholder) -->
        <div class="tab-pane" id="tabPatterns">
          <div class="empty-hint"><i class="fa-solid fa-swatchbook"></i><span>Patterns coming soon</span></div>
        </div>

        <!-- Tab: Graphics (placeholder) -->
        <div class="tab-pane" id="tabGraphics">
          <div class="empty-hint"><i class="fa-solid fa-pen-ruler"></i><span>Graphics coming soon</span></div>
        </div>

        <div class="divider-d2c"></div>

        <!-- ── STEP 2: Inspector ── -->
        <div class="panel-title d-flex align-center justify-between">
          Inspector
          <span class="step-badge">Step 2</span>
        </div>

        <!-- Model Controls -->
        <div class="subpanel">
          <div class="panel-title--sm">Model Controls</div>

          <!-- Custom / Predefined tabs -->
          <div class="tabs-d2c" id="modelTabs">
            <button class="tab-item active--purple" data-tab="tabCustom">Custom</button>
            <button class="tab-item" data-tab="tabPredefined">Predefined</button>
          </div>

          <!-- Custom mode -->
          <div class="tab-pane active" id="tabCustom">
            <div class="form-group">
              <label class="form-label-d2c">Model Prompt</label>
              <textarea class="field-d2c textarea-d2c" id="modelPrompt" rows="2"
                placeholder="editorial female model, hands in pockets, studio light..."></textarea>
            </div>
            <div class="form-group">
              <label class="form-label-d2c">Pose</label>
              <select class="field-d2c select-d2c" id="modelPose">
                <option value="front">Front</option>
                <option value="threequarter">3/4 View</option>
                <option value="side">Side</option>
                <option value="back">Back</option>
              </select>
            </div>
          </div>

          <!-- Predefined mode -->
          <div class="tab-pane" id="tabPredefined">
            <div class="predefined-grid" id="predefinedGrid">
              <?php foreach ($predefinedModels as $m): ?>
              <div class="predefined-item" data-model="<?= $m['id'] ?>">
                <i class="fa-solid <?= $m['icon'] ?>"></i>
                <span><?= $m['label'] ?></span>
              </div>
              <?php endforeach; ?>
            </div>
          </div>
        </div>

        <!-- Garment Controls -->
        <div class="subpanel">
          <div class="panel-title--sm">Garment Controls</div>
          <div class="form-row">
            <span class="form-row__label">Type</span>
            <select class="field-d2c select-d2c" id="garmentType" style="height:28px;font-size:11px;padding:0 24px 0 8px;flex:1;margin-left:8px;">
              <option value="oversized_tee">Oversized Tee</option>
              <option value="slim_fit">Slim Fit</option>
              <option value="hoodie">Hoodie</option>
              <option value="jacket">Jacket</option>
              <option value="dress">Dress</option>
            </select>
          </div>
          <div class="form-row">
            <span class="form-row__label">Fabric</span>
            <select class="field-d2c select-d2c" id="garmentFabric" style="height:28px;font-size:11px;padding:0 24px 0 8px;flex:1;margin-left:8px;">
              <option value="cotton">Cotton</option>
              <option value="jersey">Jersey</option>
              <option value="heavyweight">Heavyweight</option>
              <option value="linen">Linen</option>
              <option value="denim">Denim</option>
            </select>
          </div>
          <div class="form-row" style="justify-content:space-between;">
            <span class="form-row__label">Base Colour</span>
            <input type="color" id="garmentColor" value="#3A3A3A" class="color-input-d2c" title="Base colour">
          </div>
        </div>

        <!-- STEP 2 — Generate button -->
        <button class="btn-d2c btn-purple btn-d2c--md btn-d2c--full" id="btnGenerateModel">
          <i class="fa-solid fa-wand-magic-sparkles"></i> Generate Model
        </button>

        <div class="divider-d2c"></div>

        <!-- ── STEP 3: Artwork Controls ── -->
        <div class="panel-title--sm d-flex align-center justify-between">
          Artwork Controls
          <span class="step-badge">Step 3</span>
        </div>

        <div class="subpanel">
          <!-- Scale -->
          <div class="form-group">
            <div class="d-flex justify-between">
              <label class="form-label-d2c mb-0">Scale</label>
              <span class="form-label-d2c mb-0" id="scaleVal">85%</span>
            </div>
            <input type="range" class="range-d2c" id="artScale" min="10" max="200" value="85">
          </div>
          <!-- Rotation -->
          <div class="form-group">
            <div class="d-flex justify-between">
              <label class="form-label-d2c mb-0">Rotation</label>
              <span class="form-label-d2c mb-0" id="rotVal">0°</span>
            </div>
            <input type="range" class="range-d2c" id="artRotation" min="-180" max="180" value="0">
          </div>
          <!-- Opacity -->
          <div class="form-group">
            <div class="d-flex justify-between">
              <label class="form-label-d2c mb-0">Opacity</label>
              <span class="form-label-d2c mb-0" id="opaVal">82%</span>
            </div>
            <input type="range" class="range-d2c" id="artOpacity" min="0" max="100" value="82">
          </div>
          <!-- Blending -->
          <div class="form-group">
            <label class="form-label-d2c">Blending Mode</label>
            <select class="field-d2c select-d2c" id="artBlending">
              <option value="print">Print</option>
              <option value="multiply">Multiply</option>
              <option value="soft_light">Soft Light</option>
              <option value="overlay">Overlay</option>
              <option value="screen">Screen</option>
            </select>
          </div>
        </div>

      </div><!-- /panel left -->
    </aside>

    <!-- ────────────────────────────────────────────────────
         CENTER PANEL — Design Canvas
    ──────────────────────────────────────────────────── -->
    <main class="canvas-center">
      <div class="panel panel--alt h-100">

        <div class="d-flex align-center justify-between">
          <div class="panel-title">Design Canvas</div>
          <div class="d-flex gap-2">
            <button class="btn-icon" id="btnZoomIn" title="Zoom in"><i class="fa-solid fa-magnifying-glass-plus"></i></button>
            <button class="btn-icon" id="btnZoomOut" title="Zoom out"><i class="fa-solid fa-magnifying-glass-minus"></i></button>
            <button class="btn-icon" id="btnZoomReset" title="Reset zoom"><i class="fa-solid fa-expand"></i></button>
          </div>
        </div>

        <!-- Viewport -->
        <div class="design-viewport" id="designViewport">

          <!-- Empty state -->
          <div class="viewport-empty" id="viewportEmpty">
            <i class="fa-solid fa-shirt"></i>
            <p>Generate a model to start designing</p>
            <div class="viewport-steps">
              <div class="vs-step active" id="vs1">
                <span class="vs-num">1</span> Upload artwork
              </div>
              <i class="fa-solid fa-arrow-right vs-arrow"></i>
              <div class="vs-step" id="vs2">
                <span class="vs-num">2</span> Generate model
              </div>
              <i class="fa-solid fa-arrow-right vs-arrow"></i>
              <div class="vs-step" id="vs3">
                <span class="vs-num">3</span> Apply artwork
              </div>
            </div>
          </div>

          <!-- Canvas content (hidden until model generated) -->
          <div class="viewport-content" id="viewportContent" style="display:none;">
            <div class="canvas-layers" id="canvasLayers">
              <!-- Model image layer -->
              <img src="" alt="Generated model" class="layer-model" id="layerModel">
              <!-- Artwork overlay layer -->
              <img src="" alt="Artwork overlay" class="layer-artwork" id="layerArtwork">
            </div>
            <div class="viewport-label">AI Texture-Mapped Preview</div>
          </div>

          <!-- Loading overlay -->
          <div class="viewport-loading" id="viewportLoading" style="display:none;">
            <div class="spinner-d2c spinner-d2c--lg"></div>
            <p id="loadingMsg">Generating model...</p>
            <div class="progress-d2c" style="width:200px;margin-top:12px;">
              <div class="progress-bar-d2c" id="loadingBar" style="width:0%"></div>
            </div>
          </div>

        </div><!-- /viewport -->

        <!-- Apply Artwork prompt + button (Step 3) -->
        <div class="apply-prompt-wrap" id="applyPromptWrap">
          <label class="form-label-d2c">
            <span class="step-badge me-1">Step 3</span> Apply Artwork Prompt
            <span class="text-muted-d ms-2" style="font-weight:400;font-size:10px;">(optional refinement)</span>
          </label>
          <div class="input-wrap">
            <i class="fa-solid fa-comment-dots input-icon"></i>
            <input type="text" class="field-d2c input-d2c" id="applyPromptInput"
              placeholder="Make print placement sharper and aligned to chest...">
          </div>
        </div>

        <div class="d-flex gap-2">
          <button class="btn-d2c btn-orange btn-d2c--md flex-1" id="btnApplyArtwork" disabled>
            <i class="fa-solid fa-wand-magic-sparkles"></i> Apply Artwork
          </button>
          <button class="btn-icon" id="btnUndoApply" title="Undo last apply" disabled>
            <i class="fa-solid fa-rotate-left"></i>
          </button>
        </div>

      </div><!-- /panel center -->
    </main>

    <!-- ────────────────────────────────────────────────────
         RIGHT PANEL — Export (Step 4)
    ──────────────────────────────────────────────────── -->
    <aside class="canvas-right">
      <div class="panel h-100">

        <div class="panel-title d-flex align-center justify-between">
          Export
          <span class="step-badge">Step 4</span>
        </div>

        <!-- Result preview thumbnail -->
        <div class="export-thumb" id="exportThumb">
          <i class="fa-solid fa-image"></i>
          <span>Result preview</span>
        </div>

        <div class="panel-label">Summary</div>
        <div class="export-meta" id="exportMeta">
          <div class="export-meta-row">
            <span><i class="fa-solid fa-shirt"></i> Type</span>
            <span id="metaType">—</span>
          </div>
          <div class="export-meta-row">
            <span><i class="fa-solid fa-layer-group"></i> Asset</span>
            <span id="metaAsset">—</span>
          </div>
          <div class="export-meta-row">
            <span><i class="fa-solid fa-sliders"></i> Blending</span>
            <span id="metaBlending">—</span>
          </div>
          <div class="export-meta-row">
            <span><i class="fa-solid fa-rotate"></i> Scale / Rot</span>
            <span id="metaScaleRot">—</span>
          </div>
        </div>

        <div class="divider-d2c"></div>

        <div class="panel-label">Resolution</div>
        <div class="resolution-list" id="resolutionList">
          <label class="res-option">
            <input type="radio" name="exportRes" value="2k"> <span>2K PNG <small>2048×2048</small></span>
          </label>
          <label class="res-option">
            <input type="radio" name="exportRes" value="4k" checked> <span>4K PNG <small>4096×4096</small></span>
          </label>
          <label class="res-option">
            <input type="radio" name="exportRes" value="instagram"> <span>Instagram <small>1080×1350</small></span>
          </label>
          <label class="res-option">
            <input type="radio" name="exportRes" value="story"> <span>Story <small>1080×1920</small></span>
          </label>
          <label class="res-option">
            <input type="radio" name="exportRes" value="original"> <span>Original <small>as generated</small></span>
          </label>
        </div>

        <div class="divider-d2c"></div>

        <div class="panel-label">Format</div>
        <div class="format-row">
          <label class="res-option">
            <input type="radio" name="exportFmt" value="png" checked> <span>PNG</span>
          </label>
          <label class="res-option">
            <input type="radio" name="exportFmt" value="jpg"> <span>JPG</span>
          </label>
          <label class="res-option">
            <input type="radio" name="exportFmt" value="webp"> <span>WebP</span>
          </label>
        </div>

        <div class="divider-d2c"></div>

        <button class="btn-d2c btn-orange btn-d2c--md btn-d2c--full" id="btnExport" disabled>
          <i class="fa-solid fa-arrow-up-from-bracket"></i> Export
        </button>

        <div class="export-status" id="exportStatus" style="display:none;"></div>

      </div><!-- /panel right -->
    </aside>

  </div><!-- /canvas-shell -->

  <!-- ═══════════════════════════════════════════════════════
       FOOTER
  ═══════════════════════════════════════════════════════ -->
  <footer class="app-footer">
    <span>Design2Clothes &copy; <?= date('Y') ?> — AI Fashion Designer</span>
    <span class="d-flex align-center gap-3">
      <span id="apiStatus" class="api-status api-status--idle">
        <i class="fa-solid fa-circle"></i> Idle
      </span>
      <a href="ui-kit.html" target="_blank" class="text-dim">
        <i class="fa-solid fa-palette"></i> UI Kit
      </a>
    </span>
  </footer>

</div><!-- /app-wrapper -->

<!-- ═══════════════════════════════════════════════════════
     MODALS
═══════════════════════════════════════════════════════ -->

<!-- New Project Modal -->
<div class="modal-overlay" id="modalNewProject">
  <div class="modal-d2c">
    <div class="modal-header">
      <div class="modal-title"><i class="fa-solid fa-plus-circle text-orange me-2"></i>New Project</div>
      <button class="btn-icon" data-close-modal="modalNewProject"><i class="fa-solid fa-xmark"></i></button>
    </div>
    <div class="form-group mb-3">
      <label class="form-label-d2c">Project Name</label>
      <input type="text" class="field-d2c input-d2c" id="newProjectTitle" placeholder="ThreadVision FW27...">
    </div>
    <div class="form-group mb-3">
      <label class="form-label-d2c">Brief Description</label>
      <textarea class="field-d2c textarea-d2c" id="newProjectDesc" rows="3"
        placeholder="Describe the concept and target garments..."></textarea>
    </div>
    <div class="form-group">
      <label class="form-label-d2c">Base Garment Type</label>
      <select class="field-d2c select-d2c" id="newProjectType">
        <option value="oversized_tee">Oversized Tee</option>
        <option value="hoodie">Hoodie</option>
        <option value="jacket">Jacket</option>
        <option value="dress">Dress</option>
      </select>
    </div>
    <div class="modal-footer">
      <button class="btn-d2c btn-ghost btn-d2c--sm" data-close-modal="modalNewProject">Cancel</button>
      <button class="btn-d2c btn-orange btn-d2c--sm" id="btnCreateProject">
        <i class="fa-solid fa-plus"></i> Create Project
      </button>
    </div>
  </div>
</div>

<!-- Projects List Modal -->
<div class="modal-overlay" id="modalProjectsList">
  <div class="modal-d2c" style="max-width:680px;">
    <div class="modal-header">
      <div class="modal-title"><i class="fa-solid fa-list text-purple me-2"></i>Projects</div>
      <button class="btn-icon" data-close-modal="modalProjectsList"><i class="fa-solid fa-xmark"></i></button>
    </div>
    <div id="projectsListContent">
      <div class="empty-hint"><i class="fa-solid fa-folder-open"></i><span>No projects yet</span></div>
    </div>
    <div class="modal-footer">
      <button class="btn-d2c btn-orange btn-d2c--sm" id="btnNewFromList">
        <i class="fa-solid fa-plus"></i> New Project
      </button>
    </div>
  </div>
</div>

<!-- Toast container -->
<div class="toast-container" id="toastContainer"></div>

<!-- ═══════════════════════════════════════════════════════
     SCRIPTS
═══════════════════════════════════════════════════════ -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
  // Pass PHP constants to JS
  window.D2C = {
    basePath:   '<?= APP_BASE_PATH ?>',
    baseUrl:    '<?= APP_BASE_URL ?>',
    debug:      <?= DEBUG_MODE ? 'true' : 'false' ?>,
    sessionId:  '<?= session_id() ?>'
  };
</script>
<script src="<?= APP_BASE_PATH ?>/js/app.js?v=<?= time() ?>"></script>

</body>
</html>