ui:big ui update
refreshed the ui by making the map full screen and adding the finds as a side-sheet on top of the map.
This commit is contained in:
@@ -161,16 +161,8 @@
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.find-card {
|
.find-card {
|
||||||
background: white;
|
backdrop-filter: blur(10px);
|
||||||
border: 1px solid hsl(var(--border));
|
|
||||||
border-radius: 12px;
|
|
||||||
overflow: hidden;
|
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
transition: box-shadow 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.find-card:hover {
|
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Post Header */
|
/* Post Header */
|
||||||
|
|||||||
@@ -28,8 +28,7 @@
|
|||||||
.app-header {
|
.app-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 10;
|
z-index: 100;
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-content {
|
.header-content {
|
||||||
@@ -38,7 +37,6 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 16px 20px;
|
padding: 16px 20px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
max-width: 1200px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-container {
|
.profile-container {
|
||||||
|
|||||||
@@ -1,297 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { toast } from 'svelte-sonner';
|
|
||||||
import {
|
|
||||||
locationActions,
|
|
||||||
locationStatus,
|
|
||||||
locationError,
|
|
||||||
isLocationLoading,
|
|
||||||
isWatching
|
|
||||||
} from '$lib/stores/location';
|
|
||||||
import { Skeleton } from './skeleton';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
class?: string;
|
|
||||||
variant?: 'primary' | 'secondary' | 'icon';
|
|
||||||
size?: 'small' | 'medium' | 'large';
|
|
||||||
showLabel?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
let {
|
|
||||||
class: className = '',
|
|
||||||
variant = 'primary',
|
|
||||||
size = 'medium',
|
|
||||||
showLabel = true
|
|
||||||
}: Props = $props();
|
|
||||||
|
|
||||||
// Track if location watching is active from the derived store
|
|
||||||
|
|
||||||
async function handleLocationClick() {
|
|
||||||
if ($isWatching) {
|
|
||||||
// Stop watching if currently active
|
|
||||||
locationActions.stopWatching();
|
|
||||||
toast.success('Location watching stopped');
|
|
||||||
} else {
|
|
||||||
// Try to get current location first, then start watching
|
|
||||||
const result = await locationActions.getCurrentLocation({
|
|
||||||
enableHighAccuracy: true,
|
|
||||||
timeout: 15000,
|
|
||||||
maximumAge: 300000
|
|
||||||
});
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
// Start watching for continuous updates
|
|
||||||
locationActions.startWatching({
|
|
||||||
enableHighAccuracy: true,
|
|
||||||
timeout: 15000,
|
|
||||||
maximumAge: 60000 // Update every minute
|
|
||||||
});
|
|
||||||
toast.success('Location watching started');
|
|
||||||
} else if ($locationError) {
|
|
||||||
toast.error($locationError.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const buttonText = $derived(() => {
|
|
||||||
if ($isLocationLoading) return 'Finding location...';
|
|
||||||
if ($isWatching) return 'Stop watching location';
|
|
||||||
if ($locationStatus === 'success') return 'Watch location';
|
|
||||||
return 'Find my location';
|
|
||||||
});
|
|
||||||
|
|
||||||
const iconClass = $derived(() => {
|
|
||||||
if ($isLocationLoading) return 'loading';
|
|
||||||
if ($isWatching) return 'watching';
|
|
||||||
if ($locationStatus === 'success') return 'success';
|
|
||||||
if ($locationStatus === 'error') return 'error';
|
|
||||||
return 'default';
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="location-button {variant} {size} {className}"
|
|
||||||
onclick={handleLocationClick}
|
|
||||||
disabled={$isLocationLoading}
|
|
||||||
title={buttonText()}
|
|
||||||
>
|
|
||||||
<span class="icon {iconClass()}">
|
|
||||||
{#if $isLocationLoading}
|
|
||||||
<div class="loading-skeleton">
|
|
||||||
<Skeleton class="h-5 w-5 rounded-full" />
|
|
||||||
</div>
|
|
||||||
{:else if $isWatching}
|
|
||||||
<svg viewBox="0 0 24 24" class="watching-icon">
|
|
||||||
<path
|
|
||||||
d="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z"
|
|
||||||
/>
|
|
||||||
<circle
|
|
||||||
cx="12"
|
|
||||||
cy="9"
|
|
||||||
r="15"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="1"
|
|
||||||
fill="none"
|
|
||||||
opacity="0.3"
|
|
||||||
class="pulse-ring"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
{:else if $locationStatus === 'success'}
|
|
||||||
<svg viewBox="0 0 24 24">
|
|
||||||
<path
|
|
||||||
d="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
{:else if $locationStatus === 'error'}
|
|
||||||
<svg viewBox="0 0 24 24">
|
|
||||||
<path
|
|
||||||
d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
{:else}
|
|
||||||
<svg viewBox="0 0 24 24">
|
|
||||||
<path
|
|
||||||
d="M12,8A4,4 0 0,1 16,12A4,4 0 0,1 12,16A4,4 0 0,1 8,12A4,4 0 0,1 12,8M3.05,13H1V11H3.05C3.5,6.83 6.83,3.5 11,3.05V1H13V3.05C17.17,3.5 20.5,6.83 20.95,11H23V13H20.95C20.5,17.17 17.17,20.5 13,20.95V23H11V20.95C6.83,20.5 3.5,17.17 3.05,13M12,5A7,7 0 0,0 5,12A7,7 0 0,0 12,19A7,7 0 0,0 19,12A7,7 0 0,0 12,5Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
{/if}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
{#if showLabel && variant !== 'icon'}
|
|
||||||
<span class="label">{buttonText()}</span>
|
|
||||||
{/if}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.location-button {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-family: inherit;
|
|
||||||
font-weight: 500;
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.location-button:disabled {
|
|
||||||
cursor: not-allowed;
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Variants */
|
|
||||||
.primary {
|
|
||||||
background: #2563eb;
|
|
||||||
color: white;
|
|
||||||
box-shadow: 0 2px 4px rgba(37, 99, 235, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.primary:hover:not(:disabled) {
|
|
||||||
background: #1d4ed8;
|
|
||||||
transform: translateY(-1px);
|
|
||||||
box-shadow: 0 4px 8px rgba(37, 99, 235, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.secondary {
|
|
||||||
background: white;
|
|
||||||
color: #374151;
|
|
||||||
border: 1px solid #d1d5db;
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.secondary:hover:not(:disabled) {
|
|
||||||
background: #f9fafb;
|
|
||||||
border-color: #9ca3af;
|
|
||||||
transform: translateY(-1px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
background: transparent;
|
|
||||||
color: #6b7280;
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: 1px solid #d1d5db;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon:hover:not(:disabled) {
|
|
||||||
background: #f3f4f6;
|
|
||||||
color: #374151;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sizes */
|
|
||||||
.small {
|
|
||||||
padding: 6px 12px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.small.icon {
|
|
||||||
padding: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.medium {
|
|
||||||
padding: 8px 16px;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.medium.icon {
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.large {
|
|
||||||
padding: 12px 20px;
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.large.icon {
|
|
||||||
padding: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Icon styles */
|
|
||||||
.icon svg {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
fill: currentColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
.small .icon svg {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.large .icon svg {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading-skeleton {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon.success svg {
|
|
||||||
color: #10b981;
|
|
||||||
fill: #10b981;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon.watching svg {
|
|
||||||
color: #f59e0b;
|
|
||||||
fill: #f59e0b;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon.error svg {
|
|
||||||
color: #ef4444;
|
|
||||||
fill: #ef4444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spin {
|
|
||||||
animation: spin 1s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
from {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.watching-icon .pulse-ring {
|
|
||||||
animation: pulse-ring 2s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes pulse-ring {
|
|
||||||
0% {
|
|
||||||
transform: scale(0.5);
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: scale(1);
|
|
||||||
opacity: 0.3;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: scale(1.5);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Responsive adjustments */
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
.location-button .label {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.location-button {
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
locationActions,
|
locationActions,
|
||||||
isWatching
|
isWatching
|
||||||
} from '$lib/stores/location';
|
} from '$lib/stores/location';
|
||||||
import LocationButton from './LocationButton.svelte';
|
|
||||||
import { Skeleton } from '$lib/components/skeleton';
|
import { Skeleton } from '$lib/components/skeleton';
|
||||||
|
|
||||||
interface Find {
|
interface Find {
|
||||||
@@ -39,7 +38,6 @@
|
|||||||
center?: [number, number];
|
center?: [number, number];
|
||||||
zoom?: number;
|
zoom?: number;
|
||||||
class?: string;
|
class?: string;
|
||||||
showLocationButton?: boolean;
|
|
||||||
autoCenter?: boolean;
|
autoCenter?: boolean;
|
||||||
finds?: Find[];
|
finds?: Find[];
|
||||||
onFindClick?: (find: Find) => void;
|
onFindClick?: (find: Find) => void;
|
||||||
@@ -67,7 +65,6 @@
|
|||||||
center,
|
center,
|
||||||
zoom,
|
zoom,
|
||||||
class: className = '',
|
class: className = '',
|
||||||
showLocationButton = true,
|
|
||||||
autoCenter = true,
|
autoCenter = true,
|
||||||
finds = [],
|
finds = [],
|
||||||
onFindClick
|
onFindClick
|
||||||
@@ -179,12 +176,6 @@
|
|||||||
</Marker>
|
</Marker>
|
||||||
{/each}
|
{/each}
|
||||||
</MapLibre>
|
</MapLibre>
|
||||||
|
|
||||||
{#if showLocationButton}
|
|
||||||
<div class="location-controls">
|
|
||||||
<LocationButton variant="icon" size="medium" showLabel={false} />
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -219,17 +210,9 @@
|
|||||||
|
|
||||||
.map-container :global(.maplibregl-map) {
|
.map-container :global(.maplibregl-map) {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
|
||||||
border-radius: 12px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.location-controls {
|
|
||||||
position: absolute;
|
|
||||||
top: 12px;
|
|
||||||
right: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Location marker styles */
|
/* Location marker styles */
|
||||||
:global(.location-marker) {
|
:global(.location-marker) {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
|
|||||||
@@ -163,6 +163,7 @@
|
|||||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
|
||||||
background: white;
|
background: white;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal.dropdown {
|
.modal.dropdown {
|
||||||
@@ -171,11 +172,12 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
max-width: 320px;
|
max-width: 320px;
|
||||||
width: 320px;
|
width: 320px;
|
||||||
z-index: 1000;
|
z-index: 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal::backdrop {
|
.modal::backdrop {
|
||||||
background: rgba(0, 0, 0, 0.1);
|
background: rgba(0, 0, 0, 0.1);
|
||||||
|
z-index: 9998;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-content {
|
.modal-content {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts" module>
|
<script lang="ts" module>
|
||||||
import { tv, type VariantProps } from 'tailwind-variants';
|
import { tv, type VariantProps } from 'tailwind-variants';
|
||||||
export const sheetVariants = tv({
|
export const sheetVariants = tv({
|
||||||
base: 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
|
base: 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-[9999] flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
|
||||||
variants: {
|
variants: {
|
||||||
side: {
|
side: {
|
||||||
top: 'data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b',
|
top: 'data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b',
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
bind:ref
|
bind:ref
|
||||||
data-slot="sheet-overlay"
|
data-slot="sheet-overlay"
|
||||||
class={cn(
|
class={cn(
|
||||||
'fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0',
|
'fixed inset-0 z-[9998] bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ export { default as ProfilePictureSheet } from './components/ProfilePictureSheet
|
|||||||
export { default as Header } from './components/Header.svelte';
|
export { default as Header } from './components/Header.svelte';
|
||||||
export { default as Modal } from './components/Modal.svelte';
|
export { default as Modal } from './components/Modal.svelte';
|
||||||
export { default as Map } from './components/Map.svelte';
|
export { default as Map } from './components/Map.svelte';
|
||||||
export { default as LocationButton } from './components/LocationButton.svelte';
|
|
||||||
export { default as LocationManager } from './components/LocationManager.svelte';
|
export { default as LocationManager } from './components/LocationManager.svelte';
|
||||||
export { default as NotificationManager } from './components/NotificationManager.svelte';
|
export { default as NotificationManager } from './components/NotificationManager.svelte';
|
||||||
export { default as NotificationPrompt } from './components/NotificationPrompt.svelte';
|
export { default as NotificationPrompt } from './components/NotificationPrompt.svelte';
|
||||||
|
|||||||
@@ -64,12 +64,12 @@
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.header-skeleton {
|
.header-skeleton {
|
||||||
border-bottom: 1px solid #e5e7eb;
|
|
||||||
background: white;
|
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
height: 64px;
|
height: 64px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-content {
|
.header-content {
|
||||||
|
|||||||
@@ -238,10 +238,9 @@
|
|||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<div class="home-container">
|
<div class="home-container">
|
||||||
<main class="main-content">
|
<!-- Fullscreen map -->
|
||||||
<div class="map-section">
|
<div class="map-section">
|
||||||
<Map
|
<Map
|
||||||
showLocationButton={true}
|
|
||||||
autoCenter={true}
|
autoCenter={true}
|
||||||
center={[$coordinates?.longitude || 0, $coordinates?.latitude || 51.505]}
|
center={[$coordinates?.longitude || 0, $coordinates?.latitude || 51.505]}
|
||||||
{finds}
|
{finds}
|
||||||
@@ -249,13 +248,10 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="finds-section">
|
<!-- Left sidebar with finds list -->
|
||||||
<div class="finds-sticky-header">
|
<div class="finds-sidebar">
|
||||||
<div class="finds-header-content">
|
<div class="finds-header">
|
||||||
<div class="finds-title-section">
|
|
||||||
<h2 class="finds-title">Finds</h2>
|
|
||||||
<FindsFilter {currentFilter} onFilterChange={handleFilterChange} />
|
<FindsFilter {currentFilter} onFilterChange={handleFilterChange} />
|
||||||
</div>
|
|
||||||
<Button onclick={openCreateModal} class="create-find-button">
|
<Button onclick={openCreateModal} class="create-find-button">
|
||||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" class="mr-2">
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" class="mr-2">
|
||||||
<line x1="12" y1="5" x2="12" y2="19" stroke="currentColor" stroke-width="2" />
|
<line x1="12" y1="5" x2="12" y2="19" stroke="currentColor" stroke-width="2" />
|
||||||
@@ -264,10 +260,10 @@
|
|||||||
Create Find
|
Create Find
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="finds-list-container">
|
||||||
<FindsList {finds} onFindExplore={handleFindExplore} hideTitle={true} />
|
<FindsList {finds} onFindExplore={handleFindExplore} hideTitle={true} />
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</div>
|
||||||
|
|
||||||
<!-- Floating action button for mobile -->
|
<!-- Floating action button for mobile -->
|
||||||
<button class="fab" onclick={openCreateModal} aria-label="Create new find">
|
<button class="fab" onclick={openCreateModal} aria-label="Create new find">
|
||||||
@@ -293,68 +289,58 @@
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.home-container {
|
.home-container {
|
||||||
background-color: #f8f8f8;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-content {
|
|
||||||
padding: 24px 20px;
|
|
||||||
max-width: 1200px;
|
|
||||||
margin: 0 auto;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.map-section {
|
|
||||||
background: white;
|
|
||||||
border-radius: 12px;
|
|
||||||
overflow: hidden;
|
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.map-section :global(.map-container) {
|
|
||||||
height: 500px;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.finds-section {
|
|
||||||
background: white;
|
|
||||||
border-radius: 12px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.finds-sticky-header {
|
.map-section {
|
||||||
position: sticky;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
z-index: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-section :global(.map-container) {
|
||||||
|
height: 100vh;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-section :global(.maplibregl-map) {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.finds-sidebar {
|
||||||
|
position: fixed;
|
||||||
|
top: 80px;
|
||||||
|
left: 20px;
|
||||||
|
width: 40%;
|
||||||
|
max-width: 1000px;
|
||||||
|
min-width: 500px;
|
||||||
|
height: calc(100vh - 100px);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||||||
z-index: 50;
|
z-index: 50;
|
||||||
background: white;
|
display: flex;
|
||||||
border-bottom: 1px solid hsl(var(--border));
|
flex-direction: column;
|
||||||
padding: 24px 24px 16px 24px;
|
overflow: hidden;
|
||||||
border-radius: 12px 12px 0 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.finds-header-content {
|
.finds-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
padding: 20px;
|
||||||
align-items: center;
|
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
gap: 1rem;
|
background: rgba(255, 255, 255, 0.5);
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.finds-title-section {
|
.finds-list-container {
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 1rem;
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
.finds-title {
|
|
||||||
font-family: 'Washington', serif;
|
|
||||||
font-size: 1.875rem;
|
|
||||||
font-weight: 700;
|
|
||||||
margin: 0;
|
|
||||||
color: hsl(var(--foreground));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.create-find-button) {
|
:global(.create-find-button) {
|
||||||
@@ -377,7 +363,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
z-index: 100;
|
z-index: 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fab:hover {
|
.fab:hover {
|
||||||
@@ -386,30 +372,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.main-content {
|
.finds-sidebar {
|
||||||
|
top: auto;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 50vh;
|
||||||
|
border-radius: 20px 20px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.finds-header {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
gap: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.finds-sticky-header {
|
|
||||||
padding: 16px 16px 12px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.finds-header-content {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: stretch;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.finds-title-section {
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.finds-title {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.create-find-button) {
|
:global(.create-find-button) {
|
||||||
@@ -421,17 +395,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.map-section :global(.map-container) {
|
.map-section :global(.map-container) {
|
||||||
height: 300px;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
.main-content {
|
.finds-sidebar {
|
||||||
padding: 12px;
|
height: 60vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.finds-sticky-header {
|
.finds-header {
|
||||||
padding: 12px 12px 8px 12px;
|
padding: 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user