feat: Pipeline board full-bleed + hover actions + Programare→Calendar
Addresses the gaps surfaced after the first redesign — the board was still boxed in Filament chrome (not truly full-page), hover floating-actions and "+ Adaugă" CTAs were missing, and the P0 "Programează" from deal card had no calendar wiring. Full-page: - getMaxContentWidth() = Width::Full - getHeading()/getSubheading() return empty so Filament's title bar disappears, leaving the kanban edge-to-edge - CSS uses :has(.pb-shell) to strip Filament's page padding + heading block at the layout level - Board height = calc(100vh - 64px); columns scroll independently Hover floating-actions on every card (column-aware): - Cols 1-2 (Cerere / Calculație): 📅 quickSchedule - Col 3 (Programat): ▶ start work (creates WO) - Col 4 (În lucru): ✓ mark Gata - Col 5 (Gata): 💰 mark Achitat - All cards with phone: 📞 tel: + 💬 wa.me - All cards: ↗ open in resource edit - Shown only on .pb-deal:hover, positioned absolute top-right "+ Adaugă" CTA at column bottom: - Cols 1-3 → /app/leads/create - Cols 4-5 → /app/work-orders/create Programare → Calendar (P0 AAA): - quickSchedule($key) on PipelineBoard creates a real Appointment row for tomorrow 10:00 linked to (client_id, vehicle_id, master_id, deal_id), sets deal.stage='scheduled' + scheduled_at, then shows a toast - Panel bottom action bar gains "📅 Programează" CTA for lead/deal cards - "📅 Calendar" jump CTA for WO cards - calendarUrl() returns the canonical filament.tenant.pages.calendar-board route Empty column state now reads "Gol — trage un card aici" instead of just "Gol" so the drop affordance is explicit. Stat strip + filter bar sticky at top; board fills the remaining viewport. Tests: +1 (quickSchedule creates Appointment + moves deal). Suite 181/181. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -153,6 +153,24 @@ class PipelineBoardTest extends TestCase
|
||||
$this->assertEquals('mine', $cols['request']['cards'][0]['subject']);
|
||||
}
|
||||
|
||||
public function test_quick_schedule_creates_appointment_and_moves_deal_to_scheduled(): void
|
||||
{
|
||||
$client = Client::create(['name' => 'C', 'phone' => '+37399123000', 'type' => 'individual', 'status' => 'active']);
|
||||
$vehicle = Vehicle::create(['client_id' => $client->id, 'make' => 'X', 'model' => 'Y', 'plate' => 'SCH-1']);
|
||||
$deal = Deal::create(['client_id' => $client->id, 'vehicle_id' => $vehicle->id, 'name' => 'X Y — Repair', 'price' => 1000, 'stage' => 'contact']);
|
||||
|
||||
Livewire::test(PipelineBoard::class)->call('quickSchedule', "deal:{$deal->id}");
|
||||
|
||||
$deal->refresh();
|
||||
$this->assertEquals('scheduled', $deal->stage);
|
||||
$this->assertNotNull($deal->scheduled_at);
|
||||
|
||||
$apt = \App\Models\Tenant\Appointment::where('client_id', $client->id)->first();
|
||||
$this->assertNotNull($apt);
|
||||
$this->assertEquals('scheduled', $apt->status);
|
||||
$this->assertEquals(today()->addDay()->toDateString(), $apt->date->toDateString());
|
||||
}
|
||||
|
||||
public function test_open_card_loads_panel_detail_for_deal(): void
|
||||
{
|
||||
$client = Client::create(['name' => 'Ion Popescu', 'phone' => '+37369123456', 'type' => 'individual', 'status' => 'active']);
|
||||
|
||||
Reference in New Issue
Block a user