diff options
Diffstat (limited to 'client/src/components/Editor')
-rw-r--r-- | client/src/components/Editor/Editor.jsx | 65 | ||||
-rw-r--r-- | client/src/components/Editor/Editor.module.css | 64 |
2 files changed, 126 insertions, 3 deletions
diff --git a/client/src/components/Editor/Editor.jsx b/client/src/components/Editor/Editor.jsx index dac633c..976c1b2 100644 --- a/client/src/components/Editor/Editor.jsx +++ b/client/src/components/Editor/Editor.jsx @@ -5,13 +5,13 @@ import React, { useCallback, useMemo, } from "react"; +import { Link } from "react-router-dom"; import { useLocation, useNavigate, useParams } from "react-router-dom"; import Prism from "prismjs"; import styles from "./Editor.module.css"; import "../prism-themes/prism-gruvbox-dark.css"; import "../prism-themes/prism-line-numbers.css"; import { URL_REGEX } from "../../utils/constants"; -import Header from "../Header/Header"; import { generateAESKey, keyToString, @@ -20,6 +20,9 @@ import { decryptAES, } from "../../utils/encryption"; import Modal from "../Modal/Modal"; +import AlertToast from "../AlertToast/AlertToast"; +import CustomSelect from "../CustomSelect/CustomSelect"; +import KeyboardModal from "../KeyboardModal/KeyboardModal"; const Editor = () => { const { id } = useParams(); @@ -28,6 +31,8 @@ const Editor = () => { const [text, setText] = useState(""); const [language, setLanguage] = useState("none"); const [openModal, setOpenModal] = useState(false); + const [openKeyboardModal, setOpenKeyboardModal] = useState(false); + const [openAlertToast, setOpenAlertToast] = useState(false); const textareaRef = useRef(null); const lineNumberRef = useRef(null); const queryParams = useMemo( @@ -48,7 +53,7 @@ const Editor = () => { const handleSaveClick = useCallback(async () => { if (!text) { - alert("Please enter some text!"); + setOpenAlertToast(true); return; } if (URL_REGEX.test(text)) { @@ -189,14 +194,67 @@ const Editor = () => { }); }, []); + useEffect(() => { + const handleKeyDown = (event) => { + if (!id && event.ctrlKey && event.key.toLowerCase() === "s") { + event.preventDefault(); + handleSaveClick(); + } + }; + + document.addEventListener("keydown", handleKeyDown); + + return () => { + document.removeEventListener("keydown", handleKeyDown); + }; + }, [handleSaveClick]); + return ( <> - <Header isSelectVisible={!id} onLanguageChange={handleLanguageChange} /> + {!id && ( + <> + <KeyboardModal + textAreaRef={textareaRef} + isOpen={openKeyboardModal} + setIsOpen={setOpenKeyboardModal} + isModalOpen={openModal} + /> + <AlertToast + openAlertToast={openAlertToast} + setOpenAlertToast={setOpenAlertToast} + /> + </> + )} + <div className={styles.header}> + <Link to="/"> + <h1> + <span className={styles.header__mini}>mini</span>bin + </h1> + </Link> + {!id && ( + <div className={styles.header__right}> + <CustomSelect + onSelect={handleLanguageChange} + textAreaRef={textareaRef} + isModalOpen={openModal} + /> + <button className={styles.btn__help}> + <img + src="assets/icons/question.png" + className={styles.btn__help__icon} + alt="Help" + onClick={() => setOpenKeyboardModal(true)} + /> + </button> + </div> + )} + </div> <Modal openModal={openModal} setOpenModal={setOpenModal} onSuccessClick={handleSuccessClick} onCancelClick={handleCancelClick} + textAreaRef={textareaRef} /> <div className={styles.container}> {!id && ( @@ -220,6 +278,7 @@ const Editor = () => { ref={textareaRef} placeholder="</> Paste, save, share! (Pasting just a URL will shorten it!)" value={text} + disabled={openModal} /> <pre className="line-numbers" ref={lineNumberRef}> <code diff --git a/client/src/components/Editor/Editor.module.css b/client/src/components/Editor/Editor.module.css index 62c6759..761e3ed 100644 --- a/client/src/components/Editor/Editor.module.css +++ b/client/src/components/Editor/Editor.module.css @@ -61,6 +61,25 @@ } } +.btn__help { + height: 2.75rem; + width: 2.75rem; + background-color: var(--color-yellow); + border: none; + border-radius: 50%; + cursor: pointer; + transition: 0.3s; + z-index: 1; + &:hover { + transform: scale(1.1); + } +} + +.btn__help__icon { + height: 1.75rem; + width: 1.75rem; +} + .btn__icon { height: 3rem; width: 3rem; @@ -68,6 +87,47 @@ contrast(88%); } +.header { + display: flex; + justify-content: space-between; + align-items: center; + margin: 0.5rem 2rem; + color: var(--color-light); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.header__right { + display: flex; + align-items: center; + gap: 1rem; +} + +.header h1 { + margin: 0; +} + +.header a { + text-decoration: none; + color: inherit; +} + +.header__mini { + color: var(--color-yellow); +} + +@media screen and (max-width: 480px) { + .header { + margin: 0.5rem 1rem; + } + + .header h1 { + font-size: 2rem; + } +} + @media screen and (max-width: 768px) { .btn__save { bottom: 2rem; @@ -80,4 +140,8 @@ height: 2rem; width: 2rem; } + + .btn__help { + display: none; + } } |