This commit is contained in:
pradeepkumar
2026-01-24 23:10:02 +05:30
parent b940e77a67
commit 39af9bc59d
8 changed files with 496 additions and 103 deletions

View File

@@ -15,8 +15,9 @@ import {
ContactInfo,
PhotoUploadModal,
} from '@/components/profile';
import { agentsService, AgentProfile } from '@/services/agents.service';
import { agentsService, AgentProfile, FieldValueResponse } from '@/services/agents.service';
import { uploadService } from '@/services/upload.service';
import { mapFieldValuesToExperience, ExperienceData } from '@/utils/profileDataMapper';
// Mock data for sections not yet available from API
const mockData = {
@@ -73,24 +74,68 @@ const mockData = {
],
};
// Default experience data when no field values are available
const defaultExperience: ExperienceData = {
years: '-',
contracts: '-',
licensingAreas: [],
expertiseYears: [],
certifications: [],
};
export default function AgentDashboard() {
const { data: session } = useSession();
const [agentProfile, setAgentProfile] = useState<AgentProfile | null>(null);
const [fieldValues, setFieldValues] = useState<FieldValueResponse[]>([]);
const [experienceData, setExperienceData] = useState<ExperienceData>(defaultExperience);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [isPhotoModalOpen, setIsPhotoModalOpen] = useState(false);
const [imageError, setImageError] = useState(false);
const [avatarUrl, setAvatarUrl] = useState<string | null>(null);
const defaultImage = '/assets/demo_images/8f017153a7b4a239a4f0691234ef97dd55092282.jpg';
// Fetch agent profile on mount
// Helper to check if avatar is an S3 key (not a full URL or local path)
const isS3Key = (avatar: string | null | undefined): boolean => {
if (!avatar) return false;
// S3 keys don't start with http or /
return !avatar.startsWith('http') && !avatar.startsWith('/');
};
// Fetch agent profile and field values on mount
useEffect(() => {
const fetchProfile = async () => {
const fetchData = async () => {
try {
setLoading(true);
setError(null);
const profile = await agentsService.getMyProfile();
// Fetch profile and field values in parallel
const [profile, fieldValuesResponse] = await Promise.all([
agentsService.getMyProfile(),
agentsService.getFieldValues(),
]);
setAgentProfile(profile);
setFieldValues(fieldValuesResponse.fieldValues);
// Map field values to experience data structure
const mappedExperience = mapFieldValuesToExperience(fieldValuesResponse.fieldValues);
setExperienceData(mappedExperience);
// If avatar is an S3 key, fetch presigned URL
if (profile.avatar && isS3Key(profile.avatar)) {
try {
const presignedUrl = await uploadService.getPresignedDownloadUrl(profile.avatar);
setAvatarUrl(presignedUrl);
} catch (avatarErr) {
console.error('Failed to get avatar URL:', avatarErr);
// Don't fail the whole page, just use default image
}
} else if (profile.avatar) {
// It's already a full URL or local path
setAvatarUrl(profile.avatar);
}
} catch (err) {
console.error('Failed to fetch profile:', err);
setError('Failed to load profile data');
@@ -99,17 +144,27 @@ export default function AgentDashboard() {
}
};
fetchProfile();
fetchData();
}, []);
const handlePhotoUpload = async (file: File) => {
// Upload avatar to S3 (uses agent ID as filename for auto-replacement)
const uploadedFile = await uploadService.uploadAvatar(file);
// Update agent profile with the S3 URL
// Update agent profile with the S3 key
const updatedProfile = await agentsService.updateProfile({ avatar: uploadedFile.url });
setImageError(false); // Reset error state for new image
setAgentProfile(updatedProfile);
// Fetch new presigned URL for the uploaded avatar
if (uploadedFile.url && isS3Key(uploadedFile.url)) {
try {
const presignedUrl = await uploadService.getPresignedDownloadUrl(uploadedFile.url);
setAvatarUrl(presignedUrl);
} catch (err) {
console.error('Failed to get presigned URL for new avatar:', err);
}
}
};
const getProfileImageUrl = () => {
@@ -118,18 +173,23 @@ export default function AgentDashboard() {
return defaultImage;
}
// If we have a presigned URL from S3, use it
if (avatarUrl) {
return avatarUrl;
}
// Check for null, undefined, or empty string
if (!agentProfile?.avatar || agentProfile.avatar.trim() === '') {
return defaultImage;
}
// S3 URLs are full URLs starting with http
if (agentProfile.avatar.startsWith('http')) {
// For relative paths (local assets), return as-is
if (agentProfile.avatar.startsWith('/')) {
return agentProfile.avatar;
}
// For relative paths (local assets), return as-is
return agentProfile.avatar;
// Default fallback
return defaultImage;
};
if (loading) {
@@ -240,8 +300,8 @@ export default function AgentDashboard() {
requestsHref="/agent/network"
/>
{/* Experience Section */}
<ExperienceSection experience={mockData.experience} />
{/* Experience Section - Dynamic data from profile fields */}
<ExperienceSection experience={experienceData} />
{/* Info Cards Section */}
<div className="flex flex-col lg:grid lg:grid-cols-3 gap-6">
@@ -306,6 +366,7 @@ export default function AgentDashboard() {
onClose={() => setIsPhotoModalOpen(false)}
onUpload={handlePhotoUpload}
currentPhoto={agentProfile.avatar}
currentPhotoUrl={avatarUrl}
/>
</div>
);