Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
forbidals
/
student_panel
/
src
/
components
/
ui
/
pages
/
dashboard
:
MyProfile.tsx
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
'use client'; import React from 'react'; import { useSelector } from 'react-redux'; import { RootState } from '@/components/store'; import { useGetStudentProfile } from '@/lib/api/student/queryHooks'; import { StudentProfileData } from '@/lib/api/student/functions'; import Image from 'next/image'; import { useTranslate } from '@/components/hooks/useTranslate'; // Type for extra field items type ExtraFieldItem = NonNullable<StudentProfileData['extra_details']>[number]; export default function MyProfile() { const translate = useTranslate(); // Get school code from Redux store const schoolCode = useSelector( (state: RootState) => state.studentAuth.schoolCode ); // Fetch profile data using the API hook const { data, isLoading, isError, error } = useGetStudentProfile(schoolCode); // Show loading state while fetching data if (isLoading) { return ( <div className="bg-white rounded-[12px] border border-gray-200 p-8 flex items-center justify-center"> <div className="text-gray-500 text-center"> <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div> <p>{translate('loadingProfileData')}</p> </div> </div> ); } // Show error state if API call failed if (isError) { return ( <div className="bg-white rounded-[12px] border border-gray-200 p-8"> <div className="text-red-500 text-center"> <p className="text-lg font-semibold mb-2"> {translate('failedToLoadProfileData')} </p> <p className="text-sm text-gray-600"> {error instanceof Error ? error.message : translate('unknownErrorOccurred')} </p> </div> </div> ); } // If no data is available if (!data?.data) { return ( <div className="bg-white rounded-[12px] border border-gray-200 p-8"> <div className="text-gray-500 text-center"> <p>{translate('noProfileDataAvailable')}</p> </div> </div> ); } // Extract profile data from API response const profile = data.data; const fullName = `${profile.first_name} ${profile.last_name}`; const className = profile.class_section?.full_name || 'N/A'; const mediumName = profile.class_section?.medium?.name || 'N/A'; const schoolName = `${profile.school.name} (${profile.school.code})`; // Split extra fields into left and right columns const extraFields = profile.extra_details || []; const midPoint = Math.ceil(extraFields.length / 2); const leftExtraFields = extraFields.slice(0, midPoint); const rightExtraFields = extraFields.slice(midPoint); return ( <div className="bg-white rounded-[12px] border border-gray-200"> {/* Profile Header Section */} <div className="bg-[#F2F5F7] p-3 sm:p-4 m-2 sm:m-4 rounded-[12px]"> <div className="flex flex-col sm:flex-row items-center space-y-4 sm:space-y-0 sm:space-x-6"> {/* Profile Image */} <div className="flex-shrink-0 border border-gray-200 rounded-[4px] p-2"> {profile.image ? ( <Image src={profile.image} alt={fullName} width={128} height={128} className="w-24 h-24 sm:w-32 sm:h-32 rounded-[4px] object-cover" /> ) : ( <div className="w-24 h-24 sm:w-32 sm:h-32 bg-gray-300 rounded-[4px] flex items-center justify-center"> <div className="text-gray-500 text-xs sm:text-sm text-center"> {translate('profileImage') .split(' ') .map((word, i, arr) => ( <React.Fragment key={i}> {word} {i < arr.length - 1 && <br />} </React.Fragment> ))} </div> </div> )} </div> {/* Profile Name */} <div className="flex-1 text-center sm:text-left flex items-center"> <h1 className="text-xl sm:text-2xl font-bold text-gray-900"> {fullName} </h1> </div> </div> </div> {/* Profile Details Section */} <div className="p-4 sm:p-6"> {/* Two-column layout for profile details */} <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 sm:gap-6"> {/* Left Column */} <div className="space-y-3 sm:space-y-4"> <div className="flex flex-col space-y-1"> <label className="text-sm sm:text-base font-normal text-gray-500"> {translate('grNumber')} </label> <span className="text-sm sm:text-base text-gray-900 font-normal"> {profile.admission_no || 'N/A'} </span> </div> <div className="flex flex-col space-y-1"> <label className="text-sm sm:text-base font-normal text-gray-500"> {translate('class')} </label> <span className="text-sm sm:text-base text-gray-900 font-normal"> {className} </span> </div> <div className="flex flex-col space-y-1"> <label className="text-sm sm:text-base font-normal text-gray-500"> {translate('rollNumber')} </label> <span className="text-sm sm:text-base text-gray-900 font-normal"> {profile.roll_number || 'N/A'} </span> </div> <div className="flex flex-col space-y-1"> <label className="text-sm sm:text-base font-normal text-gray-500"> {translate('currentAddress')} </label> <span className="text-sm sm:text-base text-gray-900 font-normal"> {profile.current_address || 'N/A'} </span> </div> <div className="flex flex-col space-y-1"> <label className="text-sm sm:text-base font-normal text-gray-500"> {translate('gender')} </label> <span className="text-sm sm:text-base text-gray-900 font-normal"> {profile.gender || 'N/A'} </span> </div> {/* Display left column extra fields */} {leftExtraFields.map((field: ExtraFieldItem) => ( <div key={field.id} className="flex flex-col space-y-1"> <label className="text-sm sm:text-base font-normal text-gray-500"> {field.form_field.name} </label> {field.file_url ? ( <a href={field.file_url} target="_blank" rel="noopener noreferrer" className="text-sm sm:text-base text-black hover:underline font-normal break-all" > {field.file_url} </a> ) : ( <span className="text-sm sm:text-base text-gray-900 font-normal" dangerouslySetInnerHTML={{ __html: field.data || 'N/A', }} /> )} </div> ))} </div> {/* Right Column */} <div className="space-y-3 sm:space-y-4"> <div className="flex flex-col space-y-1"> <label className="text-sm sm:text-base font-normal text-gray-500"> {translate('school')} </label> <span className="text-sm sm:text-base text-gray-900 font-normal"> {schoolName} </span> </div> <div className="flex flex-col space-y-1"> <label className="text-sm sm:text-base font-normal text-gray-500"> {translate('medium')} </label> <span className="text-sm sm:text-base text-gray-900 font-normal"> {mediumName} </span> </div> <div className="flex flex-col space-y-1"> <label className="text-sm sm:text-base font-normal text-gray-500"> {translate('dateOfBirth')} </label> <span className="text-sm sm:text-base text-gray-900 font-normal"> {profile.dob} </span> </div> <div className="flex flex-col space-y-1"> <label className="text-sm sm:text-base font-normal text-gray-500"> {translate('permanentAddress')} </label> <span className="text-sm sm:text-base text-gray-900 font-normal"> {profile.permanent_address || 'N/A'} </span> </div> {/* Display right column extra fields */} {rightExtraFields.map((field: ExtraFieldItem) => ( <div key={field.id} className="flex flex-col space-y-1"> <label className="text-sm sm:text-base font-normal text-gray-500"> {field.form_field.name} </label> {field.file_url ? ( <a href={field.file_url} target="_blank" rel="noopener noreferrer" className="text-sm sm:text-base text-black hover:underline font-normal break-all" > {field.file_url} </a> ) : ( <span className="text-sm sm:text-base text-gray-900 font-normal" dangerouslySetInnerHTML={{ __html: field.data || 'N/A', }} /> )} </div> ))} </div> </div> </div> </div> ); }