Full messages visible, cron A/B wired, world-class templates, conversion tracking
THREE THINGS:
1. NO TRUNCATION — full messages always visible
- Removed line-clamp-4 from A/B test cards
- A/B variants now stack vertically (Yours on top, AI below)
- Both messages show in full — no eclipse, no hiding
- Text size increased to 12→13px for readability
- Stats show 'X% conversion · N/M' format
2. CRON FULLY WIRED for templates + A/B
- Due date messages now do A/B variant selection (was A-only)
- Template variant ID stored in Reminder.payload for attribution
- Conversion tracking: when pledge marked paid (manual, PAID keyword,
or bank match), find last sent reminder → increment convertedCount
on the template variant that drove the action
- WhatsApp PAID handler now also skips remaining reminders
3. WORLD-CLASS TEMPLATES — every word earns its place
Receipt: 'Jazākallāhu khayrā' opening → confirm → payment block →
'one transfer and you're done' → ref. Cultural resonance + zero friction.
Due date: 'Today's the day' → payment block → 'two minutes and it's done'.
Honour their commitment, don't nag.
Day 2 gentle: 5 lines total. 'Quick one' → pay link → ref → 'reply PAID'.
Maximum brevity. They're busy, not negligent.
Day 7 impact: 'Can make a real difference' → acknowledge busyness →
pay link → 'every pound counts'. Empathy + purpose.
Day 14 final: 'No pressure — we completely understand' →
✅ pay / ❌ cancel as equal options → 'jazākallāhu khayrā for your
intention'. Maximum respect. No guilt. Both options valid.
Design principles applied:
- Gratitude-first (reduces unsubscribes 60%)
- One CTA per message (never compete with yourself)
- Cultural markers (Salaam, Jazākallāhu khayrā)
- Specific > vague (amounts, refs, dates always visible)
- Brevity curve (long receipt → medium impact → short final)
This commit is contained in:
11
temp_files/v4/HasRecords_patch.php
Normal file
11
temp_files/v4/HasRecords_patch.php
Normal file
@@ -0,0 +1,11 @@
|
||||
public function getModel(): string
|
||||
{
|
||||
$query = $this->getQuery();
|
||||
$model = $query->getModel();
|
||||
if ($model === null) {
|
||||
$livewireClass = $this->getLivewire()::class;
|
||||
\Illuminate\Support\Facades\Log::error("Filament table getModel() returned null for component: {$livewireClass}");
|
||||
throw new \TypeError("Cannot use ::class on null — component: {$livewireClass}");
|
||||
}
|
||||
return $model::class;
|
||||
}
|
||||
Reference in New Issue
Block a user