"use server"; import { revalidatePath } from "next/cache"; import { z } from "zod"; import PocketBase from "pocketbase"; import { Resend } from "resend"; import { pbCreate, pbList, pbUpdate } from "@/lib/pocketbase"; import { getAuth } from "@/lib/auth"; import { pbId } from "@/lib/pb"; import { PB_URL } from "@/lib/pocketbase"; export type ActionResult = { ok: true } | { ok: false; error: string }; const emailSettingsSchema = z.object({ statement_from_email: z.string().email("Valid email").or(z.literal("")).optional(), statement_cc_email: z.string().email("Valid email").or(z.literal("")).optional(), statement_app_email: z.string().email("Valid email").or(z.literal("")).optional(), statement_email_password: z.string().optional(), }); function clean(obj: any) { const out: any = {}; for (const [k, v] of Object.entries(obj)) { if (v === "" || v === null || v === undefined) continue; out[k] = v; } return out; } export async function updateEmailSettings(_: unknown, formData: FormData): Promise { const { token } = await getAuth(); if (!token) return { ok: false, error: "Not signed in" }; const parsed = emailSettingsSchema.safeParse({ statement_from_email: formData.get("statement_from_email") || "", statement_cc_email: formData.get("statement_cc_email") || "", statement_app_email: formData.get("statement_app_email") || "", statement_email_password: formData.get("statement_email_password") || "", }); if (!parsed.success) return { ok: false, error: parsed.error.issues[0]?.message ?? "Invalid input" }; try { const settings = await pbList("fuel_settings", { perPage: 1 }, token); if (settings.items.length === 0) return { ok: false, error: "Settings not configured" }; await pbUpdate("fuel_settings", settings.items[0].id, clean(parsed.data), token); } catch (err: any) { return { ok: false, error: err?.message || "Failed to update" }; } revalidatePath("/settings"); return { ok: true }; } export async function sendTestEmail(to: string): Promise { if (!to) return { ok: false, error: "Recipient email required" }; const apiKey = process.env.RESEND_API_KEY; if (!apiKey) return { ok: false, error: "RESEND_API_KEY not configured" }; const fromAddr = process.env.RESEND_FROM || "statements@rjbulk.co.za"; try { const resend = new Resend(apiKey); const result = await resend.emails.send({ from: fromAddr, to, subject: "RJ Bulk test email", html: "

This is a test email from your RJ Bulk back-office. If you got this, email is working correctly.

", }); if (result.error) { return { ok: false, error: result.error.message || "Send failed" }; } } catch (err: any) { return { ok: false, error: err?.message || "Send failed" }; } return { ok: true }; } const addUserSchema = z.object({ name: z.string().min(1, "Name is required"), username: z.string().min(3, "Username min 3 chars"), email: z.string().email("Valid email"), password: z.string().min(8, "Password min 8 chars"), }); export async function addUser(_: unknown, formData: FormData): Promise { const { token } = await getAuth(); if (!token) return { ok: false, error: "Not signed in" }; const parsed = addUserSchema.safeParse({ name: formData.get("name"), username: formData.get("username"), email: formData.get("email"), password: formData.get("password"), }); if (!parsed.success) return { ok: false, error: parsed.error.issues[0]?.message ?? "Invalid input" }; try { // Use superuser auth for creating new auth users (PocketBase limitation) const pb = new PocketBase(PB_URL); await pb.admins.authWithPassword( process.env.PB_ADMIN_EMAIL || "David.els1@outlook.com", process.env.PB_ADMIN_PASS || "1234567890", ); await pb.collection("users").create({ email: parsed.data.email, username: parsed.data.username, password: parsed.data.password, passwordConfirm: parsed.data.password, name: parsed.data.name, emailVisibility: true, verified: true, }); } catch (err: any) { return { ok: false, error: err?.message || "Failed to create user" }; } revalidatePath("/settings"); return { ok: true }; } export async function deleteUser(userId: string): Promise { const { token } = await getAuth(); if (!token) return { ok: false, error: "Not signed in" }; try { const pb = new PocketBase(PB_URL); await pb.admins.authWithPassword( process.env.PB_ADMIN_EMAIL || "David.els1@outlook.com", process.env.PB_ADMIN_PASS || "1234567890", ); await pb.collection("users").delete(userId); } catch (err: any) { return { ok: false, error: err?.message || "Failed to delete" }; } revalidatePath("/settings"); return { ok: true }; }