feat: update Button and StatsCard styles for improved UI and enhance GiftsList sorting logic

This commit is contained in:
Norbert Maciaszek
2025-11-21 01:17:57 +01:00
parent e5025d89a6
commit a0eb060257
4 changed files with 45 additions and 26 deletions

View File

@@ -1,11 +1,12 @@
<script lang="ts">
import { page } from '$app/state';
import type { Snippet } from 'svelte';
const variants = {
primary:
'px-4 py-2 text-sm font-medium text-white bg-emerald-800 hover:bg-emerald-900 rounded-xl transition-all duration-200 ease-in-out disabled:opacity-70 disabled:cursor-not-allowed',
secondary:
'px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 hover:bg-gray-100 rounded-xl transition-all duration-200 ease-in-out',
'px-4 py-2 text-sm font-medium text-gray-100 bg-gray-600 border border-gray-300 hover:bg-gray-500 rounded-xl transition-all duration-200 ease-in-out',
danger:
'px-4 py-2 text-sm font-medium text-white bg-red-800 hover:bg-red-900 rounded-xl transition-all duration-200 ease-in-out disabled:opacity-70 disabled:cursor-not-allowed'
};
@@ -18,10 +19,13 @@
href?: string;
};
let { children, onClick, disabled, variant = 'primary', href }: Props = $props();
const isActive = page.params.year === href?.split('/').pop();
$inspect(isActive, 'isActive', page.params.year, href);
</script>
{#if href}
<a {href} class={variants[variant]}>
<a {href} class={variants[variant]} class:!bg-gray-900={isActive}>
{@render children()}
</a>
{:else}

View File

@@ -9,11 +9,11 @@
</script>
<div
class="rounded-2xl bg-gray-200 p-4 shadow-sm transition-all duration-200 ease-in-out hover:shadow-md md:p-6"
class="rounded-2xl bg-gray-500 p-4 shadow-sm transition-all duration-200 ease-in-out hover:shadow-md md:p-6"
>
<div class="mb-1 text-sm text-gray-600">{title}</div>
<div class="text-3xl font-bold text-gray-800">{value}</div>
<div class="mb-1 text-sm text-gray-200">{title}</div>
<div class="text-3xl font-bold text-gray-100">{value}</div>
{#if description}
<div class="mt-2 text-xs text-gray-500">{description}</div>
<div class="mt-2 text-xs text-gray-200">{description}</div>
{/if}
</div>

View File

@@ -4,7 +4,6 @@
import { DB } from '$lib/integrations/db';
import Badge from '../atoms/Badge.svelte';
import Heading from '../atoms/Heading.svelte';
import { fly } from 'svelte/transition';
import GiftModal from './GiftModal.svelte';
type Props = {
@@ -26,8 +25,6 @@
<div
class={`my-6 rounded-2xl p-4 shadow-sm transition-all duration-200 ease-in-out ${bgByStatus[gift.status]}`}
class:cursor-pointer={!!gift.editable}
in:fly={{ x: 100 }}
out:fly={{ x: -100 }}
onclick={() => (isEditModal = true)}
>
<div class="flex flex-col gap-2">

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import { flip } from 'svelte/animate';
import GiftCard from '../molecules/GiftCard.svelte';
import { cubicInOut } from 'svelte/easing';
import { fly } from 'svelte/transition';
type Props = {
gifts: Gift[];
@@ -12,29 +12,43 @@
let sort = $state<keyof Pick<Gift, 'title' | 'cost' | 'person' | 'status'>>('title');
let sortedGifts = $derived.by(() => {
let newSortedGifts = [...gifts];
if (sort === 'cost') {
newSortedGifts.sort((a, b) => a.cost - b.cost);
} else if (sort === 'person') {
newSortedGifts.sort((a, b) => a.expand.person.name.localeCompare(b.expand.person.name));
} else if (sort === 'status') {
newSortedGifts.sort((a, b) => a.status.localeCompare(b.status));
let out = [...gifts];
switch (sort) {
case 'title':
out.sort((a, b) => a.title.localeCompare(b.title));
break;
case 'cost':
out.sort((a, b) => a.cost - b.cost);
break;
case 'person':
out.sort((a, b) => a.expand.person.name.localeCompare(b.expand.person.name));
break;
case 'status':
out.sort((a, b) => a.status.localeCompare(b.status));
break;
}
return newSortedGifts;
return out;
});
let filteredGifts = $derived.by(() => {
if (filter === 'all') return sortedGifts;
return sortedGifts.filter((gift) => gift.status === filter);
let out = [...sortedGifts];
if (filter !== 'all') {
out = out.filter((gift) => gift.status === filter);
}
return out;
});
let renderGifts = $derived(filteredGifts);
let renderedGifts = $derived(filteredGifts);
</script>
<section>
<div class="flex flex-row items-center justify-between gap-4">
<select
class="rounded-xl border border-gray-300 px-4 py-2 transition-all outline-none focus:border-transparent focus:ring-2 focus:ring-blue-500"
class="ml-auto rounded-xl border border-gray-300 px-4 py-2 transition-all outline-none focus:border-transparent focus:ring-2 focus:ring-blue-500"
bind:value={filter}
>
<option value="all">Wszystkie</option>
@@ -54,9 +68,13 @@
</select>
</div>
{#each renderGifts as gift (gift.id)}
<div animate:flip={{ duration: 400, easing: cubicInOut }}>
<GiftCard {...gift} />
{#key filter}
<div in:fly={{ x: 100, delay: 250, duration: 200 }} out:fly={{ x: -100, duration: 200 }}>
{#each renderedGifts as gift (gift.id)}
<div animate:flip={{ duration: 200 }}>
<GiftCard {...gift} />
</div>
{/each}
</div>
{/each}
{/key}
</section>