Chore: Upgrade to Laravel 12 + remove Mary and Jetstream dependencies (#141)
* docs: remove requirement for setting APP_KEY manually * optimize date picker * clean up modals * spot light working * reorganization * add lazy load * wip * remove filament * styling
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
@props([
|
||||
'id' => null,
|
||||
'shortcut' => "meta.g",
|
||||
'searchText' => "Search ...",
|
||||
'noResultsText' => "Nothing found.",
|
||||
'url' => null,
|
||||
'fallbackAvatar' => null,
|
||||
])
|
||||
|
||||
@php
|
||||
$url = $url ?? route('spotlight', absolute: false);
|
||||
@endphp
|
||||
|
||||
<div x-data="{
|
||||
loading: false,
|
||||
value: '',
|
||||
results: [],
|
||||
maxDebounce: 250,
|
||||
debounceTimer: null,
|
||||
controller: new AbortController(),
|
||||
query: '',
|
||||
searchedWithNoResults: false,
|
||||
init(){
|
||||
this.$watch('value', value => {
|
||||
this.loading = true
|
||||
|
||||
this.debounce(() => this.search(), this.maxDebounce)
|
||||
})
|
||||
},
|
||||
debounce(fn, waitTime) {
|
||||
clearTimeout(this.debounceTimer)
|
||||
this.debounceTimer = setTimeout(() => fn(), waitTime)
|
||||
},
|
||||
async search() {
|
||||
|
||||
if (this.value == '') {
|
||||
this.results = [];
|
||||
this.loading = false
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
this.controller?.abort()
|
||||
this.controller = new AbortController();
|
||||
|
||||
let response = await fetch(`{{$url}}?search=${this.value}&${this.query}`, { signal: this.controller.signal })
|
||||
this.results = await response.json()
|
||||
} catch(e) {
|
||||
console.log(e)
|
||||
return
|
||||
}
|
||||
|
||||
this.loading = false
|
||||
|
||||
Object.keys(this.results).length
|
||||
? this.searchedWithNoResults = false
|
||||
: this.searchedWithNoResults = true
|
||||
}
|
||||
}">
|
||||
<x-ui.modal
|
||||
key="spotlight"
|
||||
class="backdrop-blur-sm shadow-xl"
|
||||
box-class="absolute top-10 lg:top-24 w-full lg:max-w-3xl "
|
||||
no-card="true"
|
||||
shortcut="slash"
|
||||
@keydown.up="$focus.wrap().previous()"
|
||||
@keydown.down="$focus.wrap().next()"
|
||||
>
|
||||
<div class="relative">
|
||||
|
||||
{{-- CLOSE --}}
|
||||
<x-ui.button
|
||||
title="{{ __('Close') }} (esc)"
|
||||
class="absolute top-1/2 -translate-y-1/2 right-4 btn btn-ghost hover:bg-transparent border-none shadow-none btn-xs select-none z-50"
|
||||
@click="close()"
|
||||
@focus="$focus.lastFocused().focus()"
|
||||
>
|
||||
<kbd class="kbd kbd-sm">ESC</kbd>
|
||||
</x-ui.button>
|
||||
|
||||
{{-- INPUT --}}
|
||||
<x-ui.input
|
||||
id="{{ $id }}"
|
||||
icon="o-magnifying-glass"
|
||||
x-model="value"
|
||||
placeholder=" {{ $searchText }}"
|
||||
class="text-xl flex w-full input my-2 py-6 border-none outline-none shadow-none border-transparent focus:shadow-none focus:outline-none focus:border-transparent"
|
||||
@focus="$el.focus()"
|
||||
autofocus
|
||||
tabindex="1"
|
||||
/>
|
||||
|
||||
{{-- PROGRESS --}}
|
||||
<x-ui.progress
|
||||
x-show="loading"
|
||||
class="z-60 absolute left-0 bottom-0 w-full progress progress-secondary h-[2px]"
|
||||
indeterminate="true"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{{-- NO RESULTS --}}
|
||||
<template x-if="searchedWithNoResults && value != ''">
|
||||
<div class="bg-base-100 text-base-content/50 p-4 spotlight-element">{{ $noResultsText }}</div>
|
||||
</template>
|
||||
|
||||
{{-- RESULTS --}}
|
||||
<div
|
||||
@click="close()"
|
||||
@keydown.enter="close()"
|
||||
>
|
||||
<template x-for="(item, index) in results" :key="index">
|
||||
|
||||
{{-- ITEM --}}
|
||||
<a x-bind:href="item.link" class="spotlight-element" wire:navigate tabindex="0">
|
||||
<div class="p-4 bg-base-100 hover:bg-base-200 rounded-md">
|
||||
<div class="flex gap-3 items-center">
|
||||
|
||||
{{-- ICON --}}
|
||||
<template x-if="item.icon">
|
||||
<div x-html="item.icon"></div>
|
||||
</template>
|
||||
|
||||
{{-- AVATAR --}}
|
||||
<template x-if="item.avatar && !item.icon">
|
||||
<div>
|
||||
<img :src="item.avatar" class="rounded-full w-11 h-11" @if($fallbackAvatar) onerror="this.src='{{ $fallbackAvatar }}'" @endif />
|
||||
</div>
|
||||
</template>
|
||||
<div class="flex-1 overflow-hidden whitespace-nowrap text-ellipsis truncate w-0">
|
||||
|
||||
{{-- NAME --}}
|
||||
<div x-text="item.name" class="font-semibold truncate"></div>
|
||||
|
||||
{{-- DESCRIPTION --}}
|
||||
<template x-if="item.description">
|
||||
<div x-text="item.description" class="text-base-content/50 text-sm truncate"></div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</template>
|
||||
<div x-show="results.length" class="mb-3"></div>
|
||||
</div>
|
||||
|
||||
</x-ui.modal>
|
||||
</div>
|
||||
Reference in New Issue
Block a user