responsive new lead forms
This commit is contained in:
@@ -198,7 +198,7 @@ export default function LeadPropertySection({ formData, updateField, isQuickCapt
|
|||||||
|
|
||||||
{/* Photo thumbnails */}
|
{/* Photo thumbnails */}
|
||||||
{(formData.propertyPhotos || []).length > 0 && (
|
{(formData.propertyPhotos || []).length > 0 && (
|
||||||
<div className="mt-3 grid grid-cols-4 gap-2">
|
<div className="mt-3 grid grid-cols-3 sm:grid-cols-4 gap-2">
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{(formData.propertyPhotos || []).map(photo => (
|
{(formData.propertyPhotos || []).map(photo => (
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|||||||
@@ -170,7 +170,15 @@ export default function CreateLeadPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const toggleSection = (id) => {
|
const toggleSection = (id) => {
|
||||||
setOpenSections(prev => ({ ...prev, [id]: !prev[id] }));
|
setOpenSections(prev => {
|
||||||
|
const isOpening = !prev[id];
|
||||||
|
const next = Object.keys(prev).reduce((acc, key) => {
|
||||||
|
acc[key] = false;
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
next[id] = isOpening;
|
||||||
|
return next;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
@@ -187,13 +195,16 @@ export default function CreateLeadPage() {
|
|||||||
|
|
||||||
if (missingFields.length > 0) {
|
if (missingFields.length > 0) {
|
||||||
setValidationError(`Required: ${missingFields.join(', ')}`);
|
setValidationError(`Required: ${missingFields.join(', ')}`);
|
||||||
// Open the first incomplete section
|
// Open the first incomplete section (close others for accordion behavior)
|
||||||
|
const openOnly = (id) => setOpenSections(prev =>
|
||||||
|
Object.keys(prev).reduce((acc, key) => ({ ...acc, [key]: key === id }), {})
|
||||||
|
);
|
||||||
if (!formData.firstName || !formData.lastName || !formData.phones.some(p => p.number.replace(/\D/g, '').length >= 10)) {
|
if (!formData.firstName || !formData.lastName || !formData.phones.some(p => p.number.replace(/\D/g, '').length >= 10)) {
|
||||||
setOpenSections(prev => ({ ...prev, contact: true }));
|
openOnly('contact');
|
||||||
} else if (!formData.address || !formData.city) {
|
} else if (!formData.address || !formData.city) {
|
||||||
setOpenSections(prev => ({ ...prev, property: true }));
|
openOnly('property');
|
||||||
} else {
|
} else {
|
||||||
setOpenSections(prev => ({ ...prev, job: true }));
|
openOnly('job');
|
||||||
}
|
}
|
||||||
toast.error(`Missing required fields: ${missingFields.join(', ')}`);
|
toast.error(`Missing required fields: ${missingFields.join(', ')}`);
|
||||||
return;
|
return;
|
||||||
@@ -288,7 +299,7 @@ export default function CreateLeadPage() {
|
|||||||
{/* ----------------------------------------------------------------
|
{/* ----------------------------------------------------------------
|
||||||
Page content
|
Page content
|
||||||
---------------------------------------------------------------- */}
|
---------------------------------------------------------------- */}
|
||||||
<div className="max-w-3xl mx-auto px-4 sm:px-6 py-6 lg:py-10 pb-44 md:pb-10">
|
<div className="max-w-3xl mx-auto px-4 sm:px-6 py-6 lg:py-10 pb-44 md:pb-40">
|
||||||
|
|
||||||
{/* --- Page Header --- */}
|
{/* --- Page Header --- */}
|
||||||
<div className="mb-7">
|
<div className="mb-7">
|
||||||
@@ -301,13 +312,13 @@ export default function CreateLeadPage() {
|
|||||||
Leads
|
Leads
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div className="flex items-start justify-between gap-4">
|
<div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3 sm:gap-4">
|
||||||
{/* Title */}
|
{/* Title */}
|
||||||
<div>
|
<div className="min-w-0">
|
||||||
<h1 className="font-['Barlow_Condensed'] font-black uppercase tracking-widest text-4xl leading-none text-zinc-900 dark:text-white">
|
<h1 className="font-['Barlow_Condensed'] font-black uppercase tracking-widest text-3xl sm:text-4xl leading-none text-zinc-900 dark:text-white">
|
||||||
New Lead
|
New Lead
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-sm text-zinc-500 dark:text-zinc-400 mt-1.5">
|
<p className="text-xs sm:text-sm text-zinc-500 dark:text-zinc-400 mt-1.5">
|
||||||
{isQuickCapture
|
{isQuickCapture
|
||||||
? 'Essential fields only — fastest capture at the door.'
|
? 'Essential fields only — fastest capture at the door.'
|
||||||
: 'Full lead profile with insurance and assignment details.'}
|
: 'Full lead profile with insurance and assignment details.'}
|
||||||
@@ -315,7 +326,7 @@ export default function CreateLeadPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Quick / Full Form toggle */}
|
{/* Quick / Full Form toggle */}
|
||||||
<div className={`flex items-center p-1 rounded-xl gap-0.5 shrink-0
|
<div className={`self-start sm:self-auto flex items-center p-1 rounded-xl gap-0.5 shrink-0
|
||||||
${isDark ? 'bg-zinc-800' : 'bg-zinc-200/80'}
|
${isDark ? 'bg-zinc-800' : 'bg-zinc-200/80'}
|
||||||
`}>
|
`}>
|
||||||
<button
|
<button
|
||||||
@@ -368,7 +379,7 @@ export default function CreateLeadPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* --- Sections --- */}
|
{/* --- Sections --- */}
|
||||||
<div className="space-y-3">
|
<div className="space-y-3 mb-8">
|
||||||
<AnimatePresence mode="popLayout">
|
<AnimatePresence mode="popLayout">
|
||||||
{visibleSections.map(section => (
|
{visibleSections.map(section => (
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|||||||
Reference in New Issue
Block a user