diff --git a/.gitignore b/.gitignore index 8c2a178d7..c74360ae0 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ vue-i18n-locales.generated.js vite.config.js .DS_Store resources/excel/example.xlsx +resources/ai-agent-plans/* diff --git a/app/Nova/TrainingResource.php b/app/Nova/TrainingResource.php index 1c5e35bce..5cc0138b5 100644 --- a/app/Nova/TrainingResource.php +++ b/app/Nova/TrainingResource.php @@ -82,6 +82,22 @@ public function fields(Request $request): array ->nullable() ->help('Optional pill text in the header banner'), + Text::make('Hero button text', 'hero_button_text') + ->nullable() + ->help('Optional primary CTA shown in the hero section.'), + + Text::make('Hero button URL', 'hero_button_url') + ->nullable() + ->help('Supports full URLs, root-relative paths, or #anchors.'), + + Text::make('Hero secondary button text', 'hero_secondary_button_text') + ->nullable() + ->help('Optional outline CTA shown beside the hero primary button.'), + + Text::make('Hero secondary button URL', 'hero_secondary_button_url') + ->nullable() + ->help('Supports full URLs, root-relative paths, or #anchors.'), + Trix::make('Intro', 'intro') ->nullable() ->help('Optional intro block shown above the main content'), @@ -126,6 +142,16 @@ public function fields(Request $request): array ->nullable() ->help('Optional text shown in a highlighted callout box (register on map, hashtags, etc).'), + Trix::make('About box section', 'about_box_section') + ->nullable() + ->help('Optional blue info card shown below register box (supports heading, text, lists).'), + + Number::make('Anchor offset', 'anchor_offset') + ->min(0) + ->step(1) + ->nullable() + ->help('Optional scroll offset in pixels for in-page anchor links (useful with sticky headers).'), + Text::make('Button text', 'button_text')->nullable(), Text::make('Button URL', 'button_url') diff --git a/app/TrainingResource.php b/app/TrainingResource.php index 1c98026a9..58774377c 100644 --- a/app/TrainingResource.php +++ b/app/TrainingResource.php @@ -17,6 +17,10 @@ class TrainingResource extends Model 'card_image', 'page_title', 'hero_author', + 'hero_button_text', + 'hero_button_url', + 'hero_secondary_button_text', + 'hero_secondary_button_url', 'intro', 'highlight_box', 'video_url', @@ -28,6 +32,8 @@ class TrainingResource extends Model 'pdf_links_section', 'contacts_section', 'register_box_section', + 'about_box_section', + 'anchor_offset', 'button_text', 'button_url', 'secondary_button_text', @@ -43,6 +49,7 @@ class TrainingResource extends Model protected $casts = [ 'active' => 'boolean', 'position' => 'integer', + 'anchor_offset' => 'integer', ]; public function scopeActive($query) diff --git a/database/migrations/2026_04_29_110000_add_hero_button_fields_to_training_resources_table.php b/database/migrations/2026_04_29_110000_add_hero_button_fields_to_training_resources_table.php new file mode 100644 index 000000000..3af1f7067 --- /dev/null +++ b/database/migrations/2026_04_29_110000_add_hero_button_fields_to_training_resources_table.php @@ -0,0 +1,36 @@ +string('hero_button_text')->nullable()->after('hero_author'); + $table->string('hero_button_url')->nullable()->after('hero_button_text'); + $table->string('hero_secondary_button_text')->nullable()->after('hero_button_url'); + $table->string('hero_secondary_button_url')->nullable()->after('hero_secondary_button_text'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('training_resources', function (Blueprint $table) { + $table->dropColumn([ + 'hero_button_text', + 'hero_button_url', + 'hero_secondary_button_text', + 'hero_secondary_button_url', + ]); + }); + } +}; diff --git a/database/migrations/2026_04_29_113000_add_about_box_and_anchor_offset_to_training_resources_table.php b/database/migrations/2026_04_29_113000_add_about_box_and_anchor_offset_to_training_resources_table.php new file mode 100644 index 000000000..d2787ed6e --- /dev/null +++ b/database/migrations/2026_04_29_113000_add_about_box_and_anchor_offset_to_training_resources_table.php @@ -0,0 +1,32 @@ +longText('about_box_section')->nullable()->after('register_box_section'); + $table->unsignedInteger('anchor_offset')->nullable()->after('about_box_section'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('training_resources', function (Blueprint $table) { + $table->dropColumn([ + 'about_box_section', + 'anchor_offset', + ]); + }); + } +}; diff --git a/database/seeders/TrainingResourceDiscoverDigitalProgrammeSeeder.php b/database/seeders/TrainingResourceDiscoverDigitalProgrammeSeeder.php new file mode 100644 index 000000000..7507befe8 --- /dev/null +++ b/database/seeders/TrainingResourceDiscoverDigitalProgrammeSeeder.php @@ -0,0 +1,106 @@ + 'discover-digital-programme'], + [ + 'card_title' => 'Discover Digital Programme', + 'card_author' => 'Code4Europe | Deliverable D4.2 | Public toolkit', + // Temporary thumbnail until final artwork is provided. + 'card_image' => '/images/banner_training.svg', + 'page_title' => 'Discover Digital Programme', + 'hero_author' => 'Code4Europe | Deliverable D4.2 | Public toolkit', + 'hero_button_text' => 'Open the complete toolkit', + 'hero_button_url' => 'https://codeweek-resources.s3.eu-west-1.amazonaws.com/+discover-digital-toolkit/DDP_toolkit.pdf', + 'hero_secondary_button_text' => 'Get the one-pagers pack', + 'hero_secondary_button_url' => '#key-one-pagers', + 'intro' => <<A practical toolkit for higher education institutions (HEIs) with an ICT and STEM focus to engage secondary school students through school visits, campus experiences, and digital outreach, supporting learners in the senior cycle of secondary education to imagine themselves in technology careers and understand the academic pathways that will lead them there.
+HTML, + 'content' => <<How the toolkit works +The toolkit is organised as a flexible, non-prescriptive set of steps and formats. It structures engagement into two mirroring frameworks: STEM On Tour (bringing higher education into schools and community settings) and STEM In (bringing students into a higher education institution through campus visits, open days, and themed events). HEIs may implement either framework independently or combine both for greater impact.
+Use this roadmap if you do not have time to read the full deliverable. The one-pagers mirror the toolkit flow and provide a practical checklist for implementation.
+ +These documents summarise the main operational parts of the toolkit.
+These documents provide the supporting operational detail referenced in the key one-pagers.
+Register school visits, campus visits, open days, workshops, and outreach actions on the EU Code Week platform to support visibility, coordination, and cumulative impact across the ecosystem.
+HTML, + 'about_box_section' => <<About this toolkit +The programme serves as a bridge between secondary and higher education at a critical stage in the student journey. It addresses two common challenges: students who feel overwhelmed by the range of choices available and students who disengage because higher education feels distant or irrelevant. The toolkit provides structured guidance, adaptable frameworks and models, and opportunities to experience what a future educational path in STEM can look and feel like, while also engaging families and key stakeholders within secondary education.
+