SearchResultsPage.svelte
1 <script lang="ts"> 2 import type { SearchResultsPage } from '@jet-app/app-store/api/models'; 3 4 import type { Size } from '@amp/web-app-components/src/types'; 5 import { ShelfConfig } from '@amp/web-app-components/config/components/shelf'; 6 7 import DefaultPage from './DefaultPage.svelte'; 8 import { getI18n } from '~/stores/i18n'; 9 import mediaQueries from '~/utils/media-queries'; 10 import { 11 isSearchResultShelf, 12 isRenderableInSearchResultsShelf, 13 } from '~/components/jet/shelf/SearchResultShelf.svelte'; 14 import { getPlatformFromPage } from '~/utils/seo/common'; 15 16 export let page: SearchResultsPage; 17 18 const i18n = getI18n(); 19 20 $: resultsShelf = page?.shelves?.find(isSearchResultShelf) ?? null; 21 22 $: renderableItems = (resultsShelf?.items ?? []).filter( 23 isRenderableInSearchResultsShelf, 24 ); 25 26 $: columnConfig = ShelfConfig.get().GRID_VALUES.SearchResult; 27 $: numberOfColumns = columnConfig[$mediaQueries as Size] || 3; 28 $: numberOfRows = Math.ceil(renderableItems.length / numberOfColumns); 29 $: middleRow = Math.floor(numberOfRows / 2); 30 $: insertAt = middleRow * numberOfColumns; 31 32 /** 33 * This is unfortunate but only these three platforms support the transparency link. 34 * This link is enabled via the `transparencyLawEditorialItemId` bag key, but when defining 35 * bag keys, we do not have access to the platform being viewed, so we can't opt-out there. 36 * We could do this platform check in the Jet layer, but adding two forms of opting into this 37 * link felt cumbersome and unintuitive, so we can just do it here. 38 */ 39 $: transparencyLink = 40 page.transparencyLink && 41 ['iphone', 'ipad', 'mac'].includes( 42 getPlatformFromPage(page).toLowerCase(), 43 ); 44 45 /** 46 * Here we are building constructing a new array of shelves _if_ there is a result shelf _and_ 47 * a transparency link. This creates three shelves: 48 * 1) the search results before the transparency banner in the linkable text shelf 49 * 2) the transparency banner 50 * 3) the search results after the transparency banner 51 */ 52 $: shelves = resultsShelf 53 ? transparencyLink && renderableItems.length 54 ? [ 55 insertAt > 0 && { 56 ...resultsShelf, 57 items: renderableItems.slice(0, insertAt), 58 title: null, 59 isValid: () => true, 60 }, 61 { 62 contentType: 'linkableText', 63 items: [page.transparencyLink], 64 }, 65 { 66 ...resultsShelf, 67 items: renderableItems.slice(insertAt), 68 title: null, 69 isValid: () => true, 70 }, 71 ] 72 : [{ ...resultsShelf, items: renderableItems, title: null }] 73 : []; 74 </script> 75 76 <DefaultPage 77 page={{ 78 shelves, 79 title: renderableItems.length > 0 ? resultsShelf?.title : null, 80 }} 81 > 82 <svelte:fragment slot="before-shelves"> 83 {#if renderableItems.length === 0} 84 <div> 85 <h1> 86 {$i18n.t('ASE.Web.AppStore.Search.NoResults.FirstLine')} 87 </h1> 88 <p> 89 {$i18n.t('ASE.Web.AppStore.Search.NoResults.SecondLine', { 90 term: page.searchTermContext?.term, 91 })} 92 </p> 93 </div> 94 {/if} 95 </svelte:fragment> 96 </DefaultPage> 97 98 <style> 99 div { 100 display: flex; 101 align-items: center; 102 justify-content: center; 103 flex-direction: column; 104 gap: 3px; 105 height: 70vh; 106 margin: var(--bodyGutter); 107 } 108 109 p { 110 font: var(--title-3); 111 color: var(--systemSecondary); 112 } 113 </style>