Задать вопрос
@bad_ruby

Как добавить SearchForm в шапке сайта?

Всем добрый день ! поисковик функционирует правильно, все работает как надо, но я хочу что бы сам инпут находился в шапке сайта
пытался разными способами но у меня никак не получается ... помогите с решением вопроса
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/>
  </>
}
  • Вопрос задан
  • 25 просмотров
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы