Fix various spacing and sizing issues on party details

This commit is contained in:
Justin Edmund 2025-09-24 01:24:57 -07:00
parent d8eb6b965a
commit 6ace86a00e
8 changed files with 949 additions and 831 deletions

View file

@ -747,14 +747,14 @@
alt={`Avatar of ${party.user.username}`} alt={`Avatar of ${party.user.username}`}
src={avatarSrc} src={avatarSrc}
srcset={avatarSrcSet} srcset={avatarSrcSet}
width="40" width="32"
height="40" height="32"
/> />
{:else} {:else}
<div class="avatar-placeholder" aria-hidden="true"></div> <div class="avatar-placeholder" aria-hidden="true"></div>
{/if} {/if}
</div> </div>
<span class="username">@{party.user.username}</span> <span class="username">{party.user.username}</span>
</a> </a>
</div> </div>
{/if} {/if}
@ -940,17 +940,23 @@
width: 1200px; width: 1200px;
margin: 0 auto; margin: 0 auto;
padding: $unit-half; padding: $unit-half;
gap: $unit-2x;
display: flex;
flex-direction: column;
} }
.party-header { .party-header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: start; align-items: start;
margin-bottom: $unit-half; vertical-align: middle;
padding: $unit-4x 0; align-items: center;
padding: $unit-2x 0;
} }
.party-info { .party-info {
flex-grow: 1;
h1 { h1 {
margin: 0 0 $unit-fourth 0; margin: 0 0 $unit-fourth 0;
font-size: $font-xlarge; font-size: $font-xlarge;
@ -981,8 +987,8 @@
} }
.avatar-wrapper { .avatar-wrapper {
width: $unit-5x; width: $unit-4x;
height: $unit-5x; height: $unit-4x;
border-radius: 50%; border-radius: 50%;
overflow: hidden; overflow: hidden;
background: var(--card-bg); background: var(--card-bg);
@ -1031,7 +1037,7 @@
} }
.username { .username {
font-size: $font-medium; font-size: $font-regular;
font-weight: $medium; font-weight: $medium;
} }
@ -1044,7 +1050,6 @@
.cards { .cards {
display: flex; display: flex;
gap: $unit-2x; gap: $unit-2x;
margin-bottom: $unit-2x;
// Individual card styles // Individual card styles
.description-card, .description-card,

View file

@ -17,13 +17,7 @@
class?: string class?: string
} }
let { let { selectedTab = GridType.Character, onTabChange, party, class: className }: Props = $props()
selectedTab = GridType.Character,
onTabChange,
party,
class: className
}: Props = $props()
// Handle value changes // Handle value changes
let value = $state(selectedTab) let value = $state(selectedTab)
@ -44,12 +38,7 @@
</script> </script>
<nav class={className}> <nav class={className}>
<SegmentedControl <SegmentedControl bind:value onValueChange={handleValueChange} gap={true} grow={true}>
bind:value
onValueChange={handleValueChange}
gap={true}
grow={true}
>
<RepSegment <RepSegment
value={GridType.Character} value={GridType.Character}
label={m.party_segmented_control_characters()} label={m.party_segmented_control_characters()}
@ -82,8 +71,9 @@
</nav> </nav>
<style lang="scss"> <style lang="scss">
@use '$src/themes/spacing' as *;
nav { nav {
width: 100%; width: 100%;
margin-bottom: 1rem;
} }
</style> </style>

View file

@ -95,7 +95,6 @@
} }
.actions-section { .actions-section {
margin-top: $unit-2x;
padding: $unit-2x; padding: $unit-2x;
padding-bottom: $unit-2x; padding-bottom: $unit-2x;
border-top: 1px solid var(--button-bg); border-top: 1px solid var(--button-bg);

View file

@ -10,7 +10,7 @@
padding: 0; padding: 0;
background: transparent; background: transparent;
border: none; border: none;
border-radius: $item-corner; border-radius: $card-corner;
cursor: pointer; cursor: pointer;
transition: all 0.2s ease; transition: all 0.2s ease;
@ -37,7 +37,7 @@
position: absolute; position: absolute;
inset: 0; inset: 0;
background: $grey-100; background: $grey-100;
border-radius: $item-corner; border-radius: $card-corner;
opacity: 0; opacity: 0;
transition: opacity 0.2s ease; transition: opacity 0.2s ease;

View file

@ -18,7 +18,6 @@
.segmentedControl { .segmentedControl {
display: inline-flex; display: inline-flex;
padding: 3px;
position: relative; position: relative;
gap: spacing.$unit-half; gap: spacing.$unit-half;
user-select: none; user-select: none;
@ -45,7 +44,7 @@
} }
&.gap { &.gap {
gap: spacing.$unit; gap: spacing.$unit-2x;
} }
&.raid { &.raid {

View file

@ -22,16 +22,29 @@
<section class="profile"> <section class="profile">
<header class="header"> <header class="header">
{#if data.user?.avatar?.picture} {#if data.user?.avatar?.picture}
<img class="avatar" alt={`Avatar of ${data.user.username}`} src={avatarSrc} srcset={avatarSrcSet} width="64" height="64" /> <img
class="avatar"
alt={`Avatar of ${data.user.username}`}
src={avatarSrc}
srcset={avatarSrcSet}
width="64"
height="64"
/>
{:else} {:else}
<div class="avatar" aria-hidden="true"></div> <div class="avatar" aria-hidden="true"></div>
{/if} {/if}
<div> <div>
<h1>@{data.user.username}</h1> <h1>{data.user.username}</h1>
<nav class="tabs" aria-label="Profile sections"> <nav class="tabs" aria-label="Profile sections">
<a class:active={tab==='teams'} href="?tab=teams" data-sveltekit-preload-data="hover">Teams</a> <a class:active={tab === 'teams'} href="?tab=teams" data-sveltekit-preload-data="hover"
>Teams</a
>
{#if isOwner} {#if isOwner}
<a class:active={tab==='favorites'} href="?tab=favorites" data-sveltekit-preload-data="hover">Favorites</a> <a
class:active={tab === 'favorites'}
href="?tab=favorites"
data-sveltekit-preload-data="hover">Favorites</a
>
{/if} {/if}
</nav> </nav>
</div> </div>
@ -53,13 +66,48 @@
@use '$src/themes/spacing' as *; @use '$src/themes/spacing' as *;
@use '$src/themes/colors' as *; @use '$src/themes/colors' as *;
.profile { padding: $unit-2x 0; } .profile {
.header { display: flex; align-items: center; gap: $unit-2x; margin-bottom: $unit-2x; } padding: $unit-2x 0;
.avatar { width: 64px; height: 64px; border-radius: 50%; background: $grey-80; border: 1px solid $grey-75; object-fit: cover; } }
.sub { color: $grey-55; margin: 0; } .header {
.tabs { display: flex; gap: $unit-2x; margin-top: $unit-half; } display: flex;
.tabs a { text-decoration: none; color: inherit; padding-bottom: 2px; border-bottom: 2px solid transparent; } align-items: center;
.tabs a.active { border-color: #3366ff; color: #3366ff; } gap: $unit-2x;
.pagination { display: flex; gap: $unit-2x; padding: $unit-2x 0; } margin-bottom: $unit-2x;
.pagination a { text-decoration: none; } }
.avatar {
width: 64px;
height: 64px;
border-radius: 50%;
background: $grey-80;
border: 1px solid $grey-75;
object-fit: cover;
}
.sub {
color: $grey-55;
margin: 0;
}
.tabs {
display: flex;
gap: $unit-2x;
margin-top: $unit-half;
}
.tabs a {
text-decoration: none;
color: inherit;
padding-bottom: 2px;
border-bottom: 2px solid transparent;
}
.tabs a.active {
border-color: #3366ff;
color: #3366ff;
}
.pagination {
display: flex;
gap: $unit-2x;
padding: $unit-2x 0;
}
.pagination a {
text-decoration: none;
}
</style> </style>

View file

@ -4,7 +4,10 @@
import WeaponGrid from '$lib/components/grids/WeaponGrid.svelte' import WeaponGrid from '$lib/components/grids/WeaponGrid.svelte'
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 { openSearchSidebar, closeSearchSidebar } from '$lib/features/search/openSearchSidebar.svelte' import {
openSearchSidebar,
closeSearchSidebar
} from '$lib/features/search/openSearchSidebar.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 { setContext } from 'svelte' import { setContext } from 'svelte'
@ -41,9 +44,12 @@
activeTab = gridType activeTab = gridType
// 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)
}) })
@ -74,16 +80,17 @@
let errorMessage = $state('') let errorMessage = $state('')
let errorDetails = $state<string[]>([]) let errorDetails = $state<string[]>([])
// Calculate if grids are full // Calculate if grids are full
let isWeaponGridFull = $derived(weapons.length >= 10) // 1 mainhand + 9 grid slots let isWeaponGridFull = $derived(weapons.length >= 10) // 1 mainhand + 9 grid slots
let isSummonGridFull = $derived(summons.length >= 6) // 6 summon slots (main + 4 grid + friend) let isSummonGridFull = $derived(summons.length >= 6) // 6 summon slots (main + 4 grid + friend)
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
@ -131,22 +138,26 @@
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
if (selectedSlot === null) position = -1 if (selectedSlot === null) position = -1
const addResult = await apiClient.addWeapon( const addResult = await apiClient.addWeapon(partyId, firstItem.granblue_id, position, {
partyId, mainhand: position === -1
firstItem.granblue_id, })
position,
{ mainhand: position === -1 }
)
console.log('Weapon added:', addResult) console.log('Weapon added:', addResult)
itemAdded = true itemAdded = true
// Update local state with the added weapon // Update local state with the added weapon
weapons = [...weapons, { weapons = [
...weapons,
{
id: addResult.grid_weapon?.id || `temp-${Date.now()}`, id: addResult.grid_weapon?.id || `temp-${Date.now()}`,
position, position,
object: { object: {
@ -155,21 +166,22 @@
element: firstItem.element element: firstItem.element
}, },
mainhand: position === -1 mainhand: position === -1
}] }
]
} else if (activeTab === GridType.Summon) { } else if (activeTab === GridType.Summon) {
// Use selectedSlot if available, otherwise default to main summon // Use selectedSlot if available, otherwise default to main summon
if (selectedSlot === null) position = -1 if (selectedSlot === null) position = -1
const addResult = await apiClient.addSummon( const addResult = await apiClient.addSummon(partyId, firstItem.granblue_id, position, {
partyId, main: position === -1,
firstItem.granblue_id, friend: position === 6
position, })
{ main: position === -1, friend: position === 6 }
)
console.log('Summon added:', addResult) console.log('Summon added:', addResult)
itemAdded = true itemAdded = true
// Update local state with the added summon // Update local state with the added summon
summons = [...summons, { summons = [
...summons,
{
id: addResult.grid_summon?.id || `temp-${Date.now()}`, id: addResult.grid_summon?.id || `temp-${Date.now()}`,
position, position,
object: { object: {
@ -179,7 +191,8 @@
}, },
main: position === -1, main: position === -1,
friend: position === 6 friend: position === 6
}] }
]
} else if (activeTab === GridType.Character) { } else if (activeTab === GridType.Character) {
// Use selectedSlot if available, otherwise default to first slot // Use selectedSlot if available, otherwise default to first slot
if (selectedSlot === null) position = 0 if (selectedSlot === null) position = 0
@ -193,7 +206,9 @@
itemAdded = true itemAdded = true
// Update local state with the added character // Update local state with the added character
characters = [...characters, { characters = [
...characters,
{
id: addResult.grid_character?.id || `temp-${Date.now()}`, id: addResult.grid_character?.id || `temp-${Date.now()}`,
position, position,
object: { object: {
@ -201,7 +216,8 @@
name: firstItem.name, name: firstItem.name,
element: firstItem.element element: firstItem.element
} }
}] }
]
} }
selectedSlot = null // Reset after using selectedSlot = null // Reset after using
@ -248,7 +264,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 = []
@ -268,13 +285,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]
} }
@ -288,7 +310,9 @@
) )
// Add to local state // Add to local state
weapons = [...weapons, { weapons = [
...weapons,
{
id: response.grid_weapon?.id || `temp-${Date.now()}`, id: response.grid_weapon?.id || `temp-${Date.now()}`,
position, position,
object: { object: {
@ -297,16 +321,21 @@
element: item.element element: item.element
}, },
mainhand: position === -1 mainhand: position === -1
}] }
]
} 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]
} }
@ -320,7 +349,9 @@
) )
// Add to local state // Add to local state
summons = [...summons, { summons = [
...summons,
{
id: response.grid_summon?.id || `temp-${Date.now()}`, id: response.grid_summon?.id || `temp-${Date.now()}`,
position, position,
object: { object: {
@ -330,16 +361,22 @@
}, },
main: position === -1, main: position === -1,
friend: position === 6 friend: position === 6
}] }
]
} 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]
} }
@ -353,7 +390,9 @@
) )
// Add to local state // Add to local state
characters = [...characters, { characters = [
...characters,
{
id: response.grid_character?.id || `temp-${Date.now()}`, id: response.grid_character?.id || `temp-${Date.now()}`,
position, position,
object: { object: {
@ -361,7 +400,8 @@
name: item.name, name: item.name,
element: item.element element: item.element
} }
}] }
]
} }
} }
} catch (error: any) { } catch (error: any) {
@ -377,17 +417,21 @@
if (activeTab === GridType.Weapon) { if (activeTab === GridType.Weapon) {
// Add weapons to empty slots // Add weapons to empty slots
const emptySlots = Array.from({ length: 10 }, (_, i) => i - 1) // -1 for mainhand, 0-8 for grid const emptySlots = Array.from({ length: 10 }, (_, i) => i - 1) // -1 for mainhand, 0-8 for grid
.filter(i => !weapons.find(w => w.position === i)) .filter((i) => !weapons.find((w) => w.position === i))
items.forEach((item, index) => { items.forEach((item, index) => {
let position: number let position: number
// Use selectedSlot for first item if available // Use selectedSlot for first item if available
if (index === 0 && selectedSlot !== null && !weapons.find(w => w.position === selectedSlot)) { if (
index === 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 slot // Find next empty slot
const availableSlots = emptySlots.filter(s => !weapons.find(w => w.position === s)) const availableSlots = emptySlots.filter((s) => !weapons.find((w) => w.position === s))
if (availableSlots.length === 0) return if (availableSlots.length === 0) return
position = availableSlots[0] position = availableSlots[0]
} }
@ -409,22 +453,30 @@
} else if (activeTab === GridType.Summon) { } else if (activeTab === GridType.Summon) {
// Add summons to empty slots // Add summons to empty slots
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))
items.forEach((item, index) => { items.forEach((item, index) => {
let position: number let position: number
// Use selectedSlot for first item if available // Use selectedSlot for first item if available
if (index === 0 && selectedSlot !== null && !summons.find(s => s.position === selectedSlot)) { if (
index === 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 slot // Find next empty slot
const availableSlots = emptySlots.filter(s => !summons.find(sum => sum.position === s)) const availableSlots = emptySlots.filter(
(s) => !summons.find((sum) => sum.position === s)
)
if (availableSlots.length === 0) return if (availableSlots.length === 0) return
position = availableSlots[0] position = availableSlots[0]
} }
summons = [...summons, { summons = [
...summons,
{
id: `temp-${Date.now()}-${index}`, id: `temp-${Date.now()}-${index}`,
position, position,
object: { object: {
@ -434,27 +486,35 @@
}, },
main: position === -1, main: position === -1,
friend: position === 6 friend: position === 6
}] }
]
}) })
} else if (activeTab === GridType.Character) { } else if (activeTab === GridType.Character) {
// Add characters to empty slots // Add characters to empty slots
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)
)
items.forEach((item, index) => { items.forEach((item, index) => {
let position: number let position: number
// Use selectedSlot for first item if available // Use selectedSlot for first item if available
if (index === 0 && selectedSlot !== null && !characters.find(c => c.position === selectedSlot)) { if (
index === 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 slot // Find next empty slot
const availableSlots = emptySlots.filter(s => !characters.find(c => c.position === s)) const availableSlots = emptySlots.filter((s) => !characters.find((c) => c.position === s))
if (availableSlots.length === 0) return if (availableSlots.length === 0) return
position = availableSlots[0] position = availableSlots[0]
} }
characters = [...characters, { characters = [
...characters,
{
id: `temp-${Date.now()}-${index}`, id: `temp-${Date.now()}-${index}`,
position, position,
object: { object: {
@ -462,7 +522,8 @@
name: item.name, name: item.name,
element: item.element element: item.element
} }
}] }
]
}) })
} }
} }
@ -470,19 +531,19 @@
// Remove functions // Remove functions
function removeWeapon(itemId: string) { function removeWeapon(itemId: string) {
console.log('Removing weapon:', itemId) console.log('Removing weapon:', itemId)
weapons = weapons.filter(w => w.id !== itemId) weapons = weapons.filter((w) => w.id !== itemId)
return Promise.resolve({ id: 'new', shortcode: 'new', weapons, summons, characters }) return Promise.resolve({ id: 'new', shortcode: 'new', weapons, summons, characters })
} }
function removeSummon(itemId: string) { function removeSummon(itemId: string) {
console.log('Removing summon:', itemId) console.log('Removing summon:', itemId)
summons = summons.filter(s => s.id !== itemId) summons = summons.filter((s) => s.id !== itemId)
return Promise.resolve({ id: 'new', shortcode: 'new', weapons, summons, characters }) return Promise.resolve({ id: 'new', shortcode: 'new', weapons, summons, characters })
} }
function removeCharacter(itemId: string) { function removeCharacter(itemId: string) {
console.log('Removing character:', itemId) console.log('Removing character:', itemId)
characters = characters.filter(c => c.id !== itemId) characters = characters.filter((c) => c.id !== itemId)
return Promise.resolve({ id: 'new', shortcode: 'new', weapons, summons, characters }) return Promise.resolve({ id: 'new', shortcode: 'new', weapons, summons, characters })
} }
@ -501,24 +562,36 @@
removeWeapon: (partyId: string, itemId: string) => removeWeapon(itemId), removeWeapon: (partyId: string, itemId: string) => removeWeapon(itemId),
removeSummon: (partyId: string, itemId: string) => removeSummon(itemId), removeSummon: (partyId: string, itemId: string) => removeSummon(itemId),
removeCharacter: (partyId: string, itemId: string) => removeCharacter(itemId), removeCharacter: (partyId: string, itemId: string) => removeCharacter(itemId),
addWeapon: () => Promise.resolve({ party: { id: 'new', shortcode: 'new', weapons, summons, characters } }), addWeapon: () =>
addSummon: () => Promise.resolve({ party: { id: 'new', shortcode: 'new', weapons, summons, characters } }), Promise.resolve({ party: { id: 'new', shortcode: 'new', weapons, summons, characters } }),
addCharacter: () => Promise.resolve({ party: { id: 'new', shortcode: 'new', weapons, summons, characters } }), addSummon: () =>
replaceWeapon: () => Promise.resolve({ party: { id: 'new', shortcode: 'new', weapons, summons, characters } }), Promise.resolve({ party: { id: 'new', shortcode: 'new', weapons, summons, characters } }),
replaceSummon: () => Promise.resolve({ party: { id: 'new', shortcode: 'new', weapons, summons, characters } }), addCharacter: () =>
replaceCharacter: () => Promise.resolve({ party: { id: 'new', shortcode: 'new', weapons, summons, characters } }) Promise.resolve({ party: { id: 'new', shortcode: 'new', weapons, summons, characters } }),
replaceWeapon: () =>
Promise.resolve({ party: { id: 'new', shortcode: 'new', weapons, summons, characters } }),
replaceSummon: () =>
Promise.resolve({ party: { id: 'new', shortcode: 'new', weapons, summons, characters } }),
replaceCharacter: () =>
Promise.resolve({ party: { id: 'new', shortcode: 'new', weapons, summons, characters } })
}, },
partyService: { getEditKey: () => null } partyService: { getEditKey: () => null }
}, },
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
) )
}) })
} }
@ -533,13 +606,20 @@
<h1>Create a new team</h1> <h1>Create a new team</h1>
<p class="description">Search and click items to add them to your grid</p> <p class="description">Search and click items to add them to your grid</p>
</div> </div>
<button class="toggle-sidebar" on:click={() => openSearchSidebar({ <button
type: activeTab === GridType.Weapon ? 'weapon' : class="toggle-sidebar"
activeTab === GridType.Summon ? 'summon' : on:click={() =>
'character', openSearchSidebar({
type:
activeTab === GridType.Weapon
? 'weapon'
: activeTab === GridType.Summon
? 'summon'
: 'character',
onAddItems: handleAddItems, onAddItems: handleAddItems,
canAddMore: !isGridFull(activeTab) canAddMore: !isGridFull(activeTab)
})}> })}
>
Open Search Open Search
</button> </button>
</header> </header>
@ -592,9 +672,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>
@ -622,7 +700,6 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: start; align-items: start;
margin-bottom: 1rem;
} }
.party-info h1 { .party-info h1 {

View file

@ -9,7 +9,7 @@ $desktop: 1920px;
$laptop: 1280px; $laptop: 1280px;
$tablet: 768px; $tablet: 768px;
$phone: 375px; $phone: 375px;
$grid-width: 720px; $grid-width: 780px;
$character-rep-height: 111px; $character-rep-height: 111px;
$summon-rep-height: 117px; $summon-rep-height: 117px;