Files
hersel.it/templates/admin/skills.html
Claude 425e66a473 Add edit modals and image upload for admin dashboard
User Interface Improvements:
- Added edit modal for skills with activate/deactivate checkbox
- Added edit modal for social links with activate/deactivate checkbox
- Skills and social links now default to "active" when created
- Better UX with inline editing instead of separate pages

Image Upload Feature:
- Implemented file upload for project images
- Support for png, jpg, jpeg, gif, webp (max 16 MB)
- Automatic filename sanitization and timestamp prefixing
- Preview of current image in edit mode
- Option to upload file OR enter manual URL
- Files saved to static/img/ directory

Modified Files:
- app.py: Added upload configuration (MAX_CONTENT_LENGTH, UPLOAD_FOLDER, ALLOWED_EXTENSIONS)
- routes/admin.py: Added save_uploaded_file() helper and file handling in project routes
- templates/admin/skills.html: Added edit modal with is_active checkbox
- templates/admin/social_links.html: Added edit modal with is_active checkbox
- templates/admin/project_form.html: Added file upload input with preview

Benefits:
- No more "inactive" items when creating new entries
- Easy toggle of active/inactive state
- Professional image upload with validation
- Better user experience overall
2025-11-13 15:29:10 +00:00

133 lines
6.8 KiB
HTML

{% extends "admin/base.html" %}
{% block title %}Gestione Competenze{% endblock %}
{% block page_title %}Gestione Competenze{% endblock %}
{% block content %}
<div class="card mb-4">
<div class="card-header bg-white">
<h5 class="mb-0">Aggiungi Nuova Competenza</h5>
</div>
<div class="card-body">
<form method="POST" action="{{ url_for('admin.skill_add') }}" class="row g-3">
<div class="col-md-3">
<input type="text" class="form-control" name="name" placeholder="Nome (es. Python)" required>
</div>
<div class="col-md-3">
<input type="text" class="form-control" name="icon_class" placeholder="Icona (es. fab fa-python)" required>
</div>
<div class="col-md-2">
<input type="text" class="form-control" name="category" placeholder="Categoria">
</div>
<div class="col-md-1">
<input type="number" class="form-control" name="display_order" placeholder="Ordine" value="0">
</div>
<div class="col-md-1">
<div class="form-check mt-2">
<input type="checkbox" class="form-check-input" name="is_active" id="is_active_new" checked>
<label class="form-check-label" for="is_active_new">
Attiva
</label>
</div>
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-gradient w-100">
<i class="fas fa-plus me-2"></i>Aggiungi
</button>
</div>
</form>
</div>
</div>
<div class="card">
<div class="card-header bg-white">
<h5 class="mb-0">Lista Competenze</h5>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Icona</th>
<th>Nome</th>
<th>Categoria</th>
<th>Ordine</th>
<th>Stato</th>
<th>Azioni</th>
</tr>
</thead>
<tbody>
{% for skill in skills %}
<tr>
<td><i class="{{ skill.icon_class }} fa-2x text-primary"></i></td>
<td>{{ skill.name }}</td>
<td><span class="badge bg-secondary">{{ skill.category or '-' }}</span></td>
<td>{{ skill.display_order }}</td>
<td>
{% if skill.is_active %}
<span class="badge bg-success">Attiva</span>
{% else %}
<span class="badge bg-danger">Disattiva</span>
{% endif %}
</td>
<td>
<button type="button" class="btn btn-sm btn-outline-primary me-1" data-bs-toggle="modal" data-bs-target="#editModal{{ skill.id }}">
<i class="fas fa-edit"></i>
</button>
<form method="POST" action="{{ url_for('admin.skill_delete', skill_id=skill.id) }}" class="d-inline">
<button type="submit" class="btn btn-sm btn-outline-danger" onclick="return confirm('Sicuro di voler eliminare?')">
<i class="fas fa-trash"></i>
</button>
</form>
</td>
</tr>
<!-- Edit Modal -->
<div class="modal fade" id="editModal{{ skill.id }}" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modifica Competenza</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form method="POST" action="{{ url_for('admin.skill_edit', skill_id=skill.id) }}">
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Nome</label>
<input type="text" class="form-control" name="name" value="{{ skill.name }}" required>
</div>
<div class="mb-3">
<label class="form-label">Icona (Font Awesome class)</label>
<input type="text" class="form-control" name="icon_class" value="{{ skill.icon_class }}" required>
</div>
<div class="mb-3">
<label class="form-label">Categoria</label>
<input type="text" class="form-control" name="category" value="{{ skill.category or '' }}">
</div>
<div class="mb-3">
<label class="form-label">Ordine di Visualizzazione</label>
<input type="number" class="form-control" name="display_order" value="{{ skill.display_order }}">
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" name="is_active" id="is_active_{{ skill.id }}" {% if skill.is_active %}checked{% endif %}>
<label class="form-check-label" for="is_active_{{ skill.id }}">
Competenza Attiva
</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annulla</button>
<button type="submit" class="btn btn-gradient">Salva Modifiche</button>
</div>
</form>
</div>
</div>
</div>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}