From 7666aa8a6ee7a2a6b20ed59fa7795fe8847d85e8 Mon Sep 17 00:00:00 2001 From: roble Date: Sat, 25 Apr 2026 21:58:47 +0100 Subject: [PATCH 01/11] feat: refactor demo module structure and update related configurations --- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- Taskfile.yml | 4 +-- app/Http/Controllers/DemoController.php | 35 ------------------------- app/Providers/DemoServiceProvider.php | 16 ----------- app/Providers/RouteServiceProvider.php | 17 ------------ composer.json | 13 ++++++--- database/seeders/DatabaseSeeder.php | 10 +++++++ module.json | 15 ----------- resources/js/pages/Index.vue | 6 ++--- resources/js/types/page-props.d.ts | 2 +- routes/api.php | 8 ------ routes/web.php | 6 ----- {app => src}/Filament/DemoPlugin.php | 0 src/Http/Controllers/DemoController.php | 30 +++++++++++++++++++++ src/Providers/DemoServiceProvider.php | 9 +++++++ tests/Feature/DatabaseSeederTest.php | 16 +++++++++++ 17 files changed, 82 insertions(+), 109 deletions(-) delete mode 100644 app/Http/Controllers/DemoController.php delete mode 100644 app/Providers/DemoServiceProvider.php delete mode 100644 app/Providers/RouteServiceProvider.php create mode 100644 database/seeders/DatabaseSeeder.php delete mode 100644 module.json delete mode 100644 routes/api.php delete mode 100644 routes/web.php rename {app => src}/Filament/DemoPlugin.php (100%) create mode 100644 src/Http/Controllers/DemoController.php create mode 100644 src/Providers/DemoServiceProvider.php create mode 100644 tests/Feature/DatabaseSeederTest.php diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e6d0709..160d817 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: release: uses: saucebase-dev/saucebase/.github/workflows/semantic-release.yml@main with: - version_file: 'module.json' + version_file: 'composer.json' version_file_path: '.version' prerelease: false secrets: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e338f2f..207bd53 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,5 +13,5 @@ jobs: test: uses: saucebase-dev/saucebase/.github/workflows/test-module.yml@main with: - module: Demo + module: demo dependencies: saucebase/auth saucebase/settings saucebase/billing saucebase/announcements saucebase/blog saucebase/roadmap saucebase/themes diff --git a/Taskfile.yml b/Taskfile.yml index 692eeee..807f163 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -9,11 +9,11 @@ tasks: test:e2e: desc: Run E2E tests for Demo module - cmd: npx playwright test --project="@Demo*" {{.CLI_ARGS}} + cmd: npx playwright test --project="@demo*" {{.CLI_ARGS}} interactive: true # ── Code Generation ──────────────────────────────────────────── types:generate: desc: Generate TypeScript types from PHP DTOs and enums - cmd: php artisan module:generate-types Demo + cmd: php artisan module:generate-types demo diff --git a/app/Http/Controllers/DemoController.php b/app/Http/Controllers/DemoController.php deleted file mode 100644 index 3f10d73..0000000 --- a/app/Http/Controllers/DemoController.php +++ /dev/null @@ -1,35 +0,0 @@ -isEnabled('Billing')) { - $data['products'] = Product::displayable()->get(); - } - - if (app('modules')->isEnabled('Blog')) { - $posts = Post::published() - ->with(['category', 'author']) - ->orderByDesc('published_at') - ->limit(3) - ->get(); - - $data['latestPosts'] = $posts->map(fn (Post $post) => PostData::fromPost($post)); - } - - return Inertia::render('Demo::Index', $data)->withSSR(); - } -} diff --git a/app/Providers/DemoServiceProvider.php b/app/Providers/DemoServiceProvider.php deleted file mode 100644 index 34351ca..0000000 --- a/app/Providers/DemoServiceProvider.php +++ /dev/null @@ -1,16 +0,0 @@ -group(module_path('Demo', '/routes/web.php')); - Route::middleware('api') - ->group(module_path('Demo', '/routes/api.php')); - } -} diff --git a/composer.json b/composer.json index 6fd111f..ff44ac2 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,9 @@ { "name": "saucebase/demo", - "description": "", + "description": "Demo module", "type": "saucebase-module", + "license": "proprietary", + "version": "0.5.0", "authors": [ { "name": "Saucebase", @@ -10,13 +12,15 @@ ], "extra": { "laravel": { - "providers": [], + "providers": [ + "Modules\\Demo\\Providers\\DemoServiceProvider" + ], "aliases": {} } }, "autoload": { "psr-4": { - "Modules\\Demo\\": "app/", + "Modules\\Demo\\": "src/", "Modules\\Demo\\Database\\Factories\\": "database/factories/", "Modules\\Demo\\Database\\Seeders\\": "database/seeders/" } @@ -25,5 +29,6 @@ "psr-4": { "Modules\\Demo\\Tests\\": "tests/" } - } + }, + "minimum-stability": "stable" } diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php new file mode 100644 index 0000000..2eb1421 --- /dev/null +++ b/database/seeders/DatabaseSeeder.php @@ -0,0 +1,10 @@ +prefix('api/v1/demo')->group(function () { -// Route::apiResource('demo', DemoController::class, ['as' => 'api']); -// }); diff --git a/routes/web.php b/routes/web.php deleted file mode 100644 index 7728046..0000000 --- a/routes/web.php +++ /dev/null @@ -1,6 +0,0 @@ -get(); + + $posts = Post::published() + ->with(['category', 'author']) + ->orderByDesc('published_at') + ->limit(3) + ->get(); + + $data['latestPosts'] = $posts->map(fn (Post $post) => PostData::fromPost($post)); + + return Inertia::render('Demo::Index', $data)->withSSR(); + } +} diff --git a/src/Providers/DemoServiceProvider.php b/src/Providers/DemoServiceProvider.php new file mode 100644 index 0000000..d15c14b --- /dev/null +++ b/src/Providers/DemoServiceProvider.php @@ -0,0 +1,9 @@ +seed(DatabaseSeeder::class); + + $this->assertTrue(true); + } +} From 05228b0f6a4f18ff4c524b6662d38503ab706653 Mon Sep 17 00:00:00 2001 From: roble Date: Wed, 29 Apr 2026 21:36:50 +0100 Subject: [PATCH 02/11] feat: add database seeding task for Demo module --- Taskfile.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Taskfile.yml b/Taskfile.yml index 807f163..a9e5ca8 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -12,6 +12,12 @@ tasks: cmd: npx playwright test --project="@demo*" {{.CLI_ARGS}} interactive: true + # ── Database ────────────────────────────────────────────────── + + db:seed: + desc: Seed the Demo module database + cmd: php artisan modules:seed --module=demo + # ── Code Generation ──────────────────────────────────────────── types:generate: From 6e93b7c2737fbc1bd93ec88c65848ed13cca04e4 Mon Sep 17 00:00:00 2001 From: roble Date: Fri, 22 May 2026 21:33:39 +0100 Subject: [PATCH 03/11] feat: implement new sections for demo module including features, testimonials, and tech stack --- resources/js/app.ts | 24 +------------------ resources/js/vue/app.ts | 23 ++++++++++++++++++ resources/js/{ => vue}/pages/Index.vue | 4 ++-- .../{ => vue}/pages/sections/CtaSection.vue | 0 .../{ => vue}/pages/sections/FaqSection.vue | 0 .../pages/sections/FeaturesSection.vue | 0 .../pages/sections/FilamentSection.vue | 0 .../{ => vue}/pages/sections/HeroSection.vue | 0 .../pages/sections/TechStackSection.vue | 0 .../{ => vue}/pages/sections/Testimonial.vue | 0 10 files changed, 26 insertions(+), 25 deletions(-) create mode 100644 resources/js/vue/app.ts rename resources/js/{ => vue}/pages/Index.vue (94%) rename resources/js/{ => vue}/pages/sections/CtaSection.vue (100%) rename resources/js/{ => vue}/pages/sections/FaqSection.vue (100%) rename resources/js/{ => vue}/pages/sections/FeaturesSection.vue (100%) rename resources/js/{ => vue}/pages/sections/FilamentSection.vue (100%) rename resources/js/{ => vue}/pages/sections/HeroSection.vue (100%) rename resources/js/{ => vue}/pages/sections/TechStackSection.vue (100%) rename resources/js/{ => vue}/pages/sections/Testimonial.vue (100%) diff --git a/resources/js/app.ts b/resources/js/app.ts index e9ea054..3043f15 100644 --- a/resources/js/app.ts +++ b/resources/js/app.ts @@ -1,23 +1 @@ -// import { registerIcon } from '@/lib/navigation'; -// import IconExample from '~icons/lucide/example'; - -import '../css/style.css'; - -/** - * Demo module setup - * Called during app initialization before mounting - */ -export function setup() { - console.debug('Demo module loaded'); - - // Register icons for navigation items defined in routes/navigation.php - // registerIcon('demo', IconExample); -} - -/** - * Demo module after mount logic - * Called after the app has been mounted - */ -export function afterMount() { - console.debug('Demo module after mount logic executed'); -} +export * from './vue/app'; diff --git a/resources/js/vue/app.ts b/resources/js/vue/app.ts new file mode 100644 index 0000000..17a4e1c --- /dev/null +++ b/resources/js/vue/app.ts @@ -0,0 +1,23 @@ +// import { registerIcon } from '@/lib/navigation'; +// import IconExample from '~icons/lucide/example'; + +import '@modules/demo/resources/css/style.css'; + +/** + * Demo module setup + * Called during app initialization before mounting + */ +export function setup() { + console.debug('Demo module loaded'); + + // Register icons for navigation items defined in routes/navigation.php + // registerIcon('demo', IconExample); +} + +/** + * Demo module after mount logic + * Called after the app has been mounted + */ +export function afterMount() { + console.debug('Demo module after mount logic executed'); +} diff --git a/resources/js/pages/Index.vue b/resources/js/vue/pages/Index.vue similarity index 94% rename from resources/js/pages/Index.vue rename to resources/js/vue/pages/Index.vue index 65226bd..ab5d840 100644 --- a/resources/js/pages/Index.vue +++ b/resources/js/vue/pages/Index.vue @@ -7,9 +7,9 @@ import FilamentSection from './sections/FilamentSection.vue'; import { Head } from '@inertiajs/vue3'; -import ProductSection from '@modules/billing/resources/js/components/ProductSection.vue'; +import ProductSection from '@modules/billing/resources/js/vue/components/ProductSection.vue'; import type { Product } from '@modules/billing/resources/js/types'; -import LatestPostsSection from '@modules/blog/resources/js/components/LatestPostsSection.vue'; +import LatestPostsSection from '@modules/blog/resources/js/vue/components/LatestPostsSection.vue'; import HeroSection from './sections/HeroSection.vue'; import Testimonial from './sections/Testimonial.vue'; diff --git a/resources/js/pages/sections/CtaSection.vue b/resources/js/vue/pages/sections/CtaSection.vue similarity index 100% rename from resources/js/pages/sections/CtaSection.vue rename to resources/js/vue/pages/sections/CtaSection.vue diff --git a/resources/js/pages/sections/FaqSection.vue b/resources/js/vue/pages/sections/FaqSection.vue similarity index 100% rename from resources/js/pages/sections/FaqSection.vue rename to resources/js/vue/pages/sections/FaqSection.vue diff --git a/resources/js/pages/sections/FeaturesSection.vue b/resources/js/vue/pages/sections/FeaturesSection.vue similarity index 100% rename from resources/js/pages/sections/FeaturesSection.vue rename to resources/js/vue/pages/sections/FeaturesSection.vue diff --git a/resources/js/pages/sections/FilamentSection.vue b/resources/js/vue/pages/sections/FilamentSection.vue similarity index 100% rename from resources/js/pages/sections/FilamentSection.vue rename to resources/js/vue/pages/sections/FilamentSection.vue diff --git a/resources/js/pages/sections/HeroSection.vue b/resources/js/vue/pages/sections/HeroSection.vue similarity index 100% rename from resources/js/pages/sections/HeroSection.vue rename to resources/js/vue/pages/sections/HeroSection.vue diff --git a/resources/js/pages/sections/TechStackSection.vue b/resources/js/vue/pages/sections/TechStackSection.vue similarity index 100% rename from resources/js/pages/sections/TechStackSection.vue rename to resources/js/vue/pages/sections/TechStackSection.vue diff --git a/resources/js/pages/sections/Testimonial.vue b/resources/js/vue/pages/sections/Testimonial.vue similarity index 100% rename from resources/js/pages/sections/Testimonial.vue rename to resources/js/vue/pages/sections/Testimonial.vue From 8bdf62bc20d265bd44dbc5b1533175ada5086483 Mon Sep 17 00:00:00 2001 From: roble Date: Wed, 27 May 2026 19:34:29 +0100 Subject: [PATCH 04/11] feat: add ModulesSection component and integrate it into the Index page --- resources/js/vue/pages/Index.vue | 2 + .../js/vue/pages/sections/FeaturesSection.vue | 50 +++- .../js/vue/pages/sections/HeroSection.vue | 67 +---- .../js/vue/pages/sections/ModulesSection.vue | 256 ++++++++++++++++++ 4 files changed, 305 insertions(+), 70 deletions(-) create mode 100644 resources/js/vue/pages/sections/ModulesSection.vue diff --git a/resources/js/vue/pages/Index.vue b/resources/js/vue/pages/Index.vue index ab5d840..f474204 100644 --- a/resources/js/vue/pages/Index.vue +++ b/resources/js/vue/pages/Index.vue @@ -11,6 +11,7 @@ import ProductSection from '@modules/billing/resources/js/vue/components/Product import type { Product } from '@modules/billing/resources/js/types'; import LatestPostsSection from '@modules/blog/resources/js/vue/components/LatestPostsSection.vue'; import HeroSection from './sections/HeroSection.vue'; +import ModulesSection from './sections/ModulesSection.vue'; import Testimonial from './sections/Testimonial.vue'; defineProps<{ @@ -36,6 +37,7 @@ defineProps<{
+ diff --git a/resources/js/vue/pages/sections/FeaturesSection.vue b/resources/js/vue/pages/sections/FeaturesSection.vue index 49eb72c..876ad8f 100644 --- a/resources/js/vue/pages/sections/FeaturesSection.vue +++ b/resources/js/vue/pages/sections/FeaturesSection.vue @@ -16,52 +16,82 @@ import { const features = [ { name: () => trans('One-command setup'), - description: () => trans('Docker, SSL, MySQL, Redis, Mailpit — one command and you\'re running.'), + description: () => + trans( + "Docker, SSL, MySQL, Redis, Mailpit — one command and you're running.", + ), icon: Terminal, }, { name: () => trans('Full TypeScript'), - description: () => trans('PHP enums and DTOs auto-generate .d.ts types. Type-safe routes via Ziggy.'), + description: () => + trans( + 'PHP enums and DTOs auto-generate .d.ts types. Type-safe routes via Ziggy.', + ), icon: Braces, }, { name: () => trans('Theming system'), - description: () => trans('15 built-in themes, a live visual editor, custom fonts, colors, and border radius.'), + description: () => + trans( + '15 built-in themes, a live visual editor, custom fonts, colors, and border radius.', + ), icon: Paintbrush, }, { name: () => trans('Filament admin'), - description: () => trans('Auto-discovered module plugins. Tables, forms, actions, and widgets — no manual wiring.'), + description: () => + trans( + 'Auto-discovered module plugins. Tables, forms, actions, and widgets — no manual wiring.', + ), icon: LayoutDashboard, }, { name: () => trans('Testing suite'), - description: () => trans('Per-module PHPUnit tests with factories on in-memory SQLite, plus auto-discovered Playwright E2E projects for Chromium.'), + description: () => + trans( + 'Per-module PHPUnit tests with factories on in-memory SQLite, plus auto-discovered Playwright E2E projects for Chromium.', + ), icon: FlaskConical, }, { name: () => trans('Multi-language'), - description: () => trans('Per-module translation files with async loading. Easily add any language with the built-in i18n system.'), + description: () => + trans( + 'Per-module translation files with async loading. Easily add any language with the built-in i18n system.', + ), icon: Languages, }, { name: () => trans('Module navigation'), - description: () => trans('Structured, module-aware navigation and breadcrumbs registered per module.'), + description: () => + trans( + 'Structured, module-aware navigation and breadcrumbs registered per module.', + ), icon: Navigation, }, { name: () => trans('shadcn-vue UI'), - description: () => trans('40+ accessible Tailwind 4 components, copy-and-own, dark mode built-in.'), + description: () => + trans( + '40+ accessible Tailwind 4 components, copy-and-own, dark mode built-in.', + ), icon: Component, }, { name: () => trans('Complete documentation'), - description: () => trans('Full docs site with module guides, architecture docs, and AI-optimized CLAUDE.md files.'), + description: () => + trans( + 'Full docs site with module guides, architecture docs, and AI-optimized CLAUDE.md files.', + ), icon: BookOpen, }, { name: () => trans('SSR opt-in'), - description: () => trans('Per-page server-side rendering for SEO. Public pages opt in, auth pages opt out.'), + description: () => + trans( + 'Per-page server-side rendering for SEO. Public pages opt in, auth pages opt out.', + ), icon: Globe, }, ]; diff --git a/resources/js/vue/pages/sections/HeroSection.vue b/resources/js/vue/pages/sections/HeroSection.vue index a53f974..7bc3e33 100644 --- a/resources/js/vue/pages/sections/HeroSection.vue +++ b/resources/js/vue/pages/sections/HeroSection.vue @@ -1,13 +1,9 @@ diff --git a/resources/js/vue/pages/sections/ModulesSection.vue b/resources/js/vue/pages/sections/ModulesSection.vue new file mode 100644 index 0000000..9ce6ca8 --- /dev/null +++ b/resources/js/vue/pages/sections/ModulesSection.vue @@ -0,0 +1,256 @@ + + + + + From d31c25cbd6a01952875c5218a0d85d7fe3d25737 Mon Sep 17 00:00:00 2001 From: roble Date: Wed, 27 May 2026 20:39:08 +0100 Subject: [PATCH 05/11] feat: enhance HeroSection and ModulesSection with improved layout and styling --- .../js/vue/pages/sections/HeroSection.vue | 133 ++++++++------- .../js/vue/pages/sections/ModulesSection.vue | 154 ++++++------------ 2 files changed, 110 insertions(+), 177 deletions(-) diff --git a/resources/js/vue/pages/sections/HeroSection.vue b/resources/js/vue/pages/sections/HeroSection.vue index 7bc3e33..b2dea76 100644 --- a/resources/js/vue/pages/sections/HeroSection.vue +++ b/resources/js/vue/pages/sections/HeroSection.vue @@ -28,81 +28,76 @@ onUnmounted(() => { diff --git a/resources/js/vue/pages/sections/ModulesSection.vue b/resources/js/vue/pages/sections/ModulesSection.vue index 9ce6ca8..3524825 100644 --- a/resources/js/vue/pages/sections/ModulesSection.vue +++ b/resources/js/vue/pages/sections/ModulesSection.vue @@ -48,75 +48,46 @@ const displayModules = computed(() =>