336 lines
9.0 KiB
TypeScript
336 lines
9.0 KiB
TypeScript
"use server";
|
|
|
|
import { createClient } from "@/utils/supabase/server";
|
|
import { encodedRedirect } from "@/utils/utils";
|
|
import { headers } from "next/headers";
|
|
import { redirect } from "next/navigation";
|
|
import AdminNotification from "../_components/email-templates/admin-notification";
|
|
import UserConfirmation from "../_components/email-templates/user-confirmation";
|
|
import { render } from "@react-email/components";
|
|
import { useResend } from "../_hooks/use-resend";
|
|
import { typeMessageMap } from "@/src/entities/models/contact-us.model";
|
|
|
|
export const signInAction = async (formData: { email: string }) => {
|
|
const supabase = await createClient();
|
|
const encodeEmail = encodeURIComponent(formData.email);
|
|
|
|
try {
|
|
// First, check for existing session
|
|
const {
|
|
data: { session },
|
|
error: sessionError,
|
|
} = await supabase.auth.getSession();
|
|
|
|
// If there's an active session and the email matches
|
|
if (session && session.user.email === formData.email) {
|
|
return {
|
|
success: true,
|
|
message: "Already logged in",
|
|
redirectTo: "/protected/dashboard", // or wherever you want to redirect logged in users
|
|
};
|
|
}
|
|
|
|
// If no active session or different email, proceed with OTP
|
|
const { data, error } = await supabase.auth.signInWithOtp({
|
|
email: formData.email,
|
|
options: {
|
|
shouldCreateUser: false,
|
|
},
|
|
});
|
|
|
|
if (error) {
|
|
return {
|
|
success: false,
|
|
error: error.message,
|
|
redirectTo: `/verify-otp?email=${encodeEmail}`,
|
|
};
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
message: "OTP has been sent to your email",
|
|
redirectTo: `/verify-otp?email=${encodeEmail}`,
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error: "An unexpected error occurred",
|
|
redirectTo: "/sign-in",
|
|
};
|
|
}
|
|
};
|
|
|
|
export const signUpAction = async (formData: FormData) => {
|
|
const email = formData.get("email")?.toString();
|
|
const password = formData.get("password")?.toString();
|
|
const supabase = await createClient();
|
|
const origin = (await headers()).get("origin");
|
|
|
|
if (!email || !password) {
|
|
return encodedRedirect(
|
|
"error",
|
|
"/sign-up",
|
|
"Email and password are required",
|
|
);
|
|
}
|
|
|
|
const { error } = await supabase.auth.signUp({
|
|
email,
|
|
password,
|
|
options: {
|
|
emailRedirectTo: `${origin}/auth/callback`,
|
|
},
|
|
});
|
|
|
|
if (error) {
|
|
console.error(error.code + " " + error.message);
|
|
return encodedRedirect("error", "/sign-up", error.message);
|
|
} else {
|
|
return encodedRedirect(
|
|
"success",
|
|
"/sign-up",
|
|
"Thanks for signing up! Please check your email for a verification link.",
|
|
);
|
|
}
|
|
};
|
|
|
|
|
|
export const checkSession = async () => {
|
|
const supabase = await createClient();
|
|
|
|
try {
|
|
const {
|
|
data: { session },
|
|
error,
|
|
} = await supabase.auth.getSession();
|
|
|
|
if (error) {
|
|
return {
|
|
success: false,
|
|
error: error.message,
|
|
};
|
|
}
|
|
|
|
if (session) {
|
|
return {
|
|
success: true,
|
|
session,
|
|
redirectTo: "/protected/dashboard", // or your preferred authenticated route
|
|
};
|
|
}
|
|
|
|
return {
|
|
success: false,
|
|
message: "No active session",
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error: "An unexpected error occurred",
|
|
};
|
|
}
|
|
};
|
|
|
|
export const forgotPasswordAction = async (formData: FormData) => {
|
|
const email = formData.get("email")?.toString();
|
|
const supabase = await createClient();
|
|
const origin = (await headers()).get("origin");
|
|
const callbackUrl = formData.get("callbackUrl")?.toString();
|
|
|
|
if (!email) {
|
|
return encodedRedirect("error", "/forgot-password", "Email is required");
|
|
}
|
|
|
|
const { error } = await supabase.auth.resetPasswordForEmail(email, {
|
|
redirectTo: `${origin}/auth/callback?redirect_to=/protected/reset-password`,
|
|
});
|
|
|
|
if (error) {
|
|
console.error(error.message);
|
|
return encodedRedirect(
|
|
"error",
|
|
"/forgot-password",
|
|
"Could not reset password"
|
|
);
|
|
}
|
|
|
|
if (callbackUrl) {
|
|
return redirect(callbackUrl);
|
|
}
|
|
|
|
return encodedRedirect(
|
|
"success",
|
|
"/forgot-password",
|
|
"Check your email for a link to reset your password."
|
|
);
|
|
};
|
|
|
|
export const resetPasswordAction = async (formData: FormData) => {
|
|
const supabase = await createClient();
|
|
|
|
const password = formData.get("password") as string;
|
|
const confirmPassword = formData.get("confirmPassword") as string;
|
|
|
|
if (!password || !confirmPassword) {
|
|
encodedRedirect(
|
|
"error",
|
|
"/protected/reset-password",
|
|
"Password and confirm password are required"
|
|
);
|
|
}
|
|
|
|
if (password !== confirmPassword) {
|
|
encodedRedirect(
|
|
"error",
|
|
"/protected/reset-password",
|
|
"Passwords do not match"
|
|
);
|
|
}
|
|
|
|
const { error } = await supabase.auth.updateUser({
|
|
password: password,
|
|
});
|
|
|
|
if (error) {
|
|
encodedRedirect(
|
|
"error",
|
|
"/protected/reset-password",
|
|
"Password update failed"
|
|
);
|
|
}
|
|
|
|
encodedRedirect("success", "/protected/reset-password", "Password updated");
|
|
};
|
|
|
|
export const verifyOtpAction = async (formData: FormData) => {
|
|
const email = formData.get("email") as string;
|
|
const token = formData.get("token") as string;
|
|
const supabase = await createClient();
|
|
|
|
console.log("email", email);
|
|
console.log("token", token);
|
|
|
|
if (!email || !token) {
|
|
redirect("/error?message=Email and OTP are required");
|
|
}
|
|
|
|
const {
|
|
data: { session },
|
|
error,
|
|
} = await supabase.auth.verifyOtp({
|
|
email,
|
|
token,
|
|
type: "email",
|
|
});
|
|
|
|
if (error) {
|
|
return redirect(`/verify-otp?error=${encodeURIComponent(error.message)}`);
|
|
}
|
|
|
|
return redirect("/protected/dashboard?message=OTP verified successfully");
|
|
};
|
|
|
|
export async function sendContactEmail(formData: {
|
|
name: string;
|
|
email: string;
|
|
phone: string;
|
|
typeMessage: string;
|
|
message: string;
|
|
}) {
|
|
try {
|
|
// Initialize Supabase
|
|
const supabase = await createClient();
|
|
const { resend } = useResend();
|
|
|
|
// Get message type label
|
|
const messageTypeLabel =
|
|
typeMessageMap.get(formData.typeMessage) || "Unknown";
|
|
|
|
// Save to Supabase
|
|
const { data: contactData, error: contactError } = await supabase
|
|
.from("contact_messages")
|
|
.insert([
|
|
{
|
|
name: formData.name,
|
|
email: formData.email,
|
|
phone: formData.phone,
|
|
message_type: formData.typeMessage,
|
|
message_type_label: messageTypeLabel,
|
|
message: formData.message,
|
|
status: "new",
|
|
},
|
|
])
|
|
.select();
|
|
|
|
if (contactError) {
|
|
console.error("Error saving contact message to Supabase:", contactError);
|
|
return {
|
|
success: false,
|
|
error: "Failed to save your message. Please try again later.",
|
|
};
|
|
}
|
|
|
|
// Render admin email template
|
|
const adminEmailHtml = await render(
|
|
AdminNotification({
|
|
name: formData.name,
|
|
email: formData.email,
|
|
phone: formData.phone,
|
|
messageType: messageTypeLabel,
|
|
message: formData.message,
|
|
})
|
|
);
|
|
|
|
// Send email to admin
|
|
const { data: emailData, error: emailError } = await resend.emails.send({
|
|
from: "Contact Form <contact@backspacex.tech>",
|
|
to: ["xdamazon17@gmail.com"],
|
|
subject: `New Contact Form Submission: ${messageTypeLabel}`,
|
|
html: adminEmailHtml,
|
|
});
|
|
|
|
if (emailError) {
|
|
console.error("Error sending email via Resend:", emailError);
|
|
// Note: We don't return error here since the data is already saved to Supabase
|
|
}
|
|
|
|
const userEmailHtml = await render(
|
|
UserConfirmation({
|
|
name: formData.name,
|
|
messageType: messageTypeLabel,
|
|
message: formData.message,
|
|
})
|
|
);
|
|
|
|
// Send confirmation email to user
|
|
const { data: confirmationData, error: confirmationError } =
|
|
await resend.emails.send({
|
|
from: "Your Company <support@backspacex.tech>",
|
|
to: [formData.email],
|
|
subject: "Thank you for contacting us",
|
|
html: userEmailHtml,
|
|
});
|
|
|
|
if (confirmationError) {
|
|
console.error("Error sending confirmation email:", confirmationError);
|
|
// Note: We don't return error here either
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
message: "Your message has been sent successfully!",
|
|
};
|
|
} catch (error) {
|
|
console.error("Unexpected error in sendContactEmail:", error);
|
|
return {
|
|
success: false,
|
|
error: "An unexpected error occurred. Please try again later.",
|
|
};
|
|
}
|
|
}
|
|
|
|
export const signOutAction = async () => {
|
|
const supabase = await createClient();
|
|
await supabase.auth.signOut();
|
|
return redirect("/sign-in");
|
|
}; |