Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/app/api/kyc/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const MESSAGES = {
* Interface for KYC request body structure
*/
interface KYCRequest {
userId: string;
nic: string;
recipient: string;
nicUrl: string;
Expand Down Expand Up @@ -53,6 +54,7 @@ export async function POST(req: NextRequest) {

// Validate required fields
const requiredFields: Array<keyof KYCRequest> = [
"userId",
"nic",
"recipient",
"nicUrl",
Expand All @@ -73,6 +75,7 @@ export async function POST(req: NextRequest) {

// Create new KYC record object using the data object
const newRecord = new KYC({
userId: data.userId,
nic: data.nic,
recipient: data.recipient,
dateSubmitted: new Date(),
Expand Down
63 changes: 44 additions & 19 deletions src/app/user/kyc/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import { useEffect, useState } from "react";
import { jwtDecode } from "jwt-decode";
import { useRouter } from "next/navigation";

import { useAuth } from "@/lib/context/AuthContext";

// API endpoint configuration for file uploads and KYC submission
const API_ENDPOINTS = {
Expand Down Expand Up @@ -120,6 +123,8 @@ const initialFormState: KYCFormState = {

export default function KYCForm() {
// State management hooks
const { user, isLoading ,token} = useAuth();
const router = useRouter();
const [fullName, setFullName] = useState("");
const [fullNameError, setFullNameError] = useState<string | null>(null);
const [nicError, setNicError] = useState<string | null>(null);
Expand All @@ -131,6 +136,43 @@ export default function KYCForm() {
} | null>(null);
const [formState, setFormState] = useState<KYCFormState>(initialFormState);

// 3) Your JWT-decode effect (unconditional)
useEffect(() => {
const token = localStorage.getItem("token");
if (token) {
try {
const decoded = jwtDecode<DecodedToken>(token);
const name = decoded.username || decoded.email || decoded.sub || "";
setFullName(name);
if (
name.trim().length >= 5 &&
name.includes(" ") &&
!FULLNAME_VALIDATION.PATTERN.test(name.trim())
) {
setFullNameError(MESSAGES.FULLNAME_FORMAT_ERROR);
}
} catch {
console.error("Invalid JWT");
}
}
}, []);

// 4) Your redirect-if-not-logged-in effect

useEffect(() => {
if (!isLoading && !user) {
// not logged in → go to login
router.replace("/login");
}
}, [isLoading, user, router]);
if (isLoading || !user) {
return (
<div className="flex items-center justify-center min-h-screen">
<span>Loading...</span>
</div>
);
}

// Helper function to update specific form field
const updateField = <K extends keyof KYCFormState>(
field: K,
Expand Down Expand Up @@ -159,26 +201,7 @@ export default function KYCForm() {
const validateFullName = (fullNameValue: string): boolean => {
return FULLNAME_VALIDATION.PATTERN.test(fullNameValue);
};
// Extract full name from JWT token on component mount
useEffect(() => {
const token = localStorage.getItem("token");
if (token) {
try {
const decoded = jwtDecode<DecodedToken>(token);
const name = decoded.username || decoded.email || decoded.sub || "";
setFullName(name);

// Only validate if the name from token looks complete
if (name && name.trim().length >= 5 && name.includes(" ")) {
if (!validateFullName(name.trim())) {
setFullNameError(MESSAGES.FULLNAME_FORMAT_ERROR);
}
}
} catch (err) {
console.error("Invalid JWT", err);
}
}
}, []);
// Validate file size and type
const validateFile = (file: File): string | null => {
if (file.size > FILE_CONSTRAINTS.MAX_SIZE_BYTES) {
Expand Down Expand Up @@ -389,8 +412,10 @@ export default function KYCForm() {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
},
body: JSON.stringify({
userId: user!._id,
nic: formState.nic,
recipient: fullName,
nicUrl: nicUploadData.url,
Expand Down
Loading