🔒 Repository is read-only – file editing is disabled.

PaganLinux/pagan-web-v2/templates/repo/package.html main

182 linii Raw ← Powrót
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
{% extends "base.html" %}{% block title %}{{ name }} {{ version }} – PaganOS{% endblock %}
{% block og_title %}{{ name }} {{ version }} – PaganOS{% endblock %}
{% block og_description %}{{ meta.get('description','')[:150] if meta.get('description') else name ~ ' ' ~ version ~ ' – pakiet w repozytorium PaganOS' }}{% endblock %}
{% block head %}
<style>
/* Package v2 */
.pk-wrap{display:grid;grid-template-columns:minmax(0,1fr) 330px;gap:1.25rem;align-items:start}
@media(max-width:980px){.pk-wrap{grid-template-columns:1fr}}
.pk-card{padding:0;overflow:hidden}
.pk-head{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;flex-wrap:wrap;padding:1.4rem 1.5rem 1rem}
.pk-title{font-size:1.8rem;font-weight:800;color:var(--text-bright);letter-spacing:-0.02em;margin:0;word-break:break-word}
.pk-title.v{color:var(--muted);font-weight:600;font-size:1.15rem}
.pk-meta{display:flex;flex-wrap:wrap;gap:0.4rem;align-items:center;padding:0 1.5rem 1rem}
.pk-desc{padding:0 1.5rem 1.2rem;color:var(--muted);font-size:0.95rem;line-height:1.6;border-bottom:1px solid var(--border)}
.pk-sec{padding:1.1rem 1.5rem;border-top:1px solid var(--border)}
.pk-sec h3{font-size:0.78rem;text-transform:uppercase;letter-spacing:0.07em;color:var(--muted);margin:0 0 0.7rem;display:flex;justify-content:space-between;align-items:center}
.pk-sec h3 span{color:var(--muted);font-weight:600}
.chips{display:flex;flex-wrap:wrap;gap:0.4rem}
.dchip{font-family:var(--mono);font-size:0.76rem;background:var(--bg2);border:1px solid var(--border);padding:0.2rem 0.55rem;border-radius:var(--radius-xs);color:var(--text)}
.dchip:hover{border-color:var(--accent);color:var(--accent)}
.pk-side{display:flex;flex-direction:column;gap:1rem}
.act-card{padding:1.2rem}
.install-box{display:flex;gap:0.4rem;align-items:center}
.install-box code{flex:1;font-family:var(--mono);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);padding:0.5rem 0.7rem;font-size:0.84rem;color:var(--accent);overflow-x:auto;white-space:nowrap}
.act-grid{display:flex;flex-direction:column;gap:0.5rem}
.act-grid.btn{width:100%;text-align:center;justify-content:center}
.watch-btn{width:100%}
.meta-line{display:flex;justify-content:space-between;gap:0.75rem;padding:0.35rem 0;font-size:0.84rem;border-bottom:1px dashed rgba(255,255,255,0.04)}
.meta-line.k{color:var(--muted);white-space:nowrap}
.meta-line.vv{text-align:right;word-break:break-word;font-family:var(--mono);font-size:0.78rem;color:var(--text)}
.hist-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:0.6rem}
.hist-item{background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius-sm);padding:0.7rem 0.85rem;display:flex;flex-direction:column;gap:0.3rem;transition:var(--transition)}
.hist-item:hover{border-color:var(--border-light)}
.hist-item.current{border-color:rgba(63,185,80,0.5)}
.hist-item.hv{font-weight:700;font-family:var(--mono);font-size:0.85rem;color:var(--text-bright)}
.hist-item.hs{font-size:0.72rem;color:var(--muted)}
.hist-item.act{margin-top:0.2rem}
.hashline{font-family:var(--mono);font-size:0.72rem;color:var(--muted);word-break:break-all;line-height:1.6}
</style>
{% endblock %}
{% block content %}
<div class="pk-wrap">

 <!-- ── Lewa kolumna: opis + sekcje ── -->
 <div>
 <div class="card pk-card">
 <div class="pk-head">
 <div style="min-width:0">
 <a href="/repo" style="font-size:0.8rem;color:var(--muted)">← {{ t('repo') }}</a>
 <h1 class="pk-title"> {{ name }} <span class="v">{{ version }}</span></h1>
 </div>
 <a class="btn btn-primary btn-lg" href="/repo/download/{{ category }}/{{ filename }}" style="white-space:nowrap">
 ⬇ Download <span style="opacity:0.8;font-weight:600;font-size:0.8rem">({{ size_mb }} MB)</span>
 </a>
 </div>
 <div class="pk-meta">
 <span class="chip">{{ category }}</span>
 <span class="chip">x86_64</span>
 {% if meta.get('license') and meta.license!= 'unknown' %}<span class="chip">{{ meta.license }}</span>{% endif %}
 {% if meta.get('build_date') %}<span class="chip chip-info" style="color:var(--muted)"> {{ meta.build_date }}</span>{% endif %}
 </div>
 {% if meta.get('description') %}
 <div class="pk-desc">{{ meta.description }}</div>
 {% endif %}

 {% if deps %}
 <div class="pk-sec">
 <h3>Zależności runtime <span>({{ deps|length }})</span></h3>
 <div class="chips">{% for d in deps %}<a class="dchip" href="/repo?q={{ d|urlencode }}" title="Zobacz w repo">{{ d }}</a>{% endfor %}</div>
 </div>
 {% endif %}

 {% if builddeps %}
 <div class="pk-sec">
 <h3>Zależności buildowe <span>({{ builddeps|length }})</span></h3>
 <div class="chips">{% for d in builddeps %}<a class="dchip" href="/repo?q={{ d|urlencode }}" title="Zobacz w repo">{{ d }}</a>{% endfor %}</div>
 </div>
 {% endif %}

 {% if history and history|length > 1 %}
 <div class="pk-sec">
 <h3>Historia wersji <span>({{ history|length }})</span></h3>
 <div class="hist-grid">
 {% for item in history %}
 <div class="hist-item {% if item.current %}current{% endif %}">
 <span class="hv">{{ item.version }}</span>
 <span class="hs">{{ item.size_mb }} MB{% if item.current %} · aktualna{% endif %}</span>
 {% if not item.current %}
 <a class="btn btn-sm btn-ghost act" href="/repo/package/{{ category }}/{{ item.filename }}">Zobacz</a>
 {% endif %}
 </div>
 {% endfor %}
 </div>
 </div>
 {% endif %}

 {% if meta.get('sha256') %}
 <div class="pk-sec">
 <h3>Weryfikacja</h3>
 <div class="hashline">
 <strong style="color:var(--muted)">SHA256:</strong> {{ meta.sha256 }}
 {% if meta.get('gpg_fingerprint') %}<br><strong style="color:var(--muted)">GPG:</strong> {{ meta.gpg_fingerprint }}{% endif %}
 {% if meta.get('built_by') %}<br><strong style="color:var(--muted)">Built by:</strong> {{ meta.built_by }}{% endif %}
 </div>
 </div>
 {% endif %}
 </div>
 </div>

 <!-- ── Prawa kolumna: akcje ── -->
 <div class="pk-side">
 <div class="card act-card">
 <h3 style="font-size:0.78rem;text-transform:uppercase;letter-spacing:0.07em;color:var(--muted);margin:0 0 0.6rem">Instalacja</h3>
 <div class="install-box">
 <code id="install-cmd">pag install {{ name }}</code>
 <button type="button" class="btn btn-sm" onclick="copyInstall()" style="white-space:nowrap">Kopiuj</button>
 </div>
 <script>
 function copyInstall() {
   var txt = document.getElementById('install-cmd').textContent.trim();
   (navigator.clipboard ? navigator.clipboard.writeText(txt) : Promise.reject())
     .then(function(){ var b=event.target; b.textContent='Skopiowano'; setTimeout(function(){ b.textContent='Kopiuj'; },1500); })
     .catch(function(){ window.prompt('Skopiuj ręcznie:', txt); });
 }
 </script>
 <p style="font-size:0.72rem;color:var(--muted);margin:0.5rem 0 0;line-height:1.5">
 Pakiet jest podpisany GPG — klient <code style="font-family:var(--mono)">pag</code> zweryfikuje podpis przed instalacją.
 </p>
 </div>

 <div class="card act-card">
 <div class="act-grid">
 {% if username %}
 <form method="POST" action="{{ '/repo/api/unwatch' if watching else '/repo/api/watch' }}" onsubmit="return submitWatch(this)" style="margin:0">
 <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
 <input type="hidden" name="name" value="{{ name }}">
 <button class="btn btn-ghost watch-btn" id="watch-btn" style="width:100%">
 {% if watching %} {{ t('watching_pkg') }}{% else %} {{ t('watch_pkg') }}{% endif %}
 </button>
 </form>
 <script>
 function submitWatch(f) {
 var btn = f.querySelector('button');
 fetch(f.getAttribute('action'), {method:'POST', body:new FormData(f)})
 .then(function(r){return r.json();})
 .then(function(d){
 f.setAttribute('action', d.watching? '/repo/api/unwatch' : '/repo/api/watch');
 btn.textContent = d.watching ? 'Obserwujesz (nowe wersje → e-mail)' : 'Obserwuj pakiet';
 });
 return false;
 }
 </script>
 {% endif %}
 {% if homepage %}
 <a class="btn btn-ghost" href="{{ homepage }}" target="_blank" rel="noopener"> Strona projektu</a>
 {% endif %}
 {% if recipe_path %}
 <a class="btn btn-ghost" href="https://git.paganlinux.eu/recipes/file?path={{ recipe_path }}" target="_blank" rel="noopener" title="PAGBUILD.yaml w git"> Receptura (PAGBUILD.yaml)</a>
 {% else %}
 <a class="btn btn-ghost" href="https://git.paganlinux.eu/search?q={{ name }}" target="_blank" rel="noopener"> Szukaj w kodzie</a>
 {% endif %}
 <a class="btn btn-ghost" href="/repo?cat={{ category }}"> Wróć do {{ category }}</a>
 {% if is_admin %}
 <form method="POST" action="/repo/api/delete-package" onsubmit="return confirm('Usunąć {{ filename }}?')" style="margin:0">
 <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
 <input type="hidden" name="category" value="{{ category }}">
 <input type="hidden" name="filename" value="{{ filename }}">
 <button class="btn btn-danger" style="width:100%"> Usuń pakiet</button>
 </form>
 {% endif %}
 </div>
 </div>

 <div class="card act-card" style="padding:0.9rem 1.2rem">
 <div class="meta-line"><span class="k">Kategoria</span><span class="vv">{{ category }}</span></div>
 <div class="meta-line"><span class="k">Architektura</span><span class="vv">x86_64</span></div>
 <div class="meta-line"><span class="k">Rozmiar</span><span class="vv">{{ size_mb }} MB</span></div>
 <div class="meta-line"><span class="k">Plik</span><span class="vv">{{ filename }}</span></div>
 </div>
 </div>
</div>
{% endblock %}