@afncdelacru/brady-chat 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,615 +0,0 @@
1
- import React, { useState, useEffect, useRef } from 'react';
2
- import { motion, AnimatePresence } from 'motion/react';
3
- import { X, CheckCircle } from 'lucide-react';
4
- import { CalculatorFollowUp } from './CalculatorFollowUp';
5
- import { ProgressiveContactForm } from './ProgressiveContactForm';
6
- import { useRecruitingFlow } from '../../../../src/contexts/RecruitingFlowContext';
7
-
8
- interface BranchProfitabilityCalculatorProps {
9
- isOpen: boolean;
10
- onClose: () => void;
11
- isPersonalized?: boolean;
12
- defaultVolume?: number;
13
- }
14
-
15
- export function BranchProfitabilityCalculator({
16
- isOpen,
17
- onClose,
18
- isPersonalized = false,
19
- defaultVolume = 100000000
20
- }: BranchProfitabilityCalculatorProps) {
21
- const { trackCalculatorOpen, trackCalculatorAdjustment, trackAction } = useRecruitingFlow();
22
-
23
- // State for inputs
24
- const [annualVolume, setAnnualVolume] = useState(defaultVolume);
25
- const [branchMargin, setBranchMargin] = useState(300); // bps
26
- const [loCompensation, setLOCompensation] = useState(100); // bps
27
- const [lenderCredits, setLenderCredits] = useState(50); // bps
28
- const [monthlyOpEx, setMonthlyOpEx] = useState(40000); // dollars per month
29
- const [opexReductionEnabled, setOpexReductionEnabled] = useState(true);
30
-
31
- // Tracking state
32
- const [hasInteracted, setHasInteracted] = useState(false);
33
- const [clickedPrimaryCTA, setClickedPrimaryCTA] = useState(false);
34
- const [showFollowUp, setShowFollowUp] = useState(false);
35
- const [showForm, setShowForm] = useState(false);
36
- const [submitted, setSubmitted] = useState(false);
37
- const [startTime, setStartTime] = useState<number>(0);
38
- const [volumeAdjusted, setVolumeAdjusted] = useState(false);
39
- const [marginAdjusted, setMarginAdjusted] = useState(false);
40
- const hasTrackedOpen = useRef(false);
41
- const modalRef = useRef<HTMLDivElement>(null);
42
-
43
- // Track calculator open
44
- useEffect(() => {
45
- if (isOpen && !hasTrackedOpen.current) {
46
- trackCalculatorOpen('BM');
47
- setStartTime(Date.now());
48
- hasTrackedOpen.current = true;
49
- } else if (!isOpen) {
50
- hasTrackedOpen.current = false;
51
- }
52
- }, [isOpen, trackCalculatorOpen]);
53
-
54
- // Helper function to get volume slider step
55
- const getVolumeStep = (value: number) => {
56
- if (value <= 60000000) return 5000000; // $5M increments up to $60M
57
- return 10000000; // $10M increments above $60M
58
- };
59
-
60
- // Helper function to get OpEx slider step
61
- const getOpExStep = (value: number) => {
62
- if (value <= 20000) return 1000; // $1k increments up to $20k
63
- return 5000; // $5k increments above $20k
64
- };
65
-
66
- // Derived calculations - MONTHLY
67
- const monthlyVolume = annualVolume / 12;
68
- const grossProfitBps = branchMargin - loCompensation - lenderCredits;
69
-
70
- // Current scenario calculations (MONTHLY)
71
- const currentRevenue = (monthlyVolume * branchMargin) / 10000;
72
- const currentLOComp = (monthlyVolume * loCompensation) / 10000;
73
- const currentLenderCredits = (monthlyVolume * lenderCredits) / 10000;
74
- const currentGrossProfit = (monthlyVolume * grossProfitBps) / 10000;
75
- const currentOpEx = monthlyOpEx;
76
- const currentBranchProfit = currentGrossProfit - currentOpEx;
77
-
78
- // AFN scenario calculations (MONTHLY)
79
- const volumeIncrease = 0.17; // 17% midpoint of 12-22% range
80
- const afnMonthlyVolume = monthlyVolume * (1 + volumeIncrease);
81
- const afnRevenue = (afnMonthlyVolume * branchMargin) / 10000;
82
- const afnLOComp = (afnMonthlyVolume * loCompensation) / 10000;
83
- const afnLenderCredits = (afnMonthlyVolume * lenderCredits) / 10000;
84
- const afnGrossProfit = (afnMonthlyVolume * grossProfitBps) / 10000;
85
-
86
- // Operating expenses with optional reduction
87
- const opexReductionFactor = opexReductionEnabled ? 0.75 : 1.0;
88
- const afnOpEx = monthlyOpEx * opexReductionFactor;
89
- const afnBranchProfit = afnGrossProfit - afnOpEx;
90
-
91
- const profitDelta = afnBranchProfit - currentBranchProfit;
92
-
93
- // Format currency
94
- const formatCurrency = (value: number) => {
95
- return new Intl.NumberFormat('en-US', {
96
- style: 'currency',
97
- currency: 'USD',
98
- minimumFractionDigits: 0,
99
- maximumFractionDigits: 0,
100
- }).format(value);
101
- };
102
-
103
- // Format volume
104
- const formatVolume = (value: number) => {
105
- if (value >= 1000000) {
106
- return `$${(value / 1000000).toFixed(0)}M`;
107
- }
108
- return formatCurrency(value);
109
- };
110
-
111
- // Handle volume slider change with variable steps
112
- const handleVolumeChange = (rawValue: number) => {
113
- const step = getVolumeStep(rawValue);
114
- const value = Math.round(rawValue / step) * step;
115
- setAnnualVolume(value);
116
- setHasInteracted(true);
117
- setVolumeAdjusted(true);
118
- trackCalculatorAdjustment();
119
- };
120
-
121
- // Handle OpEx slider change with variable steps
122
- const handleOpExChange = (rawValue: number) => {
123
- const step = getOpExStep(rawValue);
124
- const value = Math.round(rawValue / step) * step;
125
- setMonthlyOpEx(value);
126
- setHasInteracted(true);
127
- setMarginAdjusted(true);
128
- trackCalculatorAdjustment();
129
- };
130
-
131
- // Handle margin changes
132
- const handleMarginChange = (value: number, field: 'margin' | 'loComp' | 'credits') => {
133
- if (field === 'margin') setBranchMargin(value);
134
- if (field === 'loComp') setLOCompensation(value);
135
- if (field === 'credits') setLenderCredits(value);
136
- setHasInteracted(true);
137
- setMarginAdjusted(true);
138
- trackCalculatorAdjustment();
139
- };
140
-
141
- // Handle primary CTA click
142
- const handlePrimaryCTA = () => {
143
- setClickedPrimaryCTA(true);
144
- setHasInteracted(true);
145
- setShowForm(true);
146
- trackAction('primary_cta_click', 'high');
147
- };
148
-
149
- // Handle close without clicking primary CTA
150
- const handleClose = () => {
151
- if (!showForm) {
152
- onClose();
153
- // If user interacted but didn't click primary CTA, show follow-up
154
- if (hasInteracted && !clickedPrimaryCTA) {
155
- setTimeout(() => setShowFollowUp(true), 300);
156
- trackAction('close_without_primary_cta');
157
- }
158
- } else {
159
- // Go back from form to calculator
160
- setShowForm(false);
161
- }
162
- };
163
-
164
- // Handle form submission
165
- const handleFormSubmit = (data: any) => {
166
- console.log('Form submitted:', data);
167
- setSubmitted(true);
168
-
169
- // Tag submission with calculator data
170
- const submissionData = {
171
- calculatorType: 'Branch P&L',
172
- volumeAdjusted,
173
- marginAdjusted,
174
- opexReductionEnabled,
175
- afnProfitDelta: profitDelta,
176
- ...data
177
- };
178
- console.log('Tagged submission:', submissionData);
179
- };
180
-
181
- // Reset state when modal closes
182
- useEffect(() => {
183
- if (!isOpen) {
184
- setTimeout(() => {
185
- setHasInteracted(false);
186
- setClickedPrimaryCTA(false);
187
- setShowForm(false);
188
- setSubmitted(false);
189
- }, 300);
190
- }
191
- }, [isOpen]);
192
-
193
- if (!isOpen) return null;
194
-
195
- return (
196
- <>
197
- {/* Overlay */}
198
- <AnimatePresence>
199
- {isOpen && (
200
- <motion.div
201
- initial={{ opacity: 0 }}
202
- animate={{ opacity: 1 }}
203
- exit={{ opacity: 0 }}
204
- className="fixed inset-0 bg-black/60 backdrop-blur-sm z-50"
205
- onClick={handleClose}
206
- />
207
- )}
208
- </AnimatePresence>
209
-
210
- {/* Modal */}
211
- <AnimatePresence>
212
- {isOpen && (
213
- <motion.div
214
- ref={modalRef}
215
- initial={{ opacity: 0, scale: 0.95, y: 20 }}
216
- animate={{ opacity: 1, scale: 1, y: 0 }}
217
- exit={{ opacity: 0, scale: 0.95, y: 20 }}
218
- transition={{ duration: 0.2 }}
219
- role="dialog"
220
- aria-modal="true"
221
- className="fixed inset-4 md:inset-auto md:left-1/2 md:top-1/2 md:-translate-x-1/2 md:-translate-y-1/2 md:w-[900px] md:max-h-[90vh] bg-white dark:bg-zinc-900 rounded-2xl shadow-2xl z-50 flex flex-col overflow-hidden"
222
- >
223
- {/* Header */}
224
- <div className="flex items-start justify-between p-6 border-b border-zinc-200 dark:border-zinc-800">
225
- <div className="flex-1">
226
- <h2 className="text-2xl text-zinc-900 dark:text-white mb-2">
227
- Model Your Branch Profitability
228
- </h2>
229
- <p className="text-sm text-zinc-600 dark:text-zinc-400">
230
- Adjust the assumptions below to see how branch economics change with higher production and lower operating expenses.
231
- </p>
232
- </div>
233
- <button
234
- onClick={handleClose}
235
- className="ml-4 p-2 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-200 transition-colors"
236
- >
237
- <X className="w-5 h-5" />
238
- </button>
239
- </div>
240
-
241
- {/* Content */}
242
- <div className="flex-1 overflow-y-auto">
243
- <div className="p-6 space-y-8">
244
- {submitted ? (
245
- // Success State
246
- <div className="space-y-6 text-center py-8">
247
- <div className="flex justify-center">
248
- <CheckCircle className="w-16 h-16 text-green-500" />
249
- </div>
250
- <div className="space-y-2">
251
- <h3 className="text-2xl text-zinc-900 dark:text-white">
252
- Thanks — We'll Be In Touch
253
- </h3>
254
- <p className="text-base text-zinc-600 dark:text-zinc-400">
255
- We'll follow up shortly to build a realistic pro forma P&L using AFN rates and support structure.
256
- </p>
257
- <p className="text-sm text-zinc-500 dark:text-zinc-500">
258
- In the meantime, feel free to keep exploring.
259
- </p>
260
- </div>
261
- <button
262
- onClick={onClose}
263
- className="w-full px-6 py-3 bg-gradient-to-r from-[#4399D1] to-[#2B7AB8] hover:from-[#2B7AB8] hover:to-[#4399D1] text-white rounded-lg transition-all duration-300 shadow-lg"
264
- >
265
- Continue Exploring
266
- </button>
267
- </div>
268
- ) : showForm ? (
269
- // Form State
270
- <div className="space-y-4">
271
- <p className="text-base text-zinc-600 dark:text-zinc-400">
272
- We'll help you build a realistic pro forma P&L using AFN rates, support structure, and your branch goals.
273
- </p>
274
- <ProgressiveContactForm
275
- onSubmit={handleFormSubmit}
276
- onCancel={() => setShowForm(false)}
277
- primaryCTA="Review My Branch Scenario"
278
- secondaryCTA="Go Back"
279
- context='BM'
280
- />
281
- </div>
282
- ) : (
283
- // Calculator State
284
- <>
285
- {/* Section 1: Baseline Branch Inputs */}
286
- <div className="space-y-6">
287
- <h3 className="text-lg text-zinc-900 dark:text-white">
288
- {isPersonalized ? 'Your Current Branch Assumptions' : 'Current Branch Assumptions'}
289
- </h3>
290
-
291
- {/* Two-column grid for inputs */}
292
- <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
293
- {/* Annual Volume */}
294
- <div className="space-y-3">
295
- <div className="flex items-baseline justify-between">
296
- <label className="text-sm text-zinc-700 dark:text-zinc-300">
297
- Annual Funded Volume
298
- </label>
299
- <span className="text-base text-zinc-900 dark:text-white font-medium">
300
- {formatVolume(annualVolume)}
301
- </span>
302
- </div>
303
- <input
304
- type="range"
305
- min={20000000}
306
- max={300000000}
307
- step={5000000}
308
- value={annualVolume}
309
- onChange={(e) => handleVolumeChange(Number(e.target.value))}
310
- className="w-full h-2 bg-zinc-200 dark:bg-zinc-700 rounded-lg appearance-none cursor-pointer slider-thumb"
311
- />
312
- <div className="flex justify-between text-xs text-zinc-500">
313
- <span>$20M</span>
314
- <span>$300M</span>
315
- </div>
316
- </div>
317
-
318
- {/* Branch Margin */}
319
- <div className="space-y-3">
320
- <div className="flex items-baseline justify-between">
321
- <label className="text-sm text-zinc-700 dark:text-zinc-300">
322
- Avg Branch Margin (bps)
323
- </label>
324
- <span className="text-base text-zinc-900 dark:text-white font-medium">
325
- {branchMargin} bps
326
- </span>
327
- </div>
328
- <input
329
- type="range"
330
- min={200}
331
- max={500}
332
- step={10}
333
- value={branchMargin}
334
- onChange={(e) => handleMarginChange(Number(e.target.value), 'margin')}
335
- className="w-full h-2 bg-zinc-200 dark:bg-zinc-700 rounded-lg appearance-none cursor-pointer slider-thumb"
336
- />
337
- <p className="text-xs text-zinc-500">
338
- Blended margin across conv. and govt loans
339
- </p>
340
- </div>
341
-
342
- {/* LO Compensation */}
343
- <div className="space-y-3">
344
- <div className="flex items-baseline justify-between">
345
- <label className="text-sm text-zinc-700 dark:text-zinc-300">
346
- LO Commission (bps)
347
- </label>
348
- <span className="text-base text-zinc-900 dark:text-white font-medium">
349
- {loCompensation} bps
350
- </span>
351
- </div>
352
- <input
353
- type="range"
354
- min={50}
355
- max={200}
356
- step={5}
357
- value={loCompensation}
358
- onChange={(e) => handleMarginChange(Number(e.target.value), 'loComp')}
359
- className="w-full h-2 bg-zinc-200 dark:bg-zinc-700 rounded-lg appearance-none cursor-pointer slider-thumb"
360
- />
361
- </div>
362
-
363
- {/* Lender Credits */}
364
- <div className="space-y-3">
365
- <div className="flex items-baseline justify-between">
366
- <label className="text-sm text-zinc-700 dark:text-zinc-300">
367
- Lender Credits (bps)
368
- </label>
369
- <span className="text-base text-zinc-900 dark:text-white font-medium">
370
- {lenderCredits} bps
371
- </span>
372
- </div>
373
- <input
374
- type="range"
375
- min={0}
376
- max={150}
377
- step={5}
378
- value={lenderCredits}
379
- onChange={(e) => handleMarginChange(Number(e.target.value), 'credits')}
380
- className="w-full h-2 bg-zinc-200 dark:bg-zinc-700 rounded-lg appearance-none cursor-pointer slider-thumb"
381
- />
382
- </div>
383
- </div>
384
-
385
- {/* Gross Profit Display */}
386
- <div className="p-4 bg-zinc-50 dark:bg-zinc-800/50 rounded-lg border border-zinc-200 dark:border-zinc-700">
387
- <div className="flex items-baseline justify-between">
388
- <span className="text-sm text-zinc-700 dark:text-zinc-300">Gross Profit Margin</span>
389
- <span className="text-base text-zinc-900 dark:text-white font-medium">
390
- {grossProfitBps} bps
391
- </span>
392
- </div>
393
- </div>
394
-
395
- {/* Operating Expenses - Full Width */}
396
- <div className="space-y-3">
397
- <div className="flex items-baseline justify-between">
398
- <label className="text-sm text-zinc-700 dark:text-zinc-300">
399
- Monthly Operating Expenses
400
- </label>
401
- <span className="text-base text-zinc-900 dark:text-white font-medium">
402
- {formatCurrency(monthlyOpEx)}/mo
403
- </span>
404
- </div>
405
- <input
406
- type="range"
407
- min={0}
408
- max={100000}
409
- step={1000}
410
- value={monthlyOpEx}
411
- onChange={(e) => handleOpExChange(Number(e.target.value))}
412
- className="w-full h-2 bg-zinc-200 dark:bg-zinc-700 rounded-lg appearance-none cursor-pointer slider-thumb"
413
- />
414
- <div className="flex justify-between text-xs text-zinc-500">
415
- <span>$0</span>
416
- <span>$100k/mo</span>
417
- </div>
418
- <p className="text-xs text-zinc-500">
419
- Includes rent, staff, marketing, technology, and overhead
420
- </p>
421
- </div>
422
- </div>
423
-
424
- {/* Section 2: P&L Comparison */}
425
- <div className="space-y-4">
426
- <h3 className="text-lg text-zinc-900 dark:text-white">
427
- Monthly Branch P&L Comparison
428
- </h3>
429
-
430
- <div className="overflow-x-auto">
431
- <table className="w-full text-sm">
432
- <thead>
433
- <tr className="border-b border-zinc-200 dark:border-zinc-700">
434
- <th className="text-left py-3 text-zinc-600 dark:text-zinc-400 font-medium">Metric</th>
435
- <th className="text-right py-3 text-zinc-600 dark:text-zinc-400 font-medium">Current</th>
436
- <th className="text-right py-3 text-[#8B5CF6] font-medium">With AFN</th>
437
- </tr>
438
- </thead>
439
- <tbody className="divide-y divide-zinc-100 dark:divide-zinc-800">
440
- <tr>
441
- <td className="py-3 text-zinc-700 dark:text-zinc-300">Monthly Funded Volume</td>
442
- <td className="py-3 text-right text-zinc-900 dark:text-white">{formatVolume(monthlyVolume)}</td>
443
- <td className="py-3 text-right text-zinc-900 dark:text-white">{formatVolume(afnMonthlyVolume)}</td>
444
- </tr>
445
- <tr>
446
- <td className="py-3 text-zinc-700 dark:text-zinc-300">Branch Margin (bps)</td>
447
- <td className="py-3 text-right text-zinc-900 dark:text-white">{branchMargin}</td>
448
- <td className="py-3 text-right text-zinc-900 dark:text-white">{branchMargin}</td>
449
- </tr>
450
- <tr>
451
- <td className="py-3 text-zinc-700 dark:text-zinc-300">Revenue</td>
452
- <td className="py-3 text-right text-zinc-900 dark:text-white">{formatCurrency(currentRevenue)}</td>
453
- <td className="py-3 text-right text-zinc-900 dark:text-white">{formatCurrency(afnRevenue)}</td>
454
- </tr>
455
- <tr>
456
- <td className="py-3 text-zinc-700 dark:text-zinc-300">LO Compensation</td>
457
- <td className="py-3 text-right text-zinc-900 dark:text-white">{formatCurrency(currentLOComp)}</td>
458
- <td className="py-3 text-right text-zinc-900 dark:text-white">{formatCurrency(afnLOComp)}</td>
459
- </tr>
460
- <tr>
461
- <td className="py-3 text-zinc-700 dark:text-zinc-300">Lender Credits</td>
462
- <td className="py-3 text-right text-zinc-900 dark:text-white">{formatCurrency(currentLenderCredits)}</td>
463
- <td className="py-3 text-right text-zinc-900 dark:text-white">{formatCurrency(afnLenderCredits)}</td>
464
- </tr>
465
- <tr className="font-medium">
466
- <td className="py-3 text-zinc-700 dark:text-zinc-300">Gross Profit</td>
467
- <td className="py-3 text-right text-zinc-900 dark:text-white">{formatCurrency(currentGrossProfit)}</td>
468
- <td className="py-3 text-right text-zinc-900 dark:text-white">{formatCurrency(afnGrossProfit)}</td>
469
- </tr>
470
- <tr>
471
- <td className="py-3 text-zinc-700 dark:text-zinc-300">Operating Expenses</td>
472
- <td className="py-3 text-right text-zinc-900 dark:text-white">{formatCurrency(currentOpEx)}</td>
473
- <td className="py-3 text-right text-zinc-900 dark:text-white">{formatCurrency(afnOpEx)}</td>
474
- </tr>
475
- <tr className="font-bold border-t-2 border-zinc-300 dark:border-zinc-600">
476
- <td className="py-3 text-zinc-900 dark:text-white">Branch Profit</td>
477
- <td className="py-3 text-right text-zinc-900 dark:text-white">{formatCurrency(currentBranchProfit)}</td>
478
- <td className="py-3 text-right text-[#8B5CF6]">{formatCurrency(afnBranchProfit)}</td>
479
- </tr>
480
- </tbody>
481
- </table>
482
- </div>
483
- </div>
484
-
485
- {/* Section 3: AFN Assumptions */}
486
- <div className="space-y-4">
487
- <h3 className="text-lg text-zinc-900 dark:text-white">
488
- AFN Scenario Assumptions
489
- </h3>
490
-
491
- {/* Volume Increase */}
492
- <div className="p-4 bg-[#8B5CF6]/5 dark:bg-[#8B5CF6]/10 rounded-lg border border-[#8B5CF6]/20">
493
- <div className="flex items-start justify-between mb-2">
494
- <span className="text-sm text-zinc-700 dark:text-zinc-300">Monthly Funded Volume Increase</span>
495
- <span className="text-base text-[#8B5CF6] font-medium">+12% to +22%</span>
496
- </div>
497
- <p className="text-xs text-zinc-600 dark:text-zinc-400">
498
- Driven by faster turn times, higher pull-through, and AI-assisted workflows.
499
- </p>
500
- </div>
501
-
502
- {/* Operating Expense Reduction Toggle */}
503
- <div className="p-4 bg-zinc-50 dark:bg-zinc-800/50 rounded-lg border border-zinc-200 dark:border-zinc-700">
504
- <div className="flex items-start justify-between mb-2">
505
- <div className="flex-1">
506
- <div className="flex items-center gap-3 mb-2">
507
- <span className="text-sm text-zinc-700 dark:text-zinc-300">Operating Expense Reduction</span>
508
- <button
509
- onClick={() => {
510
- setOpexReductionEnabled(!opexReductionEnabled);
511
- setHasInteracted(true);
512
- trackCalculatorAdjustment();
513
- }}
514
- className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
515
- opexReductionEnabled
516
- ? 'bg-[#8B5CF6]'
517
- : 'bg-zinc-300 dark:bg-zinc-600'
518
- }`}
519
- >
520
- <span
521
- className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
522
- opexReductionEnabled ? 'translate-x-6' : 'translate-x-1'
523
- }`}
524
- />
525
- </button>
526
- <span className="text-base text-[#8B5CF6] font-medium">25%</span>
527
- </div>
528
- <p className="text-xs text-zinc-600 dark:text-zinc-400">
529
- Technology leverage and centralized support reduce per-loan operating costs.
530
- </p>
531
- </div>
532
- </div>
533
- </div>
534
-
535
- {/* Unchanged Assumptions */}
536
- <div className="p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-200 dark:border-blue-800">
537
- <p className="text-xs text-zinc-700 dark:text-zinc-300">
538
- Branch margin, LO compensation, and lender credits are unchanged in this scenario.
539
- </p>
540
- </div>
541
- </div>
542
-
543
- {/* Section 4: Highlighted Outcome */}
544
- <div className="p-6 bg-gradient-to-br from-[#8B5CF6]/10 to-[#8B5CF6]/5 dark:from-[#8B5CF6]/20 dark:to-[#8B5CF6]/10 rounded-xl border-2 border-[#8B5CF6]/30 shadow-[0_0_30px_rgba(139,92,246,0.15)]">
545
- <div className="space-y-4">
546
- <div>
547
- <p className="text-sm text-zinc-600 dark:text-zinc-400 mb-2">
548
- Modeled Monthly Branch Profit at AFN
549
- </p>
550
- <p className="text-5xl text-[#8B5CF6] font-bold drop-shadow-[0_0_20px_rgba(139,92,246,0.3)]">
551
- {formatCurrency(afnBranchProfit)}
552
- </p>
553
- <p className="text-xs text-zinc-500 dark:text-zinc-500 mt-2">
554
- Illustrative scenario based on your inputs.
555
- </p>
556
- </div>
557
- <div className="pt-4 border-t border-[#8B5CF6]/20">
558
- <p className="text-sm text-zinc-600 dark:text-zinc-400 mb-1">
559
- Incremental Monthly Branch Profit
560
- </p>
561
- <p className="text-2xl text-green-600 dark:text-green-400 font-bold">
562
- + {formatCurrency(profitDelta)}
563
- </p>
564
- </div>
565
- </div>
566
- </div>
567
-
568
- {/* Section 5: Disclaimers */}
569
- <div className="text-[10px] text-zinc-400 dark:text-zinc-600 leading-relaxed space-y-1">
570
- <p>This model is illustrative only and does not represent a guarantee of results.</p>
571
- <p>Actual margins, expenses, and profitability vary by branch, market, and compensation structure.</p>
572
- </div>
573
- </>
574
- )}
575
- </div>
576
- </div>
577
-
578
- {/* Sticky Footer CTA */}
579
- {!submitted && !showForm && (
580
- <div className="p-6 border-t border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900">
581
- <div className="space-y-3">
582
- <p className="text-xs text-center text-zinc-600 dark:text-zinc-400">
583
- We'll help you build a realistic pro forma P&L using AFN rates, support structure, and your branch goals.
584
- </p>
585
- <div className="flex gap-3">
586
- <button
587
- onClick={handleClose}
588
- className="flex-1 px-6 py-3 border border-zinc-300 dark:border-zinc-700 text-zinc-700 dark:text-zinc-300 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800 transition-colors"
589
- >
590
- Close
591
- </button>
592
- <button
593
- onClick={handlePrimaryCTA}
594
- className="flex-1 px-6 py-3 bg-gradient-to-r from-[#8B5CF6] to-[#7C3AED] hover:from-[#7C3AED] hover:to-[#8B5CF6] text-white rounded-lg transition-all duration-300 shadow-lg"
595
- >
596
- Sanity-Check This With AFN
597
- </button>
598
- </div>
599
- </div>
600
- </div>
601
- )}
602
- </motion.div>
603
- )}
604
- </AnimatePresence>
605
-
606
- {/* Follow-Up Modal */}
607
- <CalculatorFollowUp
608
- isOpen={showFollowUp}
609
- onClose={() => setShowFollowUp(false)}
610
- isBranchManager={true}
611
- clickedPrimaryCTA={clickedPrimaryCTA}
612
- />
613
- </>
614
- );
615
- }