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:
@@ -25,14 +25,14 @@
|
||||
</p>
|
||||
|
||||
<div class="flex flex-col sm:flex-row items-center gap-4 opacity-0" x-init="gsap.to($el, {opacity: 1, duration: 1, delay: 0.4})">
|
||||
<button wire:click="generateEmail" class="group relative inline-flex items-center justify-center px-8 py-3.5 text-base font-semibold text-white bg-pink-600 rounded-full overflow-hidden transition-all hover:bg-pink-500 hover:shadow-[0_0_20px_rgba(236,72,153,0.5)]">
|
||||
<a href="/mailbox" class="group relative inline-flex items-center justify-center px-8 py-3.5 text-base font-semibold text-white bg-pink-600 rounded-full overflow-hidden transition-all hover:bg-pink-500 hover:shadow-[0_0_20px_rgba(236,72,153,0.5)]">
|
||||
<span class="relative flex items-center gap-2">
|
||||
Start building for free
|
||||
Create mailbox for free
|
||||
<svg class="w-4 h-4 group-hover:translate-x-1 transition-transform" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3" />
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</a>
|
||||
<a href="/api-docs" class="inline-flex items-center justify-center px-8 py-3.5 text-base font-semibold text-white bg-white/5 border border-white/10 rounded-full transition-all hover:bg-white/10">
|
||||
Imail in 100 seconds <svg class="w-4 h-4 ml-2" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
||||
</a>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<!-- Right Side: CTA + Mobile Toggle -->
|
||||
<div class="flex items-center gap-4 z-50">
|
||||
<!-- CTA Button (Desktop & Mobile) -->
|
||||
<a href="#hero" class="relative inline-flex items-center justify-center px-5 py-2.5 text-sm font-semibold text-white bg-zinc-900 border border-zinc-700/80 rounded-full overflow-hidden transition-all group hover:border-pink-500 hover:shadow-[0_0_15px_rgba(236,72,153,0.4)]">
|
||||
<a href="/mailbox" class="relative inline-flex items-center justify-center px-5 py-2.5 text-sm font-semibold text-white bg-zinc-900 border border-zinc-700/80 rounded-full overflow-hidden transition-all group hover:border-pink-500 hover:shadow-[0_0_15px_rgba(236,72,153,0.4)]">
|
||||
<span class="absolute inset-0 w-full h-full transition-all duration-300 ease-out opacity-0 bg-gradient-to-r from-pink-500 to-purple-500 group-hover:opacity-20"></span>
|
||||
<span class="relative flex items-center gap-2 text-zinc-100 group-hover:text-white group-hover:drop-shadow-[0_0_8px_rgba(255,255,255,0.5)]">
|
||||
<span class="hidden sm:inline">Get Temporary Email</span>
|
||||
|
||||
@@ -1,5 +1,95 @@
|
||||
<x-layouts.app.sidebar :title="$title ?? null">
|
||||
<flux:main>
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark h-full">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{ $title ?? 'Mailbox — Imail' }}</title>
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.bunny.net">
|
||||
<link href="https://fonts.bunny.net/css?family=inter:400,500,600,700|jetbrains-mono:400,500" rel="stylesheet" />
|
||||
|
||||
<!-- Vite -->
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
|
||||
<!-- GSAP -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js"></script>
|
||||
|
||||
<style>
|
||||
body { font-family: 'Inter', sans-serif; }
|
||||
.font-mono { font-family: 'JetBrains Mono', monospace; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-app-bg text-[#FAFAFA] antialiased selection:bg-[#EC4899]/30 h-full overflow-hidden"
|
||||
x-data="{
|
||||
toasts: [],
|
||||
addToast(msg, type = 'success') {
|
||||
const id = Date.now();
|
||||
this.toasts.push({ id, msg, type });
|
||||
setTimeout(() => {
|
||||
this.toasts = this.toasts.filter(t => t.id !== id);
|
||||
}, 4000);
|
||||
}
|
||||
}"
|
||||
@notify.window="addToast($event.detail.message, $event.detail.type)">
|
||||
|
||||
{{ $slot }}
|
||||
</flux:main>
|
||||
</x-layouts.app.sidebar>
|
||||
|
||||
<!-- Global Toast Notifications -->
|
||||
<div class="fixed bottom-6 right-6 z-[100] flex flex-col gap-3 pointer-events-none">
|
||||
<template x-for="toast in toasts" :key="toast.id">
|
||||
<div x-show="true"
|
||||
x-transition:enter="transition ease-out duration-500"
|
||||
x-transition:enter-start="opacity-0 translate-x-12 scale-95"
|
||||
x-transition:enter-end="opacity-100 translate-x-0 scale-100"
|
||||
x-transition:leave="transition ease-in duration-300"
|
||||
x-transition:leave-start="opacity-100 scale-100"
|
||||
x-transition:leave-end="opacity-0 scale-90"
|
||||
class="pointer-events-auto min-w-[320px] p-4 rounded-2xl border backdrop-blur-xl shadow-2xl flex items-center gap-4 relative overflow-hidden group"
|
||||
:class="{
|
||||
'bg-emerald-500/10 border-emerald-500/20 text-emerald-100': toast.type === 'success',
|
||||
'bg-blue-500/10 border-blue-500/20 text-blue-100': toast.type === 'info',
|
||||
'bg-amber-500/10 border-amber-500/20 text-amber-100': toast.type === 'warning',
|
||||
'bg-rose-500/10 border-rose-500/20 text-rose-100': toast.type === 'danger'
|
||||
}">
|
||||
<!-- Background Glow -->
|
||||
<div class="absolute inset-0 opacity-20 group-hover:opacity-30 transition-opacity"
|
||||
:class="{
|
||||
'bg-emerald-500/10': toast.type === 'success',
|
||||
'bg-blue-400/10': toast.type === 'info',
|
||||
'bg-amber-400/10': toast.type === 'warning',
|
||||
'bg-rose-400/10': toast.type === 'danger'
|
||||
}"></div>
|
||||
|
||||
<!-- Icon -->
|
||||
<div class="w-10 h-10 rounded-xl flex items-center justify-center shrink-0 shadow-lg"
|
||||
:class="{
|
||||
'bg-emerald-500/20 text-emerald-400': toast.type === 'success',
|
||||
'bg-blue-500/20 text-blue-400': toast.type === 'info',
|
||||
'bg-amber-500/20 text-amber-400': toast.type === 'warning',
|
||||
'bg-rose-500/20 text-rose-400': toast.type === 'danger'
|
||||
}">
|
||||
<svg x-show="toast.type === 'success'" class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7" /></svg>
|
||||
<svg x-show="toast.type === 'info'" class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
|
||||
<svg x-show="toast.type === 'warning'" class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /></svg>
|
||||
<svg x-show="toast.type === 'danger'" class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /></svg>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="text-[10px] font-black uppercase tracking-[0.2em] opacity-40 mb-0.5" x-text="toast.type"></div>
|
||||
<div class="text-[11px] font-bold tracking-wide" x-text="toast.msg"></div>
|
||||
</div>
|
||||
|
||||
<button @click="toasts = toasts.filter(t => t.id !== toast.id)"
|
||||
class="p-1.5 rounded-lg hover:bg-white/5 text-zinc-600 hover:text-white transition-all">
|
||||
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- Lightweight QR Code Library -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrious/4.0.2/qrious.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user