Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
ludoguenet committed Mar 9, 2024
1 parent d23f62e commit 03d6efc
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 9 deletions.
11 changes: 10 additions & 1 deletion app/Providers/ViewServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace App\Providers;

use App\Models\Nudge;
use App\Models\User;
use Illuminate\Support\Facades;
use Illuminate\Support\ServiceProvider;
Expand All @@ -27,7 +28,15 @@ public function boot(): void
/** @var ?User $user */
$user = auth()->user();

$view->with(['notificationCount' => (int) ($user ? $user->refresh()->unreadNotifications->count() : 0)]);
$nudges = Nudge::query()
->with('user')
->validated()
->get();

$view->with([
'notificationCount' => (int) ($user ? $user->refresh()->unreadNotifications->count() : 0),
'nudges' => $nudges,
]);
});
}
}
108 changes: 108 additions & 0 deletions resources/views/components/nudge-search.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
@props([
'nudges',
])

<div class="flex-1 px-4 flex items-center justify-center">
<div x-data="dropdownSearch({{ Js::from($nudges) }})" class="relative w-full">
<input x-model="query" x-on:click.outside="reset()" x-on:keyup.escape="reset()" x-on:keyup.down="selectNextNudge" x-on:keyup.up="selectPreviousNudge" x-on:keyup.enter="goToUrl()" id="combobox" type="text" class="w-full rounded-md border-0 bg-white py-1.5 pl-3 pr-12 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-green-400 sm:text-sm sm:leading-6" role="combobox" aria-controls="options" aria-expanded="false">
<button type="button" class="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5 text-gray-400">
<path stroke-linecap="round" stroke-linejoin="round" d="M7.5 3.75H6A2.25 2.25 0 0 0 3.75 6v1.5M16.5 3.75H18A2.25 2.25 0 0 1 20.25 6v1.5m0 9V18A2.25 2.25 0 0 1 18 20.25h-1.5m-9 0H6A2.25 2.25 0 0 1 3.75 18v-1.5M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
</svg>
</button>

<ul x-show="filteredNudges.length > 0" x-transition x-cloak x-ref="nudges" class="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm" id="options" role="listbox">
<!--
Combobox option, manage highlight styles based on mouseenter/mouseleave and keyboard navigation.
Active: "text-white bg-green-600", Not Active: "text-gray-900"
-->
<template x-for="(nudge, index) in filteredNudges">
<li class="relative cursor-pointer select-none py-2 pl-3 pr-9 text-gray-900" :class="{ 'font-semibold bg-gray-100 outline-none': index === selectedNudgeIndex }" id="option-0" role="option" tabindex="-1" x-on:click.prevent="goToUrl(nudge)">
<span x-text="nudge.title" class="block truncate" :class="{ 'font-semibold': index === selectedNudgeIndex }"></span>

<span x-text="nudge.user.name" class="sm:hidden xs:block md:block absolute inset-y-2 right-0 flex items-center pr-4 text-gray-400"></span>
</li>
</template>
</ul>
<ul x-show="query !== '' && filteredNudges.length === 0" x-transition x-cloak class="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm" id="options" role="listbox">
<li class="relative cursor-default select-none py-2 pl-3 pr-9 text-gray-900" id="option-0" role="option" tabindex="-1">
<span class="block truncate font-semibold">No nudges found. <a href="{{ route('nudges.create')}}" class="text-green-400">Create it!</a></span>
</li>
</ul>
</div>
</div>

@push('scripts')
<script>
const dropdownSearch = (nudges) => {
return {
query: ""
, selectedNudgeIndex: null
, nudges: nudges,
get filteredNudges() {
if (this.query.trim() === "") {
return [];
}
return this.nudges.filter(nudge => nudge.title.toLowerCase().includes(this.query.toLowerCase()));
},
reset() {
this.query = "";
},
selectNextNudge() {
if (this.filteredNudges.length === 0) return;
if (this.selectedNudgeIndex === null) {
this.selectedNudgeIndex = 0;
} else {
this.selectedNudgeIndex++;
}
if (this.selectedNudgeIndex === this.filteredNudges.length) {
this.selectedNudgeIndex = 0;
}
this.focusSelectedNudge();
},
selectPreviousNudge() {
if (this.filteredNudges.length === 0) return;
if (this.selectedNudgeIndex === null) {
this.selectedNudgeIndex = this.filteredNudges.length - 1;
} else {
this.selectedNudgeIndex--;
}
if (this.selectedNudgeIndex < 0) {
this.selectedNudgeIndex = this.filteredNudges.length - 1;
}
this.focusSelectedNudge();
},
focusSelectedNudge() {
this.$refs.nudges.children[this.selectedNudgeIndex + 1].scrollIntoView({
block: 'nearest'
})
},
goToUrl(nudge) {
let currentNudge = nudge ? nudge : this.filteredNudges[this.selectedNudgeIndex];
if (currentNudge == null) return;
window.location = `/nudges/${currentNudge.slug}`;
},
}
}
</script>
@endpush
22 changes: 14 additions & 8 deletions resources/views/layouts/navigation.blade.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<nav x-data="{ open: false }" class="bg-white border-b border-gray-100 mb-10">
<!-- Primary Navigation Menu -->
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-16">
<div class="flex h-16">
<div class="flex">
<!-- Logo -->
<div class="shrink-0 flex items-center">
Expand All @@ -12,25 +12,31 @@

<!-- Navigation Links -->
@auth
<div class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex">
<div class="hidden space-x-4 sm:-my-px sm:ms-10 sm:flex">
<x-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')">
{{ __('Dashboard') }}
</x-nav-link>
<x-nav-link :href="route('nudges.create')" :active="request()->routeIs('nudges.create')">
{{ __('Share your nudge!') }}
</x-nav-link>

<a href="{{ route('nudges.create') }}" class="inline-flex items-center px-1 pt-1 text-sm font-medium leading-5 text-gray-900 focus:outline-none focus:border-green-700 transition duration-150 ease-in-out">
<button type="button" class="inline-flex items-center gap-x-1.5 rounded-md bg-green-500 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-green-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-500">
New Nudge
</button>
</a>
</div>
@endauth
</div>

<!-- Search -->
<x-nudge-search :nudges=$nudges />

<!-- Settings Dropdown -->
<div class="hidden sm:flex sm:items-center sm:ms-6">
@auth
<a href="{{ route('dashboard') }}" type="button" class="relative mr-1 flex-shrink-0 rounded-full bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 cursor-pointer">
<span class="absolute -inset-1.5"></span>
<span class="sr-only">View notifications</span>
<svg class="size-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0" />
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 0 0 5.454-1.31A8.967 8.967 0 0 1 18 9.75V9A6 6 0 0 0 6 9v.75a8.967 8.967 0 0 1-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 0 1-5.714 0m5.714 0a3 3 0 1 1-5.714 0" />
</svg>

@if ($notificationCount !== 0)
Expand Down Expand Up @@ -112,7 +118,7 @@
</x-responsive-nav-link>
@endif
<x-responsive-nav-link :href="route('nudges.create')" :active="request()->routeIs('nudges.create')">
{{ __('Share your nudge!') }}
{{ __('New Nudge') }}
</x-responsive-nav-link>
</div>

Expand Down

0 comments on commit 03d6efc

Please sign in to comment.