134 lines
6.5 KiB
HTML
134 lines
6.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>GPX to FIT Converter</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
|
<script>
|
|
function refreshPage() {
|
|
location.reload();
|
|
}
|
|
setInterval(refreshPage, 30000);
|
|
|
|
tailwind.config = {
|
|
theme: {
|
|
extend: {
|
|
keyframes: {
|
|
fadeIn: {
|
|
'0%': { opacity: '0' },
|
|
'100%': { opacity: '1' },
|
|
}
|
|
},
|
|
animation: {
|
|
fadeIn: 'fadeIn 0.5s ease-out',
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
</head>
|
|
<body class="bg-gray-100 min-h-screen p-8" x-data="{
|
|
selectedInputFiles: [],
|
|
selectedOutputFiles: [],
|
|
async deleteFiles(folder) {
|
|
const files = folder === 'input' ? this.selectedInputFiles : this.selectedOutputFiles;
|
|
if (files.length === 0) return;
|
|
|
|
const response = await fetch('/delete', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ files, folder }),
|
|
});
|
|
|
|
if (response.ok) {
|
|
location.reload();
|
|
} else {
|
|
alert('Error deleting files');
|
|
}
|
|
}
|
|
}">
|
|
<div class="max-w-4xl mx-auto bg-white rounded-lg shadow-xl overflow-hidden animate-fadeIn">
|
|
<div class="bg-blue-600 text-white p-6">
|
|
<h1 class="text-3xl font-bold mb-2">FIT to GPX Converter</h1>
|
|
<p class="text-lg">Convert your .gpx files to .fit format with ease!</p>
|
|
</div>
|
|
|
|
<div class="p-6">
|
|
<div class="bg-yellow-100 border-l-4 border-yellow-500 text-yellow-700 p-4 mb-6 rounded animate-fadeIn" role="alert">
|
|
<h2 class="font-bold text-lg mb-2">Quick Start Guide</h2>
|
|
<ol class="list-decimal list-inside space-y-1">
|
|
<li>Select a .gpx file using the file input below.</li>
|
|
<li>Click the "Upload and Convert" button.</li>
|
|
<li>Wait for the conversion to complete.</li>
|
|
<li>Download your converted .fit file from the output files list.</li>
|
|
</ol>
|
|
<p class="mt-2">This tool converts GPX files to Garmin FIT format, allowing you to use your fitness data in a wide range of applications and devices like garminDB importer.</p>
|
|
</div>
|
|
|
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
|
{% if messages %}
|
|
{% for category, message in messages %}
|
|
<div class="animate-fadeIn {% if category == 'success' %}bg-green-100 border-green-500 text-green-700{% else %}bg-red-100 border-red-500 text-red-700{% endif %} border-l-4 p-4 mb-4 rounded" role="alert">
|
|
<p>{{ message }}</p>
|
|
</div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% endwith %}
|
|
|
|
<form method="post" enctype="multipart/form-data" class="mb-6">
|
|
<div class="flex flex-col sm:flex-row items-center justify-center space-y-4 sm:space-y-0 sm:space-x-4">
|
|
<input type="file" name="file" accept=".fit" class="file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100" required>
|
|
<button type="submit" class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded transition duration-300 ease-in-out transform hover:scale-105">
|
|
Upload and Convert
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div>
|
|
<h2 class="text-2xl font-bold mb-4">Input Files:</h2>
|
|
{% if input_files %}
|
|
<ul class="space-y-2 animate-fadeIn">
|
|
{% for file in input_files %}
|
|
<li class="flex items-center bg-gray-50 p-3 rounded hover:bg-gray-100 transition duration-300 ease-in-out">
|
|
<input type="checkbox" class="mr-2" x-model="selectedInputFiles" :value="'{{ file }}'">
|
|
<span class="text-blue-600">{{ file }}</span>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
<button @click="deleteFiles('input')" class="mt-4 bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded transition duration-300 ease-in-out" x-bind:disabled="selectedInputFiles.length === 0">
|
|
Delete Selected Input Files
|
|
</button>
|
|
{% else %}
|
|
<p class="text-gray-600">No input files yet. Upload a .gpx file to get started!</p>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div>
|
|
<h2 class="text-2xl font-bold mb-4">Output Files:</h2>
|
|
{% if output_files %}
|
|
<ul class="space-y-2 animate-fadeIn">
|
|
{% for file in output_files %}
|
|
<li class="flex items-center bg-gray-50 p-3 rounded hover:bg-gray-100 transition duration-300 ease-in-out">
|
|
<input type="checkbox" class="mr-2" x-model="selectedOutputFiles" :value="'{{ file }}'">
|
|
<a href="{{ url_for('download_file', filename=file) }}" class="text-blue-600 hover:text-blue-800">{{ file }}</a>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
<button @click="deleteFiles('output')" class="mt-4 bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded transition duration-300 ease-in-out" x-bind:disabled="selectedOutputFiles.length === 0">
|
|
Delete Selected Output Files
|
|
</button>
|
|
{% else %}
|
|
<p class="text-gray-600">No converted files yet. Upload a .fit file to get started!</p>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|