mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-07-26 00:09:38 +02:00
refactor: enhance UI components with improved styling and layout
- Updated CollectionCard, CountryCard, LodgingCard, NoteCard, RegionCard, TransportationCard, UserCard, and ShareModal components for better visual consistency and responsiveness. - Introduced hover effects and transitions for a more interactive experience. - Improved accessibility by ensuring proper alt text for images and using semantic HTML elements. - Refactored date formatting logic into a utility function for reuse across components. - Added new translations for profile viewing and joined date in the localization files.
This commit is contained in:
parent
3acfc9f228
commit
81006af027
22 changed files with 534 additions and 364 deletions
|
@ -8,6 +8,7 @@
|
|||
import DeleteWarning from './DeleteWarning.svelte';
|
||||
// import ArrowDownThick from '~icons/mdi/arrow-down-thick';
|
||||
import { TRANSPORTATION_TYPES_ICONS } from '$lib';
|
||||
import { formatDateInTimezone } from '$lib/dateUtils';
|
||||
|
||||
function getTransportationIcon(type: string) {
|
||||
if (type in TRANSPORTATION_TYPES_ICONS) {
|
||||
|
@ -18,23 +19,6 @@
|
|||
}
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function formatDateInTimezone(utcDate: string, timezone?: string): string {
|
||||
if (!utcDate) return '';
|
||||
try {
|
||||
return new Intl.DateTimeFormat(undefined, {
|
||||
timeZone: timezone,
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: true
|
||||
}).format(new Date(utcDate));
|
||||
} catch {
|
||||
return new Date(utcDate).toLocaleString();
|
||||
}
|
||||
}
|
||||
|
||||
export let transportation: Transportation;
|
||||
export let user: User | null = null;
|
||||
export let collection: Collection | null = null;
|
||||
|
@ -123,66 +107,62 @@
|
|||
{/if}
|
||||
|
||||
<div
|
||||
class="card w-full max-w-xs sm:max-w-sm md:max-w-md lg:max-w-md xl:max-w-md bg-neutral text-neutral-content shadow-xl"
|
||||
class="card w-full max-w-md bg-base-300 text-base-content shadow-2xl hover:shadow-3xl transition-all duration-300 border border-base-300 hover:border-primary/20 group"
|
||||
>
|
||||
<div class="card-body space-y-4">
|
||||
<!-- Title and Type -->
|
||||
<h2 class="card-title text-lg font-semibold truncate">{transportation.name}</h2>
|
||||
<div>
|
||||
<div class="badge badge-secondary">
|
||||
{$t(`transportation.modes.${transportation.type}`) +
|
||||
' ' +
|
||||
getTransportationIcon(transportation.type)}
|
||||
<div class="card-body p-6 space-y-4">
|
||||
<!-- Title & Mode -->
|
||||
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2">
|
||||
<h2 class="card-title text-xl font-semibold truncate">{transportation.name}</h2>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<div class="badge badge-secondary">
|
||||
{$t(`transportation.modes.${transportation.type}`)}
|
||||
{' '}{getTransportationIcon(transportation.type)}
|
||||
</div>
|
||||
{#if transportation.type === 'plane' && transportation.flight_number}
|
||||
<div class="badge badge-neutral">{transportation.flight_number}</div>
|
||||
{/if}
|
||||
{#if unlinked}
|
||||
<div class="badge badge-error">{$t('adventures.out_of_range')}</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if transportation.type == 'plane' && transportation.flight_number}
|
||||
<div class="badge badge-neutral-200">{transportation.flight_number}</div>
|
||||
{/if}
|
||||
{#if unlinked}
|
||||
<div class="badge badge-error">{$t('adventures.out_of_range')}</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Locations -->
|
||||
<!-- Start Section -->
|
||||
<div class="space-y-2">
|
||||
{#if transportation.from_location}
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-medium text-sm">{$t('adventures.from')}:</span>
|
||||
<p class="break-words">{transportation.from_location}</p>
|
||||
<span class="text-sm font-medium">{$t('adventures.from')}:</span>
|
||||
<p class="text-sm break-words">{transportation.from_location}</p>
|
||||
</div>
|
||||
{/if}
|
||||
{#if transportation.date}
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-medium text-sm">{$t('adventures.start')}:</span>
|
||||
<p>
|
||||
{formatDateInTimezone(transportation.date, transportation.start_timezone ?? undefined)}
|
||||
<span class="text-sm font-medium">{$t('adventures.start')}:</span>
|
||||
<p class="text-sm">
|
||||
{formatDateInTimezone(transportation.date, transportation.start_timezone)}
|
||||
{#if transportation.start_timezone}
|
||||
<span class="text-xs opacity-60 ml-1">({transportation.start_timezone})</span>
|
||||
<span class="ml-1 text-xs opacity-60">({transportation.start_timezone})</span>
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Dates -->
|
||||
<!-- End Section -->
|
||||
<div class="space-y-2">
|
||||
{#if transportation.to_location}
|
||||
<!-- <ArrowDownThick class="w-4 h-4" /> -->
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-medium text-sm">{$t('adventures.to')}:</span>
|
||||
|
||||
<p class="break-words">{transportation.to_location}</p>
|
||||
<span class="text-sm font-medium">{$t('adventures.to')}:</span>
|
||||
<p class="text-sm break-words">{transportation.to_location}</p>
|
||||
</div>
|
||||
{/if}
|
||||
{#if transportation.end_date}
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-medium text-sm">{$t('adventures.end')}:</span>
|
||||
<p>
|
||||
{formatDateInTimezone(
|
||||
transportation.end_date,
|
||||
transportation.end_timezone || undefined
|
||||
)}
|
||||
<span class="text-sm font-medium">{$t('adventures.end')}:</span>
|
||||
<p class="text-sm">
|
||||
{formatDateInTimezone(transportation.end_date, transportation.end_timezone)}
|
||||
{#if transportation.end_timezone}
|
||||
<span class="text-xs opacity-60 ml-1">({transportation.end_timezone})</span>
|
||||
<span class="ml-1 text-xs opacity-60">({transportation.end_timezone})</span>
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
|
@ -190,20 +170,20 @@
|
|||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
{#if transportation.user_id == user?.uuid || (collection && user && collection.shared_with && collection.shared_with.includes(user.uuid))}
|
||||
<div class="card-actions justify-end">
|
||||
{#if transportation.user_id == user?.uuid || (collection && user && collection.shared_with?.includes(user.uuid))}
|
||||
<div class="pt-4 border-t border-base-300 flex justify-end gap-2">
|
||||
<button
|
||||
class="btn btn-primary btn-sm flex items-center gap-1"
|
||||
class="btn btn-neutral btn-sm flex items-center gap-1"
|
||||
on:click={editTransportation}
|
||||
title="Edit"
|
||||
title={$t('transportation.edit')}
|
||||
>
|
||||
<FileDocumentEdit class="w-5 h-5" />
|
||||
<span>{$t('transportation.edit')}</span>
|
||||
</button>
|
||||
<button
|
||||
on:click={() => (isWarningModalOpen = true)}
|
||||
class="btn btn-secondary btn-sm flex items-center gap-1"
|
||||
title="Delete"
|
||||
on:click={() => (isWarningModalOpen = true)}
|
||||
title={$t('adventures.delete')}
|
||||
>
|
||||
<TrashCanOutline class="w-5 h-5" />
|
||||
<span>{$t('adventures.delete')}</span>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue