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" %}
|
{% extends "base.html" %}
|
||||||
{% block title %}Edit Adventure - {{ post.title }}{% endblock %}
|
{% 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 %}
|
{% block content %}
|
||||||
<div class="container-fluid">
|
<div class="min-h-screen bg-gradient-to-br from-blue-900 via-purple-900 to-teal-900 py-12">
|
||||||
<div class="row">
|
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<!-- Form Section -->
|
<!-- Header -->
|
||||||
<div class="col-lg-8">
|
<div class="text-center mb-8">
|
||||||
<div class="card shadow-sm">
|
<h1 class="text-4xl font-bold text-white mb-4">
|
||||||
<div class="card-header bg-primary text-white">
|
<i class="fas fa-edit"></i> Edit Your Adventure
|
||||||
<h4 class="mb-0">
|
</h1>
|
||||||
<i class="fas fa-edit"></i> Edit Your Adventure
|
<p class="text-blue-200 text-lg">
|
||||||
</h4>
|
Update your motorcycle journey story - "{{ post.title }}"
|
||||||
</div>
|
</p>
|
||||||
<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>
|
</div>
|
||||||
|
|
||||||
<!-- Info Panel -->
|
<!-- Main Form -->
|
||||||
<div class="col-lg-4">
|
<form id="editPostForm" method="POST" action="{{ url_for('community.edit_post', id=post.id) }}" enctype="multipart/form-data" class="space-y-6">
|
||||||
<div class="card shadow-sm">
|
<!-- Basic Information Section -->
|
||||||
<div class="card-header bg-info text-white">
|
<div class="bg-white/10 backdrop-blur-sm rounded-2xl p-6 border border-white/20">
|
||||||
<h5 class="mb-0">
|
<h2 class="text-2xl font-bold text-white mb-6">📝 Basic Information</h2>
|
||||||
<i class="fas fa-info-circle"></i> Editing Guidelines
|
|
||||||
</h5>
|
<!-- 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>
|
||||||
<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">
|
<!-- Title -->
|
||||||
<h6><i class="fas fa-image text-success"></i> Photo Guidelines</h6>
|
<div class="mb-6">
|
||||||
<ul class="small mb-0">
|
<label for="title" class="block text-white font-semibold mb-2">Adventure Title *</label>
|
||||||
<li>Use high-quality images (JPEG, PNG)</li>
|
<input type="text" id="title" name="title" required value="{{ post.title }}"
|
||||||
<li>Landscape orientation works best for cover photos</li>
|
class="w-full px-4 py-3 rounded-lg bg-white/10 backdrop-blur-sm border border-white/20
|
||||||
<li>Maximum file size: 10MB</li>
|
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>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div>
|
||||||
<h6><i class="fas fa-route text-info"></i> GPX File Tips</h6>
|
<h3 class="text-lg font-semibold text-cyan-300 mb-3">
|
||||||
<ul class="small mb-0">
|
<i class="fas fa-route"></i> GPX File Tips
|
||||||
<li>Export from your GPS device or app</li>
|
</h3>
|
||||||
<li>Should contain track points</li>
|
<ul class="text-white/80 text-sm space-y-1">
|
||||||
<li>Will be displayed on the community map</li>
|
<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>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div>
|
||||||
<h6><i class="fas fa-star text-warning"></i> Difficulty Levels</h6>
|
<h3 class="text-lg font-semibold text-cyan-300 mb-3">
|
||||||
<div class="small">
|
<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>Easy:</strong> Paved roads, good weather</div>
|
||||||
<div><strong>Moderate:</strong> Some gravel, hills</div>
|
<div><strong>Moderate:</strong> Some gravel, hills</div>
|
||||||
<div><strong>Challenging:</strong> Off-road, technical</div>
|
<div><strong>Challenging:</strong> Off-road, technical</div>
|
||||||
@@ -203,36 +270,54 @@
|
|||||||
<div><strong>Expert:</strong> Dangerous, experts only</div>
|
<div><strong>Expert:</strong> Dangerous, experts only</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="alert alert-warning">
|
<div class="mt-6 p-4 bg-yellow-500/20 border border-yellow-400/50 rounded-lg">
|
||||||
<i class="fas fa-exclamation-triangle"></i>
|
<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."
|
<strong>Note:</strong> Updating your post will reset its status to "pending review."
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Preview Modal -->
|
<!-- Preview Modal -->
|
||||||
<div class="modal fade" id="previewModal" tabindex="-1" aria-labelledby="previewModalLabel" aria-hidden="true">
|
<div class="modal fade" id="previewModal" tabindex="-1" aria-labelledby="previewModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-xl">
|
<div class="modal-dialog modal-xl">
|
||||||
<div class="modal-content">
|
<div class="modal-content bg-gray-900 text-white border-0">
|
||||||
<div class="modal-header">
|
<div class="modal-header border-gray-700">
|
||||||
<h5 class="modal-title" id="previewModalLabel">
|
<h5 class="modal-title text-white" id="previewModalLabel">
|
||||||
<i class="fas fa-eye"></i> Post Preview
|
<i class="fas fa-eye text-cyan-400"></i> Adventure Preview
|
||||||
</h5>
|
</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>
|
||||||
<div class="modal-body">
|
<div class="modal-body bg-gradient-to-br from-blue-900 via-purple-900 to-teal-900">
|
||||||
<div id="previewContent">
|
<div id="previewContent">
|
||||||
<!-- Preview content will be loaded here -->
|
<!-- Preview content will be loaded here -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer border-gray-700">
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close Preview</button>
|
<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="btn btn-success" onclick="submitForm()">
|
<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"></i> Looks Good - Update Post
|
<i class="fas fa-paper-plane mr-2"></i> Looks Good - Update Post
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -241,48 +326,72 @@
|
|||||||
|
|
||||||
<!-- JavaScript -->
|
<!-- JavaScript -->
|
||||||
<script>
|
<script>
|
||||||
function previewCoverImage(input) {
|
// Cover image preview functionality
|
||||||
const preview = document.getElementById('cover_preview');
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
preview.innerHTML = '';
|
const coverInput = document.getElementById('cover_picture');
|
||||||
|
const coverUploadArea = document.querySelector('.cover-upload-area');
|
||||||
if (input.files && input.files[0]) {
|
const coverUploadContent = document.querySelector('.cover-upload-content');
|
||||||
const reader = new FileReader();
|
const coverPreview = document.querySelector('.cover-preview');
|
||||||
reader.onload = function(e) {
|
const coverPreviewImage = document.querySelector('.cover-preview-image');
|
||||||
preview.innerHTML = `
|
const coverRemoveBtn = document.querySelector('.cover-remove-btn');
|
||||||
<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]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateGpxFile(input) {
|
// Cover upload click handler
|
||||||
const info = document.getElementById('gpx_info');
|
coverUploadArea.addEventListener('click', function() {
|
||||||
info.innerHTML = '';
|
coverInput.click();
|
||||||
|
});
|
||||||
if (input.files && input.files[0]) {
|
|
||||||
const file = input.files[0];
|
// Cover file change handler
|
||||||
if (file.name.toLowerCase().endsWith('.gpx')) {
|
coverInput.addEventListener('change', function(e) {
|
||||||
info.innerHTML = `
|
const file = e.target.files[0];
|
||||||
<div class="alert alert-success">
|
if (file) {
|
||||||
<i class="fas fa-check-circle"></i>
|
const reader = new FileReader();
|
||||||
GPX file selected: ${file.name} (${(file.size / 1024).toFixed(1)} KB)
|
reader.onload = function(e) {
|
||||||
</div>
|
coverPreviewImage.src = e.target.result;
|
||||||
`;
|
coverUploadContent.classList.add('hidden');
|
||||||
} else {
|
coverPreview.classList.remove('hidden');
|
||||||
info.innerHTML = `
|
};
|
||||||
<div class="alert alert-danger">
|
reader.readAsDataURL(file);
|
||||||
<i class="fas fa-exclamation-triangle"></i>
|
|
||||||
Please select a valid GPX file
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
input.value = '';
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
// 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() {
|
function previewPost() {
|
||||||
// Get form data
|
// Get form data
|
||||||
@@ -291,16 +400,17 @@ function previewPost() {
|
|||||||
const content = document.getElementById('content').value;
|
const content = document.getElementById('content').value;
|
||||||
const difficulty = document.getElementById('difficulty').value;
|
const difficulty = document.getElementById('difficulty').value;
|
||||||
|
|
||||||
// Get difficulty stars
|
// Get difficulty display
|
||||||
const difficultyStars = '⭐'.repeat(difficulty);
|
const difficultyOptions = {
|
||||||
const difficultyLabels = {
|
'1': { emoji: '🟢', text: 'Easy - Beginner friendly roads' },
|
||||||
'1': 'Easy',
|
'2': { emoji: '🟡', text: 'Moderate - Some experience needed' },
|
||||||
'2': 'Moderate',
|
'3': { emoji: '🟠', text: 'Challenging - Experienced riders' },
|
||||||
'3': 'Challenging',
|
'4': { emoji: '🔴', text: 'Difficult - Advanced skills required' },
|
||||||
'4': 'Hard',
|
'5': { emoji: '🟣', text: 'Expert - Only for experts' }
|
||||||
'5': 'Expert'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const difficultyDisplay = difficultyOptions[difficulty] || { emoji: '', text: 'Select difficulty' };
|
||||||
|
|
||||||
// Format content (simple markdown-like formatting)
|
// Format content (simple markdown-like formatting)
|
||||||
const formattedContent = content
|
const formattedContent = content
|
||||||
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
||||||
@@ -311,38 +421,38 @@ function previewPost() {
|
|||||||
const previewHTML = `
|
const previewHTML = `
|
||||||
<div class="post-preview">
|
<div class="post-preview">
|
||||||
<!-- Hero Section -->
|
<!-- Hero Section -->
|
||||||
<div class="hero-section bg-primary text-white p-4 rounded mb-4">
|
<div class="bg-gradient-to-r from-blue-600 to-purple-600 text-white p-8 rounded-2xl mb-6">
|
||||||
<div class="container">
|
<div class="max-w-4xl mx-auto">
|
||||||
<h1 class="display-4 mb-2">${title || 'Your Adventure Title'}</h1>
|
<h1 class="text-4xl font-bold mb-4">${title || 'Your Adventure Title'}</h1>
|
||||||
${subtitle ? `<p class="lead mb-3">${subtitle}</p>` : ''}
|
${subtitle ? `<p class="text-xl mb-4 text-blue-100">${subtitle}</p>` : ''}
|
||||||
<div class="d-flex align-items-center">
|
<div class="flex items-center space-x-4">
|
||||||
<span class="badge bg-warning text-dark me-3">
|
<span class="inline-flex items-center px-3 py-1 bg-white/20 rounded-full text-sm font-medium">
|
||||||
${difficultyStars} ${difficultyLabels[difficulty] || 'Select difficulty'}
|
${difficultyDisplay.emoji} ${difficultyDisplay.text}
|
||||||
</span>
|
</span>
|
||||||
<small>By {{ current_user.nickname }} • Updated today</small>
|
<span class="text-blue-200">Updated today</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Content Section -->
|
<!-- Content Section -->
|
||||||
<div class="container">
|
<div class="max-w-4xl mx-auto">
|
||||||
<div class="row">
|
<div class="grid lg:grid-cols-3 gap-8">
|
||||||
<div class="col-lg-8">
|
<div class="lg:col-span-2">
|
||||||
<div class="adventure-content">
|
<div class="bg-white/10 backdrop-blur-sm rounded-2xl p-6 border border-white/20">
|
||||||
<h3>Adventure Story</h3>
|
<h3 class="text-2xl font-bold text-white mb-4">Adventure Story</h3>
|
||||||
<div class="content-text">
|
<div class="text-white/90 leading-relaxed">
|
||||||
${formattedContent || '<em>No content provided yet...</em>'}
|
${formattedContent || '<em class="text-white/60">No content provided yet...</em>'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-4">
|
<div class="lg:col-span-1">
|
||||||
<div class="adventure-info">
|
<div class="bg-white/10 backdrop-blur-sm rounded-2xl p-6 border border-white/20">
|
||||||
<h5>Adventure Details</h5>
|
<h5 class="text-xl font-bold text-white mb-4">Adventure Details</h5>
|
||||||
<ul class="list-unstyled">
|
<div class="space-y-3 text-white/80">
|
||||||
<li><strong>Difficulty:</strong> ${difficultyStars} ${difficultyLabels[difficulty] || 'Not set'}</li>
|
<div><strong>Difficulty:</strong> ${difficultyDisplay.emoji} ${difficultyDisplay.text}</div>
|
||||||
<li><strong>Status:</strong> <span class="badge bg-warning">Pending Review</span></li>
|
<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>
|
||||||
<li><strong>Last Updated:</strong> Today</li>
|
<div><strong>Last Updated:</strong> Today</div>
|
||||||
</ul>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -360,7 +470,7 @@ function submitForm() {
|
|||||||
document.getElementById('editPostForm').submit();
|
document.getElementById('editPostForm').submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Form submission with AJAX
|
// Form submission with enhanced feedback
|
||||||
document.getElementById('editPostForm').addEventListener('submit', function(e) {
|
document.getElementById('editPostForm').addEventListener('submit', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@@ -369,7 +479,7 @@ document.getElementById('editPostForm').addEventListener('submit', function(e) {
|
|||||||
const originalText = submitButton.innerHTML;
|
const originalText = submitButton.innerHTML;
|
||||||
|
|
||||||
// Show loading state
|
// 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;
|
submitButton.disabled = true;
|
||||||
|
|
||||||
fetch(this.action, {
|
fetch(this.action, {
|
||||||
@@ -381,37 +491,50 @@ document.getElementById('editPostForm').addEventListener('submit', function(e) {
|
|||||||
if (data.success) {
|
if (data.success) {
|
||||||
// Show success message
|
// Show success message
|
||||||
const alert = document.createElement('div');
|
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 = `
|
alert.innerHTML = `
|
||||||
<i class="fas fa-check-circle"></i> ${data.message}
|
<div class="flex items-center">
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
<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(() => {
|
setTimeout(() => {
|
||||||
|
alert.remove();
|
||||||
window.location.href = data.redirect_url;
|
window.location.href = data.redirect_url;
|
||||||
}, 2000);
|
}, 2000);
|
||||||
} else {
|
} else {
|
||||||
// Show error message
|
// Show error message
|
||||||
const alert = document.createElement('div');
|
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 = `
|
alert.innerHTML = `
|
||||||
<i class="fas fa-exclamation-triangle"></i> ${data.error}
|
<div class="flex items-center">
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
<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 => {
|
.catch(error => {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
const alert = document.createElement('div');
|
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 = `
|
alert.innerHTML = `
|
||||||
<i class="fas fa-exclamation-triangle"></i> An error occurred while updating your post.
|
<div class="flex items-center">
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
<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(() => {
|
.finally(() => {
|
||||||
// Restore button state
|
// Restore button state
|
||||||
|
|||||||
Reference in New Issue
Block a user