From de70b8c97f3d65fdc4ff4b4e2ca3fe20db608509 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 28 Jun 2025 23:51:37 +0200 Subject: [PATCH] content management rewrite, groups, chunking, multidimensional collections --- BLAIzor.csproj | 14 +- BLAIzor.sln | 6 + Components/App.razor | 5 +- Components/Layout/MainLayout.razor | 2 +- Components/Pages/CreateForm.razor | 4 +- Components/Pages/Index.razor | 91 +- Components/Pages/MainPageBase.cs | 65 +- Components/Pages/ManageContentGroups.razor | 127 + Components/Pages/ManageSiteInfo.razor | 24 +- Components/Pages/ManageUploads.razor | 143 +- Components/Pages/Pdf-form-extractor.razor | 4 +- Components/Pages/Preview.razor | 559 +- Components/Pages/RadzenGridTest.razor | 16 +- Components/Pages/Sites.razor | 27 +- Components/Partials/ContentItemList.razor | 148 + Components/Partials/DialogCardPage.razor | 23 + Components/Partials/EditContentGroup.razor | 120 + Components/Partials/EditContentItem.razor | 92 + Components/Partials/EditorUIComponentBase.cs | 28 + Components/Partials/FooterComponent.razor | 128 + .../Partials/GenerateFromDocument.razor | 28 +- Components/Partials/GenerateFromScratch.razor | 28 +- .../Partials/ManageContentGroupsPartial.razor | 208 + .../Partials/ManageSiteInfoPartial.razor | 152 + .../Partials/MenuItemContentEditor.razor | 5 +- Components/Partials/NavMenu.razor | 2 +- Components/Partials/NewNavMenu.razor | 150 + Components/Partials/VideoComponent.razor | 9 +- Data/ApplicationDbContext.cs | 46 +- Helpers/ChunkingHelper.cs | 130 + Helpers/Notification.cs | 50 + Helpers/TextHelper.cs | 4 + Helpers/VectorHashHelper.cs | 48 + ...CollectionAdministrationUpdate.Designer.cs | 841 + ...17221435_CollectionAdministrationUpdate.cs | 214 + ...lectionAdministrationUpdateFIX.Designer.cs | 841 + ...24307_CollectionAdministrationUpdateFIX.cs | 41 + ...ollectionAdministrationUpdate2.Designer.cs | 855 ++ ...8105221_CollectionAdministrationUpdate2.cs | 49 + ...625185236_StoredCollectionName.Designer.cs | 858 ++ .../20250625185236_StoredCollectionName.cs | 35 + Migrations/20250628191216_logger.Designer.cs | 885 ++ Migrations/20250628191216_logger.cs | 38 + .../ApplicationDbContextModelSnapshot.cs | 248 +- Models/AiPrompts.cs | 424 + Models/AppLog.cs | 11 + Models/ContentChunk.cs | 14 + Models/ContentGroup.cs | 21 + Models/ContentGroupModel.cs | 9 + Models/ContentItem.cs | 20 + Models/ContentItemModel.cs | 11 + Models/Editor/UploadedFilesModel.cs | 8 +- Models/MenuItem.cs | 18 +- Models/SiteInfo.cs | 3 +- Models/WebPageContent.cs | 23 +- Models/WebsiteContentModel.cs | 9 + Program.cs | 2 + SeemGen.Tests/ContentEditorServiceTests.cs | 116 + SeemGen.Tests/SeemGen.Tests.csproj | 27 + SeemGen.Tests/UnitTest1.cs | 10 + Services/AIService.cs | 915 +- Services/CerebrasAPIService.cs | 4 + Services/ContentEditorAIService.cs | 215 + Services/ContentEditorService.cs | 1012 +- Services/HtmlSnippetProcessor.cs | 2 +- Services/ISimpleLogger.cs | 20 + Services/OpenAIApiService.cs | 5 +- Services/QDrantService.cs | 461 +- Services/ScopedContentService.cs | 156 +- Services/SimpleLogger.cs | 70 + Services/WebsiteContentLoaderService.cs | 142 + appsettings.json | 4 +- wwwroot/admin.css | 251 + wwwroot/main.css | 53 +- wwwroot/scripts/finisher-header.es5.min.js | 1 + wwwroot/temp/style_19779c82.css | 12704 ---------------- wwwroot/temp/style_1f958996.css | 12704 ---------------- wwwroot/temp/style_2c483fdb.css | 471 - wwwroot/temp/style_4f82336e.css | 471 - wwwroot/temp/style_63bf07cf.css | 12704 ---------------- ...{style_dc975e92.css => style_7c8bd76c.css} | 231 +- wwwroot/temp/style_ab67f439.css | 168 - wwwroot/temp/style_b06ef8f3.css | 12704 ---------------- wwwroot/temp/style_cb747a87.css | 12704 ---------------- wwwroot/temp/style_dbd3e4db.css | 168 - wwwroot/temp/style_fc8f1da8.css | 12704 ---------------- .../images/szoftver.jpg | Bin 0 -> 1272188 bytes .../images/thumbnails/10262403.jpg | Bin 0 -> 15479 bytes ...6537457352993553_2093941074766316375_n.jpg | Bin 0 -> 78099 bytes ..._8553833781365611_797678058825756959_n.jpg | Bin 0 -> 24301 bytes ...8571192746296381_2492674641604205759_n.jpg | Bin 0 -> 24721 bytes ...8560471694035153_8000699131803786124_n.jpg | Bin 0 -> 25638 bytes ...8570940996321556_6613785466010075519_n.jpg | Bin 0 -> 15035 bytes ...8580789888670000_2158336133679231152_n.jpg | Bin 0 -> 11371 bytes ...8580788705336785_8040240833958164225_n.jpg | Bin 0 -> 13746 bytes .../images/thumbnails/5.jpg | Bin 0 -> 21050 bytes ...2159856217430098_8842486812262793216_n.jpg | Bin 0 -> 13253 bytes .../images/thumbnails/Collaboration_1.png | Bin 0 -> 89652 bytes .../images/thumbnails/Collections22-23.png | Bin 0 -> 54384 bytes .../images/thumbnails/Daige_logo.png | Bin 0 -> 28813 bytes .../images/thumbnails/Hero.png | Bin 0 -> 103762 bytes .../Képernyőkép 2025-03-13 195512.png | Bin 0 -> 158374 bytes .../Képernyőkép 2025-06-10 231302.png | Bin 0 -> 38858 bytes .../images/thumbnails/Melinda.png | Bin 0 -> 108597 bytes .../images/thumbnails/Multicategory brand.png | Bin 0 -> 54103 bytes .../images/thumbnails/Robotics.png | Bin 0 -> 93243 bytes .../images/thumbnails/Seemgen_logo_1000.png | Bin 0 -> 41362 bytes .../images/thumbnails/The_atelier.png | Bin 0 -> 75963 bytes .../images/thumbnails/Vhembe-1.jpg | Bin 0 -> 22345 bytes .../images/thumbnails/Vhembe-10.jpg | Bin 0 -> 16387 bytes .../images/thumbnails/Vhembe-11.png | Bin 0 -> 27421 bytes .../images/thumbnails/Vhembe-12.png | Bin 0 -> 24530 bytes .../images/thumbnails/Vhembe-13.jpg | Bin 0 -> 23630 bytes .../images/thumbnails/Vhembe-14.jpg | Bin 0 -> 10359 bytes .../images/thumbnails/Vhembe-2.jpg | Bin 0 -> 21282 bytes .../images/thumbnails/Vhembe-3.jpg | Bin 0 -> 12694 bytes .../images/thumbnails/Vhembe-4.png | Bin 0 -> 33254 bytes .../images/thumbnails/Vhembe-6.jpg | Bin 0 -> 6714 bytes .../images/thumbnails/Vhembe-8.jpg | Bin 0 -> 8263 bytes .../images/thumbnails/Vhembe-9.jpg | Bin 0 -> 8534 bytes .../images/thumbnails/Vhembe-news-1.jpg | Bin 0 -> 16920 bytes .../images/thumbnails/Vhembe-news-2.jpg | Bin 0 -> 19696 bytes .../images/thumbnails/Vhembe-news-3-b.jpg | Bin 0 -> 14243 bytes .../images/thumbnails/Vhembe-news-3.jpg | Bin 0 -> 13556 bytes .../images/thumbnails/Vhembe-news-4.jpg | Bin 0 -> 32127 bytes .../images/thumbnails/Vhembe_logo.png | Bin 0 -> 114610 bytes .../images/thumbnails/ai_voice_agent.jpg | Bin 0 -> 24778 bytes .../images/thumbnails/all moods.png | Bin 0 -> 14488 bytes .../thumbnails/article-1-header-cover.jpg | Bin 0 -> 25971 bytes .../thumbnails/article-in-content-image.jpg | Bin 0 -> 19463 bytes .../images/thumbnails/beleptetorendszerek.jpg | Bin 0 -> 36153 bytes .../images/thumbnails/csomagok.png | Bin 0 -> 72892 bytes .../images/thumbnails/darkstar.png | Bin 0 -> 70490 bytes .../images/thumbnails/gepilatas.jpg | Bin 0 -> 39052 bytes .../growtika-nGoCBxiaRO0-unsplash.jpg | Bin 0 -> 16884 bytes .../thumbnails/halfscreen-parallax-img-1.jpg | Bin 0 -> 17725 bytes .../thumbnails/halfscreen-parallax-img-2.jpg | Bin 0 -> 19030 bytes .../images/thumbnails/hero-image-03_b.jpg | Bin 0 -> 10293 bytes .../images/thumbnails/ipar40.jpg | Bin 0 -> 46967 bytes .../images/thumbnails/knitwear.jpg | Bin 0 -> 11983 bytes ...n-sales-solutions-oFMI6CdD7yU-unsplash.jpg | Bin 0 -> 23017 bytes .../images/thumbnails/logo_social.jpg | Bin 0 -> 19904 bytes .../images/thumbnails/makita4190D.png | Bin 0 -> 8798 bytes .../thumbnails/makita4190D_figure_1.png | Bin 0 -> 27668 bytes .../images/thumbnails/munkaero.jpg | Bin 0 -> 44760 bytes .../images/thumbnails/original_prints.jpg | Bin 0 -> 36878 bytes .../images/thumbnails/press_1.png | Bin 0 -> 83712 bytes .../images/thumbnails/press_2.png | Bin 0 -> 62727 bytes .../images/thumbnails/press_3.jpg | Bin 0 -> 19920 bytes .../images/thumbnails/press_4.jpg | Bin 0 -> 16206 bytes .../images/thumbnails/press_5.png | Bin 0 -> 70217 bytes .../images/thumbnails/press_6.png | Bin 0 -> 104938 bytes .../images/thumbnails/ribi1_bg.png | Bin 0 -> 22593 bytes .../images/thumbnails/ribi1_brighter.png | Bin 0 -> 38164 bytes .../images/thumbnails/ribi1_front.png | Bin 0 -> 46424 bytes .../images/thumbnails/salespower_2.png | Bin 0 -> 71032 bytes .../images/thumbnails/salespower_logo.png | Bin 0 -> 24918 bytes .../images/thumbnails/seemgen.png | Bin 0 -> 106148 bytes .../images/thumbnails/stocklist.jpg | Bin 0 -> 27872 bytes .../images/thumbnails/szoftver.jpg | Bin 0 -> 51980 bytes .../images/thumbnails/szoftverrobotok.jpg | Bin 0 -> 46562 bytes .../images/thumbnails/voicechat.png | Bin 0 -> 104814 bytes .../images/thumbnails/webshop.png | Bin 0 -> 64491 bytes 163 files changed, 10248 insertions(+), 78913 deletions(-) create mode 100644 Components/Pages/ManageContentGroups.razor create mode 100644 Components/Partials/ContentItemList.razor create mode 100644 Components/Partials/DialogCardPage.razor create mode 100644 Components/Partials/EditContentGroup.razor create mode 100644 Components/Partials/EditContentItem.razor create mode 100644 Components/Partials/EditorUIComponentBase.cs create mode 100644 Components/Partials/FooterComponent.razor create mode 100644 Components/Partials/ManageContentGroupsPartial.razor create mode 100644 Components/Partials/ManageSiteInfoPartial.razor create mode 100644 Components/Partials/NewNavMenu.razor create mode 100644 Helpers/ChunkingHelper.cs create mode 100644 Helpers/Notification.cs create mode 100644 Helpers/VectorHashHelper.cs create mode 100644 Migrations/20250617221435_CollectionAdministrationUpdate.Designer.cs create mode 100644 Migrations/20250617221435_CollectionAdministrationUpdate.cs create mode 100644 Migrations/20250617224307_CollectionAdministrationUpdateFIX.Designer.cs create mode 100644 Migrations/20250617224307_CollectionAdministrationUpdateFIX.cs create mode 100644 Migrations/20250618105221_CollectionAdministrationUpdate2.Designer.cs create mode 100644 Migrations/20250618105221_CollectionAdministrationUpdate2.cs create mode 100644 Migrations/20250625185236_StoredCollectionName.Designer.cs create mode 100644 Migrations/20250625185236_StoredCollectionName.cs create mode 100644 Migrations/20250628191216_logger.Designer.cs create mode 100644 Migrations/20250628191216_logger.cs create mode 100644 Models/AiPrompts.cs create mode 100644 Models/AppLog.cs create mode 100644 Models/ContentChunk.cs create mode 100644 Models/ContentGroup.cs create mode 100644 Models/ContentGroupModel.cs create mode 100644 Models/ContentItem.cs create mode 100644 Models/ContentItemModel.cs create mode 100644 Models/WebsiteContentModel.cs create mode 100644 SeemGen.Tests/ContentEditorServiceTests.cs create mode 100644 SeemGen.Tests/SeemGen.Tests.csproj create mode 100644 SeemGen.Tests/UnitTest1.cs create mode 100644 Services/ContentEditorAIService.cs create mode 100644 Services/ISimpleLogger.cs create mode 100644 Services/SimpleLogger.cs create mode 100644 Services/WebsiteContentLoaderService.cs create mode 100644 wwwroot/admin.css create mode 100644 wwwroot/scripts/finisher-header.es5.min.js delete mode 100644 wwwroot/temp/style_19779c82.css delete mode 100644 wwwroot/temp/style_1f958996.css delete mode 100644 wwwroot/temp/style_2c483fdb.css delete mode 100644 wwwroot/temp/style_4f82336e.css delete mode 100644 wwwroot/temp/style_63bf07cf.css rename wwwroot/temp/{style_dc975e92.css => style_7c8bd76c.css} (72%) delete mode 100644 wwwroot/temp/style_ab67f439.css delete mode 100644 wwwroot/temp/style_b06ef8f3.css delete mode 100644 wwwroot/temp/style_cb747a87.css delete mode 100644 wwwroot/temp/style_dbd3e4db.css delete mode 100644 wwwroot/temp/style_fc8f1da8.css create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/szoftver.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/10262403.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/267111581_6537457352993553_2093941074766316375_n.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/464609293_8553833781365611_797678058825756959_n.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/464702374_8571192746296381_2492674641604205759_n.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/464847960_8560471694035153_8000699131803786124_n.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/464867041_8570940996321556_6613785466010075519_n.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/464947949_8580789888670000_2158336133679231152_n.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/465164116_8580788705336785_8040240833958164225_n.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/5.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/58441485_2159856217430098_8842486812262793216_n.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Collaboration_1.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Collections22-23.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Daige_logo.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Hero.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Képernyőkép 2025-03-13 195512.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Képernyőkép 2025-06-10 231302.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Melinda.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Multicategory brand.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Robotics.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Seemgen_logo_1000.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/The_atelier.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-1.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-10.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-11.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-12.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-13.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-14.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-2.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-3.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-4.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-6.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-8.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-9.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-news-1.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-news-2.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-news-3-b.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-news-3.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe-news-4.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/Vhembe_logo.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/ai_voice_agent.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/all moods.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/article-1-header-cover.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/article-in-content-image.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/beleptetorendszerek.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/csomagok.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/darkstar.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/gepilatas.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/growtika-nGoCBxiaRO0-unsplash.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/halfscreen-parallax-img-1.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/halfscreen-parallax-img-2.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/hero-image-03_b.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/ipar40.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/knitwear.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/linkedin-sales-solutions-oFMI6CdD7yU-unsplash.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/logo_social.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/makita4190D.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/makita4190D_figure_1.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/munkaero.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/original_prints.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/press_1.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/press_2.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/press_3.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/press_4.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/press_5.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/press_6.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/ribi1_bg.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/ribi1_brighter.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/ribi1_front.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/salespower_2.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/salespower_logo.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/seemgen.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/stocklist.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/szoftver.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/szoftverrobotok.jpg create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/voicechat.png create mode 100644 wwwroot/uploads/0988758e-e16c-4c2c-8c1e-efa3ac5f0274/images/thumbnails/webshop.png diff --git a/BLAIzor.csproj b/BLAIzor.csproj index 35ed0f9..d2ed224 100644 --- a/BLAIzor.csproj +++ b/BLAIzor.csproj @@ -7,6 +7,13 @@ BLAIzor + + + + + + + @@ -30,9 +37,11 @@ - + + + @@ -57,6 +66,9 @@ Always + + Always + Always diff --git a/BLAIzor.sln b/BLAIzor.sln index b40073c..b649b0b 100644 --- a/BLAIzor.sln +++ b/BLAIzor.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 17.10.35004.147 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BLAIzor", "BLAIzor.csproj", "{A7A021E4-C303-4DF0-B55B-CE3233137085}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SeemGen.Tests", "SeemGen.Tests\SeemGen.Tests.csproj", "{9B3FF465-BD0D-F50F-F19B-E2D1338E7FE6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {A7A021E4-C303-4DF0-B55B-CE3233137085}.Debug|Any CPU.Build.0 = Debug|Any CPU {A7A021E4-C303-4DF0-B55B-CE3233137085}.Release|Any CPU.ActiveCfg = Release|Any CPU {A7A021E4-C303-4DF0-B55B-CE3233137085}.Release|Any CPU.Build.0 = Release|Any CPU + {9B3FF465-BD0D-F50F-F19B-E2D1338E7FE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B3FF465-BD0D-F50F-F19B-E2D1338E7FE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B3FF465-BD0D-F50F-F19B-E2D1338E7FE6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B3FF465-BD0D-F50F-F19B-E2D1338E7FE6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Components/App.razor b/Components/App.razor index c5981d1..11dffec 100644 --- a/Components/App.razor +++ b/Components/App.razor @@ -12,6 +12,7 @@ + @@ -23,6 +24,7 @@ + @* - + + diff --git a/Components/Layout/MainLayout.razor b/Components/Layout/MainLayout.razor index 1ec84bc..d98ce7d 100644 --- a/Components/Layout/MainLayout.razor +++ b/Components/Layout/MainLayout.razor @@ -1,6 +1,6 @@ @using BLAIzor.Services @inherits LayoutComponentBase - + @Body
diff --git a/Components/Pages/CreateForm.razor b/Components/Pages/CreateForm.razor index 966e2c4..1605fcf 100644 --- a/Components/Pages/CreateForm.razor +++ b/Components/Pages/CreateForm.razor @@ -8,7 +8,7 @@ @using BLAIzor.Components.Layout @attribute [Authorize] @layout AdminLayout -@inject ContentEditorService ContentEditorService +@inject ContentEditorAIService ContentEditorAIService

Create a new from from pdf or word

@@ -68,7 +68,7 @@ private async Task> CallAiForFieldExtraction(string plainText) { - var jsonResult = await ContentEditorService.AnalyzeGroupedFormFieldsFromText(plainText); + var jsonResult = await ContentEditorAIService.AnalyzeGroupedFormFieldsFromText(plainText); Console.WriteLine($"📄 PDF form AI response: {jsonResult}"); try diff --git a/Components/Pages/Index.razor b/Components/Pages/Index.razor index d158f86..d9a0877 100644 --- a/Components/Pages/Index.razor +++ b/Components/Pages/Index.razor @@ -1,4 +1,4 @@ -@page "/" +@page "/" @page "/menu/{topic?}" @inherits MainPageBase @using BLAIzor.Models @@ -21,44 +21,52 @@ -
- -
+
+ +
-
- Home - - @* +
+ Home + @{ + if(SiteInfo!= null) + { + if (!string.IsNullOrEmpty(SiteInfo.BackgroundVideo)) + { + + } + } + } + @* *@ -
+
- @*
*@ + @*
*@ -
-
+
@@ -190,19 +199,6 @@ private string ChatGptResponse = string.Empty; private bool isRecording = false; - // private string FirstColumnClass = ""; - // private bool isEmailFormVisible = false; - - // private ContactFormModel ContactFormModel = new(); - // // private string? SuccessMessage; - // // private string? ErrorMessage; - // private string? DocumentEmailAddress = ""; - - private string dynamicallyLoadedCss = string.Empty; - - private string Menu; - - private void AllowAIVoice() { AiVoicePermitted = true; @@ -210,7 +206,7 @@ private void MuteAI() { AiVoicePermitted = false; - } + } protected override async Task OnAfterRenderAsync(bool firstRender) { @@ -234,7 +230,7 @@ SelectedBrandName = "default"; } Subdomain = HttpContextAccessor.HttpContext?.Items["Subdomain"]?.ToString(); - SiteInfo = await _scopedContentService.GetSiteInfoByNameAsync(Subdomain); + SiteInfo = await _contentEditorService.GetSiteInfoByNameAsync(Subdomain); if (SiteInfo != null && SiteInfo.IsPublished) { @@ -253,6 +249,8 @@ STTEnabled = false; } _scopedContentService.SelectedSiteId = SiteId; + ContentCollectionName = SiteInfo.VectorCollectionName ?? "default_content_collection"; + Console.Write("------------------------"); // Load the CSS template for the selected brand from the database @@ -273,16 +271,19 @@ Console.Write($"------------------------ {SiteInfo.MenuItems}, {SiteId}, {SiteInfo.TemplateId}, {SiteInfo.SiteName}"); Menu = await GetMenuList(SiteId); + MenuItems = await GetMenuItems(SiteId); if (string.IsNullOrEmpty(HtmlContent.ToString())) { - if(!string.IsNullOrWhiteSpace(topic)) + if (!string.IsNullOrWhiteSpace(topic)) { UserInput = topic; - await ChatGptService.ProcessContentRequest(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, Menu, true); + await ChatGptService.ProcessContentRequest(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, ContentCollectionName, Menu, true); } else - { + { await ChatGptService.GetChatGptWelcomeMessage(SessionId, SiteId, TemplateCollectionName, Menu); + SiteModel = await ChatGptService.InitSite(SessionId, SiteId, TemplateCollectionName, Menu); + //await ChatGptService.ProcessContentRequest(SessionId, MenuItems.FirstOrDefault(), SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, Menu, true); } // HtmlContent = await ChatGptService.GetChatGptWelcomeMessage(); // UserInput = "Sumerize for me, what is this website about, and what can I do on this website?"; @@ -340,7 +341,7 @@ VoiceEnabled = configuration?.GetSection("AiSettings")?.GetValue("VoiceActivated") ?? false; } - private async void UpdateContent(string receivedSessionId, string content) + private async void UpdateContent(string receivedSessionId, string content, MenuItem? menuItem) { if (receivedSessionId == SessionId) // Only accept messages meant for this tab { diff --git a/Components/Pages/MainPageBase.cs b/Components/Pages/MainPageBase.cs index 3794794..87ce250 100644 --- a/Components/Pages/MainPageBase.cs +++ b/Components/Pages/MainPageBase.cs @@ -1,19 +1,17 @@ using BLAIzor.Models; using BLAIzor.Services; -using Google.Api; using Google.Cloud.Speech.V1; using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; -using System.Collections; +using Radzen; using System.Text; using System.Text.Json; -using UglyToad.PdfPig.DocumentLayoutAnalysis; namespace BLAIzor.Components.Pages { public class MainPageBase : ComponentBase - { + { public string SelectedBrandName = "default"; [Inject] protected ScopedContentService _scopedContentService { get; set; } [Inject] protected ContentEditorService _contentEditorService { get; set; } @@ -21,6 +19,7 @@ namespace BLAIzor.Components.Pages [Inject] protected HttpClient Http { get; set; } [Inject] protected IJSRuntime jsRuntime { get; set; } [Inject] protected AIService ChatGptService { get; set; } + [Inject] NotificationService NotificationService { get; set; } public static readonly Dictionary _instances = new(); @@ -34,6 +33,7 @@ namespace BLAIzor.Components.Pages public string StatusContent = ""; public string UserInput = string.Empty; public string TemplateCollectionName = "html_snippets"; + public string ContentCollectionName = ""; public bool VoiceEnabled; public bool TTSEnabled; @@ -49,6 +49,13 @@ namespace BLAIzor.Components.Pages // private string? ErrorMessage; public string? DocumentEmailAddress = ""; + public string Menu; + public List MenuItems = new(); + public string dynamicallyLoadedCss = string.Empty; + public MenuItem currentMenuItem = new(); + + public WebsiteContentModel SiteModel = new(); + public void DoSharedWork() { // Logic here @@ -91,13 +98,13 @@ namespace BLAIzor.Components.Pages public async Task> GetMenuItems(int siteId) { - List menuItems = (await _contentEditorService.GetMenuItemsBySiteIdAsync(siteId)).Where(m => m.ShowInMainMenu == true).OrderBy(m => m.SortOrder).ToList(); + List menuItems = (await _contentEditorService.GetMenuItemsBySiteIdWithChildrenAsync(siteId)).Where(m => m.ShowInMainMenu == true).OrderBy(m => m.SortOrder).ToList(); return menuItems; } private string GetApiKey() => - configuration?.GetSection("ElevenLabsAPI")?.GetValue("ApiKey") ?? string.Empty; + configuration?.GetSection("ElevenLabsAPI")?.GetValue("ApiKey") ?? string.Empty; public async Task ConvertTextToSpeech(string textContent) { @@ -211,14 +218,26 @@ namespace BLAIzor.Components.Pages { HtmlContent.Clear(); var menu = await GetMenuList(SiteId); - var menuItem = (await GetMenuItems(SiteId)).Where(m => m.Name == input).FirstOrDefault(); + var menuList = await GetMenuItems(SiteId); + + var menuItem = CompareMenuItemNames(input, menuList); if (menuItem == null) { - await ChatGptService.ProcessContentRequest(SessionId, input, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu, forceUnmodified); + await ChatGptService.ProcessContentRequest(SessionId, input, SiteId, (int)SiteInfo.TemplateId!, ContentCollectionName, menu, forceUnmodified); } else { - await ChatGptService.ProcessContentRequest(SessionId, menuItem, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu, forceUnmodified); + currentMenuItem = menuItem; + if (!string.IsNullOrEmpty(menuItem.StoredHtml)) + { + + HtmlContent.Clear(); + HtmlContent.Append(menuItem.StoredHtml); + } + else + { + await ChatGptService.ProcessContentRequest(SessionId, menuItem, SiteId, (int)SiteInfo.TemplateId!, ContentCollectionName, menu, forceUnmodified); + } } UserInput = string.Empty; } @@ -296,16 +315,40 @@ namespace BLAIzor.Components.Pages Console.Write("openEmail with: " + emailAddress); } - public async Task SendMessage() { Console.WriteLine("Button clicked!"); var menu = await GetMenuList(SiteId); HtmlContent.Clear(); - await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu); + await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, ContentCollectionName, menu); UserInput = string.Empty; } + public MenuItem CompareMenuItemNames(string input, List menuList) + { + var parent = menuList.FirstOrDefault(ml => ml.Name == input); + if (parent != null) + { + return parent; + } + + foreach (var item in menuList) + { + var child = item.Children.FirstOrDefault(ch => ch.Name == input); + if (child != null) + { + return child; + } + } + return null; // or throw, or return a default + } + + public void ShowNotification(NotificationMessage message) + { + NotificationService.Notify(message); + } + + } } diff --git a/Components/Pages/ManageContentGroups.razor b/Components/Pages/ManageContentGroups.razor new file mode 100644 index 0000000..8678003 --- /dev/null +++ b/Components/Pages/ManageContentGroups.razor @@ -0,0 +1,127 @@ +@page "/site/{SiteInfoId:int}/content-groups" +@using BLAIzor.Components.Layout +@using BLAIzor.Models +@using BLAIzor.Services +@using Microsoft.AspNetCore.Components.Authorization +@layout AdminLayout +@inject ContentEditorService contentEditorService +@inject NavigationManager Navigation +@attribute [Authorize] + +@if (isLoading) +{ +

Loading content groups...

+} +else +{ + @foreach (var group in groups) + { + if (selectedGroupId == group.Id) + { + +
+ + +
+ + + +
+
+
+ } + else + { +
+
+ @group.Name
+ @group.Type +
+ +
+ } + } + + +} + + + +@code { + [Parameter] + public int SiteInfoId { get; set; } + + private List groups = new(); + private bool isLoading = true; + + private int? selectedGroupId = null; + + private void SelectGroup(int groupId) + { + selectedGroupId = groupId; + } + + private void DeselectGroup() + { + selectedGroupId = null; + } + + + protected override async Task OnInitializedAsync() + { + isLoading = true; + groups = (await contentEditorService.GetContentGroupsBySiteInfoIdAsync(SiteInfoId)) + .Where(g => g.SiteInfoId == SiteInfoId) + .OrderByDescending(g => g.LastUpdated) + .ToList(); + isLoading = false; + } + + private void EditGroup(ContentGroup group) + { + Navigation.NavigateTo($"/content-group/{group.Id}/items"); + } + + private async Task SaveGroup(ContentGroup group) + { + group.LastUpdated = DateTime.UtcNow; + group.Version = group.Version + 1; + var result = await contentEditorService.UpdateContentGroupByIdAsync(group); + if(result != null) ; + } + + private async Task DeleteGroup(ContentGroup group) + { + + var result = await contentEditorService.DeleteContentGroupByIdAsync(group.Id); ; + groups.Remove(group); + } + + private async Task AddNewGroup() + { + var newGroup = new ContentGroup + { + SiteInfoId = SiteInfoId, + Name = "New Group", + Slug = $"group-{DateTime.UtcNow.Ticks}", + Type = "manual", + VectorSize = 384, + EmbeddingModel = "default", + CreatedAt = DateTime.UtcNow, + LastUpdated = DateTime.UtcNow, + Version = 1 + }; + var result = await contentEditorService.CreateContentGroupAsync(newGroup); + if(result!=null) + { + groups.Insert(0, newGroup); + } + } + +} diff --git a/Components/Pages/ManageSiteInfo.razor b/Components/Pages/ManageSiteInfo.razor index dc13f66..41d124e 100644 --- a/Components/Pages/ManageSiteInfo.razor +++ b/Components/Pages/ManageSiteInfo.razor @@ -5,33 +5,35 @@ @using BLAIzor.Services @using Microsoft.AspNetCore.Components.Authorization @layout AdminLayout -@inject ScopedContentService SiteInfoService +@inject ContentEditorService _contentEditorService @inject AuthenticationStateProvider AuthenticationStateProvider @inject CustomAuthenticationStateProvider CustomAuthProvider -

Site Information

- +