Added file upload support for GPX files
This commit is contained in:
14
src/App.vue
14
src/App.vue
@@ -11,8 +11,8 @@
|
|||||||
<MapView />
|
<MapView />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-center py-8 text-gray-500">
|
<div class="mb-6">
|
||||||
<p>Upload GPX files to see your tracks on the map</p>
|
<FileUpload @files-uploaded="handleFilesUploaded" />
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
@@ -20,11 +20,19 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MapView from './components/MapView.vue'
|
import MapView from './components/MapView.vue'
|
||||||
|
import FileUpload from './components/FileUpload.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
components: {
|
||||||
MapView
|
MapView,
|
||||||
|
FileUpload
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleFilesUploaded(files) {
|
||||||
|
console.log('Files uploaded:', files)
|
||||||
|
// TODO: Parse GPX files and display on map
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
91
src/components/FileUpload.vue
Normal file
91
src/components/FileUpload.vue
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<template>
|
||||||
|
<div class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center hover:border-blue-400 transition-colors">
|
||||||
|
<div
|
||||||
|
@drop.prevent="handleDrop"
|
||||||
|
@dragover.prevent
|
||||||
|
@dragenter.prevent
|
||||||
|
class="cursor-pointer"
|
||||||
|
@click="$refs.fileInput.click()"
|
||||||
|
>
|
||||||
|
<div class="mb-4">
|
||||||
|
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="text-lg font-medium text-gray-900 mb-2">
|
||||||
|
Drop GPX files here or click to browse
|
||||||
|
</div>
|
||||||
|
<div class="text-sm text-gray-500">
|
||||||
|
Upload your cycling tracks to visualize them on the map
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input
|
||||||
|
ref="fileInput"
|
||||||
|
type="file"
|
||||||
|
multiple
|
||||||
|
accept=".gpx"
|
||||||
|
class="hidden"
|
||||||
|
@change="handleFileSelect"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- File list -->
|
||||||
|
<div v-if="uploadedFiles.length > 0" class="mt-6 text-left">
|
||||||
|
<h3 class="font-medium text-gray-900 mb-3">Uploaded Files:</h3>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<div
|
||||||
|
v-for="file in uploadedFiles"
|
||||||
|
:key="file.name"
|
||||||
|
class="flex items-center justify-between p-3 bg-gray-50 rounded-lg"
|
||||||
|
>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<svg class="h-5 w-5 text-green-500 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
|
</svg>
|
||||||
|
<span class="text-sm font-medium">{{ file.name }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="text-xs text-gray-500">
|
||||||
|
{{ (file.size / 1024).toFixed(1) }} KB
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FileUpload',
|
||||||
|
emits: ['files-uploaded'],
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const uploadedFiles = ref([])
|
||||||
|
|
||||||
|
const handleDrop = (event) => {
|
||||||
|
const files = Array.from(event.dataTransfer.files).filter(file =>
|
||||||
|
file.name.toLowerCase().endsWith('.gpx')
|
||||||
|
)
|
||||||
|
processFiles(files)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFileSelect = (event) => {
|
||||||
|
const files = Array.from(event.target.files)
|
||||||
|
processFiles(files)
|
||||||
|
}
|
||||||
|
|
||||||
|
const processFiles = (files) => {
|
||||||
|
if (files.length === 0) return
|
||||||
|
|
||||||
|
uploadedFiles.value = [...uploadedFiles.value, ...files]
|
||||||
|
emit('files-uploaded', files)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
uploadedFiles,
|
||||||
|
handleDrop,
|
||||||
|
handleFileSelect
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user