Javascript 未触发支柱的反应模式
在react项目中的一个页面中,我有一个触发useState的函数,该函数包含一个布尔值,负责显示或不显示与同一页面重叠的模式Javascript 未触发支柱的反应模式,javascript,reactjs,modal-dialog,Javascript,Reactjs,Modal Dialog,在react项目中的一个页面中,我有一个触发useState的函数,该函数包含一个布尔值,负责显示或不显示与同一页面重叠的模式 const [modalOpened, setModalOpened] = useState(false); 这是负责处理状态更改的功能: const handleImageClick = () => { setModalOpened(!modalOpened); }; “我的模态”接受一个道具,该道具将用于设置处理模态是否显示的状态
const [modalOpened, setModalOpened] = useState(false);
这是负责处理状态更改的功能:
const handleImageClick = () => {
setModalOpened(!modalOpened);
};
“我的模态”接受一个道具,该道具将用于设置处理模态是否显示的状态
<ProductModal openModal={modalOpened} />
由于某种原因,在触发改变外部页面状态的功能时,模式不会显示。我可能在渲染方面做了一些错误的事情,但是如果你有一个好的解决方案,我在听
外部页面的完整代码:
import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { WhiteLink } from "../shared/Buttons";
import { ProductAddProgressBar, Step } from "../shared/ProgressBars";
import { apiClient } from "../../API/ApiClient";
import { TemplateProductPTO } from "./AddProductPageSecond";
import { useAppDispatch } from "../../store/store";
import {
selectSearchQuery,
selectSearchResults,
updateTemplateProduct,
updateSearchQuery,
updateSearchResults,
} from "../../store/inventory/slice";
import { useSelector } from "react-redux";
import ProductModal from "./ProductModal";
export const AddProductPageFirst = () => {
const [modalOpened, setModalOpened] = useState(false);
const dispatch = useAppDispatch();
const searchQuery = useSelector(selectSearchQuery);
const searchResults = useSelector(selectSearchResults);
const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
dispatch(updateSearchQuery(event.target.value));
};
const searchProducts = async () => {
if (searchQuery) {
const results = await apiClient.searchProducts(searchQuery);
dispatch(updateSearchResults(results));
}
};
const enterSearchProducts = (event: any) => {
var code = event.keyCode || event.which;
if (code === 13) {
//13 is the enter keycode
searchProducts();
}
};
const handleImageClick = () => {
setModalOpened(!modalOpened);
console.log(modalOpened);
};
const steps: Step[] = [
{
status: "current",
name: "Select product",
link: "/addproduct/1/",
},
{
status: "upcoming",
name: "Edit Details",
link: "/addproduct/2/",
},
{
status: "upcoming",
name: "Add photos",
link: "/addproduct/3/",
},
{
status: "upcoming",
name: "Summary",
link: "/addproduct/4/",
},
];
useEffect(() => {}, [modalOpened]);
return (
<div className="container mx-auto px-4 sm:px-6 lg:px-8 my-32">
<div className="mb-8">
<WhiteLink message={"Exit"} link={"/inventory"} />
</div>
<ProductAddProgressBar steps={steps} />
<div className="flex">
<nav className="space-y-1 w-1/5 mr-8 mt-16" aria-label="Sidebar">
{/*<!-- Current: "bg-gray-100 text-gray-900", Default: "text-gray-600 hover:bg-gray-50 hover:text-gray-900" -->*/}
<a
href="#"
className="bg-gray-100 text-gray-900 group flex items-center px-3 py-2 text-sm font-medium rounded-md"
aria-current="page"
>
<span className="truncate">Dashboard</span>
{/*<!-- Current: "bg-white", Default: "bg-gray-100 text-gray-600 group-hover:bg-gray-200" -->*/}
<span className="bg-white ml-auto inline-block py-0.5 px-3 text-xs rounded-full">
5
</span>
</a>
<a
href="#"
className="text-gray-600 hover:bg-gray-50 hover:text-gray-900 group flex items-center px-3 py-2 text-sm font-medium rounded-md"
>
<span className="truncate">Team</span>
</a>
<a
href="#"
className="text-gray-600 hover:bg-gray-50 hover:text-gray-900 group flex items-center px-3 py-2 text-sm font-medium rounded-md"
>
<span className="truncate">Projects</span>
<span className="bg-gray-100 text-gray-600 group-hover:bg-gray-200 ml-auto inline-block py-0.5 px-3 text-xs rounded-full">
19
</span>
</a>
<a
href="#"
className="text-gray-600 hover:bg-gray-50 hover:text-gray-900 group flex items-center px-3 py-2 text-sm font-medium rounded-md"
>
<span className="truncate">Calendar</span>
<span className="bg-gray-100 text-gray-600 group-hover:bg-gray-200 ml-auto inline-block py-0.5 px-3 text-xs rounded-full">
20+
</span>
</a>
<a
href="#"
className="text-gray-600 hover:bg-gray-50 hover:text-gray-900 group flex items-center px-3 py-2 text-sm font-medium rounded-md"
>
<span className="truncate">Documents</span>
</a>
<a
href="#"
className="text-gray-600 hover:bg-gray-50 hover:text-gray-900 group flex items-center px-3 py-2 text-sm font-medium rounded-md"
>
<span className="truncate">Reports</span>
</a>
</nav>
<div className="w-4/5 h-full mt-16">
<div className="mt-6 grid grid-cols-4 gap-6">
<div className="col-span-4 sm:col-span-1" />
<div className="col-span-4 sm:col-span-2 bg-white overflow-hidden shadow rounded-lg h-full">
<div className="px-4 py-5 sm:p-6">
<h2 className="text-center text-3xl font-extrabold tracking-tight text-gray-900 flex justify-center">
Find your product in the LocalShops database
</h2>
</div>
<div className="px-4 py-5 sm:p-6">
<div className="mt-1 flex rounded-md shadow-sm">
<div className="relative flex items-stretch flex-grow focus-within:z-10">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
{/* Heroicon name: solid/users */}
<svg
className="flex-shrink-0 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
clipRule="evenodd"
/>
</svg>
</div>
</div>
<input
onChange={(event) => handleSearchChange(event)}
onSubmit={() => searchProducts()}
onKeyPress={(event) => enterSearchProducts(event)}
value={searchQuery ?? ""}
type="text"
name="q"
id="q"
className="focus:ring-indigo-500 focus:border-indigo-500 block w-full rounded-none rounded-l-md pl-10 sm:text-sm border-gray-300"
placeholder="Type the name of your product"
/>
<button
onClick={() => searchProducts()}
type="submit"
className="-ml-px relative inline-flex items-center space-x-2 py-2 px-4 border border-transparent rounded-r-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
{/* Heroicon name: solid/sort-ascending */}
<span>Search</span>
</button>
</div>
</div>
</div>
<div className="col-span-4 sm:col-span-1 bg-white overflow-hidden shadow rounded-lg h-full">
<div className="px-4 py-5 sm:p-6">
<h2 className="text-lg leading-6 font-medium text-gray-900 flex justify-center">
What is the LocalShops database?
</h2>
<p className="text-sm leading-5 font-normal text-gray-500">
All the products sold on LocalShops have to be included in the
database for them to be found when users search. By adding a
product from the database to your shop, you are able to add
the inventory and sell it.
</p>
</div>
</div>
</div>
{/* Table */}
{searchResults.length > 0 && (
<div className="flex flex-col mt-16">
<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">
<div className="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Image
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Name
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Product SKU
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Rating
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Stocked By
</th>
<th scope="col" className="relative px-6 py-3" />
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{searchResults.map(
(default_product: TemplateProductPTO) => (
<tr>
<td className="px-6 py-4 whitespace-nowrap">
<div
className="flex items-center"
onClick={() => handleImageClick()}
>
<div className="flex-shrink-0 h-10 w-10">
{default_product.photos.length > 0 && (
<img
className="h-10 w-10 rounded-sm"
src={default_product.photos[0].image}
alt=""
/>
)}
</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center">
<div>
<div className="text-sm font-medium text-gray-900">
{default_product.name}
</div>
<div className="text-sm text-gray-500 truncate max-w-xs">
{default_product.desc}
</div>
</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center">
<div>
<div className="text-sm font-medium text-gray-900">
{default_product.sku}
</div>
</div>
</div>
</td>
{/*<td className="px-6 py-4 whitespace-nowrap">*/}
{/* <span className="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">*/}
{/* Active*/}
{/* </span>*/}
{/*</td>*/}
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center">
<div>
<div className="text-sm font-medium text-gray-900">
{default_product.rating}
</div>
</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center">
<div>
<div className="text-sm font-medium text-gray-900">
{`${
default_product.products.length
} shop${
default_product.products.length > 1
? "s"
: ""
}`}
</div>
</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<Link
to={{
pathname: "/addproduct/2",
}}
onClick={() =>
dispatch(
updateTemplateProduct(default_product)
)
}
className="font-medium text-indigo-600 hover:text-indigo-500"
>
Choose
</Link>
</td>
</tr>
)
)}
</tbody>
</table>
</div>
</div>
</div>
</div>
)}
<ProductModal openModal={modalOpened} />
</div>
</div>
</div>
);
};
import React,{useffect,useState}来自“React”;
从“react router dom”导入{Link};
从“./shared/Buttons”导入{WhiteLink};
从“./shared/ProgressBars”导入{ProductAddProgressBar,步骤}”;
从“../../API/apiClient”导入{apiClient}”;
从“/AddProductPageSecond”导入{TemplateProductPTO};
从“./../store/store”导入{useAppDispatch}”;
进口{
选择SearchQuery,
选择搜索结果,
updateTemplateProduct,
更新搜索查询,
更新搜索结果,
}来自“../../store/inventory/slice”;
从“react redux”导入{useSelector};
从“/ProductModal”导入ProductModal;
导出常量AddProductPageFirst=()=>{
const[modalOpened,setModalOpened]=使用状态(false);
const dispatch=useAppDispatch();
const searchQuery=useSelector(selectSearchQuery);
const searchResults=useSelector(selectSearchResults);
const handleSearchChange=(事件:React.ChangeEvent)=>{
分派(updateSearchQuery(event.target.value));
};
const searchProducts=async()=>{
如果(搜索查询){
const results=await apiClient.searchProducts(searchQuery);
发送(更新搜索结果(结果));
}
};
const enterSearchProducts=(事件:任意)=>{
var code=event.keyCode | | event.which;
如果(代码===13){
//13是输入键代码
搜索产品();
}
};
常量handleImageClick=()=>{
setModalOpened(!modalOpened);
控制台日志(modalOpened);
};
常量步骤:步骤[]=[
{
状态:“当前”,
名称:“选择产品”,
链接:“/addproduct/1/”,
},
{
状态:“即将到来”,
名称:“编辑详细信息”,
链接:“/addproduct/2/”,
},
{
状态:“即将到来”,
名称:“添加照片”,
链接:“/addproduct/3/”,
},
{
状态:“即将到来”,
名称:“摘要”,
链接:“/addproduct/4/”,
},
];
useffect(()=>{},[modalOpened]);
返回(
{/**/}
在LocalShops数据库中查找您的产品
{/*关于名称:solid/users*/}
handleSearchChange(事件)}
onSubmit={()=>searchProducts()}
onKeyPress={(事件)=>enterSearchProducts(事件)}
值={searchQuery???“}
type=“text”
name=“q”
id=“q”
className=“焦点:环-靛蓝-500焦点:边框-靛蓝-500块w-全圆角非圆角-l-md pl-10 sm:文本sm-边框-灰色-300”
占位符=“键入产品的名称”
/>
searchProducts()}
type=“提交”
className=“-ml px相对内联flex项目中心空间-x-2 py-2 px-4边框透明圆形-r-md阴影sm文本sm字体中文本白色bg-indigo-600悬停:bg-indigo-700焦点:轮廓无焦点:环-2焦点:环-offset-2焦点:环-indigo-500”
>
{/*关于名称:实数/升序排序*/}
搜寻
什么是LocalShops数据库?
本地商店销售的所有产品都必须包含在
当用户搜索时要查找的数据库。通过添加
产品从数据库到您的店铺,您可以添加
检查库存并将其出售。
{/*表*/}
{searchResults.length>0&&(
形象
名称
产品SKU
评级
库存
{searchResults.map(
(默认产品:TemplateProductPTO)=>(
handleImageClick()}
>
{default_product.photos.length>0&&(
)}
import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { WhiteLink } from "../shared/Buttons";
import { ProductAddProgressBar, Step } from "../shared/ProgressBars";
import { apiClient } from "../../API/ApiClient";
import { TemplateProductPTO } from "./AddProductPageSecond";
import { useAppDispatch } from "../../store/store";
import {
selectSearchQuery,
selectSearchResults,
updateTemplateProduct,
updateSearchQuery,
updateSearchResults,
} from "../../store/inventory/slice";
import { useSelector } from "react-redux";
import ProductModal from "./ProductModal";
export const AddProductPageFirst = () => {
const [modalOpened, setModalOpened] = useState(false);
const dispatch = useAppDispatch();
const searchQuery = useSelector(selectSearchQuery);
const searchResults = useSelector(selectSearchResults);
const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
dispatch(updateSearchQuery(event.target.value));
};
const searchProducts = async () => {
if (searchQuery) {
const results = await apiClient.searchProducts(searchQuery);
dispatch(updateSearchResults(results));
}
};
const enterSearchProducts = (event: any) => {
var code = event.keyCode || event.which;
if (code === 13) {
//13 is the enter keycode
searchProducts();
}
};
const handleImageClick = () => {
setModalOpened(!modalOpened);
console.log(modalOpened);
};
const steps: Step[] = [
{
status: "current",
name: "Select product",
link: "/addproduct/1/",
},
{
status: "upcoming",
name: "Edit Details",
link: "/addproduct/2/",
},
{
status: "upcoming",
name: "Add photos",
link: "/addproduct/3/",
},
{
status: "upcoming",
name: "Summary",
link: "/addproduct/4/",
},
];
useEffect(() => {}, [modalOpened]);
return (
<div className="container mx-auto px-4 sm:px-6 lg:px-8 my-32">
<div className="mb-8">
<WhiteLink message={"Exit"} link={"/inventory"} />
</div>
<ProductAddProgressBar steps={steps} />
<div className="flex">
<nav className="space-y-1 w-1/5 mr-8 mt-16" aria-label="Sidebar">
{/*<!-- Current: "bg-gray-100 text-gray-900", Default: "text-gray-600 hover:bg-gray-50 hover:text-gray-900" -->*/}
<a
href="#"
className="bg-gray-100 text-gray-900 group flex items-center px-3 py-2 text-sm font-medium rounded-md"
aria-current="page"
>
<span className="truncate">Dashboard</span>
{/*<!-- Current: "bg-white", Default: "bg-gray-100 text-gray-600 group-hover:bg-gray-200" -->*/}
<span className="bg-white ml-auto inline-block py-0.5 px-3 text-xs rounded-full">
5
</span>
</a>
<a
href="#"
className="text-gray-600 hover:bg-gray-50 hover:text-gray-900 group flex items-center px-3 py-2 text-sm font-medium rounded-md"
>
<span className="truncate">Team</span>
</a>
<a
href="#"
className="text-gray-600 hover:bg-gray-50 hover:text-gray-900 group flex items-center px-3 py-2 text-sm font-medium rounded-md"
>
<span className="truncate">Projects</span>
<span className="bg-gray-100 text-gray-600 group-hover:bg-gray-200 ml-auto inline-block py-0.5 px-3 text-xs rounded-full">
19
</span>
</a>
<a
href="#"
className="text-gray-600 hover:bg-gray-50 hover:text-gray-900 group flex items-center px-3 py-2 text-sm font-medium rounded-md"
>
<span className="truncate">Calendar</span>
<span className="bg-gray-100 text-gray-600 group-hover:bg-gray-200 ml-auto inline-block py-0.5 px-3 text-xs rounded-full">
20+
</span>
</a>
<a
href="#"
className="text-gray-600 hover:bg-gray-50 hover:text-gray-900 group flex items-center px-3 py-2 text-sm font-medium rounded-md"
>
<span className="truncate">Documents</span>
</a>
<a
href="#"
className="text-gray-600 hover:bg-gray-50 hover:text-gray-900 group flex items-center px-3 py-2 text-sm font-medium rounded-md"
>
<span className="truncate">Reports</span>
</a>
</nav>
<div className="w-4/5 h-full mt-16">
<div className="mt-6 grid grid-cols-4 gap-6">
<div className="col-span-4 sm:col-span-1" />
<div className="col-span-4 sm:col-span-2 bg-white overflow-hidden shadow rounded-lg h-full">
<div className="px-4 py-5 sm:p-6">
<h2 className="text-center text-3xl font-extrabold tracking-tight text-gray-900 flex justify-center">
Find your product in the LocalShops database
</h2>
</div>
<div className="px-4 py-5 sm:p-6">
<div className="mt-1 flex rounded-md shadow-sm">
<div className="relative flex items-stretch flex-grow focus-within:z-10">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
{/* Heroicon name: solid/users */}
<svg
className="flex-shrink-0 h-5 w-5 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
clipRule="evenodd"
/>
</svg>
</div>
</div>
<input
onChange={(event) => handleSearchChange(event)}
onSubmit={() => searchProducts()}
onKeyPress={(event) => enterSearchProducts(event)}
value={searchQuery ?? ""}
type="text"
name="q"
id="q"
className="focus:ring-indigo-500 focus:border-indigo-500 block w-full rounded-none rounded-l-md pl-10 sm:text-sm border-gray-300"
placeholder="Type the name of your product"
/>
<button
onClick={() => searchProducts()}
type="submit"
className="-ml-px relative inline-flex items-center space-x-2 py-2 px-4 border border-transparent rounded-r-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
{/* Heroicon name: solid/sort-ascending */}
<span>Search</span>
</button>
</div>
</div>
</div>
<div className="col-span-4 sm:col-span-1 bg-white overflow-hidden shadow rounded-lg h-full">
<div className="px-4 py-5 sm:p-6">
<h2 className="text-lg leading-6 font-medium text-gray-900 flex justify-center">
What is the LocalShops database?
</h2>
<p className="text-sm leading-5 font-normal text-gray-500">
All the products sold on LocalShops have to be included in the
database for them to be found when users search. By adding a
product from the database to your shop, you are able to add
the inventory and sell it.
</p>
</div>
</div>
</div>
{/* Table */}
{searchResults.length > 0 && (
<div className="flex flex-col mt-16">
<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">
<div className="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Image
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Name
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Product SKU
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Rating
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Stocked By
</th>
<th scope="col" className="relative px-6 py-3" />
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{searchResults.map(
(default_product: TemplateProductPTO) => (
<tr>
<td className="px-6 py-4 whitespace-nowrap">
<div
className="flex items-center"
onClick={() => handleImageClick()}
>
<div className="flex-shrink-0 h-10 w-10">
{default_product.photos.length > 0 && (
<img
className="h-10 w-10 rounded-sm"
src={default_product.photos[0].image}
alt=""
/>
)}
</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center">
<div>
<div className="text-sm font-medium text-gray-900">
{default_product.name}
</div>
<div className="text-sm text-gray-500 truncate max-w-xs">
{default_product.desc}
</div>
</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center">
<div>
<div className="text-sm font-medium text-gray-900">
{default_product.sku}
</div>
</div>
</div>
</td>
{/*<td className="px-6 py-4 whitespace-nowrap">*/}
{/* <span className="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">*/}
{/* Active*/}
{/* </span>*/}
{/*</td>*/}
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center">
<div>
<div className="text-sm font-medium text-gray-900">
{default_product.rating}
</div>
</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center">
<div>
<div className="text-sm font-medium text-gray-900">
{`${
default_product.products.length
} shop${
default_product.products.length > 1
? "s"
: ""
}`}
</div>
</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<Link
to={{
pathname: "/addproduct/2",
}}
onClick={() =>
dispatch(
updateTemplateProduct(default_product)
)
}
className="font-medium text-indigo-600 hover:text-indigo-500"
>
Choose
</Link>
</td>
</tr>
)
)}
</tbody>
</table>
</div>
</div>
</div>
</div>
)}
<ProductModal openModal={modalOpened} />
</div>
</div>
</div>
);
};
/* This example requires Tailwind CSS v2.0+ */
import { Fragment, useEffect, useState } from "react";
import { Dialog, Transition } from "@headlessui/react";
import { CheckIcon } from "@heroicons/react/outline";
interface modalProps {
openModal: boolean;
}
const ProductModal: React.FC<modalProps> = ({ openModal }) => {
const [open, setOpen] = useState(false);
useEffect(() => {
setOpen(openModal);
}, [openModal]);
return (
<Transition.Root show={open} as={Fragment}>
<Dialog
as="div"
static
className="fixed z-10 inset-0 overflow-y-auto"
open={open}
onClose={() => setOpen(false)}
>
<div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Dialog.Overlay className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
</Transition.Child>
{/* This element is to trick the browser into centering the modal contents. */}
<span
className="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true"
>
​
</span>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<div className="inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-sm sm:w-full sm:p-6">
<div>
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100">
<CheckIcon
className="h-6 w-6 text-green-600"
aria-hidden="true"
/>
</div>
<div className="mt-3 text-center sm:mt-5">
<Dialog.Title
as="h3"
className="text-lg leading-6 font-medium text-gray-900"
>
Payment successful
</Dialog.Title>
<div className="mt-2">
<p className="text-sm text-gray-500">
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Consequatur amet labore.
</p>
</div>
</div>
</div>
<div className="mt-5 sm:mt-6">
<button
type="button"
className="inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 bg-indigo-600 text-base font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:text-sm"
onClick={() => setOpen(false)}
>
Go back to dashboard
</button>
</div>
</div>
</Transition.Child>
</div>
</Dialog>
</Transition.Root>
);
};
export default ProductModal;