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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user