mirror of
https://github.com/lukevella/rallly.git
synced 2025-07-23 19:27:25 +02:00
♻️ Use safe action (#1832)
This commit is contained in:
parent
c9b5527432
commit
08ce80fb8d
5 changed files with 61 additions and 61 deletions
23
apps/web/src/app/[locale]/control-panel/settings/actions.ts
Normal file
23
apps/web/src/app/[locale]/control-panel/settings/actions.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
"use server";
|
||||
|
||||
import { prisma } from "@rallly/database";
|
||||
import { revalidateTag } from "next/cache";
|
||||
import { instanceSettingsTag } from "@/features/instance-settings/constants";
|
||||
import { instanceSettingsSchema } from "@/features/instance-settings/schema";
|
||||
import { adminActionClient } from "@/features/safe-action/server";
|
||||
|
||||
export const updateInstanceSettingsAction = adminActionClient
|
||||
.metadata({
|
||||
actionName: "update_instance_settings",
|
||||
})
|
||||
.inputSchema(instanceSettingsSchema)
|
||||
.action(async ({ parsedInput }) => {
|
||||
await prisma.instanceSettings.update({
|
||||
where: {
|
||||
id: 1,
|
||||
},
|
||||
data: parsedInput,
|
||||
});
|
||||
|
||||
revalidateTag(instanceSettingsTag);
|
||||
});
|
|
@ -26,10 +26,11 @@ import {
|
|||
SettingsGroupTitle,
|
||||
} from "@/components/settings-group";
|
||||
import { Trans } from "@/components/trans";
|
||||
import { updateInstanceSettings } from "@/features/instance-settings/mutations";
|
||||
import type { InstanceSettings } from "@/features/instance-settings/schema";
|
||||
import { instanceSettingsSchema } from "@/features/instance-settings/schema";
|
||||
import { useSafeAction } from "@/features/safe-action/client";
|
||||
import { useTranslation } from "@/i18n/client";
|
||||
import { updateInstanceSettingsAction } from "./actions";
|
||||
|
||||
export function InstanceSettingsForm({
|
||||
defaultValue,
|
||||
|
@ -41,6 +42,8 @@ export function InstanceSettingsForm({
|
|||
resolver: zodResolver(instanceSettingsSchema),
|
||||
});
|
||||
|
||||
const updateInstanceSettings = useSafeAction(updateInstanceSettingsAction);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
|
@ -49,7 +52,7 @@ export function InstanceSettingsForm({
|
|||
name="instance-settings-form"
|
||||
onSubmit={form.handleSubmit(async (data) => {
|
||||
try {
|
||||
await updateInstanceSettings(data);
|
||||
await updateInstanceSettings.executeAsync(data);
|
||||
form.reset(data);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
|
|
@ -1,35 +1,37 @@
|
|||
"use server";
|
||||
|
||||
import { requireUser } from "@/auth/queries";
|
||||
import type { Feedback } from "@/features/feedback/schema";
|
||||
import { feedbackSchema } from "@/features/feedback/schema";
|
||||
import { authActionClient } from "@/features/safe-action/server";
|
||||
import { getEmailClient } from "@/utils/emails";
|
||||
|
||||
import { rateLimit } from "../rate-limit";
|
||||
|
||||
export const submitFeedback = async (formData: Feedback) => {
|
||||
const { success } = await rateLimit("submitFeedback", 3, "1h");
|
||||
export const submitFeedbackAction = authActionClient
|
||||
.metadata({
|
||||
actionName: "submitFeedback",
|
||||
})
|
||||
.inputSchema(feedbackSchema)
|
||||
.action(async ({ ctx, parsedInput }) => {
|
||||
const { success } = await rateLimit("submitFeedback", 3, "1h");
|
||||
|
||||
if (!success) {
|
||||
return {
|
||||
error: "Rate limit exceeded" as const,
|
||||
};
|
||||
}
|
||||
if (!success) {
|
||||
return {
|
||||
error: "Rate limit exceeded" as const,
|
||||
};
|
||||
}
|
||||
|
||||
const user = await requireUser();
|
||||
try {
|
||||
const { content } = feedbackSchema.parse(formData);
|
||||
getEmailClient().sendEmail({
|
||||
to: "feedback@rallly.co",
|
||||
subject: "Feedback",
|
||||
text: `User: ${user.name} (${user.email})\n\n${content}`,
|
||||
});
|
||||
return {
|
||||
success: true,
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
error: "Invalid Form Data" as const,
|
||||
};
|
||||
}
|
||||
};
|
||||
try {
|
||||
const { content } = parsedInput;
|
||||
getEmailClient().sendEmail({
|
||||
to: "feedback@rallly.co",
|
||||
subject: "Feedback",
|
||||
text: `User: ${ctx.user.name} (${ctx.user.email})\n\n${content}`,
|
||||
});
|
||||
return {
|
||||
success: true,
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
error: "Invalid Form Data" as const,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
|
@ -24,12 +24,14 @@ import { useForm } from "react-hook-form";
|
|||
|
||||
import { Trans } from "@/components/trans";
|
||||
|
||||
import { useSafeAction } from "@/features/safe-action/client";
|
||||
import { isSelfHosted } from "@/utils/constants";
|
||||
import { submitFeedback } from "../actions";
|
||||
import { submitFeedbackAction } from "../actions";
|
||||
import type { Feedback } from "../schema";
|
||||
import { feedbackSchema } from "../schema";
|
||||
|
||||
export function FeedbackToggle() {
|
||||
const submitFeedback = useSafeAction(submitFeedbackAction);
|
||||
const form = useForm<Feedback>({
|
||||
resolver: zodResolver(feedbackSchema),
|
||||
});
|
||||
|
@ -72,17 +74,7 @@ export function FeedbackToggle() {
|
|||
</DialogHeader>
|
||||
|
||||
<Form {...form}>
|
||||
<form
|
||||
onSubmit={form.handleSubmit(async (data) => {
|
||||
const res = await submitFeedback(data);
|
||||
|
||||
if (res.error) {
|
||||
form.setError("content", {
|
||||
message: res.error,
|
||||
});
|
||||
}
|
||||
})}
|
||||
>
|
||||
<form onSubmit={form.handleSubmit(submitFeedback.executeAsync)}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="content"
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
"use server";
|
||||
|
||||
import type { InstanceSettings } from "@rallly/database";
|
||||
import { prisma } from "@rallly/database";
|
||||
import { revalidateTag } from "next/cache";
|
||||
import { requireAdmin } from "@/auth/queries";
|
||||
import { instanceSettingsTag } from "./constants";
|
||||
|
||||
export async function updateInstanceSettings(data: Partial<InstanceSettings>) {
|
||||
await requireAdmin();
|
||||
|
||||
await prisma.instanceSettings.update({
|
||||
where: {
|
||||
id: 1,
|
||||
},
|
||||
data,
|
||||
});
|
||||
|
||||
revalidateTag(instanceSettingsTag);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue