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">
|
<script lang="ts">
|
||||||
|
import { page } from '$app/state';
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
|
|
||||||
const variants = {
|
const variants = {
|
||||||
primary:
|
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',
|
'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:
|
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:
|
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'
|
'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;
|
href?: string;
|
||||||
};
|
};
|
||||||
let { children, onClick, disabled, variant = 'primary', href }: Props = $props();
|
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>
|
</script>
|
||||||
|
|
||||||
{#if href}
|
{#if href}
|
||||||
<a {href} class={variants[variant]}>
|
<a {href} class={variants[variant]} class:!bg-gray-900={isActive}>
|
||||||
{@render children()}
|
{@render children()}
|
||||||
</a>
|
</a>
|
||||||
{:else}
|
{:else}
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<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="mb-1 text-sm text-gray-200">{title}</div>
|
||||||
<div class="text-3xl font-bold text-gray-800">{value}</div>
|
<div class="text-3xl font-bold text-gray-100">{value}</div>
|
||||||
{#if description}
|
{#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}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
import { DB } from '$lib/integrations/db';
|
import { DB } from '$lib/integrations/db';
|
||||||
import Badge from '../atoms/Badge.svelte';
|
import Badge from '../atoms/Badge.svelte';
|
||||||
import Heading from '../atoms/Heading.svelte';
|
import Heading from '../atoms/Heading.svelte';
|
||||||
import { fly } from 'svelte/transition';
|
|
||||||
import GiftModal from './GiftModal.svelte';
|
import GiftModal from './GiftModal.svelte';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -26,8 +25,6 @@
|
|||||||
<div
|
<div
|
||||||
class={`my-6 rounded-2xl p-4 shadow-sm transition-all duration-200 ease-in-out ${bgByStatus[gift.status]}`}
|
class={`my-6 rounded-2xl p-4 shadow-sm transition-all duration-200 ease-in-out ${bgByStatus[gift.status]}`}
|
||||||
class:cursor-pointer={!!gift.editable}
|
class:cursor-pointer={!!gift.editable}
|
||||||
in:fly={{ x: 100 }}
|
|
||||||
out:fly={{ x: -100 }}
|
|
||||||
onclick={() => (isEditModal = true)}
|
onclick={() => (isEditModal = true)}
|
||||||
>
|
>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { flip } from 'svelte/animate';
|
import { flip } from 'svelte/animate';
|
||||||
import GiftCard from '../molecules/GiftCard.svelte';
|
import GiftCard from '../molecules/GiftCard.svelte';
|
||||||
import { cubicInOut } from 'svelte/easing';
|
import { fly } from 'svelte/transition';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
gifts: Gift[];
|
gifts: Gift[];
|
||||||
@@ -12,29 +12,43 @@
|
|||||||
let sort = $state<keyof Pick<Gift, 'title' | 'cost' | 'person' | 'status'>>('title');
|
let sort = $state<keyof Pick<Gift, 'title' | 'cost' | 'person' | 'status'>>('title');
|
||||||
|
|
||||||
let sortedGifts = $derived.by(() => {
|
let sortedGifts = $derived.by(() => {
|
||||||
let newSortedGifts = [...gifts];
|
let out = [...gifts];
|
||||||
if (sort === 'cost') {
|
|
||||||
newSortedGifts.sort((a, b) => a.cost - b.cost);
|
switch (sort) {
|
||||||
} else if (sort === 'person') {
|
case 'title':
|
||||||
newSortedGifts.sort((a, b) => a.expand.person.name.localeCompare(b.expand.person.name));
|
out.sort((a, b) => a.title.localeCompare(b.title));
|
||||||
} else if (sort === 'status') {
|
break;
|
||||||
newSortedGifts.sort((a, b) => a.status.localeCompare(b.status));
|
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(() => {
|
let filteredGifts = $derived.by(() => {
|
||||||
if (filter === 'all') return sortedGifts;
|
let out = [...sortedGifts];
|
||||||
return sortedGifts.filter((gift) => gift.status === filter);
|
|
||||||
|
if (filter !== 'all') {
|
||||||
|
out = out.filter((gift) => gift.status === filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
});
|
});
|
||||||
|
|
||||||
let renderGifts = $derived(filteredGifts);
|
let renderedGifts = $derived(filteredGifts);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div class="flex flex-row items-center justify-between gap-4">
|
<div class="flex flex-row items-center justify-between gap-4">
|
||||||
<select
|
<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}
|
bind:value={filter}
|
||||||
>
|
>
|
||||||
<option value="all">Wszystkie</option>
|
<option value="all">Wszystkie</option>
|
||||||
@@ -54,9 +68,13 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#each renderGifts as gift (gift.id)}
|
{#key filter}
|
||||||
<div animate:flip={{ duration: 400, easing: cubicInOut }}>
|
<div in:fly={{ x: 100, delay: 250, duration: 200 }} out:fly={{ x: -100, duration: 200 }}>
|
||||||
<GiftCard {...gift} />
|
{#each renderedGifts as gift (gift.id)}
|
||||||
|
<div animate:flip={{ duration: 200 }}>
|
||||||
|
<GiftCard {...gift} />
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/key}
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user