11import { Card , Flex , Grid , Radio , Text } from '@sanity/ui'
22import { useCallback } from 'react'
3- import { HiOutlineViewColumns } from 'react-icons/hi2'
43import { LuText } from 'react-icons/lu'
54import { MdImage } from 'react-icons/md'
5+ import { RiMegaphoneLine } from 'react-icons/ri'
66import {
77 type Image ,
88 type PortableTextBlock ,
@@ -12,14 +12,22 @@ import {
1212 set ,
1313 type ValidationContext ,
1414} from 'sanity'
15+ import { capitalizeFirstLetter } from '@/helpers/formatters'
1516import blocksToText from '../../../helpers/blocksToText'
17+ import anchorLinkReference from '../anchorLinkList/anchorLinkReference'
1618import {
1719 hideTitle ,
1820 ingress ,
1921 layoutGrid ,
2022 theme ,
2123 title ,
2224} from '../commonFields/commonFields'
25+ import {
26+ externalLink ,
27+ homepageLink ,
28+ internalReference ,
29+ internalReferenceOtherLanguage ,
30+ } from '../linkSelector/common'
2331
2432type PromotionLayoutInputProps = {
2533 options : any [ ]
@@ -125,50 +133,125 @@ export default {
125133 name : 'promotedItem' ,
126134 title : 'Promoted item' ,
127135 fields : [
128- /* {
129- title: 'Page to be promoted',
130- name: 'reference',
131- description: 'Select the page you want to promote',
132- type: 'reference',
133- to: [...routes].filter(e => e),
134- options: {
135- filter: topicPromotionFilter,
136- disableNew: true,
137- },
138- }, */
139136 {
140137 name : 'link' ,
141- type : 'linkSelector' ,
142- validation : ( Rule : Rule ) => Rule . required ( ) ,
138+ type : 'array' ,
139+ of : [
140+ externalLink ,
141+ internalReference ,
142+ internalReferenceOtherLanguage ,
143+ homepageLink ,
144+ anchorLinkReference ,
145+ ] ,
146+ validation : ( Rule : Rule ) => Rule . length ( 1 ) . required ( ) ,
147+ } ,
148+ {
149+ name : 'label' ,
150+ title : 'Link label' ,
151+ description :
152+ 'Required when external, leave empty if you want to use referenced title' ,
153+ type : 'string' ,
154+ validation : ( Rule : Rule ) =>
155+ Rule . custom ( ( value : string , ctx : ValidationContext ) => {
156+ if ( ctx . parent ?. link ?. [ 0 ] ?. _type === 'link' ) {
157+ return value ? true : 'You must add a label'
158+ }
159+ return true
160+ } ) ,
143161 } ,
144162 {
145163 name : 'image' ,
146164 title : 'Image' ,
147165 type : 'imageWithAlt' ,
148166 hidden : ( { parent } : DocumentType ) => {
149- return parent ?. link ?. [ 0 ] ?. _type !== 'link'
167+ return (
168+ parent ?. link ?. [ 0 ] ?. _type !== 'link' &&
169+ parent ?. link ?. [ 0 ] ?. _type !== 'anchorLinkReference'
170+ )
150171 } ,
172+ validation : ( Rule : Rule ) =>
173+ Rule . custom ( ( value : string , ctx : ValidationContext ) => {
174+ if (
175+ ctx . parent ?. link ?. [ 0 ] ?. _type === 'link' ||
176+ ctx . parent ?. link ?. [ 0 ] ?. _type === 'anchorLinkReference'
177+ ) {
178+ return value ? true : 'You must add an image'
179+ }
180+ return true
181+ } ) ,
151182 } ,
152183 ] ,
153184 preview : {
154185 select : {
155- topicTitle : 'reference.content.title' ,
156- topicMedia : 'reference.content.heroFigure.image' ,
186+ referenceNewsMagTitle : 'link.0.title' ,
187+ referenceNewsMedia : 'link.0.heroImage.image' ,
188+ referenceMagMedia : 'link.0.heroFigure.image' ,
189+ referenceTopicTitle : 'link.0.content.title' ,
190+ referenceTopicMedia : 'link.0.content.heroFigure.image' ,
191+ customImage : 'image' ,
192+ link : 'link' ,
193+ label : 'label' ,
194+ type : 'link.0._type' ,
157195 } ,
158196 prepare ( {
159- topicTitle,
160- topicMedia,
197+ referenceNewsMagTitle,
198+ referenceNewsMedia,
199+ referenceMagMedia,
200+ referenceTopicTitle,
201+ referenceTopicMedia,
202+ customImage,
203+ link,
204+ label,
205+ type,
161206 } : {
162- topicTitle : PortableTextBlock [ ]
163- topicMedia : Image
207+ referenceNewsMagTitle ?: PortableTextBlock [ ]
208+ referenceNewsMedia ?: Image
209+ referenceMagMedia ?: Image
210+ referenceTopicTitle ?: PortableTextBlock [ ]
211+ referenceTopicMedia ?: Image
212+ customImage ?: Image
213+ link ?: any
214+ label ?: string
215+ type ?: string
164216 } ) {
165- const plainTitle = topicTitle
166- ? blocksToText ( topicTitle )
167- : 'Untitled'
217+ let promoType = type ?? 'not set'
218+
219+ if ( type ?. includes ( 'route' ) ) {
220+ promoType = 'internal route'
221+ }
222+ if ( type ?. includes ( 'anchorLinkReference' ) ) {
223+ promoType = 'anchor link'
224+ }
225+ if ( type === 'link' ) {
226+ promoType = 'external link'
227+ }
228+ const referenceTitle =
229+ referenceTopicTitle ?? referenceNewsMagTitle
230+ let title = label ?? 'Missing title'
231+ if (
232+ link ?. [ 0 ] ?. _type === 'anchorLinkReference' &&
233+ typeof label === 'undefined'
234+ ) {
235+ title = link ?. [ 0 ] ?. title
236+ }
237+ if (
238+ link ?. [ 0 ] ?. _type !== 'link' &&
239+ link ?. [ 0 ] ?. _type !== 'anchorLinkReference' &&
240+ typeof label === 'undefined' &&
241+ referenceTitle
242+ ) {
243+ title = blocksToText ( referenceTitle ) ?? 'Missing title'
244+ }
168245
169246 return {
170- title : plainTitle ,
171- media : topicMedia ,
247+ title : title ,
248+ subtitle : `${ capitalizeFirstLetter ( promoType ) } ` ,
249+ media :
250+ customImage ??
251+ referenceTopicMedia ??
252+ referenceNewsMedia ??
253+ referenceMagMedia ??
254+ RiMegaphoneLine ,
172255 }
173256 } ,
174257 } ,
@@ -203,9 +286,11 @@ export default {
203286 if ( Number ( ctx . parent ?. promoteList ?. length ) < Number ( value ) ) {
204287 return 'Fewer promotions than grid columns. Please select lower grid columns'
205288 }
206- // @ts -ignore:todo
289+
207290 if (
291+ //@ts -ignore:todo
208292 ctx . parent ?. layoutDirection === 'row' &&
293+ //@ts -ignore:todo
209294 ctx . parent ?. layoutGrid !== 'sm'
210295 ) {
211296 if ( value === '4' ) {
@@ -253,7 +338,7 @@ export default {
253338 return {
254339 title : plainTitle ,
255340 subtitle : subTitle ,
256- media : HiOutlineViewColumns ,
341+ media : RiMegaphoneLine ,
257342 }
258343 } ,
259344 } ,
0 commit comments