Skip to content

Commit 052966b

Browse files
RickaPrincysanda03
andauthored
feat: reply form
* chore: restyle reply * feat: can reply a form --------- Co-authored-by: sanda03 <hei.sanda.2@gmail.com>
1 parent 94cbcfd commit 052966b

File tree

18 files changed

+876
-183
lines changed

18 files changed

+876
-183
lines changed

src/assets/images/error_multiple.png

69.2 KB
Loading

src/assets/images/private.png

134 KB
Loading

src/assets/images/success.png

32.2 KB
Loading

src/gen/client/api.ts

+482
Large diffs are not rendered by default.
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Button, Typography } from "@material-tailwind/react";
2+
import { useNavigate } from "react-router-dom";
3+
4+
import errorImage from "../../assets/images/private.png";
5+
6+
export function AlreadyRespond() {
7+
const navigate = useNavigate();
8+
9+
return (
10+
<div className="w-[800px] mx-auto flex-col min-h-[500px] gap-5 flex items-center justify-center">
11+
<img src={errorImage} className="w-[350px]" />
12+
<Typography className="text-bgray text-[30px] text-center">
13+
Form not found or Multiple responses are not allowed for the form, so
14+
you no longer have access to respond.
15+
</Typography>
16+
<Button onClick={() => navigate("/dashboard")}>Go to Dashboard</Button>
17+
</div>
18+
);
19+
}

src/operations/error/PrivateForm.jsx

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Button, Typography } from "@material-tailwind/react";
2+
import { useNavigate } from "react-router-dom";
3+
4+
import errorImage from "../../assets/images/error_multiple.png";
5+
6+
export function PrivateForm() {
7+
const navigate = useNavigate();
8+
9+
return (
10+
<div className="w-[500px] mx-auto flex-col min-h-[500px] gap-5 flex items-center justify-center">
11+
<img src={errorImage} className="w-[350px]" />
12+
<Typography className="text-bgray text-[30px] text-center">
13+
Only the form owner can view the results as the form is set to private
14+
</Typography>
15+
<Button onClick={() => navigate("/dashboard")}>Go to Dashboard</Button>
16+
</div>
17+
);
18+
}

src/operations/error/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./AlreadyRespond";
2+
export * from "./PrivateForm";

src/operations/forms/create/FormEdit.jsx

+1-4
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,7 @@ export function FormEdit() {
2828
setAll(newStore);
2929
})
3030
.catch(() => {
31-
notify("Oops, form not found or something went wrong", {
32-
color: "red",
33-
});
34-
navigate("/dashboard");
31+
navigate("/dashboard/error/multiple");
3532
})
3633
.finally(() => dumbLoading(() => setIsLoading(false)));
3734
};

src/operations/forms/create/components/CreateFormHeader.jsx

+18-7
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,24 @@ export function CreateFormHeader() {
4949
/>
5050
<NumberOfQuestion />
5151
<CollapseConfig title="More configuration">
52-
<Switch
53-
label="Private"
54-
name="isPrivate"
55-
className="text-bgray text-[14px]"
56-
checked={config.isPrivate}
57-
onChange={({ target }) => updateConfig("isPrivate", target.checked)}
58-
/>
52+
<div className="flex items-center gap-5">
53+
<Switch
54+
label="Multiple response"
55+
name="allowMultipleChoice"
56+
className="text-bgray text-[14px]"
57+
checked={config.allowMultipleChoice}
58+
onChange={({ target }) =>
59+
updateConfig("allowMultipleChoice", target.checked)
60+
}
61+
/>
62+
<Switch
63+
label="Private"
64+
name="isPrivate"
65+
className="text-bgray text-[14px]"
66+
checked={config.isPrivate}
67+
onChange={({ target }) => updateConfig("isPrivate", target.checked)}
68+
/>
69+
</div>
5970
<Input
6071
type="color"
6172
name="color"

src/operations/forms/create/components/Question.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export const Question = React.memo(({ questionIndex }) => {
9292
)}
9393
<div className="flex gap-10 items-start w-full">
9494
<Switch
95-
value={question.isRequired}
95+
checked={question.isRequired}
9696
onChange={({ target }) =>
9797
updateQuestion(question.id, "isRequired", target.checked)
9898
}

src/operations/forms/list/components/Actions.jsx

+14
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ export function Actions({ formId }) {
2222
const { setIsLoading, fetchForms } = useContext(LIST_CONTEXT);
2323
const notify = useNotify();
2424

25+
const copyLink = () => {
26+
const url = `${window.location.origin}/dashboard/forms/${formId}/reply`;
27+
navigator.clipboard.writeText(url);
28+
notify("Link copied", { color: "green" });
29+
};
30+
2531
const doDelete = async () => {
2632
setIsLoading(true);
2733
formsProvider
@@ -47,6 +53,14 @@ export function Actions({ formId }) {
4753
</IconButton>
4854
</PopoverHandler>
4955
<PopoverContent className="p-0 w-[150px]">
56+
<Button
57+
size="sm"
58+
variant="text"
59+
className="py-2 w-full block"
60+
onClick={copyLink}
61+
>
62+
CopyLink
63+
</Button>
5064
<Button
5165
size="sm"
5266
variant="text"
+55-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,63 @@
1+
import { useNavigate, useParams } from "react-router-dom";
2+
import { useEffect, useState } from "react";
13
import { ReplyFormHeader, ReplyFormBody } from "./components";
4+
import { useNotify } from "../../../hooks";
5+
import { useDashboardState } from "../../../stores";
6+
import { formsProvider } from "../../../providers";
7+
import { dumbLoading } from "../../utils";
28

9+
/*eslint-disable*/
310
export function FormReply() {
11+
const [form, setForms] = useState(null);
12+
const { formId } = useParams();
13+
const notify = useNotify((state) => state.setNotify);
14+
const navigate = useNavigate();
15+
const { isLoading, setIsLoading } = useDashboardState();
16+
17+
useEffect(() => {
18+
setIsLoading(true);
19+
20+
const getFormById = async () => {
21+
formsProvider
22+
.getFormById(formId)
23+
.then((formResponse) => {
24+
setForms(formResponse);
25+
})
26+
.catch(() => {
27+
notify("Oops, form not found or something went wrong", {
28+
color: "red",
29+
});
30+
navigate("/dashboard");
31+
})
32+
.finally(() => dumbLoading(() => setIsLoading(false)));
33+
};
34+
35+
const testIfCanReply = async () => {
36+
formsProvider
37+
.canIReply(formId)
38+
.then((data) => {
39+
if (!data) {
40+
navigate("/dashboard/error/multiple");
41+
dumbLoading(() => setIsLoading(false));
42+
} else {
43+
getFormById();
44+
}
45+
})
46+
.catch(async () => {
47+
navigate("/dashboard/error/multiple");
48+
dumbLoading(() => setIsLoading(false));
49+
});
50+
};
51+
52+
testIfCanReply();
53+
}, [formId]);
54+
55+
if (isLoading || form === null) return null;
56+
457
return (
558
<div className="w-full mx-auto max-w-[900px]">
6-
<ReplyFormHeader />
7-
<ReplyFormBody />
59+
<ReplyFormHeader form={form} />
60+
<ReplyFormBody questions={form.questions || []} formId={form.id} />
861
</div>
962
);
1063
}

0 commit comments

Comments
 (0)