diff --git a/app/Nova/TrainingResource.php b/app/Nova/TrainingResource.php index dc9a9ea50..9ac5ec18c 100644 --- a/app/Nova/TrainingResource.php +++ b/app/Nova/TrainingResource.php @@ -157,24 +157,26 @@ public function fields(Request $request): array Select::make('Roadmap embed format', 'roadmap_embed_kind') ->options([ - 'pdf' => 'PDF (recommended — keeps clickable links from the file)', + 'pdf' => 'PDF (inline viewer, links inside the file)', + 'image' => 'Image (PNG/JPG thumbnail linking to URL you set)', 'svg' => 'SVG (static graphic; exports usually do not preserve PDF links)', 'none' => 'None (remove placeholder output)', ]) ->default('pdf') - ->help('Put [[embed_roadmap_pdf]] or [[embed_roadmap]] in Content where the roadmap should appear. Use PDF when the roadmap must open real URLs from the document.'), + ->help('Put [[embed_roadmap_pdf]] or [[embed_roadmap]] in Content where the roadmap should appear.'), Text::make('Roadmap PDF embed URL', 'roadmap_pdf_embed_url') ->nullable() ->rules('nullable', 'url') ->dependsOn(['roadmap_embed_kind'], function (Text $field, NovaRequest $request, FormData $formData) { - if (($formData->roadmap_embed_kind ?? 'pdf') === 'pdf') { + $kind = $formData->roadmap_embed_kind ?? 'pdf'; + if ($kind === 'pdf' || $kind === 'image') { $field->show(); } else { $field->hide(); } }) - ->help('HTTPS URL to the PDF. Shown in an iframe with the browser’s built-in PDF viewer so links inside the file stay active.'), + ->help('HTTPS URL to the roadmap PDF. For PDF format this is embedded in-page. For Image format use it too (or Roadmap image link URL) as the PDF click target.'), Textarea::make('Roadmap SVG', 'roadmap_svg') ->nullable() @@ -188,6 +190,30 @@ public function fields(Request $request): array }) ->help('Optional: paste full ... only for a non-interactive graphic. For clickable resources, prefer PDF above.'), + Text::make('Roadmap image URL', 'roadmap_image_url') + ->nullable() + ->rules('nullable', 'url') + ->dependsOn(['roadmap_embed_kind'], function (Text $field, NovaRequest $request, FormData $formData) { + if (($formData->roadmap_embed_kind ?? 'pdf') === 'image') { + $field->show(); + } else { + $field->hide(); + } + }) + ->help('Full URL of the roadmap graphic (e.g. PNG on S3). The whole image is clickable.'), + + Text::make('Roadmap image link URL', 'roadmap_image_link_url') + ->nullable() + ->rules('nullable', 'url') + ->dependsOn(['roadmap_embed_kind'], function (Text $field, NovaRequest $request, FormData $formData) { + if (($formData->roadmap_embed_kind ?? 'pdf') === 'image') { + $field->show(); + } else { + $field->hide(); + } + }) + ->help('Where clicks go (e.g. full PDF). If empty, falls back to Roadmap PDF embed URL.'), + Text::make('Button text', 'button_text')->nullable(), Text::make('Button URL', 'button_url') diff --git a/app/TrainingResource.php b/app/TrainingResource.php index fabc3255c..2db19bc8b 100644 --- a/app/TrainingResource.php +++ b/app/TrainingResource.php @@ -37,6 +37,8 @@ class TrainingResource extends Model 'roadmap_pdf_embed_url', 'roadmap_embed_kind', 'roadmap_svg', + 'roadmap_image_url', + 'roadmap_image_link_url', 'button_text', 'button_url', 'secondary_button_text', diff --git a/database/migrations/2026_05_02_100000_add_roadmap_image_fields_to_training_resources_table.php b/database/migrations/2026_05_02_100000_add_roadmap_image_fields_to_training_resources_table.php new file mode 100644 index 000000000..9f8753757 --- /dev/null +++ b/database/migrations/2026_05_02_100000_add_roadmap_image_fields_to_training_resources_table.php @@ -0,0 +1,23 @@ +string('roadmap_image_url', 2048)->nullable()->after('roadmap_svg'); + $table->string('roadmap_image_link_url', 2048)->nullable()->after('roadmap_image_url'); + }); + } + + public function down(): void + { + Schema::table('training_resources', function (Blueprint $table) { + $table->dropColumn(['roadmap_image_url', 'roadmap_image_link_url']); + }); + } +}; diff --git a/database/seeders/TrainingResourceDiscoverDigitalProgrammeSeeder.php b/database/seeders/TrainingResourceDiscoverDigitalProgrammeSeeder.php index 44c1695d5..b7cf26c7a 100644 --- a/database/seeders/TrainingResourceDiscoverDigitalProgrammeSeeder.php +++ b/database/seeders/TrainingResourceDiscoverDigitalProgrammeSeeder.php @@ -93,6 +93,8 @@ public function run(): void 'roadmap_pdf_embed_url' => 'https://codeweek-resources.s3.eu-west-1.amazonaws.com/+discover-digital-toolkit/DDP_toolkit_roadmap.pdf', 'roadmap_embed_kind' => 'pdf', 'roadmap_svg' => null, + 'roadmap_image_url' => 'https://codeweek-resources.s3.eu-west-1.amazonaws.com/+discover-digital-toolkit/DDP_toolkit_roadmap.png', + 'roadmap_image_link_url' => 'https://codeweek-resources.s3.eu-west-1.amazonaws.com/+discover-digital-toolkit/DDP_toolkit_roadmap.pdf', 'third_button_text' => 'Register an activity', 'third_button_url' => 'https://codeweek.eu/add?skip=1', 'meta_title' => 'Discover Digital Programme - Toolkit', diff --git a/resources/views/training/partials/roadmap-image-embed.blade.php b/resources/views/training/partials/roadmap-image-embed.blade.php new file mode 100644 index 000000000..4b22b06aa --- /dev/null +++ b/resources/views/training/partials/roadmap-image-embed.blade.php @@ -0,0 +1,40 @@ +@props([ + 'imageUrl', + 'linkUrl', + 'altText' => null, +]) +@php + $alt = $altText !== null && trim((string) $altText) !== '' ? trim((string) $altText) : __('Roadmap overview'); + $external = \Illuminate\Support\Str::startsWith($linkUrl, ['http://', 'https://', '//']); +@endphp +
+ + {{ $alt }} + +
+

+ + {{ __('Open linked resource') }} + + — {{ __('same destination as clicking the image above.') }} +

diff --git a/resources/views/training/show.blade.php b/resources/views/training/show.blade.php index 0faeeb184..fb1e3b318 100644 --- a/resources/views/training/show.blade.php +++ b/resources/views/training/show.blade.php @@ -27,10 +27,12 @@ $renderedContent = $trainingResource->content ?? ''; $roadmapEmbedUrl = trim((string) ($trainingResource->roadmap_pdf_embed_url ?? '')); $roadmapEmbedKind = strtolower(trim((string) ($trainingResource->roadmap_embed_kind ?? 'pdf'))); - if (! in_array($roadmapEmbedKind, ['pdf', 'svg', 'none'], true)) { + if (! in_array($roadmapEmbedKind, ['pdf', 'svg', 'image', 'none'], true)) { $roadmapEmbedKind = 'pdf'; } $roadmapSvg = trim((string) ($trainingResource->roadmap_svg ?? '')); + $roadmapImageUrl = trim((string) ($trainingResource->roadmap_image_url ?? '')); + $roadmapImageLinkUrl = trim((string) ($trainingResource->roadmap_image_link_url ?? '')); $roadmapPlaceholders = ['[[embed_roadmap_pdf]]', '[[embed_roadmap]]']; $hasRoadmapPlaceholder = str_contains($renderedContent, '[[embed_roadmap_pdf]]') @@ -42,6 +44,14 @@ $roadmapEmbedHtml = view('training.partials.roadmap-pdf-embed', ['url' => $roadmapEmbedUrl])->render(); } elseif ($roadmapEmbedKind === 'svg' && $roadmapSvg !== '') { $roadmapEmbedHtml = view('training.partials.roadmap-svg-embed', ['svg' => $roadmapSvg])->render(); + } elseif ($roadmapEmbedKind === 'image' && $roadmapImageUrl !== '') { + $imageLinkHref = $roadmapImageLinkUrl !== '' ? $roadmapImageLinkUrl : $roadmapEmbedUrl; + if ($imageLinkHref !== '') { + $roadmapEmbedHtml = view('training.partials.roadmap-image-embed', [ + 'imageUrl' => $roadmapImageUrl, + 'linkUrl' => $imageLinkHref, + ])->render(); + } } foreach ($roadmapPlaceholders as $token) {