search stuffs
This commit is contained in:
@@ -7,10 +7,12 @@ use GoldSpecDigital\LaravelEloquentUUID\Database\Eloquent\Uuid;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Source;
|
||||
use App\Topic;
|
||||
use Laravel\Scout\Searchable;
|
||||
|
||||
class Article extends Model
|
||||
{
|
||||
use Uuid;
|
||||
use Searchable;
|
||||
|
||||
/**
|
||||
* The "type" of the auto-incrementing ID.
|
||||
@@ -73,4 +75,14 @@ class Article extends Model
|
||||
return $this->with('source', 'topics')
|
||||
->latest("published_date");
|
||||
}
|
||||
|
||||
public function toSearchableArray()
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'title' => $this->title,
|
||||
'body' => implode(" ",$this->body),
|
||||
'author' => $this->author
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -15,12 +15,15 @@
|
||||
"fruitcake/laravel-cors": "^2.0",
|
||||
"goldspecdigital/laravel-eloquent-uuid": "^8.0",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"http-interop/http-factory-guzzle": "^1.0",
|
||||
"jinas/moosun": "^1.1",
|
||||
"laravel/framework": "^8.0",
|
||||
"laravel/jetstream": "^1.2",
|
||||
"laravel/sanctum": "^2.6",
|
||||
"laravel/scout": "^9.2",
|
||||
"laravel/tinker": "^2.0",
|
||||
"livewire/livewire": "^2.0",
|
||||
"meilisearch/meilisearch-php": "^0.18.3",
|
||||
"mtownsend/read-time": "^2.0",
|
||||
"predis/predis": "^1.1",
|
||||
"realrashid/sweet-alert": "^3.1",
|
||||
|
929
composer.lock
generated
929
composer.lock
generated
File diff suppressed because it is too large
Load Diff
64
package-lock.json
generated
64
package-lock.json
generated
@@ -5,6 +5,7 @@
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"meilisearch": "^0.19.0",
|
||||
"moment": "^2.28.0",
|
||||
"turbolinks": "^5.2.0",
|
||||
"vue": "^2.6.11",
|
||||
@@ -4153,6 +4154,14 @@
|
||||
"yarn": ">=1"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
|
||||
"integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==",
|
||||
"dependencies": {
|
||||
"node-fetch": "2.6.1"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
@@ -7888,6 +7897,14 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/meilisearch": {
|
||||
"version": "0.19.0",
|
||||
"resolved": "https://registry.npmjs.org/meilisearch/-/meilisearch-0.19.0.tgz",
|
||||
"integrity": "sha512-o1rKT65q09i0W/vigpGEXVTX44A8IBscNQhZ+JkAlEgpk2+mYZMQxHXcoBtWjZI/CYKoswVnUxBVB4HEJ8tJQw==",
|
||||
"dependencies": {
|
||||
"cross-fetch": "^3.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/mem": {
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.npmjs.org/mem/-/mem-8.1.1.tgz",
|
||||
@@ -8375,6 +8392,14 @@
|
||||
"lodash.toarray": "^4.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-forge": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
|
||||
@@ -18206,7 +18231,8 @@
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.3.tgz",
|
||||
"integrity": "sha512-WQs0ep98FXX2XBAfQpRbY0Ma6ADw8JR6xoIkaIiJIzClGOMqVRvPCWqndTxf28DgFopWan0EKtHtg/5W1h0Zkw==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"@webpack-cli/info": {
|
||||
"version": "1.2.4",
|
||||
@@ -18221,7 +18247,8 @@
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.4.0.tgz",
|
||||
"integrity": "sha512-xgT/HqJ+uLWGX+Mzufusl3cgjAcnqYYskaB7o0vRcwOEfuu6hMzSILQpnIzFMGsTaeaX4Nnekl+6fadLbl1/Vg==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"@xtuc/ieee754": {
|
||||
"version": "1.2.0",
|
||||
@@ -18317,7 +18344,8 @@
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
|
||||
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"alphanum-sort": {
|
||||
"version": "1.0.2",
|
||||
@@ -19518,6 +19546,14 @@
|
||||
"cross-spawn": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"cross-fetch": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
|
||||
"integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==",
|
||||
"requires": {
|
||||
"node-fetch": "2.6.1"
|
||||
}
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
@@ -21637,7 +21673,8 @@
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
|
||||
"integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.2.1",
|
||||
@@ -22457,6 +22494,14 @@
|
||||
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
|
||||
"dev": true
|
||||
},
|
||||
"meilisearch": {
|
||||
"version": "0.19.0",
|
||||
"resolved": "https://registry.npmjs.org/meilisearch/-/meilisearch-0.19.0.tgz",
|
||||
"integrity": "sha512-o1rKT65q09i0W/vigpGEXVTX44A8IBscNQhZ+JkAlEgpk2+mYZMQxHXcoBtWjZI/CYKoswVnUxBVB4HEJ8tJQw==",
|
||||
"requires": {
|
||||
"cross-fetch": "^3.1.4"
|
||||
}
|
||||
},
|
||||
"mem": {
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.npmjs.org/mem/-/mem-8.1.1.tgz",
|
||||
@@ -22840,6 +22885,11 @@
|
||||
"lodash.toarray": "^4.4.0"
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
|
||||
},
|
||||
"node-forge": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
|
||||
@@ -24974,7 +25024,8 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
|
||||
"integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"postcss-modules-local-by-default": {
|
||||
"version": "4.0.0",
|
||||
@@ -28830,7 +28881,8 @@
|
||||
"version": "7.4.5",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz",
|
||||
"integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.2",
|
||||
|
@@ -28,6 +28,7 @@
|
||||
"vue-template-compiler": "^2.6.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"meilisearch": "^0.19.0",
|
||||
"moment": "^2.28.0",
|
||||
"turbolinks": "^5.2.0",
|
||||
"vue": "^2.6.11",
|
||||
|
2013
public/css/app.css
vendored
2013
public/css/app.css
vendored
File diff suppressed because one or more lines are too long
59551
public/js/app.js
vendored
59551
public/js/app.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"/js/app.js": "/js/app.js?id=abf0a000d5784d7aa33c",
|
||||
"/css/app.css": "/css/app.css?id=414685d6b836d6325b7b"
|
||||
"/js/app.js": "/js/app.js",
|
||||
"/css/app.css": "/css/app.css"
|
||||
}
|
||||
|
4
public/vendor/livewire/livewire.js
vendored
4
public/vendor/livewire/livewire.js
vendored
File diff suppressed because one or more lines are too long
2
public/vendor/livewire/livewire.js.map
vendored
2
public/vendor/livewire/livewire.js.map
vendored
File diff suppressed because one or more lines are too long
2
public/vendor/livewire/manifest.json
vendored
2
public/vendor/livewire/manifest.json
vendored
@@ -1 +1 @@
|
||||
{"/livewire.js":"/livewire.js?id=09c5bbff75d74521e6c7"}
|
||||
{"/livewire.js":"/livewire.js?id=e6704f81026a73a52725"}
|
4
resources/css/app.css
vendored
4
resources/css/app.css
vendored
@@ -1,3 +1,7 @@
|
||||
@import 'tailwindcss/base';
|
||||
@import 'tailwindcss/components';
|
||||
@import 'tailwindcss/utilities';
|
||||
|
||||
.search-result em {
|
||||
@apply bg-green-200;
|
||||
}
|
10
resources/js/app.js
vendored
10
resources/js/app.js
vendored
@@ -1,5 +1,15 @@
|
||||
require('./bootstrap');
|
||||
|
||||
import { MeiliSearch } from 'meilisearch';
|
||||
|
||||
window.MeiliSearch = MeiliSearch;
|
||||
|
||||
import search from './search';
|
||||
|
||||
window.components = {
|
||||
search,
|
||||
};
|
||||
|
||||
import Vue from 'vue';
|
||||
import Turbolinks from 'turbolinks';
|
||||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
|
36
resources/js/search.js
vendored
Normal file
36
resources/js/search.js
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
export default function (meilisearchConfig, index, searchOptions) {
|
||||
const defaultSearchOptiobns = {
|
||||
limit: 10,
|
||||
};
|
||||
|
||||
searchOptions = { ...defaultSearchOptiobns, ...searchOptions };
|
||||
|
||||
return {
|
||||
query: "",
|
||||
index: null,
|
||||
results: null,
|
||||
|
||||
watchQuery() {
|
||||
this.$watch("query", (query) => {
|
||||
if (query == "") {
|
||||
this.results = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this.search(query);
|
||||
});
|
||||
},
|
||||
|
||||
async search(query) {
|
||||
this.results = await this.index.search(query, searchOptions);
|
||||
},
|
||||
|
||||
init() {
|
||||
const client = new window.MeiliSearch(meilisearchConfig);
|
||||
|
||||
this.index = client.index(index);
|
||||
|
||||
this.watchQuery();
|
||||
},
|
||||
};
|
||||
}
|
44
resources/views/admin/search.blade.php
Normal file
44
resources/views/admin/search.blade.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<x-app-layout>
|
||||
<x-slot name="header">
|
||||
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
|
||||
{{ __('Dashboard') }}
|
||||
</h2>
|
||||
</x-slot>
|
||||
|
||||
<div class="py-12">
|
||||
<div class="max-w-3xl mx-auto sm:px-6 lg:px-8">
|
||||
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
|
||||
<div
|
||||
x-data="
|
||||
window.components.search({
|
||||
host: '{{ config('scout.meilisearch.host') }}'
|
||||
}, 'articles', {
|
||||
limit: 10,
|
||||
attributesToHighlight: ['title', 'body']
|
||||
})
|
||||
"
|
||||
x-init="init"
|
||||
class="bg-white border-b border-gray-200"
|
||||
>
|
||||
<x-input id="query" class="block border-none w-full" type="search" name="query"
|
||||
placeholder="Search for shits.." x-model.debounce.200="query" />
|
||||
|
||||
<template x-if="results">
|
||||
<div class="py-2 px-3 border-b border-gray-200 italic">
|
||||
Found <span x-text="results.nbHits"></span> results
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<template x-if="results" x-for="hit in results.hits">
|
||||
<a href="" class="block py-2 px-3 border-b border-gray-200 search-result">
|
||||
<h1 class="MvWaheed text-xl" x-html="hit._formatted.title"></h1>
|
||||
|
||||
<p class="MvTyper text-sm" x-html="hit._formatted.body"></p>
|
||||
</a>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-app-layout>
|
3
resources/views/components/input.blade.php
Normal file
3
resources/views/components/input.blade.php
Normal file
@@ -0,0 +1,3 @@
|
||||
@props(['disabled' => false])
|
||||
|
||||
<input {{ $disabled ? 'disabled' : '' }} {!! $attributes->merge(['class' => 'rounded-md shadow-sm border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50']) !!}>
|
@@ -12,11 +12,17 @@
|
||||
|
||||
<!-- Styles -->
|
||||
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
|
||||
<link rel="stylesheet" href="/css/styles.css">
|
||||
|
||||
@livewireStyles
|
||||
|
||||
<!-- Scripts -->
|
||||
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.6.0/dist/alpine.js" defer></script>
|
||||
|
||||
<script src="{{ asset('js/app.js') }}" defer></script>
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
<body class="font-sans antialiased">
|
||||
<div class="min-h-screen bg-gray-100">
|
||||
|
@@ -28,6 +28,12 @@
|
||||
{{ __('Monitor') }}
|
||||
</x-jet-nav-link>
|
||||
</div>
|
||||
|
||||
<div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
|
||||
<x-jet-nav-link href="/dashboard/search" :active="request()->routeIs('dashboard.search')">
|
||||
{{ __('Search') }}
|
||||
</x-jet-nav-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Settings Dropdown -->
|
||||
|
@@ -66,6 +66,9 @@ Route::middleware(['auth:sanctum', 'verified'])->prefix('dashboard')->namespace(
|
||||
|
||||
Route::get('/analytics', AnalyticsController::class)->name('dashboard.analytics');
|
||||
Route::get('/monitor', MonitorController::class)->name('dashboard.monitor');
|
||||
Route::get('/search', function() {
|
||||
return view('admin.search');
|
||||
})->name('dashboard.search');
|
||||
});
|
||||
|
||||
Route::get('ogimage/{article}', function(Article $article){
|
||||
|
Reference in New Issue
Block a user