1
0
Fork 0
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:
Sean Morley 2025-05-29 17:47:58 -04:00
parent 3acfc9f228
commit 81006af027
22 changed files with 534 additions and 364 deletions

View file

@ -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>