Update edit_post.html to match modern gradient design of new_post.html

- Applied consistent gradient background styling
- Updated form layout to match new_post design
- Modernized UI components with backdrop blur effects
- Enhanced JavaScript functionality for file uploads
- Improved preview modal styling
- Updated button styling to match site theme
This commit is contained in:
ske087
2025-08-09 15:34:40 +03:00
parent 5897ed1cbc
commit f2530a1c5b

View File

@@ -1,201 +1,268 @@
{% extends "base.html" %}
{% block title %}Edit Adventure - {{ post.title }}{% endblock %}
{% block head %}
<style>
.content-section {
border: 2px dashed #d1d5db;
border-radius: 0.75rem;
padding: 1.5rem;
margin-bottom: 1rem;
transition: all 0.3s ease;
background: rgba(255, 255, 255, 0.05);
}
.content-section.editing {
border-color: #3b82f6;
background: rgba(59, 130, 246, 0.1);
}
.content-section.saved {
border-color: #10b981;
border-style: solid;
background: rgba(16, 185, 129, 0.1);
}
.cover-upload-area {
transition: all 0.3s ease;
cursor: pointer;
}
.cover-upload-area:hover {
background: rgba(255, 255, 255, 0.05);
}
/* Dropdown styling */
select option {
background-color: #1f2937;
color: #ffffff;
}
select option:checked {
background-color: #0891b2;
}
/* Section styling */
.section-actions-frame {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.2);
}
</style>
{% endblock %}
{% block content %}
<div class="container-fluid">
<div class="row">
<!-- Form Section -->
<div class="col-lg-8">
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h4 class="mb-0">
<i class="fas fa-edit"></i> Edit Your Adventure
</h4>
</div>
<div class="card-body">
<form id="editPostForm" method="POST" enctype="multipart/form-data" action="{{ url_for('community.edit_post', id=post.id) }}">
<!-- Title -->
<div class="mb-4">
<label for="title" class="form-label fw-bold">
<i class="fas fa-heading text-primary"></i> Adventure Title *
</label>
<input type="text" class="form-control form-control-lg" id="title" name="title"
value="{{ post.title }}" required maxlength="100"
placeholder="Enter your adventure title">
<div class="form-text">Make it catchy and descriptive!</div>
</div>
<!-- Subtitle -->
<div class="mb-4">
<label for="subtitle" class="form-label fw-bold">
<i class="fas fa-text-height text-info"></i> Subtitle
</label>
<input type="text" class="form-control" id="subtitle" name="subtitle"
value="{{ post.subtitle or '' }}" maxlength="200"
placeholder="A brief description of your adventure">
<div class="form-text">Optional - appears under the main title</div>
</div>
<!-- Difficulty Level -->
<div class="mb-4">
<label for="difficulty" class="form-label fw-bold">
<i class="fas fa-mountain text-warning"></i> Difficulty Level *
</label>
<select class="form-select" id="difficulty" name="difficulty" required>
<option value="">Select difficulty...</option>
<option value="1" {% if post.difficulty == 1 %}selected{% endif %}>⭐ Easy - Beginner friendly</option>
<option value="2" {% if post.difficulty == 2 %}selected{% endif %}>⭐⭐ Moderate - Some experience needed</option>
<option value="3" {% if post.difficulty == 3 %}selected{% endif %}>⭐⭐⭐ Challenging - Good skills required</option>
<option value="4" {% if post.difficulty == 4 %}selected{% endif %}>⭐⭐⭐⭐ Hard - Advanced riders only</option>
<option value="5" {% if post.difficulty == 5 %}selected{% endif %}>⭐⭐⭐⭐⭐ Expert - Extreme difficulty</option>
</select>
</div>
<!-- Current Cover Image -->
{% if post.images %}
{% set cover_image = post.images | selectattr('is_cover', 'equalto', True) | first %}
{% if cover_image %}
<div class="mb-4">
<label class="form-label fw-bold">
<i class="fas fa-image text-success"></i> Current Cover Photo
</label>
<div class="current-cover-preview">
<img src="{{ cover_image.get_thumbnail_url() }}" alt="Current cover"
class="img-thumbnail" style="max-width: 200px;">
<small class="text-muted d-block mt-1">{{ cover_image.original_name }}</small>
</div>
</div>
{% endif %}
{% endif %}
<!-- Cover Photo Upload -->
<div class="mb-4">
<label for="cover_picture" class="form-label fw-bold">
<i class="fas fa-camera text-success"></i>
{% if post.images and post.images | selectattr('is_cover', 'equalto', True) | first %}
Replace Cover Photo
{% else %}
Cover Photo
{% endif %}
</label>
<input type="file" class="form-control" id="cover_picture" name="cover_picture"
accept="image/*" onchange="previewCoverImage(this)">
<div class="form-text">
Optional - Upload a new cover photo to replace the current one
</div>
<div id="cover_preview" class="mt-2"></div>
</div>
<!-- Adventure Story/Content -->
<div class="mb-4">
<label for="content" class="form-label fw-bold">
<i class="fas fa-book text-primary"></i> Your Adventure Story *
</label>
<textarea class="form-control" id="content" name="content" rows="8" required
placeholder="Tell us about your adventure... Where did you go? What did you see? Any challenges or highlights?">{{ post.content }}</textarea>
<div class="form-text">
<i class="fas fa-info-circle"></i>
You can use **bold text** and *italic text* in your story!
</div>
</div>
<!-- Current GPX File -->
{% if post.gpx_files %}
<div class="mb-4">
<label class="form-label fw-bold">
<i class="fas fa-route text-info"></i> Current GPS Track
</label>
{% for gpx_file in post.gpx_files %}
<div class="current-gpx-file border rounded p-3 bg-light">
<div class="d-flex align-items-center">
<i class="fas fa-file-alt text-info me-2"></i>
<div>
<strong>{{ gpx_file.original_name }}</strong>
<small class="text-muted d-block">
Size: {{ "%.1f"|format(gpx_file.size / 1024) }} KB
• Uploaded: {{ gpx_file.created_at.strftime('%Y-%m-%d') }}
</small>
</div>
<a href="{{ url_for('community.serve_gpx', post_folder=post.media_folder, filename=gpx_file.filename) }}"
class="btn btn-sm btn-outline-primary ms-auto">
<i class="fas fa-download"></i> Download
</a>
</div>
</div>
{% endfor %}
</div>
{% endif %}
<!-- GPX File Upload -->
<div class="mb-4">
<label for="gpx_file" class="form-label fw-bold">
<i class="fas fa-route text-info"></i>
{% if post.gpx_files %}
Replace GPS Track File
{% else %}
GPS Track File (GPX)
{% endif %}
</label>
<input type="file" class="form-control" id="gpx_file" name="gpx_file"
accept=".gpx" onchange="validateGpxFile(this)">
<div class="form-text">
Optional - Upload a new GPX file to replace the current route
</div>
<div id="gpx_info" class="mt-2"></div>
</div>
<!-- Submit Buttons -->
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<a href="{{ url_for('community.profile') }}" class="btn btn-secondary me-md-2">
<i class="fas fa-arrow-left"></i> Cancel
</a>
<button type="button" class="btn btn-info me-md-2" onclick="previewPost()">
<i class="fas fa-eye"></i> Preview Changes
</button>
<button type="submit" class="btn btn-success">
<i class="fas fa-paper-plane"></i> Update & Resubmit for Review
</button>
</div>
</form>
</div>
</div>
<div class="min-h-screen bg-gradient-to-br from-blue-900 via-purple-900 to-teal-900 py-12">
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
<!-- Header -->
<div class="text-center mb-8">
<h1 class="text-4xl font-bold text-white mb-4">
<i class="fas fa-edit"></i> Edit Your Adventure
</h1>
<p class="text-blue-200 text-lg">
Update your motorcycle journey story - "{{ post.title }}"
</p>
</div>
<!-- Info Panel -->
<div class="col-lg-4">
<div class="card shadow-sm">
<div class="card-header bg-info text-white">
<h5 class="mb-0">
<i class="fas fa-info-circle"></i> Editing Guidelines
</h5>
<!-- Main Form -->
<form id="editPostForm" method="POST" action="{{ url_for('community.edit_post', id=post.id) }}" enctype="multipart/form-data" class="space-y-6">
<!-- Basic Information Section -->
<div class="bg-white/10 backdrop-blur-sm rounded-2xl p-6 border border-white/20">
<h2 class="text-2xl font-bold text-white mb-6">📝 Basic Information</h2>
<!-- Current Cover Image Display -->
{% if post.images %}
{% set cover_image = post.images | selectattr('is_cover', 'equalto', True) | first %}
{% if cover_image %}
<div class="mb-6">
<label class="block text-white font-semibold mb-2">
<i class="fas fa-image text-cyan-400"></i> Current Cover Photo
</label>
<div class="current-cover-preview bg-white/5 rounded-lg p-4 border border-white/20">
<img src="{{ cover_image.get_thumbnail_url() }}" alt="Current cover"
class="max-h-48 mx-auto rounded-lg border-2 border-white/20">
<p class="text-white/80 text-center mt-2 text-sm">{{ cover_image.original_name }}</p>
</div>
</div>
{% endif %}
{% endif %}
<!-- Cover Picture Upload -->
<div class="mb-6">
<label for="cover_picture" class="block text-white font-semibold mb-2">
{% if post.images and post.images | selectattr('is_cover', 'equalto', True) | first %}
Replace Cover Picture
{% else %}
Set Cover Picture for the Post
{% endif %}
</label>
<div class="cover-upload-area border-2 border-dashed border-white/30 rounded-lg p-6 text-center hover:border-white/50 transition-all duration-300">
<input type="file" id="cover_picture" name="cover_picture" accept="image/*" class="hidden">
<div class="cover-upload-content">
<div class="text-4xl mb-2">📸</div>
<p class="text-white/80 mb-2">Click to upload new cover image</p>
<p class="text-sm text-white/60">Recommended: 1920x1080 pixels</p>
</div>
<div class="cover-preview hidden">
<img class="cover-preview-image max-h-48 mx-auto rounded-lg" alt="Cover preview">
<button type="button" class="cover-remove-btn mt-2 px-3 py-1 bg-red-500/80 text-white rounded hover:bg-red-600 transition-colors">Remove</button>
</div>
</div>
</div>
<div class="card-body">
<div class="mb-3">
<h6><i class="fas fa-edit text-primary"></i> What happens after editing?</h6>
<p class="small">Your updated post will be resubmitted for admin review before being published again.</p>
</div>
<div class="mb-3">
<h6><i class="fas fa-image text-success"></i> Photo Guidelines</h6>
<ul class="small mb-0">
<li>Use high-quality images (JPEG, PNG)</li>
<li>Landscape orientation works best for cover photos</li>
<li>Maximum file size: 10MB</li>
<!-- Title -->
<div class="mb-6">
<label for="title" class="block text-white font-semibold mb-2">Adventure Title *</label>
<input type="text" id="title" name="title" required value="{{ post.title }}"
class="w-full px-4 py-3 rounded-lg bg-white/10 backdrop-blur-sm border border-white/20
text-white placeholder-white/60 focus:outline-none focus:ring-2 focus:ring-cyan-400
focus:border-transparent transition-all duration-300"
placeholder="Give your adventure a captivating title..." maxlength="100">
</div>
<!-- Subtitle -->
<div class="mb-6">
<label for="subtitle" class="block text-white font-semibold mb-2">Subtitle</label>
<input type="text" id="subtitle" name="subtitle" value="{{ post.subtitle or '' }}"
class="w-full px-4 py-3 rounded-lg bg-white/10 backdrop-blur-sm border border-white/20
text-white placeholder-white/60 focus:outline-none focus:ring-2 focus:ring-cyan-400
focus:border-transparent transition-all duration-300"
placeholder="A brief description of your adventure" maxlength="200">
</div>
<!-- Difficulty Rating -->
<div class="mb-6">
<label for="difficulty" class="block text-white font-semibold mb-2">Route Difficulty *</label>
<select id="difficulty" name="difficulty" required
class="w-full px-4 py-3 rounded-lg bg-white/10 backdrop-blur-sm border border-white/20
text-white focus:outline-none focus:ring-2 focus:ring-cyan-400
focus:border-transparent transition-all duration-300">
<option value="" class="bg-gray-800 text-gray-300">Select difficulty level...</option>
<option value="1" {% if post.difficulty == 1 %}selected{% endif %} class="bg-gray-800 text-green-400">🟢 Easy - Beginner friendly roads</option>
<option value="2" {% if post.difficulty == 2 %}selected{% endif %} class="bg-gray-800 text-yellow-400">🟡 Moderate - Some experience needed</option>
<option value="3" {% if post.difficulty == 3 %}selected{% endif %} class="bg-gray-800 text-orange-400">🟠 Challenging - Experienced riders</option>
<option value="4" {% if post.difficulty == 4 %}selected{% endif %} class="bg-gray-800 text-red-400">🔴 Difficult - Advanced skills required</option>
<option value="5" {% if post.difficulty == 5 %}selected{% endif %} class="bg-gray-800 text-purple-400">🟣 Expert - Only for experts</option>
</select>
</div>
</div>
<!-- Adventure Story Section -->
<div class="bg-white/10 backdrop-blur-sm rounded-2xl p-6 border border-white/20">
<h2 class="text-2xl font-bold text-white mb-6">📖 Adventure Story</h2>
<!-- Adventure Story/Content -->
<div class="mb-6">
<label for="content" class="block text-white font-semibold mb-2">
<i class="fas fa-book text-cyan-400"></i> Your Adventure Story *
</label>
<textarea id="content" name="content" rows="8" required
class="w-full px-4 py-3 rounded-lg bg-white/10 backdrop-blur-sm border border-white/20
text-white placeholder-white/60 focus:outline-none focus:ring-2 focus:ring-cyan-400
focus:border-transparent transition-all duration-300"
placeholder="Tell us about your adventure... Where did you go? What did you see? Any challenges or highlights?">{{ post.content }}</textarea>
<div class="text-blue-200 text-sm mt-2">
<i class="fas fa-info-circle"></i>
You can use **bold text** and *italic text* in your story!
</div>
</div>
</div>
<!-- Route File Section -->
<div class="bg-white/10 backdrop-blur-sm rounded-2xl p-6 border border-white/20">
<h2 class="text-2xl font-bold text-white mb-6">🗺️ Route File</h2>
<!-- Current GPX File Display -->
{% if post.gpx_files %}
<div class="mb-6">
<label class="block text-white font-semibold mb-2">
<i class="fas fa-route text-cyan-400"></i> Current GPS Track
</label>
{% for gpx_file in post.gpx_files %}
<div class="current-gpx-file bg-white/5 rounded-lg p-4 border border-white/20">
<div class="flex items-center justify-between">
<div class="flex items-center">
<i class="fas fa-file-alt text-cyan-400 mr-3 text-xl"></i>
<div>
<div class="text-white font-semibold">{{ gpx_file.original_name }}</div>
<div class="text-white/60 text-sm">
Size: {{ "%.1f"|format(gpx_file.size / 1024) }} KB
• Uploaded: {{ gpx_file.created_at.strftime('%Y-%m-%d') }}
</div>
</div>
</div>
<a href="{{ url_for('community.serve_gpx', post_folder=post.media_folder, filename=gpx_file.filename) }}"
class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition-colors">
<i class="fas fa-download"></i> Download
</a>
</div>
</div>
{% endfor %}
</div>
{% endif %}
<!-- GPX File Upload -->
<div class="border-2 border-dashed border-white/30 rounded-lg p-8 text-center">
<i class="fas fa-route text-4xl text-blue-300 mb-4"></i>
<div class="text-white font-semibold mb-2">
{% if post.gpx_files %}
Replace GPX Route File
{% else %}
Upload GPX Route File
{% endif %}
</div>
<div class="text-blue-200 text-sm mb-4">
Share your exact route so others can follow your adventure
</div>
<input type="file" id="gpx_file" name="gpx_file" accept=".gpx" class="hidden">
<label for="gpx_file" class="inline-flex items-center px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 cursor-pointer transition">
<i class="fas fa-upload mr-2"></i>
Choose GPX File
</label>
<div id="gpx_info" class="mt-4 text-green-300 hidden"></div>
</div>
</div>
<!-- Guidelines Section -->
<div class="bg-white/10 backdrop-blur-sm rounded-2xl p-6 border border-white/20">
<h2 class="text-2xl font-bold text-white mb-6">
<i class="fas fa-info-circle text-cyan-400"></i> Editing Guidelines
</h2>
<div class="grid md:grid-cols-2 gap-6">
<div>
<h3 class="text-lg font-semibold text-cyan-300 mb-3">
<i class="fas fa-edit"></i> What happens after editing?
</h3>
<p class="text-white/80 text-sm">Your updated post will be resubmitted for admin review before being published again.</p>
</div>
<div>
<h3 class="text-lg font-semibold text-cyan-300 mb-3">
<i class="fas fa-image"></i> Photo Guidelines
</h3>
<ul class="text-white/80 text-sm space-y-1">
<li>• Use high-quality images (JPEG, PNG)</li>
<li>• Landscape orientation works best</li>
<li>• Maximum file size: 10MB</li>
</ul>
</div>
<div class="mb-3">
<h6><i class="fas fa-route text-info"></i> GPX File Tips</h6>
<ul class="small mb-0">
<li>Export from your GPS device or app</li>
<li>Should contain track points</li>
<li>Will be displayed on the community map</li>
<div>
<h3 class="text-lg font-semibold text-cyan-300 mb-3">
<i class="fas fa-route"></i> GPX File Tips
</h3>
<ul class="text-white/80 text-sm space-y-1">
<li>• Export from your GPS device or app</li>
<li>• Should contain track points</li>
<li>• Will be displayed on the community map</li>
</ul>
</div>
<div class="mb-3">
<h6><i class="fas fa-star text-warning"></i> Difficulty Levels</h6>
<div class="small">
<div>
<h3 class="text-lg font-semibold text-cyan-300 mb-3">
<i class="fas fa-star"></i> Difficulty Levels
</h3>
<div class="text-white/80 text-sm space-y-1">
<div><strong>Easy:</strong> Paved roads, good weather</div>
<div><strong>Moderate:</strong> Some gravel, hills</div>
<div><strong>Challenging:</strong> Off-road, technical</div>
@@ -203,36 +270,54 @@
<div><strong>Expert:</strong> Dangerous, experts only</div>
</div>
</div>
</div>
<div class="alert alert-warning">
<i class="fas fa-exclamation-triangle"></i>
<div class="mt-6 p-4 bg-yellow-500/20 border border-yellow-400/50 rounded-lg">
<div class="flex items-center text-yellow-300">
<i class="fas fa-exclamation-triangle mr-2"></i>
<strong>Note:</strong> Updating your post will reset its status to "pending review."
</div>
</div>
</div>
</div>
<!-- Submit Buttons -->
<div class="text-center space-x-4">
<a href="{{ url_for('community.profile') }}" class="bg-gray-600 hover:bg-gray-700 text-white px-8 py-4 rounded-lg font-bold text-lg transition-all duration-200 shadow-lg inline-block">
<i class="fas fa-arrow-left mr-3"></i>
Cancel
</a>
<button type="button" onclick="previewPost()" class="bg-gradient-to-r from-blue-500 to-indigo-600 text-white px-8 py-4 rounded-lg font-bold text-lg hover:from-blue-600 hover:to-indigo-700 transform hover:scale-105 transition-all duration-200 shadow-lg">
<i class="fas fa-eye mr-3"></i>
Preview Changes
</button>
<button type="submit" class="bg-gradient-to-r from-orange-500 to-red-600 text-white px-12 py-4 rounded-lg font-bold text-lg hover:from-orange-600 hover:to-red-700 transform hover:scale-105 transition-all duration-200 shadow-lg">
<i class="fas fa-paper-plane mr-3"></i>
Update Adventure
</button>
</div>
</form>
</div>
</div>
<!-- Preview Modal -->
<div class="modal fade" id="previewModal" tabindex="-1" aria-labelledby="previewModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="previewModalLabel">
<i class="fas fa-eye"></i> Post Preview
<div class="modal-content bg-gray-900 text-white border-0">
<div class="modal-header border-gray-700">
<h5 class="modal-title text-white" id="previewModalLabel">
<i class="fas fa-eye text-cyan-400"></i> Adventure Preview
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="modal-body bg-gradient-to-br from-blue-900 via-purple-900 to-teal-900">
<div id="previewContent">
<!-- Preview content will be loaded here -->
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close Preview</button>
<button type="button" class="btn btn-success" onclick="submitForm()">
<i class="fas fa-paper-plane"></i> Looks Good - Update Post
<div class="modal-footer border-gray-700">
<button type="button" class="bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded-lg transition-colors" data-bs-dismiss="modal">Close Preview</button>
<button type="button" class="bg-gradient-to-r from-orange-500 to-red-600 text-white px-6 py-2 rounded-lg hover:from-orange-600 hover:to-red-700 transition-all duration-200" onclick="submitForm()">
<i class="fas fa-paper-plane mr-2"></i> Looks Good - Update Post
</button>
</div>
</div>
@@ -241,48 +326,72 @@
<!-- JavaScript -->
<script>
function previewCoverImage(input) {
const preview = document.getElementById('cover_preview');
preview.innerHTML = '';
if (input.files && input.files[0]) {
const reader = new FileReader();
reader.onload = function(e) {
preview.innerHTML = `
<div class="mt-2">
<img src="${e.target.result}" alt="Cover preview" class="img-thumbnail" style="max-width: 200px;">
<small class="text-success d-block mt-1">✓ New cover photo ready</small>
</div>
`;
};
reader.readAsDataURL(input.files[0]);
}
}
// Cover image preview functionality
document.addEventListener('DOMContentLoaded', function() {
const coverInput = document.getElementById('cover_picture');
const coverUploadArea = document.querySelector('.cover-upload-area');
const coverUploadContent = document.querySelector('.cover-upload-content');
const coverPreview = document.querySelector('.cover-preview');
const coverPreviewImage = document.querySelector('.cover-preview-image');
const coverRemoveBtn = document.querySelector('.cover-remove-btn');
function validateGpxFile(input) {
const info = document.getElementById('gpx_info');
info.innerHTML = '';
if (input.files && input.files[0]) {
const file = input.files[0];
if (file.name.toLowerCase().endsWith('.gpx')) {
info.innerHTML = `
<div class="alert alert-success">
<i class="fas fa-check-circle"></i>
GPX file selected: ${file.name} (${(file.size / 1024).toFixed(1)} KB)
</div>
`;
} else {
info.innerHTML = `
<div class="alert alert-danger">
<i class="fas fa-exclamation-triangle"></i>
Please select a valid GPX file
</div>
`;
input.value = '';
// Cover upload click handler
coverUploadArea.addEventListener('click', function() {
coverInput.click();
});
// Cover file change handler
coverInput.addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(e) {
coverPreviewImage.src = e.target.result;
coverUploadContent.classList.add('hidden');
coverPreview.classList.remove('hidden');
};
reader.readAsDataURL(file);
}
}
}
});
// Cover remove button
coverRemoveBtn.addEventListener('click', function(e) {
e.stopPropagation();
coverInput.value = '';
coverUploadContent.classList.remove('hidden');
coverPreview.classList.add('hidden');
});
// GPX file handler
const gpxInput = document.getElementById('gpx_file');
const gpxInfo = document.getElementById('gpx_info');
gpxInput.addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
if (file.name.toLowerCase().endsWith('.gpx')) {
gpxInfo.innerHTML = `
<div class="text-green-300">
<i class="fas fa-check-circle mr-2"></i>
GPX file selected: ${file.name} (${(file.size / 1024).toFixed(1)} KB)
</div>
`;
gpxInfo.classList.remove('hidden');
} else {
gpxInfo.innerHTML = `
<div class="text-red-300">
<i class="fas fa-exclamation-triangle mr-2"></i>
Please select a valid GPX file
</div>
`;
gpxInfo.classList.remove('hidden');
gpxInput.value = '';
}
} else {
gpxInfo.classList.add('hidden');
}
});
});
function previewPost() {
// Get form data
@@ -291,16 +400,17 @@ function previewPost() {
const content = document.getElementById('content').value;
const difficulty = document.getElementById('difficulty').value;
// Get difficulty stars
const difficultyStars = '⭐'.repeat(difficulty);
const difficultyLabels = {
'1': 'Easy',
'2': 'Moderate',
'3': 'Challenging',
'4': 'Hard',
'5': 'Expert'
// Get difficulty display
const difficultyOptions = {
'1': { emoji: '🟢', text: 'Easy - Beginner friendly roads' },
'2': { emoji: '🟡', text: 'Moderate - Some experience needed' },
'3': { emoji: '🟠', text: 'Challenging - Experienced riders' },
'4': { emoji: '🔴', text: 'Difficult - Advanced skills required' },
'5': { emoji: '🟣', text: 'Expert - Only for experts' }
};
const difficultyDisplay = difficultyOptions[difficulty] || { emoji: '', text: 'Select difficulty' };
// Format content (simple markdown-like formatting)
const formattedContent = content
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
@@ -311,38 +421,38 @@ function previewPost() {
const previewHTML = `
<div class="post-preview">
<!-- Hero Section -->
<div class="hero-section bg-primary text-white p-4 rounded mb-4">
<div class="container">
<h1 class="display-4 mb-2">${title || 'Your Adventure Title'}</h1>
${subtitle ? `<p class="lead mb-3">${subtitle}</p>` : ''}
<div class="d-flex align-items-center">
<span class="badge bg-warning text-dark me-3">
${difficultyStars} ${difficultyLabels[difficulty] || 'Select difficulty'}
<div class="bg-gradient-to-r from-blue-600 to-purple-600 text-white p-8 rounded-2xl mb-6">
<div class="max-w-4xl mx-auto">
<h1 class="text-4xl font-bold mb-4">${title || 'Your Adventure Title'}</h1>
${subtitle ? `<p class="text-xl mb-4 text-blue-100">${subtitle}</p>` : ''}
<div class="flex items-center space-x-4">
<span class="inline-flex items-center px-3 py-1 bg-white/20 rounded-full text-sm font-medium">
${difficultyDisplay.emoji} ${difficultyDisplay.text}
</span>
<small>By {{ current_user.nickname }} • Updated today</small>
<span class="text-blue-200">Updated today</span>
</div>
</div>
</div>
<!-- Content Section -->
<div class="container">
<div class="row">
<div class="col-lg-8">
<div class="adventure-content">
<h3>Adventure Story</h3>
<div class="content-text">
${formattedContent || '<em>No content provided yet...</em>'}
<div class="max-w-4xl mx-auto">
<div class="grid lg:grid-cols-3 gap-8">
<div class="lg:col-span-2">
<div class="bg-white/10 backdrop-blur-sm rounded-2xl p-6 border border-white/20">
<h3 class="text-2xl font-bold text-white mb-4">Adventure Story</h3>
<div class="text-white/90 leading-relaxed">
${formattedContent || '<em class="text-white/60">No content provided yet...</em>'}
</div>
</div>
</div>
<div class="col-lg-4">
<div class="adventure-info">
<h5>Adventure Details</h5>
<ul class="list-unstyled">
<li><strong>Difficulty:</strong> ${difficultyStars} ${difficultyLabels[difficulty] || 'Not set'}</li>
<li><strong>Status:</strong> <span class="badge bg-warning">Pending Review</span></li>
<li><strong>Last Updated:</strong> Today</li>
</ul>
<div class="lg:col-span-1">
<div class="bg-white/10 backdrop-blur-sm rounded-2xl p-6 border border-white/20">
<h5 class="text-xl font-bold text-white mb-4">Adventure Details</h5>
<div class="space-y-3 text-white/80">
<div><strong>Difficulty:</strong> ${difficultyDisplay.emoji} ${difficultyDisplay.text}</div>
<div><strong>Status:</strong> <span class="inline-flex items-center px-2 py-1 bg-yellow-500/20 text-yellow-300 rounded-full text-sm">Pending Review</span></div>
<div><strong>Last Updated:</strong> Today</div>
</div>
</div>
</div>
</div>
@@ -360,7 +470,7 @@ function submitForm() {
document.getElementById('editPostForm').submit();
}
// Form submission with AJAX
// Form submission with enhanced feedback
document.getElementById('editPostForm').addEventListener('submit', function(e) {
e.preventDefault();
@@ -369,7 +479,7 @@ document.getElementById('editPostForm').addEventListener('submit', function(e) {
const originalText = submitButton.innerHTML;
// Show loading state
submitButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Updating...';
submitButton.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Updating...';
submitButton.disabled = true;
fetch(this.action, {
@@ -381,37 +491,50 @@ document.getElementById('editPostForm').addEventListener('submit', function(e) {
if (data.success) {
// Show success message
const alert = document.createElement('div');
alert.className = 'alert alert-success alert-dismissible fade show';
alert.className = 'fixed top-4 right-4 bg-green-500 text-white p-4 rounded-lg shadow-lg z-50';
alert.innerHTML = `
<i class="fas fa-check-circle"></i> ${data.message}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
<div class="flex items-center">
<i class="fas fa-check-circle mr-2"></i>
${data.message}
</div>
`;
this.insertBefore(alert, this.firstChild);
document.body.appendChild(alert);
// Redirect after delay
// Remove alert and redirect after delay
setTimeout(() => {
alert.remove();
window.location.href = data.redirect_url;
}, 2000);
} else {
// Show error message
const alert = document.createElement('div');
alert.className = 'alert alert-danger alert-dismissible fade show';
alert.className = 'fixed top-4 right-4 bg-red-500 text-white p-4 rounded-lg shadow-lg z-50';
alert.innerHTML = `
<i class="fas fa-exclamation-triangle"></i> ${data.error}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
<div class="flex items-center">
<i class="fas fa-exclamation-triangle mr-2"></i>
${data.error}
<button onclick="this.parentElement.parentElement.remove()" class="ml-4 text-white hover:text-gray-300">
<i class="fas fa-times"></i>
</button>
</div>
`;
this.insertBefore(alert, this.firstChild);
document.body.appendChild(alert);
}
})
.catch(error => {
console.error('Error:', error);
const alert = document.createElement('div');
alert.className = 'alert alert-danger alert-dismissible fade show';
alert.className = 'fixed top-4 right-4 bg-red-500 text-white p-4 rounded-lg shadow-lg z-50';
alert.innerHTML = `
<i class="fas fa-exclamation-triangle"></i> An error occurred while updating your post.
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
<div class="flex items-center">
<i class="fas fa-exclamation-triangle mr-2"></i>
An error occurred while updating your post.
<button onclick="this.parentElement.parentElement.remove()" class="ml-4 text-white hover:text-gray-300">
<i class="fas fa-times"></i>
</button>
</div>
`;
this.insertBefore(alert, this.firstChild);
document.body.appendChild(alert);
})
.finally(() => {
// Restore button state