feat: Implement authentication checks for profile actions and user layout, and add presigned URL fetching for file viewing.
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { signIn } from 'next-auth/react';
|
||||
import Link from 'next/link';
|
||||
import { authService, AuthService, RegisterRequest } from '@/services';
|
||||
import { authService, AuthService, RegisterRequest, agentsService, AgentType } from '@/services';
|
||||
|
||||
type UserType = 'USER' | 'AGENT';
|
||||
|
||||
@@ -23,6 +23,25 @@ export default function SignUpPage() {
|
||||
const [fieldErrors, setFieldErrors] = useState<ValidationError[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [registrationSuccess, setRegistrationSuccess] = useState(false);
|
||||
const [agentTypes, setAgentTypes] = useState<AgentType[]>([]);
|
||||
const [selectedAgentTypeId, setSelectedAgentTypeId] = useState('');
|
||||
const [loadingAgentTypes, setLoadingAgentTypes] = useState(false);
|
||||
|
||||
// Fetch agent types on mount
|
||||
useEffect(() => {
|
||||
const fetchAgentTypes = async () => {
|
||||
setLoadingAgentTypes(true);
|
||||
try {
|
||||
const types = await agentsService.getAgentTypes();
|
||||
setAgentTypes(types);
|
||||
} catch (err) {
|
||||
console.error('Failed to fetch agent types:', err);
|
||||
} finally {
|
||||
setLoadingAgentTypes(false);
|
||||
}
|
||||
};
|
||||
fetchAgentTypes();
|
||||
}, []);
|
||||
|
||||
const getFieldError = (fieldName: string): string | null => {
|
||||
const fieldError = fieldErrors.find((e) => e.field === fieldName);
|
||||
@@ -35,6 +54,13 @@ export default function SignUpPage() {
|
||||
setError('');
|
||||
setFieldErrors([]);
|
||||
|
||||
// Validate agent type if registering as agent
|
||||
if (userType === 'AGENT' && !selectedAgentTypeId) {
|
||||
setError('Please select an agent type');
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const registerData: RegisterRequest = {
|
||||
firstName,
|
||||
@@ -42,6 +68,7 @@ export default function SignUpPage() {
|
||||
email,
|
||||
password,
|
||||
role: userType,
|
||||
...(userType === 'AGENT' && selectedAgentTypeId && { agentTypeId: selectedAgentTypeId }),
|
||||
};
|
||||
|
||||
await authService.register(registerData);
|
||||
@@ -228,6 +255,37 @@ export default function SignUpPage() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Agent Type Selection - Only for Agents */}
|
||||
{userType === 'AGENT' && (
|
||||
<div>
|
||||
<select
|
||||
value={selectedAgentTypeId}
|
||||
onChange={(e) => setSelectedAgentTypeId(e.target.value)}
|
||||
required
|
||||
disabled={loadingAgentTypes}
|
||||
className={`w-full px-6 py-6 bg-[#f0f5fc] rounded-[20px] text-[#00293d] text-sm font-light focus:outline-none focus:ring-2 focus:ring-[#00293d]/20 transition-all appearance-none cursor-pointer ${
|
||||
!selectedAgentTypeId ? 'text-[#00293d]/60' : ''
|
||||
} ${getFieldError('agentTypeId') ? 'ring-2 ring-red-400' : ''}`}
|
||||
style={{
|
||||
backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%2300293d'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M19 9l-7 7-7-7'/%3E%3C/svg%3E")`,
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundPosition: 'right 1.5rem center',
|
||||
backgroundSize: '1.25rem',
|
||||
}}
|
||||
>
|
||||
<option value="">Select Agent Type</option>
|
||||
{agentTypes.map((type) => (
|
||||
<option key={type.id} value={type.id}>
|
||||
{type.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{getFieldError('agentTypeId') && (
|
||||
<p className="text-red-500 text-xs mt-1 ml-2">{getFieldError('agentTypeId')}</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Sign Up Button */}
|
||||
<button
|
||||
type="submit"
|
||||
|
||||
Reference in New Issue
Block a user