From 6941be23c32adfac4d502c8efab234f74667fc16 Mon Sep 17 00:00:00 2001 From: Wmj Ismail Date: Fri, 14 Aug 2026 11:56:05 +0800 Subject: [PATCH] feat: implement ui/ux dashboard improvements (search, layout, cta) --- src/lib/FamilySwitcher.svelte | 73 ++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/src/lib/FamilySwitcher.svelte b/src/lib/FamilySwitcher.svelte index 842c206..23412cc 100644 --- a/src/lib/FamilySwitcher.svelte +++ b/src/lib/FamilySwitcher.svelte @@ -6,6 +6,7 @@ let families = $state([]); let invites = $state([]); let newFamilyName = $state(''); + let searchQuery = $state(''); let loading = $state(true); let error = $state(''); @@ -45,6 +46,7 @@ } const isAgentForMultiple = $derived(families.filter(f => f.role === 'agent').length > 1); + const filteredFamilies = $derived(families.filter(f => f.name.toLowerCase().includes(searchQuery.toLowerCase())));
@@ -65,12 +67,22 @@ {#if loading}

Loading your families…

{:else} +
+

Start your own family estate

+

If you're the head of family setting this up for the first time, create your family here. You can invite an estate agent to help manage it once it's set up.

+ + +
+ {#if invites.length}

Pending invitations

{#each invites as inv} -
- {inv.familyName} — as {inv.role} +
+
+ {inv.familyName} + Role: {inv.role} +
{/each} @@ -79,22 +91,29 @@ {#if families.length}
-

{isAgentForMultiple ? 'Your assigned families' : 'Your families'}

- {#each families as f} - - {/each} +
+

{isAgentForMultiple ? 'Your assigned families' : 'Your families'}

+ +
+
+ {#each filteredFamilies as f} + + {/each} + {#if filteredFamilies.length === 0} +

No families found matching "{searchQuery}"

+ {/if} +
{/if} - -
-

Start your own family estate

-

If you're the head of family setting this up for the first time, create your family here. You can invite an estate agent to help manage it once it's set up.

- - -
{/if}
@@ -114,12 +133,30 @@ .hint { font-size: 11.5px; color: #8A8478; line-height: 1.5; margin-bottom: 12px; } .invite-row { display: flex; justify-content: space-between; align-items: center; background: rgba(201,168,76,0.08); border: 1px solid rgba(201,168,76,0.25); border-radius: 10px; padding: 12px; margin-bottom: 8px; font-size: 13px; color: #E8E4DC; } .btn-small { background: #C9A84C; color: #070A0D; border: none; border-radius: 8px; padding: 8px 12px; font-size: 12px; font-weight: 600; cursor: pointer; } - .family-row { width: 100%; display: flex; justify-content: space-between; align-items: center; background: rgba(255,255,255,0.04); border: none; border-radius: 10px; padding: 14px; margin-bottom: 8px; font-size: 14px; color: #E8E4DC; cursor: pointer; text-align: left; } + + .section-header { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; } + .search-input { background: rgba(255,255,255,0.05); border: 1px solid rgba(201,168,76,0.2); border-radius: 8px; padding: 8px 12px; color: #E8E4DC; font-size: 13px; width: 100%; outline: none; transition: border-color 0.2s; } + .search-input:focus { border-color: #C9A84C; } + + .cards-grid { display: flex; flex-direction: column; gap: 10px; } + .family-card { width: 100%; display: flex; flex-direction: column; gap: 12px; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); border-radius: 12px; padding: 16px; font-size: 14px; color: #E8E4DC; cursor: pointer; text-align: left; transition: all 0.2s; } + .family-card:hover { background: rgba(255,255,255,0.06); border-color: rgba(201,168,76,0.3); transform: translateY(-1px); } + .card-top { display: flex; justify-content: space-between; align-items: center; width: 100%; } + .card-bottom { display: flex; justify-content: space-between; align-items: center; width: 100%; font-size: 11px; color: #8A8478; border-top: 1px solid rgba(255,255,255,0.05); padding-top: 10px; } + .card-title { font-weight: 600; font-size: 15px; } + .status-indicator { display: flex; align-items: center; gap: 4px; } + .status-indicator::before { content: ''; width: 6px; height: 6px; background: #2ECC71; border-radius: 50%; } + .action-hint { color: #C9A84C; opacity: 0; transition: opacity 0.2s; } + .family-card:hover .action-hint { opacity: 1; } + + .empty-state { text-align: center; color: #8A8478; font-size: 13px; padding: 20px 0; font-style: italic; } + .role-badge { font-size: 10px; text-transform: uppercase; padding: 3px 8px; border-radius: 6px; background: rgba(255,255,255,0.1); color: #B8B2A6; } .role-badge.owner { background: rgba(201,168,76,0.15); color: #C9A84C; } .field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; } .field span { font-size: 12px; color: #B8B2A6; } .field input { background: rgba(255,255,255,0.05); border: 1px solid rgba(201,168,76,0.2); border-radius: 8px; padding: 10px 12px; color: #E8E4DC; font-size: 14px; width: 100%; } - .btn-primary { width: 100%; padding: 12px; border-radius: 8px; border: none; font-weight: 600; cursor: pointer; background: #C9A84C; color: #070A0D; } + .btn-primary { width: 100%; padding: 12px; border-radius: 8px; border: none; font-weight: 600; cursor: pointer; background: #C9A84C; color: #070A0D; transition: opacity 0.2s; } + .btn-primary:hover { opacity: 0.9; } .error-text { color: #EF4444; font-size: 12.5px; margin-bottom: 12px; } -- 2.52.0