Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
eronisko committed Apr 26, 2024
1 parent 4aa293e commit cacdd70
Show file tree
Hide file tree
Showing 2 changed files with 258 additions and 40 deletions.
227 changes: 202 additions & 25 deletions resources/js/components/SearchBar.vue
Original file line number Diff line number Diff line change
@@ -1,29 +1,206 @@
<script setup lang="ts">
import axios from 'axios'
import { computed, ref, watch } from 'vue'
import {
PopoverRoot,
PopoverTrigger,
PopoverContent,
ListboxRoot,
ListboxContent,
ListboxGroup,
ListboxGroupLabel,
ListboxItem,
Separator,
} from 'radix-vue'
// TODO highligher vue-highlight-words
// TODO import Bloodhound from 'corejs-typeahead/dist/bloodhound' instead of using Axios
// TODO submitting, keyboard navigation
// TODO Collections
// TODO Articles
type Option = {
value: string
url: string
}
type ItemOption = Option & {
image: string
author: string
title: string
}
type AuthorOption = Option & {
image: string
name: string
birthYear: number | null
deathYear: number | null
}
const searchTerm = ref('')
const itemOptions = ref<ItemOption[]>([])
const authorOptions = ref<AuthorOption[]>([])
function fetchItemOptions(searchTerm: string) {
axios
.get('/katalog/suggestions', {
params: {
search: searchTerm,
},
})
.then(
({ data }) =>
(itemOptions.value = data.map((item) => ({
value: `${item.author}: ${item.title}`,
url: route('dielo', { id: item.id }),
image: item.image,
author: item.author,
title: item.title,
}))),
)
}
function fetchAuthorOptions(searchTerm: string) {
axios
.get('/autori/suggestions', {
params: {
search: searchTerm,
},
})
.then(
({ data }) =>
(authorOptions.value = data.map((author) => ({
value: author.name,
url: `/autor/${author.id}`,
image: author.image,
name: author.name,
birthYear: author.birth_year,
deathYear: author.death_year,
}))),
)
}
watch(searchTerm, (searchTerm) => {
fetchItemOptions(searchTerm)
fetchAuthorOptions(searchTerm)
})
const allOptions = computed(() => {
return [...authorOptions.value, ...itemOptions.value]
})
watch(allOptions, () => {
// Do not lose focus to the Listbox
input.value?.focus()
})
const input = ref<HTMLInputElement>()
function onKeyDown() {
console.log('onKeyDown')
}
</script>
<template>
<form method="GET" class="xukraine navbar-form tailwind-rules">
<div class="tw-relative tw-flex tw-items-center">
<i class="fa fa-search tw-absolute tw-right-3 tw-text-sm tw-pointer-events-none"></i>

<input
type="text"
name="search"
autocomplete="off"
class="tw-peer tw-text-sm placeholder:tw-text-sky-300 tw-px-3 tw-py-1.5 tw-border tw-border-gray-600 tw-w-full focus:tw-outline-none tw-ring-0 tw-bg-white tw-z-10"
:placeholder="$t('master.search_placeholder')"
/>

<!-- Ukraine -->
<div class="tw-relative tw-flex tw-items-center tw-bg-red-400">
<input
ref="input"
autocomplete="off"
v-model="searchTerm"
class="tw-peer tw-z-10 tw-w-full tw-border tw-border-gray-600 tw-bg-white tw-px-3 tw-py-1.5 tw-text-sm tw-ring-0 placeholder:tw-text-sky-300 focus:tw-outline-none"
:placeholder="$t('master.search_placeholder')"
@keydown.down="onKeyDown"
/>
<i
class="fa fa-search tw-pointer-events-none tw-absolute tw-right-3 tw-z-20 tw-text-sm"
></i>

<!-- Ukraine -->
<div
class="tw-absolute tw-flex tw-h-full tw-w-full tw-flex-col tw-opacity-0 tw-transition-opacity peer-focus:tw-opacity-50"
>
<div
class="tw-flex tw-flex-col tw-opacity-0 tw-absolute tw-w-full tw-h-full peer-focus:tw-opacity-50 tw-transition-opacity"
>
<div
class="tw-shadow-[0px_0px_5px_2px_#0057b7] sm:tw-shadow-[0px_0px_10px_3px_#0057b7] tw-h-full"
></div>
<div
class="tw-shadow-[0px_0px_5px_2px_#ffd700] sm:tw-shadow-[0px_0px_10px_3px_#ffd700] tw-h-full"
></div>
</div>

<!-- <input type="submit" value="submit" /> -->
class="tw-h-full tw-shadow-[0px_0px_5px_2px_#0057b7] sm:tw-shadow-[0px_0px_10px_3px_#0057b7]"
></div>
<div
class="tw-h-full tw-shadow-[0px_0px_5px_2px_#ffd700] sm:tw-shadow-[0px_0px_10px_3px_#ffd700]"
></div>
</div>

<div class="tw-absolute tw-top-4 tw-w-full">
<PopoverRoot :open="allOptions.length > 0">
<!-- Used for measuring with --radis-popover-trigger-width -->
<PopoverTrigger class="tw-pointer-events-none tw-invisible tw-w-full" />

<PopoverContent
:trapFocus="false"
class="tw-z-10 tw-mt-1 tw-w-[--radix-popover-trigger-width] tw-border tw-bg-white tw-shadow-md"
>
<ListboxRoot @entryFocus.prevent highlightOnHover>
<ListboxContent>
<ListboxGroup v-show="authorOptions.length > 0">
<ListboxGroupLabel
class="tw-mt-2.5 tw-px-2.5 tw-text-sm tw-font-thin tw-capitalize"
>
{{ $t('authority.authors') }}
</ListboxGroupLabel>
<template v-for="author in authorOptions" :key="author.value">
<ListboxItem
:value="author.url"
class="tw-flex tw-cursor-pointer tw-space-x-3 tw-px-2.5 tw-py-2 focus:tw-outline-none data-[highlighted]:tw-bg-gray-800 data-[highlighted]:tw-text-white"
>
<img
:src="author.image"
class="tw-h-9 tw-w-9 tw-rounded-full"
/>
<div
class="tw-flex tw-flex-col tw-text-xs tw-leading-4 tw-tracking-wider"
>
<span class="tw-italic">
{{ author.name }}
</span>
<span v-if="author.birthYear">
<span v-if="author.deathYear">
(✴ {{ author.birthYear }} – ✝
{{ author.deathYear }})
</span>
<span v-else>(✴ {{ author.birthYear }})</span>
</span>
</div>
</ListboxItem>
<Separator
class="tw-z-20 tw-h-px tw-bg-gray-300 last:tw-hidden"
/>
</template>
</ListboxGroup>
<ListboxGroup v-show="itemOptions.length > 0">
<ListboxGroupLabel
class="tw-mt-2.5 tw-px-2.5 tw-text-sm tw-font-thin tw-capitalize"
>
{{ $t('katalog.title') }}
</ListboxGroupLabel>
<template v-for="item in itemOptions" :key="item.id">
<ListboxItem
class="tw-flex tw-cursor-pointer tw-space-x-3 tw-px-2.5 tw-py-2 focus:tw-outline-none data-[highlighted]:tw-bg-gray-800 data-[highlighted]:tw-text-white"
:value="item.url"
>
<img :src="item.image" class="tw-h-9 tw-w-9" />
<div
class="tw-flex tw-flex-col tw-text-xs tw-leading-4 tw-tracking-wider"
>
<span class="tw-italic">
{{ item.author }}
</span>
<span>{{ item.title }}</span>
</div>
</ListboxItem>
<Separator
class="tw-z-20 tw-h-px tw-bg-gray-300 last:tw-hidden"
/>
</template>
</ListboxGroup>
</ListboxContent>
</ListboxRoot>
</PopoverContent>
</PopoverRoot>
</div>
</form>
</div>
</template>
71 changes: 56 additions & 15 deletions resources/views/components/nav_bar.blade.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<nav class="navbar {!! (Request::is('/') || isSet($transparent_menu)) ? '' : 'dark-text' !!}" role="navigation">
<nav class="navbar {!! Request::is('/') || isset($transparent_menu) ? '' : 'dark-text' !!}" role="navigation">
<div class="container">
<div class="navbar-header page-scroll">
@include('components.langswitch', [
Expand All @@ -7,58 +7,99 @@
'localizedURLs' => getLocalizedURLArray(),
])

<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-main-collapse">
<button type="button" class="navbar-toggle" data-toggle="collapse"
data-target=".navbar-main-collapse">
<i class="fa fa-bars fa-2x"></i>
</button>
<a class="navbar-brand no-border hidden-xs first-part" href="{!! URL::to('') !!}">
web
</a>

@include('components.searchbar', [
'search' => isSet($search) ? $search : '',
'search' => isset($search) ? $search : '',
])

<a class="navbar-brand no-border hidden-xs second-part" href="{!! URL::to('') !!}">
umenia
</a>
</div>
{{-- TODO Duplicated header -- remove before merging --}}
<div class="tailwind-rules navbar-header page-scroll">
@include('components.langswitch', [
'currentLocale' => App::getLocale(),
'localesOrdered' => LaravelLocalization::getLocalesOrder(),
'localizedURLs' => getLocalizedURLArray(),
])

<button type="button" class="navbar-toggle" data-toggle="collapse"
data-target=".navbar-main-collapse">
<i class="fa fa-bars fa-2x"></i>
</button>
<a class="navbar-brand no-border hidden-xs first-part" href="{!! URL::to('') !!}">
web
</a>

<div class="tw-inline-block tw-w-[80%] tw-max-w-[425px] tw-px-4 tw-text-left">
<search-bar>
{{-- Placeholder before JS loads up --}}
<div class="tw-relative tw-flex tw-items-center">
<i
class="fa fa-search tw-pointer-events-none tw-absolute tw-right-3 tw-z-20 tw-text-sm"></i>
<input autocomplete="off"
class="tw-peer tw-z-10 tw-w-full tw-border tw-border-gray-600 tw-bg-white tw-px-3 tw-py-1.5 tw-text-sm tw-ring-0 placeholder:tw-text-sky-300 focus:tw-outline-none"
placeholder="{{ trans('master.search_placeholder') }}" />
</div>
</search-bar>
</div>

<a class="navbar-brand no-border hidden-xs second-part" href="{!! URL::to('') !!}">
umenia
</a>
</div>

<div class="collapse navbar-collapse navbar-main-collapse">
<ul class="nav navbar-nav">
<li class="visible-xs {{ Request::is('/') ? 'active' : '' }}">
<a href="/">Web umenia</a>
</li>
<li class="{{ Route::is('frontend.catalog.index', 'dielo') ? 'active' : '' }}">
<a href="{{ route('frontend.catalog.index') }}">{{ utrans('master.artworks') }}</a>
<a
href="{{ route('frontend.catalog.index') }}">{{ utrans('master.artworks') }}</a>
</li>
<li class="{{ Route::is('frontend.collection.*') ? 'active' : '' }}">
<a href="{{ route('frontend.collection.index') }}">{{ utrans('master.collections') }}</a>
<a
href="{{ route('frontend.collection.index') }}">{{ utrans('master.collections') }}</a>
</li>
<li class="{{ Route::is('frontend.author.*') ? 'active' : '' }}">
<a href="{{ route('frontend.author.index') }}">{{ utrans('master.authors') }}</a>
<a
href="{{ route('frontend.author.index') }}">{{ utrans('master.authors') }}</a>
</li>
<li class="{{ Route::is('frontend.article.*') ? 'active' : '' }}">
<a href="{{ route('frontend.article.index') }}">{{ utrans('master.articles') }}</a>
<a
href="{{ route('frontend.article.index') }}">{{ utrans('master.articles') }}</a>
</li>
<li class="{{ Route::is('frontend.educational-article.*') ? 'active' : '' }}">
<a href="{{ route('frontend.educational-article.index') }}">{{ utrans('master.education') }}</a>
<a
href="{{ route('frontend.educational-article.index') }}">{{ utrans('master.education') }}</a>
</li>
<li class="{{ Route::is('frontend.reproduction.index') ? 'active' : '' }}">
<a href="{{ route('frontend.reproduction.index') }}">{{ utrans('master.reproductions') }}</a>
<a
href="{{ route('frontend.reproduction.index') }}">{{ utrans('master.reproductions') }}</a>
</li>
<li class="{{ Route::is('frontend.info') ? 'active' : '' }}">
<a href="{{ route('frontend.info') }}">{{ utrans('master.info') }}</a>
<a href="{{ route('frontend.info') }}">{{ utrans('master.info') }}</a>
</li>
@if (Session::has('cart') && count(Session::get('cart')) > 0)
<li class="{{ Route::is('frontend.reproduction.detail') ? 'active' : '' }}">
<a href="{{ route('frontend.reproduction.detail') }}" class=""><i class="fa fa-shopping-cart"></i><span class="badge badge-sup badge-notify">{!! count(Session::get('cart')) !!}</span></a>
</li>
<li class="{{ Route::is('frontend.reproduction.detail') ? 'active' : '' }}">
<a href="{{ route('frontend.reproduction.detail') }}" class=""><i
class="fa fa-shopping-cart"></i><span
class="badge badge-sup badge-notify">{!! count(Session::get('cart')) !!}</span></a>
</li>
@endif
<li class="{{ Route::is('frontend.user-collection.show') ? 'active' : '' }}">
<user-collections-nav-link
base-href="{{ route('frontend.user-collection.show') }}"
title="{{ utrans('master.favourites') }}"
></user-collections-nav-link>
title="{{ utrans('master.favourites') }}"></user-collections-nav-link>
</li>
</ul>
</div>
Expand Down

0 comments on commit cacdd70

Please sign in to comment.