docs: added Feedback component (#2274)
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
sidebar_position: 4
|
sidebar_position: 4
|
||||||
---
|
---
|
||||||
|
|
||||||
|
import UiIcon from '@site/src/components/UiIcon';
|
||||||
|
|
||||||
# Manage Shipping Options
|
# Manage Shipping Options
|
||||||
|
|
||||||
In this document, you’ll learn how to manage a region’s shipping options in your Medusa Admin.
|
In this document, you’ll learn how to manage a region’s shipping options in your Medusa Admin.
|
||||||
|
|||||||
Binary file not shown.
@@ -30,6 +30,7 @@
|
|||||||
"prism-react-renderer": "^1.3.1",
|
"prism-react-renderer": "^1.3.1",
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
|
"react-transition-group": "^4.4.5",
|
||||||
"redocusaurus": "^1.3.0",
|
"redocusaurus": "^1.3.0",
|
||||||
"url-loader": "^4.1.1"
|
"url-loader": "^4.1.1"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
.inline-feedback {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline-question,
|
||||||
|
.feedback-message {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline-feedback span,
|
||||||
|
.inline-question span {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline-feedback span {
|
||||||
|
margin-right: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline-question span {
|
||||||
|
margin-bottom: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feedback-btn {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 600;
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid #E5E7EB;
|
||||||
|
color: var(--ifm-font-color-base);
|
||||||
|
}
|
||||||
|
|
||||||
|
.feedback-btn:focus {
|
||||||
|
box-shadow: 0px 0px 0px 4px rgba(124, 58, 237, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
html:not([data-theme="dark"]) .feedback-btn:hover {
|
||||||
|
background: #F3F4F6;
|
||||||
|
}
|
||||||
|
|
||||||
|
html:not([data-theme="dark"]) .feedback-btn:active,
|
||||||
|
html:not([data-theme="dark"]) .feedback-btn:disabled {
|
||||||
|
background: #E5E7EB;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .feedback-btn,
|
||||||
|
[data-theme="dark"] .inline-question textarea {
|
||||||
|
border-color: rgba(255, 255, 255, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.feedback-btn:not(:last-child) {
|
||||||
|
margin-right: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline-question .feedback-btn {
|
||||||
|
margin-top: 13px;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline-question textarea {
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid #E5E7EB;
|
||||||
|
padding: 8px;
|
||||||
|
font-family: var(--ifm-font-family-base);
|
||||||
|
}
|
||||||
|
|
||||||
|
.feedback-message {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-in {
|
||||||
|
-webkit-animation: fade-in .3s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
|
||||||
|
animation: fade-in .3s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fade-in {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fade-in {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-out {
|
||||||
|
-webkit-animation: fade-out .3s ease-out both;
|
||||||
|
animation: fade-out .3s ease-out both;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fade-out {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fade-out {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
import { CSSTransition, SwitchTransition } from 'react-transition-group';
|
||||||
|
import './index.css';
|
||||||
|
|
||||||
|
import useIsBrowser from '@docusaurus/useIsBrowser';
|
||||||
|
import {useLocation} from '@docusaurus/router';
|
||||||
|
|
||||||
|
export default function Feedback () {
|
||||||
|
const [showForm, setShowForm] = useState(false);
|
||||||
|
const [submittedFeedback, setSubmittedFeedback] = useState(false);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const inlineFeedbackRef = useRef(null);
|
||||||
|
const inlineQuestionRef = useRef(null);
|
||||||
|
const inlineMessageRef = useRef(null)
|
||||||
|
const [positiveFeedback, setPositiveFeedbac] = useState(false);
|
||||||
|
const [message, setMessage] = useState("");
|
||||||
|
const nodeRef = submittedFeedback ? inlineMessageRef : (showForm ? inlineQuestionRef : inlineFeedbackRef);
|
||||||
|
|
||||||
|
const isBrowser = useIsBrowser();
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
|
function handleFeedback (e) {
|
||||||
|
setPositiveFeedbac(e.target.classList.contains('positive'));
|
||||||
|
setShowForm(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitFeedback (e) {
|
||||||
|
if (isBrowser) {
|
||||||
|
if (window.analytics) {
|
||||||
|
setLoading(true);
|
||||||
|
window.analytics.track('survey', {
|
||||||
|
url: location.pathname,
|
||||||
|
label: document.title,
|
||||||
|
feedback: positiveFeedback ? 'yes' : 'no',
|
||||||
|
message
|
||||||
|
}, function () {
|
||||||
|
setLoading(false);
|
||||||
|
setShowForm(false);
|
||||||
|
setSubmittedFeedback(true);
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setShowForm(false);
|
||||||
|
setSubmittedFeedback(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='feedback-container'>
|
||||||
|
<SwitchTransition mode="out-in">
|
||||||
|
<CSSTransition
|
||||||
|
key={showForm}
|
||||||
|
nodeRef={nodeRef}
|
||||||
|
timeout={300}
|
||||||
|
addEndListener={(done) => {
|
||||||
|
nodeRef.current.addEventListener("transitionend", done, false);
|
||||||
|
}}
|
||||||
|
classNames={{
|
||||||
|
enter: 'fade-in',
|
||||||
|
exit: 'fade-out'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
{(!showForm && !submittedFeedback) && (
|
||||||
|
<div className='inline-feedback' ref={inlineFeedbackRef}>
|
||||||
|
<span>Was this page helpful?</span>
|
||||||
|
<button className='positive feedback-btn' onClick={handleFeedback}>Yes</button>
|
||||||
|
<button className='negative feedback-btn' onClick={handleFeedback}>No</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{(showForm && !submittedFeedback) && (
|
||||||
|
<div className='inline-question' ref={inlineQuestionRef}>
|
||||||
|
<span>{positiveFeedback ? 'What was most helpful?' : 'What can we improve?'}</span>
|
||||||
|
<textarea rows={4} value={message} onChange={(e) => setMessage(e.target.value)}></textarea>
|
||||||
|
<button className='feedback-btn' onClick={submitFeedback} disabled={loading}>Submit</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{submittedFeedback && (
|
||||||
|
<div className='feedback-message' ref={inlineMessageRef}>
|
||||||
|
Thank you for helping improve our documentation!
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</CSSTransition>
|
||||||
|
</SwitchTransition>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import React, { useEffect } from "react"
|
|
||||||
|
|
||||||
import RootLayout from "@theme/Layout"
|
|
||||||
|
|
||||||
const Layout = ({ children, ...props }) => {
|
|
||||||
return (
|
|
||||||
<RootLayout {...props}>
|
|
||||||
<div className="container">{children}</div>
|
|
||||||
</RootLayout>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Layout
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { default as Layout } from "./Layout"
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import React from "react"
|
|
||||||
import styles from "./tab.module.css"
|
|
||||||
|
|
||||||
const TabItem = ({ title, isOverviewCard, items }) => {
|
|
||||||
const overviewModeList = () =>
|
|
||||||
items.map((item) => <p className="margin-bottom--xs">{item.title}</p>)
|
|
||||||
return (
|
|
||||||
<div className="col col--4 padding-right--md padding-bottom--md">
|
|
||||||
<div className={styles.card}>
|
|
||||||
<div className={styles.cardContent}>
|
|
||||||
<h3>{title}</h3>
|
|
||||||
<div>{isOverviewCard && overviewModeList()}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TabItem
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { default as TabItem } from "./TabItem"
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
.card {
|
|
||||||
background-color: var(--ifm-medusa-gray);
|
|
||||||
min-height: 257px;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 20px 13px;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cardContent {
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cardContent p {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
import clsx from "clsx"
|
|
||||||
import React, { useState } from "react"
|
|
||||||
import { TabItem } from "./TabItem/"
|
|
||||||
|
|
||||||
const BUTTONS_DATA = [
|
|
||||||
{ buttonTitle: "Overview", value: "overview" },
|
|
||||||
{ buttonTitle: "Tutorial", value: "tutorial" },
|
|
||||||
{ buttonTitle: "Guides", value: "guide" },
|
|
||||||
{ buttonTitle: "Reference", value: "reference" },
|
|
||||||
]
|
|
||||||
|
|
||||||
const OVERVIEW_DATA = ["Tutorial", "Guides", "Reference"]
|
|
||||||
|
|
||||||
const TabsPanel = ({ items }) => {
|
|
||||||
const [sort, setSort] = useState("overview")
|
|
||||||
|
|
||||||
const buttons = BUTTONS_DATA.map((item) => (
|
|
||||||
// <button
|
|
||||||
// className={clsx(
|
|
||||||
// { [styles.buttonActive]: sort === item.value },
|
|
||||||
// styles.button
|
|
||||||
// )}
|
|
||||||
// onClick={() => setSort(item.value)}
|
|
||||||
// >
|
|
||||||
// {item.buttonTitle}
|
|
||||||
// </button>
|
|
||||||
<li
|
|
||||||
className={clsx("tabs__item", {
|
|
||||||
"tabs__item--active": sort === item.value,
|
|
||||||
})}
|
|
||||||
onClick={() => setSort(item.value)}
|
|
||||||
>
|
|
||||||
{item.buttonTitle}
|
|
||||||
</li>
|
|
||||||
))
|
|
||||||
|
|
||||||
const getOverviewCardItemsSet = (currentCard) =>
|
|
||||||
items.filter((item) => item.key === currentCard.toLowerCase())
|
|
||||||
|
|
||||||
const overviewCardsSet = () =>
|
|
||||||
OVERVIEW_DATA.map((item) => (
|
|
||||||
<TabItem
|
|
||||||
isOverviewCard
|
|
||||||
title={item}
|
|
||||||
items={getOverviewCardItemsSet(item)}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
|
|
||||||
const getSortedArray = () => {
|
|
||||||
return items.filter((entry) => entry.type === sort)
|
|
||||||
}
|
|
||||||
|
|
||||||
const renderTabItems = () => {
|
|
||||||
if (sort === "overview") return overviewCardsSet()
|
|
||||||
return getSortedArray().length > 0 ? (
|
|
||||||
getSortedArray().map((item) => {
|
|
||||||
return <TabItem title={item.title} />
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<p>hold tight! we are building these things</p>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="padding-bottom--xl">
|
|
||||||
{/* <Box sx={{ borderBottom: "1px solid black", marginBottom: "50px" }}>
|
|
||||||
{buttons}
|
|
||||||
</Box> */}
|
|
||||||
<ul class="tabs margin-bottom--lg">{buttons}</ul>
|
|
||||||
<div className="container padding--none">
|
|
||||||
<div className="row row--no-gutters">{renderTabItems()}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TabsPanel
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { default as TabsPanel } from "./TabsPanel"
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
.button {
|
|
||||||
background-color: transparent;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
height: 30px;
|
|
||||||
font-size: 16px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttonActive {
|
|
||||||
color: var(--ifm-color-primary);
|
|
||||||
border-bottom: 3px solid var(--ifm-color-primary) !important;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Footer from '@theme-original/DocItem/Footer';
|
||||||
|
import Feedback from '../../../components/Feedback';
|
||||||
|
|
||||||
|
export default function FooterWrapper(props) {
|
||||||
|
return (
|
||||||
|
<div className='docusaurus-mt-lg'>
|
||||||
|
<Feedback />
|
||||||
|
<Footer {...props} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -2883,6 +2883,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7":
|
||||||
|
version: 7.19.0
|
||||||
|
resolution: "@babel/runtime@npm:7.19.0"
|
||||||
|
dependencies:
|
||||||
|
regenerator-runtime: ^0.13.4
|
||||||
|
checksum: 42d4f11d6a5bfcf5a3d05346e7f1aef79a53b9e1968b4dc54a0682df60284300c97de3be63f4d5dd47b404d3a1022a8a57444b5d150822ec8974757de7233f6e
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@babel/runtime@npm:^7.8.4":
|
"@babel/runtime@npm:^7.8.4":
|
||||||
version: 7.17.8
|
version: 7.17.8
|
||||||
resolution: "@babel/runtime@npm:7.17.8"
|
resolution: "@babel/runtime@npm:7.17.8"
|
||||||
@@ -6427,6 +6436,7 @@ __metadata:
|
|||||||
prism-react-renderer: ^1.3.1
|
prism-react-renderer: ^1.3.1
|
||||||
react: ^17.0.1
|
react: ^17.0.1
|
||||||
react-dom: ^17.0.1
|
react-dom: ^17.0.1
|
||||||
|
react-transition-group: ^4.4.5
|
||||||
redocusaurus: ^1.3.0
|
redocusaurus: ^1.3.0
|
||||||
url-loader: ^4.1.1
|
url-loader: ^4.1.1
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
@@ -6488,6 +6498,16 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"dom-helpers@npm:^5.0.1":
|
||||||
|
version: 5.2.1
|
||||||
|
resolution: "dom-helpers@npm:5.2.1"
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime": ^7.8.7
|
||||||
|
csstype: ^3.0.2
|
||||||
|
checksum: f735074d66dd759b36b158fa26e9d00c9388ee0e8c9b16af941c38f014a37fc80782de83afefd621681b19ac0501034b4f1c4a3bff5caa1b8667f0212b5e124c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"dom-serializer@npm:^1.0.1":
|
"dom-serializer@npm:^1.0.1":
|
||||||
version: 1.3.2
|
version: 1.3.2
|
||||||
resolution: "dom-serializer@npm:1.3.2"
|
resolution: "dom-serializer@npm:1.3.2"
|
||||||
@@ -10858,6 +10878,21 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"react-transition-group@npm:^4.4.5":
|
||||||
|
version: 4.4.5
|
||||||
|
resolution: "react-transition-group@npm:4.4.5"
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime": ^7.5.5
|
||||||
|
dom-helpers: ^5.0.1
|
||||||
|
loose-envify: ^1.4.0
|
||||||
|
prop-types: ^15.6.2
|
||||||
|
peerDependencies:
|
||||||
|
react: ">=16.6.0"
|
||||||
|
react-dom: ">=16.6.0"
|
||||||
|
checksum: 2ba754ba748faefa15f87c96dfa700d5525054a0141de8c75763aae6734af0740e77e11261a1e8f4ffc08fd9ab78510122e05c21c2d79066c38bb6861a886c82
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"react@npm:^17.0.1":
|
"react@npm:^17.0.1":
|
||||||
version: 17.0.2
|
version: 17.0.2
|
||||||
resolution: "react@npm:17.0.2"
|
resolution: "react@npm:17.0.2"
|
||||||
|
|||||||
Reference in New Issue
Block a user