Modified the UI layout

This commit is contained in:
Atharva Sawant
2024-12-01 11:18:45 +05:30
parent c5f2496f8b
commit 40866642c3
4 changed files with 73 additions and 103 deletions

View File

@@ -2,7 +2,6 @@
<div id="app" class="h-screen flex flex-col"> <div id="app" class="h-screen flex flex-col">
<header class="bg-blue-600 text-white p-4 flex-shrink-0"> <header class="bg-blue-600 text-white p-4 flex-shrink-0">
<h1 class="text-2xl font-bold">TrackMap</h1> <h1 class="text-2xl font-bold">TrackMap</h1>
<p class="text-blue-100">Analyze your cycling tracks</p>
</header> </header>
<div class="flex flex-1 overflow-hidden"> <div class="flex flex-1 overflow-hidden">
@@ -11,70 +10,69 @@
:tracks="tracks" :tracks="tracks"
:selectedTrackIndex="selectedTrackIndex" :selectedTrackIndex="selectedTrackIndex"
@track-selected="handleTrackSelected" @track-selected="handleTrackSelected"
@files-uploaded="handleFilesUploaded"
/> />
<!-- Main Content --> <!-- Main Content -->
<div class="flex-1 flex flex-col overflow-hidden"> <div class="flex-1 flex flex-col overflow-hidden">
<!-- Map --> <!-- Map - takes full space when no tracks, or flexible space when tracks exist -->
<div class="flex-1 p-4"> <div :class="tracks.length > 0 ? 'flex-1' : 'flex-1'" class="p-4">
<MapView :tracks="tracks" :selectedTrackIndex="selectedTrackIndex" /> <MapView :tracks="tracks" :selectedTrackIndex="selectedTrackIndex" />
</div> </div>
<!-- Upload Area --> <!-- Statistics Section - only shows when tracks exist -->
<div class="p-4 border-t border-gray-200 bg-gray-50"> <div v-if="tracks.length > 0" class="border-t border-gray-200 bg-white">
<FileUpload @files-uploaded="handleFilesUploaded" /> <!-- Selected Track Details -->
</div> <div v-if="selectedTrack" class="p-4">
<h3 class="text-lg font-medium mb-3">{{ selectedTrack.name }}</h3>
<!-- Selected Track Details --> <div class="grid grid-cols-2 md:grid-cols-5 gap-4">
<div v-if="selectedTrack" class="p-4 border-t border-gray-200 bg-white"> <div class="text-center">
<h3 class="text-lg font-medium mb-3">{{ selectedTrack.name }}</h3> <div class="text-xl font-bold text-blue-600">{{ formatDistance(selectedTrack.stats?.distance || 0) }}</div>
<div class="grid grid-cols-2 md:grid-cols-5 gap-4"> <div class="text-sm text-gray-600">Distance</div>
<div class="text-center"> </div>
<div class="text-xl font-bold text-blue-600">{{ formatDistance(selectedTrack.stats?.distance || 0) }}</div> <div class="text-center">
<div class="text-sm text-gray-600">Distance</div> <div class="text-xl font-bold text-green-600">{{ formatDuration(selectedTrack.stats?.duration || 0) }}</div>
</div> <div class="text-sm text-gray-600">Duration</div>
<div class="text-center"> </div>
<div class="text-xl font-bold text-green-600">{{ formatDuration(selectedTrack.stats?.duration || 0) }}</div> <div class="text-center">
<div class="text-sm text-gray-600">Duration</div> <div class="text-xl font-bold text-orange-600">{{ selectedTrack.stats?.avgSpeed || 0 }} km/h</div>
</div> <div class="text-sm text-gray-600">Avg Speed</div>
<div class="text-center"> </div>
<div class="text-xl font-bold text-orange-600">{{ selectedTrack.stats?.avgSpeed || 0 }} km/h</div> <div class="text-center">
<div class="text-sm text-gray-600">Avg Speed</div> <div class="text-xl font-bold text-red-600">{{ selectedTrack.stats?.elevationGain || 0 }}m</div>
</div> <div class="text-sm text-gray-600">Elevation Gain</div>
<div class="text-center"> </div>
<div class="text-xl font-bold text-red-600">{{ selectedTrack.stats?.elevationGain || 0 }}m</div> <div class="text-center">
<div class="text-sm text-gray-600">Elevation Gain</div> <div class="text-xl font-bold text-purple-600">{{ formatDate(selectedTrack.stats?.startTime) }}</div>
</div> <div class="text-sm text-gray-600">Date</div>
<div class="text-center"> </div>
<div class="text-xl font-bold text-purple-600">{{ formatDate(selectedTrack.stats?.startTime) }}</div>
<div class="text-sm text-gray-600">Date</div>
</div> </div>
</div> </div>
</div>
<!-- Total Statistics -->
<!-- Total Statistics --> <div v-else class="p-4">
<div v-else-if="tracks.length > 0" class="p-4 border-t border-gray-200 bg-white"> <h3 class="text-lg font-medium mb-3">Total Statistics</h3>
<h3 class="text-lg font-medium mb-3">Total Statistics</h3> <div class="grid grid-cols-2 md:grid-cols-5 gap-4">
<div class="grid grid-cols-2 md:grid-cols-5 gap-4"> <div class="text-center">
<div class="text-center"> <div class="text-xl font-bold text-blue-600">{{ totalStats.totalTracks }}</div>
<div class="text-xl font-bold text-blue-600">{{ totalStats.totalTracks }}</div> <div class="text-sm text-gray-600">Total Tracks</div>
<div class="text-sm text-gray-600">Total Tracks</div> </div>
</div> <div class="text-center">
<div class="text-center"> <div class="text-xl font-bold text-green-600">{{ totalStats.totalDistance }}</div>
<div class="text-xl font-bold text-green-600">{{ totalStats.totalDistance }}</div> <div class="text-sm text-gray-600">Total Distance (km)</div>
<div class="text-sm text-gray-600">Total Distance (km)</div> </div>
</div> <div class="text-center">
<div class="text-center"> <div class="text-xl font-bold text-purple-600">{{ totalStats.totalDuration }}</div>
<div class="text-xl font-bold text-purple-600">{{ totalStats.totalDuration }}</div> <div class="text-sm text-gray-600">Total Hours</div>
<div class="text-sm text-gray-600">Total Hours</div> </div>
</div> <div class="text-center">
<div class="text-center"> <div class="text-xl font-bold text-orange-600">{{ totalStats.avgSpeed }}</div>
<div class="text-xl font-bold text-orange-600">{{ totalStats.avgSpeed }}</div> <div class="text-sm text-gray-600">Avg Speed (km/h)</div>
<div class="text-sm text-gray-600">Avg Speed (km/h)</div> </div>
</div> <div class="text-center">
<div class="text-center"> <div class="text-xl font-bold text-red-600">{{ totalStats.totalElevationGain }}</div>
<div class="text-xl font-bold text-red-600">{{ totalStats.totalElevationGain }}</div> <div class="text-sm text-gray-600">Elevation Gain (m)</div>
<div class="text-sm text-gray-600">Elevation Gain (m)</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,24 +1,11 @@
<template> <template>
<div class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center hover:border-blue-400 transition-colors"> <div class="flex items-center justify-center">
<div <button
@drop.prevent="handleDrop"
@dragover.prevent
@dragenter.prevent
class="cursor-pointer"
@click="$refs.fileInput.click()" @click="$refs.fileInput.click()"
class="bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-lg transition-colors"
> >
<div class="mb-4"> Upload GPX Files
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"> </button>
<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 <input
ref="fileInput" ref="fileInput"
@@ -30,25 +17,8 @@
/> />
<!-- File list --> <!-- File list -->
<div v-if="uploadedFiles.length > 0" class="mt-6 text-left"> <div v-if="uploadedFiles.length > 0" class="ml-4 text-sm text-gray-600">
<h3 class="font-medium text-gray-900 mb-3">Uploaded Files:</h3> {{ uploadedFiles.length }} file{{ uploadedFiles.length > 1 ? 's' : '' }} uploaded
<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>
</div> </div>
</template> </template>
@@ -62,13 +32,6 @@ export default {
setup(props, { emit }) { setup(props, { emit }) {
const uploadedFiles = ref([]) 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 handleFileSelect = (event) => {
const files = Array.from(event.target.files) const files = Array.from(event.target.files)
processFiles(files) processFiles(files)
@@ -83,7 +46,6 @@ export default {
return { return {
uploadedFiles, uploadedFiles,
handleDrop,
handleFileSelect handleFileSelect
} }
} }

View File

@@ -1,5 +1,5 @@
<template> <template>
<div id="map" class="w-full h-96 rounded-lg shadow-md"></div> <div id="map" class="w-full h-full rounded-lg shadow-md"></div>
</template> </template>
<script> <script>

View File

@@ -64,12 +64,22 @@
</div> </div>
</div> </div>
</div> </div>
<!-- Sticky Upload Button at Bottom -->
<div class="p-4 border-t border-gray-200 bg-white">
<FileUpload @files-uploaded="$emit('files-uploaded', $event)" />
</div>
</div> </div>
</template> </template>
<script> <script>
import FileUpload from './FileUpload.vue'
export default { export default {
name: 'TrackList', name: 'TrackList',
components: {
FileUpload
},
props: { props: {
tracks: { tracks: {
type: Array, type: Array,
@@ -80,7 +90,7 @@ export default {
default: null default: null
} }
}, },
emits: ['track-selected'], emits: ['track-selected', 'files-uploaded'],
methods: { methods: {
selectTrack(index) { selectTrack(index) {
this.$emit('track-selected', index) this.$emit('track-selected', index)