Всем добрый день ! поисковик функционирует правильно, все работает как надо, но я хочу что бы сам инпут находился в шапке сайта
пытался разными способами но у меня никак не получается ... помогите с решением вопроса
components/jsph/JSPH-table.jsx
import classes from "./Jsph.module.css";
import useSWR from "swr";
import toast from "react-hot-toast";
import { useState } from "react";
import { ObjTable, SearchForm } from "../ObjTable";
const
ADD = 'add',
API_URL = "http://localhost:3333/items",
CART_URL = "http://localhost:3333/cart",
fetcher = async () => {
const res = await fetch(API_URL);
if (!res.ok) throw new Error("fetcher" + res.status);
return await res.json();
},
infofetcher = async () => {
console.log("infofetcher",);
const pr = fetcher();
toast.promise(pr, {
loading: 'Загрузка',
success: 'Авто-обновление',
error: (err) => `${err.toString()}`,
});
return await pr
};
export function JSPHTable() {
const
{ data, error, isLoading, isValidating, mutate } = useSWR(API_URL, infofetcher, { revalidateOnFocus: false }),
[addItem, setAddItem] = useState(),
onClick = async event => {
const
action = event.target.closest('[data-action]')?.dataset?.action,
id = +event.target.closest('[data-id]')?.dataset?.id;
console.log("action and id", action, id);
console.log("addItem", addItem);
console.log("data", data);
if (!action) return;
let
optimisticData;
const
getPromise = () => {
switch (action) {
case ADD:
const newObj = {};
optimisticData = data.concat(newObj);
console.log("newObj", newObj);
return fetch(API_URL,
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(newObj)
}).then(res => {
if (!res.ok) {
throw new Error(res.status + " " + res.statusText);
}
});
}
},
promise = getPromise();
if (promise) {
toast.promise(promise, {
loading: "Fetching" + action,
success: 'ok',
error: (err) => `${err.toString()}`,
});
await mutate(promise.then(optimisticData, fetcher), { optimisticData });
};
};
return <>
<div
className={classes.loading}>
{isLoading && '⌛'}
{isValidating && ''}
{error && `❌ ${error.toString()}`}
</div>
{data && <SearchForm data={data} />}
</>
}
components/ObjTable/index.jsx
import { useMemo, useState } from "react";
import classes from "./ObjTable.module.css"
export function SearchForm({ data}) {
const
[sort, setSort] = useState(null),
[search, setSearch] = useState(''),
[isOpen, setIsOpen] = useState(true),
sortAndFilterData = useMemo(() => {
return data
.filter(row => {
if (!search.length) return true;
for (const key in row) {
console.log({ key, row }, row[key]?.includes)
if (String(row[key]).toLowerCase()?.includes?.(search.toLowerCase())) return true;
}
console.log(search)
return false;
});
}, [data, sort, search]),
itemClick = (event) => {
setSearch(event.target.textContent)
setIsOpen(!isOpen)
},
inputClick = () => {
setIsOpen(true)
};
console.debug('ObjTable render');
return <>
<form className={classes.search__form}>
<input
className={classes.search__input}
type="search" value={search}
onInput={event => setSearch(event.target.value)}
onClick={inputClick} />
<ul className={classes.autocomplete}>
{
search && isOpen
? sortAndFilterData
.filter(row => {
if (!search.length) return true;
for (const key in row) {
console.log({ key, row }, row[key]?.includes)
if (String(row[key]).toLowerCase()?.includes?.(search.toLowerCase())) return true;
}
console.log(search)
return false;
})
.map((row) => {
return <li
onClick={itemClick}
key={row.id}
className={classes.autocomplete__item}
>{row.title}</li>
})
:
null
}
</ul>
</form>
<ObjTable data={sortAndFilterData}/>
</>
}
export function ObjTable({ data }) {
console.debug('ObjTable render', data);
return <main className={classes.product__section}>
{data.map(obj => <article className={classes.product__article} key={obj.id}>
<figure className={classes.figure}>
<img className={classes.product__image} src={obj.images} alt={obj.title} />
<figcaption className={classes.product__caption}>
<h2 className={classes.product__title}>{obj.title}</h2>
</figcaption>
</figure>
<div className={classes.product__details}>
<p className={classes.product__price}><strong>Цена:</strong><span className={classes.product__value}>{obj.price}</span></p>
<button className={classes.add__to__cart__button}>Добавить в корзину</button>
</div>
</article>
)}
</main>
}
components/Link/index.jsx
import Link from "next/link";
import { FaShoppingCart } from "react-icons/fa";
import { SearchForm } from "../ObjTable/index";
const
pages = [
{href: '/', title:'Главная'},
{href: '/shopping-cart', title:'Корзина'},
];
export function PagesWebsite() {
return<header>
<nav>
<ul>
{pages.map(({href, title})=>
<li key={href}>
< Link href={href}>
{title}
</Link>
</li>)}
</ul>
</nav>
</header>
}
pages/index.jsx
import Head from "next/head";
import { JSPHTable } from "../components/jsph/JSPH-table";
export default function Home() {
return <>
<Head>
<title>интернет-магазин:WILDBERRIS</title>
</Head>
<JSPHTable/>
</>
}
pages/_app.tsx
import "@/styles/globals.css";
import type { AppProps } from "next/app";
import { PagesWebsite } from "@/components/LinkPages";
import { JSPHTable } from "@/components/jsph/JSPH-table";
import { Toaster } from "react-hot-toast";
import { useState } from "react";
export default function App({ Component, pageProps }: AppProps) {
return <>
<PagesWebsite />
<Component {...pageProps} />
<Toaster/>
</>
}