aboutsummaryrefslogtreecommitdiff
path: root/client/src/components/Editor
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/components/Editor')
-rw-r--r--client/src/components/Editor/Editor.jsx65
-rw-r--r--client/src/components/Editor/Editor.module.css64
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;
+ }
}