diff --git a/docusaurus.config.js b/docusaurus.config.js index 41fac199..d89f2262 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -44,6 +44,14 @@ const config = { title: 'Report an Issue', url : 'https://github.com/rsksmart/devportal/issues', }, + requestArticle : { + title: 'Request an Article', + form : { + id : '5qQ40ScPu', + title : 'Request a New Article', + description : 'Looking for information we haven’t covered? Fill out the form below to request a new article, and we’ll consider it in future updates.', + } + }, } }, // GitHub pages deployment config. diff --git a/src/components/FeedbackForm/index.js b/src/components/FeedbackForm/index.js index 8174d0a4..166b6c10 100644 --- a/src/components/FeedbackForm/index.js +++ b/src/components/FeedbackForm/index.js @@ -1,160 +1,7 @@ -import React, {useState, useEffect} from "react"; +import React, {useState} from "react"; import Translate from '@docusaurus/Translate'; -import Modal from 'react-bootstrap/Modal'; -import {useFormspark} from "@formspark/use-formspark"; -function MyVerticallyCenteredModal(props) { - const [url, setUrl] = useState('#'); - - const [submit, submitting] = useFormspark({ - formId: `vg6LeINWT`, - }); - - const [message, setMessage] = useState(""); - const [email, setEmail] = useState(""); - const [name, setName] = useState(""); - - const [sending, setSending] = useState(false); - const [submitted, setSubmitted] = useState(false); - - const totalStars = 5; - const [rating, setRating] = useState(props.rating || 0); - const [hover, setHover] = useState(null); - - useEffect(() => { - setRating(props.rating); - - if (window) { - setUrl(window.location.origin + window.location.pathname); - } - }, [props.rating, props.show]); - - const onSubmit = async (e) => { - if (submitting) return; - - e.preventDefault(); - setSending(true); - await submit( - {message, email, name, rating, url} - ); - setSubmitted(true); - setSending(false); - setMessage(""); - setEmail(""); - setName(""); - setRating(0); - setTimeout(() => { - setSubmitted(false); - }, 4000) - }; - - return ( - - - - - - - - - Thank you for your feedback! - - We would love to hear your thoughts and feedback so that we can improve these Docs for you and others! - - Current rating - - {[...Array(totalStars)].map((star, index) => { - const currentRating = index + 1; - - return ( - setHover(currentRating)} - onMouseLeave={() => setHover(null)} - > - setRating(currentRating)} - /> - - - - - - ); - })} - - - - - - setName(e.target.value)} - /> - setEmail(e.target.value)} - /> - - setMessage(e.target.value)}/> - - - - - {!submitted ? (`Not now`) : (`Close`)} - - - - - {sending && ( - <> - Submitting - - Loading... - - > - )} - {!sending && !submitted && ( - <> - Submit - - - - > - )} - {!sending && submitted && ( - <> - Submitted - - - - > - )} - - - - - - - - - - ); -} +import { ModalFormSpark } from "/src/components/ModalFormSpark"; export const FeedbackForm = () => { @@ -200,9 +47,10 @@ export const FeedbackForm = () => { })} - setModalShow(false)} /> diff --git a/src/components/ModalFormSpark/Forms/FormFeedback/index.js b/src/components/ModalFormSpark/Forms/FormFeedback/index.js new file mode 100644 index 00000000..fe4fcc72 --- /dev/null +++ b/src/components/ModalFormSpark/Forms/FormFeedback/index.js @@ -0,0 +1,149 @@ +import React, { useEffect, useState } from 'react' +import { useFormspark } from '@formspark/use-formspark' + +export const FormFeedback = (props) => { + const [url, setUrl] = useState('#'); + + const { form } = props; + + const [submit, submitting] = useFormspark({ + formId: form?.id || ``, + }); + + + const [message, setMessage] = useState(""); + const [email, setEmail] = useState(""); + const [name, setName] = useState(""); + + const [sending, setSending] = useState(false); + const [submitted, setSubmitted] = useState(false); + + const totalStars = 5; + const [rating, setRating] = useState(props.rating || 0); + const [hover, setHover] = useState(null); + + useEffect(() => { + if (props.rating) { + setRating(props.rating); + } + + if (window) { + setUrl(window.location.origin + window.location.pathname); + } + }, [props.rating]); + + const onSubmit = async (e) => { + if (submitting) return; + + e.preventDefault(); + setSending(true); + let query = {message, email, name, url} + + query = props?.rating ? {...query, rating} : query; + + await submit(query); + setSubmitted(true); + setSending(false); + setMessage(""); + setEmail(""); + setName(""); + setRating(0); + setTimeout(() => { + setSubmitted(false); + }, 4000) + }; + + return form?.id && ( + <> + {props?.rating && ( + + Current rating + + {[...Array(totalStars)].map((star, index) => { + const currentRating = index + 1; + + return ( + setHover(currentRating)} + onMouseLeave={() => setHover(null)} + > + setRating(currentRating)} + /> + + + + + + ); + })} + + + )} + + + + {props?.rating && ( + + )} + setName(e.target.value)} + /> + setEmail(e.target.value)} + /> + + setMessage(e.target.value)}/> + + + + + {!submitted ? (`Not now`) : (`Close`)} + + + + + {sending && ( + <> + Submitting + + Loading... + + > + )} + {!sending && !submitted && ( + <> + Submit + + + + > + )} + {!sending && submitted && ( + <> + Submitted + + + + > + )} + + + + + + > + ); +} diff --git a/src/components/ModalFormSpark/Forms/FormRequestArticle/index.js b/src/components/ModalFormSpark/Forms/FormRequestArticle/index.js new file mode 100644 index 00000000..55c27c60 --- /dev/null +++ b/src/components/ModalFormSpark/Forms/FormRequestArticle/index.js @@ -0,0 +1,131 @@ +import React, { useEffect, useState } from 'react' +import { useFormspark } from '@formspark/use-formspark' + +export const FormRequestArticle = (props) => { + const { form } = props + + const [submit, submitting] = useFormspark({ + formId: form?.id || ``, + }) + + const requestTypes = ['Tutorial', 'Guide', 'Video', 'Image'] + + const initFormData = { + requestType: requestTypes[0], + title: '', + publicationLocation: '', + why: '', + otherInformation: '', + } + + const [formData, setFormData] = useState(initFormData) + + const handleInputChange = (e) => { + const { name, value } = e.target + setFormData((prevFormData) => ({ + ...prevFormData, + [name]: value, + })) + } + + const [sending, setSending] = useState(false) + const [submitted, setSubmitted] = useState(false) + + useEffect(() => { + if (window) { + const url = window.location.origin + window.location.pathname; + + setFormData((prevFormData) => ({ + ...prevFormData, + url: url, + })) + } + }, []) + + const onSubmit = async (e) => { + if (submitting) return + + e.preventDefault() + setSending(true) + + await submit(formData) + setSubmitted(true); + setSending(false); + setFormData(initFormData); + + setTimeout(() => { + setSubmitted(false) + }, 4000) + } + + return form?.id && ( + + + {requestTypes.length > 0 && ( + + {requestTypes.map((value, index) => ( + + + {value} + + ))} + + )} + + + + + + Are you a technical contributor? + Submit a Pull Request or an Issue + + + + + + {!submitted ? (`Not now`) : (`Close`)} + + + + + {sending && ( + <> + Submitting + + Loading... + + > + )} + {!sending && !submitted && ( + <> + Submit + + + + > + )} + {!sending && submitted && ( + <> + Submitted + + + + > + )} + + + + + ) +} diff --git a/src/components/ModalFormSpark/index.js b/src/components/ModalFormSpark/index.js new file mode 100644 index 00000000..8502300f --- /dev/null +++ b/src/components/ModalFormSpark/index.js @@ -0,0 +1,38 @@ +import React from 'react' +import Modal from 'react-bootstrap/Modal' +import { FormFeedback } from './Forms/FormFeedback' +import { FormRequestArticle } from './Forms/FormRequestArticle' + +export const ModalFormSpark = (props) => { + + const { form } = props; + + return form?.id && ( + + + + + + + + {form?.title && ( + + {form.title} + + )} + {form.description && ( + {form.description} + )} + + {(form?.type === 'feedback') && } + {(form?.type === 'request-article') && } + + + + ); +} diff --git a/src/components/RequestArticle/index.js b/src/components/RequestArticle/index.js new file mode 100644 index 00000000..0433e1c4 --- /dev/null +++ b/src/components/RequestArticle/index.js @@ -0,0 +1,32 @@ +import React, {useState} from "react"; +import Translate from '@docusaurus/Translate'; + +import { ModalFormSpark } from "/src/components/ModalFormSpark"; +import IconArticle from "@theme/Icon/Article"; + +export const RequestArticle = ({label, form}) => { + + const [modalShow, setModalShow] = useState(false); + + return label && form?.id && ( + <> + setModalShow(true)} + type="button" + > + + + {label} + + + + setModalShow(false)} + /> + > + ) +} diff --git a/src/scss/abstracts/_variables.scss b/src/scss/abstracts/_variables.scss index f8d3b825..4055eaae 100644 --- a/src/scss/abstracts/_variables.scss +++ b/src/scss/abstracts/_variables.scss @@ -562,3 +562,7 @@ $form-select-font-size-lg: $input-font-size-lg; $form-select-border-radius-lg: $input-border-radius-lg; $form-select-transition: $input-transition; + +$form-check-input-checked-bg-color: #{'var(--bs-body-bg)'}; +$form-check-input-checked-border-color: #{'var(--bs-body-color)'}; +$form-check-input-focus-box-shadow: 0 0 0 0.20rem rgba(var(--bs-body-color-rgb), 0.15) diff --git a/src/scss/base/_forms.scss b/src/scss/base/_forms.scss index 9c141d3a..765ab73e 100644 --- a/src/scss/base/_forms.scss +++ b/src/scss/base/_forms.scss @@ -64,3 +64,9 @@ label { --bs-form-select-bg-img: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M16.59 8.295L12 12.875L7.41 8.295L6 9.705L12 15.705L18 9.705L16.59 8.295Z' fill='white'/%3E%3C/svg%3E%0A"); } } +.form-check-input:checked[type=radio]{ + --bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23000'/%3e%3c/svg%3e"); + [data-theme='dark']:root & { + --bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e"); + } +} diff --git a/src/theme/DocItem/MoreActions/index.js b/src/theme/DocItem/MoreActions/index.js index 6a54e6a7..796e8090 100644 --- a/src/theme/DocItem/MoreActions/index.js +++ b/src/theme/DocItem/MoreActions/index.js @@ -13,6 +13,7 @@ import IconCommunity from "@theme/Icon/Community"; import IconChangelog from "@theme/Icon/Changelog"; import Link from '@docusaurus/Link'; +import { RequestArticle } from '../../../components/RequestArticle' export default function MoreActions({editUrl}) { @@ -74,6 +75,11 @@ export default function MoreActions({editUrl}) { )} + {links?.requestArticle && links.requestArticle?.form?.id && ( + + + + )} } diff --git a/src/theme/Icon/Article/index.js b/src/theme/Icon/Article/index.js new file mode 100644 index 00000000..0ae32a08 --- /dev/null +++ b/src/theme/Icon/Article/index.js @@ -0,0 +1,15 @@ +import React from 'react'; +import clsx from 'clsx'; + +export default function IconArticle ({ className, ...restProps }) { + return ( + + + + + ) +}
We would love to hear your thoughts and feedback so that we can improve these Docs for you and others!
Are you a technical contributor?
Submit a Pull Request or an Issue
{form.description}