summaryrefslogtreecommitdiff
path: root/src/components/pages/SearchResultsPage.svelte
blob: c17b644a81c679d42af34c9572f580ea7b6670fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<script lang="ts">
    import type { SearchResultsPage } from '@jet-app/app-store/api/models';

    import type { Size } from '@amp/web-app-components/src/types';
    import { ShelfConfig } from '@amp/web-app-components/config/components/shelf';

    import DefaultPage from './DefaultPage.svelte';
    import { getI18n } from '~/stores/i18n';
    import mediaQueries from '~/utils/media-queries';
    import {
        isSearchResultShelf,
        isRenderableInSearchResultsShelf,
    } from '~/components/jet/shelf/SearchResultShelf.svelte';
    import { getPlatformFromPage } from '~/utils/seo/common';

    export let page: SearchResultsPage;

    const i18n = getI18n();

    $: resultsShelf = page?.shelves?.find(isSearchResultShelf) ?? null;

    $: renderableItems = (resultsShelf?.items ?? []).filter(
        isRenderableInSearchResultsShelf,
    );

    $: columnConfig = ShelfConfig.get().GRID_VALUES.SearchResult;
    $: numberOfColumns = columnConfig[$mediaQueries as Size] || 3;
    $: numberOfRows = Math.ceil(renderableItems.length / numberOfColumns);
    $: middleRow = Math.floor(numberOfRows / 2);
    $: insertAt = middleRow * numberOfColumns;

    /**
     * This is unfortunate but only these three platforms support the transparency link.
     * This link is enabled via the `transparencyLawEditorialItemId` bag key, but when defining
     * bag keys, we do not have access to the platform being viewed, so we can't opt-out there.
     * We could do this platform check in the Jet layer, but adding two forms of opting into this
     * link felt cumbersome and unintuitive, so we can just do it here.
     */
    $: transparencyLink =
        page.transparencyLink &&
        ['iphone', 'ipad', 'mac'].includes(
            getPlatformFromPage(page).toLowerCase(),
        );

    /**
     * Here we are building constructing a new array of shelves _if_ there is a result shelf _and_
     * a transparency link. This creates three shelves:
     * 1) the search results before the transparency banner in the linkable text shelf
     * 2) the transparency banner
     * 3) the search results after the transparency banner
     */
    $: shelves = resultsShelf
        ? transparencyLink && renderableItems.length
            ? [
                  insertAt > 0 && {
                      ...resultsShelf,
                      items: renderableItems.slice(0, insertAt),
                      title: null,
                      isValid: () => true,
                  },
                  {
                      contentType: 'linkableText',
                      items: [page.transparencyLink],
                  },
                  {
                      ...resultsShelf,
                      items: renderableItems.slice(insertAt),
                      title: null,
                      isValid: () => true,
                  },
              ]
            : [{ ...resultsShelf, items: renderableItems, title: null }]
        : [];
</script>

<DefaultPage
    page={{
        shelves,
        title: renderableItems.length > 0 ? resultsShelf?.title : null,
    }}
>
    <svelte:fragment slot="before-shelves">
        {#if renderableItems.length === 0}
            <div>
                <h1>
                    {$i18n.t('ASE.Web.AppStore.Search.NoResults.FirstLine')}
                </h1>
                <p>
                    {$i18n.t('ASE.Web.AppStore.Search.NoResults.SecondLine', {
                        term: page.searchTermContext?.term,
                    })}
                </p>
            </div>
        {/if}
    </svelte:fragment>
</DefaultPage>

<style>
    div {
        display: flex;
        align-items: center;
        justify-content: center;
        flex-direction: column;
        gap: 3px;
        height: 70vh;
        margin: var(--bodyGutter);
    }

    p {
        font: var(--title-3);
        color: var(--systemSecondary);
    }
</style>