teams/new: reformat and restructure page

This commit is contained in:
Justin Edmund 2025-12-13 14:35:03 -08:00
parent 47563634b3
commit 015650104e

View file

@ -6,8 +6,14 @@
import SummonGrid from '$lib/components/grids/SummonGrid.svelte'
import CharacterGrid from '$lib/components/grids/CharacterGrid.svelte'
import JobSection from '$lib/components/job/JobSection.svelte'
import { openSearchSidebar, closeSearchSidebar } from '$lib/features/search/openSearchSidebar.svelte'
import { openJobSelectionSidebar, openJobSkillSelectionSidebar } from '$lib/features/job/openJobSidebar.svelte'
import {
openSearchSidebar,
closeSearchSidebar
} from '$lib/features/search/openSearchSidebar.svelte'
import {
openJobSelectionSidebar,
openJobSkillSelectionSidebar
} from '$lib/features/job/openJobSidebar.svelte'
import PartySegmentedControl from '$lib/components/party/PartySegmentedControl.svelte'
import { GridType } from '$lib/types/enums'
import { Gender } from '$lib/utils/jobUtils'
@ -76,27 +82,31 @@
// Set selectedSlot to first valid empty slot for this tab
if (gridType === GridType.Character) {
// Find first empty character slot
const emptySlot = [0, 1, 2, 3, 4].find(i => !characters.find(c => c.position === i))
const emptySlot = [0, 1, 2, 3, 4].find((i) => !characters.find((c) => c.position === i))
selectedSlot = emptySlot ?? 0
} else if (gridType === GridType.Weapon) {
// Find first empty weapon slot (mainhand first, then grid)
const emptySlot = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8].find(i =>
!weapons.find(w => w.position === i || (i === -1 && w.mainhand))
const emptySlot = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8].find(
(i) => !weapons.find((w) => w.position === i || (i === -1 && w.mainhand))
)
selectedSlot = emptySlot ?? -1
} else {
// Find first empty summon slot (main, grid, friend)
const emptySlot = [-1, 0, 1, 2, 3, 6].find(i =>
!summons.find(s => s.position === i || (i === -1 && s.main) || (i === 6 && s.friend))
const emptySlot = [-1, 0, 1, 2, 3, 6].find(
(i) =>
!summons.find((s) => s.position === i || (i === -1 && s.main) || (i === 6 && s.friend))
)
selectedSlot = emptySlot ?? -1
}
// Open sidebar when switching tabs
openSearchSidebar({
type: gridType === GridType.Weapon ? 'weapon' :
gridType === GridType.Summon ? 'summon' :
'character',
type:
gridType === GridType.Weapon
? 'weapon'
: gridType === GridType.Summon
? 'summon'
: 'character',
onAddItems: handleAddItems,
canAddMore: !isGridFull(gridType)
})
@ -269,9 +279,11 @@
let isCharacterGridFull = $derived(characters.length >= 5) // 5 character slots
let canAddMore = $derived(
activeTab === GridType.Weapon ? !isWeaponGridFull :
activeTab === GridType.Summon ? !isSummonGridFull :
!isCharacterGridFull
activeTab === GridType.Weapon
? !isWeaponGridFull
: activeTab === GridType.Summon
? !isSummonGridFull
: !isCharacterGridFull
)
// Handle adding items from search
@ -323,16 +335,18 @@
}
// Update the query cache with the created party
queryClient.setQueryData(
partyKeys.detail(createdParty.shortcode),
createdParty
)
queryClient.setQueryData(partyKeys.detail(createdParty.shortcode), createdParty)
// Step 2: Add the first item to the party
let position = selectedSlot !== null ? selectedSlot : -1 // Use selectedSlot if available
let itemAdded = false
try {
console.log('Adding item to party:', { partyId, itemId: firstItem.id, type: activeTab, position })
console.log('Adding item to party:', {
partyId,
itemId: firstItem.id,
type: activeTab,
position
})
if (activeTab === GridType.Weapon) {
// Use selectedSlot if available, otherwise default to mainhand
@ -422,7 +436,8 @@
} else if (error.errors && typeof error.errors === 'object') {
// Rails-style validation errors
errorDetails = Object.entries(error.errors).map(
([field, messages]) => `${field}: ${Array.isArray(messages) ? messages.join(', ') : messages}`
([field, messages]) =>
`${field}: ${Array.isArray(messages) ? messages.join(', ') : messages}`
)
} else {
errorDetails = []
@ -443,13 +458,18 @@
if (activeTab === GridType.Weapon) {
// Use selectedSlot for first item if available
if (i === 0 && selectedSlot !== null && !weapons.find(w => w.position === selectedSlot)) {
if (
i === 0 &&
selectedSlot !== null &&
!weapons.find((w) => w.position === selectedSlot)
) {
position = selectedSlot
selectedSlot = null // Reset after using
} else {
// Find next empty weapon slot
const emptySlots = Array.from({ length: 10 }, (_, i) => i - 1)
.filter(i => !weapons.find(w => w.position === i))
const emptySlots = Array.from({ length: 10 }, (_, i) => i - 1).filter(
(i) => !weapons.find((w) => w.position === i)
)
if (emptySlots.length === 0) return // Grid full
position = emptySlots[0]!
}
@ -466,13 +486,17 @@
addItemToCache('weapons', response)
} else if (activeTab === GridType.Summon) {
// Use selectedSlot for first item if available
if (i === 0 && selectedSlot !== null && !summons.find(s => s.position === selectedSlot)) {
if (
i === 0 &&
selectedSlot !== null &&
!summons.find((s) => s.position === selectedSlot)
) {
position = selectedSlot
selectedSlot = null // Reset after using
} else {
// Find next empty summon slot
const emptySlots = [-1, 0, 1, 2, 3, 6] // main, 4 grid slots, friend
.filter(i => !summons.find(s => s.position === i))
.filter((i) => !summons.find((s) => s.position === i))
if (emptySlots.length === 0) return // Grid full
position = emptySlots[0]!
}
@ -490,13 +514,18 @@
addItemToCache('summons', response)
} else if (activeTab === GridType.Character) {
// Use selectedSlot for first item if available
if (i === 0 && selectedSlot !== null && !characters.find(c => c.position === selectedSlot)) {
if (
i === 0 &&
selectedSlot !== null &&
!characters.find((c) => c.position === selectedSlot)
) {
position = selectedSlot
selectedSlot = null // Reset after using
} else {
// Find next empty character slot
const emptySlots = Array.from({ length: 5 }, (_, i) => i)
.filter(i => !characters.find(c => c.position === i))
const emptySlots = Array.from({ length: 5 }, (_, i) => i).filter(
(i) => !characters.find((c) => c.position === i)
)
if (emptySlots.length === 0) return // Grid full
position = emptySlots[0]!
}
@ -522,7 +551,6 @@
}
}
// Provide party context using query data
setContext('party', {
getParty: () => party,
@ -565,15 +593,21 @@
}
}
},
openPicker: (opts: { type: 'weapon' | 'summon' | 'character'; position: number; item?: any }) => {
openPicker: (opts: {
type: 'weapon' | 'summon' | 'character'
position: number
item?: any
}) => {
selectedSlot = opts.position
openSearchSidebar({
type: opts.type,
onAddItems: handleAddItems,
canAddMore: !isGridFull(
opts.type === 'weapon' ? GridType.Weapon :
opts.type === 'summon' ? GridType.Summon :
GridType.Character
opts.type === 'weapon'
? GridType.Weapon
: opts.type === 'summon'
? GridType.Summon
: GridType.Character
)
})
}
@ -625,11 +659,7 @@
console.log('Open accessory selection sidebar')
}}
/>
<CharacterGrid
{characters}
{mainWeaponElement}
{partyElement}
/>
<CharacterGrid {characters} {mainWeaponElement} {partyElement} />
</div>
{/if}
</div>
@ -659,9 +689,7 @@
{/if}
<div class="dialog-actions">
<Dialog.Close class="dialog-button">
OK
</Dialog.Close>
<Dialog.Close class="dialog-button">OK</Dialog.Close>
</div>
</Dialog.Content>
</Dialog.Portal>
@ -719,7 +747,7 @@
background: rgba(0, 0, 0, 0.5);
z-index: 50;
}
/*
:global(.dialog-content) {
position: fixed;
left: 50%;
@ -734,7 +762,7 @@
overflow-y: auto;
z-index: 51;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
}
} */
.dialog-title {
font-size: 18px;