From f7653244147d4e1a4947b038ad671dcf676ed5c2 Mon Sep 17 00:00:00 2001 From: bernardhanna Date: Wed, 29 Apr 2026 14:59:15 +0100 Subject: [PATCH] Enable Council Presidency content management in Nova. Load Council Presidency profiles from the partners table with a fallback, and add Nova fields/category support so editors can manage profile name, title, text, and image without code changes. Made-with: Cursor --- app/Livewire/PartnerContentComponent.php | 45 +++++++++++++------ app/Nova/Partner.php | 9 +++- app/Partner.php | 2 + ..._29_120000_add_title_to_partners_table.php | 22 +++++++++ .../council-content-component.blade.php | 4 +- 5 files changed, 64 insertions(+), 18 deletions(-) create mode 100644 database/migrations/2026_04_29_120000_add_title_to_partners_table.php diff --git a/app/Livewire/PartnerContentComponent.php b/app/Livewire/PartnerContentComponent.php index 44c2d30d9..76c61da0d 100644 --- a/app/Livewire/PartnerContentComponent.php +++ b/app/Livewire/PartnerContentComponent.php @@ -591,6 +591,36 @@ private function getAllPartners() return collect(self::$defaultPartnersRaw); } + private function getCouncilMembers() + { + $fromDb = Partner::active() + ->ordered() + ->whereJsonContains('categories', 'Council Presidency') + ->get(); + + if ($fromDb->isNotEmpty()) { + return $fromDb->map(function (Partner $member) { + $obj = $member->toPartnerObject(); + $obj->title = $member->title ?: 'Council President'; + $obj->image = $member->main_img_url ?: $member->logo_url; + + return $obj; + }); + } + + return collect([ + (object) [ + 'name' => 'Annie Bergh – Sweden', + 'title' => 'Council President', + 'description' => 'Building bridges between classrooms and code + Annie Bergh began her educational journey in 1991 as a preschool teacher and later taught students aged 6 to 13. But since 2014, she’s taken on a broader mission: supporting all 85 schools in Malmö municipality as a driving force behind internationalisation, coding, and robotics. Annie is the proud caretaker of 17 NAO robots—yes, actual humanoid robots—which teachers across Malmö can borrow to bring coding and AI to life in their classrooms. Through hands-on workshops and energetic TeachMeets, she inspires educators from preschool to upper secondary to integrate technology into their teaching in meaningful and creative ways. + Until recently, Annie also led the regional First Lego League (FLL) initiative for eight years, helping young minds explore science and innovation through teamwork and robotics. While she no longer teaches in a classroom, she’s still very much an educator—just one with a few more robots and a lot more cables. + My motto in the presidency is: Innovate, educate, collaborate: Together, I know that we can build a brighter, more collaborative future through the power of code.', + 'image' => 'images/council/AnnieBergh.jpg', + ], + ]); + } + /** * Return default partners as array of arrays (for seeding into DB). Call after getAllPartners() or ensure defaults are loaded. */ @@ -605,22 +635,9 @@ public static function getDefaultPartnersForSeeding(): array public function render() { if ($this->filter === 'Council Presidency') { - // Council Presidency content - $councilContent = collect([ - (object)[ - 'name' => 'Annie Bergh – Sweden', - 'title' => 'Council President', - 'description' => 'Building bridges between classrooms and code - Annie Bergh began her educational journey in 1991 as a preschool teacher and later taught students aged 6 to 13. But since 2014, she’s taken on a broader mission: supporting all 85 schools in Malmö municipality as a driving force behind internationalisation, coding, and robotics. Annie is the proud caretaker of 17 NAO robots—yes, actual humanoid robots—which teachers across Malmö can borrow to bring coding and AI to life in their classrooms. Through hands-on workshops and energetic TeachMeets, she inspires educators from preschool to upper secondary to integrate technology into their teaching in meaningful and creative ways. - Until recently, Annie also led the regional First Lego League (FLL) initiative for eight years, helping young minds explore science and innovation through teamwork and robotics. While she no longer teaches in a classroom, she’s still very much an educator—just one with a few more robots and a lot more cables. - My motto in the presidency is: Innovate, educate, collaborate: Together, I know that we can build a brighter, more collaborative future through the power of code.', - 'image' => 'images/council/AnnieBergh.jpg', - ], - ]); - // Render the Council Presidency content view return view('livewire.council-content-component', [ - 'councilMembers' => $councilContent + 'councilMembers' => $this->getCouncilMembers(), ]); } diff --git a/app/Nova/Partner.php b/app/Nova/Partner.php index c8657ceca..73284844c 100644 --- a/app/Nova/Partner.php +++ b/app/Nova/Partner.php @@ -45,6 +45,10 @@ public function fields(Request $request): array ->nullable() ->help('Display name. Optional for sponsor logos (e.g. EU Code Week Supporters).'), + Text::make('Title', 'title') + ->nullable() + ->help('Used in the Council Presidency tab (e.g. "Council President").'), + Text::make('Logo URL', 'logo_url') ->rules('required') ->help('Path from site root, e.g. images/partners/logo.png (no leading slash), or full URL.'), @@ -53,8 +57,9 @@ public function fields(Request $request): array ->options([ 'Partners' => 'Partners', 'Sponsor' => 'EU Code Week Supporters (Sponsor)', + 'Council Presidency' => 'Council Presidency', ]) - ->help('Partners = "Partners" tab; Sponsor = "EU Code Week Supporters" tab.') + ->help('Partners = "Partners" tab; Sponsor = "EU Code Week Supporters" tab; Council Presidency = "Council Presidency" tab.') ->resolveUsing(function ($value) { $arr = is_array($value) ? $value : (array) json_decode($value ?? '[]', true); return $arr[0] ?? null; @@ -74,7 +79,7 @@ public function fields(Request $request): array Text::make('Main image URL', 'main_img_url') ->nullable() - ->help('Larger image path (optional).'), + ->help('Larger image path (optional). Used as profile image for Council Presidency.'), Number::make('Position', 'position') ->min(0) diff --git a/app/Partner.php b/app/Partner.php index 5de0efac9..4d0cb155a 100644 --- a/app/Partner.php +++ b/app/Partner.php @@ -8,6 +8,7 @@ class Partner extends Model { protected $fillable = [ 'name', + 'title', 'logo_url', 'categories', 'description', @@ -41,6 +42,7 @@ public function toPartnerObject(): \stdClass $o = new \stdClass; $o->id = $this->id; $o->name = $this->name; + $o->title = $this->title; $o->logo_url = $this->logo_url; $o->categories = $this->categories ?? []; $o->description = $this->description; diff --git a/database/migrations/2026_04_29_120000_add_title_to_partners_table.php b/database/migrations/2026_04_29_120000_add_title_to_partners_table.php new file mode 100644 index 000000000..54bebee95 --- /dev/null +++ b/database/migrations/2026_04_29_120000_add_title_to_partners_table.php @@ -0,0 +1,22 @@ +string('title')->nullable()->after('name'); + }); + } + + public function down(): void + { + Schema::table('partners', function (Blueprint $table) { + $table->dropColumn('title'); + }); + } +}; diff --git a/resources/views/livewire/council-content-component.blade.php b/resources/views/livewire/council-content-component.blade.php index 8d160db8c..6d19d1a1e 100644 --- a/resources/views/livewire/council-content-component.blade.php +++ b/resources/views/livewire/council-content-component.blade.php @@ -15,7 +15,7 @@ Portrait of Stamatis Papadakis, EU Code Week Council President @@ -59,7 +59,7 @@ class="object-cover h-full max-h-[396px] w-full mt-6 md:hidden block rounded-[12