]> _ Git - odl.git/commitdiff
WIP #4781 @8
authorStephen Cameron <stephen@cubedesigners.com>
Wed, 24 Nov 2021 22:27:33 +0000 (23:27 +0100)
committerStephen Cameron <stephen@cubedesigners.com>
Wed, 24 Nov 2021 22:27:33 +0000 (23:27 +0100)
17 files changed:
package-lock.json
package.json
resources/css/app.css
resources/css/common/global.css
resources/css/common/plyr.css [new file with mode: 0644]
resources/js/alpine.js
resources/js/media-library.js
resources/js/search.js [new file with mode: 0644]
resources/views/components/link.blade.php
resources/views/components/media-library/filter-interface.blade.php
resources/views/components/media-library/index.blade.php
resources/views/components/media-library/player.blade.php
resources/views/components/search.blade.php [new file with mode: 0644]
resources/views/front/home.blade.php
resources/views/front/resources.blade.php
resources/views/layouts/app.blade.php
tailwind.config.js

index 696a89c10827c08931405cd806377c410ba35688..d098bf47382a6437b8aca8bef1f055dd246e7547 100644 (file)
@@ -6,12 +6,14 @@
         "": {
             "devDependencies": {
                 "@alpinejs/intersect": "^3.4.2",
+                "@tailwindcss/line-clamp": "^0.2.2",
                 "alpinejs": "^3.4.2",
                 "autoprefixer": "^10.3.7",
                 "axios": "^0.21",
                 "isotope-layout": "^3.0.6",
                 "laravel-mix": "^6.0.6",
                 "lodash": "^4.17.19",
+                "minisearch": "^3.1.0",
                 "plyr": "^3.6.9",
                 "postcss": "^8.3.10",
                 "postcss-import": "^14.0.2",
                 "node": ">= 8"
             }
         },
+        "node_modules/@tailwindcss/line-clamp": {
+            "version": "0.2.2",
+            "resolved": "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.2.2.tgz",
+            "integrity": "sha512-NgA4Ds+/eCiO+6O3SooRsfJ8m7M2+QvNvHwOjBQq7FIYoWwAV4I4Wu4fjHeuO9Yi6p47ceHUKEGGEBh0ozQodg==",
+            "dev": true,
+            "peerDependencies": {
+                "tailwindcss": ">=2.0.0 || >=3.0.0-alpha.1"
+            }
+        },
         "node_modules/@trysound/sax": {
             "version": "0.2.0",
             "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
             "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
             "dev": true
         },
+        "node_modules/minisearch": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-3.1.0.tgz",
+            "integrity": "sha512-Lm1YCI3O1BGZFm4RG0LSHCslR4DlW/idmv/QuLdBfI7toDkI8NPcFbo1673tkq4Vz3KqwfnS/6500qSJckcy6A==",
+            "dev": true
+        },
         "node_modules/mkdirp": {
             "version": "0.5.5",
             "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
                 "fastq": "^1.6.0"
             }
         },
+        "@tailwindcss/line-clamp": {
+            "version": "0.2.2",
+            "resolved": "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.2.2.tgz",
+            "integrity": "sha512-NgA4Ds+/eCiO+6O3SooRsfJ8m7M2+QvNvHwOjBQq7FIYoWwAV4I4Wu4fjHeuO9Yi6p47ceHUKEGGEBh0ozQodg==",
+            "dev": true,
+            "requires": {}
+        },
         "@trysound/sax": {
             "version": "0.2.0",
             "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
             "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
             "dev": true
         },
+        "minisearch": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-3.1.0.tgz",
+            "integrity": "sha512-Lm1YCI3O1BGZFm4RG0LSHCslR4DlW/idmv/QuLdBfI7toDkI8NPcFbo1673tkq4Vz3KqwfnS/6500qSJckcy6A==",
+            "dev": true
+        },
         "mkdirp": {
             "version": "0.5.5",
             "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
index 939c6e9fd1186314e2c3e40db628307cd17f3cc3..b8c29a17488b3ee2e4a5e8ec882311bc18126f27 100644 (file)
     },
     "devDependencies": {
         "@alpinejs/intersect": "^3.4.2",
+        "@tailwindcss/line-clamp": "^0.2.2",
         "alpinejs": "^3.4.2",
         "autoprefixer": "^10.3.7",
         "axios": "^0.21",
         "isotope-layout": "^3.0.6",
         "laravel-mix": "^6.0.6",
         "lodash": "^4.17.19",
+        "minisearch": "^3.1.0",
         "plyr": "^3.6.9",
         "postcss": "^8.3.10",
         "postcss-import": "^14.0.2",
index 7518436dc50bf85c2b7fa064084292f097df1315..d12f1b77c869bd5dd2d355b46a51abaaa72f3ecc 100644 (file)
@@ -1,6 +1,7 @@
 @import "tailwindcss/base";
 @import 'common/fonts.css';
 @import 'common/menu.css';
+@import 'common/plyr.css';
 @import 'common/global.css';
 
 @import "tailwindcss/components";
index 21e8a5d6bdf221320b2a5f6703634133a664fbde..5b8f38b9581630a70e031d53e64ccf9255f9ba46 100644 (file)
@@ -13,7 +13,7 @@ h1, h2, h3, h4 {
 h1 { @apply text-6xl; }
 h2 { @apply text-4xl; }
 
-[x-cloak] { display: none !important; }
+[x-cloak] { visibility: hidden !important; }
 
 .circle-arrow {
     display: inline-block;
diff --git a/resources/css/common/plyr.css b/resources/css/common/plyr.css
new file mode 100644 (file)
index 0000000..03a12c3
--- /dev/null
@@ -0,0 +1,16 @@
+:root {
+    --plyr-color-main: theme('colors.blue-dark');
+    --plyr-range-fill-background: #fff;
+    --plyr-control-radius: 50%;
+    --plyr-control-spacing: 21.45px;
+}
+
+.plyr--audio {
+    --plyr-range-fill-background: #000;
+}
+
+.plyr__time {
+    @apply font-secondary;
+    font-feature-settings: "tnum";
+    font-variant-numeric: tabular-nums;
+}
index 7df739fcf2ceba0b39d7a0f52c8c2eb685b8a41e..74788ba40723f3107c32cee9d126bf536dbd755f 100644 (file)
@@ -1,13 +1,16 @@
 // AlpineJS setup - https://alpinejs.dev/
 import Alpine from 'alpinejs';
+import intersect from '@alpinejs/intersect';
+import media_library from './media-library';
+import search from './search';
+
 window.Alpine = Alpine;
 
 // Plugins
-import intersect from '@alpinejs/intersect';
 Alpine.plugin(intersect);
 
 // Components
-import media_library from './media-library';
 Alpine.data('media_library', media_library);
+Alpine.data('search', search);
 
 Alpine.start();
index b3f9522f6ca5598c7f7d5097bbaeffea8ae650ef..acb2c8ed5d3285710888eaf9e9690a99a633a1f4 100644 (file)
@@ -16,7 +16,7 @@ export default (options = {}) => ({
     playerOpen: false, // Visibility of the media player overlay
     player: {}, // Holds the Plyr instance
     playerOptions: { // Settings used for Plyr instantiation (https://github.com/sampotts/plyr#options)
-        debug: true,
+        debug: false,
     },
 
     /***********\
diff --git a/resources/js/search.js b/resources/js/search.js
new file mode 100644 (file)
index 0000000..9e1b943
--- /dev/null
@@ -0,0 +1,43 @@
+//=======================//
+// Search functionality //
+//=====================//
+
+import MiniSearch from 'minisearch';
+
+export default (searchData = []) => ({
+
+    miniSearch: {}, // Holds the MiniSearch instance
+    setup: { // MiniSearch options: https://lucaong.github.io/minisearch/#search-options
+        fields: ['title', 'text'], // fields to index for full-text search
+        storeFields: ['id', 'title', 'text', 'type', 'url', 'thumb'], // fields to return with search results
+        searchOptions: {
+            prefix: true, // Allow partial matches
+        },
+    },
+    query: '', // The search query
+
+    init() {
+        this.miniSearch = new MiniSearch(this.setup);
+        this.miniSearch.addAll(searchData);
+    },
+
+    get results() {
+        if (this.query === '') {
+            return [];
+        }
+
+        // console.log(`search results: ${this.query}`);
+        // console.table(this.miniSearch.search(this.query))
+
+        return this.miniSearch.search(this.query)
+    },
+
+    get resultCount() {
+        if (this.results.length === 1) {
+            return '1 résultat'
+        }
+
+        return `${this.results.length} résultats`;
+    },
+
+});
index 10a8a95495933fb2bdd41834f215edb25466553c..e9a130e9d6231c38c68c65011e695cf68ed53b50 100644 (file)
@@ -1,6 +1,8 @@
 {{-- Standard Link --}}
 @php
-    if (Illuminate\Support\Str::startsWith($href, '/')) {
+    use Illuminate\Support\Str;
+
+    if (!Str::startsWith($href, 'http') && !Str::startsWith($href, '/tools/')) {
         // TODO: add adapt local URLs based on environment (whether dynamic or static HTML output)
         $href = '/front' . $href; // Prefix URLs for frontend preview
     }
index a7190537eab08199f14e51a0a83ca069cc8f0d49..468842fd8fac11e6bac4f17c0ad7b7d74c5672a8 100644 (file)
@@ -24,9 +24,9 @@
         <h2 class="text-6xl uppercase">Filtres</h2>
 
         {{-- Filter Options --}}
-        <div class="flex mt-15">
+        <div class="flex flex-col lg:flex-row mt-15">
             {{-- Media Type Filters --}}
-            <div class="w-1/3">
+            <div class="lg:w-1/3">
                 <h3 class="font-medium text-4xl mb-5">Média</h3>
                 <div class="grid grid-cols-1 gap-5">
                     @foreach($types as $type_id => $type)
@@ -48,7 +48,7 @@
             </div>
 
             {{-- Theme Filters --}}
-            <div class="w-2/3">
+            <div class="mt-15 lg:mt-0 lg:w-2/3">
                 <h3 class="font-medium text-4xl mb-5">Thème</h3>
                 <div class="grid grid-cols-2 gap-5">
                     @foreach($themes as $theme_id => $theme)
index 42ef8109aae8751eb096ee179cac05f05dbd425b..ba56df4c92f2e20607cafe0f5b8f0ece9ca4affe 100644 (file)
@@ -27,7 +27,7 @@
 
     {{-- MEDIA LIBRARY GRID --}}
     {{-- Negative margins applied here to offset margins used in Isotope grid --}}
-    <div class="media-grid mt-10 -mb-16 -mx-2.5" x-init="initIsotope($el)">
+    <div class="media-grid mt-10 -mb-16 -mx-2.5" x-init="initIsotope($el)" x-cloak>
         @foreach ($media as $item)
             <div @click="openPlayer({
                      type: '{{ $item['type'] }}',
@@ -39,7 +39,7 @@
                  })"
                  class="media-item
                         {{-- Width is 25% minus the gutters (2 * 0.625rem that comes from mx-2.5) --}}
-                        float-left w-[calc(25%-1.25rem)] mx-2.5 mb-16
+                        float-left w-[calc(33%-1.25rem)] lg:w-[calc(25%-1.25rem)] mx-2.5 mb-16
                         media-{{ $item['type'] }}
                         theme-{{ $item['theme']['id'] }}"
             >
index 359f1a78c33dae60ef962877a44d845624be1840..e677c0662249d7ec5b5bc916835c4d17b208922a 100644 (file)
@@ -83,7 +83,7 @@
                     {{-- Right side --}}
                     <div class="flex items-center">
                         {{-- Time codes --}}
-                        <div class="plyr__time plyr__time--current" aria-label="Current time">00:00</div>
+                        <div class="plyr__time plyr__time--current mr-2" aria-label="Current time">00:00</div>
                         <div class="plyr__time plyr__time--duration" aria-label="Duration">00:00</div>
                     </div>
 
diff --git a/resources/views/components/search.blade.php b/resources/views/components/search.blade.php
new file mode 100644 (file)
index 0000000..9848cdf
--- /dev/null
@@ -0,0 +1,62 @@
+{{-- SEARCH (full screen overlay) --}}
+
+@push('before_scripts')
+    <script>
+        @php
+            // TODO: Consider fetching this via JS only when search is used
+            echo file_get_contents(storage_path('search.js'));
+        @endphp
+    </script>
+@endpush
+
+<div class="search-overlay
+            fixed top-0 left-0 w-screen h-screen
+            flex flex-col
+            bg-white text-black
+            px-30
+            z-20
+            transition ease-out-cubic duration-500"
+     {{-- Pass search index [documents] to component for setup --}}
+     {{-- See js/search.js --}}
+     x-data="search(documents)"
+     x-show="searchOpen"
+     x-transition:enter-start="opacity-0"
+     x-transition:enter-end="opacity-100"
+     x-transition:leave-start="opacity-100"
+     x-transition:leave-end="opacity-0"
+     x-cloak>
+
+    <x-close @click.prevent="searchOpen = false" />
+
+    {{-- Search Field --}}
+    <div class="w-full pt-30 flex-grow-0">
+        <p class="font-medium text-2xl">Tapez ici le ou les mots-clé de votre recherche</p>
+
+        <input
+            x-ref="searchField"
+            x-model="query"
+            type="search"
+            placeholder="Recherche"
+            class="appearance-none outline-none
+                   mt-8 w-full
+                   font-semibold text-6xl uppercase
+                   border-b-2 border-black">
+    </div>
+
+    {{-- Search Results --}}
+    <div class="flex-1 max-h-full overflow-y-auto">
+        <div x-show="query !== ''" class="font-secondary font-medium">
+            <p x-text="resultCount" class="mt-15 opacity-50"></p>
+
+            <div class="h-full max-h-full overflow-y-auto">
+                <template x-for="result in results" :key="result.id">
+                    <div class="py-8 border-b border-black border-opacity-20">
+                        <a :href="result.url" x-text="result.title" class="text-2xl text-blue"></a>
+                        <p x-text="result.text" class="mt-2 line-clamp-1"></p>
+                    </div>
+                </template>
+            </div>
+        </div>
+    </div>
+
+</div>
index c8b0beae546c462c2be8828ac241ac164aae1305..14a84e63ee0fab945c460e96d9a2fee699a6fb19 100644 (file)
@@ -7,6 +7,7 @@
         $logo = 'https://odl.paris.cubedesigners.com/storage/102/groupe-84.svg';
         $subtitle = "Découvrez le coeur de l'offre sous forme de feuilleteur interactif";
         $button = "Découvrir l'offre";
+        $button_link = '/tools/fluidbookpreview/';
         $illustration = 'https://odl.paris.cubedesigners.com/storage/137/home-magazine.jpg';
         $shortcuts = [
             [
@@ -50,7 +51,7 @@
                 @endif
                 @if($button)
                     <a class="bg-blue text-white py-4 px-10 rounded-full transition transform hover:scale-105"
-                       href="#"
+                       href="{{ $button_link }}"
                        x-show="shown" x-transition.opacity.scale.80.origin.bottom.duration.500ms.delay.300ms>
                         {{ $button }}
                     </a>
         </div>
 
         {{-- Link blocks --}}
-        <div class="grid grid-cols-3 gap-6" x-data="{ shown: false }" x-intersect="shown = true">
+        <div class="grid grid-cols-3 gap-6 text-center lg:text-left" x-data="{ shown: false }" x-intersect="shown = true">
             @foreach($shortcuts as $shortcut)
-                <div class="relative bg-blue flex items-center text-white p-6 rounded-lg overflow-hidden">
-                    <img class="flex-shrink mr-8 w-[40%]" src="{{ $shortcut['image'] }}" alt="">
+                <div class="relative bg-blue flex flex-col lg:flex-row items-center text-white p-6 rounded-lg overflow-hidden max-h-[22vh] lg:max-h-none">
+                    <img class="flex-shrink mr-8 max-h-[40%] lg:max-h-none lg:w-[40%]" src="{{ $shortcut['image'] }}" alt="">
                     <div class="flex-1 flex-shrink-0 space-y-2">
                         <h3 class="font-semibold uppercase">{{ $shortcut['title'] }}</h3>
                         <p>{{ $shortcut['content'] }}</p>
index 5ab00b1edd9524d4f1f2029cef604ac2d4f7d24f..2730ef2886367aa6160f2f2488c21d25ab97d90a 100644 (file)
     <h2 class="font-medium text-2xl mb-14 w-1/2">{{ $subtitle }}</h2>
 
     {{-- DOCUMENTS --}}
-    <div class="grid grid-cols-2 gap-6">
+    <div class="grid lg:grid-cols-2 gap-6">
         @foreach($documents as $doc)
             <div class="bg-blue flex p-10 text-white rounded-md">
                 <img class="w-1/2 pr-6" src="{{ $doc['document_image'] }}" alt="{{ $doc['document_title'] }}">
index c7c23ad5b91ff7bb9676c6d54249fac194db4826..6d6034c75ad23a580224385d1fd9b3236ea0f73e 100644 (file)
@@ -8,7 +8,9 @@
     @stack('after_css')
     <title>{{ config('app.name') }}</title>
 </head>
-<body class="font-primary p-8" :class="menuOpen && 'menu-open'" x-data="{ menuOpen: false }">
+<body x-data="{ menuOpen: false, searchOpen: false }"
+      :class="{ 'menu-open': menuOpen, 'overflow-hidden': searchOpen }"
+      class="font-primary p-8">
     <header class="site-header relative flex justify-between z-20 transition-colors duration-500">
         {{-- Menu Toggle --}}
         <a href="#" @click.prevent="menuOpen = !menuOpen">
@@ -41,7 +43,7 @@
 
 
         {{-- Search Icon --}}
-        <a href="#">
+        <a href="#" @click.prevent="searchOpen = true; $dispatch('searchOpen')">
             <svg class="stroke-current fixed top-8 right-8" xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 29.414 29.414">
                 <g fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
                     <path d="M1 12.25A11.25 11.25 0 1 0 12.25 1 11.25 11.25 0 0 0 1 12.25Z"/>
@@ -81,7 +83,7 @@
             @php
                 $menu_links = [
                     '/' => 'Accueil',
-                    '/fluidbook' => 'Cœur de l’offre',
+                    '/tools/fluidbookpreview/' => 'Cœur de l’offre',
                     '/ressources' => 'Ressources',
                     '/mediatheque' => 'Médiathèque',
                     '/tour' => 'Visite guidée',
         </ul>
     </div>
 
+    {{-- Search Overlay --}}
+    <x-search />
+
     @stack('before_scripts')
     <script src="{{ asset('js/app.js') }}"></script>
     @stack('after_scripts')
index 22a941689329caf4cfd723f05a0583a64aaf2d3b..c7431537bad5e7945860b415f5abd08a712a77ad 100644 (file)
@@ -25,6 +25,10 @@ module.exports = {
       fontSize: {
         '6xl': ['3.375rem', 1], // 54px, line-height: 1
       },
+      maxHeight: {
+        'none': 'none',
+        '1/2': '50%',
+      },
       spacing: {
         '15': '3.75rem', // 60px
         '22': '5.5rem', // 88px
@@ -46,5 +50,7 @@ module.exports = {
   variants: {
     extend: {},
   },
-  plugins: [],
+  plugins: [
+    require('@tailwindcss/line-clamp')
+  ],
 }