2025-05-24 14:35:35 +02:00

246 lines
10 KiB
HTML

{% extends "base.html" %}
{% block title %}{{ image.filename }} - SEREACT Web Client{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">
<i class="fas fa-image"></i> {{ image.filename }}
</h5>
<div class="btn-group" role="group">
<a href="{{ url_for('edit_image', image_id=image.id) }}" class="btn btn-outline-primary btn-sm">
<i class="fas fa-edit"></i> Edit
</a>
<a href="{{ get_api_base_url() }}/api/v1/images/{{ image.id }}/download"
class="btn btn-outline-success btn-sm" target="_blank">
<i class="fas fa-download"></i> Download
</a>
</div>
</div>
<div class="card-body text-center">
<img src="{{ get_api_base_url() }}/api/v1/images/{{ image.id }}/download"
alt="{{ image.filename }}"
class="img-fluid rounded"
style="max-height: 600px;"
onerror="this.src='data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjMwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZjhmOWZhIiBzdHJva2U9IiNkZWUyZTYiLz48dGV4dCB4PSI1MCUiIHk9IjUwJSIgZm9udC1mYW1pbHk9IkFyaWFsIiBmb250LXNpemU9IjE4IiBmaWxsPSIjNmM3NTdkIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBkeT0iLjNlbSI+SW1hZ2UgTm90IEZvdW5kPC90ZXh0Pjwvc3ZnPg=='">
</div>
</div>
</div>
<div class="col-md-4">
<!-- Image Information -->
<div class="card mb-3">
<div class="card-header">
<h6 class="mb-0">
<i class="fas fa-info-circle"></i> Image Information
</h6>
</div>
<div class="card-body">
<dl class="row mb-0">
<dt class="col-sm-5">Filename:</dt>
<dd class="col-sm-7">{{ image.filename }}</dd>
<dt class="col-sm-5">Original:</dt>
<dd class="col-sm-7">{{ image.original_filename }}</dd>
<dt class="col-sm-5">Size:</dt>
<dd class="col-sm-7">{{ (image.file_size / 1024 / 1024) | round(2) }} MB</dd>
<dt class="col-sm-5">Type:</dt>
<dd class="col-sm-7">{{ image.content_type }}</dd>
<dt class="col-sm-5">Uploaded:</dt>
<dd class="col-sm-7">{{ image.upload_date.strftime('%Y-%m-%d %H:%M') if image.upload_date else 'Unknown' }}</dd>
<dt class="col-sm-5">Uploader:</dt>
<dd class="col-sm-7">{{ image.uploader_id }}</dd>
<dt class="col-sm-5">Team:</dt>
<dd class="col-sm-7">{{ image.team_id }}</dd>
{% if image.collection_id %}
<dt class="col-sm-5">Collection:</dt>
<dd class="col-sm-7">{{ image.collection_id }}</dd>
{% endif %}
</dl>
</div>
</div>
<!-- AI Status -->
<div class="card mb-3">
<div class="card-header">
<h6 class="mb-0">
<i class="fas fa-brain"></i> AI Processing Status
</h6>
</div>
<div class="card-body">
{% if image.has_embedding %}
<div class="alert alert-success" role="alert">
<i class="fas fa-check-circle"></i>
<strong>Ready for Search</strong><br>
This image has been processed and is available for AI-powered search.
</div>
{% else %}
<div class="alert alert-warning" role="alert">
<i class="fas fa-clock"></i>
<strong>Processing</strong><br>
AI processing is in progress. The image will be searchable once complete.
</div>
{% endif %}
</div>
</div>
<!-- Description -->
{% if image.description %}
<div class="card mb-3">
<div class="card-header">
<h6 class="mb-0">
<i class="fas fa-align-left"></i> Description
</h6>
</div>
<div class="card-body">
<p class="mb-0">{{ image.description }}</p>
</div>
</div>
{% endif %}
<!-- Tags -->
{% if image.tags %}
<div class="card mb-3">
<div class="card-header">
<h6 class="mb-0">
<i class="fas fa-tags"></i> Tags
</h6>
</div>
<div class="card-body">
{% for tag in image.tags %}
<span class="badge bg-secondary me-1 mb-1">{{ tag }}</span>
{% endfor %}
</div>
</div>
{% endif %}
<!-- Metadata -->
{% if image.metadata %}
<div class="card mb-3">
<div class="card-header">
<h6 class="mb-0">
<i class="fas fa-code"></i> Technical Metadata
</h6>
</div>
<div class="card-body">
<pre class="small text-muted mb-0">{{ image.metadata | tojson(indent=2) }}</pre>
</div>
</div>
{% endif %}
<!-- Actions -->
<div class="card">
<div class="card-header">
<h6 class="mb-0">
<i class="fas fa-tools"></i> Actions
</h6>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="{{ url_for('edit_image', image_id=image.id) }}" class="btn btn-primary">
<i class="fas fa-edit"></i> Edit Image
</a>
<a href="{{ get_api_base_url() }}/api/v1/images/{{ image.id }}/download"
class="btn btn-success" target="_blank">
<i class="fas fa-download"></i> Download Original
</a>
{% if image.has_embedding %}
<button type="button" class="btn btn-info" onclick="findSimilar()">
<i class="fas fa-search-plus"></i> Find Similar Images
</button>
{% endif %}
<button type="button" class="btn btn-outline-danger"
onclick="confirmDelete('{{ image.filename }}', '{{ url_for('delete_image', image_id=image.id) }}')">
<i class="fas fa-trash"></i> Delete Image
</button>
</div>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-12">
<div class="d-flex justify-content-between">
<a href="{{ url_for('images') }}" class="btn btn-secondary">
<i class="fas fa-arrow-left"></i> Back to Images
</a>
<div class="btn-group" role="group">
<a href="{{ url_for('upload_image') }}" class="btn btn-outline-primary">
<i class="fas fa-upload"></i> Upload Another
</a>
<a href="{{ url_for('search') }}" class="btn btn-outline-success">
<i class="fas fa-search"></i> Search Images
</a>
</div>
</div>
</div>
</div>
<!-- Delete Confirmation Modal -->
<div class="modal fade" id="deleteModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="fas fa-exclamation-triangle text-warning"></i> Confirm Delete
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>Are you sure you want to delete the image "<span id="deleteImageName"></span>"?</p>
<div class="alert alert-warning" role="alert">
<i class="fas fa-exclamation-triangle"></i>
<strong>Warning:</strong> This action cannot be undone. The image will be permanently removed from storage.
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<i class="fas fa-times"></i> Cancel
</button>
<form id="deleteForm" method="POST" style="display: inline;">
<button type="submit" class="btn btn-danger">
<i class="fas fa-trash"></i> Delete Image
</button>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
function confirmDelete(imageName, deleteUrl) {
document.getElementById('deleteImageName').textContent = imageName;
document.getElementById('deleteForm').action = deleteUrl;
new bootstrap.Modal(document.getElementById('deleteModal')).show();
}
function findSimilar() {
// Redirect to search with a query to find similar images
const searchUrl = "{{ url_for('search') }}";
const form = document.createElement('form');
form.method = 'POST';
form.action = searchUrl;
const queryInput = document.createElement('input');
queryInput.type = 'hidden';
queryInput.name = 'query';
queryInput.value = 'similar to {{ image.filename }}';
form.appendChild(queryInput);
document.body.appendChild(form);
form.submit();
}
</script>
{% endblock %}