forked from M-Labs/web2019
99 lines
3.5 KiB
JavaScript
99 lines
3.5 KiB
JavaScript
import React, {useState} from "react";
|
|
import {Modal} from "react-bootstrap";
|
|
import {useShopStore} from "./shop_store";
|
|
import {useClickAway} from "./options/useClickAway";
|
|
|
|
// #!render_count
|
|
import {useRenderCount} from "@uidotdev/usehooks";
|
|
import {Validation} from "./validate";
|
|
|
|
|
|
const copyButtonStates = {
|
|
[Validation.OK]: {
|
|
style: "btn-outline-success",
|
|
content: "✓ copied"
|
|
},
|
|
[Validation.Empty]: {
|
|
style: "btn-outline-primary",
|
|
content: "Copy"
|
|
},
|
|
[Validation.Invalid]: {
|
|
style: "btn-outline-danger",
|
|
content: "Error"
|
|
},
|
|
};
|
|
|
|
|
|
export function ShowJSON() {
|
|
// #!render_count
|
|
const renderCount = useRenderCount();
|
|
|
|
const shouldShow = useShopStore((state) => state.shouldShowDescription);
|
|
const description = useShopStore((state) => state.description);
|
|
const closeDescription = useShopStore((state) => state.closeDescription);
|
|
const showDescription = useShopStore((state) => state.showDescription);
|
|
|
|
const [copiedState, setCopiedState] = useState(Validation.Empty);
|
|
|
|
// #!render_count
|
|
console.log("ShowJSON renders: ", renderCount)
|
|
|
|
const ref = useClickAway((e) => {
|
|
if (e.type === "mousedown") // ignore touchstart
|
|
closeDescription()
|
|
}
|
|
);
|
|
|
|
const copyToClipboard = (text) => {
|
|
try {
|
|
navigator.clipboard.writeText(text)
|
|
.then((_value) => { // success
|
|
setCopiedState(Validation.OK);
|
|
setTimeout(() => {setCopiedState(Validation.Empty)}, 1500);
|
|
}, (reason) => { // error
|
|
setCopiedState(Validation.Invalid);
|
|
setTimeout(() => {setCopiedState(Validation.Empty)}, 3000);
|
|
console.warn("Copy to clipboard rejected: ", reason)
|
|
});
|
|
} catch (e) {
|
|
setCopiedState(Validation.Invalid);
|
|
setTimeout(() => {setCopiedState(Validation.Empty)}, 3000);
|
|
console.warn("Copy to clipboard error: ", e)
|
|
}
|
|
};
|
|
|
|
return (<>
|
|
<input
|
|
className="btn btn-outline-primary w-100 m-0 mb-2 mb-sm-0 me-sm-2"
|
|
style={{'cursor': 'pointer', 'fontWeight': '700'}}
|
|
defaultValue="Show JSON"
|
|
onClick={showDescription}
|
|
readOnly={true}/>
|
|
<Modal show={shouldShow} animation={true} className="rfqFeedback" centered>
|
|
<Modal.Body ref={ref}>
|
|
<textarea
|
|
value={description}
|
|
className="form-control w-100"
|
|
rows={10}
|
|
readOnly={true}
|
|
placeholder="There should be description of the crate"/>
|
|
|
|
<div className="d-flex flex-column flex-sm-row justify-content-end">
|
|
{window.isSecureContext && (
|
|
<a type="button"
|
|
onClick={() => {
|
|
copyToClipboard(description)
|
|
}}
|
|
className={"btn btn-sm m-0 mb-1 mt-2 mb-sm-0 me-sm-2 " + copyButtonStates[copiedState].style}
|
|
>
|
|
{copyButtonStates[copiedState].content}
|
|
</a>
|
|
)}
|
|
|
|
<a type="button" onClick={closeDescription}
|
|
className="btn btn-sm btn-outline-primary m-0 mb-1 mt-2 mb-sm-0 me-sm-2">Close</a>
|
|
</div>
|
|
</Modal.Body>
|
|
</Modal>
|
|
</>)
|
|
} |