/ src / components / pages / SearchResultsPage.svelte
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>