Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/app/.env.local-example
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
NEXT_PUBLIC_API_URL=http://api.devfaq.localhost:3002
NEXT_PUBLIC_APP_URL=http://app.devfaq.localhost:3000
NEXT_PUBLIC_REVALIDATION_SECRET=

FLAGSMITH_SERVER_SIDE_ENVIRONMENT_KEY=
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,7 @@ export default async function SingleQuestionPage({ params }: { params: Params<"q
</>
);
}

export async function generateStaticParams() {
return [];
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Button } from "../../Button/Button";
import { WysiwygEditor } from "../../WysiwygEditor/WysiwygEditor";
import { URL_REGEX } from "../../../lib/constants";
import { Error } from "../../Error";
import { useRevalidation } from "../../../hooks/useRevalidation";
import { AnswerSources } from "./AnswerSources";

type AddAnswerFormProps = Readonly<{
Expand All @@ -21,9 +22,13 @@ export const AddAnswerForm = ({ questionId }: AddAnswerFormProps) => {
const [isError, setIsError] = useState(false);

const { createQuestionAnswerMutation } = useQuestionMutation();
const { revalidateMutation } = useRevalidation();

const disabled =
content.trim().length === 0 || !sources.every((source) => URL_REGEX.test(source));
content.trim().length === 0 ||
!sources.every((source) => URL_REGEX.test(source)) ||
createQuestionAnswerMutation.isLoading ||
revalidateMutation.isLoading;

const handleFormSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
Expand All @@ -36,9 +41,14 @@ export const AddAnswerForm = ({ questionId }: AddAnswerFormProps) => {
},
{
onSuccess: () => {
router.refresh();
setContent("");
setSources([]);
revalidateMutation.mutate(`/questions/p/${questionId}`, {
onSuccess: () => {
router.refresh();
setContent("");
setSources([]);
},
onError: () => setIsError(true),
});
},
onError: () => setIsError(true),
},
Expand Down
8 changes: 8 additions & 0 deletions apps/app/src/hooks/useRevalidation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useMutation } from "@tanstack/react-query";
import { revalidate } from "../services/revalidation.service";

export const useRevalidation = () => {
const revalidateMutation = useMutation(revalidate);

return { revalidateMutation };
};
3 changes: 3 additions & 0 deletions apps/app/src/lib/revalidation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const validatePath = (path: string | string[] | undefined): path is string => {
return Boolean(path) && typeof path === "string";
};
21 changes: 21 additions & 0 deletions apps/app/src/pages/api/revalidation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { validatePath } from "../../lib/revalidation";

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { token, path } = req.query;

if (token !== process.env.NEXT_PUBLIC_REVALIDATION_SECRET) {
return res.status(401).json({ message: "Invalid token" });
}

if (!validatePath(path)) {
return res.status(400).json({ message: "Incorrect path format" });
}

try {
await res.revalidate(path);
return res.status(204).end();
} catch (err) {
return res.status(500).json({ message: "Error revalidating" });
}
}
5 changes: 5 additions & 0 deletions apps/app/src/services/revalidation.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const revalidate = (path: string) =>
fetch(
`/api/revalidation?token=${process.env.NEXT_PUBLIC_REVALIDATION_SECRET || ""}&path=${path}`,
{ method: "POST" },
);