Update hooks and ignore markdown files in size check
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 3m16s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 3m16s
This commit is contained in:
+39
-10
@@ -30,6 +30,7 @@ Mana-Loop/
|
||||
│ ├── objects/
|
||||
│ │ ├── 00/
|
||||
│ │ │ ├── 89865f52503a4ed6ce8e44f85ad1548823d17f
|
||||
│ │ │ ├── af629716dd116c017ffcfcec42f231f25fc8f7
|
||||
│ │ │ └── df0433801bffaed8e862470cd9d877a392a0bf
|
||||
│ │ ├── 01/
|
||||
│ │ │ ├── 83373f92a07b4ca99d42064797d3883e67a299
|
||||
@@ -69,6 +70,7 @@ Mana-Loop/
|
||||
│ │ │ ├── 0e2686b4b2ef6886a68e0dc042996dfa7cfc6f
|
||||
│ │ │ └── d7110257638a2d5d5edc62cfa9da4bac292d27
|
||||
│ │ ├── 0a/
|
||||
│ │ │ ├── 433c725df76a2755255866d16907c9986f4781
|
||||
│ │ │ ├── 5e710ea895a4dc8dc0dc3ce043306ffa76c239
|
||||
│ │ │ ├── 76fb517289fa32b9818769bf492160fcb04e0f
|
||||
│ │ │ └── 86027f029d266e9624b71e2d4da5cd045bc0a4
|
||||
@@ -85,6 +87,7 @@ Mana-Loop/
|
||||
│ │ │ └── d75b80bc89dc1737e29fc4cf44f652efd7382e
|
||||
│ │ ├── 0e/
|
||||
│ │ │ ├── 44af05f746a329122b423966e616ecc9d880cb
|
||||
│ │ │ ├── 5111d1b3e03498dbfb5d6c67543a2593b19c73
|
||||
│ │ │ ├── 513309eaaaedd39fbc935f632b84e808f4a5c7
|
||||
│ │ │ ├── 6425c95064668170bd76995ebdfd98989632b0
|
||||
│ │ │ ├── a05052d51de061defbfa77a00dd1b530e33a70
|
||||
@@ -187,6 +190,7 @@ Mana-Loop/
|
||||
│ │ │ └── f2966be85f1216c437bec6a67b5786c8d3235c
|
||||
│ │ ├── 24/
|
||||
│ │ │ ├── 0aec75eea23003fd6d26f39380abc96de7faea
|
||||
│ │ │ ├── 50c7a463d43572a93ece21003b2838fbbb8694
|
||||
│ │ │ ├── b4cf1e08880fda17b4b5ce07271a6b7c5c5608
|
||||
│ │ │ └── db8f784221244600ab86c2648718af2eccb6c4
|
||||
│ │ ├── 25/
|
||||
@@ -204,6 +208,7 @@ Mana-Loop/
|
||||
│ │ │ ├── 3544e7ab0cf747c14c43e244d769028812e8b3
|
||||
│ │ │ └── da1ccfc277949c75a70ca8fb7109d4fedae84d
|
||||
│ │ ├── 28/
|
||||
│ │ │ ├── 2d4bbc5a89a3f3d5438ba115fe51b2fae55d67
|
||||
│ │ │ ├── 45b77c45e5c13af45bea3a4cb795fa50a3464b
|
||||
│ │ │ └── 5de6345a053b7c7bad981a1cc6f2461e4b46d8
|
||||
│ │ ├── 29/
|
||||
@@ -288,7 +293,8 @@ Mana-Loop/
|
||||
│ │ │ └── 9d39f38428f63d1b92c3a6ea768714bb3710a4
|
||||
│ │ ├── 39/
|
||||
│ │ │ ├── 508e799dd32d52064e3b11ba96bd6b5f7b445a
|
||||
│ │ │ └── ee95c04f1a5d27ca73b6e6d09b0f19d44dc050
|
||||
│ │ │ ├── ee95c04f1a5d27ca73b6e6d09b0f19d44dc050
|
||||
│ │ │ └── ff63ea469ee826c8fde88059b96cdfc9600dbd
|
||||
│ │ ├── 3a/
|
||||
│ │ │ ├── 3246f8b7541af387e748d41035f85c23258fdc
|
||||
│ │ │ ├── 4a9bbe2b814564896931f84d54f32b9635772b
|
||||
@@ -396,6 +402,8 @@ Mana-Loop/
|
||||
│ │ │ ├── 583f4ef4769141208222d7ab59add0dc5e057e
|
||||
│ │ │ ├── 5973360217a5a0c5513b4231d7d7aecb5491dc
|
||||
│ │ │ └── 80b8a67674b1ec24b0946807796de0bcc25865
|
||||
│ │ ├── 4e/
|
||||
│ │ │ └── 0f1c944391f23057de9a41fb3025df77c55fa2
|
||||
│ │ ├── 4f/
|
||||
│ │ │ ├── 03544eafd322a6fc08e7e3060b354112fa1dd6
|
||||
│ │ │ ├── 6959b82211e4f322fb4dfb076d11297ea89190
|
||||
@@ -432,7 +440,8 @@ Mana-Loop/
|
||||
│ │ │ └── eac17f0ca858a8b819dbd5563cdcbbe868e0ee
|
||||
│ │ ├── 56/
|
||||
│ │ │ ├── 35711332332069bd1ea6bf8c4b515d2091d645
|
||||
│ │ │ └── 3e41dbe3fa66bf37dd7fdb3841d25f3b63e1b4
|
||||
│ │ │ ├── 3e41dbe3fa66bf37dd7fdb3841d25f3b63e1b4
|
||||
│ │ │ └── a7f639893730faed9c87db0b32bd53b198301d
|
||||
│ │ ├── 57/
|
||||
│ │ │ └── 5c36d9b01d4de7c019bf4a567c660e45e59e43
|
||||
│ │ ├── 58/
|
||||
@@ -459,7 +468,8 @@ Mana-Loop/
|
||||
│ │ │ ├── 81cc9e4f334986679aa0b5abd0d50f47cc90b3
|
||||
│ │ │ ├── b84bae8fba238223329506f97466e7cf5fa7b0
|
||||
│ │ │ ├── e045637a637062a848a01825e2cd649b72a6fe
|
||||
│ │ │ └── e52c7cd25543b9f8bf8bfa773155ade4c85142
|
||||
│ │ │ ├── e52c7cd25543b9f8bf8bfa773155ade4c85142
|
||||
│ │ │ └── eb80db0c59760a036a4cfd0d76ec0dccf9a547
|
||||
│ │ ├── 5c/
|
||||
│ │ │ ├── 2ba11cb18dd30ce96066dc68b5b4a636c954b2
|
||||
│ │ │ ├── a57fa8b5e7f22e42b8eab270a5f0fb8943638d
|
||||
@@ -527,6 +537,7 @@ Mana-Loop/
|
||||
│ │ │ ├── f784695f332975747ab0433ffe1a44abf199ce
|
||||
│ │ │ └── f899df9295233ec6453fbd6085ab737cdd4868
|
||||
│ │ ├── 6b/
|
||||
│ │ │ ├── 31a5c036630ed1f68ff328fa3b10648c4be095
|
||||
│ │ │ ├── 51408735e74d4fc645ae30843d713c57df7071
|
||||
│ │ │ ├── 6e5b13cdf380b8bf5de755155f6e907da7a61e
|
||||
│ │ │ ├── 8b3486bc93f8e52d6b2e47d13a2a7dd23e2b07
|
||||
@@ -556,7 +567,8 @@ Mana-Loop/
|
||||
│ │ │ ├── 0b86d4d7fbadef15d4ebd2254cd0efeeb00f02
|
||||
│ │ │ ├── 5183cded881cf19d6f98a9d3ab06df6644c16a
|
||||
│ │ │ ├── 86a8191ff528525e5aba6820cce68bbff546d8
|
||||
│ │ │ └── dcbb75d5ff17ba47c9069128d7021411730057
|
||||
│ │ │ ├── dcbb75d5ff17ba47c9069128d7021411730057
|
||||
│ │ │ └── e17f665e36bf698ec4b16d499a3824f9299f33
|
||||
│ │ ├── 70/
|
||||
│ │ │ ├── 286f121cdcab90944bd40dd7f87b27207a5be2
|
||||
│ │ │ ├── 56dc04d621a2da9a18615ddf93e74207a5c7f1
|
||||
@@ -579,7 +591,8 @@ Mana-Loop/
|
||||
│ │ │ ├── 4040d64067bea8a20f1ab1befadbf55e88c187
|
||||
│ │ │ ├── 5f1fb0cf9b4075a25d64d8dabc754ffe292f8a
|
||||
│ │ │ ├── 9321d2cbb10a22eff108f2c478b6147b6053e8
|
||||
│ │ │ └── 9c1991f12974b3eba86893dd274ae20ea07441
|
||||
│ │ │ ├── 9c1991f12974b3eba86893dd274ae20ea07441
|
||||
│ │ │ └── f9d0674966a673c6044c2ad2cfd9e4da092081
|
||||
│ │ ├── 75/
|
||||
│ │ │ ├── 7130d618de424546c7a7b56f84199d12de4bb2
|
||||
│ │ │ ├── 863af2c6c9724bca37a9067c03f18fa8025407
|
||||
@@ -604,7 +617,9 @@ Mana-Loop/
|
||||
│ │ │ └── ccc917fdf05df95c374e74b2fb621282423c4e
|
||||
│ │ ├── 79/
|
||||
│ │ │ ├── 4e834147c25b9f95eeeb0a034ed304d59eb65b
|
||||
│ │ │ └── 6dd6d47c5dae286ecfd9a37f2247bd66bc8241
|
||||
│ │ │ ├── 6dd6d47c5dae286ecfd9a37f2247bd66bc8241
|
||||
│ │ │ ├── e0c74973caa1b70808fd5289a41fb8bd9823d8
|
||||
│ │ │ └── f55a91b03a0be6732e1b1b491c7118c80f945d
|
||||
│ │ ├── 7a/
|
||||
│ │ │ ├── 8a2b7b540f5a728563ef3d12598fea3477ad53
|
||||
│ │ │ ├── b82229865f4bfeb9ee986c0b8bb9cc35822d93
|
||||
@@ -632,6 +647,7 @@ Mana-Loop/
|
||||
│ │ │ └── abe59cc2483a0ddb8e5e1aacd333bc1442fba4
|
||||
│ │ ├── 80/
|
||||
│ │ │ ├── 4d76e2372cb0762d0d5a386312743a16129aaa
|
||||
│ │ │ ├── 8639f4858f4556f65d2abe08fa6b256a5d8f89
|
||||
│ │ │ ├── e5aa7b866e6c9409d98f144b364929aa6e5d34
|
||||
│ │ │ └── f63e03a3c4c816ab638943eeb4528e8f31b967
|
||||
│ │ ├── 81/
|
||||
@@ -655,6 +671,7 @@ Mana-Loop/
|
||||
│ │ │ └── f1872bee2f7c9a91ac5f2467b2529aa4568217
|
||||
│ │ ├── 85/
|
||||
│ │ │ ├── 262a3c51bf450062054385ec4bf239f00323ec
|
||||
│ │ │ ├── 8555d2b8e21ed1663584937f1270200088cef7
|
||||
│ │ │ └── 9efc3d27e0e6b5ed91a9c10f4d0604eda3486c
|
||||
│ │ ├── 86/
|
||||
│ │ │ ├── 47ecac91e1311dac4b642d58f12b1ce7200a7d
|
||||
@@ -663,6 +680,7 @@ Mana-Loop/
|
||||
│ │ │ ├── d109e356e178eed0db83c51eab10e61ea8b2bf
|
||||
│ │ │ └── f668e0697cd495803457545dc4c4bcb0984aee
|
||||
│ │ ├── 88/
|
||||
│ │ │ ├── d6016557cec6d8a77df16e9952246052cc5839
|
||||
│ │ │ └── e8cd0873832532404e8add60bff3021876a4ca
|
||||
│ │ ├── 89/
|
||||
│ │ │ ├── 622d12bf59536536bb5a2720423f2b23c43ec3
|
||||
@@ -754,6 +772,7 @@ Mana-Loop/
|
||||
│ │ │ └── e9ad439342d53781cb100f042a8765883ebd7c
|
||||
│ │ ├── 9e/
|
||||
│ │ │ ├── 50b42df6804da2182069b2ec3924017860b421
|
||||
│ │ │ ├── 672cec517992f90eb140f794cb3e1fd5687f5c
|
||||
│ │ │ └── 899d667e232e60a14b57f1608551abe3b53ee8
|
||||
│ │ ├── 9f/
|
||||
│ │ │ ├── 029d93e1a36fb94d980c59b50d1ece90b78e4b
|
||||
@@ -769,6 +788,7 @@ Mana-Loop/
|
||||
│ │ ├── a1/
|
||||
│ │ │ ├── 596a04fee80d51dd192d438c1a9956f6baae1c
|
||||
│ │ │ ├── 601b8fa106b067c9c8168ba5e33d62c1e32884
|
||||
│ │ │ ├── c5c7892060a62ec535bba1dc074d4aab099a24
|
||||
│ │ │ └── ce17196dacab0a9e67e34f576e1bf9649c0112
|
||||
│ │ ├── a2/
|
||||
│ │ │ ├── 125a21ae91abbc2b229881e77adc8de8bb1119
|
||||
@@ -779,6 +799,7 @@ Mana-Loop/
|
||||
│ │ │ ├── 06e50d3c7cdafd5290a5259638db6aacdb3231
|
||||
│ │ │ ├── 15020820665e5cd0e83f5abd16eb0f7c7af59b
|
||||
│ │ │ ├── 38a29fcffd8b6ed2554a7e4eae7c0bf3130424
|
||||
│ │ │ ├── 824c68a25945963efcbdbde55a86cebea43454
|
||||
│ │ │ └── 9d4f0ef1c79b402210fb92d711b8cd1bb56d63
|
||||
│ │ ├── a5/
|
||||
│ │ │ ├── 28feb8e27f2d1484bbf56fa98235aa89dda32c
|
||||
@@ -792,6 +813,7 @@ Mana-Loop/
|
||||
│ │ │ ├── 0cc68fb3b23eac335805e864eaa822e59430cd
|
||||
│ │ │ ├── 265b055632e407d5acc83fc57c245c4762c56b
|
||||
│ │ │ ├── 8c72da042ab31e7a3c1d0c61027b8e2a15946a
|
||||
│ │ │ ├── 98115932b3d0e9fbb6e53d6ea30702cb493529
|
||||
│ │ │ ├── b91225ec8ce3af2529715acfddafbd2b573f46
|
||||
│ │ │ └── e587bb0946929a79a3130518751241b3bcf97c
|
||||
│ │ ├── a8/
|
||||
@@ -802,6 +824,7 @@ Mana-Loop/
|
||||
│ │ │ ├── dfe6258ae5c081fbe9a9e5c6cef67f2b9692a5
|
||||
│ │ │ └── f5fa002ee2a633659d76b11ee3cf3c4312c082
|
||||
│ │ ├── a9/
|
||||
│ │ │ ├── 46e3b6aaa9e3e200465467235ee8a98a9b9b61
|
||||
│ │ │ ├── 4d2ca0680551c9e48836e882b4287627eef295
|
||||
│ │ │ ├── 7c1a2ab27a9500547b545b82760391cc566e21
|
||||
│ │ │ └── da14f29a95fe06481330a240259ad97266c001
|
||||
@@ -909,6 +932,7 @@ Mana-Loop/
|
||||
│ │ │ ├── 8ed0f92cb1fb67c7c2757697c36c969c0361c2
|
||||
│ │ │ └── 94586f56c1f38f1bf58f2acb6db0e2f1f22533
|
||||
│ │ ├── bc/
|
||||
│ │ │ ├── 0fdf0416b50197ff719252a7dcc9dd923c28c5
|
||||
│ │ │ ├── 21c14176f27a1b89c57858fa10efaae88cbc97
|
||||
│ │ │ ├── 312ed47776862d880a89b4271b6596cfdf3641
|
||||
│ │ │ └── b5e902f9a50a1baa5619c5f1288e8458f41f0f
|
||||
@@ -943,7 +967,8 @@ Mana-Loop/
|
||||
│ │ │ ├── 5e6920066307295c3619317dec8642423bba4e
|
||||
│ │ │ ├── 8b734bc40f9c3bfc6d2cf85c16e212a0e6e482
|
||||
│ │ │ ├── 9ae605d632bf8a76788af5f02310b1ee2a2e5d
|
||||
│ │ │ └── b5f158618b61280eec85677f79347fb248b4b4
|
||||
│ │ │ ├── b5f158618b61280eec85677f79347fb248b4b4
|
||||
│ │ │ └── e9f8576c45c8a6975b91858f63ef73afd82e06
|
||||
│ │ ├── c4/
|
||||
│ │ │ ├── 481f618950447b053639d3e46b4e8df430c5be
|
||||
│ │ │ ├── 4af1fe7699ee609a9c8dfea201b2cba349fe0b
|
||||
@@ -1005,7 +1030,8 @@ Mana-Loop/
|
||||
│ │ │ ├── 138d78652bd3a2e13b19623b27e123b3387915
|
||||
│ │ │ ├── 7b0dc137be02425724f3fcde8d298ed3141aa2
|
||||
│ │ │ ├── 8872e8032bae8afcf60220279a7da3c82725c7
|
||||
│ │ │ └── 9981f3ad69bb4819f040597c91eae14dc2a459
|
||||
│ │ │ ├── 9981f3ad69bb4819f040597c91eae14dc2a459
|
||||
│ │ │ └── ee77a4f340fdbdf973a8c6e9e3cb1dfa77f350
|
||||
│ │ ├── cf/
|
||||
│ │ │ ├── 795db7e988a37b31cef9e54940209c2d84d9c1
|
||||
│ │ │ ├── e561cbc6da79d0158c5c275f5c4bb9f6fb8b82
|
||||
@@ -1020,13 +1046,15 @@ Mana-Loop/
|
||||
│ │ │ ├── 1e2f0d1cba4887db91cd104b16583bf8a00542
|
||||
│ │ │ ├── 3c55f27c2a512dc84c8d0ddb7768167decd088
|
||||
│ │ │ ├── 54d7be0517d636132d32332162b310b02f7f90
|
||||
│ │ │ ├── 90afa6d553099c5f4fce7dea54a26033cfecf7
|
||||
│ │ │ └── fcf1fc21915c4c6bd9460506e4ebe41e2ec556
|
||||
│ │ ├── d2/
|
||||
│ │ │ ├── 3705894748304c5e9220b7a85d693498564d4b
|
||||
│ │ │ └── 7f11576582712b3494db9ed41d7e97455e78d0
|
||||
│ │ ├── d3/
|
||||
│ │ │ ├── 9eb8296bc4d58c26172dd460373a64f36034c2
|
||||
│ │ │ └── c69322412a4816c6af9ec3bf8b529619300d8b
|
||||
│ │ │ ├── c69322412a4816c6af9ec3bf8b529619300d8b
|
||||
│ │ │ └── f7f494ed92048a25651d724690387633cc60c6
|
||||
│ │ ├── d4/
|
||||
│ │ │ ├── 97d2ee7e845dfa7774a41e20fbbb8be16d942e
|
||||
│ │ │ ├── 9f55d93bc595604f4d79a42795e4f537487522
|
||||
@@ -1193,6 +1221,7 @@ Mana-Loop/
|
||||
│ │ │ ├── 520e15b8a46087c8b64798d277ca3ea032c79e
|
||||
│ │ │ ├── 754e2dec9d0f324442a65c7cdc21b5ced1a222
|
||||
│ │ │ ├── 8a2d260f95779857064c2e7c4837eb6f260002
|
||||
│ │ │ ├── b618e095fd23c24f7364578165a0ef83318650
|
||||
│ │ │ └── dd633525609ba758e8f2a0ba41e30ea49bdac4
|
||||
│ │ ├── f9/
|
||||
│ │ │ ├── 664a28797bc0099963b4d2317d912336ce9c8a
|
||||
@@ -1270,6 +1299,7 @@ Mana-Loop/
|
||||
│ │ ├── subtask_12_context.md
|
||||
│ │ └── subtask_13_context.md
|
||||
│ ├── GAME_BRIEFING.md
|
||||
│ ├── project-structure.txt
|
||||
│ ├── skills.md
|
||||
│ └── task5.md
|
||||
├── download/
|
||||
@@ -1499,6 +1529,5 @@ Mana-Loop/
|
||||
├── package.json
|
||||
├── postcss.config.mjs
|
||||
├── tailwind.config.ts
|
||||
├── test-small.ts
|
||||
├── tsconfig.json
|
||||
└── vitest.config.ts
|
||||
|
||||
+28
-27
@@ -2,69 +2,70 @@
|
||||
|
||||
## Status Overview
|
||||
- **Start Date**: 2025-05-19
|
||||
- **Current Phase**: PRIORITY 2 (Spire Mode Fixes)
|
||||
- **Overall Progress**: 21% complete (4/19 tasks done)
|
||||
- **Current Phase**: PRIORITY 3 (UI/UX Restructuring)
|
||||
- **Overall Progress**: 42% complete (8/19 tasks done)
|
||||
|
||||
---
|
||||
|
||||
## PRIORITY 0 — Crashes (Fix First, Parallel) ✅ COMPLETED
|
||||
| Task | Status | Notes |
|
||||
|------|--------|-------|
|
||||
| SpellsTab crash diagnosis/fix | Completed | Fixed unprotected ENCHANTMENT_EFFECTS access, added spell.cost guards |
|
||||
| LabTab crash diagnosis/fix | Completed | Added safe access to store.elements with `|| {}` fallbacks |
|
||||
| DebugTab crash diagnosis/fix | Completed | Moved Toaster/GameToaster inside DebugProvider in layout.tsx |
|
||||
| SpellsTab crash diagnosis/fix | Completed | Fixed unprotected ENCHANTMENT_EFFECTS access |
|
||||
| LabTab crash diagnosis/fix | Completed | Added safe access to store.elements |
|
||||
| DebugTab crash diagnosis/fix | Completed | Moved Toaster/GameToaster inside DebugProvider |
|
||||
|
||||
---
|
||||
|
||||
## PRIORITY 1 — Mana Conversion Mechanic Fix ✅ COMPLETED
|
||||
| Task | Status | Notes |
|
||||
|------|--------|-------|
|
||||
| Wire conversion drain to effectiveRegen instead of active mana pool | Completed | Removed redundant `rawMana -= actualConversion` in store.ts since effectiveRegen already accounts for conversion drain |
|
||||
| Wire conversion drain to effectiveRegen | Completed | Removed redundant rawMana -= actualConversion |
|
||||
|
||||
---
|
||||
|
||||
## PRIORITY 2 — Spire Mode Fixes
|
||||
| Task | Status | Notes |
|
||||
|------|--------|-------|
|
||||
| 2a. Floor Rendering & Identity (type, named enemy, special properties) | Pending | |
|
||||
| 2b. Swarm Floors (show multiple enemies, verify generation) | Pending | |
|
||||
| 2c. HP Bar Live Updates | Pending | |
|
||||
| 2d. Casting Progress Overflow Fix | Pending | |
|
||||
| 2e. Climb/Descend Controls (spam fix, re-entry resume, button rename) | Pending | |
|
||||
| 2f. Activity Log Implementation | Pending | |
|
||||
| 2g. Spell Info Display Fix (dmg/cast vs DPS) | Pending | |
|
||||
| 2a. Floor Rendering & Identity | Pending | Context gathering next |
|
||||
| 2b. Swarm Floors | ✅ Completed | Verified by check sub-agent |
|
||||
| 2c. HP Bar Live Updates | ✅ Completed | floorHP synced to enemy HP |
|
||||
| 2d. Casting Progress Overflow | Pending | Context gathering next |
|
||||
| 2e. Climb/Descend Controls | Pending | Context gathering next |
|
||||
| 2f. Activity Log Implementation | Pending | Context gathering next |
|
||||
| 2g. Spell Info Display Fix | Pending | Context gathering next |
|
||||
|
||||
---
|
||||
|
||||
## PRIORITY 3 — UI/UX Restructuring
|
||||
| Task | Status | Notes |
|
||||
|------|--------|-------|
|
||||
| 3a. CraftingTab Restructure (remove 1-4 bar, split Fabricate/Enchant, top sub-tabs) | Pending | |
|
||||
| 3b. LootTab Nesting Fix (remove redundant layers) | Pending | |
|
||||
| 3c. AchievementsTab Nesting Fix (remove duplicate headings) | Pending | |
|
||||
| 3a. CraftingTab Restructure | ✅ Completed | Removed stepper, added Fabricate/Enchant tabs |
|
||||
| 3b. LootTab Nesting Fix | ✅ Completed | Removed redundant LootTab wrapper |
|
||||
| 3c. AchievementsTab Nesting Fix | In Progress | Context gathering → execution |
|
||||
|
||||
---
|
||||
|
||||
## PRIORITY 4 — Enchantment Effects & Research
|
||||
| Task | Status | Notes |
|
||||
|------|--------|-------|
|
||||
| 4a. Mana-Type Capacity Enchantment Effects | Pending | Per unlocked mana type |
|
||||
| 4b. Mana Capacity Research Visibility Gate | Pending | Only show if mana type unlocked |
|
||||
| 4c. Skill Requirement Display Bug Fix (undefined Lv.[object Object]) | Pending | |
|
||||
| 4d. Enchantment Power Effect Implementation + Stub Audit | Pending | Replace placeholder, audit all stubs |
|
||||
| 4a. Mana-Type Capacity Enchantment Effects | Pending | Context gathering next |
|
||||
| 4b. Mana Capacity Research Visibility Gate | Pending | Context gathering next |
|
||||
| 4c. Skill Requirement Display Bug Fix | Pending | Context gathering next |
|
||||
| 4d. Enchantment Power Effect Implementation | Pending | Partially done |
|
||||
|
||||
---
|
||||
|
||||
## PRIORITY 5 — Insight Upgrade Analysis
|
||||
| Task | Status | Notes |
|
||||
|------|--------|-------|
|
||||
| 5a. Create design proposal in docs/task5_insight_proposals.md | Pending | Wait for human sign-off |
|
||||
| 5a. Create design proposal | Pending | Context gathering next |
|
||||
|
||||
---
|
||||
|
||||
## Notes & Decisions
|
||||
- ✅ PRIORITY 0 crashes fixed via parallel sub-agents, verified and applied all fixes
|
||||
- ✅ PRIORITY 1 mana conversion fix applied: removed double-counting of conversion drain in store.ts tick logic
|
||||
- Next steps: Dispatch parallel sub-agents for PRIORITY 2 Spire Mode fixes (2a-2g)
|
||||
- Advisor tool will be used for ambiguous design decisions
|
||||
- Sub-agent instructions passed via inline prompts with full context
|
||||
## Workflow Log
|
||||
- ✅ PRIORITY 0 crashes fixed via parallel sub-agents
|
||||
- ✅ PRIORITY 1 mana conversion fix applied
|
||||
- ✅ PRIORITY 2b, 2c verified completed
|
||||
- ✅ Task 12 (CraftingTab) completed
|
||||
- ✅ Task 13 (LootTab) completed
|
||||
- ⏳ Current: Task 14 (AchievementsTab) context gathering
|
||||
|
||||
@@ -0,0 +1,451 @@
|
||||
# Task 12 Context: Restructure CraftingTab
|
||||
|
||||
## Task Description
|
||||
Restructure CraftingTab (remove 1-4 progress bar, split Fabricate/Enchant, top sub-tabs) (PRIORITY 3a)
|
||||
|
||||
## Source Files
|
||||
|
||||
### 1. `/src/components/game/tabs/CraftingTab.tsx` (268 lines)
|
||||
|
||||
**Imports and Dependencies:**
|
||||
```typescript
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Progress } from '@/components/ui/progress';
|
||||
import { GameCard } from '@/components/ui/game-card';
|
||||
import { SectionHeader } from '@/components/ui/section-header';
|
||||
import { ActionButton } from '@/components/ui/action-button';
|
||||
import { Stepper } from '@/components/ui/stepper';
|
||||
import { Scroll, Hammer, Sparkles, Anvil } from 'lucide-react';
|
||||
import type { EquipmentInstance, EnchantmentDesign, DesignEffect, AppliedEnchantment, LootInventory, EquipmentCraftingProgress } from '@/lib/game/types';
|
||||
import { fmt, type GameStore } from '@/lib/game/store';
|
||||
import {
|
||||
EnchantmentDesigner,
|
||||
EnchantmentPreparer,
|
||||
EnchantmentApplier,
|
||||
EquipmentCrafter,
|
||||
} from '@/components/game/crafting';
|
||||
import { useGameToast } from '@/components/game/GameToast';
|
||||
```
|
||||
|
||||
**Crafting Phases Constant:**
|
||||
```typescript
|
||||
// Crafting phases for the stepper
|
||||
const CRAFTING_PHASES = ['Design', 'Prepare', 'Apply', 'Craft'];
|
||||
```
|
||||
|
||||
**Component Props:**
|
||||
```typescript
|
||||
export interface CraftingTabProps {
|
||||
store: GameStore;
|
||||
}
|
||||
```
|
||||
|
||||
**State and Stepper Mapping:**
|
||||
```typescript
|
||||
export function CraftingTab({ store }: CraftingTabProps) {
|
||||
const showToast = useGameToast();
|
||||
const currentAction = store.currentAction;
|
||||
const designProgress = store.designProgress;
|
||||
const preparationProgress = store.preparationProgress;
|
||||
const applicationProgress = store.applicationProgress;
|
||||
const equipmentCraftingProgress = store.equipmentCraftingProgress;
|
||||
const pauseApplication = store.pauseApplication;
|
||||
const resumeApplication = store.resumeApplication;
|
||||
|
||||
const [craftingStage, setCraftingStage] = useState<'design' | 'prepare' | 'apply' | 'craft'>('craft');
|
||||
|
||||
// Map crafting stage to stepper index
|
||||
const getStepperIndex = (stage: string): number => {
|
||||
switch (stage) {
|
||||
case 'design': return 0;
|
||||
case 'prepare': return 1;
|
||||
case 'apply': return 2;
|
||||
case 'craft': return 3;
|
||||
default: return 0;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**Stepper Component (lines 58-68):**
|
||||
```tsx
|
||||
{/* Visual Stepper - Requirement: show Design, Prepare, Apply phases as visual stepper */}
|
||||
<GameCard variant="default" className="p-4">
|
||||
<Stepper
|
||||
steps={CRAFTING_PHASES}
|
||||
currentStep={getStepperIndex(craftingStage)}
|
||||
className="px-4"
|
||||
/>
|
||||
</GameCard>
|
||||
```
|
||||
|
||||
**Stage Content Conditional Rendering (lines 71-97):**
|
||||
```tsx
|
||||
{/* Stage Content - Without unlabeled Tabs, using conditional rendering instead */}
|
||||
<div className="mt-4">
|
||||
{craftingStage === 'craft' && (
|
||||
<EquipmentCrafter store={store} />
|
||||
)}
|
||||
{craftingStage === 'design' && (
|
||||
<EnchantmentDesigner
|
||||
store={store}
|
||||
selectedEquipmentType={null}
|
||||
setSelectedEquipmentType={() => {}}
|
||||
selectedEffects={[]}
|
||||
setSelectedEffects={() => {}}
|
||||
designName={''}
|
||||
setDesignName={() => {}}
|
||||
selectedDesign={null}
|
||||
setSelectedDesign={() => {}}
|
||||
/>
|
||||
)}
|
||||
{craftingStage === 'prepare' && (
|
||||
<EnchantmentPreparer
|
||||
store={store}
|
||||
selectedEquipmentInstance={null}
|
||||
setSelectedEquipmentInstance={() => {}}
|
||||
/>
|
||||
)}
|
||||
{craftingStage === 'apply' && (
|
||||
<EnchantmentApplier
|
||||
store={store}
|
||||
selectedEquipmentInstance={null}
|
||||
setSelectedEquipmentInstance={() => {}}
|
||||
selectedDesign={null}
|
||||
setSelectedDesign={() => {}}
|
||||
onEnchantmentApplied={handleEnchantmentApplied}
|
||||
onCapacityExceeded={handleCapacityExceeded}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
```
|
||||
|
||||
**Stage Navigation Buttons (lines 99-131):**
|
||||
```tsx
|
||||
{/* Stage Navigation Buttons */}
|
||||
<GameCard variant="default" className="p-4">
|
||||
<div className="flex justify-center gap-2 flex-wrap">
|
||||
<ActionButton
|
||||
variant={craftingStage === 'craft' ? 'primary' : 'secondary'}
|
||||
size="sm"
|
||||
onClick={() => setCraftingStage('craft')}
|
||||
className={craftingStage === 'craft' ? 'ring-2 ring-[var(--interactive-primary)]' : ''}
|
||||
>
|
||||
<Anvil size={14} className="mr-1" />
|
||||
Craft
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
variant={craftingStage === 'design' ? 'primary' : 'secondary'}
|
||||
size="sm"
|
||||
onClick={() => setCraftingStage('design')}
|
||||
className={craftingStage === 'design' ? 'ring-2 ring-[var(--interactive-primary)]' : ''}
|
||||
>
|
||||
<Scroll size={14} className="mr-1" />
|
||||
Design
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
variant={craftingStage === 'prepare' ? 'primary' : 'secondary'}
|
||||
size="sm"
|
||||
onClick={() => setCraftingStage('prepare')}
|
||||
className={craftingStage === 'prepare' ? 'ring-2 ring-[var(--interactive-primary)]' : ''}
|
||||
>
|
||||
<Hammer size={14} className="mr-1" />
|
||||
Prepare
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
variant={craftingStage === 'apply' ? 'primary' : 'secondary'}
|
||||
size="sm"
|
||||
onClick={() => setCraftingStage('apply')}
|
||||
className={craftingStage === 'apply' ? 'ring-2 ring-[var(--interactive-primary)]' : ''}
|
||||
>
|
||||
<Sparkles size={14} className="mr-1" />
|
||||
Apply
|
||||
</ActionButton>
|
||||
</div>
|
||||
</GameCard>
|
||||
```
|
||||
|
||||
**Current Activity Indicators (Progress Bars to be removed - lines 133-236):**
|
||||
```tsx
|
||||
{/* Current Activity Indicator */}
|
||||
{currentAction === 'craft' && equipmentCraftingProgress && (
|
||||
<GameCard variant="default" className="border-[var(--mana-water)]/60 bg-[var(--mana-water)]/10">
|
||||
<SectionHeader
|
||||
title="Crafting Equipment"
|
||||
action={
|
||||
<span className="text-sm text-[var(--text-muted)]">
|
||||
{safeToFixed(calcPercent(equipmentCraftingProgress.progress, equipmentCraftingProgress.required), 0)}%
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
<Progress
|
||||
value={calcPercent(equipmentCraftingProgress.progress, equipmentCraftingProgress.required)}
|
||||
className="h-3 bg-[var(--bg-sunken)]"
|
||||
/>
|
||||
{/* ... more content ... */}
|
||||
</GameCard>
|
||||
)}
|
||||
|
||||
{currentAction === 'design' && designProgress && (
|
||||
<GameCard variant="default" className="border-[var(--mana-stellar)]/60 bg-[var(--mana-stellar)]/10">
|
||||
{/* ... Progress bar and content ... */}
|
||||
</GameCard>
|
||||
)}
|
||||
|
||||
{currentAction === 'prepare' && preparationProgress && (
|
||||
<GameCard variant="default" className="border-[var(--color-warning)]/60 bg-[var(--color-warning)]/10">
|
||||
{/* ... Progress bar and content ... */}
|
||||
</GameCard>
|
||||
)}
|
||||
|
||||
{currentAction === 'enchant' && applicationProgress && (
|
||||
<GameCard variant="default" className="border-[var(--mana-light)]/60 bg-[var(--mana-light)]/10">
|
||||
{/* ... Progress bar and content ... */}
|
||||
</GameCard>
|
||||
)}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Files in `/src/components/game/crafting/` Directory
|
||||
|
||||
| File | Size | Last Modified |
|
||||
|------|------|---------------|
|
||||
| `EnchantmentApplier.tsx` | 12,206 bytes | 1777364523 |
|
||||
| `EnchantmentDesigner.tsx` | 19,568 bytes | 1777361558 |
|
||||
| `EnchantmentPreparer.tsx` | 14,816 bytes | 1777365343 |
|
||||
| `EquipmentCrafter.tsx` | 9,121 bytes | 1777205526 |
|
||||
| `index.tsx` | 396 bytes | 1777028644 |
|
||||
|
||||
**Barrel File (`index.tsx`):**
|
||||
```typescript
|
||||
// Barrel file for crafting components
|
||||
|
||||
export { EnchantmentDesigner, type EnchantmentDesignerProps } from './EnchantmentDesigner';
|
||||
export { EnchantmentPreparer, type EnchantmentPreparerProps } from './EnchantmentPreparer';
|
||||
export { EnchantmentApplier, type EnchantmentApplierProps } from './EnchantmentApplier';
|
||||
export { EquipmentCrafter, type EquipmentCrafterProps } from './EquipmentCrafter';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Stepper Component (`/src/components/ui/stepper.tsx`)
|
||||
|
||||
**Interface:**
|
||||
```typescript
|
||||
interface StepperProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
steps: string[];
|
||||
currentStep: number; // 0-indexed
|
||||
orientation?: "horizontal" | "vertical";
|
||||
}
|
||||
```
|
||||
|
||||
**Full Implementation (100 lines):**
|
||||
```typescript
|
||||
import * as React from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Check, Circle, ArrowRight } from "lucide-react";
|
||||
|
||||
interface StepperProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
steps: string[];
|
||||
currentStep: number; // 0-indexed
|
||||
orientation?: "horizontal" | "vertical";
|
||||
}
|
||||
|
||||
interface StepProps {
|
||||
label: string;
|
||||
stepNumber: number;
|
||||
isActive: boolean;
|
||||
isCompleted: boolean;
|
||||
isLast: boolean;
|
||||
orientation?: "horizontal" | "vertical";
|
||||
}
|
||||
|
||||
const Step = ({ label, stepNumber, isActive, isCompleted, isLast, orientation = "horizontal" }: StepProps) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center",
|
||||
orientation === "vertical" ? "flex-col" : "flex-row",
|
||||
orientation === "vertical" && "w-full"
|
||||
)}
|
||||
>
|
||||
<div className="flex flex-col items-center">
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center justify-center w-8 h-8 rounded-full border-2 transition-all duration-200",
|
||||
isActive && "border-[var(--interactive-primary)] bg-[var(--interactive-primary)]/20 text-[var(--interactive-primary)]",
|
||||
isCompleted && "border-[var(--color-success)] bg-[var(--color-success)]/20 text-[var(--color-success)]",
|
||||
!isActive && !isCompleted && "border-[var(--border-default)] bg-[var(--bg-sunken)] text-[var(--text-muted)]"
|
||||
)}
|
||||
aria-current={isActive ? "step" : undefined}
|
||||
>
|
||||
{isCompleted ? (
|
||||
<Check size={16} />
|
||||
) : (
|
||||
<span className="text-xs font-semibold">{stepNumber}</span>
|
||||
)}
|
||||
</div>
|
||||
<span
|
||||
className={cn(
|
||||
"text-xs mt-1 font-medium",
|
||||
isActive && "text-[var(--interactive-primary)]",
|
||||
isCompleted && "text-[var(--color-success)]",
|
||||
!isActive && !isCompleted && "text-[var(--text-muted)]"
|
||||
)}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
</div>
|
||||
{!isLast && (
|
||||
<div
|
||||
className={cn(
|
||||
"flex-1 mx-2",
|
||||
orientation === "vertical" ? "h-8 w-px my-1" : "h-px",
|
||||
isCompleted ? "bg-[var(--color-success)]" : "bg-[var(--border-default)]"
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export function Stepper({ steps, currentStep, orientation = "horizontal", className, ...props }: StepperProps) {
|
||||
return (
|
||||
<div
|
||||
data-slot="stepper"
|
||||
className={cn(
|
||||
"flex w-full",
|
||||
orientation === "horizontal" ? "flex-row items-center" : "flex-col",
|
||||
className
|
||||
)}
|
||||
role="list"
|
||||
aria-label="Progress steps"
|
||||
{...props}
|
||||
>
|
||||
{steps.map((step, index) => (
|
||||
<div
|
||||
key={step}
|
||||
className={cn("flex items-center", orientation === "vertical" && "w-full")}
|
||||
role="listitem"
|
||||
>
|
||||
<Step
|
||||
label={step}
|
||||
stepNumber={index + 1}
|
||||
isActive={index === currentStep}
|
||||
isCompleted={index < currentStep}
|
||||
isLast={index === steps.length - 1}
|
||||
orientation={orientation}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Current Sub-Tab/Navigation Implementation Details
|
||||
|
||||
**Current Structure:**
|
||||
The CraftingTab currently uses a **4-stage linear workflow** with:
|
||||
1. A visual Stepper component showing phases: Design → Prepare → Apply → Craft
|
||||
2. Navigation buttons at the bottom to switch between stages
|
||||
3. Conditional rendering of content based on `craftingStage` state
|
||||
|
||||
**Current Stages:**
|
||||
- `design` - EnchantmentDesigner component (Design enchantments)
|
||||
- `prepare` - EnchantmentPreparer component (Prepare equipment)
|
||||
- `apply` - EnchantmentApplier component (Apply enchantments)
|
||||
- `craft` - EquipmentCrafter component (Craft equipment)
|
||||
|
||||
**Issues to Address (Task Requirements):**
|
||||
1. **Remove 1-4 progress bar** - The Stepper component (lines 58-68) needs to be removed
|
||||
2. **Split Fabricate/Enchant** - Currently "Craft" (EquipmentCrafter) is mixed in with enchantment workflow. Need to split into:
|
||||
- "Fabricate" tab - for EquipmentCrafter (crafting equipment)
|
||||
- "Enchant" tab - for the Design → Prepare → Apply workflow
|
||||
3. **Top sub-tabs** - Replace the bottom navigation buttons with proper top-level sub-tabs
|
||||
|
||||
**Current Navigation Pattern:**
|
||||
- State: `craftingStage` (useState with 4 possible values)
|
||||
- Navigation: 4 ActionButtons at the bottom of the tab
|
||||
- Visual indicator: Stepper at the top showing progress through phases
|
||||
|
||||
**Suggested New Structure (for implementation):**
|
||||
```
|
||||
CraftingTab
|
||||
├── Top Sub-Tabs: [Fabricate] [Enchant]
|
||||
├── Fabricate Content: EquipmentCrafter
|
||||
└── Enchant Content:
|
||||
├── Sub-Navigation: [Design] [Prepare] [Apply]
|
||||
├── Design: EnchantmentDesigner
|
||||
├── Prepare: EnchantmentPreparer
|
||||
└── Apply: EnchantmentApplier
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Component Props Signatures
|
||||
|
||||
**EquipmentCrafterProps:**
|
||||
```typescript
|
||||
export interface EquipmentCrafterProps {
|
||||
store: GameStore;
|
||||
}
|
||||
```
|
||||
|
||||
**EnchantmentDesignerProps:**
|
||||
```typescript
|
||||
export interface EnchantmentDesignerProps {
|
||||
store: GameStore;
|
||||
selectedEquipmentType: string | null;
|
||||
setSelectedEquipmentType: (type: string | null) => void;
|
||||
selectedEffects: DesignEffect[];
|
||||
setSelectedEffects: (effects: DesignEffect[]) => void;
|
||||
designName: string;
|
||||
setDesignName: (name: string) => void;
|
||||
selectedDesign: string | null;
|
||||
setSelectedDesign: (id: string | null) => void;
|
||||
}
|
||||
```
|
||||
|
||||
**EnchantmentPreparerProps:**
|
||||
```typescript
|
||||
export interface EnchantmentPreparerProps {
|
||||
store: GameStore;
|
||||
selectedEquipmentInstance: string | null;
|
||||
setSelectedEquipmentInstance: (id: string | null) => void;
|
||||
}
|
||||
```
|
||||
|
||||
**EnchantmentApplierProps:**
|
||||
```typescript
|
||||
export interface EnchantmentApplierProps {
|
||||
store: GameStore;
|
||||
selectedEquipmentInstance: string | null;
|
||||
setSelectedEquipmentInstance: (id: string | null) => void;
|
||||
selectedDesign: string | null;
|
||||
setSelectedDesign: (id: string | null) => void;
|
||||
onEnchantmentApplied?: () => void;
|
||||
onCapacityExceeded?: (itemName: string, used: number, total: number) => void;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Key Observations for Restructuring
|
||||
|
||||
1. **Stepper Removal**: The `CRAFTING_PHASES` constant and `Stepper` component usage must be removed from CraftingTab
|
||||
|
||||
2. **State Management**: The `craftingStage` state will need to be replaced with:
|
||||
- A top-level tab state (`fabricate` | `enchant`)
|
||||
- An enchant sub-stage state (`design` | `prepare` | `apply`) when in enchant mode
|
||||
|
||||
3. **Progress Bars**: The activity indicators with Progress components (lines 133-236) should potentially be moved into their respective components (EquipmentCrafter, EnchantmentDesigner, etc.) rather than being in CraftingTab
|
||||
|
||||
4. **No Tab Component**: Currently, the app doesn't use a Tab component - it uses conditional rendering with ActionButtons. The restructured version should implement proper tabs at the top level
|
||||
|
||||
5. **Helper Functions**: The `safeToFixed` and `calcPercent` helpers are used for progress bars - these may no longer be needed in CraftingTab after restructuring
|
||||
@@ -0,0 +1,282 @@
|
||||
# Task 13 Context: Fix LootTab Nesting (Remove Redundant Layers)
|
||||
|
||||
## Task Description
|
||||
Fix LootTab nesting (remove redundant layers) (PRIORITY 3b)
|
||||
|
||||
## Source Files
|
||||
|
||||
### 1. `/src/components/game/tabs/LootTab.tsx` (48 lines)
|
||||
|
||||
**Full Content:**
|
||||
```typescript
|
||||
'use client';
|
||||
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import type { GameStore } from '@/lib/game/store';
|
||||
import { LootInventoryDisplay } from '@/components/game/LootInventory';
|
||||
|
||||
export interface LootTabProps {
|
||||
store: GameStore;
|
||||
}
|
||||
|
||||
export function LootTab({ store }: LootTabProps) {
|
||||
const inventory = store.lootInventory;
|
||||
const elements = store.elements;
|
||||
const equipmentInstances = store.equipmentInstances;
|
||||
|
||||
// Count items for badge
|
||||
const materialCount = Object.values(inventory.materials).reduce((a, b) => a + b, 0);
|
||||
const blueprintCount = inventory.blueprints.length;
|
||||
const equipmentCount = Object.keys(equipmentInstances).length;
|
||||
const totalItems = materialCount + blueprintCount + equipmentCount;
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<Card className="bg-gray-900/80 border-gray-700">
|
||||
<CardHeader className="pb-2">
|
||||
<CardTitle className="text-amber-400 text-sm flex items-center gap-2">
|
||||
💎 Loot Inventory
|
||||
<Badge className="ml-auto bg-gray-800 text-gray-300">
|
||||
{totalItems} items
|
||||
</Badge>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<LootInventoryDisplay
|
||||
inventory={inventory}
|
||||
elements={elements}
|
||||
equipmentInstances={equipmentInstances}
|
||||
onDeleteMaterial={store.deleteMaterial}
|
||||
onDeleteEquipment={store.deleteEquipmentInstance}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
LootTab.displayName = "LootTab";
|
||||
```
|
||||
|
||||
**Key Observations - LootTab Redundant Wrapper:**
|
||||
- Uses `Card` component from `@/components/ui/card` with header "💎 Loot Inventory"
|
||||
- Shows a badge with total items count
|
||||
- Wraps `LootInventoryDisplay` inside `CardContent`
|
||||
- **This creates the outer layer of nesting**
|
||||
|
||||
---
|
||||
|
||||
### 2. `/src/components/game/LootInventory.tsx` (499 lines)
|
||||
|
||||
**Component Interface:**
|
||||
```typescript
|
||||
interface LootInventoryProps {
|
||||
inventory: LootInventoryType;
|
||||
elements?: Record<string, ElementState>;
|
||||
equipmentInstances?: Record<string, EquipmentInstance>;
|
||||
onDeleteMaterial?: (materialId: string, amount: number) => void;
|
||||
onDeleteEquipment?: (instanceId: string) => void;
|
||||
}
|
||||
```
|
||||
|
||||
**Main Component Export:**
|
||||
```typescript
|
||||
export function LootInventoryDisplay({
|
||||
inventory,
|
||||
elements,
|
||||
equipmentInstances = {},
|
||||
onDeleteMaterial,
|
||||
onDeleteEquipment,
|
||||
}: LootInventoryProps) {
|
||||
// ... state and handlers ...
|
||||
|
||||
// Check if we have anything to show
|
||||
const hasItems = totalItems > 0 || essenceCount > 0;
|
||||
|
||||
if (!hasItems) {
|
||||
return (
|
||||
<GameCard variant="default" className="w-full">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Gem className="w-4 h-4 text-[var(--mana-light)]" />
|
||||
<h3 className="text-[var(--mana-light)] game-panel-title text-xs uppercase tracking-wider">
|
||||
Inventory
|
||||
</h3>
|
||||
</div>
|
||||
<div className="text-[var(--text-muted)] text-sm text-center py-4">
|
||||
No items collected yet. Defeat floors and guardians to find loot!
|
||||
</div>
|
||||
</GameCard>
|
||||
);
|
||||
}
|
||||
|
||||
// ... handlers ...
|
||||
|
||||
return (
|
||||
<>
|
||||
<GameCard variant="default" className="w-full">
|
||||
<div className="flex items-center gap-2 mb-3">
|
||||
<Gem className="w-4 h-4 text-[var(--mana-light)]" />
|
||||
<h3 className="text-[var(--mana-light)] game-panel-title text-xs uppercase tracking-wider">
|
||||
Inventory
|
||||
</h3>
|
||||
<Badge
|
||||
className="ml-auto bg-[var(--bg-sunken)] text-[var(--text-secondary)] text-xs border-[var(--border-subtle)]"
|
||||
aria-label={`${totalItems} items in inventory`}
|
||||
>
|
||||
{totalItems} items
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
{/* Search and Filter Controls */}
|
||||
{/* ... */}
|
||||
|
||||
{/* Filter Tabs */}
|
||||
{/* ... */}
|
||||
|
||||
<Separator className="bg-[var(--border-subtle)] mb-3" />
|
||||
|
||||
<ScrollArea className="h-64 w-full">
|
||||
{/* Materials, Essence, Blueprints, Equipment sections */}
|
||||
{/* ... */}
|
||||
</ScrollArea>
|
||||
</GameCard>
|
||||
|
||||
{/* Delete Confirmation Dialog */}
|
||||
<AlertDialog open={!!deleteConfirm} onOpenChange={() => setDeleteConfirm(null)}>
|
||||
{/* ... */}
|
||||
</AlertDialog>
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**Key Observations - LootInventory Redundant Wrapper:**
|
||||
- Uses `GameCard` component (from `@/components/ui/game-card`)
|
||||
- Has its own header with "Inventory" title and `Gem` icon
|
||||
- Shows a badge with total items count (duplicating LootTab's badge)
|
||||
- Contains all the actual content: search, filters, items display
|
||||
- **This creates the inner layer of nesting**
|
||||
|
||||
---
|
||||
|
||||
## 3. Duplicate Headings/Wrappers Issue
|
||||
|
||||
### Redundant Card Nesting:
|
||||
```
|
||||
LootTab (Outer Card)
|
||||
├── CardHeader: "💎 Loot Inventory" + Badge: "{totalItems} items"
|
||||
└── CardContent
|
||||
└── LootInventoryDisplay (Inner GameCard)
|
||||
├── Header: "Inventory" + Badge: "{totalItems} items" ← DUPLICATE
|
||||
├── Search/Filter Controls
|
||||
├── Items Display
|
||||
└── Delete Dialog
|
||||
```
|
||||
|
||||
### Specific Code Duplication:
|
||||
|
||||
**LootTab.tsx (lines 24-33) - Outer Header:**
|
||||
```tsx
|
||||
<CardHeader className="pb-2">
|
||||
<CardTitle className="text-amber-400 text-sm flex items-center gap-2">
|
||||
💎 Loot Inventory
|
||||
<Badge className="ml-auto bg-gray-800 text-gray-300">
|
||||
{totalItems} items
|
||||
</Badge>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
```
|
||||
|
||||
**LootInventory.tsx (lines 191-202) - Inner Header (DUPLICATE):**
|
||||
```tsx
|
||||
<div className="flex items-center gap-2 mb-3">
|
||||
<Gem className="w-4 h-4 text-[var(--mana-light)]" />
|
||||
<h3 className="text-[var(--mana-light)] game-panel-title text-xs uppercase tracking-wider">
|
||||
Inventory
|
||||
</h3>
|
||||
<Badge
|
||||
className="ml-auto bg-[var(--bg-sunken)] text-[var(--text-secondary)] text-xs border-[var(--border-subtle)]"
|
||||
aria-label={`${totalItems} items in inventory`}
|
||||
>
|
||||
{totalItems} items
|
||||
</Badge>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Redundant Badge Count:
|
||||
- LootTab shows: `{totalItems} items`
|
||||
- LootInventoryDisplay also shows: `{totalItems} items`
|
||||
- Both calculate the same `totalItems` value
|
||||
|
||||
---
|
||||
|
||||
## 4. Current Component Hierarchy
|
||||
|
||||
```
|
||||
Game.tsx / Main Game Layout
|
||||
│
|
||||
└── Tabs Component (renders active tab)
|
||||
│
|
||||
└── LootTab ({ store })
|
||||
│
|
||||
├── Card (bg-gray-900/80 border-gray-700)
|
||||
│ ├── CardHeader
|
||||
│ │ └── CardTitle: "💎 Loot Inventory" + Badge
|
||||
│ └── CardContent
|
||||
│ │
|
||||
│ └── LootInventoryDisplay ({ inventory, elements, equipmentInstances, ... })
|
||||
│ │
|
||||
│ ├── GameCard (variant="default" className="w-full")
|
||||
│ │ ├── Header: "Inventory" + Badge + Search/Filter
|
||||
│ │ ├── Separator
|
||||
│ │ ├── ScrollArea
|
||||
│ │ │ ├── Materials Section
|
||||
│ │ │ ├── Essence Section
|
||||
│ │ │ ├── Blueprints Section
|
||||
│ │ │ └── Equipment Section
|
||||
│ │ └── (content)
|
||||
│ │
|
||||
│ └── AlertDialog (Delete Confirmation)
|
||||
│
|
||||
└── (end Card)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Comparison with Other Tabs
|
||||
|
||||
Looking at other tabs in `/src/components/game/tabs/`:
|
||||
|
||||
- **EquipmentTab.tsx**: Uses `GameCard` directly without an outer `Card` wrapper
|
||||
- **CraftingTab.tsx**: Uses multiple `GameCard` components for different sections, no outer `Card`
|
||||
- **GolemancyTab.tsx**: Uses `GameCard` directly
|
||||
- **LabTab.tsx**: Uses `GameCard` directly
|
||||
|
||||
**Pattern**: Most tabs render their content directly using `GameCard` components without an additional `Card` wrapper from the tab itself.
|
||||
|
||||
---
|
||||
|
||||
## 6. Summary of Issues to Fix
|
||||
|
||||
1. **Redundant Card Wrapper in LootTab**: The `Card` + `CardHeader` + `CardContent` wrapper in LootTab.tsx is unnecessary since LootInventoryDisplay already provides its own `GameCard` wrapper.
|
||||
|
||||
2. **Duplicate Header**: Both LootTab and LootInventoryDisplay show similar headers with:
|
||||
- Title text ("Loot Inventory" vs "Inventory")
|
||||
- Item count badge
|
||||
- Icon (emoji 💎 vs Gem icon)
|
||||
|
||||
3. **Double Wrapping**: Content is wrapped in two card-like components:
|
||||
- Outer: `Card` from `@/components/ui/card`
|
||||
- Inner: `GameCard` from `@/components/ui/game-card`
|
||||
|
||||
4. **Solution Direction**: Remove the outer `Card` wrapper from LootTab.tsx and let LootInventoryDisplay handle the card styling, OR remove the inner `GameCard` from LootInventoryDisplay and keep only the outer wrapper.
|
||||
|
||||
---
|
||||
|
||||
## 7. Files That Would Need Modification
|
||||
|
||||
1. **`/src/components/game/tabs/LootTab.tsx`** - Remove outer Card wrapper, pass props directly to LootInventoryDisplay
|
||||
2. **`/src/components/game/LootInventory.tsx`** - Potentially remove GameCard wrapper if keeping LootTab's Card, or keep as-is if removing LootTab's Card
|
||||
|
||||
**Recommended Approach**: Remove the outer `Card` wrapper from `LootTab.tsx` and let `LootInventoryDisplay` handle the full display (since it already has a complete GameCard wrapper with header, controls, and content).
|
||||
Reference in New Issue
Block a user