Skip to content

Commit

Permalink
add category search functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
saleem-hadad committed Mar 28, 2024
1 parent 1e16898 commit 90b973a
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 22 deletions.
14 changes: 13 additions & 1 deletion app/Models/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

namespace App\Models;

use App\Contracts\Searchable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Category extends Model
class Category extends Model implements Searchable
{
use HasFactory;

Expand All @@ -27,4 +29,14 @@ public function brands()
{
return $this->hasMany(Brand::class);
}

/**
* @param $query
* @return Builder
*/
public static function search($query): Builder
{
return (new static())->newQuery()
->where('name', 'LIKE', "%$query%");
}
}
2 changes: 1 addition & 1 deletion graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type Query {
@orderBy(column: id direction: DESC)

allCategories: [Category!]! @all
categories: [Category!]!
categories(search: String @search): [Category!]!
@paginate(defaultCount: 50)
@orderBy(column: id direction: DESC)

Expand Down
2 changes: 1 addition & 1 deletion public/js/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"/js/app.js": "/js/app.js?id=e46970d4146019f17f019679336faf94",
"/js/app.js": "/js/app.js?id=0beb19fbc5c9f3f7f2b1142b3638266a",
"/css/app.css": "/css/app.css?id=a29af113c48845a119a56553951013db"
}
12 changes: 6 additions & 6 deletions resources/js/Api/categories.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@ export const getAllCategories = () => {
return client
.query(gql`
query {
allCategories {
id
allCategories {
id
name
color
}
}
}
`)
.toPromise();
}

export const getCategories = (page) => {
export const getCategories = (page, searchQuery) => {
return client
.query(gql`
query {
categories(page: ${page}) {
categories(search: """${searchQuery}""" page: ${page}) {
data {
id
name
Expand Down Expand Up @@ -63,4 +63,4 @@ export const updateCategory = ({id, name, type, color}) => {
}
`)
.toPromise();
}
}
61 changes: 49 additions & 12 deletions resources/js/Pages/Category/Index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, {useEffect, useMemo, useState} from 'react';
import { PencilAltIcon, TrashIcon } from '@heroicons/react/outline';
import { Head } from '@inertiajs/inertia-react';

Expand All @@ -10,11 +10,13 @@ import Button from '@/Components/Global/Button';
import Delete from '@/Components/Domain/Delete';
import { getCategories } from '@/Api';
import { animateRowItem } from '@/Utils';
import {debounce} from "lodash";

export default function Index({auth}) {
const [categories, setCategories] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [hasMorePages, setHasMorePages] = useState(true);
const [searchQuery, setSearchQuery] = useState('');
const [loading, setLoading] = useState(false);
const [editCategory, setEditCategory] = useState(null);
const [showCreate, setShowCreate] = useState(false);
Expand All @@ -24,7 +26,7 @@ export default function Index({auth}) {
if(! hasMorePages) return;
setLoading(true);

getCategories(currentPage)
getCategories(currentPage, searchQuery)
.then(({data}) => {
setCategories([...categories, ...data.categories.data])
setHasMorePages(data.categories.paginatorInfo.hasMorePages)
Expand All @@ -33,6 +35,18 @@ export default function Index({auth}) {
.catch(console.error);
}, [currentPage]);

useEffect(() => {
setLoading(true);

getCategories(currentPage, searchQuery)
.then(({data}) => {
setCategories([...categories, ...data.categories.data])
setHasMorePages(data.categories.paginatorInfo.hasMorePages)
setLoading(false);
})
.catch(console.error);
}, [searchQuery]);

const onCreate = (createdItem) => {
setShowCreate(false)
setCategories([createdItem, ...categories])
Expand Down Expand Up @@ -61,17 +75,38 @@ export default function Index({auth}) {
})
}

return (
<Authenticated auth={auth}
header={
<div className='flex justify-between items-center'>
<h2 className="font-semibold text-xl text-gray-800 leading-tight">
Categories
</h2>

<Button children={"Create Category"} type="button" onClick={() => setShowCreate(true)} />
const performSearchHandler = (e) => {
setCategories([]);
setSearchQuery(e.target.value ?? '');
setCurrentPage(1);
}

const performSearch = useMemo(
() => debounce(performSearchHandler, 300)
, []);

const header = <div className="w-full pb-3 mb-4 px-4 sm:px-0">
<h2 className='text-lg text-gray-600'>Categories</h2>

<div className='flex justify-between items-center mt-2'>
<div>
<div className="relative flex items-center">
<input
type="text"
name="search"
placeholder='🔍 Search'
onChange={performSearch}
className="block w-full rounded-full border-0 py-1.5 pr-14 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-500 sm:text-sm sm:leading-6"
/>
</div>
}>
</div>

<Button children={"Create Category"} type="button" onClick={() => setShowCreate(true)} />
</div>
</div>

return (
<Authenticated auth={auth}>
<Head title="Categories" />

<Create showCreate={showCreate}
Expand All @@ -90,6 +125,8 @@ export default function Index({auth}) {

<div className="py-12">
<div className="max-w-7xl mx-auto sm:px-6 lg:px-8">
{header}

<div className="flex flex-col">
{categories.length > 0 && <div className="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div className="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
Expand Down
11 changes: 11 additions & 0 deletions tests/Unit/Models/Categories/CategoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,15 @@ public function category_can_have_brands()

$this->assertCount(3, $sut->brands);
}

/** @test */
public function is_does_search_about_amount_brand_or_note()
{
Category::factory()->create(['name' => 'debt']);
Category::factory()->create(['name' => 'deee']);

$this->assertCount(0, Category::search('goo')->get());
$this->assertCount(1, Category::search('debt')->get());
$this->assertCount(2, Category::search('de')->get());
}
}

0 comments on commit 90b973a

Please sign in to comment.