feat: Add agent network feature with invitation cards and sidebar, and revamp agent edit availability UI to include office hours and contact methods.

This commit is contained in:
pradeepkumar
2026-01-18 23:13:56 +05:30
parent 7d5de4aa93
commit 74fe46335f
2 changed files with 104 additions and 35 deletions

View File

@@ -8,13 +8,19 @@ interface FormCheckboxProps {
export function FormCheckbox({ label, checked, onChange }: FormCheckboxProps) { export function FormCheckbox({ label, checked, onChange }: FormCheckboxProps) {
return ( return (
<label className="flex items-center gap-2 cursor-pointer"> <label className="flex items-center gap-3 cursor-pointer">
<input <div
type="checkbox" onClick={() => onChange(!checked)}
checked={checked} className={`w-[22px] h-[22px] rounded-[5px] border border-[#00293D]/20 flex items-center justify-center transition-colors ${
onChange={(e) => onChange(e.target.checked)} checked ? 'bg-[#E58625] border-[#E58625]' : 'bg-white'
className="w-4 h-4 rounded border-[#00293D]/30 text-[#E58625] focus:ring-[#E58625] focus:ring-offset-0 accent-[#E58625]" }`}
/> >
{checked && (
<svg width="12" height="10" viewBox="0 0 12 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 5L4.5 8.5L11 1" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
)}
</div>
<span className="text-[14px] font-serif text-[#00293D]">{label}</span> <span className="text-[14px] font-serif text-[#00293D]">{label}</span>
</label> </label>
); );

View File

@@ -100,8 +100,11 @@ const initialFormData = {
{ name: 'Certified Residential Specialist (CRS)', org: 'Residential Real Estate Council' }, { name: 'Certified Residential Specialist (CRS)', org: 'Residential Real Estate Council' },
], ],
availability: { availability: {
type: 'Full Time Weekend', officeHours: ['MON-FRI 8am-6pm', 'Sat 10am-2pm'],
workFrom: 'Work from Method', contactMethod: {
email: true,
call: false,
},
}, },
}; };
@@ -110,6 +113,7 @@ export default function EditProfilePage() {
const [formData, setFormData] = useState(initialFormData); const [formData, setFormData] = useState(initialFormData);
const scrollContainerRef = useRef<HTMLDivElement>(null); const scrollContainerRef = useRef<HTMLDivElement>(null);
const [stateInput, setStateInput] = useState(''); const [stateInput, setStateInput] = useState('');
const [officeHoursInput, setOfficeHoursInput] = useState('');
const handleCancel = () => { const handleCancel = () => {
router.push('/agent/dashboard'); router.push('/agent/dashboard');
@@ -140,6 +144,31 @@ export default function EditProfilePage() {
} }
}; };
const handleAddOfficeHours = (value: string) => {
const trimmedValue = value.trim();
if (trimmedValue && !formData.availability.officeHours.includes(trimmedValue)) {
updateField('availability', {
...formData.availability,
officeHours: [...formData.availability.officeHours, trimmedValue],
});
}
setOfficeHoursInput('');
};
const handleOfficeHoursKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter' || e.key === ',') {
e.preventDefault();
handleAddOfficeHours(officeHoursInput);
}
};
const handleRemoveOfficeHours = (hour: string) => {
updateField('availability', {
...formData.availability,
officeHours: formData.availability.officeHours.filter((h) => h !== hour),
});
};
return ( return (
<div className="flex gap-6 h-[calc(100vh-180px)]"> <div className="flex gap-6 h-[calc(100vh-180px)]">
{/* Left Sidebar - Quick Links */} {/* Left Sidebar - Quick Links */}
@@ -596,32 +625,66 @@ export default function EditProfilePage() {
{/* Availability */} {/* Availability */}
<div className="bg-white rounded-[15px] border border-[#00293D]/20 shadow-[0px_10px_20px_#D9D9D9] p-6"> <div className="bg-white rounded-[15px] border border-[#00293D]/20 shadow-[0px_10px_20px_#D9D9D9] p-6">
<FormSection id="availability" icon="/assets/icons/availability-clock-icon.svg" title="Availability"> <FormSection id="availability" icon="/assets/icons/availability-clock-icon.svg" title="Availability">
<div className="flex flex-col md:flex-row gap-4"> <div className="flex flex-col lg:flex-row gap-6">
<FormSelect {/* Typical Office Hours */}
label="Availability" <div className="flex-1">
value={formData.availability.type} <label className="block text-[14px] font-semibold text-[#00293D] font-serif mb-2">
onChange={(value) => Typical Office Hours
updateField('availability', { ...formData.availability, type: value }) </label>
} <div className="flex items-center gap-2 h-[40px] px-4 border border-[#00293D]/20 rounded-[15px]">
options={[ {formData.availability.officeHours.map((hour) => (
{ value: 'Full Time Weekend', label: 'Full Time Weekend' }, <span
{ value: 'Part Time', label: 'Part Time' }, key={hour}
{ value: 'Weekdays Only', label: 'Weekdays Only' }, className="inline-flex items-center gap-1 text-[14px] font-semibold font-serif text-[#00293D]"
]} >
{hour}
<button
onClick={() => handleRemoveOfficeHours(hour)}
className="text-[#00293d]/50 hover:text-[#E58625] transition-colors ml-1"
>
×
</button>
</span>
))}
<input
type="text"
value={officeHoursInput}
onChange={(e) => setOfficeHoursInput(e.target.value)}
onKeyDown={handleOfficeHoursKeyDown}
placeholder={formData.availability.officeHours.length === 0 ? "Add office hours" : ""}
className="flex-1 h-full text-[14px] font-serif text-[#00293D] placeholder:text-[#00293D]/40 focus:outline-none bg-transparent"
/> />
<FormSelect </div>
label="Work From Method" </div>
value={formData.availability.workFrom}
onChange={(value) => {/* Preferred Contact Method */}
updateField('availability', { ...formData.availability, workFrom: value }) <div className="lg:w-[250px]">
<label className="block text-[14px] font-semibold text-[#00293D] font-serif mb-2">
Preferred Contact Method
</label>
<div className="flex items-center gap-6 h-[40px]">
<FormCheckbox
label="Email"
checked={formData.availability.contactMethod.email}
onChange={(checked) =>
updateField('availability', {
...formData.availability,
contactMethod: { ...formData.availability.contactMethod, email: checked },
})
} }
options={[
{ value: 'Work from Method', label: 'Work from Method' },
{ value: 'Remote', label: 'Remote' },
{ value: 'In Office', label: 'In Office' },
{ value: 'Hybrid', label: 'Hybrid' },
]}
/> />
<FormCheckbox
label="Call"
checked={formData.availability.contactMethod.call}
onChange={(checked) =>
updateField('availability', {
...formData.availability,
contactMethod: { ...formData.availability.contactMethod, call: checked },
})
}
/>
</div>
</div>
</div> </div>
</FormSection> </FormSection>
</div> </div>