mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-02-22 21:02:00 +00:00
- Updated `package.json` to include a new script for launching Prisma Studio. - Modified `signup` function in `auth-actions.ts` to include account number in user data. - Refactored `createPayment` function in `payment.ts` to improve error handling and return structured responses. - Updated UI components in the dashboard to improve layout and responsiveness, including changes to `UserDevices` and `UserPayments` pages. - Introduced new `AdminDevicesTable` and `UsersPaymentsTable` components for better admin functionalities. - Enhanced `DeviceCartDrawer` to provide user feedback during payment processing. - Added account number input to the signup form and updated validation schema accordingly. - Updated Prisma schema to include a new `ninja_user_id` field for user management. These changes improve the overall functionality, maintainability, and user experience of the application, particularly in user management and payment processing.
152 lines
3.8 KiB
TypeScript
152 lines
3.8 KiB
TypeScript
"use server";
|
|
|
|
import { authClient } from "@/lib/auth-client";
|
|
import prisma from "@/lib/db";
|
|
import { signUpFormSchema } from "@/lib/schemas";
|
|
import { headers } from "next/headers";
|
|
// import type { User } from "@prisma/client";
|
|
import { redirect } from "next/navigation";
|
|
import { z } from "zod";
|
|
const formSchema = z.object({
|
|
phoneNumber: z
|
|
.string()
|
|
.regex(/^[7|9][0-9]{2}-[0-9]{4}$/, "Please enter a valid phone number"),
|
|
});
|
|
|
|
export async function signin(previousState: ActionState, formData: FormData) {
|
|
const phoneNumber = formData.get("phoneNumber") as string;
|
|
const result = formSchema.safeParse({ phoneNumber });
|
|
console.log(phoneNumber);
|
|
|
|
if (!result.success) {
|
|
return {
|
|
message: result.error.errors[0].message, // Get the error message from Zod
|
|
status: "error",
|
|
};
|
|
}
|
|
|
|
if (!phoneNumber) {
|
|
return {
|
|
message: "Please enter a phone number",
|
|
status: "error",
|
|
};
|
|
}
|
|
const NUMBER_WITH_COUNTRY_CODE: string = `+960${phoneNumber.split("-").join("")}`;
|
|
|
|
const userExists = await prisma.user.findUnique({
|
|
where: {
|
|
phoneNumber: NUMBER_WITH_COUNTRY_CODE,
|
|
},
|
|
});
|
|
if (!userExists) {
|
|
return redirect(`/signup?phone_number=${phoneNumber}`);
|
|
}
|
|
await authClient.phoneNumber.sendOtp({
|
|
phoneNumber: NUMBER_WITH_COUNTRY_CODE,
|
|
});
|
|
redirect(
|
|
`/verify-otp?phone_number=${encodeURIComponent(NUMBER_WITH_COUNTRY_CODE)}`,
|
|
);
|
|
}
|
|
|
|
type ActionState = {
|
|
message: string;
|
|
payload?: FormData;
|
|
};
|
|
|
|
export async function signup(_actionState: ActionState, formData: FormData) {
|
|
const data = Object.fromEntries(formData.entries());
|
|
const parsedData = signUpFormSchema.safeParse(data);
|
|
// get phone number from /signup?phone_number=999-1231
|
|
const headersList = await headers();
|
|
const referer = headersList.get("referer");
|
|
const number = referer?.split("?")[1]?.split("=")[1];
|
|
let NUMBER_WITH_COUNTRY_CODE: string;
|
|
|
|
console.log(data);
|
|
|
|
if (!parsedData.success) {
|
|
return {
|
|
message: "Invalid form data",
|
|
payload: formData,
|
|
errors: parsedData.error.flatten(),
|
|
};
|
|
}
|
|
|
|
if (number) {
|
|
NUMBER_WITH_COUNTRY_CODE = `+960${number.split("-").join("")}`;
|
|
} else {
|
|
NUMBER_WITH_COUNTRY_CODE = `+960${parsedData.data.phone_number.split("-").join("")}`;
|
|
}
|
|
console.log({ NUMBER_WITH_COUNTRY_CODE });
|
|
const idCardExists = await prisma.user.findFirst({
|
|
where: {
|
|
id_card: parsedData.data.id_card,
|
|
},
|
|
});
|
|
|
|
if (idCardExists) {
|
|
return {
|
|
message: "ID card already exists.",
|
|
payload: formData,
|
|
db_error: "id_card",
|
|
};
|
|
}
|
|
|
|
const phoneNumberExists = await prisma.user.findFirst({
|
|
where: {
|
|
phoneNumber: NUMBER_WITH_COUNTRY_CODE,
|
|
},
|
|
});
|
|
|
|
if (phoneNumberExists) {
|
|
return {
|
|
message: "Phone number already exists.",
|
|
payload: formData,
|
|
db_error: "phone_number",
|
|
};
|
|
}
|
|
|
|
const newUser = await prisma.user.create({
|
|
data: {
|
|
name: parsedData.data.name,
|
|
islandId: parsedData.data.island_id,
|
|
atollId: parsedData.data.atoll_id,
|
|
address: parsedData.data.address,
|
|
id_card: parsedData.data.id_card,
|
|
dob: new Date(parsedData.data.dob),
|
|
role: "USER",
|
|
accNo: parsedData.data.accNo,
|
|
phoneNumber: NUMBER_WITH_COUNTRY_CODE,
|
|
},
|
|
});
|
|
await authClient.phoneNumber.sendOtp({
|
|
phoneNumber: newUser.phoneNumber,
|
|
});
|
|
redirect(
|
|
`/verify-otp?phone_number=${encodeURIComponent(newUser.phoneNumber)}`,
|
|
);
|
|
|
|
return { message: "Post created" };
|
|
}
|
|
|
|
export const sendOtp = async (phoneNumber: string, code: string) => {
|
|
// Implement sending OTP code via SMS
|
|
console.log("Send OTP server fn", phoneNumber, code);
|
|
const respose = await fetch(`${process.env.SMS_API_BASE_URL}/api/sms`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${process.env.SMS_API_KEY}`,
|
|
},
|
|
body: JSON.stringify({
|
|
check_delivery: false,
|
|
number: phoneNumber,
|
|
message: `Your OTP code is ${code}`,
|
|
}),
|
|
});
|
|
const data = await respose.json();
|
|
console.log(data);
|
|
return data;
|
|
};
|