temporal upload. parcial Phase 2 implementation
This commit is contained in:
@@ -27,11 +27,11 @@
|
||||
<label for="{{ project_form.category.id_for_label }}">Category</label>
|
||||
{{ project_form.category }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group" id="description-group">
|
||||
{{ project_form.description.errors }}
|
||||
<label for="{{ project_form.description.id_for_label }}">Description</label>
|
||||
{{ project_form.description }}
|
||||
<p class="bio-help"><i class="fas fa-info-circle"></i> Supports Markdown — headings, lists, links, code, tables and more.</p>
|
||||
<p class="bio-help"><i class="fas fa-info-circle"></i> Supports Markdown — headings, lists, links, code, tables and more. Guides don't use this field.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -116,4 +116,14 @@
|
||||
<script src="{% static 'js/tags.js' %}"></script>
|
||||
<script src="{% static 'js/uploads.js' %}"></script>
|
||||
<script src="{% static 'js/create.js' %}"></script>
|
||||
<script>
|
||||
(function () {
|
||||
const cat = document.getElementById('id_category');
|
||||
const group = document.getElementById('description-group');
|
||||
if (!cat || !group) return;
|
||||
function toggle() { group.style.display = cat.value === 'guide' ? 'none' : ''; }
|
||||
cat.addEventListener('change', toggle);
|
||||
toggle();
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -60,14 +60,33 @@
|
||||
{% endif %}
|
||||
|
||||
<div class="tab-bar" role="tablist">
|
||||
<button class="tab-btn active" data-tab="description" role="tab">Description</button>
|
||||
<button class="tab-btn active" data-tab="{% if project.category == 'guide' %}guide{% else %}description{% endif %}" role="tab">
|
||||
{% if project.category == 'guide' %}Guide{% else %}Description{% endif %}
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="versions" role="tab">Versions</button>
|
||||
{% if project.category == 'modpack' %}<button class="tab-btn" data-tab="mods" role="tab">Mods</button>{% endif %}
|
||||
<button class="tab-btn" data-tab="gallery" role="tab">Gallery</button>
|
||||
</div>
|
||||
|
||||
<section class="tab-panel active" id="tab-description">
|
||||
<section class="tab-panel active" id="tab-{% if project.category == 'guide' %}guide{% else %}description{% endif %}">
|
||||
<div class="card">
|
||||
{% if project.description %}
|
||||
{% if project.category == 'guide' %}
|
||||
<div class="guide-docs">
|
||||
{% if guide_docs %}
|
||||
<div class="guide-switcher" role="tablist">
|
||||
{% for doc in guide_docs %}
|
||||
<button type="button" class="guide-switch-btn{% if forloop.first %} active{% endif %}"
|
||||
data-url="{% url 'library:guide_doc' project.slug doc.version.pk doc.file.uuid %}">{{ doc.filename }}</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="markdown-body guide-content" id="guide-content">
|
||||
<p class="empty-hint">Loading…</p>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="empty-hint">No guide documents uploaded yet.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% elif project.description %}
|
||||
<div class="markdown-body project-description">{{ project.description|markdown }}</div>
|
||||
{% else %}
|
||||
<p class="empty-hint">No description yet.</p>
|
||||
@@ -84,10 +103,14 @@
|
||||
<div class="version-name-row">
|
||||
<strong class="version-name">{{ version.version_name }}</strong>
|
||||
{% if forloop.first %}<span class="latest-badge">latest</span>{% endif %}
|
||||
{% if version.pack_format %}<span class="pack-format-badge">pack format {{ version.pack_format }}</span>{% endif %}
|
||||
</div>
|
||||
<span class="version-date"><i class="fas fa-clock"></i> {{ version.created_at|date:"M j, Y" }}</span>
|
||||
<span class="version-downloads"><i class="fas fa-download"></i> {{ version.downloads }}</span>
|
||||
</div>
|
||||
{% if version.pack_description %}
|
||||
<p class="pack-description"><i class="fas fa-info-circle"></i> {{ version.pack_description }}</p>
|
||||
{% endif %}
|
||||
{% if version.changelog %}
|
||||
<div class="markdown-body version-changelog">{{ version.changelog|markdown }}</div>
|
||||
{% endif %}
|
||||
@@ -96,6 +119,8 @@
|
||||
<div class="version-file">
|
||||
{% if vf.is_png %}
|
||||
<img class="version-file-thumb" src="{% url 'library:file_request' vf.file.uuid %}" alt="{{ vf.filename }}">
|
||||
{% elif vf.is_markdown %}
|
||||
<i class="fas fa-file-lines version-file-icon"></i>
|
||||
{% else %}
|
||||
<i class="fas fa-file-archive version-file-icon"></i>
|
||||
{% endif %}
|
||||
@@ -113,6 +138,28 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% if project.category == 'modpack' %}
|
||||
<section class="tab-panel" id="tab-mods">
|
||||
<div class="card">
|
||||
<h2><i class="fas fa-cubes"></i> Mods</h2>
|
||||
{% for version in versions %}
|
||||
{% if version.mods_manifest.files %}
|
||||
<div class="mods-version">
|
||||
<h3>{{ version.version_name }} <span class="mods-source-badge">{{ version.mods_manifest.source }}</span></h3>
|
||||
<ul class="mods-list">
|
||||
{% for mod in version.mods_manifest.files %}
|
||||
<li><i class="fas fa-cube"></i> {{ mod.name }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<p class="empty-hint">No mods detected in the uploaded packs.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
<section class="tab-panel" id="tab-gallery">
|
||||
<div class="card">
|
||||
<h2><i class="fas fa-images"></i> Gallery</h2>
|
||||
@@ -172,6 +219,28 @@
|
||||
xhr.send();
|
||||
});
|
||||
});
|
||||
|
||||
// Guide document file-switcher (fetches + renders the selected .md).
|
||||
const guideContent = document.getElementById('guide-content');
|
||||
if (guideContent) {
|
||||
const guideBtns = document.querySelectorAll('.guide-switch-btn');
|
||||
function loadGuide(url) {
|
||||
guideContent.innerHTML = '<p class="empty-hint">Loading…</p>';
|
||||
fetch(url, { headers: { 'Accept': 'text/html' } })
|
||||
.then(r => { if (!r.ok) throw new Error('http'); return r.text(); })
|
||||
.then(html => { guideContent.innerHTML = html; })
|
||||
.catch(() => { guideContent.innerHTML = '<p class="empty-hint">Could not load this document.</p>'; });
|
||||
}
|
||||
guideBtns.forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
guideBtns.forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
loadGuide(btn.dataset.url);
|
||||
});
|
||||
});
|
||||
const first = guideBtns[0];
|
||||
if (first) loadGuide(first.dataset.url);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -29,11 +29,11 @@
|
||||
<label for="{{ project_form.category.id_for_label }}">Category</label>
|
||||
{{ project_form.category }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group" id="description-group">
|
||||
{{ project_form.description.errors }}
|
||||
<label for="{{ project_form.description.id_for_label }}">Description</label>
|
||||
{{ project_form.description }}
|
||||
<p class="bio-help"><i class="fas fa-info-circle"></i> Supports Markdown — headings, lists, links, code, tables and more.</p>
|
||||
<p class="bio-help"><i class="fas fa-info-circle"></i> Supports Markdown — headings, lists, links, code, tables and more. Guides don't use this field.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -74,4 +74,14 @@
|
||||
<script src="{% static 'js/tags.js' %}"></script>
|
||||
<script src="{% static 'js/uploads.js' %}"></script>
|
||||
<script src="{% static 'js/edit.js' %}"></script>
|
||||
<script>
|
||||
(function () {
|
||||
const cat = document.getElementById('id_category');
|
||||
const group = document.getElementById('description-group');
|
||||
if (!cat || !group) return;
|
||||
function toggle() { group.style.display = cat.value === 'guide' ? 'none' : ''; }
|
||||
cat.addEventListener('change', toggle);
|
||||
toggle();
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user