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