2023-09-19 20:52:02 +08:00
|
|
|
import React, { useEffect, useState, useCallback } from "react";
|
2023-09-19 20:51:49 +08:00
|
|
|
import logo_light from "../assets/logo_light_46.png";
|
|
|
|
import logo_dark from "../assets/logo_dark_46.png";
|
2023-09-23 01:09:02 +08:00
|
|
|
import { Banner, Button, Input, Upload, Toast } from "@douyinfe/semi-ui";
|
2023-09-19 20:51:49 +08:00
|
|
|
import {
|
|
|
|
IconSun,
|
|
|
|
IconMoon,
|
|
|
|
IconGithubLogo,
|
|
|
|
IconPaperclip,
|
|
|
|
} from "@douyinfe/semi-icons";
|
|
|
|
import RichEditor from "../components/rich_editor";
|
2023-09-19 20:52:02 +08:00
|
|
|
import { LexicalComposer } from "@lexical/react/LexicalComposer";
|
|
|
|
import { editorConfig } from "../data/editor_config";
|
|
|
|
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
|
|
import { $generateHtmlFromNodes } from "@lexical/html";
|
2023-09-23 01:09:02 +08:00
|
|
|
import axios from "axios";
|
2023-09-19 20:52:02 +08:00
|
|
|
|
|
|
|
function Form({ theme }) {
|
|
|
|
const [editor] = useLexicalComposerContext();
|
2023-09-23 01:09:02 +08:00
|
|
|
const [data, setData] = useState({
|
|
|
|
title: "",
|
|
|
|
attachments: [],
|
|
|
|
});
|
|
|
|
|
|
|
|
const onFileChange = (fileList) => {
|
|
|
|
const attachments = [];
|
|
|
|
|
|
|
|
const processFile = (index) => {
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
|
|
|
reader.onload = (event) => {
|
|
|
|
const dataUri = event.target.result;
|
|
|
|
attachments.push({ path: dataUri, filename: fileList[index].name });
|
|
|
|
};
|
|
|
|
|
|
|
|
reader.readAsDataURL(fileList[index].fileInstance);
|
|
|
|
};
|
|
|
|
|
|
|
|
fileList.forEach((_, i) => processFile(i));
|
|
|
|
|
|
|
|
setData((prev) => ({
|
|
|
|
...prev,
|
|
|
|
attachments: attachments,
|
|
|
|
}));
|
|
|
|
};
|
2023-09-19 20:52:02 +08:00
|
|
|
|
|
|
|
const onSubmit = useCallback(
|
|
|
|
(e) => {
|
|
|
|
editor.update(() => {
|
2023-09-23 01:09:02 +08:00
|
|
|
const sendMail = async () => {
|
|
|
|
await axios
|
|
|
|
.post(`${process.env.REACT_APP_BACKEND_URL}/report_bug`, {
|
|
|
|
subject: data.title,
|
|
|
|
message: $generateHtmlFromNodes(editor),
|
|
|
|
attachments: data.attachments,
|
|
|
|
})
|
|
|
|
.then((res) => Toast.success("Bug reported!"))
|
|
|
|
.catch((err) => Toast.error("Oops! Something went wrong."));
|
|
|
|
};
|
|
|
|
sendMail();
|
2023-09-19 20:52:02 +08:00
|
|
|
});
|
|
|
|
},
|
2023-09-23 01:09:02 +08:00
|
|
|
[editor, data]
|
2023-09-19 20:52:02 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className="p-5 mt-6 card-theme rounded-md">
|
2023-09-23 01:09:02 +08:00
|
|
|
<Input
|
|
|
|
placeholder="Title"
|
|
|
|
value={data.title}
|
|
|
|
onChange={(v) => setData((prev) => ({ ...prev, title: v }))}
|
|
|
|
/>
|
2023-09-19 20:52:02 +08:00
|
|
|
<RichEditor theme={theme} />
|
|
|
|
<Upload
|
|
|
|
action="#"
|
2023-09-23 01:09:02 +08:00
|
|
|
onChange={(info) => onFileChange(info.fileList)}
|
|
|
|
beforeUpload={({ file, fileList }) => {
|
|
|
|
return {
|
|
|
|
autoRemove: false,
|
|
|
|
fileInstance: file.fileInstance,
|
|
|
|
status: "success",
|
|
|
|
shouldUpload: false,
|
|
|
|
};
|
|
|
|
}}
|
2023-09-19 20:52:02 +08:00
|
|
|
draggable={true}
|
|
|
|
dragMainText="Click to upload the file or drag and drop the file here"
|
2023-09-23 01:09:02 +08:00
|
|
|
dragSubText="Upload up to 3 images"
|
|
|
|
accept="image/*"
|
|
|
|
limit={3}
|
2023-09-19 20:52:02 +08:00
|
|
|
></Upload>
|
2023-09-23 01:09:02 +08:00
|
|
|
<div className="pt-4 flex justify-between items-center">
|
|
|
|
<div className="text-sm opacity-80">
|
|
|
|
<i className="fa-brands fa-markdown me-1"></i>Styling with markdown is
|
|
|
|
supported
|
|
|
|
</div>
|
|
|
|
<Button onClick={onSubmit} style={{ padding: "16px 24px" }}>
|
|
|
|
Submit
|
|
|
|
</Button>
|
|
|
|
</div>
|
2023-09-19 20:52:02 +08:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
2023-09-19 20:51:49 +08:00
|
|
|
|
|
|
|
export default function BugReport() {
|
|
|
|
const [theme, setTheme] = useState("");
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
const t = localStorage.getItem("theme");
|
|
|
|
setTheme(t);
|
|
|
|
if (t === "dark") {
|
|
|
|
const body = document.body;
|
|
|
|
if (body.hasAttribute("theme-mode")) {
|
|
|
|
body.setAttribute("theme-mode", "dark");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const body = document.body;
|
|
|
|
if (body.hasAttribute("theme-mode")) {
|
|
|
|
body.setAttribute("theme-mode", "light");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
document.title = "Report a bug - drawDB";
|
|
|
|
document.body.setAttribute("class", "theme");
|
|
|
|
}, [setTheme]);
|
|
|
|
|
|
|
|
const changeTheme = () => {
|
|
|
|
const body = document.body;
|
|
|
|
const t = body.getAttribute("theme-mode");
|
|
|
|
if (t === "dark") {
|
|
|
|
if (body.hasAttribute("theme-mode")) {
|
|
|
|
body.setAttribute("theme-mode", "light");
|
|
|
|
setTheme("light");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (body.hasAttribute("theme-mode")) {
|
|
|
|
body.setAttribute("theme-mode", "dark");
|
|
|
|
setTheme("dark");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<div className="sm:py-3 py-5 px-6 flex justify-between items-center">
|
|
|
|
<div className="flex items-center justify-start">
|
|
|
|
<img
|
|
|
|
src={theme === "dark" ? logo_dark : logo_light}
|
|
|
|
alt="logo"
|
|
|
|
className="me-2 sm:h-[28px] md:h-[46px]"
|
|
|
|
/>
|
|
|
|
<div className="ms-4 sm:text-sm xl:text-lg font-semibold">
|
|
|
|
Report a bug
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="flex items-center">
|
|
|
|
<Button
|
|
|
|
icon={
|
|
|
|
theme === "dark" ? (
|
|
|
|
<IconSun size="extra-large" />
|
|
|
|
) : (
|
|
|
|
<IconMoon size="extra-large" />
|
|
|
|
)
|
|
|
|
}
|
|
|
|
theme="borderless"
|
|
|
|
onClick={changeTheme}
|
|
|
|
></Button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<hr
|
|
|
|
className={`${
|
|
|
|
theme === "dark" ? "border-zinc-700" : "border-zinc-300"
|
|
|
|
} my-1`}
|
|
|
|
/>
|
|
|
|
<div className="grid grid-cols-12 gap-8 my-6 mx-8">
|
2023-09-19 20:51:59 +08:00
|
|
|
<div className="col-span-4">
|
|
|
|
<div className="card-theme p-6 rounded-md">
|
|
|
|
<div className="flex items-center">
|
|
|
|
<IconPaperclip />
|
|
|
|
<div className="font-bold ms-1">Describe the bug </div>
|
|
|
|
</div>
|
|
|
|
<div className="text-sm mt-1">
|
|
|
|
Please provide a clear and concise description of what the bug is.
|
|
|
|
</div>
|
|
|
|
<div className="flex items-center mt-3">
|
|
|
|
<IconPaperclip />
|
|
|
|
<div className="font-bold ms-1">Steps to reproduce the bug </div>
|
|
|
|
</div>
|
|
|
|
<div className="text-sm mt-1">
|
|
|
|
Please provide the steps of how to reproduce the bug.
|
|
|
|
</div>
|
|
|
|
<div className="flex items-center mt-3">
|
|
|
|
<IconPaperclip />
|
|
|
|
<div className="font-bold ms-1">Expected behaviour</div>
|
|
|
|
</div>
|
|
|
|
<div className="text-sm mt-1">
|
|
|
|
Tell us what you expected to see vs what you saw.
|
|
|
|
</div>
|
|
|
|
<div className="flex items-center mt-3">
|
|
|
|
<IconPaperclip />
|
|
|
|
<div className="font-bold ms-1">Your browser and device</div>
|
|
|
|
</div>
|
|
|
|
<div className="text-sm mt-1">
|
|
|
|
What web browser and device did you encounter the bug on.
|
|
|
|
</div>
|
|
|
|
<div className="flex items-center mt-3">
|
|
|
|
<IconPaperclip />
|
|
|
|
<div className="font-bold ms-1">Screenshots</div>
|
|
|
|
</div>
|
|
|
|
<div className="text-sm mt-1">
|
|
|
|
Add any relevant images if possible.
|
|
|
|
</div>
|
|
|
|
<div className="flex items-center justify-center my-2">
|
|
|
|
<hr
|
|
|
|
className={`${
|
|
|
|
theme === "dark" ? "border-zinc-700" : "border-zinc-300"
|
|
|
|
} flex-grow`}
|
|
|
|
/>
|
|
|
|
<div className="text-sm font-semibold m-2">Alternatively</div>
|
|
|
|
<hr
|
|
|
|
className={`${
|
|
|
|
theme === "dark" ? "border-zinc-700" : "border-zinc-300"
|
|
|
|
} flex-grow`}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
<Button
|
|
|
|
block
|
|
|
|
icon={<IconGithubLogo />}
|
|
|
|
style={{ backgroundColor: "#239144", color: "white" }}
|
|
|
|
onClick={() => {
|
|
|
|
window.open(
|
|
|
|
"https://github.com/drawdb-io/drawdb-issues/issues",
|
|
|
|
"_self"
|
|
|
|
);
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
Add an issue
|
|
|
|
</Button>
|
2023-09-19 20:51:49 +08:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="col-span-8">
|
|
|
|
<Banner
|
|
|
|
fullMode={false}
|
|
|
|
type="info"
|
|
|
|
icon={null}
|
|
|
|
closeIcon={null}
|
|
|
|
description={
|
|
|
|
<div>
|
|
|
|
We value your feedback! If you've encountered a bug or issue
|
|
|
|
while using our platform, please help us improve by reporting
|
|
|
|
it. Your input is invaluable in making our service better.
|
|
|
|
</div>
|
|
|
|
}
|
|
|
|
/>
|
2023-09-19 20:52:02 +08:00
|
|
|
<LexicalComposer initialConfig={editorConfig}>
|
|
|
|
<Form theme={theme} />
|
|
|
|
</LexicalComposer>
|
2023-09-19 20:51:49 +08:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<hr
|
|
|
|
className={`${
|
|
|
|
theme === "dark" ? "border-zinc-700" : "border-zinc-300"
|
|
|
|
} my-1`}
|
|
|
|
/>
|
|
|
|
<div className="text-center text-sm py-3">
|
|
|
|
© 2024 <strong>drawDB</strong> - All right reserved.
|
|
|
|
</div>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
}
|