projectbased/app/Views/projects/view.php

SHA-256: 3e7dcf776e76052790064957d62cf0bf84f871381e8949859d4e8e213a1c323f
<?php
use App\Lib\Url;
use App\Lib\ProjectPhases;

$phase = (string)($project['phase'] ?? 'idea');
$phaseLabel = ProjectPhases::label($phase);
$progress = ProjectPhases::progress($phase);

function roleLabel(string $r): string {
  return match($r) {
    'initiator' => 'Initiator',
    'coordinator' => 'Koordinator',
    'member' => 'Mitwirkend',
    'observer' => 'Beobachter',
    default => $r
  };
}

$coordinator = null;
$initiator = null;
foreach(($roles ?? []) as $r){
  if(($r['role'] ?? '')==='coordinator' && (int)($r['active'] ?? 1)===1 && !$coordinator) $coordinator=$r;
  if(($r['role'] ?? '')==='initiator' && (int)($r['active'] ?? 1)===1 && !$initiator) $initiator=$r;
}
?>
<div class="d-flex flex-wrap justify-content-between align-items-start gap-2 mb-3">
  <div>
    <h1 class="h4 mb-1"><?= htmlspecialchars($project['title'] ?? '') ?></h1>
    <div class="muted">
      Kategorie: <span class="chip"><?= htmlspecialchars($project['category'] ?? 'general') ?></span>
      · Region: <span class="chip"><?= htmlspecialchars($project['region'] ?? '') ?></span>
      · Owner: <span class="chip"><?= htmlspecialchars($project['owner_name'] ?? '') ?></span>
    </div>
  </div>
  <div class="d-flex gap-2">
    <a class="btn btn-outline-light btn-sm" href="<?= Url::route('projects') ?>">← Zur Liste</a>
  </div>
</div>

<div class="row g-3">
  <div class="col-12 col-lg-7">
    <div class="card p-4 mb-3">
      <div class="d-flex justify-content-between align-items-center flex-wrap gap-2">
        <div class="d-flex align-items-center gap-2">
          <span class="badge badge-soft">Phase: <?= htmlspecialchars($phaseLabel) ?></span>
          <span class="badge badge-soft">Score: <?= (int)$score ?></span>
        </div>
        <?php if (!empty($canManage)): ?>
          <button class="btn btn-primary btn-sm" data-bs-toggle="collapse" data-bs-target="#phasePanel">Phase ändern</button>
        <?php endif; ?>
      </div>

      <div class="mt-3">
        <div class="muted small mb-1">Fortschritt (Demo-Indikator)</div>
        <div class="progress" style="height:10px;">
          <div class="progress-bar" role="progressbar" style="width: <?= (int)$progress ?>%"></div>
        </div>
      </div>

      <?php if (!empty($project['description'])): ?>
        <div class="mt-3"><?= nl2br(htmlspecialchars($project['description'])) ?></div>
      <?php else: ?>
        <div class="mt-3 muted">Keine Beschreibung hinterlegt.</div>
      <?php endif; ?>

      <?php if (!empty($canManage)): ?>
      <div class="collapse mt-3" id="phasePanel">
        <div class="card p-3">
          <form method="post" action="<?= Url::route('project_phase') ?>" class="row g-2">
            <input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf) ?>">
            <input type="hidden" name="project_id" value="<?= (int)$project['id'] ?>">
            <div class="col-12 col-md-4">
              <label class="form-label">Neue Phase</label>
              <select class="form-select" name="phase">
                <?php foreach(($phases ?? []) as $ph): ?>
                  <option value="<?= htmlspecialchars($ph) ?>" <?= $ph===$phase?'selected':'' ?>><?= htmlspecialchars(ProjectPhases::label($ph)) ?></option>
                <?php endforeach; ?>
              </select>
            </div>
            <div class="col-12 col-md-8">
              <label class="form-label">Begründung (optional)</label>
              <input class="form-control" name="reason" placeholder="z. B. Planung abgeschlossen, Umsetzung startet…">
            </div>
            <div class="col-12">
              <button class="btn btn-primary btn-sm" type="submit">Speichern</button>
            </div>
          </form>
        </div>
      </div>
      <?php endif; ?>
    </div>

    <div class="card p-4 mb-3">
      <h2 class="h6 mb-3">Meilensteine</h2>

      <?php if (empty($milestones)): ?>
        <div class="muted">Noch keine Meilensteine. (v9 macht Projekte planbar.)</div>
      <?php else: ?>
        <div class="table-responsive">
          <table class="table table-sm align-middle mb-0">
            <thead><tr><th>Titel</th><th>Status</th><th style="width:160px;"></th></tr></thead>
            <tbody>
              <?php foreach($milestones as $m): ?>
                <tr>
                  <td>
                    <div class="fw-semibold"><?= htmlspecialchars($m['title'] ?? '') ?></div>
                    <?php if (!empty($m['description'])): ?>
                      <div class="muted small"><?= htmlspecialchars($m['description']) ?></div>
                    <?php endif; ?>
                  </td>
                  <td><span class="badge badge-soft"><?= htmlspecialchars($m['status'] ?? 'open') ?></span></td>
                  <td class="text-end">
                    <?php if (!empty($canManage)): ?>
                      <form method="post" action="<?= Url::route('project_milestone_status') ?>" class="d-inline">
                        <input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf) ?>">
                        <input type="hidden" name="milestone_id" value="<?= (int)$m['id'] ?>">
                        <input type="hidden" name="status" value="active">
                        <button class="btn btn-outline-light btn-sm" type="submit">Aktiv</button>
                      </form>
                      <form method="post" action="<?= Url::route('project_milestone_status') ?>" class="d-inline">
                        <input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf) ?>">
                        <input type="hidden" name="milestone_id" value="<?= (int)$m['id'] ?>">
                        <input type="hidden" name="status" value="done">
                        <button class="btn btn-outline-light btn-sm" type="submit">Erledigt</button>
                      </form>
                    <?php endif; ?>
                  </td>
                </tr>
              <?php endforeach; ?>
            </tbody>
          </table>
        </div>
      <?php endif; ?>

      <?php if (!empty($canManage)): ?>
        <div class="mt-3">
          <div class="muted small mb-2">Neuen Meilenstein anlegen</div>
          <form method="post" action="<?= Url::route('project_milestone_add') ?>" class="row g-2">
            <input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf) ?>">
            <input type="hidden" name="project_id" value="<?= (int)$project['id'] ?>">
            <div class="col-12 col-md-5"><input class="form-control" name="title" placeholder="Titel" required></div>
            <div class="col-12 col-md-5"><input class="form-control" name="description" placeholder="Kurzbeschreibung (optional)"></div>
            <div class="col-6 col-md-1"><input class="form-control" name="order_index" type="number" value="0"></div>
            <div class="col-6 col-md-1"><button class="btn btn-primary w-100" type="submit">+</button></div>
          </form>
        </div>
      <?php endif; ?>
    </div>

    <div class="card p-4">
      <h2 class="h6 mb-3">Abstimmung & Veto</h2>

      <div class="d-flex gap-2 flex-wrap align-items-center mb-3">
        <form method="post" action="<?= Url::route('project_vote') ?>" class="d-inline">
          <input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf) ?>">
          <input type="hidden" name="project_id" value="<?= (int)$project['id'] ?>">
          <input type="hidden" name="value" value="1">
          <button class="btn btn-outline-light btn-sm" type="submit">👍 Unterstützen</button>
        </form>
        <form method="post" action="<?= Url::route('project_vote') ?>" class="d-inline">
          <input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf) ?>">
          <input type="hidden" name="project_id" value="<?= (int)$project['id'] ?>">
          <input type="hidden" name="value" value="-1">
          <button class="btn btn-outline-light btn-sm" type="submit">👎 Ablehnen</button>
        </form>

        <span class="muted small">Gesamt-Score: <b><?= (int)$score ?></b></span>
      </div>

      <form method="post" action="<?= Url::route('project_veto') ?>" class="row g-2">
        <input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf) ?>">
        <input type="hidden" name="project_id" value="<?= (int)$project['id'] ?>">
        <div class="col-12">
          <label class="form-label">Veto (Begründung, min. 10 Zeichen)</label>
          <textarea class="form-control" name="reason" rows="2" placeholder="Warum sollte dieses Projekt so nicht gestartet werden? (konkret)"></textarea>
        </div>
        <div class="col-12">
          <button class="btn btn-primary btn-sm" type="submit">Veto einreichen</button>
        </div>
      </form>

      <?php if (!empty($vetoes)): ?>
        <hr class="my-3">
        <div class="muted small mb-2">Letzte Vetos</div>
        <?php foreach($vetoes as $v): ?>
          <div class="card p-3 mb-2">
            <div class="d-flex justify-content-between flex-wrap gap-2">
              <div class="fw-semibold"><?= htmlspecialchars($v['display_name'] ?? '') ?></div>
              <div class="muted small"><?= htmlspecialchars($v['created_at'] ?? '') ?></div>
            </div>
            <div class="mt-2"><?= nl2br(htmlspecialchars($v['reason'] ?? '')) ?></div>
          </div>
        <?php endforeach; ?>
      <?php endif; ?>
    </div>
  </div>

  <div class="col-12 col-lg-5">
    <div class="card p-4 mb-3">
      <h2 class="h6 mb-3">Rollen & Beteiligung</h2>

      <div class="d-flex flex-wrap gap-2 mb-3">
        <span class="badge badge-soft">Initiator: <?= htmlspecialchars($initiator['display_name'] ?? ($project['owner_name'] ?? '')) ?></span>
        <span class="badge badge-soft">Koordinator: <?= htmlspecialchars($coordinator['display_name'] ?? '—') ?></span>
        <?php if (!empty($coordinator['rotation_due_at'])): ?>
          <span class="badge badge-soft">Rotation: <?= htmlspecialchars($coordinator['rotation_due_at']) ?></span>
        <?php endif; ?>
      </div>

      <div class="muted small mb-2">Aktive Rollen</div>
      <div class="table-responsive">
        <table class="table table-sm align-middle mb-0">
          <thead><tr><th>Person</th><th>Rolle</th></tr></thead>
          <tbody>
            <?php foreach(($roles ?? []) as $r): ?>
              <?php if((int)($r['active'] ?? 1) !== 1) continue; ?>
              <tr>
                <td><?= htmlspecialchars($r['display_name'] ?? '') ?></td>
                <td><span class="badge badge-soft"><?= htmlspecialchars(roleLabel((string)($r['role'] ?? ''))) ?></span></td>
              </tr>
            <?php endforeach; ?>
          </tbody>
        </table>
      </div>

      <hr class="my-3">

      <h3 class="h6 mb-2">Beitritt (verbindlich, aber freiwillig)</h3>

      <?php if (!empty($commitment)): ?>
        <div class="card p-3">
          <div class="fw-semibold">Dein Commitment</div>
          <div class="muted small">
            Rolle: <?= htmlspecialchars(roleLabel((string)($commitment['role'] ?? 'member'))) ?>
            · <?= (int)($commitment['hours_per_week'] ?? 0) ?> h/Woche
            · bis <?= htmlspecialchars($commitment['until_date'] ?? '') ?>
          </div>
        </div>
      <?php else: ?>
        <form method="post" action="<?= Url::route('project_commit') ?>" class="row g-2">
          <input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf) ?>">
          <input type="hidden" name="project_id" value="<?= (int)$project['id'] ?>">

          <div class="col-12 col-md-6">
            <label class="form-label">Rolle</label>
            <select class="form-select" name="role">
              <option value="member">Mitwirkend</option>
              <option value="observer">Beobachter</option>
              <option value="coordinator">Koordinator (nur wenn passend)</option>
            </select>
          </div>

          <div class="col-6 col-md-3">
            <label class="form-label">h/Woche</label>
            <input class="form-control" type="number" name="hours_per_week" value="2" min="1" max="40">
          </div>

          <div class="col-6 col-md-3">
            <label class="form-label">Tage</label>
            <input class="form-control" type="number" name="days" value="30" min="7" max="365">
          </div>

          <div class="col-12">
            <button class="btn btn-primary btn-sm" type="submit">Ich trete bei</button>
          </div>
        </form>
      <?php endif; ?>
    </div>

    <div class="card p-4 mb-3">
      <h2 class="h6 mb-3">Mitwirkende</h2>
      <?php if (empty($members)): ?>
        <div class="muted">Noch keine Mitglieder.</div>
      <?php else: ?>
        <div class="table-responsive">
          <table class="table table-sm align-middle mb-0">
            <thead><tr><th>Name</th><th>R</th><th>Seit</th></tr></thead>
            <tbody>
              <?php foreach($members as $m): ?>
                <tr>
                  <td><?= htmlspecialchars($m['display_name'] ?? '') ?></td>
                  <td><span class="badge badge-soft"><?= (int)($m['r_index'] ?? 0) ?></span></td>
                  <td class="muted small"><?= htmlspecialchars($m['joined_at'] ?? '') ?></td>
                </tr>
              <?php endforeach; ?>
            </tbody>
          </table>
        </div>
      <?php endif; ?>
    </div>

    
    <div class="card p-4 mb-3">
      <h2 class="h6 mb-3">Gesuchte Skills</h2>

      <?php if (empty($skillNeeds)): ?>
        <div class="muted">Noch keine Skill-Bedarfe definiert. (v11 Matching wird besser, wenn du hier Skills einträgst.)</div>
      <?php else: ?>
        <div class="table-responsive">
          <table class="table table-sm align-middle mb-0">
            <thead><tr><th>Skill</th><th>Benötigt</th><th>Prio</th><th style="width:70px;"></th></tr></thead>
            <tbody>
              <?php foreach($skillNeeds as $sn): ?>
                <tr>
                  <td><?= htmlspecialchars($sn['name'] ?? '') ?></td>
                  <td><span class="badge badge-soft"><?= (int)($sn['needed_count'] ?? 1) ?></span></td>
                  <td><span class="badge badge-soft"><?= (int)($sn['priority'] ?? 3) ?></span></td>
                  <td class="text-end">
                    <?php if (!empty($canManage)): ?>
                      <form method="post" action="<?= \App\Lib\Url::route('project_skill_need_remove') ?>" class="d-inline">
                        <input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf) ?>">
                        <input type="hidden" name="project_id" value="<?= (int)$project['id'] ?>">
                        <input type="hidden" name="id" value="<?= (int)$sn['id'] ?>">
                        <button class="btn btn-outline-light btn-sm" type="submit">×</button>
                      </form>
                    <?php endif; ?>
                  </td>
                </tr>
              <?php endforeach; ?>
            </tbody>
          </table>
        </div>
      <?php endif; ?>

      <?php if (!empty($canManage)): ?>
        <hr class="my-3">
        <div class="muted small mb-2">Skill-Bedarf hinzufügen</div>
        <form method="post" action="<?= \App\Lib\Url::route('project_skill_need_add') ?>" class="row g-2">
          <input type="hidden" name="csrf" value="<?= htmlspecialchars($csrf) ?>">
          <input type="hidden" name="project_id" value="<?= (int)$project['id'] ?>">
          <div class="col-12 col-md-6"><input class="form-control" name="skill" placeholder="z. B. Elektriker, Statik, Pflege" required></div>
          <div class="col-6 col-md-3"><input class="form-control" name="needed_count" type="number" value="1" min="1" max="999"></div>
          <div class="col-6 col-md-3">
            <select class="form-select" name="priority">
              <option value="5">Prio 5</option>
              <option value="4">Prio 4</option>
              <option value="3" selected>Prio 3</option>
              <option value="2">Prio 2</option>
              <option value="1">Prio 1</option>
            </select>
          </div>
          <div class="col-12">
            <button class="btn btn-primary btn-sm" type="submit">Hinzufügen</button>
          </div>
        </form>
      <?php endif; ?>
    </div>

<div class="card p-4">
      <h2 class="h6 mb-3">Phase-Historie</h2>
      <?php if (empty($phaseHistory)): ?>
        <div class="muted">Noch keine Historie.</div>
      <?php else: ?>
        <?php foreach($phaseHistory as $h): ?>
          <div class="card p-3 mb-2">
            <div class="d-flex justify-content-between flex-wrap gap-2">
              <div class="fw-semibold"><?= htmlspecialchars(ProjectPhases::label((string)($h['phase'] ?? ''))) ?></div>
              <div class="muted small"><?= htmlspecialchars($h['changed_at'] ?? '') ?></div>
            </div>
            <div class="muted small">von <?= htmlspecialchars($h['display_name'] ?? '') ?></div>
            <?php if (!empty($h['reason'])): ?>
              <div class="mt-2"><?= nl2br(htmlspecialchars($h['reason'])) ?></div>
            <?php endif; ?>
          </div>
        <?php endforeach; ?>
      <?php endif; ?>
    </div>
  </div>
</div>