@@ -56,6 +56,97 @@ private static function localesSorted(): array
5656 return $ locales ;
5757 }
5858
59+ /**
60+ * Locales offered in the "Translated page content" panel.
61+ */
62+ private static function pageTranslationLocales (): array
63+ {
64+ $ configured = config ('codeweek.training_translation_locales ' , ['it ' ]);
65+ if (is_string ($ configured )) {
66+ $ configured = array_map ('trim ' , explode (', ' , $ configured ));
67+ }
68+
69+ $ available = self ::localesSorted ();
70+
71+ return array_values (array_filter (
72+ (array ) $ configured ,
73+ fn ($ locale ) => $ locale !== 'en ' && in_array ($ locale , $ available , true )
74+ ));
75+ }
76+
77+ /**
78+ * Build one translation field, stored under locale_overrides[$locale][$field].
79+ */
80+ private function translationField (string $ locale , string $ field , string $ label , string $ type )
81+ {
82+ $ novaField = match ($ type ) {
83+ 'trix ' => Trix::make ($ label .' ( ' .strtoupper ($ locale ).') ' , 'locale_ ' .$ locale .'_ ' .$ field ),
84+ 'textarea ' => Textarea::make ($ label .' ( ' .strtoupper ($ locale ).') ' , 'locale_ ' .$ locale .'_ ' .$ field ),
85+ default => Text::make ($ label .' ( ' .strtoupper ($ locale ).') ' , 'locale_ ' .$ locale .'_ ' .$ field ),
86+ };
87+
88+ return $ novaField
89+ ->nullable ()
90+ ->hideFromIndex ()
91+ ->resolveUsing (function () use ($ locale , $ field ) {
92+ $ overrides = $ this ->resource ->locale_overrides ?? [];
93+
94+ return $ overrides [$ locale ][$ field ] ?? '' ;
95+ })
96+ ->fillUsing (function ($ request , $ model , $ attribute , $ requestAttribute ) use ($ locale , $ field ) {
97+ $ overrides = $ model ->locale_overrides ?? [];
98+ if (! isset ($ overrides [$ locale ]) || ! is_array ($ overrides [$ locale ])) {
99+ $ overrides [$ locale ] = [];
100+ }
101+
102+ $ value = $ request ->get ($ requestAttribute );
103+ if ($ value === null || trim (strip_tags ((string ) $ value )) === '' ) {
104+ unset($ overrides [$ locale ][$ field ]);
105+ } else {
106+ $ overrides [$ locale ][$ field ] = $ value ;
107+ }
108+
109+ if ($ overrides [$ locale ] === []) {
110+ unset($ overrides [$ locale ]);
111+ }
112+
113+ $ model ->locale_overrides = $ overrides === [] ? null : $ overrides ;
114+ });
115+ }
116+
117+ /**
118+ * Full-page translation fields for one locale, mirroring the English field types.
119+ */
120+ private function pageTranslationFieldsFor (string $ locale ): array
121+ {
122+ $ definitions = [
123+ ['card_title ' , 'Card title ' , 'text ' ],
124+ ['card_author ' , 'Card author ' , 'text ' ],
125+ ['page_title ' , 'Page title ' , 'text ' ],
126+ ['hero_author ' , 'Hero author ' , 'text ' ],
127+ ['hero_button_text ' , 'Hero button text ' , 'text ' ],
128+ ['hero_secondary_button_text ' , 'Hero secondary button text ' , 'text ' ],
129+ ['highlight_box ' , 'Highlight box ' , 'trix ' ],
130+ ['intro ' , 'Intro ' , 'trix ' ],
131+ ['content ' , 'Content ' , 'trix ' ],
132+ ['body_image_alt ' , 'Body image alt text ' , 'text ' ],
133+ ['video_script_text ' , 'Video script link text ' , 'text ' ],
134+ ['contacts_section ' , 'Contacts section ' , 'trix ' ],
135+ ['register_box_section ' , 'Register box section ' , 'trix ' ],
136+ ['about_box_section ' , 'About box section ' , 'trix ' ],
137+ ['button_text ' , 'Button text ' , 'text ' ],
138+ ['secondary_button_text ' , 'Secondary button text ' , 'text ' ],
139+ ['third_button_text ' , 'Third button text ' , 'text ' ],
140+ ['meta_title ' , 'Meta title ' , 'text ' ],
141+ ['meta_description ' , 'Meta description ' , 'textarea ' ],
142+ ];
143+
144+ return array_map (
145+ fn (array $ definition ) => $ this ->translationField ($ locale , ...$ definition ),
146+ $ definitions
147+ );
148+ }
149+
59150 public function fields (Request $ request ): array
60151 {
61152 $ pdfTranslationFields = [];
@@ -311,6 +402,16 @@ public function fields(Request $request): array
311402 ->collapsedByDefault ();
312403 }
313404
405+ foreach (self ::pageTranslationLocales () as $ locale ) {
406+ $ fields [] = Panel::make (
407+ 'Translated page content ( ' .strtoupper ($ locale ).') ' ,
408+ $ this ->pageTranslationFieldsFor ($ locale )
409+ )
410+ ->help ('Full page translation for ' .strtoupper ($ locale ).'. Any field left empty falls back to the English version above, so a partly translated page never renders blank. PDF download links live in the “Translated PDF links” panel. ' )
411+ ->collapsable ()
412+ ->collapsedByDefault ();
413+ }
414+
314415 return $ fields ;
315416 }
316417
0 commit comments