feat: implement adaptive multi-pane mailbox with utilities and security gates
- Added fully responsive 3-pane layout for Mailbox - Integrated global cinematic Toast system in app shell - Implemented Copy to Clipboard and QR Code modal utilities - Added diverse mock email data for premium demonstration - Implemented security gates for custom mailboxes and attachments - Fixed critical 500 error for orphaned email selection - Refined landing page hero CTA text
This commit is contained in:
255
app/Livewire/Mailbox.php
Normal file
255
app/Livewire/Mailbox.php
Normal file
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Layout('components.layouts.app')]
|
||||
class Mailbox extends Component
|
||||
{
|
||||
public $activeMailboxes = [
|
||||
['id' => 1, 'address' => 'idevakk@imail.com', 'expires_at' => '23:59:12', 'progress' => 90],
|
||||
['id' => 2, 'address' => 'tester_99@devmail.ai', 'expires_at' => '45:12:05', 'progress' => 40],
|
||||
];
|
||||
|
||||
public $currentMailboxId = 1;
|
||||
|
||||
public $activeFolder = 'inbox';
|
||||
|
||||
public $selectedEmailId = null;
|
||||
|
||||
public $search = '';
|
||||
|
||||
public $page = 1;
|
||||
|
||||
public $totalPages = 5;
|
||||
|
||||
// Create State
|
||||
public $showCreateModal = false;
|
||||
|
||||
public $createType = 'random'; // random | custom
|
||||
|
||||
public $customUsername = '';
|
||||
|
||||
public $customDomain = 'imail.com';
|
||||
|
||||
public $availableDomains = ['imail.com', 'devmail.ai', 'temp-inbox.net'];
|
||||
|
||||
public function getEmailsProperty()
|
||||
{
|
||||
// Mock emails based on mailbox ID for demonstration
|
||||
$emails = [
|
||||
1 => [
|
||||
[
|
||||
'id' => 1,
|
||||
'from_name' => 'GitHub Security',
|
||||
'from_email' => 'noreply@github.com',
|
||||
'subject' => '[GitHub] A new personal access token was created',
|
||||
'preview' => 'A new personal access token (classic) was recently added to your account.',
|
||||
'content' => '<p>Hi @idevakk,</p><p>A new personal access token (classic) was recently added to your account IDEVAKK.</p><p>If this was you, you can safely ignore this email.</p><p>If this was not you, please visit https://github.com/settings/tokens to revoke the token.</p>',
|
||||
'time' => '10:24 AM',
|
||||
'unread' => true,
|
||||
'flagged' => true,
|
||||
'attachments' => [],
|
||||
],
|
||||
[
|
||||
'id' => 101,
|
||||
'from_name' => 'Linear',
|
||||
'from_email' => 'updates@linear.app',
|
||||
'subject' => 'New issue assigned: [UI-124] Fix sidebar overflow',
|
||||
'preview' => 'You have been assigned to a new issue in the UI project. Please review the details...',
|
||||
'content' => '<p>Hello,</p><p>You have been assigned to <strong>[UI-124] Fix sidebar overflow in mobile view</strong>.</p><p>Priority: High</p><p>Project: Imail Revamp</p><p>View details at https://linear.app/imail/issue/UI-124</p>',
|
||||
'time' => '11:45 AM',
|
||||
'unread' => true,
|
||||
'flagged' => false,
|
||||
'attachments' => [],
|
||||
],
|
||||
[
|
||||
'id' => 102,
|
||||
'from_name' => 'Canva',
|
||||
'from_email' => 'design@canva.com',
|
||||
'subject' => 'Your design "Imail Presentation" is ready',
|
||||
'preview' => 'Collaborate with your team on your latest design for the Imail product launch.',
|
||||
'content' => '<p>Hey there!</p><p>Your team is waiting for your feedback on the <strong>Imail Presentation</strong> design.</p><p>Check the latest comments and approve the final version.</p>',
|
||||
'time' => '9:12 AM',
|
||||
'unread' => false,
|
||||
'flagged' => false,
|
||||
'attachments' => [
|
||||
['name' => 'presentation_v1.pdf', 'size' => '4.2 MB'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => 103,
|
||||
'from_name' => 'Figma',
|
||||
'from_email' => 'notifications@figma.com',
|
||||
'subject' => 'Atul Kumar mentioned you in "Mobile App (Draft)"',
|
||||
'preview' => '"@idevakk take a look at the revised QR modal design, let me know if..."',
|
||||
'content' => '<p><strong>Atul Kumar</strong> mentioned you in a comment on <strong>Mobile App (Draft)</strong>:</p><blockquote>"@idevakk take a look at the revised QR modal design, let me know if the proportions look right to you."</blockquote><p>Reply in Figma or view the comment online.</p>',
|
||||
'time' => '8:30 AM',
|
||||
'unread' => false,
|
||||
'flagged' => true,
|
||||
'attachments' => [],
|
||||
],
|
||||
],
|
||||
2 => [
|
||||
[
|
||||
'id' => 2,
|
||||
'from_name' => 'Stripe',
|
||||
'from_email' => 'support@stripe.com',
|
||||
'subject' => 'Your weekly payment report',
|
||||
'preview' => 'Your weekly report for the period of Feb 24 - Mar 2 is now available.',
|
||||
'content' => '<p>Hello,</p><p>Your weekly report for the period of Feb 24 - Mar 2 is now available in your dashboard.</p><p>Total Volume: $12,450.00</p><p>View the full report details online.</p>',
|
||||
'time' => 'Yesterday',
|
||||
'unread' => false,
|
||||
'flagged' => false,
|
||||
'attachments' => [
|
||||
['name' => 'report_mar_02.pdf', 'size' => '1.2 MB'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => 201,
|
||||
'from_name' => 'Postmark',
|
||||
'from_email' => 'alerts@postmarkapp.com',
|
||||
'subject' => 'Outbound volume spike detected',
|
||||
'preview' => 'We noticed a sudden increase in outbound emails from your "Production" server.',
|
||||
'content' => '<p>Alert: Outbound volume spike.</p><p>Server: Production</p><p>We detected 5,000+ emails sent in the last hour. Please ensure this is expected activity.</p>',
|
||||
'time' => 'Yesterday',
|
||||
'unread' => true,
|
||||
'flagged' => false,
|
||||
'attachments' => [],
|
||||
],
|
||||
[
|
||||
'id' => 202,
|
||||
'from_name' => 'Vercel',
|
||||
'from_email' => 'deployments@vercel.com',
|
||||
'subject' => 'Team "idevakk" deployment successful',
|
||||
'preview' => 'Production deployment for the imail-frontend project has completed.',
|
||||
'content' => '<p>Your deployment is live!</p><p>Project: imail-frontend</p><p>Command: <code>npm run build</code></p><p>View your deployment here: https://imail.app</p>',
|
||||
'time' => 'Mar 2',
|
||||
'unread' => false,
|
||||
'flagged' => false,
|
||||
'attachments' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
return $emails[$this->currentMailboxId] ?? [
|
||||
[
|
||||
'id' => 3,
|
||||
'from_name' => 'Slack',
|
||||
'from_email' => 'notifications@slack.com',
|
||||
'subject' => 'You have 12 unread messages from your team',
|
||||
'preview' => 'Atul Kumar: "Did you check the new API endpoints? We need them for..."',
|
||||
'content' => '<p>You have new activity in Slack.</p><ul><li><strong>#dev-chat</strong>: 8 new messages</li><li><strong>#announcements</strong>: 4 new messages</li></ul>',
|
||||
'time' => 'Mar 1',
|
||||
'unread' => true,
|
||||
'flagged' => false,
|
||||
'attachments' => [],
|
||||
],
|
||||
[
|
||||
'id' => 301,
|
||||
'from_name' => 'Zoom',
|
||||
'from_email' => 'no-reply@zoom.us',
|
||||
'subject' => 'Meeting Reminder: "Sprint Planning"',
|
||||
'preview' => 'Your Sprint Planning meeting is scheduled to start in 15 minutes.',
|
||||
'content' => '<p>Friendly reminder that your Sprint Planning call starts soon.</p><p>Link: https://zoom.us/j/123456789</p>',
|
||||
'time' => 'Feb 28',
|
||||
'unread' => false,
|
||||
'flagged' => false,
|
||||
'attachments' => [],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function selectEmail($id)
|
||||
{
|
||||
$this->selectedEmailId = $id;
|
||||
}
|
||||
|
||||
public function switchMailbox($id)
|
||||
{
|
||||
$this->currentMailboxId = $id;
|
||||
$this->selectedEmailId = null;
|
||||
$this->search = '';
|
||||
}
|
||||
|
||||
public function createMailbox()
|
||||
{
|
||||
$newAddress = $this->createType === 'random'
|
||||
? fake()->userName().'_'.rand(10, 99).'@'.$this->availableDomains[array_rand($this->availableDomains)]
|
||||
: $this->customUsername.'@'.$this->customDomain;
|
||||
|
||||
$newId = count($this->activeMailboxes) + 1;
|
||||
$this->activeMailboxes[] = [
|
||||
'id' => $newId,
|
||||
'address' => $newAddress,
|
||||
'expires_at' => '24:00:00',
|
||||
'progress' => 100,
|
||||
];
|
||||
|
||||
$this->currentMailboxId = $newId;
|
||||
$this->showCreateModal = false;
|
||||
$this->customUsername = '';
|
||||
}
|
||||
|
||||
public function deleteMailbox($id)
|
||||
{
|
||||
$this->activeMailboxes = array_filter($this->activeMailboxes, fn ($m) => $m['id'] !== $id);
|
||||
|
||||
if ($this->currentMailboxId === $id) {
|
||||
$this->currentMailboxId = count($this->activeMailboxes) > 0 ? reset($this->activeMailboxes)['id'] : null;
|
||||
$this->selectedEmailId = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function downloadEmail($id)
|
||||
{
|
||||
// Mock download logic
|
||||
$this->js("alert('Downloading email #{$id}... (Mock Action)')");
|
||||
}
|
||||
|
||||
public function printEmail($id)
|
||||
{
|
||||
// Mock print logic
|
||||
$this->js('window.print()');
|
||||
}
|
||||
|
||||
public function deleteEmail($id)
|
||||
{
|
||||
// Mock delete logic
|
||||
$this->js("alert('Email #{$id} deleted successfully! (Mock Action)')");
|
||||
$this->selectedEmailId = null;
|
||||
}
|
||||
|
||||
public function nextPage()
|
||||
{
|
||||
if ($this->page < $this->totalPages) {
|
||||
$this->page++;
|
||||
}
|
||||
}
|
||||
|
||||
public function previousPage()
|
||||
{
|
||||
if ($this->page > 1) {
|
||||
$this->page--;
|
||||
}
|
||||
}
|
||||
|
||||
public function generateQrCode($address)
|
||||
{
|
||||
// Mock QR generation with a slight delay
|
||||
usleep(800000); // 800ms
|
||||
$this->dispatch('qrCodeGenerated', address: $address);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$currentMailbox = collect($this->activeMailboxes)->firstWhere('id', $this->currentMailboxId);
|
||||
|
||||
return view('livewire.mailbox', [
|
||||
'emails' => $this->getEmailsProperty(),
|
||||
'currentMailbox' => $currentMailbox,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user