diff --git a/src/lib/components/database/UncapCell.svelte b/src/lib/components/database/UncapCell.svelte
new file mode 100644
index 00000000..9a821e27
--- /dev/null
+++ b/src/lib/components/database/UncapCell.svelte
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/lib/components/database/cells/CharacterUncapCell.svelte b/src/lib/components/database/cells/CharacterUncapCell.svelte
new file mode 100644
index 00000000..5b667e4b
--- /dev/null
+++ b/src/lib/components/database/cells/CharacterUncapCell.svelte
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/lib/components/database/cells/LastUpdatedCell.svelte b/src/lib/components/database/cells/LastUpdatedCell.svelte
new file mode 100644
index 00000000..a4ed278b
--- /dev/null
+++ b/src/lib/components/database/cells/LastUpdatedCell.svelte
@@ -0,0 +1,144 @@
+
+
+
+
+
+ {formattedDate}
+ {#if updateType}
+ {updateType}
+ {/if}
+
+
+
diff --git a/src/lib/components/database/cells/SummonUncapCell.svelte b/src/lib/components/database/cells/SummonUncapCell.svelte
new file mode 100644
index 00000000..87409d50
--- /dev/null
+++ b/src/lib/components/database/cells/SummonUncapCell.svelte
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/lib/components/database/cells/WeaponUncapCell.svelte b/src/lib/components/database/cells/WeaponUncapCell.svelte
new file mode 100644
index 00000000..38abbfa6
--- /dev/null
+++ b/src/lib/components/database/cells/WeaponUncapCell.svelte
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/lib/components/uncap/TranscendenceFragment.svelte b/src/lib/components/uncap/TranscendenceFragment.svelte
new file mode 100644
index 00000000..ca9fd68d
--- /dev/null
+++ b/src/lib/components/uncap/TranscendenceFragment.svelte
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/lib/components/uncap/TranscendenceStar.svelte b/src/lib/components/uncap/TranscendenceStar.svelte
new file mode 100644
index 00000000..84d5e01c
--- /dev/null
+++ b/src/lib/components/uncap/TranscendenceStar.svelte
@@ -0,0 +1,237 @@
+
+
+
+
+
+
+ {#if interactive}
+ {#each Array(NUM_FRAGMENTS) as _, i}
+ {@const loopStage = i + 1}
+
+ {/each}
+ {/if}
+
+
+
+
+
\ No newline at end of file
diff --git a/src/lib/components/uncap/UncapIndicator.svelte b/src/lib/components/uncap/UncapIndicator.svelte
new file mode 100644
index 00000000..7e41854a
--- /dev/null
+++ b/src/lib/components/uncap/UncapIndicator.svelte
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+ {#each Array(numStars) as _, i}
+ {@const star = renderStar(i)}
+ {#if star}
+ {#if star.type === 'transcendence'}
+
+ {:else}
+
+ {/if}
+ {/if}
+ {/each}
+
+
+
+
\ No newline at end of file
diff --git a/src/lib/components/uncap/UncapStar.svelte b/src/lib/components/uncap/UncapStar.svelte
new file mode 100644
index 00000000..356cfbbc
--- /dev/null
+++ b/src/lib/components/uncap/UncapStar.svelte
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/lib/components/units/CharacterUnit.svelte b/src/lib/components/units/CharacterUnit.svelte
index 765d355b..b027be38 100644
--- a/src/lib/components/units/CharacterUnit.svelte
+++ b/src/lib/components/units/CharacterUnit.svelte
@@ -5,6 +5,7 @@
import Icon from '$lib/components/Icon.svelte'
import ContextMenu from '$lib/components/ui/ContextMenu.svelte'
import { ContextMenu as ContextMenuBase } from 'bits-ui'
+ import UncapIndicator from '$lib/components/uncap/UncapIndicator.svelte'
interface Props {
item?: GridCharacter
@@ -33,15 +34,12 @@
}
// Use $derived to ensure consistent computation between server and client
let imageUrl = $derived(() => {
- // Handle both new structure (item.character) and old structure (item.object) for compatibility
- const characterData = item?.character || (item as any)?.object
-
- // If no item or no granblueId, return placeholder
- if (!item || !characterData?.granblueId) {
+ // If no item or no character with granblueId, return placeholder
+ if (!item || !item.character?.granblueId) {
return '/images/placeholders/placeholder-weapon-grid.png'
}
- const id = characterData.granblueId
+ const id = item.character.granblueId
const uncap = item?.uncapLevel ?? 0
const transStep = item?.transcendenceStep ?? 0
let suffix = '01'
@@ -87,7 +85,7 @@
{#if item}
{#snippet children()}
- {#key (item as any).id ?? position}
+ {#key item?.id ?? position}
})
{#if ctx?.canEdit() && item?.id}
@@ -143,7 +141,46 @@
{/key}
{/if}
- {item ? displayName(item?.character || (item as any)?.object) : ''}
+ {#if item}
+ {
+ if (!item?.id || !ctx) return
+ try {
+ const editKey = ctx.getEditKey()
+ const updated = await ctx.services.gridService.updateCharacterUncap(item.id, level, undefined, editKey || undefined)
+ if (updated) {
+ ctx.updateParty(updated)
+ }
+ } catch (err) {
+ console.error('Failed to update character uncap:', err)
+ // TODO: Show user-friendly error notification
+ }
+ }}
+ updateTranscendence={async (stage) => {
+ if (!item?.id || !ctx) return
+ try {
+ const editKey = ctx.getEditKey()
+ // When setting transcendence > 0, also set uncap to max (6)
+ const maxUncap = stage > 0 ? 6 : undefined
+ const updated = await ctx.services.gridService.updateCharacterUncap(item.id, maxUncap, stage, editKey || undefined)
+ if (updated) {
+ ctx.updateParty(updated)
+ }
+ } catch (err) {
+ console.error('Failed to update character transcendence:', err)
+ // TODO: Show user-friendly error notification
+ }
+ }}
+ />
+ {/if}
+ {item ? displayName(item?.character) : ''}