From b0bcf6767b077491d8bcb5355ac127b04f38ebfa Mon Sep 17 00:00:00 2001 From: Sakib Ahmed Date: Sun, 4 Aug 2024 00:00:33 +0600 Subject: [PATCH 1/3] devarea page added with two tools, issue (#247) --- package.json | 1 + src/components/DevAreaTools/JSONFormatter.jsx | 72 ++++++++++++ .../DevAreaTools/MarkDownEditor.jsx | 104 ++++++++++++++++++ src/components/Header/Header.jsx | 5 + src/components/Search/SearchInput.jsx | 22 ++-- src/main.jsx | 12 ++ src/pages/DevArea/DevTools.jsx | 18 +++ src/pages/DevArea/index.jsx | 73 ++++++++++++ yarn.lock | 7 ++ 9 files changed, 303 insertions(+), 11 deletions(-) create mode 100644 src/components/DevAreaTools/JSONFormatter.jsx create mode 100644 src/components/DevAreaTools/MarkDownEditor.jsx create mode 100644 src/pages/DevArea/DevTools.jsx create mode 100644 src/pages/DevArea/index.jsx diff --git a/package.json b/package.json index 4567c49..02f2c2e 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "react-dom": "^18.2.0", "react-hot-toast": "^2.4.0", "react-icons": "^4.7.1", + "react-json-pretty": "^2.2.0", "react-markdown": "^9.0.1", "react-modal": "^3.16.1", "react-router-dom": "^6.25.1", diff --git a/src/components/DevAreaTools/JSONFormatter.jsx b/src/components/DevAreaTools/JSONFormatter.jsx new file mode 100644 index 0000000..5e21031 --- /dev/null +++ b/src/components/DevAreaTools/JSONFormatter.jsx @@ -0,0 +1,72 @@ +import React, { useState } from 'react'; +import { Input, Button, Alert } from 'antd'; +import JSONPretty from 'react-json-pretty'; // You might need to install this library for pretty JSON output +import 'react-json-pretty/themes/monikai.css'; // Optional: import a theme for JSONPretty +import { toast } from 'sonner'; + +const JSONFormatter = () => { + const [jsonInput, setJsonInput] = useState(''); + const [formattedJson, setFormattedJson] = useState(null); + const [error, setError] = useState(''); + + const handleFormat = () => { + try { + const parsedJson = JSON.parse(jsonInput); + setFormattedJson(parsedJson); + setError(''); + } catch (err) { + setError('Invalid JSON format'); + setFormattedJson(null); + } + }; + + const handleClear = () => { + setJsonInput(''); + setFormattedJson(null); + setError(''); + }; + + const handleCopy = () => { + if (formattedJson) { + navigator.clipboard.writeText(JSON.stringify(formattedJson, null, 2)) + .then(() => { + toast.success('JSON copied to clipboard'); + }) + .catch(err => alert('Failed to copy JSON: ' + err)); + } else { + alert('Nothing to copy'); + } + }; + + return ( +
+

JSON Formatter

+ setJsonInput(e.target.value)} + placeholder="Paste your JSON here" + autoSize={{ minRows: 10 }} + className='mb-4 dark:bg-dark dark:text-white' + /> +
+ + + +
+ {error && } + {formattedJson && ( +
+ navigator.clipboard.writeText(JSON.stringify(data, null, 2))} /> +
+ )} +
+ ); +}; + +export default JSONFormatter; diff --git a/src/components/DevAreaTools/MarkDownEditor.jsx b/src/components/DevAreaTools/MarkDownEditor.jsx new file mode 100644 index 0000000..454fd99 --- /dev/null +++ b/src/components/DevAreaTools/MarkDownEditor.jsx @@ -0,0 +1,104 @@ +import React, { useState } from 'react'; +import ReactMarkdown from 'react-markdown'; +import remarkGfm from 'remark-gfm'; +import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; +import { a11yDark } from 'react-syntax-highlighter/dist/esm/styles/prism'; +import { Input, Button } from 'antd'; +import Layout from '../Layout/Layout'; + +const MarkDownEditor = () => { + const [content, setContent] = useState(""); + + const handleDownload = () => { + const blob = new Blob([content], { type: 'text/markdown;charset=utf-8' }); + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.download = 'document.md'; + link.click(); + URL.revokeObjectURL(url); + }; + + return ( +
+
+ setContent(e.target.value)} + placeholder="Enter markdown here" + autoSize={{ minRows: 20 }} + className='min-h-screen dark:bg-black text-sm md:text-base dark:text-white p-4 !outline-none placeholder:font-semibold' + /> + +
+ +
+ + {String(children).replace(/\n$/, '')} + + ) : ( + + {children} + + ); + }, + blockquote({ node, children }) { + return
{children}
; + }, + li({ node, children }) { + return
  • {children}
  • ; + }, + ul({ node, children }) { + return
      {children}
    ; + }, + ol({ node, children }) { + return
      {children}
    ; + }, + img({ node, src, alt }) { + return {alt}; + }, + h1({ node, children }) { + return

    {children}

    ; + }, + h2({ node, children }) { + return

    {children}

    ; + }, + h3({ node, children }) { + return

    {children}

    ; + }, + h4({ node, children }) { + return

    {children}

    ; + }, + h5({ node, children }) { + return
    {children}
    ; + }, + h6({ node, children }) { + return
    {children}
    ; + } + }} + > + {content} +
    +
    +
    + ); +}; + +export default MarkDownEditor; diff --git a/src/components/Header/Header.jsx b/src/components/Header/Header.jsx index 1b4b4b0..25a371c 100644 --- a/src/components/Header/Header.jsx +++ b/src/components/Header/Header.jsx @@ -36,6 +36,11 @@ function Header({notice }) { link: "/doc", icon: , }, + { + name: "DevArea", + link: "/devarea", + icon: , + }, { name: "Resources", link: "/resources", diff --git a/src/components/Search/SearchInput.jsx b/src/components/Search/SearchInput.jsx index 03171e1..0c3e6aa 100644 --- a/src/components/Search/SearchInput.jsx +++ b/src/components/Search/SearchInput.jsx @@ -48,17 +48,17 @@ function SearchInput({ search, setSearch, setType }) { className="flex items-center border border-primary gap-4 py-2 px-6 rounded-lg w-11/12 md:w-4/6" > - { - setSearch(e.target.value); - setType(""); - }} -/> + { + setSearch(e.target.value); + setType(""); + }} + /> - - - {error && } + {error && } {formattedJson && ( -
    +
    navigator.clipboard.writeText(JSON.stringify(data, null, 2))} />
    )} diff --git a/src/components/Search/SearchInput.jsx b/src/components/Search/SearchInput.jsx index 0c3e6aa..64f105a 100644 --- a/src/components/Search/SearchInput.jsx +++ b/src/components/Search/SearchInput.jsx @@ -60,6 +60,8 @@ function SearchInput({ search, setSearch, setType }) { }} /> + +