@@ -33,6 +33,7 @@ import (
3333 "github.com/keyxmakerx/chronicle/internal/templates/layouts"
3434 "github.com/keyxmakerx/chronicle/internal/templates/pages"
3535 ws "github.com/keyxmakerx/chronicle/internal/websocket"
36+ "github.com/keyxmakerx/chronicle/internal/plugins/armory"
3637 "github.com/keyxmakerx/chronicle/internal/plugins/npcs"
3738 "github.com/keyxmakerx/chronicle/internal/widgets/notes"
3839 "github.com/keyxmakerx/chronicle/internal/widgets/posts"
@@ -692,6 +693,44 @@ func (a *npcVisibilityTogglerAdapter) TogglePrivate(ctx context.Context, entityI
692693 return a .svc .TogglePrivate (ctx , entityID )
693694}
694695
696+ // armoryItemTypeFinderAdapter wraps entities.EntityService to implement the
697+ // armory.ItemTypeFinder interface. Resolves item-category entity types using
698+ // the preset_category column.
699+ type armoryItemTypeFinderAdapter struct {
700+ svc entities.EntityService
701+ }
702+
703+ // FindItemTypeIDs returns the IDs of entity types with preset_category "item".
704+ func (a * armoryItemTypeFinderAdapter ) FindItemTypeIDs (ctx context.Context , campaignID string ) ([]int , error ) {
705+ types , err := a .svc .GetEntityTypesByPresetCategory (ctx , campaignID , "item" )
706+ if err != nil {
707+ return nil , err
708+ }
709+ ids := make ([]int , len (types ))
710+ for i , t := range types {
711+ ids [i ] = t .ID
712+ }
713+ return ids , nil
714+ }
715+
716+ // FindItemTypes returns item-category entity types for the Armory filter dropdown.
717+ func (a * armoryItemTypeFinderAdapter ) FindItemTypes (ctx context.Context , campaignID string ) ([]armory.ItemTypeInfo , error ) {
718+ types , err := a .svc .GetEntityTypesByPresetCategory (ctx , campaignID , "item" )
719+ if err != nil {
720+ return nil , err
721+ }
722+ infos := make ([]armory.ItemTypeInfo , len (types ))
723+ for i , t := range types {
724+ infos [i ] = armory.ItemTypeInfo {
725+ ID : t .ID ,
726+ Name : t .Name ,
727+ Icon : t .Icon ,
728+ Color : t .Color ,
729+ }
730+ }
731+ return infos , nil
732+ }
733+
695734// RegisterRoutes sets up all application routes. It registers public routes
696735// directly and delegates to each plugin's route registration function.
697736//
@@ -1038,6 +1077,12 @@ func (a *App) RegisterRoutes() {
10381077 npcHandler .SetVisibilityToggler (& npcVisibilityTogglerAdapter {svc : entityService })
10391078 npcs .RegisterRoutes (e , npcHandler , campaignService , authService , addonService )
10401079
1080+ // Armory plugin: gallery/hub view for item-category entities.
1081+ armoryRepo := armory .NewArmoryRepository (a .DB )
1082+ armorySvc := armory .NewArmoryService (armoryRepo , & armoryItemTypeFinderAdapter {svc : entityService })
1083+ armoryHandler := armory .NewHandler (armorySvc )
1084+ armory .RegisterRoutes (e , armoryHandler , campaignService , authService , addonService )
1085+
10411086 // Notes widget: personal floating note-taking panel (Google Keep-style).
10421087 noteRepo := notes .NewNoteRepository (a .DB )
10431088 attRepo := notes .NewAttachmentRepository (a .DB )
@@ -1117,6 +1162,19 @@ func (a *App) RegisterRoutes() {
11171162 return npcs .BlockNPCGallery (bctx .CC , cards , limit )
11181163 })
11191164
1165+ // Armory preview block — embeds a compact item grid on entity pages/dashboards.
1166+ blockRegistry .Register (entities.BlockMeta {
1167+ Type : "armory_preview" , Label : "Armory Preview" , Icon : "fa-shield-halved" ,
1168+ Description : "Grid of campaign items" , Addon : "armory" ,
1169+ }, func (bctx entities.BlockRenderContext ) templ.Component {
1170+ limit := entities .BlockConfigLimit (bctx .Block .Config , "limit" , 8 )
1171+ cards , err := armoryHandler .GalleryBlock (context .Background (), bctx .CC .Campaign .ID , int (bctx .CC .MemberRole ), "" , limit )
1172+ if err != nil {
1173+ return templ .NopComponent
1174+ }
1175+ return armory .BlockArmoryPreview (bctx .CC , cards , limit )
1176+ })
1177+
11201178 // Set the registry on the entity service (validation) and as the global (rendering).
11211179 // The addon checker lets Render() skip blocks whose addon is disabled.
11221180 blockRegistry .SetAddonChecker (addonService )
@@ -1159,12 +1217,13 @@ func (a *App) RegisterRoutes() {
11591217 extApplier := extensions .NewContentApplier (
11601218 a .Config .ExtensionsPath ,
11611219 extRepo ,
1162- extensions .NewEntityTypeAdapter (func (ctx context.Context , campaignID string , name , namePlural , icon , color string ) (int , string , error ) {
1220+ extensions .NewEntityTypeAdapter (func (ctx context.Context , campaignID string , name , namePlural , icon , color , presetCategory string ) (int , string , error ) {
11631221 et , err := entityService .CreateEntityType (ctx , campaignID , entities.CreateEntityTypeInput {
1164- Name : name ,
1165- NamePlural : namePlural ,
1166- Icon : icon ,
1167- Color : color ,
1222+ Name : name ,
1223+ NamePlural : namePlural ,
1224+ Icon : icon ,
1225+ Color : color ,
1226+ PresetCategory : presetCategory ,
11681227 })
11691228 if err != nil {
11701229 return 0 , "" , err
0 commit comments