mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-10-07 11:11:37 +00:00
chore: add skeletons to tables and loading.tsx files for routes and run formatting ♻️
All checks were successful
Build and Push Docker Images / Build and Push Docker Images (push) Successful in 12m20s
All checks were successful
Build and Push Docker Images / Build and Push Docker Images (push) Successful in 12m20s
This commit is contained in:
@@ -4,226 +4,226 @@ import { redirect } from "next/navigation";
|
||||
import { z } from "zod";
|
||||
import { signUpFormSchema } from "@/lib/schemas";
|
||||
import {
|
||||
backendRegister,
|
||||
checkIdOrPhone,
|
||||
checkTempIdOrPhone,
|
||||
backendRegister,
|
||||
checkIdOrPhone,
|
||||
checkTempIdOrPhone,
|
||||
} from "@/queries/authentication";
|
||||
import { handleApiResponse, tryCatch } from "@/utils/tryCatch";
|
||||
|
||||
const formSchema = z.object({
|
||||
phoneNumber: z
|
||||
.string()
|
||||
.regex(/^[7|9][0-9]{2}-[0-9]{4}$/, "Please enter a valid phone number"),
|
||||
phoneNumber: z
|
||||
.string()
|
||||
.regex(/^[7|9][0-9]{2}-[0-9]{4}$/, "Please enter a valid phone number"),
|
||||
});
|
||||
|
||||
export type FilterUserResponse = {
|
||||
ok: boolean;
|
||||
verified: boolean;
|
||||
ok: boolean;
|
||||
verified: boolean;
|
||||
};
|
||||
export type FilterTempUserResponse = {
|
||||
ok: boolean;
|
||||
otp_verified: boolean;
|
||||
t_verified: boolean;
|
||||
ok: boolean;
|
||||
otp_verified: boolean;
|
||||
t_verified: boolean;
|
||||
};
|
||||
|
||||
export async function signin(_previousState: ActionState, formData: FormData) {
|
||||
const phoneNumber = formData.get("phoneNumber") as string;
|
||||
const result = formSchema.safeParse({ phoneNumber });
|
||||
console.log(phoneNumber);
|
||||
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 (!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 FORMATTED_MOBILE_NUMBER: string = `${phoneNumber.split("-").join("")}`;
|
||||
console.log({ FORMATTED_MOBILE_NUMBER });
|
||||
if (!phoneNumber) {
|
||||
return {
|
||||
message: "Please enter a phone number",
|
||||
status: "error",
|
||||
};
|
||||
}
|
||||
const FORMATTED_MOBILE_NUMBER: string = `${phoneNumber.split("-").join("")}`;
|
||||
console.log({ FORMATTED_MOBILE_NUMBER });
|
||||
|
||||
const user = await fetch(
|
||||
`${process.env.SARLINK_API_BASE_URL}/api/auth/users/filter/?mobile=${FORMATTED_MOBILE_NUMBER}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
const userData = (await user.json()) as FilterUserResponse;
|
||||
console.log({ userData });
|
||||
if (!userData.ok) {
|
||||
redirect(`/auth/signup?phone_number=${phoneNumber}`);
|
||||
}
|
||||
if (!userData.verified) {
|
||||
return {
|
||||
message:
|
||||
"Your account is on pending verification. Please wait for a response from admin or contact shihaam.",
|
||||
status: "error",
|
||||
};
|
||||
}
|
||||
const user = await fetch(
|
||||
`${process.env.SARLINK_API_BASE_URL}/api/auth/users/filter/?mobile=${FORMATTED_MOBILE_NUMBER}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
const userData = (await user.json()) as FilterUserResponse;
|
||||
console.log({ userData });
|
||||
if (!userData.ok) {
|
||||
redirect(`/auth/signup?phone_number=${phoneNumber}`);
|
||||
}
|
||||
if (!userData.verified) {
|
||||
return {
|
||||
message:
|
||||
"Your account is on pending verification. Please wait for a response from admin or contact shihaam.",
|
||||
status: "error",
|
||||
};
|
||||
}
|
||||
|
||||
const sendOTPResponse = await fetch(
|
||||
`${process.env.SARLINK_API_BASE_URL}/auth/mobile/`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
mobile: FORMATTED_MOBILE_NUMBER,
|
||||
}),
|
||||
},
|
||||
);
|
||||
const otpResponse = await sendOTPResponse.json();
|
||||
console.log("otpResponse", otpResponse);
|
||||
const sendOTPResponse = await fetch(
|
||||
`${process.env.SARLINK_API_BASE_URL}/auth/mobile/`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
mobile: FORMATTED_MOBILE_NUMBER,
|
||||
}),
|
||||
},
|
||||
);
|
||||
const otpResponse = await sendOTPResponse.json();
|
||||
console.log("otpResponse", otpResponse);
|
||||
|
||||
redirect(`/auth/verify-otp?phone_number=${FORMATTED_MOBILE_NUMBER}`);
|
||||
redirect(`/auth/verify-otp?phone_number=${FORMATTED_MOBILE_NUMBER}`);
|
||||
}
|
||||
|
||||
export type ActionState = {
|
||||
status?: string;
|
||||
payload?: FormData;
|
||||
errors?: z.typeToFlattenedError<
|
||||
{
|
||||
id_card: string;
|
||||
phone_number: string;
|
||||
name: string;
|
||||
atoll_id: string;
|
||||
island_id: string;
|
||||
address: string;
|
||||
dob: Date;
|
||||
terms: string;
|
||||
policy: string;
|
||||
accNo: string;
|
||||
},
|
||||
string
|
||||
>;
|
||||
db_error?: string;
|
||||
error?: string;
|
||||
status?: string;
|
||||
payload?: FormData;
|
||||
errors?: z.typeToFlattenedError<
|
||||
{
|
||||
id_card: string;
|
||||
phone_number: string;
|
||||
name: string;
|
||||
atoll_id: string;
|
||||
island_id: string;
|
||||
address: string;
|
||||
dob: Date;
|
||||
terms: string;
|
||||
policy: string;
|
||||
accNo: string;
|
||||
},
|
||||
string
|
||||
>;
|
||||
db_error?: string;
|
||||
error?: string;
|
||||
};
|
||||
|
||||
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 data = Object.fromEntries(formData.entries());
|
||||
const parsedData = signUpFormSchema.safeParse(data);
|
||||
// get phone number from /signup?phone_number=999-1231
|
||||
|
||||
console.log("DATA ON SERVER SIDE", data);
|
||||
console.log("DATA ON SERVER SIDE", data);
|
||||
|
||||
if (!parsedData.success) {
|
||||
return {
|
||||
message: "Invalid form data",
|
||||
payload: formData,
|
||||
errors: parsedData.error.flatten(),
|
||||
};
|
||||
}
|
||||
const age =
|
||||
new Date().getFullYear() - new Date(parsedData.data.dob).getFullYear();
|
||||
if (age < 18) {
|
||||
return {
|
||||
message: "You must be at least 18 years old to register.",
|
||||
payload: formData,
|
||||
db_error: "dob",
|
||||
};
|
||||
}
|
||||
if (!parsedData.success) {
|
||||
return {
|
||||
message: "Invalid form data",
|
||||
payload: formData,
|
||||
errors: parsedData.error.flatten(),
|
||||
};
|
||||
}
|
||||
const age =
|
||||
new Date().getFullYear() - new Date(parsedData.data.dob).getFullYear();
|
||||
if (age < 18) {
|
||||
return {
|
||||
message: "You must be at least 18 years old to register.",
|
||||
payload: formData,
|
||||
db_error: "dob",
|
||||
};
|
||||
}
|
||||
|
||||
const idCardExists = await checkIdOrPhone({
|
||||
id_card: parsedData.data.id_card,
|
||||
});
|
||||
if (idCardExists.ok) {
|
||||
return {
|
||||
message: "ID card already exists.",
|
||||
payload: formData,
|
||||
db_error: "id_card",
|
||||
};
|
||||
}
|
||||
const idCardExists = await checkIdOrPhone({
|
||||
id_card: parsedData.data.id_card,
|
||||
});
|
||||
if (idCardExists.ok) {
|
||||
return {
|
||||
message: "ID card already exists.",
|
||||
payload: formData,
|
||||
db_error: "id_card",
|
||||
};
|
||||
}
|
||||
|
||||
const phoneNumberExists = await checkIdOrPhone({
|
||||
phone_number: parsedData.data.phone_number,
|
||||
});
|
||||
const phoneNumberExists = await checkIdOrPhone({
|
||||
phone_number: parsedData.data.phone_number,
|
||||
});
|
||||
|
||||
const tempPhoneNumberExists = await checkTempIdOrPhone({
|
||||
phone_number: parsedData.data.phone_number,
|
||||
});
|
||||
if (phoneNumberExists.ok || tempPhoneNumberExists.ok) {
|
||||
return {
|
||||
message: "Phone number already exists.",
|
||||
payload: formData,
|
||||
db_error: "phone_number",
|
||||
};
|
||||
}
|
||||
const tempPhoneNumberExists = await checkTempIdOrPhone({
|
||||
phone_number: parsedData.data.phone_number,
|
||||
});
|
||||
if (phoneNumberExists.ok || tempPhoneNumberExists.ok) {
|
||||
return {
|
||||
message: "Phone number already exists.",
|
||||
payload: formData,
|
||||
db_error: "phone_number",
|
||||
};
|
||||
}
|
||||
|
||||
const [signupError, signupResponse] = await tryCatch(
|
||||
backendRegister({
|
||||
payload: {
|
||||
firstname: parsedData.data.name.split(" ")[0],
|
||||
lastname: parsedData.data.name.split(" ").slice(1).join(" "),
|
||||
username: parsedData.data.phone_number,
|
||||
address: parsedData.data.address,
|
||||
id_card: parsedData.data.id_card,
|
||||
dob: new Date(parsedData.data.dob).toISOString().split("T")[0],
|
||||
mobile: parsedData.data.phone_number,
|
||||
island: Number.parseInt(parsedData.data.island_id),
|
||||
atoll: Number.parseInt(parsedData.data.atoll_id),
|
||||
acc_no: parsedData.data.accNo,
|
||||
terms_accepted: parsedData.data.terms,
|
||||
policy_accepted: parsedData.data.policy,
|
||||
},
|
||||
}),
|
||||
);
|
||||
if (signupError) {
|
||||
return {
|
||||
message: signupError.message,
|
||||
payload: formData,
|
||||
db_error: "phone_number",
|
||||
};
|
||||
}
|
||||
console.log("SIGNUP RESPONSE", signupResponse);
|
||||
const [signupError, signupResponse] = await tryCatch(
|
||||
backendRegister({
|
||||
payload: {
|
||||
firstname: parsedData.data.name.split(" ")[0],
|
||||
lastname: parsedData.data.name.split(" ").slice(1).join(" "),
|
||||
username: parsedData.data.phone_number,
|
||||
address: parsedData.data.address,
|
||||
id_card: parsedData.data.id_card,
|
||||
dob: new Date(parsedData.data.dob).toISOString().split("T")[0],
|
||||
mobile: parsedData.data.phone_number,
|
||||
island: Number.parseInt(parsedData.data.island_id),
|
||||
atoll: Number.parseInt(parsedData.data.atoll_id),
|
||||
acc_no: parsedData.data.accNo,
|
||||
terms_accepted: parsedData.data.terms,
|
||||
policy_accepted: parsedData.data.policy,
|
||||
},
|
||||
}),
|
||||
);
|
||||
if (signupError) {
|
||||
return {
|
||||
message: signupError.message,
|
||||
payload: formData,
|
||||
db_error: "phone_number",
|
||||
};
|
||||
}
|
||||
console.log("SIGNUP RESPONSE", signupResponse);
|
||||
|
||||
redirect(
|
||||
`/auth/verify-otp-registration?phone_number=${encodeURIComponent(signupResponse.t_username)}`,
|
||||
);
|
||||
return { message: "User created successfully", error: "success" };
|
||||
redirect(
|
||||
`/auth/verify-otp-registration?phone_number=${encodeURIComponent(signupResponse.t_username)}`,
|
||||
);
|
||||
return { message: "User created successfully", error: "success" };
|
||||
}
|
||||
|
||||
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;
|
||||
// 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;
|
||||
};
|
||||
|
||||
export async function backendMobileLogin({ mobile }: { mobile: string }) {
|
||||
const response = await fetch(
|
||||
`${process.env.SARLINK_API_BASE_URL}/auth/mobile/`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
mobile,
|
||||
}),
|
||||
},
|
||||
);
|
||||
return handleApiResponse<{ detail: string }>(response, "backendMobileLogin");
|
||||
const response = await fetch(
|
||||
`${process.env.SARLINK_API_BASE_URL}/auth/mobile/`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
mobile,
|
||||
}),
|
||||
},
|
||||
);
|
||||
return handleApiResponse<{ detail: string }>(response, "backendMobileLogin");
|
||||
}
|
||||
|
Reference in New Issue
Block a user