Quiz-PDF/Frontend/app/actions.ts

278 lines
8.4 KiB
TypeScript

"use server";
import { redirect } from "next/navigation";
import pb from "@/lib/pocketbase";
import { cookies } from "next/headers";
import CryptoJS from 'crypto-js';
import { CheckoutSession, SignUpForm, SourceModal, Subscription, SubscriptionSession, User } from "@/types";
import { apiPrices } from "./(public)/pricing/actions";
export async function mailchimp(formData: {
email: string;
first_name: string;
last_name: string;
phone_number?: string;
company_size: string;
source?: SourceModal;
}) {
const email = formData.email;
const mailchimpBaseUrl = process.env.NEXT_PUBLIC_MAILCHIMP_BASE_URL;
const mailchimpApiKey = process.env.NEXT_PUBLIC_MAILCHIMP_BASE64_API_KEY;
const mailchimpList = process.env.NEXT_PUBLIC_MAILCHIMP_LIST_ID;
if (!mailchimpApiKey) return;
try {
const subscriberHash = CryptoJS.MD5(email.toLocaleLowerCase());
const mailchimpResponse = await fetch(`${mailchimpBaseUrl}/3.0/lists/${mailchimpList}/members/${subscriberHash}`,
{
method: 'PUT',
headers: {
"Content-Type": "application/json",
Authorization: mailchimpApiKey,
},
body: JSON.stringify(
{
"email_address": email,
status: "subscribed",
merge_fields: {
EMAIL: formData.email,
FNAME: formData.first_name,
LNAME: formData.last_name,
PHONE: !formData.phone_number ? '' : formData.phone_number,
CSIZE: formData.company_size,
SOURCE: formData.source
}
}
)
})
if (mailchimpResponse.status !== 200) {
throw new Error("couldn't complete the request");
}
return mailchimpResponse.json();
} catch (err) {
throw new Error("couldn't complete the request");
}
}
export async function signup(formData: SignUpForm) {
const email = formData.email;
const password = formData.password;
const organisation = formData.organisation;
console.log('app/(authenticated)/actions', 'organisation', organisation)
const pocketbaseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL as string;
const adminToken = process.env.NEXT_PUBLIC_POCKETBASE_ADMIN_TOKEN as string;
try {
const orgRes = await fetch(
`${pocketbaseUrl}/api/collections/organisation/records`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: adminToken,
},
body: JSON.stringify({
name: organisation,
}),
}
);
console.log("orgRes.status: ", orgRes.status);
if (orgRes.status !== 200) {
throw new Error("Failed to create organisation");
}
const orgData = await orgRes.json();
console.log(orgData);
const userRes = await fetch(
`${pocketbaseUrl}/api/collections/user/records`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: adminToken,
},
body: JSON.stringify({
firstName: formData.first_name,
lastName: formData.last_name,
displayName: formData.first_name + ' ' + formData.last_name,
email: email,
password: password,
passwordConfirm: password,
organisation: orgData?.id,
role: "Admin",
lastSeen: new Date(),
}),
}
);
console.log("userRes.status: ", userRes.status);
if (userRes.status !== 200) {
console.log(userRes);
throw new Error("Failed to create user");
}
} catch (err) {
if (err instanceof Error) {
throw new Error(err.message);
}
}
}
export async function login(formData: { email: string; password: string }) {
console.log('login')
const email = formData.email as string;
const password = formData.password as string;
try {
const { token, record: data } = await pb
.collection("user")
.authWithPassword(email, password);
if (pb.authStore.isValid) {
const cookie = pb.authStore.exportToCookie();
cookies().set("pb_auth", cookie, {
secure: true,
path: "/",
sameSite: "strict",
httpOnly: true,
});
}
return { success: true, error: "Failed to log in", token: token, data: data };
} catch (error) {
console.log(error)
if ((error as any).status == 403) {
await pb.collection('user').requestVerification(email);
}
return JSON.parse(JSON.stringify(error))
}
}
export async function getAuthCookie() {
try {
const cookie = cookies().get('pb_auth');
pb.authStore.loadFromCookie(cookie?.value || '');
return pb.authStore.token;
} catch (error) {
return undefined;
}
}
export async function isAuthenticated() {
try {
const cookie = cookies().get('pb_auth');
if(!cookie) return false;
pb.authStore.loadFromCookie(cookie?.value || '');
return pb.authStore.isValid || false;
} catch (error) {
return undefined;
}
}
export async function getUser() {
try {
const cookie = cookies().get('pb_auth');
if(!cookie) return false;
pb.authStore.loadFromCookie(cookie?.value || '');
return pb.authStore.model;
} catch (error) {
return undefined;
}
}
export async function logout() {
cookies().delete("pb_auth");
redirect('/');
}
export async function createCheckoutSession(price_id: string, type: string) {
const pocketbaseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL;
if (!pocketbaseUrl) {
throw Error('Connection Timeout');
}
if (!price_id) {
throw Error('There was an error during the payment processing');
}
const token = await getAuthCookie();
if (!token) {
throw Error('Could not authenticate');
}
console.log('token', token);
console.log('url ', `${pocketbaseUrl}/create-checkout-session`);
const body = JSON.stringify({
price: {
id: price_id,
type: type
},
quantity: 1
});
console.log('body',body);
try{
const createCheckoutSessionResponse = await fetch(
`${pocketbaseUrl}/create-checkout-session`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: token,
},
body: body,
}
);
if (createCheckoutSessionResponse.status !== 200) {
throw new Error("Failed to process Request");
}
const createCheckoutSessionData: CheckoutSession = await createCheckoutSessionResponse.json();
if (createCheckoutSessionData.url === "") {
throw new Error("Failed to process request an invalid URL was served");
}
return createCheckoutSessionData;
} catch (error) {
throw error;
}
}
export async function getSubscriptions() {
const cookie = cookies().get('pb_auth');
pb.authStore.loadFromCookie(cookie?.value || '');
const userId = (pb.authStore.model as User).id
const subscriptions = await pb.collection("subscription").getFullList<Subscription>({filter: `user_id="${userId}" && status="active"`});
console.log('app/(authenticated)/actions', 'subscriptions', subscriptions)
if (subscriptions.length === 0){
return [];
}
const products = await apiPrices();
const subscriptionWithProducts = subscriptions.map(subscription => {return {...subscription, product: products.find(product => product?.yearlyPrice?.price_id === subscription.price_id || product?.monthlyPrice?.price_id === subscription.price_id)}}) as Subscription[]
return subscriptionWithProducts;
}
export async function createManagementSubscriptionSession() {
const pocketbaseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL;
if (!pocketbaseUrl) {
throw Error('Connection Timeout');
}
const token = await getAuthCookie();
if (!token) {
throw Error('Could not authenticate');
}
console.log('token', token);
console.log('url ', `${pocketbaseUrl}/create-checkout-session`);
try{
const createManagementSessionResponse = await fetch(
`${pocketbaseUrl}/create-portal-link`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: token,
},
body: JSON.stringify({}),
}
);
if (createManagementSessionResponse.status !== 200) {
console.log(createManagementSessionResponse.status)
throw new Error(JSON.stringify( await createManagementSessionResponse.json()));
}
const createManagementSessionData: SubscriptionSession = await createManagementSessionResponse.json();
return createManagementSessionData;
} catch (error) {
throw error;
}
}