From 7ef0354687bb6abeda97a32ebcb0e39de91691e5 Mon Sep 17 00:00:00 2001 From: rohan09-raj Date: Mon, 19 Feb 2024 20:50:51 +0530 Subject: feat: Implement frontend UI for minibin - Use prism.js for syntax highlighting - USe react-router-dom for routing --- client/src/components/Editor/Editor.jsx | 129 +++++++++++++++++++++++++ client/src/components/Editor/Editor.module.css | 107 ++++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 client/src/components/Editor/Editor.jsx create mode 100644 client/src/components/Editor/Editor.module.css (limited to 'client/src/components/Editor') diff --git a/client/src/components/Editor/Editor.jsx b/client/src/components/Editor/Editor.jsx new file mode 100644 index 0000000..c291872 --- /dev/null +++ b/client/src/components/Editor/Editor.jsx @@ -0,0 +1,129 @@ +import { useState, useEffect, useRef } from "react"; +import { useNavigate, useParams } from "react-router-dom"; +import Prism from "prismjs"; +import styles from "./Editor.module.css"; +import "../prism-themes/prism-gruvbox-dark.css"; +import { SERVER_BASE_URL, SUPPORTED_LANGUAGES } from "../../utils/constants"; + +const Editor = () => { + const navigate = useNavigate(); + const params = useParams(); + const [text, setText] = useState(""); + const [language, setLanguage] = useState("js"); + const textareaRef = useRef(null); + const lineNumberRef = useRef(null); + + const handleTextChange = (event) => { + setText(event.target.value); + }; + + const handleScroll = () => { + if (textareaRef.current && lineNumberRef.current) { + lineNumberRef.current.scrollTop = textareaRef.current.scrollTop; + } + }; + + const handleClick = async () => { + const response = await fetch(`${SERVER_BASE_URL}/bin`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + language, + content: text, + }), + }); + const data = await response.json(); + if (response.ok) { + navigate(`/${data.id}`); + } else { + console.error(data); + } + }; + + const handleLanguageChange = (event) => { + setLanguage(event.target.value); + }; + + useEffect(() => { + Prism.highlightAll(); + }, [text, language]); + + useEffect(() => { + if (params.id) fetchData(); + else { + textareaRef.current.value = ""; + setText(""); + } + }, [params.id]); + + const fetchData = async () => { + const response = await fetch(`${SERVER_BASE_URL}/bin/${params.id}`); + const data = await response.json(); + if (response.ok) { + setLanguage(data.language); + setText(data.content); + } + }; + + const lines = text.split("\n"); + + return ( +
+ {!params.id && ( + <> + + + + )} + +
+
+ {lines.map((_, index) => ( +
+ {index + 1} +
+ ))} +
+
+