diff --git a/src/lib/components/crew/PhantomRow.svelte b/src/lib/components/crew/PhantomRow.svelte
index ad35a368..f07c7a8e 100644
--- a/src/lib/components/crew/PhantomRow.svelte
+++ b/src/lib/components/crew/PhantomRow.svelte
@@ -43,9 +43,6 @@
{phantom.name}
- {#if phantom.granblueId}
-
ID: {phantom.granblueId}
- {/if}
{#if phantom.joinedAt}
Joined {formatDate(phantom.joinedAt)}
{/if}
@@ -144,11 +141,6 @@
color: var(--text-primary);
}
- .granblue-id {
- font-size: typography.$font-small;
- color: var(--text-secondary);
- }
-
.joined-date {
font-size: typography.$font-small;
color: var(--text-tertiary);
diff --git a/src/routes/(app)/crew/members/+page.svelte b/src/routes/(app)/crew/members/+page.svelte
index 5ac9c811..31d71654 100644
--- a/src/routes/(app)/crew/members/+page.svelte
+++ b/src/routes/(app)/crew/members/+page.svelte
@@ -16,6 +16,8 @@
import Button from '$lib/components/ui/Button.svelte'
import Dialog from '$lib/components/ui/Dialog.svelte'
import DropdownMenu from '$lib/components/ui/DropdownMenu.svelte'
+ import Input from '$lib/components/ui/Input.svelte'
+ import DatePicker from '$lib/components/ui/DatePicker.svelte'
import ModalHeader from '$lib/components/ui/ModalHeader.svelte'
import ModalBody from '$lib/components/ui/ModalBody.svelte'
import ModalFooter from '$lib/components/ui/ModalFooter.svelte'
@@ -66,10 +68,10 @@
enabled: crewStore.isOfficer && !!crewStore.crew?.id
}))
- // Query for phantoms (needed for pending claims badge when not viewing phantom/all filter)
+ // Query for phantoms (needed for pending claims badge when viewing pending filter)
const phantomsQuery = createQuery(() => ({
...crewQueries.members('phantom'),
- enabled: filter !== 'phantom' && filter !== 'all' && crewStore.isOfficer
+ enabled: filter === 'pending' && crewStore.isOfficer
}))
// Calculate total active roster size (members + phantoms)
@@ -97,8 +99,7 @@
const filterOptions = $derived.by(() => {
const options: { value: MemberFilter; label: string }[] = [
{ value: 'all', label: 'All' },
- { value: 'active', label: 'Active' },
- { value: 'phantom', label: 'Phantoms' }
+ { value: 'active', label: 'Active' }
]
if (crewStore.isOfficer) {
options.push({ value: 'pending', label: 'Pending' })
@@ -130,6 +131,7 @@
let editJoinDate = $state('')
let editRetired = $state(false)
let editRetiredAt = $state('')
+ let editGranblueId = $state('')
// Dialog state for scout modal
let scoutModalOpen = $state(false)
@@ -216,6 +218,7 @@
editJoinDate = phantom.joinedAt ? (phantom.joinedAt.split('T')[0] ?? '') : ''
editRetired = phantom.retired
editRetiredAt = phantom.retiredAt ? (phantom.retiredAt.split('T')[0] ?? '') : ''
+ editGranblueId = phantom.granblueId ?? ''
editDialogOpen = true
}
@@ -238,7 +241,8 @@
await crewAdapter.updatePhantom(crewStore.crew.id, editingPhantom.id, {
joinedAt: editJoinDate,
retired: editRetired,
- retiredAt: editRetired ? editRetiredAt || undefined : undefined
+ retiredAt: editRetired ? editRetiredAt || undefined : undefined,
+ granblueId: editGranblueId || undefined
})
// Invalidate members query
membersQuery.refetch()
@@ -255,6 +259,7 @@
editJoinDate = ''
editRetired = false
editRetiredAt = ''
+ editGranblueId = ''
}
function openDeletePhantomDialog(phantom: PhantomPlayer) {
@@ -315,12 +320,11 @@
)
// Get phantoms with pending claims (assigned but not confirmed)
- // Use phantom query when not viewing phantom/all filter to ensure badge always has data
+ // Use phantom query when viewing pending filter since it doesn't include phantoms
const pendingClaimPhantoms = $derived.by(() => {
- let phantoms = membersQuery.data?.phantoms
- if (filter !== 'phantom' && filter !== 'all') {
- phantoms = phantomsQuery.data?.phantoms
- }
+ const phantoms = filter === 'pending'
+ ? phantomsQuery.data?.phantoms
+ : membersQuery.data?.phantoms
return phantoms?.filter((p) => p.claimedBy && !p.claimConfirmed) ?? []
})
@@ -444,52 +448,56 @@
Failed to load members
{:else}
-
- {#if membersQuery.data?.members && membersQuery.data.members.length > 0}
-
- {#each membersQuery.data.members as member}
- openEditMemberDialog(member)}
- onPromote={() => openPromoteDialog(member)}
- onDemote={() => openDemoteDialog(member)}
- onRemove={() => openRemoveDialog(member)}
- />
- {/each}
-
- {:else if filter !== 'phantom'}
-
No members found
- {/if}
+ {@const hasMembers = membersQuery.data?.members && membersQuery.data.members.length > 0}
+ {@const hasPhantoms = membersQuery.data?.phantoms && membersQuery.data.phantoms.length > 0}
-
- {#if membersQuery.data?.phantoms && membersQuery.data.phantoms.length > 0}
- {#if filter === 'all' && membersQuery.data.members.length > 0}
-
- Phantom Players
-
- {/if}
-
- {#each membersQuery.data.phantoms as phantom}
- openEditPhantomDialog(phantom)}
- onDelete={() => openDeletePhantomDialog(phantom)}
- onAssign={() => openAssignPhantomDialog(phantom)}
- onAccept={() => openConfirmClaimDialog(phantom)}
- onDecline={() => handleDeclineClaim(phantom)}
- />
- {/each}
-
- {:else if filter === 'phantom'}
+
+ {#if (filter === 'active' || filter === 'retired') && !hasMembers && !hasPhantoms}
-
No phantom players.
- {#if crewStore.isOfficer}
-
(bulkPhantomDialogOpen = true)}>
- Add phantoms...
-
- {/if}
+
No {filter} players found.
+ {:else}
+
+ {#if hasMembers}
+ {#if (filter === 'active' || filter === 'retired') && hasPhantoms}
+
+ Members ({membersQuery.data?.members.length})
+
+ {/if}
+
+ {#each membersQuery.data?.members ?? [] as member}
+ openEditMemberDialog(member)}
+ onPromote={() => openPromoteDialog(member)}
+ onDemote={() => openDemoteDialog(member)}
+ onRemove={() => openRemoveDialog(member)}
+ />
+ {/each}
+
+ {/if}
+
+
+ {#if hasPhantoms}
+ {#if filter === 'all' || filter === 'active' || filter === 'retired'}
+
+ Phantom Players ({membersQuery.data?.phantoms.length})
+
+ {/if}
+
+ {#each membersQuery.data?.phantoms ?? [] as phantom}
+ openEditPhantomDialog(phantom)}
+ onDelete={() => openDeletePhantomDialog(phantom)}
+ onAssign={() => openAssignPhantomDialog(phantom)}
+ onAccept={() => openConfirmClaimDialog(phantom)}
+ onDecline={() => handleDeclineClaim(phantom)}
+ />
+ {/each}
+
+ {/if}
{/if}
{/if}
@@ -543,10 +551,15 @@