User-side feedback

This commit is contained in:
Wind-Explorer
2024-08-11 15:22:32 +08:00
parent b35c74ac68
commit 7966f8710b
7 changed files with 270 additions and 3 deletions

View File

@@ -33,7 +33,7 @@ import CommunityPostManagement from "./pages/CommunityPostManagement";
import ManageVoucherPage from "./pages/ManageVoucherPage";
import CreateVoucherPage from "./pages/CreateVoucherPage";
import EditVoucherPage from "./pages/EditVoucherPage";
import FeedbackPage from "./pages/FeedbackPage";
function App() {
return (
@@ -83,6 +83,7 @@ function App() {
element={<ResetPasswordPage />}
path="reset-password/:token"
/>
<Route element={<FeedbackPage />} path="feedback" />
</Route>
</Route>

View File

@@ -1,12 +1,22 @@
import { Button, Link } from "@nextui-org/react";
import { useNavigate } from "react-router-dom";
export default function SiteFooter() {
const navigate = useNavigate();
return (
<div className="bg-black text-white p-8">
<div className="flex flex-col text-center *:mx-auto gap-16">
<div className="flex flex-col gap-4 *:mx-auto">
<p className="text-2xl font-bold">Have a question?</p>
<Button color="primary" variant="solid" className="px-24" size="lg">
<Button
color="primary"
variant="solid"
className="px-24"
size="lg"
onPress={() => {
navigate("/feedback");
}}
>
Get in touch with us
</Button>
</div>

View File

@@ -1,6 +1,7 @@
import { Outlet, useNavigate } from "react-router-dom";
import EcoconnectFullLogo from "../components/EcoconnectFullLogo";
import { Button, Card } from "@nextui-org/react";
import { Toaster } from "react-hot-toast";
export default function RestrictedLayout() {
const navigate = useNavigate();
@@ -29,6 +30,7 @@ export default function RestrictedLayout() {
</div>
</div>
</div>
<Toaster />
</div>
);
}

View File

@@ -0,0 +1,151 @@
import { useEffect, useState } from "react";
import { retrieveUserInformation } from "../security/users";
import { useNavigate } from "react-router-dom";
import { ErrorMessage, Field, Formik, Form } from "formik";
import * as Yup from "yup";
import NextUIFormikInput from "../components/NextUIFormikInput";
import { Button, Checkbox } from "@nextui-org/react";
import NextUIFormikTextarea from "../components/NextUIFormikTextarea";
import NextUIFormikSelect from "../components/NextUIFormikSelect";
import instance from "../security/http";
import config from "../config";
import { popErrorToast, popToast } from "../utilities";
export default function FeedbackPage() {
const [userInformation, setUserInformation] = useState<any>();
const navigate = useNavigate();
useEffect(() => {
retrieveUserInformation()
.then((response) => {
setUserInformation(response);
})
.catch(() => {
navigate("/signin");
});
}, []);
const validationSchema = Yup.object({
feedbackCategory: Yup.string().trim().required("Select feedback type."),
subject: Yup.string().trim().min(1).max(100).required("Enter a subject."),
comment: Yup.string()
.trim()
.min(1)
.max(1024)
.required("Enter your comments."),
allowContact: Yup.boolean().oneOf([true, false], "please decide"),
});
const initialValues = {
feedbackCategory: "",
subject: "",
comment: "",
allowContact: false,
};
const handleSubmit = async (values: any) => {
try {
console.log(values.feedbackCategory);
instance
.post(config.serverAddress + "/feedback", {
...values,
userId: userInformation.id,
feedbackCategory: parseInt(values.feedbackCategory),
})
.then(() => {
popToast("Your feedback has been submitted!", 1);
navigate("/springboard");
});
} catch (error) {
popErrorToast(error);
}
};
return (
<>
{userInformation && (
<div className="">
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-4">
<p className="text-3xl font-bold">Feedback</p>
<p>
Use the form below to send us your comments. We read all
feedback carefully, but we are unable to respond to each
submission individually.
</p>
</div>
<div>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{({ isValid, dirty }) => (
<Form>
<div className="flex flex-col gap-4">
<div className="flex flex-row gap-4">
<NextUIFormikInput
label="Subject"
name="subject"
type="text"
placeholder=""
labelPlacement="inside"
/>
<div className="w-96">
<NextUIFormikSelect
label="Feedback category"
name="feedbackCategory"
placeholder=""
labelPlacement="inside"
options={[
{ key: "0", label: "Feature request" },
{ key: "1", label: "Bug report" },
{ key: "2", label: "Get in contact" },
]}
/>
</div>
</div>
<NextUIFormikTextarea
label="Comments"
name="comment"
placeholder=""
labelPlacement="inside"
/>
<div>
<Field
name="allowContact"
type="checkbox"
as={Checkbox}
aria-label="Allow the team to contact you"
>
<p>
I permit the ecoconnect administrators to contact me
via{" "}
<span className="font-bold underline">
{userInformation.email}
</span>{" "}
to better understand the comments I submitted.
</p>
</Field>
<ErrorMessage
name="allowContact"
component="div"
className="text-red-500"
/>
</div>
<Button
type="submit"
color="primary"
isDisabled={!isValid || !dirty}
>
Submit Feedback
</Button>
</div>
</Form>
)}
</Formik>
</div>
</div>
</div>
)}
</>
);
}