Enhance Map Zoom Control and Improve Map Page Layout
Some checks failed
build.yaml / Enhance Map Zoom Control and Improve Map Page Layout (push) Failing after 0s
Some checks failed
build.yaml / Enhance Map Zoom Control and Improve Map Page Layout (push) Failing after 0s
- Refactored zoom control component for better accessibility and styling. - Added hover effects and improved button states for zoom in/out buttons. - Updated map page layout with enhanced dataset card design and responsive styles. - Introduced empty state for no datasets found and improved results header. - Added icons for dataset cards and improved author display.
This commit is contained in:
parent
88e37bfee8
commit
4229001572
7 changed files with 1520 additions and 452 deletions
|
|
@ -1,40 +1,15 @@
|
|||
<script setup lang="ts">
|
||||
import { Head } from '@inertiajs/vue3';
|
||||
import { ref, Ref } from 'vue';
|
||||
import { mdiChartTimelineVariant, mdiGithub } from '@mdi/js';
|
||||
import { mdiChartTimelineVariant, mdiGithub, mdiMapMarker, mdiCalendar, mdiLockOpenVariant } from '@mdi/js';
|
||||
import LayoutAuthenticated from '@/Layouts/LayoutAuthenticated.vue';
|
||||
import SectionMain from '@/Components/SectionMain.vue';
|
||||
import BaseButton from '@/Components/BaseButton.vue';
|
||||
import SectionTitleLineWithButton from '@/Components/SectionTitleLineWithButton.vue';
|
||||
import { MapOptions } from '@/Components/Map/MapOptions';
|
||||
// import { stardust } from '@eidellev/adonis-stardust/client';
|
||||
import SearchMap from '@/Components/Map/SearchMap.vue';
|
||||
import { OpensearchDocument } from '@/Dataset';
|
||||
|
||||
// const fitBounds: LatLngBoundsExpression = [
|
||||
// [46.4318173285, 9.47996951665],
|
||||
// [49.0390742051, 16.9796667823],
|
||||
// ];
|
||||
|
||||
// const mapId = 'map';
|
||||
|
||||
// const coverage = {
|
||||
// x_min: undefined,
|
||||
// y_min: undefined,
|
||||
// x_max: undefined,
|
||||
// y_max: undefined,
|
||||
// elevation_min: undefined,
|
||||
// elevation_max: undefined,
|
||||
// elevation_absolut: undefined,
|
||||
// depth_min: undefined,
|
||||
// depth_max: undefined,
|
||||
// depth_absolut: undefined,
|
||||
// time_min: undefined,
|
||||
// time_max: undefined,
|
||||
// time_absolut: undefined,
|
||||
// };
|
||||
|
||||
// Replace with your actual data
|
||||
const datasets: Ref<OpensearchDocument[]> = ref([]);
|
||||
const openAccessLicences: Array<string> = ['CC-BY-4.0', 'CC-BY-SA-4.0'];
|
||||
|
||||
|
|
@ -48,58 +23,499 @@ const mapOptions: MapOptions = {
|
|||
|
||||
<template>
|
||||
<LayoutAuthenticated :showAsideMenu="false">
|
||||
|
||||
<Head title="Map" />
|
||||
|
||||
<!-- <section class="p-6" v-bind:class="containerMaxW"> -->
|
||||
<SectionMain>
|
||||
<SectionTitleLineWithButton v-bind:icon="mdiChartTimelineVariant" title="Tethys Map" main>
|
||||
<BaseButton href="https://gitea.geosphere.at/geolba/tethys" target="_blank" :icon="mdiGithub"
|
||||
label="Star on GeoSPhere Forgejo" color="contrast" rounded-full small />
|
||||
<!-- <BaseButton :route-name="stardust.route('app.login.show')" label="Login" color="white" rounded-full small /> -->
|
||||
<BaseButton
|
||||
href="https://gitea.geosphere.at/geolba/tethys"
|
||||
target="_blank"
|
||||
:icon="mdiGithub"
|
||||
label="Star on GeoSphere Forgejo"
|
||||
color="contrast"
|
||||
rounded-full
|
||||
small
|
||||
/>
|
||||
</SectionTitleLineWithButton>
|
||||
|
||||
<!-- <SectionBannerStarOnGitea /> -->
|
||||
<!-- Map Component with enhanced styling -->
|
||||
<div class="map-wrapper">
|
||||
<SearchMap :datasets="datasets" :map-options="mapOptions"></SearchMap>
|
||||
</div>
|
||||
|
||||
<!-- <CardBox> -->
|
||||
<!-- <div id="map" class="map-container mapDesktop mt-6 mb-6 rounded-2xl py-12 px-6 text-center">
|
||||
<DrawControlComponent ref="draw" :preserve="false" :mapId="mapId" :southWest="southWest"
|
||||
:northEast="northEast">
|
||||
</DrawControlComponent>
|
||||
</div> -->
|
||||
<SearchMap :datasets="datasets" :map-options="mapOptions"></SearchMap>
|
||||
<!-- Results Header -->
|
||||
<div v-if="datasets.length > 0" class="results-header">
|
||||
<h2 class="results-title">
|
||||
<span class="results-count">{{ datasets.length }}</span>
|
||||
{{ datasets.length === 1 ? 'Dataset' : 'Datasets' }} Found
|
||||
</h2>
|
||||
<p class="results-subtitle">Click on any card to view details</p>
|
||||
</div>
|
||||
|
||||
<div d="search-result-list-wrapper" class="flex flex-wrap col-span-24 h-full">
|
||||
<div v-for="dataset in datasets" :key="dataset.id" class="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 p-4">
|
||||
<div class="bg-white rounded shadow p-6">
|
||||
<h3 class="text-lg leading-tight text-gray-500 dark:text-slate-400">
|
||||
<!-- Enhanced Results Grid -->
|
||||
<div class="results-grid">
|
||||
<div
|
||||
v-for="(dataset, index) in datasets"
|
||||
:key="dataset.id"
|
||||
class="dataset-card"
|
||||
:style="{ animationDelay: `${index * 50}ms` }"
|
||||
>
|
||||
<!-- Card Header with Icon -->
|
||||
<div class="card-header">
|
||||
<div class="card-icon">
|
||||
<svg class="icon" viewBox="0 0 24 24">
|
||||
<path :d="mdiMapMarker" />
|
||||
</svg>
|
||||
</div>
|
||||
<span class="card-type">{{ dataset.doctype }}</span>
|
||||
</div>
|
||||
|
||||
<!-- Card Content -->
|
||||
<div class="card-content">
|
||||
<h3 class="card-title">
|
||||
{{ dataset.title_output }}
|
||||
</h3>
|
||||
<!-- <h2 class="text-xl font-bold mb-2">{{ dataset.title_output }}</h2> -->
|
||||
<p class="text-gray-700 mb-2">{{ dataset.abstract_output }}</p>
|
||||
<div class="text-sm text-gray-600">
|
||||
<div v-for="author in dataset.author" :key="author" class="mb-1">{{ author }}</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<span
|
||||
class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">
|
||||
{{ dataset.year }}
|
||||
</span>
|
||||
<span
|
||||
class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">
|
||||
{{ dataset.language }}
|
||||
</span>
|
||||
</div>
|
||||
<p>
|
||||
<span class="label"><i class="fas fa-file"></i> {{ dataset.doctype }}</span>
|
||||
<!-- <span>Licence: {{ document.licence }}</span> -->
|
||||
<span v-if="openAccessLicences.includes(dataset.licence)" class="label titlecase"><i
|
||||
class="fas fa-lock-open"></i> Open Access</span>
|
||||
<p class="card-abstract">
|
||||
{{ dataset.abstract_output }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Authors Section -->
|
||||
<div v-if="dataset.author && dataset.author.length > 0" class="card-authors">
|
||||
<div class="author-label">Authors:</div>
|
||||
<div class="author-list">
|
||||
<span v-for="(author, idx) in dataset.author.slice(0, 3)" :key="idx" class="author-tag">
|
||||
{{ author }}
|
||||
</span>
|
||||
<span v-if="dataset.author.length > 3" class="author-more"> +{{ dataset.author.length - 3 }} more </span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card Footer with Metadata -->
|
||||
<div class="card-footer">
|
||||
<div class="metadata-tags">
|
||||
<span class="tag tag-year">
|
||||
<svg class="tag-icon" viewBox="0 0 24 24">
|
||||
<path :d="mdiCalendar" />
|
||||
</svg>
|
||||
{{ dataset.year }}
|
||||
</span>
|
||||
<span class="tag tag-language">
|
||||
{{ dataset.language?.toUpperCase() }}
|
||||
</span>
|
||||
<span v-if="openAccessLicences.includes(dataset.licence)" class="tag tag-open-access">
|
||||
<svg class="tag-icon" viewBox="0 0 24 24">
|
||||
<path :d="mdiLockOpenVariant" />
|
||||
</svg>
|
||||
Open Access
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hover Effect Overlay -->
|
||||
<div class="card-overlay"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Empty State -->
|
||||
<div v-if="datasets.length === 0" class="empty-state">
|
||||
<div class="empty-icon">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" />
|
||||
<circle cx="12" cy="10" r="3" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="empty-title">No datasets selected</h3>
|
||||
<p class="empty-description">Draw a rectangle on the map to search for datasets in that area</p>
|
||||
</div>
|
||||
</SectionMain>
|
||||
<!-- </section> -->
|
||||
</LayoutAuthenticated>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Map Wrapper */
|
||||
.map-wrapper {
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
position: relative;
|
||||
border-radius: 1rem;
|
||||
overflow: hidden;
|
||||
box-shadow:
|
||||
0 4px 6px -1px rgba(0, 0, 0, 0.1),
|
||||
0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
transition: box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.map-wrapper:hover {
|
||||
box-shadow:
|
||||
0 10px 15px -3px rgba(0, 0, 0, 0.1),
|
||||
0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
/* Results Header */
|
||||
.results-header {
|
||||
margin-bottom: 1.5rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 2px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.dark .results-header {
|
||||
border-bottom-color: #374151;
|
||||
}
|
||||
|
||||
.results-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
color: #1f2937;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.dark .results-title {
|
||||
color: #f9fafb;
|
||||
}
|
||||
|
||||
.results-count {
|
||||
display: inline-block;
|
||||
padding: 0.25rem 0.75rem;
|
||||
background: linear-gradient(135deg, #65dc21 0%, #357c06 100%);
|
||||
color: white;
|
||||
border-radius: 0.5rem;
|
||||
font-size: 1.25rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.results-subtitle {
|
||||
color: #6b7280;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.dark .results-subtitle {
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
/* Results Grid */
|
||||
.results-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
/* Dataset Card */
|
||||
.dataset-card {
|
||||
background: white;
|
||||
border-radius: 1rem;
|
||||
overflow: hidden;
|
||||
box-shadow:
|
||||
0 1px 3px 0 rgba(0, 0, 0, 0.1),
|
||||
0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
animation: fadeInUp 0.5s ease-out forwards;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.dark .dataset-card {
|
||||
background: #1f2937;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.dataset-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow:
|
||||
0 20px 25px -5px rgba(0, 0, 0, 0.1),
|
||||
0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.dark .dataset-card:hover {
|
||||
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
/* Card Header */
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 1rem 1.5rem;
|
||||
background: linear-gradient(135deg, #65dc21 0%, #357c06 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.card-type {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
/* Card Content */
|
||||
.card-content {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
color: #1f2937;
|
||||
margin-bottom: 0.75rem;
|
||||
line-height: 1.4;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dark .card-title {
|
||||
color: #f9fafb;
|
||||
}
|
||||
|
||||
.card-abstract {
|
||||
color: #6b7280;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.6;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dark .card-abstract {
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
/* Authors Section */
|
||||
.card-authors {
|
||||
padding: 0 1.5rem 1rem;
|
||||
border-top: 1px solid #f3f4f6;
|
||||
}
|
||||
|
||||
.dark .card-authors {
|
||||
border-top-color: #374151;
|
||||
}
|
||||
|
||||
.author-label {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
color: #6b7280;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.dark .author-label {
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
.author-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.author-tag {
|
||||
font-size: 0.75rem;
|
||||
color: #4b5563;
|
||||
background: #f3f4f6;
|
||||
padding: 0.25rem 0.625rem;
|
||||
border-radius: 0.375rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.dark .author-tag {
|
||||
color: #d1d5db;
|
||||
background: #374151;
|
||||
}
|
||||
|
||||
.author-more {
|
||||
font-size: 0.75rem;
|
||||
color: #6b7280;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.dark .author-more {
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
/* Card Footer */
|
||||
.card-footer {
|
||||
padding: 1rem 1.5rem;
|
||||
background: #f9fafb;
|
||||
border-top: 1px solid #f3f4f6;
|
||||
}
|
||||
|
||||
.dark .card-footer {
|
||||
background: #111827;
|
||||
border-top-color: #374151;
|
||||
}
|
||||
|
||||
.metadata-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
padding: 0.375rem 0.75rem;
|
||||
border-radius: 9999px;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.tag:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.tag-icon {
|
||||
width: 0.875rem;
|
||||
height: 0.875rem;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.tag-year {
|
||||
background: #dbeafe;
|
||||
color: #1e40af;
|
||||
}
|
||||
|
||||
.dark .tag-year {
|
||||
background: #1e3a8a;
|
||||
color: #93c5fd;
|
||||
}
|
||||
|
||||
.tag-language {
|
||||
background: #fce7f3;
|
||||
color: #9f1239;
|
||||
}
|
||||
|
||||
.dark .tag-language {
|
||||
background: #831843;
|
||||
color: #fbcfe8;
|
||||
}
|
||||
|
||||
.tag-open-access {
|
||||
background: #d1fae5;
|
||||
color: #065f46;
|
||||
}
|
||||
|
||||
.dark .tag-open-access {
|
||||
background: #064e3b;
|
||||
color: #6ee7b7;
|
||||
}
|
||||
|
||||
/* Card Overlay */
|
||||
.card-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(135deg, rgba(101, 220, 33, 0.1) 0%, rgba(53, 124, 6, 0.1) 100%);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.dataset-card:hover .card-overlay {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Empty State */
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 4rem 2rem;
|
||||
background: white;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.dark .empty-state {
|
||||
background: #1f2937;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
margin: 0 auto 1.5rem;
|
||||
color: #d1d5db;
|
||||
}
|
||||
|
||||
.dark .empty-icon {
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.empty-icon svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.empty-title {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: #1f2937;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.dark .empty-title {
|
||||
color: #f9fafb;
|
||||
}
|
||||
|
||||
.empty-description {
|
||||
color: #6b7280;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.dark .empty-description {
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 640px) {
|
||||
.results-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.results-title {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue