diff --git a/apps/web/src/app/[locale]/control-panel/settings/actions.ts b/apps/web/src/app/[locale]/control-panel/settings/actions.ts new file mode 100644 index 000000000..f8317b807 --- /dev/null +++ b/apps/web/src/app/[locale]/control-panel/settings/actions.ts @@ -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); + }); diff --git a/apps/web/src/app/[locale]/control-panel/settings/instance-settings-form.tsx b/apps/web/src/app/[locale]/control-panel/settings/instance-settings-form.tsx index f8549a506..5ebbe41f1 100644 --- a/apps/web/src/app/[locale]/control-panel/settings/instance-settings-form.tsx +++ b/apps/web/src/app/[locale]/control-panel/settings/instance-settings-form.tsx @@ -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); diff --git a/apps/web/src/features/feedback/actions.ts b/apps/web/src/features/feedback/actions.ts index 7f1e7717e..adaff2a6f 100644 --- a/apps/web/src/features/feedback/actions.ts +++ b/apps/web/src/features/feedback/actions.ts @@ -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, + }; + } + }); diff --git a/apps/web/src/features/feedback/components/feedback-toggle.tsx b/apps/web/src/features/feedback/components/feedback-toggle.tsx index 45cf4e219..add09a8cf 100644 --- a/apps/web/src/features/feedback/components/feedback-toggle.tsx +++ b/apps/web/src/features/feedback/components/feedback-toggle.tsx @@ -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({ resolver: zodResolver(feedbackSchema), }); @@ -72,17 +74,7 @@ export function FeedbackToggle() {
- { - const res = await submitFeedback(data); - - if (res.error) { - form.setError("content", { - message: res.error, - }); - } - })} - > + ) { - await requireAdmin(); - - await prisma.instanceSettings.update({ - where: { - id: 1, - }, - data, - }); - - revalidateTag(instanceSettingsTag); -}