feat: update Button and StatsCard styles for improved UI and enhance GiftsList sorting logic
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user