1<!DOCTYPE html> 2<html lang="en" class="scroll-smooth"> 3 <head> 4 <!-- Essential Meta Tags --> 5<meta charset="utf-8"/> 6<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/> 7<meta http-equiv="X-UA-Compatible" content="IE=edge"/> 8 9<!-- Primary Meta Tags --> 10<title>PHPFlasher | Easy Flash Messages for PHP</title> 11<meta name="title" content="PHPFlasher"/> 12<meta name="description" content="PHPFlasher is a powerful PHP notification library that makes it simple to add beautiful flash messages to your Laravel or Symfony applications. Perfect for form submissions, API responses, and user interactions."/> 13<meta name="author" content="Younes ENNAJI"/> 14<meta name="keywords" content="php flash messages, laravel notifications, symfony notifications, php notifications, toastr php, sweetalert php, flash messages"/> 15<meta name="robots" content="index, follow"/> 16<meta name="language" content="English"/> 17<meta name="revisit-after" content="7 days"/> 18<meta name="theme-color" content="#4052B5"/> 19<meta name="publish_date" property="og:publish_date" content="2023-01-10T00:00:00+00:00"/> 20 21<!-- Open Graph / Facebook --> 22<meta property="og:type" content="website"/> 23<meta property="og:url" content="https://php-flasher.io/"/> 24<meta property="og:title" content="Easily add flash messages to your #Laravel or #Symfony projects with PHPFlasher - a powerful, easy-to-use package for improved user engagement & experience"/> 25<meta property="og:description" content="PHPFlasher is a powerful PHP notification library that makes it simple to add beautiful flash messages to your Laravel or Symfony applications. Perfect for form submissions, API responses, and user interactions."/> 26<meta property="og:image" content="https://php-flasher.io/static/images/php-flasher-social-card.jpg"/> 27<meta property="og:image:alt" content="Easily add flash messages to your #Laravel or #Symfony projects with PHPFlasher - a powerful, easy-to-use package for improved user engagement & experience"/> 28<meta property="og:image:width" content="1024"/> 29<meta property="og:image:height" content="512"/> 30<meta property="og:site_name" content="PHPFlasher"/> 31<meta property="og:locale" content="en_US"/> 32<meta property="article:author" content="https://github.com/yoeunes"/> 33<meta property="article:published_time" content="2023-01-10T00:00:00+00:00"/> 34<meta property="article:modified_time" content="2026-09-02T15:58:38+00:00"/> 35 36<!-- Twitter --> 37<meta name="twitter:card" content="summary_large_image"/> 38<meta name="twitter:creator" content="@yoeunes"/> 39<meta name="twitter:site" content="@phpflasher"/> 40<meta name="twitter:title" content="Easily add flash messages to your #Laravel or #Symfony projects with PHPFlasher - a powerful, easy-to-use package for improved user engagement & experience"/> 41<meta name="twitter:description" content="PHPFlasher is a powerful PHP notification library that makes it simple to add beautiful flash messages to your Laravel or Symfony applications. Perfect for form submissions, API responses, and user interactions."/> 42<meta name="twitter:image" content="https://php-flasher.io/static/images/php-flasher-social-card.jpg"/> 43<meta name="twitter:image:alt" content="PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution."/> 44 45<!-- Favicon --> 46<link rel="icon" type="image/x-icon" href="/static/images/favicon.ico"/> 47<link rel="apple-touch-icon" sizes="180x180" href="/static/images/apple-touch-icon.png"/> 48<link rel="icon" type="image/png" sizes="32x32" href="/static/images/favicon-32x32.png"/> 49<link rel="icon" type="image/png" sizes="16x16" href="/static/images/favicon-16x16.png"/> 50<link rel="mask-icon" href="/static/images/safari-pinned-tab.svg" color="#5bbad5"/> 51<link rel="canonical" href="https://php-flasher.io/"/> 52 53<!-- Preconnect to External Domains --> 54<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin/>
55<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin/> 56 57<!-- Styles --> 58<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Raleway:wght@400;600;700&family=Varela+Round&display=swap"/> 59<link rel="stylesheet" href="/dist/main.b2cdcaf6.css"/> 60<link rel="stylesheet" href="/static/css/fontawesome.css"/> 61<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css"/> 62 63<!-- Structured Data -->
64<script type="application/ld+json"> 65{ 66 "@context": "https://schema.org", 67 "@type": "SoftwareApplication", 68 "name": "PHPFlasher", 69 "applicationCategory": "DeveloperApplication", 70 "operatingSystem": "PHP", 71 "author": { 72 "@type": "Person", 73 "name": "Younes ENNAJI", 74 "url": "https://github.com/yoeunes" 75 }, 76 "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", 77 "softwareVersion": "2.x", 78 "url": "https://php-flasher.io", 79 "downloadUrl": "https://packagist.org/packages/php-flasher/flasher", 80 "license": "https://github.com/php-flasher/flasher/blob/main/LICENSE", 81 "programmingLanguage": "PHP" 82} 83</script>
83 84 85<!-- Scripts -->
86<script defer src="/dist/main.29f69f71.js"></script>
vendor: 1 bytes, line 86
86
87<script defer src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
vendor: 1 bytes, line 87
87
88<script defer src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
88 89 90<!-- Initialize Messages Object -->
91<script>var messages = {};</script>
91 92 93 94<!-- Analytics -->
vendor: 64 bytes, lines 94-95
94 95<script async src="https://www.googletagmanager.com/gtag/js?id=
95G-T4D78SM7TC
vendor: 12 bytes, line 95
95"></script>
96<script> 97
vendor: 139 bytes, lines 97-100
97window.dataLayer = window.dataLayer || []; 98 function gtag(){dataLayer.push(arguments);} 99 gtag('js', new Date()); 100 gtag('config', '
100G-T4D78SM7TC
vendor: 4 bytes, line 100
100');
101</script>
101 102 103 104 </head> 105 <body class="min-h-screen bg-slate-50 text-slate-800 font-sans leading-relaxed" data-controller="anchor clipboard navigation tryit "> 106 107 108 <div class="bg-green-700 text-white text-center p-1.5 leading-tight shadow-lg relative overflow-hidden"> 109 <div class="absolute inset-0 bg-gradient-to-r from-green-800 to-green-600 opacity-50"></div> 110 <div class="container mx-auto px-4 relative z-10"> 111 <span class="text-xl font-bold"><img src="/static/images/palestine-flag.png" alt="Palestinian Flag" class="inline h-4 w-auto mr-1"> Solidarity with Palestine.</span> 112 <span class="inline text-xs sm:text-sm md:text-base ml-1">We seek justice and peace, and strongly oppose all forms of injustice and genocide.</span> 113 </div> 114</div> 115 116 <header class="w-full bg-white border-b border-slate-200 shadow-sm"> 117 <div class="container max-w-7xl mx-auto px-4 lg:px-6"> 118 <div class="flex items-center justify-between h-16"> 119 <!-- Logo Area --> 120 <div class="flex items-center space-x-4"> 121 <a href="/" class="flex items-center space-x-3 group"> 122 <div class="relative"> 123 <span class="text-xl font-semibold text-indigo-900">PHP<span class="text-indigo-500">Flasher</span></span> 124 </div> 125 </a> 126 127 <!-- Version Selector --> 128 <div class="hidden sm:flex items-center space-x-2"> 129 130 <a href="https://php-flasher.io/" class="bg-indigo-500 text-white text-xs px-2.5 py-1 rounded-full font-medium transition"> 131 2.x 132 </a> 133 134 </div> 135 </div> 136 137 <!-- Mobile Menu Button --> 138 <div class="lg:hidden"> 139 <button id="menu-toggle" class="p-2 rounded-md text-slate-500 hover:bg-slate-100 focus:outline-none"> 140 <svg class="menu-closed:shown h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> 141 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> 142 </svg> 143 <svg class="menu-closed:hidden h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> 144 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> 145 </svg> 146 </button> 147 </div> 148 149 <!-- Desktop Navigation Links --> 150 <nav class="hidden lg:flex items-center space-x-4"> 151 <a href="https://github.com/php-flasher/php-flasher" class="text-slate-600 hover:text-indigo-600 p-2 flex items-center gap-1.5 transition-colors"> 152 <i class="fa-brands fa-github"></i> <span>GitHub</span> 153 </a> 154 <a href="/symfony/" class="text-slate-600 hover:text-indigo-600 p-2 flex items-center gap-1.5 transition-colors"> 155 <i class="fa-duotone fa-book"></i> <span>Documentation</span> 156 </a> 157 <a href="https://www.linkedin.com/in/yoeunes/" class="text-slate-600 hover:text-indigo-600 p-2 flex items-center gap-1.5 transition-colors"> 158 <i class="fa-brands fa-linkedin"></i> <span>Author</span> 159 </a> 160 </nav> 161 </div> 162 </div> 163</header> 164 165 166 167 <div class="container mx-auto px-4 lg:px-6 py-8"> 168 <div class="flex flex-col lg:flex-row gap-8"> 169 <!-- Sidebar Navigation --> 170 <aside class="lg:w-64 shrink-0"> 171 <nav id="main-navigation" class="sticky top-24 hidden lg:block"> 172 <div class="bg-white rounded-xl shadow-sm border border-slate-200 p-4 transition-shadow hover:shadow-md max-h-[calc(100vh-8rem)] overflow-y-auto"> 173 174 <div class="mb-6"> 175 <h3 class="text-xs font-semibold text-indigo-600 uppercase tracking-wider mb-3 flex items-center">
176 <span class="w-1 h-4 bg-indigo-500 inline-block mr-2 rounded"></span> 177 <i class="fa-duotone fa-rocket"></i> Getting Started 178 </h3> 179 <ul class="space-y-1.5"> 180 181 <li> 182 <a href="/" 183 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 184 185 bg-indigo-50 text-indigo-700 font-medium border-l-2 border-indigo-500 pl-2.5 186 "> 187 <i class="fa-duotone fa-book text-indigo-900 mr-1 fa-lg"></i> Introduction 188 </a> 189 </li> 190 191 <li> 192 <a href="/playground/" 193 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 194 195 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 196 "> 197 <i class="fa-duotone fa-flask text-purple-600 mr-1 fa-lg"></i> Playground 198 </a> 199 </li> 200 201 <li> 202 <a href="/symfony/" 203 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 204 205 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 206 "> 207 <i class="fa-brands fa-symfony fa-lg text-black mr-1"></i> Symfony 208 </a> 209 </li> 210 211 <li> 212 <a href="/laravel/" 213 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 214 215 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 216 "> 217 <i class="fa-brands fa-laravel fa-lg text-red-900 mr-1"></i> Laravel 218 </a> 219 </li> 220 221 <li> 222 <a href="/livewire/" 223 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 224 225 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 226 "> 227 <i class="fa-duotone fa-ghost fa-lg text-pink-800 mr-1"></i> Livewire 228 </a> 229 </li> 230 231 <li> 232 <a href="/inertia/" 233 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 234 235 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 236 "> 237 <i class="fa-duotone fa-angles-right fa-lg text-indigo-900 mr-1"></i> Inertia 238 </a> 239 </li> 240 241 </ul> 242 </div> 243 244 <div class="mb-6"> 245 <h3 class="text-xs font-semibold text-indigo-600 uppercase tracking-wider mb-3 flex items-center"> 246 <span class="w-1 h-4 bg-indigo-500 inline-block mr-2 rounded"></span> 247 <i class="fa-duotone fa-plug"></i> 3rd Party 248 </h3> 249 <ul class="space-y-1.5"> 250 251 <li> 252 <a href="/library/noty/" 253 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 254 255 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 256 "> 257 <i class="fa-duotone fa-bell text-indigo-900 mr-1 fa-lg"></i> Noty 258 </a> 259 </li> 260 261 <li> 262 <a href="/library/notyf/" 263 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 264 265 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 266 "> 267 <i class="fa-duotone fa-info-circle text-indigo-900 mr-1 fa-lg"></i> Notyf 268 </a> 269 </li> 270 271 <li> 272 <a href="/library/sweetalert/" 273 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 274 275 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 276 "> 277 <i class="fa-duotone fa-exclamation-circle text-indigo-900 mr-1 fa-lg"></i> Sweetalert 278 </a> 279 </li> 280 281 <li> 282 <a href="/library/toastr/" 283 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 284 285 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 286 "> 287 <i class="fa-duotone fa-bread-loaf text-indigo-900 mr-1 fa-lg"></i> Toastr 288 </a> 289 </li> 290 291 </ul> 292 </div> 293 294 <div class="mb-6"> 295 <h3 class="text-xs font-semibold text-indigo-600 uppercase tracking-wider mb-3 flex items-center">
296 <span class="w-1 h-4 bg-indigo-500 inline-block mr-2 rounded"></span> 297 <i class="fa-duotone fa-palette"></i> Themes <span class="text-xs bg-indigo-500 text-white px-2 py-0.5 rounded-full font-medium ml-1">NEW</span> 298 </h3> 299 <ul class="space-y-1.5"> 300 301 <li> 302 <a href="/themes/" 303 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 304 305 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 306 "> 307 <i class="fa-duotone fa-th-large text-indigo-600 mr-1 fa-lg"></i> All Themes 308 </a> 309 </li> 310 311 <li> 312 <a href="/theme/minimal/" 313 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 314 315 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 316 "> 317 <i class="fa-duotone fa-circle-minus text-indigo-900 mr-1 fa-lg"></i> Minimal 318 </a> 319 </li> 320 321 <li> 322 <a href="/theme/amber/" 323 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 324 325 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 326 "> 327 <i class="fa-duotone fa-sun text-yellow-600 mr-1 fa-lg"></i> Amber 328 </a> 329 </li> 330 331 <li> 332 <a href="/theme/crystal/" 333 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 334 335 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 336 "> 337 <i class="fa-duotone fa-diamond text-indigo-900 mr-1 fa-lg"></i> Crystal 338 </a> 339 </li> 340 341 <li> 342 <a href="/theme/neon/" 343 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 344 345 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 346 "> 347 <i class="fa-duotone fa-lightbulb text-yellow-300 mr-1 fa-lg"></i> Neon 348 </a> 349 </li> 350 351 <li> 352 <a href="/theme/onyx/" 353 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 354 355 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 356 "> 357 <i class="fa-duotone fa-gem text-purple-800 mr-1 fa-lg"></i> Onyx 358 </a> 359 </li> 360 361 <li> 362 <a href="/theme/emerald/" 363 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 364 365 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 366 "> 367 <i class="fa-duotone fa-gem text-green-500 mr-1 fa-lg"></i> Emerald 368 </a> 369 </li> 370 371 <li> 372 <a href="/theme/jade/" 373 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 374 375 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 376 "> 377 <i class="fa-duotone fa-leaf text-green-600 mr-1 fa-lg"></i> Jade 378 </a> 379 </li> 380 381 <li> 382 <a href="/theme/aurora/" 383 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 384 385 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 386 "> 387 <i class="fa-duotone fa-sparkles text-blue-400 mr-1 fa-lg"></i> Aurora 388 </a> 389 </li> 390 391 <li>
392 <a href="/theme/ruby/" 393 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 394 395 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 396 "> 397 <i class="fa-duotone fa-gem text-red-600 mr-1 fa-lg"></i> Ruby 398 </a> 399 </li> 400 401 <li> 402 <a href="/theme/sapphire/" 403 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 404 405 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 406 "> 407 <i class="fa-duotone fa-gem text-blue-500 mr-1 fa-lg"></i> Sapphire 408 </a> 409 </li> 410 411 <li> 412 <a href="/theme/material/" 413 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 414 415 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 416 "> 417 <i class="fa-duotone fa-layer-group text-indigo-900 mr-1 fa-lg"></i> Material 418 </a> 419 </li> 420 421 <li> 422 <a href="/theme/google/" 423 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 424 425 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 426 "> 427 <i class="fa-brands fa-google text-red-500 mr-1 fa-lg"></i> Google 428 </a> 429 </li> 430 431 <li> 432 <a href="/theme/amazon/" 433 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 434 435 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 436 "> 437 <i class="fa-duotone fa-shopping-bag text-indigo-900 mr-1 fa-lg"></i> Amazon 438 </a> 439 </li> 440 441 <li> 442 <a href="/theme/facebook/" 443 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 444 445 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 446 "> 447 <i class="fa-brands fa-facebook text-blue-600 mr-1 fa-lg"></i> Facebook 448 </a> 449 </li> 450 451 <li> 452 <a href="/theme/ios/" 453 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 454 455 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 456 "> 457 <i class="fa-brands fa-apple text-gray-800 mr-1 fa-lg"></i> IOS 458 </a> 459 </li> 460 461 <li> 462 <a href="/theme/slack/" 463 class="flex items-center py-1.5 px-3 rounded-md text-sm leading-tight transition-colors 464 465 text-slate-700 hover:bg-slate-50 hover:text-indigo-700 466 "> 467 <i class="fa-brands fa-slack text-purple-500 mr-1 fa-lg"></i> Slack 468 </a> 469 </li> 470 471 </ul> 472 </div> 473 474 </div> 475</nav> 476 477<!-- Mobile Navigation Menu --> 478<div id="mobile-menu" class="fixed inset-0 z-40 bg-slate-900/50 backdrop-blur-sm hidden"> 479 <div class="fixed right-0 top-0 bottom-0 w-72 bg-white shadow-xl p-5 overflow-y-auto"> 480 <div class="flex justify-between items-center mb-5 border-b border-slate-100 pb-3"> 481 <h2 class="text-lg font-bold text-indigo-900"> 482 PHP<span class="text-indigo-500">Flasher</span>
483 <span class="text-xs font-normal text-slate-500 block mt-0.5">Navigation</span> 484 </h2> 485 <button id="close-menu" class="p-2 text-slate-500 hover:text-slate-700 rounded-full hover:bg-slate-100"> 486 <i class="fa-solid fa-xmark"></i> 487 </button> 488 </div> 489 490 491 <div class="mb-6"> 492 <h3 class="text-xs font-semibold text-indigo-600 uppercase tracking-wider mb-2 flex items-center"> 493 <span class="w-1 h-3 bg-indigo-500 inline-block mr-2 rounded"></span> 494 <i class="fa-duotone fa-rocket"></i> Getting Started 495 </h3> 496 <ul class="space-y-1 pl-3"> 497 498 <li> 499 <a href="/" 500 class="block py-2 text-sm leading-tight 501 502 text-indigo-600 font-medium 503 "> 504 <i class="fa-duotone fa-book text-indigo-900 mr-1 fa-lg"></i> Introduction 505 </a> 506 </li> 507 508 <li> 509 <a href="/playground/" 510 class="block py-2 text-sm leading-tight 511 512 text-slate-700 hover:text-indigo-600 513 "> 514 <i class="fa-duotone fa-flask text-purple-600 mr-1 fa-lg"></i> Playground 515 </a> 516 </li> 517 518 <li> 519 <a href="/symfony/" 520 class="block py-2 text-sm leading-tight 521 522 text-slate-700 hover:text-indigo-600 523 "> 524 <i class="fa-brands fa-symfony fa-lg text-black mr-1"></i> Symfony 525 </a> 526 </li> 527 528 <li> 529 <a href="/laravel/" 530 class="block py-2 text-sm leading-tight 531 532 text-slate-700 hover:text-indigo-600 533 "> 534 <i class="fa-brands fa-laravel fa-lg text-red-900 mr-1"></i> Laravel 535 </a> 536 </li> 537 538 <li> 539 <a href="/livewire/" 540 class="block py-2 text-sm leading-tight 541 542 text-slate-700 hover:text-indigo-600 543 "> 544 <i class="fa-duotone fa-ghost fa-lg text-pink-800 mr-1"></i> Livewire 545 </a> 546 </li> 547 548 <li> 549 <a href="/inertia/" 550 class="block py-2 text-sm leading-tight 551 552 text-slate-700 hover:text-indigo-600 553 "> 554 <i class="fa-duotone fa-angles-right fa-lg text-indigo-900 mr-1"></i> Inertia 555 </a> 556 </li> 557 558 </ul> 559 </div> 560 561 <div class="mb-6"> 562 <h3 class="text-xs font-semibold text-indigo-600 uppercase tracking-wider mb-2 flex items-center"> 563 <span class="w-1 h-3 bg-indigo-500 inline-block mr-2 rounded"></span> 564 <i class="fa-duotone fa-plug"></i> 3rd Party 565 </h3> 566 <ul class="space-y-1 pl-3"> 567 568 <li> 569 <a href="/library/noty/" 570 class="block py-2 text-sm leading-tight 571 572 text-slate-700 hover:text-indigo-600 573 "> 574 <i class="fa-duotone fa-bell text-indigo-900 mr-1 fa-lg"></i> Noty 575 </a> 576 </li> 577 578 <li> 579 <a href="/library/notyf/" 580 class="block py-2 text-sm leading-tight 581 582 text-slate-700 hover:text-indigo-600 583 "> 584 <i class="fa-duotone fa-info-circle text-indigo-900 mr-1 fa-lg"></i> Notyf 585 </a> 586 </li> 587 588 <li> 589 <a href="/library/sweetalert/" 590 class="block py-2 text-sm leading-tight 591 592 text-slate-700 hover:text-indigo-600 593 "> 594 <i class="fa-duotone fa-exclamation-circle text-indigo-900 mr-1 fa-lg"></i> Sweetalert 595 </a> 596 </li> 597 598 <li> 599 <a href="/library/toastr/" 600 class="block py-2 text-sm leading-tight 601 602 text-slate-700 hover:text-indigo-600 603 "> 604 <i class="fa-duotone fa-bread-loaf text-indigo-900 mr-1 fa-lg"></i> Toastr 605 </a> 606 </li> 607 608 </ul> 609 </div> 610 611 <div class="mb-6"> 612 <h3 class="text-xs font-semibold text-indigo-600 uppercase tracking-wider mb-2 flex items-center">
613 <span class="w-1 h-3 bg-indigo-500 inline-block mr-2 rounded"></span> 614 <i class="fa-duotone fa-palette"></i> Themes <span class="text-xs bg-indigo-500 text-white px-2 py-0.5 rounded-full font-medium ml-1">NEW</span> 615 </h3> 616 <ul class="space-y-1 pl-3"> 617 618 <li> 619 <a href="/themes/" 620 class="block py-2 text-sm leading-tight 621 622 text-slate-700 hover:text-indigo-600 623 "> 624 <i class="fa-duotone fa-th-large text-indigo-600 mr-1 fa-lg"></i> All Themes 625 </a> 626 </li> 627 628 <li> 629 <a href="/theme/minimal/" 630 class="block py-2 text-sm leading-tight 631 632 text-slate-700 hover:text-indigo-600 633 "> 634 <i class="fa-duotone fa-circle-minus text-indigo-900 mr-1 fa-lg"></i> Minimal 635 </a> 636 </li> 637 638 <li> 639 <a href="/theme/amber/" 640 class="block py-2 text-sm leading-tight 641 642 text-slate-700 hover:text-indigo-600 643 "> 644 <i class="fa-duotone fa-sun text-yellow-600 mr-1 fa-lg"></i> Amber 645 </a> 646 </li> 647 648 <li> 649 <a href="/theme/crystal/" 650 class="block py-2 text-sm leading-tight 651 652 text-slate-700 hover:text-indigo-600 653 "> 654 <i class="fa-duotone fa-diamond text-indigo-900 mr-1 fa-lg"></i> Crystal 655 </a> 656 </li> 657 658 <li> 659 <a href="/theme/neon/" 660 class="block py-2 text-sm leading-tight 661 662 text-slate-700 hover:text-indigo-600 663 "> 664 <i class="fa-duotone fa-lightbulb text-yellow-300 mr-1 fa-lg"></i> Neon 665 </a> 666 </li> 667 668 <li> 669 <a href="/theme/onyx/" 670 class="block py-2 text-sm leading-tight 671 672 text-slate-700 hover:text-indigo-600 673 "> 674 <i class="fa-duotone fa-gem text-purple-800 mr-1 fa-lg"></i> Onyx 675 </a> 676 </li> 677 678 <li> 679 <a href="/theme/emerald/" 680 class="block py-2 text-sm leading-tight 681 682 text-slate-700 hover:text-indigo-600 683 "> 684 <i class="fa-duotone fa-gem text-green-500 mr-1 fa-lg"></i> Emerald 685 </a> 686 </li> 687 688 <li> 689 <a href="/theme/jade/" 690 class="block py-2 text-sm leading-tight 691 692 text-slate-700 hover:text-indigo-600 693 "> 694 <i class="fa-duotone fa-leaf text-green-600 mr-1 fa-lg"></i> Jade 695 </a> 696 </li> 697 698 <li> 699 <a href="/theme/aurora/" 700 class="block py-2 text-sm leading-tight 701 702 text-slate-700 hover:text-indigo-600 703 "> 704 <i class="fa-duotone fa-sparkles text-blue-400 mr-1 fa-lg"></i> Aurora 705 </a> 706 </li> 707 708 <li>
709 <a href="/theme/ruby/" 710 class="block py-2 text-sm leading-tight 711 712 text-slate-700 hover:text-indigo-600 713 "> 714 <i class="fa-duotone fa-gem text-red-600 mr-1 fa-lg"></i> Ruby 715 </a> 716 </li> 717 718 <li> 719 <a href="/theme/sapphire/" 720 class="block py-2 text-sm leading-tight 721 722 text-slate-700 hover:text-indigo-600 723 "> 724 <i class="fa-duotone fa-gem text-blue-500 mr-1 fa-lg"></i> Sapphire 725 </a> 726 </li> 727 728 <li> 729 <a href="/theme/material/" 730 class="block py-2 text-sm leading-tight 731 732 text-slate-700 hover:text-indigo-600 733 "> 734 <i class="fa-duotone fa-layer-group text-indigo-900 mr-1 fa-lg"></i> Material 735 </a> 736 </li> 737 738 <li> 739 <a href="/theme/google/" 740 class="block py-2 text-sm leading-tight 741 742 text-slate-700 hover:text-indigo-600 743 "> 744 <i class="fa-brands fa-google text-red-500 mr-1 fa-lg"></i> Google 745 </a> 746 </li> 747 748 <li> 749 <a href="/theme/amazon/" 750 class="block py-2 text-sm leading-tight 751 752 text-slate-700 hover:text-indigo-600 753 "> 754 <i class="fa-duotone fa-shopping-bag text-indigo-900 mr-1 fa-lg"></i> Amazon 755 </a> 756 </li> 757 758 <li> 759 <a href="/theme/facebook/" 760 class="block py-2 text-sm leading-tight 761 762 text-slate-700 hover:text-indigo-600 763 "> 764 <i class="fa-brands fa-facebook text-blue-600 mr-1 fa-lg"></i> Facebook 765 </a> 766 </li> 767 768 <li> 769 <a href="/theme/ios/" 770 class="block py-2 text-sm leading-tight 771 772 text-slate-700 hover:text-indigo-600 773 "> 774 <i class="fa-brands fa-apple text-gray-800 mr-1 fa-lg"></i> IOS 775 </a> 776 </li> 777 778 <li> 779 <a href="/theme/slack/" 780 class="block py-2 text-sm leading-tight 781 782 text-slate-700 hover:text-indigo-600 783 "> 784 <i class="fa-brands fa-slack text-purple-500 mr-1 fa-lg"></i> Slack 785 </a> 786 </li> 787 788 </ul> 789 </div> 790 791 792 <div class="mt-8 pt-6 border-t border-slate-100"> 793 <div class="flex justify-around"> 794 <a href="https://github.com/php-flasher/php-flasher" class="p-3 text-indigo-600 hover:bg-indigo-50 rounded-full transition-colors"> 795 <i class="fa-brands fa-github text-xl"></i> 796 </a> 797 <a href="/symfony/" class="p-3 text-indigo-600 hover:bg-indigo-50 rounded-full transition-colors"> 798 <i class="fa-solid fa-book text-xl"></i> 799 </a> 800 <a href="https://www.linkedin.com/in/yoeunes/" class="p-3 text-indigo-600 hover:bg-indigo-50 rounded-full transition-colors"> 801 <i class="fa-brands fa-linkedin text-xl"></i> 802 </a> 803 </div> 804 </div> 805 </div> 806</div> 807 808 </aside> 809 810 <!-- Main Content --> 811 <main class="flex-1 min-w-0"> 812 <div class="bg-white rounded-xl shadow-sm border border-slate-200 p-6"> 813 <div class="prose prose-slate max-w-none"> 814 <div class="bg-gradient-to-r from-indigo-50 to-blue-50 border border-indigo-100 rounded-lg p-4 mb-8 transform transition-all duration-300 hover:shadow-md"> 815 <div class="flex flex-col sm:flex-row items-center gap-4"> 816 <div class="hidden sm:flex items-center justify-center w-12 h-12 bg-indigo-100 rounded-full flex-shrink-0"> 817 <i class="fa-brands fa-github text-indigo-800 text-2xl"></i> 818 </div> 819 <div class="text-center sm:text-left"> 820 <div class="text-slate-700 text-sm leading-relaxed"> 821 Enjoying <strong><span class="text-indigo-900 italic transform -rotate-1 inline-block">PHP<span class="text-indigo-500">Flasher</span></span></strong>? 822 Show your support with a <strong><i class="fa-solid fa-star text-amber-400"></i> star</strong> on 823 <a href="https://github.com/php-flasher/php-flasher" class="text-indigo-700 hover:text-indigo-900 font-medium transition-colors"><i class="fab fa-github text-black"></i> GitHub</a>! 824 <strong class="text-indigo-800">Thank you</strong> <i class="fa-solid fa-heart text-red-600 animate-pulse"></i> 825 </div> 826 </div> 827 <div class="sm:ml-auto flex-shrink-0"> 828 <a href="https://github.com/php-flasher/php-flasher" class="inline-flex items-center px-3 py-1.5 bg-indigo-600 hover:bg-indigo-700 text-white text-sm font-medium rounded-full transition-colors shadow-sm"> 829 <i class="fa-solid fa-star mr-1.5"></i> Star 830 </a> 831 </div> 832 </div> 833</div> 834 835 <div class="container max-w-7xl mx-auto px-4 lg:px-6 py-4"> 836 <!-- Hero Section with Animated Bell in SVG --> 837 <section class="relative overflow-hidden bg-gradient-to-b from-indigo-50 to-white pt-16 pb-12 rounded-3xl mb-16 shadow-sm"> 838 <div class="absolute inset-0 overflow-hidden"> 839 <div class="absolute left-0 top-0 w-1/3 h-1/3 bg-gradient-to-br from-purple-100 to-transparent opacity-60 blur-3xl"></div> 840 <div class="absolute right-0 bottom-0 w-1/3 h-1/3 bg-gradient-to-tl from-indigo-100 to-transparent opacity-60 blur-3xl"></div> 841 </div> 842 843 <div class="relative z-10 container mx-auto px-4"> 844 <div class="text-center"> 845 <div class="flex justify-center mb-8 animate-fade-in"> 846 <div class="relative inline-block"> 847 <svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="320" height="50" viewB
847ox="0 0 5082 781" preserveAspectRatio="xMidYMid meet" class="mx-auto"> 848 <g transform="translate(0.000000,781.000000) scale(0.100000,-0.100000)" fill="#FFFFFF" stroke="none"> 849 <!-- Bell path with animation class --> 850 <path id="bell-icon" class="animate-bell" fill="#4052B5" d="M45570 7540 c-283 -43 -490 -282 -490 -565 0 -200 118 -404 284 -491 31 -16 55 -32 53 -35 -1 -4 -39 -34 -85 -68 -439 -325 -739 -810 -843 -1365 -27 -142 -37 -465 -19 -617 31 -272 65 -381 300 -954 259 -633 265 -653 265 -955 0 -149 -4 -215 -18 -280 -32 -153 -79 -282 -161 -440 -44 -85 -95 -184 -113 -220 -101 -198 -102 -473 -3 -671 115 -230 303 -375 550 -425 98 -19 249 -15 343 10 31 9 363 142 738 296 374 154 683 280 687 280 4 0 16 -30 26 -66 43 -151 158 -332 273 -432 263 -226 594 -301 920 -206 153 44 272 114 392 228 93 90 150 169 205 287 68 144 90 246 89 409 -1 162 -28 283 -96 422 l-42 88 45 19 c25 10 326 135 670 276 344 141 657 273 695 293 102 53 247 200 302 307 60 117 84 203 90 325 13 240 -73 452 -250 616 -94 88 -205 147 -372 198 -66 21 -151 49 -190 63 -322 119 -616 373 -784 677 -27 50 -136 300 -241 554 -206 500 -223 539 -308 676 -338 546 -876 904 -1521 1013 -145 25 -513 24 -653 0 -137 -24 -128 -29 -105 56 32 125 13 277 -51 402 -102 201 -356 329 -582 295z"/> 851 <path fill="#2D264B" d="M19237 6013 c-4 -3 -7 -1252 -7 -2775 l0 -2768 640 0 640 0 0 2775 0 2775 -633 0 c-349 0 -637 -3 -640 -7z"/> 852 <path fill="#2D264B" d="M30710 3245 l0 -2775 640 0 640 0 0 1188 c0 1271 1 1296 51 1444 43 129 97 218 188 308 131 131 259 188 464 210 75 8 131 8 199 1 345 -39 574 -235 670 -576 l23 -80 3 -1247 3 -1248 640 0 640 0 -4 1348 c-3 1322 -3 1349 -25 1479 -84 520 -288 873 -657 1138 -428 307 -1127 349 -1655 99 -185 -88 -377 -237 -503 -394 l-37 -45 0 963 0 962 -640 0 -640 0 0 -2775z"/> 853 <path fill="#4052B5" d="M300 3100 l0 -2630 635 0 635 0 0 944 0 944 538 5 c576 5 639 9 881 63 482 108 880 386 1100 769 100 174 176 412 201 627 18 149 8 429 -20 578 -79 425 -298 769 -636 996 -234 156 -489 250 -832 306 -135 22 -154 22 -1319 25 l-1183 4 0 -2631z m2239 1571 c223 -58 362 -183 427 -385 22 -66 27 -106 31 -216 6 -166 -10 -251 -68 -368 -71 -145 -189 -239 -369 -293 -72 -22 -92 -23 -532 -27 l-458 -3 0 654 c0 359 3 657 7 661 4 4 204 6 443 3 408 -3 440 -5 519 -26z"/> 854 <path fill="#4052B5" d="M4970 3100 l0 -2630 640 0 640 0 0 1085 0 1085 1000 0 1000 0 0 -1085 0 -1085 640 0 640 0 0 2630 0 2630 -640 0 -640 0 0 -1030 0 -1030 -1000 0 -1000 0 0 1030 0 1030 -640 0 -640 0 0 -2630z"/> 855 <path fill="#4052B5" d="M10460 3100 l0 -2630 635 0 635 0 0 944 0 944 538 5 c576 5 639 9 881 63 343 77 630 232 866 469 132 131 199 224 275 380 127 258 177 510 167 834 -8 275 -54 479 -158 700 -141 299 -362 524 -680 690 -181 95 -394 160 -657 203 -135 22 -154 22 -1319 25 l-1183 4 0 -2631z m2239 1571 c115 -30 199 -72 267 -134 126 -114 183 -252 191 -457 15 -357 -130 -578 -437 -671 -72 -22 -92 -23 -532 -27 l-458 -3 0 654 c0 359 3 657 7 661 4 4 204 6 443 3 408 -3 440 -5 519 -26z"/> 856 <path fill="#2D264B" d="M15130 3100 l0 -2630 640 0 640 0 0 1065 0 1065 805 0 805 0 0 495 0 495 -802 2 -803 3 0 555 0 555 1073 3 1072 2 0 510 0 510 -1715 0 -1715 0 0 -2630z"/> 857 <path fill="#2D264B" d="M22776 4695 c-704 -100 -1262 -603 -1481 -1335 -112 -373 -137 -881 -65 -1300 101 -589 393 -1067 829 -1361 433 -292 1009 -369 1511 -203 273 91 532 273 692 487 l58 79 0 -296 0 -296 640 0 640 0 0 2090 0 2090 -640 0 -640 0 -2 -291 -3 -291 -43 61 c-128 182 -349 356 -578 456 -95 41 -223 79 -341 101 -122 22 -447 28 -577 9z m854 -1126 c156 -39 317 -138 441 -274 176 -192 259 -459 246 -790 -12 -304 -95 -519 -270 -702 -135 -140 -281 -223 -456 -258 -128 -26 -337 -17 -451 20 -236 76 -406 216 -520 428 -80 147 -118 301 -127 512 -19 439 134 771 446 963 93 57 239 109 344 122 97 12 254 2 347 -21z"/> 858 <path fill="#2D264B" d="M27855 4699 c-696 -66 -1217 -427 -1369 -950 -36 -124 -50 -261 -42 -408 14 -287 94 -485 266 -661 242 -247 448 -339 1170 -520 456 -115 702 -208 774 -292 122 -142 63 -361 -120 -452 -85 -42 -175 -59 -319 -59 -100 1 -148 6 -208 22 -221 59 -386 215 -428 404 l-12 57 -629 0 -628 0 0 -36 c0 -57 37 -225 71 -321 72 -203 168 -353 334 -518 292 -293 685 -471 1185 -537 124 -16 538 -16 655 0 313 44 578 131 790 262 280 172 467 418 546 717 26 99 36 322 20 446 -41 309 -186 542 -467 753 -171 127 -521 256 -1079 395 -486 122 -635 188 -702 311 -26 48 -25 198 2 253 66 134 232 201 475 192 192 -7 316 -55 430 -167 71 -69 120 -161 144 -272 l6 -28 591 0 591 0 -7 53 c-22
858167 -85 377 -155 517 -100 198 -285 414 -467 543 -225 160 -528 263 -867 296 -126 13 -419 12 -551 0z"/> 859 <path fill="#2D264B" d="M37390 4704 c-340 -40 -571 -103 -813 -225 -298 -150 -537 -361 -724 -639 -204 -305 -321 -686 -342 -1122 -28 -570 90 -1048 357 -1443 192 -285 415 -480 727 -635 228 -113 428 -173 705 -211 144 -20 518 -17 660 4 478 74 859 262 1161 574 164 169 302 371 382 559 38 89 97 259 97 281 0 11 -121 13 -679 13 l-680 0 -38 -72 c-77 -146 -231 -265 -399 -308 -322 -83 -667 18 -843 247 -92 119 -157 290 -177 462 l-7 61 1451 0 1450 0 9 78 c13 120 10 515 -5 627 -69 522 -310 986 -667 1284 -286 238 -615 382 -1020 447 -95 15 -521 28 -605 18z m423 -1040 c221 -46 420 -194 508 -378 39 -81 69 -202 69 -277 l0 -39 -800 0 c-770 0 -800 1 -800 18 0 47 45 186 89 277 115 236 326 380 610 415 82 11 234 3 324 -16z"/> 860 <path fill="#2D264B" d="M42860 4693 c-173 -12 -381 -68 -536 -144 -215 -105 -440 -292 -590 -492 l-74 -98 0 346 0 345 -640 0 -640 0 0 -2090 0 -2090 640 0 640 0 0 1029 c0 884 2 1047 16 1153 9 67 20 128 25 134 5 6 10 20 12 32 2 12 6 25 10 28 4 4 7 15 7 24 0 9 18 52 40 96 101 198 323 325 640 364 46 5 191 10 322 10 l238 0 0 680 0 680 -32 -2 c-18 -1 -53 -3 -78 -5z"/> 861 </g> 862 </svg> 863 </div> 864 </div> 865 866 <h1 class="text-3xl md:text-4xl font-bold text-slate-800 mb-4 tracking-tight"> 867 Beautiful Flash Notifications <span class="text-indigo-600">Made Simple</span> 868 </h1> 869 870 <p class="text-lg text-slate-600 max-w-2xl mx-auto mb-8"> 871 Add elegant notifications to your Laravel or Symfony applications with just <span class="bg-indigo-50 text-indigo-700 px-2 py-1 rounded">one line of code</span>. Perfect for developers of all skill levels. 872 </p> 873 874 <!-- 875 <div class="flex flex-wrap gap-3 justify-center mb-8"> 876 <a href="#quick-start" class="px-5 py-3 bg-indigo-600 hover:bg-indigo-700 text-white font-medium rounded-lg transition-colors duration-200 shadow-md hover:shadow-lg flex items-center"> 877 <i class="fa-solid fa-rocket mr-2"></i> Get Started 878 </a> 879 <a href="https://github.com/php-flasher/php-flasher" class="px-5 py-3 bg-white hover:bg-slate-50 text-slate-700 font-medium rounded-lg border border-slate-200 transition-colors duration-200 flex items-center"> 880 <i class="fa-brands fa-github mr-2"></i> View on GitHub 881 </a> 882 </div> 883 --> 884 885 <div class="flex flex-wrap justify-center gap-3"> 886 <a href="https://www.linkedin.com/in/yoeunes/" class="text-slate-500 hover:text-indigo-700 transition-colors duration-200"> 887 <img src="https://img.shields.io/badge/[email protected]" alt="Author Badge" class="transform hover:scale-105 transition-transform" /> 888 </a> 889 <a href="https://github.com/php-flasher/php-flasher" class="text-slate-500 hover:text-indigo-700 transition-colors duration-200"> 890 <img src="https://img.shields.io/badge/source-php--flasher/php--flasher-blue.svg" alt="Source Code Badge" class="transform hover:scale-105 transition-transform" /> 891 </a> 892 <a href="https://github.com/php-flasher/php-flasher/releases" class="text-slate-500 hover:text-indigo-700 transition-colors duration-200"> 893 <img src="https://img.shields.io/github/tag/php-flasher/flasher.svg" alt="GitHub Release Badge" class="transform hover:scale-105 transition-transform" /> 894 </a> 895 <a href="https://github.com/php-flasher/flasher/blob/master/LICENSE" class="text-slate-500 hover:text-indigo-700 transition-colors duration-200"> 896 <img src="https://img.shields.io/badge/license-MIT-brightgreen.svg" alt="License Badge" class="transform hover:scale-105 transition-transform" /> 897 </a> 898 <a href="https://packagist.org/packages/php-flasher/flasher" class="text-slate-500 hover:text-indigo-700 transition-colors duration-200"> 899 <img src="https://img.shields.io/packagist/dt/php-flasher/flasher.svg" alt="Packagist Downloads Badge" class="transform hover:scale-105 transition-transform" /> 900 </a> 901 <a href="https://github.com/php-flasher/php-flasher" class="text-slate-500 hover:text-indigo-700 transition-colors duration-200"> 902 <img src="https://img.shields.io/github/stars/php-flasher/php-flasher.svg" alt="GitHub Stars Badge" class="transform hover:scale-105 transition-transform" /> 903 </a> 904 <a href="https://packagist.org/packages/php-flasher/flasher" class="text-slate-500 hover:text-indigo-700 transition-colors duration-200"> 905 <img src="https://img.shields.io/packagist/php-v/php-flasher/flasher.svg" alt="Supported PHP Version Badge" class="transform hover:scale-105 transition-transform" /> 906 </a> 907 </div> 908 </div> 909 </div> 910 </section> 911 912 <!-- PHPFlasher Interactive Studio - Enhanced 3.0 --> 913<section data-controller="flasher-studio" class="relative overflow-hidden bg-gradient-to-br from-indigo-50 to-slate-50 py-12 my-8 rounded-2xl"> 914 <!-- Dynamic background elements --> 915 <div class="absolute inset-0 z-0"> 916 <div class="absolute top-0 right-0 w-1/3 h-1/3 bg-gradient-to-br from-indigo-500/10 to-purple-500/10 rounded-full blur-3xl animate-[float_20s_ease-in-out_infinite]"></div> 917 <div class="absolute bottom-0 left-0 w-1/3 h-1/3 bg-gradient-to-tr from-emerald-500/10 to-blue-500/10 rounded-full blur-3xl animate-[float_15s_ease-in-out_infinite_reverse]"></div> 918 919 <!-- Animated floating elements --> 920 <div class="absolute top-[15%] left-[10%] w-16 h-16 rounded-full bg-gradient-to-br from-blue-500/10 to-indigo-500/10 animate-[float_8s_ease-in-out_infinite]"></div> 921 <div class="absolute top-[40%] left-[80%] w-20 h-20 rounded-full bg-gradient-to-br from-green-500/5 to-emerald-500/5 animate-[float_12s_ease-in-out_infinite]"></div> 922 <div class="absolute top-[80%] left-[20%] w-12 h-12 rounded-full bg-gradient-to-br from-amber-500/5 to-orange-500/5 animate-[float_10s_ease-in-out_infinite]"></div> 923 </div> 924 925 <!-- Main content --> 926 <div class="container relative z-10 mx-auto px-4 max-w-7xl"> 927 <!-- Quick Presets --> 928 <div class="mb-6 bg-white rounded-xl shadow-sm border border-slate-200 p-4"> 929 <div class="flex items-center justify-between mb-3"> 930 <h3 class="text-sm font-semibold text-slate-700 flex items-center"> 931 <i class="fas fa-bolt text-amber-500 mr-2"></i> 932 Quick Presets 933 </h3>
934 <span class="text-xs text-slate-500">Common use cases</span> 935 </div> 936 <div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-2"> 937 <button data-preset="user-created" class="preset-btn px-3 py-2 text-xs font-medium rounded-lg bg-emerald-50 text-emerald-700 border border-emerald-200 hover:bg-emerald-100 transition-all"> 938 <i class="fas fa-user-plus mr-1"></i> User Created 939 </button> 940 <button data-preset="payment-failed" class="preset-btn px-3 py-2 text-xs font-medium rounded-lg bg-red-50 text-red-700 border border-red-200 hover:bg-red-100 transition-all"> 941 <i class="fas fa-credit-card mr-1"></i> Payment Failed 942 </button> 943 <button data-preset="login-success" class="preset-btn px-3 py-2 text-xs font-medium rounded-lg bg-blue-50 text-blue-700 border border-blue-200 hover:bg-blue-100 transition-all"> 944 <i class="fas fa-sign-in-alt mr-1"></i> Login Success 945 </button> 946 <button data-preset="validation-error" class="preset-btn px-3 py-2 text-xs font-medium rounded-lg bg-amber-50 text-amber-700 border border-amber-200 hover:bg-amber-100 transition-all"> 947 <i class="fas fa-exclamation-triangle mr-1"></i> Validation Error 948 </button> 949 <button data-preset="order-processing" class="preset-btn px-3 py-2 text-xs font-medium rounded-lg bg-indigo-50 text-indigo-700 border border-indigo-200 hover:bg-indigo-100 transition-all"> 950 <i class="fas fa-shopping-cart mr-1"></i> Order Processing 951 </button> 952 <button data-preset="welcome-message" class="preset-btn px-3 py-2 text-xs font-medium rounded-lg bg-purple-50 text-purple-700 border border-purple-200 hover:bg-purple-100 transition-all"> 953 <i class="fas fa-heart mr-1"></i> Welcome 954 </button> 955 </div> 956 </div> 957 958 <!-- Main interactive area --> 959 <div class="rounded-xl shadow-xl bg-white overflow-hidden backdrop-blur-sm border border-slate-100 transition-all hover:shadow-2xl"> 960 <!-- Toolbar with improved styling --> 961 <div class="bg-gradient-to-r from-slate-800 to-slate-900 border-b border-slate-700 px-6 py-3 flex items-center justify-between"> 962 <div class="flex items-center space-x-2"> 963 <div class="w-3 h-3 rounded-full bg-red-400"></div> 964 <div class="w-3 h-3 rounded-full bg-yellow-400"></div> 965 <div class="w-3 h-3 rounded-full bg-green-400"></div> 966 </div> 967 <div class="text-xs font-medium text-slate-300">PHPFlasher Studio</div> 968 <div id="status-indicator" class="flex items-center space-x-2"> 969 <span id="status-text" class="text-xs text-emerald-400">Ready</span> 970 <div class="w-2 h-2 bg-emerald-500 rounded-full animate-[ping_2.5s_cubic-bezier(0,0,0.2,1)_infinite]"></div> 971 </div> 972 </div> 973 974 <!-- Main content area with tabs --> 975 <div class="flex flex-col xl:flex-row"> 976 <!-- Left panel: Options with improved UI --> 977 <div class="w-full xl:w-2/5 border-r border-slate-100 max-h-[750px] overflow-y-auto"> 978 <!-- Options panel --> 979 <div class="p-5"> 980 <div class="mb-1"> 981 <div class="inline-block px-2 py-1 bg-indigo-50 text-indigo-700 rounded-full text-xs font-medium mb-2">Step 1: Choose Type</div> 982 </div> 983 984 <!-- Notification Type Selection with improved visual appeal --> 985 <div class="mb-6"> 986 <div class="grid grid-cols-4 gap-3 w-full"> 987 <button data-type="success" class="type-button flex flex-col items-center justify-center p-3 rounded-lg bg-emerald-50 border border-emerald-100 hover:bg-emerald-100 transition-all duration-300 active:scale-95 transform border-2 border-emerald-500 shadow-sm">
988 <span class="flex items-center justify-center w-10 h-10 rounded-md bg-emerald-500/90 text-white mb-2"> 989 <i class="fas fa-check text-lg"></i> 990 </span> 991 <span class="text-xs font-medium text-slate-700">Success</span> 992 </button> 993 994 <button data-type="error" class="type-button flex flex-col items-center justify-center p-3 rounded-lg bg-red-50 border border-red-100 hover:bg-red-100 transition-all duration-300 active:scale-95 transform shadow-sm"> 995 <span class="flex items-center justify-center w-10 h-10 rounded-md bg-red-500/90 text-white mb-2"> 996 <i class="fas fa-times text-lg"></i> 997 </span> 998 <span class="text-xs font-medium text-slate-700">Error</span> 999 </button> 1000 1001 <button data-type="info" class="type-button flex flex-col items-center justify-center p-3 rounded-lg bg-blue-50 border border-blue-100 hover:bg-blue-100 transition-all duration-300 active:scale-95 transform shadow-sm"> 1002 <span class="flex items-center justify-center w-10 h-10 rounded-md bg-blue-500/90 text-white mb-2"> 1003 <i class="fas fa-info text-lg"></i> 1004 </span> 1005 <span class="text-xs font-medium text-slate-700">Info</span> 1006 </button> 1007 1008 <button data-type="warning" class="type-button flex flex-col items-center justify-center p-3 rounded-lg bg-amber-50 border border-amber-100 hover:bg-amber-100 transition-all duration-300 active:scale-95 transform shadow-sm"> 1009 <span class="flex items-center justify-center w-10 h-10 rounded-md bg-amber-500/90 text-white mb-2"> 1010 <i class="fas fa-exclamation-triangle text-lg"></i> 1011 </span> 1012 <span class="text-xs font-medium text-slate-700">Warning</span> 1013 </button> 1014 </div> 1015 </div> 1016 1017 <div class="mb-1"> 1018 <div class="inline-block px-2 py-1 bg-indigo-50 text-indigo-700 rounded-full text-xs font-medium mb-2">Step 2: Customize Message</div> 1019 </div> 1020 1021 <!-- Content Section with improved form styling --> 1022 <div class="mb-6 space-y-4"> 1023 <div> 1024 <div class="flex items-center justify-between mb-2"> 1025 <label for="title-input" class="block text-sm font-medium text-slate-700">Title</label> 1026 <span class="text-xs text-slate-400 bg-slate-50 px-2 py-0.5 rounded">Optional</span> 1027 </div> 1028 <input 1029 id="title-input" 1030 type="text" 1031 class="w-full px-3 py-2.5 bg-slate-50 border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all duration-300" 1032 placeholder="Enter notification title" 1033 value=""> 1034 </div> 1035 1036 <div> 1037 <label for="message-input" class="block mb-2 text-sm font-medium text-slate-700">Message</label> 1038 <input id="message-input" 1039 type="text" 1040 class="w-full px-3 py-2.5 bg-slate-50 border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all duration-300" 1041 placeholder="Enter your notification message" 1042 value="Your product has been created successfully!"> 1043 </div> 1044 </div> 1045 1046 <div class="mb-1"> 1047 <div class="inline-block px-2 py-1 bg-indigo-50 text-indigo-700 rounded-full text-xs font-medium mb-2">Step 3: Advanced Options</div> 1048 </div> 1049 1050 <!-- Configuration Options --> 1051 <div class="px-3 py-3 mb-3 bg-slate-50 rounded-lg border border-slate-100"> 1052 <div class="grid grid-cols-2 gap-3 mb-4"> 1053 <div> 1054 <label for="position-select" class="block mb-1.5 text-sm font-medium text-slate-700">Position</label> 1055 <div class="relative"> 1056 <select id="position-select" class="w-full appearance-none px-3 py-2.5 bg-white border border-slate-200 rounded-lg pr-10 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all duration-300"> 1057 <option value="">Default</option> 1058 <option value="top-right">Top Right</option> 1059 <option value="top-left">
1059Top Left</option> 1060 <option value="bottom-right">Bottom Right</option> 1061 <option value="bottom-left">Bottom Left</option> 1062 <option value="center-top">Center Top</option> 1063 <option value="center-bottom">Center Bottom</option> 1064 </select> 1065 <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-slate-400"> 1066 <i class="fas fa-chevron-down text-xs"></i> 1067 </div> 1068 </div> 1069 </div> 1070 <div> 1071 <label for="timeout-select" class="block mb-1.5 text-sm font-medium text-slate-700">Duration</label> 1072 <div class="relative"> 1073 <select id="timeout-select" class="w-full appearance-none px-3 py-2.5 bg-white border border-slate-200 rounded-lg pr-10 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all duration-300"> 1074 <option value="">Default</option> 1075 <option value="30000">30 seconds</option> 1076 <option value="10000">10 seconds</option> 1077 <option value="5000">5 seconds</option> 1078 <option value="3000">3 seconds</option> 1079 <option value="false">Sticky</option> 1080 </select> 1081 <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-slate-400"> 1082 <i class="fas fa-chevron-down text-xs"></i> 1083 </div> 1084 </div> 1085 </div> 1086 </div> 1087 1088 <div class="grid grid-cols-2 gap-3 mb-4"> 1089 <div> 1090 <label for="theme-select" class="block mb-1.5 text-sm font-medium text-slate-700">Theme</label> 1091 <div class="relative"> 1092 <select id="theme-select" class="w-full appearance-none px-3 py-2.5 bg-white border border-slate-200 rounded-lg pr-10 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all duration-300"> 1093 <option value="">Default</option> 1094 <option value="material">Material</option> 1095 <option value="minimal">Minimal</option> 1096 <option value="neon">Neon</option> 1097 <option value="ios">iOS</option> 1098 <option value="slack">Slack</option> 1099 <option value="facebook">Facebook</option> 1100 <option value="google">Google</option> 1101 <option value="amazon">Amazon</option> 1102 <option value="ruby">Ruby</option> 1103 <option value="jade">Jade</option> 1104 <option value="aurora">Aurora</option> 1105 <option value="sapphire">Sapphire</option> 1106 <option value="onyx">Onyx</option> 1107 <option value="amber">Amber</option> 1108 <option value="emerald">Emerald</option> 1109 <option value="flasher">Flasher</option> 1110 <option value="crystal">Crystal</option> 1111 </select> 1112 <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-slate-400"> 1113 <i class="fas fa-chevron-down text-xs"></i> 1114 </div> 1115 </div> 1116 </div> 1117 <div> 1118 <label for="direction-select" class="block mb-1.5 text-sm font-medium text-slate-700">Direction</label> 1119 <div class="relative"> 1120 <select id="direction-select" class="w-full appearance-none px-3 py-2.5 bg-white border border-slate-200 rounded-lg pr-10 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all duration-300"> 1121 <option value="">Default</option> 1122 <option value="top">Top</option> 1123 <option value="bottom">Bottom</option> 1124 </select> 1125 <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-slate-400"> 1126 <i class="fas fa-chevron-down text-xs"></i> 1127 </div> 1128 </div> 1129 </div> 1130 </div> 1131 1132 <div class="mt-4 grid grid-cols-2 gap-3"> 1133 <div class="flex items-center"> 1134 <input type="checkbox" id="rtl-check" class="h-4 w-4 roun
1134ded border-slate-300 text-indigo-600 focus:ring-indigo-500 transition"> 1135 <label for="rtl-check" class="ml-2 text-sm text-slate-700">RTL Layout</label> 1136 </div> 1137 <div class="flex items-center"> 1138 <input type="checkbox" id="escape-html-check" class="h-4 w-4 rounded border-slate-300 text-indigo-600 focus:ring-indigo-500 transition" checked> 1139 <label for="escape-html-check" class="ml-2 text-sm text-slate-700">Escape HTML</label> 1140 </div> 1141 </div> 1142 </div> 1143 1144 <!-- Preview & Launch buttons - enhanced with better visual hierarchy --> 1145 <div class="flex gap-2"> 1146 <button id="show-notification-btn" class="flex-1 group relative overflow-hidden rounded-lg shadow-md"> 1147 <span class="absolute inset-0 bg-gradient-to-r from-indigo-600 to-purple-600 group-hover:from-indigo-700 group-hover:to-purple-700 transition-all duration-300"></span> 1148 <span class="relative px-5 py-3.5 flex items-center justify-center text-white font-medium"> 1149 <i class="fas fa-bell mr-2"></i> 1150 <span>Show Notification</span> 1151 </span> 1152 <span class="absolute top-0 -inset-full h-full w-1/2 block transform -skew-x-12 bg-gradient-to-r from-transparent to-white opacity-20 group-hover:animate-[shine_1s_forwards]"></span> 1153 </button> 1154 </div> 1155 </div> 1156 </div> 1157 1158 <!-- Right panel: Code Preview --> 1159 <div class="w-full xl:w-3/5" style="background: #f5f2f0; border: none; box-sizing: unset;"> 1160 <div class="border-b border-slate-200 px-6 py-3 flex flex-col sm:flex-row items-start sm:items-center justify-between bg-slate-50 gap-2"> 1161 <div class="text-sm font-medium text-slate-700">Generated Code</div> 1162 <div class="flex items-center gap-2"> 1163 <button id="compare-btn" class="text-xs text-slate-600 hover:text-indigo-600 transition-colors flex items-center px-2 py-1 rounded hover:bg-slate-100"> 1164 <i class="fas fa-columns mr-1"></i> Compare 1165 </button> 1166 <div class="text-xs text-slate-400">Copy-paste into your project</div> 1167 </div> 1168 </div> 1169 1170 <!-- Code tabs with improved styling --> 1171 <div class="flex flex-wrap border-b border-slate-200 bg-slate-50"> 1172 <button id="laravel-tab" data-tab="laravel" class="code-tab-btn px-4 py-3 text-sm font-medium text-indigo-600 border-b-2 border-indigo-600 flex items-center space-x-2"> 1173 <i class="fab fa-laravel text-red-500"></i> 1174 <span>Laravel</span> 1175 </button> 1176 <button id="symfony-tab" data-tab="symfony" class="code-tab-btn px-4 py-3 text-sm font-medium text-slate-600 hover:text-slate-800 flex items-center space-x-2"> 1177 <i class="fab fa-symfony text-black"></i> 1178 <span>Symfony</span> 1179 </button> 1180 <button id="js-tab" data-tab="js" class="code-tab-btn px-4 py-3 text-sm font-medium text-slate-600 hover:text-slate-800 flex items-center space-x-2"> 1181 <i class="fab fa-js text-yellow-500"></i> 1182 <span>JavaScript</span> 1183 </button> 1184 <button id="noty-tab" data-tab="noty" class="code-tab-btn px-4 py-3 text-sm font-medium text-slate-600 hover:text-slate-800 flex items-center space-x-2">
1185 <span class="w-4 h-4 bg-blue-500 rounded text-white text-xs flex items-center justify-center">N</span> 1186 <span>Noty</span> 1187 </button> 1188 <button id="toastr-tab" data-tab="toastr" class="code-tab-btn px-4 py-3 text-sm font-medium text-slate-600 hover:text-slate-800 flex items-center space-x-2"> 1189 <span class="w-4 h-4 bg-orange-500 rounded text-white text-xs flex items-center justify-center">T</span> 1190 <span>Toastr</span> 1191 </button> 1192 <button id="sweetalert-tab" data-tab="sweetalert" class="code-tab-btn px-4 py-3 text-sm font-medium text-slate-600 hover:text-slate-800 flex items-center space-x-2"> 1193 <span class="w-4 h-4 bg-pink-500 rounded text-white text-xs flex items-center justify-center">S</span> 1194 <span>SweetAlert</span> 1195 </button> 1196 </div> 1197 1198 <!-- Code animation wrapper with improved styles --> 1199 <div id="code-display-wrapper" class="relative"> 1200 <!-- Laravel Code Panel --> 1201 <div id="laravel-code-panel" class="bg-gray-50 overflow-y-auto code-panel active p-4"> 1202 <!-- Code will be inserted here by JavaScript --> 1203 </div> 1204 1205 <!-- Symfony Code Panel --> 1206 <div id="symfony-code-panel" class="bg-gray-50 overflow-y-auto hidden code-panel p-4"> 1207 <!-- Code will be inserted here by JavaScript --> 1208 </div> 1209 1210 <!-- JavaScript Code Panel --> 1211 <div id="js-code-panel" class="bg-gray-50 overflow-y-auto hidden code-panel p-4"> 1212 <!-- Code will be inserted here by JavaScript --> 1213 </div> 1214 1215 <!-- Noty Code Panel (New) --> 1216 <div id="noty-code-panel" class="bg-gray-50 overflow-y-auto hidden code-panel p-4"> 1217 <!-- Code will be inserted here by JavaScript --> 1218 </div> 1219 1220 <!-- Toastr Code Panel (New) --> 1221 <div id="toastr-code-panel" class="bg-gray-50 overflow-y-auto hidden code-panel p-4"> 1222 <!-- Code will be inserted here by JavaScript --> 1223 </div> 1224 1225 <!-- SweetAlert Code Panel (New) --> 1226 <div id="sweetalert-code-panel" class="bg-gray-50 overflow-y-auto hidden code-panel p-4"> 1227 <!-- Code will be inserted here by JavaScript --> 1228 </div> 1229 1230 <!-- Animation overlay --> 1231 <div id="animation-layer" class="absolute top-0 left-0 w-full h-full pointer-events-none"></div> 1232 </div> 1233 1234 <!-- Code Comparison Modal (New) --> 1235 <div id="comparison-modal" class="hidden fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"> 1236 <div class="bg-white rounded-xl shadow-2xl max-w-6xl w-full max-h-[90vh] overflow-hidden"> 1237 <div class="flex items-center justify-between px-6 py-4 border-b border-slate-200"> 1238 <h3 class="text-lg font-semibold text-slate-800">Code Comparison: Before vs After PHPFlasher</h3> 1239 <button id="close-comparison-btn" class="text-slate-400 hover:text-slate-600 transition-colors"> 1240 <i class="fas fa-times text-xl"></i> 1241 </button> 1242 </div> 1243 <div class="grid grid-cols-2 divide-x divide-slate-200 max-h-[70vh] overflow-y-auto"> 1244 <div class="p-4"> 1245 <h4 class="text-sm font-medium text-red-600 mb-2 flex items-center"> 1246 <i class="fas fa-times-circle mr-2"></i> Before PHPFlasher 1247 </h4> 1248 <pre id="before-code" class="bg-red-50 rounded-lg p-4 text-sm overflow-x-auto"><code></code></pre> 1249 </div> 1250 <div class="p-4"> 1251 <h4 class="text-sm font-medium text-green-600 mb-2 flex items-center"> 1252 <i class="fas fa-check-circle mr-2"></i> After PHPFlasher 1253 </h4> 1254 <pre id="after-code" class="bg-green-50 rounded-lg p-4 text-sm overflow-x-auto"><code></code></pre> 1255 </div> 1256 </div> 1257 </div> 1258 </div> 1259 </div> 1260 </div> 1261 1262 <!-- Footer with improved design --> 1263 <div class="px-6 py-3.5 bg-slate-50 border-t border-slate-200 flex flex-col sm:flex-row items-center justify-between gap-3"> 1264 <div class="text-xs text-slate-500">Customize your perfect notification in seconds</div> 1265 <div class="flex space-x-4"> 1266 <a href="https://php-flasher.io" class="text-xs text-slate-600 hover:text-indigo-600 transition-colors flex items-center hover:underline"> 1267 <i class="fas fa-book mr-1.5 text-xs"></i> Documentation 1268 </a> 1269 <a href="https://github.com/php-flasher/php-flasher" class="text-xs text-slate-600 hover:text-indigo-600 transition-colors flex items-center hover:underline"> 1270 <i class="fab fa-github mr-1.5 text-xs"></i> GitHub 1271 </a> 1272 <a href="https://php-flasher.io/symfony/" class="text-xs text-slate-600 hover:text-indigo-600 transition-colors flex items-center hover:underline"> 1273 <i class="fas fa-lightbulb mr-1.5 text-xs"></i> Examples 1274 </a> 1275 </div> 1276 </div> 1277 </div> 1278 </div> 1279</section> 1280 1281<style> 1282 /* Base styles */ 1283 :root { 1284 --primary-color: #4F46E5; 1285 --success-color: #10B981; 1286 --error-color: #EF4444; 1287 --info-color: #3B82F6; 1288 --warning-color: #F59E0B; 1289 --highlight-color: rgba(16, 185, 129, 0.1); 1290 } 1291 1292 body { 1293 font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 1294 } 1295 1296 /* Custom animations */
1297 @keyframes shine { 1298 to { 1299 left: 100%; 1300 } 1301 } 1302 1303 @keyframes ping { 1304 0% { 1305 transform: scale(1); 1306 opacity: 1; 1307 } 1308 75%, 100% { 1309 transform: scale(2); 1310 opacity: 0; 1311 } 1312 } 1313 1314 @keyframes float { 1315 0%, 100% { transform: translateY(0); } 1316 50% { transform: translateY(-15px); } 1317 } 1318 1319 /* Code style improvements */ 1320 pre code { 1321 font-family: 'JetBrains Mono', 'Fira Code', monospace !important; 1322 font-size: 0.9rem; 1323 } 1324 1325 /* Preset button styles */ 1326 .preset-btn { 1327 transition: all 0.2s ease; 1328 } 1329 1330 .preset-btn:hover { 1331 transform: translateY(-1px); 1332 } 1333 1334 /* Type button styles */ 1335 .type-button { 1336 transition: all 0.3s ease; 1337 position: relative; 1338 } 1339 1340 .type-button:hover { 1341 transform: translateY(-3px); 1342 box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); 1343 } 1344 1345 .type-button::after { 1346 content: ''; 1347 position: absolute; 1348 inset: 0; 1349 border-radius: 8px; 1350 opacity: 0; 1351 transition: opacity 0.3s ease; 1352 box-shadow: 0 0 0 2px var(--primary-color); 1353 } 1354 1355 .type-button:focus::after { 1356 opacity: 1; 1357 } 1358 1359 /* Code panel enhancements */ 1360 .code-panel { 1361 transition: opacity 0.3s ease; 1362 min-height: 300px; 1363 max-height: 500px; 1364 overflow-y: auto; 1365 } 1366 1367 .code-panel.hidden { 1368 opacity: 0; 1369 } 1370 1371 .code-panel.active { 1372 opacity: 1; 1373 } 1374 1375 /* Typing container styles */ 1376 .typing-container { 1377 line-height: 1.4; 1378 overflow: visible; 1379 font-family: 'JetBrains Mono', 'Fira Code', monospace; 1380 } 1381 1382 #code-display-wrapper { 1383 background-color: #f5f2f0; 1384 } 1385 1386 /* Cursor animation */ 1387 .cursor { 1388 display: inline-block; 1389 width: 3px; 1390 height: 1em; 1391 background-color: var(--primary-color); 1392 margin-left: 4px; 1393 animation: blink 1s infinite; 1394 vertical-align: middle; 1395 position: relative; 1396 top: -1em; 1397 } 1398 1399 @keyframes blink { 1400 0%, 100% { 1401 opacity: 1; 1402 } 1403 50% { 1404 opacity: 0; 1405 } 1406 } 1407 1408 /* Mobile responsive adjustments */ 1409 @media (max-width: 768px) { 1410 .code-panel { 1411 height: 350px !important; 1412 } 1413 1414 .code-tab-btn { 1415 padding: 0.75rem 0.5rem; 1416 font-size: 0.75rem; 1417 } 1418 1419 .code-tab-btn span:last-child { 1420 display: none; 1421 } 1422 } 1423 1424 /* Comparison modal animation */ 1425 #comparison-modal { 1426 animation: fadeIn 0.2s ease-out; 1427 } 1428 1429 @keyframes fadeIn { 1430 from { 1431 opacity: 0; 1432 } 1433 to { 1434 opacity: 1; 1435 } 1436 } 1437 1438 /* Scrollbar styling for code panels */ 1439 .code-panel::-webkit-scrollbar {
1440 width: 8px; 1441 } 1442 1443 .code-panel::-webkit-scrollbar-track { 1444 background: #f1f1f1; 1445 border-radius: 4px; 1446 } 1447 1448 .code-panel::-webkit-scrollbar-thumb { 1449 background: #cbd5e1; 1450 border-radius: 4px; 1451 } 1452 1453 .code-panel::-webkit-scrollbar-thumb:hover { 1454 background: #94a3b8; 1455 } 1456</style> 1457
1458<script> 1459 /** 1460 * PHPFlasher Interactive Studio - Enhanced Edition 3.0 1461 * 1462 * Features: 1463 * - Real-time code generation with typing animation 1464 * - Context-aware examples for different notification types 1465 * - Advanced animations and transitions 1466 * - Clean and concise code examples 1467 * - Copy to clipboard functionality 1468 * - Quick presets for common use cases 1469 * - Multiple adapter support (Laravel, Symfony, JS, Noty, Toastr, SweetAlert) 1470 * - Code comparison view 1471 * - Mobile responsive design 1472 */ 1473 1474 // Quick Presets Configuration 1475 const presets = { 1476 'user-created': { 1477 type: 'success', 1478 title: 'User Created', 1479 message: 'User account created successfully! You can now log in.' 1480 }, 1481 'payment-failed': { 1482 type: 'error', 1483 title: 'Payment Failed', 1484 message: 'Your payment could not be processed. Please try again or use a different payment method.' 1485 }, 1486 'login-success': { 1487 type: 'success', 1488 title: 'Welcome Back!', 1489 message: 'You have successfully logged in.' 1490 }, 1491 'validation-error': { 1492 type: 'warning', 1493 title: 'Validation Error', 1494 message: 'Please check the form for errors and try again.' 1495 }, 1496 'order-processing': { 1497 type: 'info', 1498 title: 'Order Processing', 1499 message: 'Your order is being processed. You will receive a confirmation email shortly.' 1500 }, 1501 'welcome-message': { 1502 type: 'success', 1503 title: 'Welcome!', 1504 message: 'Thank you for joining us. Get started by exploring our features.' 1505 } 1506 }; 1507 1508 // Before/After Code Examples for Comparison 1509 const beforeAfterExamples = { 1510 success: { 1511 before: `// WITHOUT PHPFlasher - Multiple lines needed 1512session()->flash('success', 'Product created!'); 1513return redirect()->back(); 1514 1515// In your Blade template: 1516@if(session('success')) 1517 <div class="alert alert-success"> 1518 1519 </div> 1520@endif`, 1521 after: `// WITH PHPFlasher - One simple line 1522flash()->success('Product created successfully!'); 1523 1524// That's it! No template code needed.` 1525 }, 1526 error: { 1527 before: `// WITHOUT PHPFlasher 1528return redirect()->back() 1529 ->with('error', 'Payment failed!') 1530 ->with('error_code', 'CARD_DECLINED'); 1531 1532// Template: 1533@if(session('error')) 1534 <div class="alert alert-danger" data-code=""> 1535 1536 </div> 1537@endif`, 1538 after: `// WITH PHPFlasher - Clean & simple 1539flash()->error('Payment failed!', [], 'Error'); 1540flash()->option('timeout', 10000); 1541 1542// Auto-dismisses after 10 seconds` 1543 }, 1544 info: { 1545 before: `// WITHOUT PHPFlasher - Manual notification system 1546$notification = new Notification(); 1547$notification->type = 'info'; 1548$notification->message = 'Order processing...'; 1549$notification->save(); 1550 1551// Complex template rendering...`, 1552 after: `// WITH PHPFlasher - Instant feedback 1553flash()->info('Your order is being processed.', [], 'Order Status'); 1554 1555// Beautiful, animated notification instantly` 1556 }, 1557 warning: { 1558 before: `// WITHOUT PHPFlasher 1559Session::put('warning', 'Account expiring soon!'); 1560Session::put('days_left', 3); 1561 1562// Template checks and rendering...`, 1563 after: `// WITH PHPFlasher - Simple & effective 1564flash()->warning('Your account will expire in 3 days.', [], 'Account Expiring'); 1565 1566// Professional warning with minimal code` 1567 } 1568 }; 1569 1570 // State Management 1571 const createStateProxy = () => { 1572 const stateTarget = { 1573 type: "success", 1574 title: "", 1575 message: "Your product has been created successfully!", 1576 timeout: "", 1577 position: "", 1578 direction: "", 1579 rtl: false, 1580 theme: "", 1581 escapeHtml: true, 1582 _previousState: {}, 1583 _animationInProgress: false, 1584 }; 1585 return new Proxy(stateTarget, { 1586 set(target, property, value) { 1587 if (property !== "_previousState" && property !== "_animationInProgress") { 1588 target._previousState[property] = target[property]; 1589 } 1590 target[property] = value; 1591 if (document.readyState === "complete" && property !== "_previousState" && property !== "_animationInProgress") { 1592 if (property === "type") { 1593 updateStatus("Changing template..."); 1594 } 1595 updateCodeDisplay(true); 1596 } 1597 return true; 1598 } 1599 }); 1600 }; 1601 const state = createStateProxy(); 1602 1603 // Context Templates for Code Generation 1604 const contextTemplates = { 1605 success: { 1606 laravel: { 1607 title: "Success", 1608 message: "Your product has been created successfully!", 1609 controller: "ProductController", 1610 method: "store", 1611 code: { 1612 before: `// ProductController.php 1613namespace App\\Http\\Controllers; 1614 1615use App\\Models\\Product; 1616use App\\Http\\Requests\\ProductRequest; 1617 1618class ProductController extends Controller 1619{ 1620 public function store(ProductRequest $request) 1621 { 1622 // Create product 1623 $product = Product::create($request->validated()); 1624`, 1625 after: ` 1626 return redirect()->route('products.index'); 1627 } 1628}` 1629 } 1630 }, 1631 symfony: { 1632 title: "Success", 1633 message: "Your product has been created successfully!", 1634 controller: "ProductController", 1635 method: "create", 1636 code: { 1637 before: `// ProductController.php 1638namespace App\\Controller; 1639 1640use App\\Entity\\Product; 1641use Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController; 1642 1643class ProductController extends AbstractController 1644{ 1645 #[Route('/product/new', name: 'app_product_create')] 1646 public function create(Request $request): Response 1647 { 1648 // Process form & save product 1649 $product = new Product(); 1650`, 1651 after: ` 1652 return $this->redirectToRoute('app_product_index'); 1653 } 1654}` 1655 } 1656 }, 1657 js: { 1658 title: "Success", 1659 message: "Your product has been created successfully!", 1660 file: "product-service.js", 1661 method: "createProduct", 1662 code: { 1663 before: `// product-service.js 1664import flasher from '@flasher/flasher'; 1665 1666async function createProduct(data) { 1667 try { 1668 const response = await api.post('/products', data); 1669`, 1670 after: ` 1671 return response.data; 1672 } catch (error) { 1673 flasher.error('Failed to create product'); 1674 throw error; 1675 } 1676}` 1677 } 1678 }, 1679 noty: { 1680 title: "Success", 1681 message: "Your product has been created successfully!", 1682 code: { 1683 before: `// Noty adapter 1684import Noty from 'noty'; 1685 1686`, 1687 after: ` 1688new Noty({ 1689 type: 'success', 1690 text: 'Your product has been created successfully!', 1691 timeout: 3000 1692}).show();` 1693 } 1694 }, 1695 toastr: { 1696 title: "Success", 1697 message: "Your product has been created successfully!", 1698 code: { 1699 before: `// Toastr adapter 1700import toastr from 'toastr'; 1701 1702`, 1703 after: ` 1704toastr.success('Your product has been created successfully!');` 1705 } 1706 }, 1707 sweetalert: { 1708 title: "Success", 1709 message: "Your product has been created successfully!", 1710 code: { 1711 before: `// SweetAlert adapter 1712import Swal from 'sweetalert2'; 1713 1714`, 1715 after: ` 1716Swal.fire({ 1717 icon: 'success', 1718 title: 'Success', 1719 text: 'Your product has been created successfully!', 1720 timer: 3000 1721});` 1722 } 1723 } 1724 }, 1725 error: { 1726 laravel: { 1727 title: "Error", 1728 message: "An error occurred while processing your request.", 1729 controller: "PaymentController", 1730 method: "process", 1731 code: { 1732 before: `// PaymentController.php 1733namespace App\\Http\\Controllers; 1734 1735use App\\Services\\PaymentGateway; 1736 1737class PaymentController extends Controller 1738{ 1739 public function process(Request $request) 1740 { 1741 try { 1742 $result = $this->paymentGateway->charge($request->token); 1743 } catch (\\Exception $e) { 1744`, 1745 after: ` 1746 return back(); 1747 } 1748 1749 return redirect()->route('payment.success'); 1750 } 1751}` 1752 } 1753 }, 1754 symfony: { 1755 title: "Error", 1756 message: "An error occurred while processing your request.", 1757 controller: "PaymentController", 1758 method: "process", 1759 code: { 1760 before: `// PaymentController.php 1761namespace App\\Controller; 1762 1763use Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController; 1764 1765class PaymentController extends AbstractController 1766{ 1767 public function process(Request $request): Response 1768 { 1769 try { 1770 $payment = $this->paymentService->process($request->get('token')); 1771 } catch (\\Exception $e) { 1772`, 1773 after: ` 1774 return $this->redirectToRoute('payment_form'); 1775 } 1776 1777 return $this->redirectToRoute('payment_success'); 1778 } 1779}` 1780 } 1781 }, 1782 js: { 1783 title: "Error", 1784 message: "An error occurred while processing your request.", 1785 file: "payment-service.js", 1786 method: "processPayment", 1787 code: { 1788 before: `// payment-service.js 1789import flasher from '@flasher/flasher'; 1790 1791async function processPayment(paymentData) { 1792 try { 1793 const response = await api.post('/payments', paymentData); 1794 if (!response.ok) { 1795`, 1796 after: ` 1797 return false;
1798 } 1799 return response.data; 1800 } catch (error) { 1801 console.error(error); 1802 return false; 1803 } 1804}` 1805 } 1806 }, 1807 noty: { 1808 title: "Error", 1809 message: "An error occurred while processing your request.", 1810 code: { 1811 before: `// Noty adapter 1812import Noty from 'noty'; 1813 1814`, 1815 after: ` 1816new Noty({ 1817 type: 'error', 1818 text: 'An error occurred while processing your request.', 1819 timeout: 5000 1820}).show();` 1821 } 1822 }, 1823 toastr: { 1824 title: "Error", 1825 message: "An error occurred while processing your request.", 1826 code: { 1827 before: `// Toastr adapter 1828import toastr from 'toastr'; 1829 1830`, 1831 after: ` 1832toastr.error('An error occurred while processing your request.');` 1833 } 1834 }, 1835 sweetalert: { 1836 title: "Error", 1837 message: "An error occurred while processing your request.", 1838 code: { 1839 before: `// SweetAlert adapter 1840import Swal from 'sweetalert2'; 1841 1842`, 1843 after: ` 1844Swal.fire({ 1845 icon: 'error', 1846 title: 'Error', 1847 text: 'An error occurred while processing your request.' 1848});` 1849 } 1850 } 1851 }, 1852 info: { 1853 laravel: { 1854 title: "Information", 1855 message: "Your order is being processed.", 1856 controller: "OrderController", 1857 method: "submit", 1858 code: { 1859 before: `// OrderController.php 1860namespace App\\Http\\Controllers; 1861 1862use App\\Models\\Order; 1863 1864class OrderController extends Controller 1865{ 1866 public function submit(Request $request) 1867 { 1868 // Create and save order 1869 $order = Order::create($request->validated()); 1870`, 1871 after: ` 1872 // Send to processing queue 1873 ProcessOrderJob::dispatch($order); 1874 1875 return redirect()->route('orders.show', $order); 1876 } 1877}` 1878 } 1879 }, 1880 symfony: { 1881 title: "Information", 1882 message: "Your order is being processed.", 1883 controller: "OrderController", 1884 method: "create", 1885 code: { 1886 before: `// OrderController.php 1887namespace App\\Controller; 1888 1889use App\\Entity\\Order; 1890use Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController; 1891 1892class OrderController extends AbstractController 1893{ 1894 public function create(Request $request): Response 1895 { 1896 // Create and save order 1897 $order = new Order(); 1898 // ... set order properties 1899 $this->entityManager->persist($order); 1900 $this->entityManager->flush(); 1901`, 1902 after: ` 1903 // Dispatch order processing 1904 $this->messageBus->
1904dispatch(new ProcessOrder($order->getId())); 1905 1906 return $this->redirectToRoute('app_order_show', [ 1907 'id' => $order->getId() 1908 ]); 1909 } 1910}` 1911 } 1912 }, 1913 js: { 1914 title: "Information", 1915 message: "Your order is being processed.", 1916 file: "order-service.js", 1917 method: "submitOrder", 1918 code: { 1919 before: `// order-service.js 1920import flasher from '@flasher/flasher'; 1921 1922async function submitOrder(orderData) { 1923 try { 1924 const response = await api.post('/orders', orderData); 1925 const order = response.data; 1926`, 1927 after: ` 1928 // Track order 1929 analytics.trackOrder(order.id); 1930 return order; 1931 } catch (error) { 1932 flasher.error('Order submission failed'); 1933 throw error; 1934 } 1935}` 1936 } 1937 }, 1938 noty: { 1939 title: "Information", 1940 message: "Your order is being processed.", 1941 code: { 1942 before: `// Noty adapter 1943import Noty from 'noty'; 1944 1945`, 1946 after: ` 1947new Noty({ 1948 type: 'info', 1949 text: 'Your order is being processed.', 1950 timeout: 4000 1951}).show();` 1952 } 1953 }, 1954 toastr: { 1955 title: "Information", 1956 message: "Your order is being processed.", 1957 code: { 1958 before: `// Toastr adapter 1959import toastr from 'toastr'; 1960 1961`, 1962 after: ` 1963toastr.info('Your order is being processed.');` 1964 } 1965 }, 1966 sweetalert: { 1967 title: "Information", 1968 message: "Your order is being processed.", 1969 code: { 1970 before: `// SweetAlert adapter 1971import Swal from 'sweetalert2'; 1972 1973`, 1974 after: ` 1975Swal.fire({ 1976 icon: 'info', 1977 title: 'Information', 1978 text: 'Your order is being processed.', 1979 timer: 4000 1980});` 1981 } 1982 } 1983 }, 1984 warning: { 1985 laravel: { 1986 title: "Warning", 1987 message: "Your account will expire in 3 days.", 1988 controller: "AccountController", 1989 method: "dashboard", 1990 code: { 1991 before: `// AccountController.php 1992namespace App\\Http\\Controllers; 1993 1994class AccountController extends Controller 1995{ 1996 public function dashboard() 1997 { 1998 $user = auth()->user(); 1999 $subscription = $user->subscription; 2000 if ($subscription && $subscription->daysUntilExpiration() <= 3) { 2001`, 2002 after: ` 2003 } 2004 2005 return view('account.dashboard', compact('user')); 2006 } 2007}` 2008 } 2009 }, 2010 symfony: { 2011 title: "Warning", 2012 message: "Your account will expire in 3 days.", 2013 controller: "AccountController", 2014 method: "dashboard", 2015 code: { 2016 before: `// AccountController.php 2017namespace App\\Controller; 2018 2019use Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController; 2020 2021class AccountController extends AbstractController 2022{ 2023 public function dashboard(): Response 2024 { 2025 $user = $this->getUser(); 2026 $subscription = $user->getSubscription(); 2027 if ($subscription && $subscription->getDaysRemaining() <= 3) { 2028`, 2029 after: ` 2030 } 2031 2032 return $this->render('account/dashboard.html.twig', [ 2033 'user' => $user 2034 ]); 2035 } 2036}` 2037 } 2038 }, 2039 js: { 2040 title: "Warning", 2041 message: "Your account will expire in 3 days.", 2042 file: "account-service.js", 2043 method: "checkStatus", 2044 code: { 2045 before: `// account-service.js 2046import flasher from '@flasher/flasher'; 2047 2048async function checkStatus() { 2049 const response = await api.get('/account/status'); 2050 const { subscription } = response.data; 2051 if (subscription && subscription.daysRemaining <= 3) { 2052`, 2053 after: ` 2054 } 2055 return subscription; 2056}` 2057 } 2058 }, 2059 noty: { 2060 title: "Warning", 2061 message: "Your account will expire in 3 days.", 2062 code: { 2063 before: `// Noty adapter 2064import Noty from 'noty'; 2065 2066`, 2067 after: ` 2068new Noty({ 2069 type: 'warning', 2070 text: 'Your account will expire in 3 days.', 2071 timeout: 6000 2072}).show();` 2073 } 2074 }, 2075 toastr: { 2076 title: "Warning", 2077 message: "Your account will expire in 3 days.", 2078 code: { 2079 before: `// Toastr adapter 2080import toastr from 'toastr'; 2081 2082`, 2083 after: ` 2084toastr.warning('Your account will expire in 3 days.');` 2085 } 2086 }, 2087 sweetalert: { 2088 title: "Warning", 2089 message: "Your account will expire in 3 days.", 2090 code: { 2091 before: `// SweetAlert adapter 2092import Swal from 'sweetalert2'; 2093 2094`, 2095 after: ` 2096Swal.fire({ 2097 icon: 'warning', 2098 title: 'Warning', 2099 text: 'Your account will expire in 3 days.', 2100 timer: 6000 2101});` 2102 } 2103 } 2104 } 2105 }; 2106 2107 const indentMap = { 2108 js: { success: " ", error: " ", info: " ", warning: " " }, 2109 laravel: { success: " ", error: " ", info: " ", warning: " " }, 2110 symfony: { success: " ", error: " ", info: " ", warning: " " }, 2111 noty: { success: "", error: "", info: "", warning: "" }, 2112 toastr: { success: "", error: "", info: "", warning: "" }, 2113 sweetalert: { success: "", error: "", info: "", warning: "" } 2114 }; 2115 2116 // Helper Functions 2117 function sanitizeForCode(str) { 2118 if (typeof str !== "string") return str; 2119 return str 2120 .replace(/\\/g, "\\\\") 2121 .replace(/'/g, "\\'") 2122 .replace(/"/g, "\\\"") 2123 .replace(/\n/g, "\\n") 2124 .replace(/\r/g, "\\r") 2125 .replace(/\t/g, "\\t"); 2126 } 2127 2128 function escapeHtml(text) { 2129 if (typeof text !== "string") return ""; 2130 return text 2131 .replace(/&/g, "&") 2132 .replace(/</g, "<") 2133 .replace(/>/g, ">") 2134 .replace(/"/g, """) 2135 .replace(/'/g, "'"); 2136 } 2137 2138 function initializeTypeButtons() { 2139 document.querySelectorAll(".type-button").forEach(btn => { 2140 const type = btn.dataset.type; 2141 btn.classList.remove("border-2"); 2142 btn.classList.remove("border-green-500", "border-red-500", "border-blue-500", "border-amber-500"); 2143 if (type === state.type) { 2144 btn.classList.add("border-2"); 2145 switch (type) { 2146 case "success": btn.classList.add("border-green-500"); break; 2147 case "error": btn.classList.add("border-red-500"); break; 2148 case "info": btn.classList.add("border-blue-500"); break; 2149 case "warning": btn.classList.add("border-amber-500"); break; 2150 } 2151 } 2152 }); 2153 } 2154 2155 function initializeFormValues() { 2156 const template = contextTemplates[state.type]; 2157 const currentTab = getCurrentTab(); 2158 2159 if (!state.title && template && template[currentTab]) { 2160 state.title = template[currentTab].title; 2161 } 2162 2163 if (state.title && (state.title.toLowerCase() === state.type.toLowerCase() || 2164 (state.title.toLowerCase() === "information" && state.type.toLowerCase() === "info"))) { 2165 state.title = ""; 2166 } 2167
2168 document.getElementById("title-input").value = state.title || ""; 2169 document.getElementById("message-input").value = state.message || ""; 2170 document.getElementById("position-select").value = state.position || ""; 2171 document.getElementById("timeout-select").value = state.timeout === false ? "false" : (state.timeout || ""); 2172 document.getElementById("theme-select").value = state.theme || ""; 2173 document.getElementById("direction-select").value = state.direction || ""; 2174 document.getElementById("rtl-check").checked = !!state.rtl; 2175 document.getElementById("escape-html-check").checked = state.escapeHtml !== false; 2176 } 2177 2178 function updateStatus(message) { 2179 const statusText = document.getElementById("status-text"); 2180 if (!statusText) return; 2181 statusText.textContent = message; 2182 statusText.classList.remove("text-emerald-600"); 2183 statusText.classList.add("text-blue-600"); 2184 const dot = document.querySelector("#status-indicator div"); 2185 if (dot) { 2186 dot.classList.remove("bg-emerald-500"); 2187 dot.classList.add("bg-blue-500"); 2188 } 2189 setTimeout(() => { 2190 statusText.classList.remove("text-blue-600"); 2191 statusText.classList.add("text-emerald-600"); 2192 statusText.textContent = "Ready"; 2193 if (dot) { 2194 dot.classList.remove("bg-blue-500"); 2195 dot.classList.add("bg-emerald-500"); 2196 } 2197 }, 2000); 2198 } 2199 2200 function getCurrentTab() { 2201 const activeTab = document.querySelector(".code-tab-btn.text-indigo-600, .code-tab-btn.text-blue-600"); 2202 return activeTab ? activeTab.getAttribute("data-tab") : "laravel"; 2203 } 2204 2205 function showCodeTab(tab) { 2206 document.querySelectorAll(".code-panel").forEach(panel => { 2207 panel.classList.add("hidden"); 2208 panel.classList.remove("active"); 2209 }); 2210 const activePanel = document.getElementById(`${tab}-code-panel`); 2211 if (activePanel) { 2212 activePanel.classList.remove("hidden"); 2213 activePanel.classList.add("active"); 2214 } 2215 document.querySelectorAll(".code-tab-btn").forEach(btn => { 2216 btn.classList.remove("text-indigo-600", "text-blue-600", "border-b-2", "border-indigo-600", "border-blue-500"); 2217 btn.classList.add("text-slate-600", "text-gray-600"); 2218 }); 2219 const activeTabBtn = document.querySelector(`[data-tab="${tab}"]`); 2220 if (activeTabBtn) { 2221 activeTabBtn.classList.remove("text-slate-600", "text-gray-600"); 2222 activeTabBtn.classList.add("text-indigo-600", "border-b-2", "border-indigo-600"); 2223 } 2224 updateCodeDisplay(state.animationsEnabled); 2225 } 2226 2227 function generateFlashCode(framework, indent = "") { 2228 const safeMessage = sanitizeForCode(state.message); 2229 const safeTitle = state.title && state.title.toLowerCase() !== state.type.toLowerCase() ? sanitizeForCode(state.title) : ""; 2230 let lines = []; 2231 2232 // Adapter-specific code generation 2233 if (framework === "noty") { 2234 return contextTemplates[state.type].noty.code.before + 2235 `new Noty({ 2236 type: '${state.type}', 2237 text: '${safeMessage}'${safeTitle ? `, 2238 title: '${safeTitle}'` : ''}${state.timeout ? `, 2239 timeout: ${state.timeout}` : ''} 2240}).show();`; 2241 } 2242 2243 if (framework === "toastr") { 2244 const toastrType = state.type === "error" ? "error" : (state.type === "warning" ? "warning" : "success"); 2245 return contextTemplates[state.type].toastr.code.before + 2246 `toastr.${toastrType}('${safeMessage}'${safeTitle ? `, '${safeTitle}'` : ''});`; 2247 } 2248 2249 if (framework === "sweetalert") { 2250 const iconMap = { success: "success", error: "error", info: "info", warning: "warning" }; 2251 return contextTemplates[state.type].sweetalert.code.before + 2252 `Swal.fire({ 2253 icon: '${iconMap[state.type]}', 2254 ${safeTitle ? `title: '${safeTitle}',\n ` : ``}text: '${safeMessage}'${state.timeout ? `, 2255 timer: ${state.timeout}` : ''} 2256});`; 2257 } 2258 2259 // Standard Flasher code (Laravel, Symfony, JS) 2260 const prefix = framework === "js" ? "flasher" : "flash()"; 2261 2262 if (framework === "js") { 2263 const options = {}; 2264 if (state.position) options.position = state.position; 2265 if (state.timeout !== undefined && state.timeout !== "") options.timeout = state.t
2265imeout; 2266 if (state.theme) options.theme = state.theme; 2267 if (state.direction) options.direction = state.direction; 2268 if (state.rtl) options.rtl = true; 2269 if (state.escapeHtml === false) options.escapeHtml = false; 2270 2271 if (Object.keys(options).length === 0) { 2272 return `${indent}${prefix}.${state.type}('${safeMessage}'${safeTitle ? `, '${safeTitle}'` : ""});`; 2273 } 2274 lines.push(`${indent}${prefix}`); 2275 lines.push(`${indent} .${state.type}('${safeMessage}'${safeTitle ? `, '${safeTitle}'` : ""}, {`); 2276 Object.entries(options).forEach(([key, value], index, array) => { 2277 const comma = index < array.length - 1 ? "," : ""; 2278 if (typeof value === "string") { 2279 lines.push(`${indent} ${key}: '${value}'${comma}`); 2280 } else { 2281 lines.push(`${indent} ${key}: ${value}${comma}`); 2282 } 2283 }); 2284 lines.push(`${indent} });`); 2285 } else { 2286 lines.push(`${indent}${prefix}`); 2287 if (state.theme) lines.push(`${indent} ->use('theme.${state.theme}')`); 2288 if (state.position) lines.push(`${indent} ->option('position', '${state.position}')`); 2289 if (state.timeout !== undefined && state.timeout !== "") { 2290 const timeoutValue = state.timeout === false ? 'false' : state.timeout; 2291 lines.push(`${indent} ->option('timeout', ${timeoutValue})`); 2292 } 2293 if (state.direction) lines.push(`${indent} ->option('direction', '${state.direction}')`); 2294 if (state.rtl) lines.push(`${indent} ->option('rtl', true)`); 2295 if (state.escapeHtml === false) lines.push(`${indent} ->option('escapeHtml', false)`); 2296 lines.push(`${indent} ->${state.type}('${safeMessage}'${safeTitle ? `, '${safeTitle}'` : ""});`); 2297 } 2298 return lines.join("\n"); 2299 } 2300 2301 function updateCodeDisplay(animate = true) { 2302 const currentTab = getCurrentTab(); 2303 const panel = document.getElementById(`${currentTab}-code-panel`); 2304 if (!panel) return; 2305 2306 const template = contextTemplates[state.type][currentTab]; 2307 if (!template) return; 2308 2309 const defaultIndent = indentMap[currentTab] && indentMap[currentTab][state.type] ? indentMap[currentTab][state.type] : " "; 2310 const flashCode = generateFlashCode(currentTab, defaultIndent); 2311 2312 if (animate && template.code) { 2313 panel.innerHTML = `<pre class="language-${currentTab === "js" ? "javascript" : "php"}"><code>${escapeHtml(template.code.before)}</code></pre>`; 2314 if (typeof Prism !== "undefined") { 2315 Prism.highlightElement(panel.querySelector("code")); 2316 } 2317 const typingContainer = document.createElement("div"); 2318 typingContainer.className = "typing-container border-l-4 mt-4 border-green-500 bg-green-50/20"; 2319 typingContainer.style.fontFamily = "monospace"; 2320 2321 const panelPre = panel.querySelector("pre"); 2322 panelPre.appendChild(typingContainer); 2323 panelPre.style.marginBottom = "0"; 2324 panelPre.style.paddingBottom = "0"; 2325 2326 if (template.code.after) { 2327 const afterContainer = document.createElement("pre"); 2328 afterContainer.className = `language-${currentTab === "js" ? "javascript" : "php"}`; 2329 afterContainer.style.marginTop = "0"; 2330 afterContainer.style.paddingTop = "0"; 2331 afterContainer.innerHTML = `<code>${escapeHtml(template.code.after)}</code>`; 2332 panel.appendChild(afterContainer); 2333 if (typeof Prism !== "undefined") { 2334 Prism.highlightElement(afterContainer.querySelector("code")); 2335 } 2336 } 2337 typeCode(flashCode, typingContainer); 2338 } else { 2339 let completeCode = ""; 2340 if (template.code && template.code.before) { 2341 completeCode = template.code.before + flashCode; 2342 if (template.code.after) { 2343 completeCode += template.code.after; 2344 } 2345 } else { 2346 completeCode = flashCode; 2347 } 2348 panel.innerHTML = `<pre class="language-${currentTab === "js" || currentTab === "sweetalert" ? "javascript" : "php"}"><code>${escapeHtml(completeCode)}</code></pre>`; 2349 if (typeof Prism !== "undefined") { 2350 Prism.highlightElement(panel.querySelector("code")); 2351 } 2352 } 2353 } 2354 2355 function typeCode(code, container) { 2356 const cursor = document.createElement("span"); 2357 cursor.className = "cursor"; 2358 container.appendChild(cursor); 2359 2360 let i = 0; 2361 let currentLine = document.createElement("div"); 2362 currentLine.style.minHeight = "1.2em"; 2363 container.insertBefore(currentLine, cursor); 2364 2365 const charsPerMinute = 5000; 2366 const baseDelay = 60000 / charsPerMinute; 2367 2368 function typeNextChar() { 2369 if (i < code.length) { 2370 const char = code.charAt(i); 2371 2372 if (char === "\n") { 2373 currentLine = document.createElement("div"); 2374 currentLine.style.minHeight = "1.2em"; 2375 container.insertBefore(currentLine, cursor); 2376 } else { 2377 const charSpan = document.createElement("span"); 2378 if ("(){}[];".includes(char)) { 2379 charSpan.style.color = "#a626a4"; 2380 } else if ("'\"`".includes(char)) { 2381 charSpan.style.color = "#50a14f"; 2382 } else if (char === "-" && i > 0 && code.charAt(i - 1) === "-" && code.charAt(i - 2) === ">") { 2383 charSpan.style.color = "#e45649"; 2384 } else if (char === ">") { 2385 charSpan.style.color = "#e45649"; 2386 } else { 2387 charSpan.style.color = "#383a42"; 2388 } 2389 charSpan.textContent = char; 2390 currentLine.appendChild(charSpan); 2391 } 2392 2393 i++; 2394 let delay = baseDelay; 2395 2396 if ([".", ",", ";", ")", "}", ">", "!"].includes(char)) { 2397 delay *= 2.5; 2398 } else if (char === "\n") { 2399 delay *= 4; 2400 } else { 2401 delay *= (0.7 + Math.random() * 0.6); 2402 } 2403 2404 if (Math.random() < 0.05) { 2405 delay += Math.random() * 500; 2406 } 2407 2408 setTimeout(typeNextChar, delay); 2409 } else { 2410 setTimeout(() => { 2411 cursor.remove(); 2412 }, 50); 2413 } 2414 } 2415 2416 setTimeout(typeNextChar, 150); 2417 } 2418 2419 function updateContentForType(type) { 2420 const currentTab = getCurrentTab(); 2421 const template = contextTemplates[type][currentTab]; 2422 if (!template) return; 2423 2424 document.getElementById("message-input").value = template.message; 2425 state.message = template.message; 2426 2427 if (template.title && template.title.toLowerCase() !== type.toLowerCase() && 2428 !(template.title.toLowerCase() === "information" && type.toLowerCase() === "info")) { 2429 document.getElementById("title-input").value = template.title; 2430 state.title = template.title; 2431 } else { 2432 document.getElementById("title-input").value = ""; 2433 state.title = ""; 2434 } 2435 } 2436 2437 function applyPreset(presetKey) { 2438 const preset = presets[presetKey]; 2439 if (!preset) return; 2440 2441 state.type = preset.type; 2442 state.title = preset.title; 2443 state.message = preset.message; 2444 2445 document.getElementById("title-input").value = preset.title; 2446 document.getElementById("message-input").value = preset.message; 2447 2448 initializeTypeButtons(); 2449 updateStatus(`Preset applied: ${presetKey} â`); 2450 } 2451 2452 function showComparison() { 2453 const modal = document.getElementById("comparison-modal"); 2454 const beforeCode = document.getElementById("before-code").querySelector("code"); 2455 const afterCode = document.getElementById("after-code").querySelector("code"); 2456 2457 const example = beforeAfterExamples[state.type]; 2458 if (!example) return; 2459 2460 beforeCode.textContent = example.before; 2461 afterCode.textContent = example.after; 2462 2463 if (typeof Prism !== "undefined") { 2464 Prism.highlightElement(beforeCode); 2465 Prism.highlightElement(afterCode); 2466 } 2467 2468 modal.classList.remove("hidden"); 2469 } 2470 2471 function showNotification() { 2472 const options = {}; 2473 if (state.position) options.position = state.position; 2474 if (state.timeout !== undefined && state.timeout !== "") options.timeout = state.t
2474imeout; 2475 if (state.direction) options.direction = state.direction; 2476 if (state.rtl) options.rtl = state.rtl; 2477 if (state.escapeHtml !== undefined) options.escapeHtml = state.escapeHtml; 2478 2479 console.log("Showing notification with options:", options); 2480 2481 try { 2482 if (typeof flasher !== "undefined") { 2483 if (state.theme) { 2484 const notificationOptions = { 2485 type: state.type, 2486 message: state.message, 2487 title: state.title || undefined, 2488 ...options 2489 }; 2490 delete notificationOptions.theme; 2491 flasher.use(`theme.${state.theme}`).flash(notificationOptions); 2492 } else { 2493 flasher[state.type](state.message, state.title || null, options); 2494 } 2495 updateStatus("Notification shown â"); 2496 } else { 2497 let optionsText = Object.entries(options) 2498 .map(([k, v]) => `${k}: ${JSON.stringify(v)}`) 2499 .join("\n"); 2500 alert(`Notification would display with:\n\n` + 2501 `Type: ${state.type}\n` + 2502 `Message: ${state.message}\n` + 2503 (state.title ? `Title: ${state.title}\n` : "") + 2504 (optionsText ? `\nOptions:\n${optionsText}` : "")); 2505 } 2506 } catch (e) { 2507 console.error("Error showing notification:", e); 2508 updateStatus("Error: " + e.message); 2509 } 2510 } 2511 2512 // Initialize 2513 document.addEventListener("DOMContentLoaded", function() { 2514 initializeFormValues(); 2515 initializeTypeButtons(); 2516 2517 // Type buttons 2518 document.querySelectorAll(".type-button").forEach(btn => { 2519 btn.addEventListener("click", () => { 2520 const type = btn.dataset.type; 2521 state.type = type; 2522 updateContentForType(type); 2523 initializeTypeButtons(); 2524 updateStatus(`Type: ${state.type}`); 2525 }); 2526 }); 2527 2528 // Preset buttons 2529 document.querySelectorAll(".preset-btn").forEach(btn => { 2530 btn.addEventListener("click", () => { 2531 const preset = btn.dataset.preset; 2532 applyPreset(preset); 2533 }); 2534 }); 2535 2536 // Form inputs 2537 document.getElementById("title-input").addEventListener("input", (e) => { 2538 state.title = e.target.value.trim(); 2539 }); 2540 document.getElementById("message-input").addEventListener("input", (e) => { 2541 state.message = e.target.value; 2542 }); 2543 document.getElementById("position-select").addEventListener("change", (e) => { 2544 state.position = e.target.value; 2545 }); 2546 document.getElementById("timeout-select").addEventListener("change", (e) => { 2547 if (e.target.value === "false") { 2548 state.timeout = false; 2549 } else if (e.target.value) { 2550 state.timeout = parseInt(e.target.value); 2551 } else { 2552 state.timeout = ""; 2553 } 2554 }); 2555 document.getElementById("theme-select").addEventListener("change", (e) => { 2556 state.theme = e.target.value; 2557 }); 2558 document.getElementById("direction-select").addEventListener("change", (e) => { 2559 state.direction = e.target.value; 2560 }); 2561 document.getElementById("rtl-check").addEventListener("change", (e) => { 2562 state.rtl = e.target.checked; 2563 }); 2564 document.getElementById("escape-html-check").addEventListener("change", (e) => { 2565 state.escapeHtml = e.target.checked; 2566 }); 2567 2568 // Code tab buttons 2569 document.querySelectorAll(".code-tab-btn").forEach(button => { 2570 button.addEventListener("click", () => { 2571 const tab = button.getAttribute("data-tab"); 2572 showCodeTab(tab); 2573 }); 2574 }); 2575 2576 // Compare button 2577 document.getElementById("compare-btn").addEventListener("click", showComparison); 2578 document.getElementById("close-comparison-btn").addEventListener("click", () => { 2579 document.getElementById("comparison-modal").classList.add("hidden"); 2580 }); 2581 2582 // Show notification button 2583 const notificationBtn = document.getElementById("show-notification-btn"); 2584 notificationBtn.addEventListener("click", () => { 2585 notificationBtn.classList.add("scale-95"); 2586 setTimeout(() => notificationBtn.classList.remove("scale-95"), 150); 2587 updateStatus("Launching notification..."); 2588 showNotification(); 2589 }); 2590 2591 // Close modal on outside click 2592 document.getElementById("comparison-modal").addEventListener("click", (e) => { 2593 if (e.target.id === "comparison-modal") { 2594 document.getElementById("comparison-modal").classList.add("hidden"); 2595 } 2596 }); 2597 2598 // Konami code easter egg 2599 let konamiCode = [];
2600 const konamiSequence = ["ArrowUp", "ArrowUp", "ArrowDown", "ArrowDown", 2601 "ArrowLeft", "ArrowRight", "ArrowLeft", "ArrowRight", "b", "a"]; 2602 document.addEventListener("keydown", function(e) { 2603 konamiCode.push(e.key); 2604 konamiCode = konamiCode.slice(-konamiSequence.length); 2605 if (konamiCode.join(",") === konamiSequence.join(",")) { 2606 if (typeof flasher !== "undefined") { 2607 flasher.use("neon").success("You found the Konami code! ð®", "Secret Unlocked"); 2608 } 2609 } 2610 }); 2611 2612 console.info("%cTry the Konami code for a surprise!", "color: #10B981; font-style: italic;"); 2613 showCodeTab("laravel"); 2614 }); 2615</script>
2615 2616 2617 2618 <!-- Quick Start Section (Moved before Features) --> 2619 <section id="quick-start" class="container mx-auto px-4 mb-16"> 2620 <div class="text-center mb-12"> 2621 <div class="inline-block px-3 py-1 bg-indigo-50 text-indigo-700 rounded-full text-sm font-medium mb-2">Get Started</div> 2622 <h2 class="text-2xl md:text-3xl font-bold text-slate-800 mb-2">Quick Installation</h2> 2623 <p class="text-slate-600 max-w-2xl mx-auto">Get up and running in less than a minute</p> 2624 </div> 2625 2626 <div class="max-w-4xl mx-auto"> 2627 <div class="bg-white rounded-xl shadow-md overflow-hidden border border-slate-100 mb-8"> 2628 <div class="bg-slate-800 p-4 flex items-center justify-between"> 2629 <div class="flex items-center"> 2630 <div class="flex space-x-1 mr-4"> 2631 <div class="w-3 h-3 rounded-full bg-red-400"></div> 2632 <div class="w-3 h-3 rounded-full bg-yellow-400"></div> 2633 <div class="w-3 h-3 rounded-full bg-green-400"></div> 2634 </div> 2635 <span class="text-slate-400 text-sm">Terminal</span> 2636 </div> 2637 <div class="text-slate-400 text-sm">Installation</div> 2638 </div> 2639 2640 <div class="p-6 bg-slate-900"> 2641 <div class="flex flex-col gap-4"> 2642 <div class="relative"> 2643 <div class="flex items-center mb-2"> 2644 <div class="w-5 h-5 bg-red-500 text-white rounded-full flex items-center justify-center mr-2 text-xs"> 2645 <i class="fa-brands fa-laravel"></i> 2646 </div> 2647 <span class="text-slate-300 text-sm">Laravel Installation</span> 2648 </div> 2649 <pre class="bg-slate-800 p-4 rounded-lg text-sm overflow-x-auto"><code class="language-bash text-slate-200">composer require php-flasher/flasher-laravel</code></pre> 2650 </div> 2651 2652 <div class="relative"> 2653 <div class="flex items-center mb-2"> 2654 <div class="w-5 h-5 bg-black text-white rounded-full flex items-center justify-center mr-2 text-xs"> 2655 <i class="fa-brands fa-symfony"></i> 2656 </div> 2657 <span class="text-slate-300 text-sm">Symfony Installation</span> 2658 </div> 2659 <pre class="bg-slate-800 p-4 rounded-lg text-sm overflow-x-auto"><code class="language-bash text-slate-200">composer require php-flasher/flasher-symfony</code></pre> 2660 </div> 2661 </div> 2662 </div> 2663 </div> 2664 2665 <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> 2666 <!-- Laravel Quick Start --> 2667 <a href="/laravel/" class="group bg-white rounded-xl shadow-sm hover:shadow-md transition-all duration-300 border border-slate-100 overflow-hidden hover:border-red-200"> 2668 <div class="p-6"> 2669 <div class="flex items-center mb-4"> 2670 <div class="w-10 h-10 bg-red-50 text-red-500 rounded-lg flex items-center justify-center mr-3 group-hover:bg-red-100 transition-colors"> 2671 <i class="fa-brands fa-laravel text-lg"></i> 2672 </div> 2673 <h3 class="text-lg font-semibold text-slate-800">Laravel Guide</h3> 2674 </div> 2675 <p class="text-slate-600 mb-4">Perfect integration with Laravel's notification system. Get started in minutes.</p> 2676 <div class="flex items-center text-red-600 font-medium"> 2677 Learn more 2678 <i class="fa-solid fa-arrow-right ml-1 transform group-hover:translate-x-1 transition-transform"></i> 2679 </div> 2680 </div> 2681 </a> 2682 2683 <!-- Symfony Quick Start --> 2684 <a href="/symfony/" class="group bg-white rounded-xl shadow-sm hover:shadow-md transition-all duration-300 border border-slate-100 overflow-hidden hover:border-slate-300"> 2685 <div class="p-6"> 2686 <div class="flex items-center mb-4"> 2687 <div class="w-10 h-10 bg-slate-50 text-black rounded-lg flex items-center justify-center mr-3 group-hover:bg-slate-100 transition-colors"> 2688 <i class="fa-brands fa-symfony text-lg"></i> 2689 </div> 2690 <h3 class="text-lg font-semibold text-slate-800">Symfony Guide</h3> 2691 </div> 2692 <p class="text-slate-600 mb-4">Complete Symfony integration with bundle configuration and services.</p> 2693 <div class="flex items-center text-slate-700 font-medium"> 2694 Learn more 2695 <i class="fa-solid fa-arrow-right ml-1 transform group-hover:translate-x-1 transition-transform"></i> 2696 </div> 2697 </div> 2698 </a> 2699 </div> 2700 2701 <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mt-6"> 2702 <!-- Livewire Quick Start --> 2703 <a href="/livewire/" class="group bg-white rounded-xl shadow-sm hover:shadow-md transition-all duration-300 border border-slate-100 overflow-hidden hover:border-purple-200"> 2704 <div class="p-6"> 2705 <div class="flex items-center mb-4"> 2706 <div class="w-10 h-10 bg-purple-50 text-purple-600 rounded-lg flex items-center justify-center mr-3 group-hover:bg-purple-100 transition-colors"> 2707 <i class="fa-solid fa-bolt text-lg"></i> 2708 </div> 2709 <h3 class="text-lg font-semibold text-slate-800">Livewire Guide</h3> 2710 </div> 2711 <p class="text-slate-600 mb-4">Real-time notifications in your Laravel Livewire components.</p> 2712 <div class="flex items-center text-purple-600 font-medium"> 2713 Learn more 2714 <i class="fa-solid fa-arrow-right ml-1 transform group-hover:translate-x-1 transition-transform"></i> 2715 </div> 2716 </div> 2717 </a> 2718 2719 <!-- Inertia Quick Start --> 2720 <a href="/inertia/" class="group bg-white rounded-xl shadow-sm hover:shadow-md transition-all duration-300 border border-slate-100 overflow-hidden hover:border-blue-200"> 2721 <div class="p-6"> 2722 <div class="flex items-center mb-4"> 2723 <div class="w-10 h-10 bg-blue-50 text-blue-600 rounded-lg flex items-center justify-center mr-3 group-hover:bg-blue-100 transition-colors"> 2724 <i class="fa-solid fa-arrows-rotate text-lg"></i> 2725 </div> 2726 <h3 class="text-lg font-semibold text-slate-800">Inertia Guide</h3> 2727 </div> 2728 <p class="text-slate-600 mb-4">Modern SPA notifications with Inertia.js integration.</p> 2729 <div class="flex items-center text-blue-600 font-medium"> 2730 Learn more 2731 <i class="fa-solid fa-arrow-right ml-1 transform group-hover:translate-x-1 transition-transform"></i> 2732 </div> 2733 </div> 2734 </a> 2735 </div> 2736 </div> 2737 </section> 2738 2739 <!-- Features Section --> 2740 <section class="container mx-auto px-4 mb-20"> 2741 <div class="text-center mb-16"> 2742 <div class="inline-block px-3 py-1 bg-indigo-50 text-indigo-700 rounded-full text-sm font-medium mb-3">Features</div> 2743 <h2 class="text-3xl sm:text-4xl font-bold text-slate-800 mb-4">Why Choose PHPFlasher?</h2> 2744 <p class="text-slate-600 max-w-2xl mx-auto text-lg">The modern notification library for PHP developers</p> 2745 </div> 2746 2747 <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 max-w-6xl mx-auto"> 2748 <!-- Feature 1 - One Line API --> 2749 <div class="group bg-white rounded-2xl p-8 border border-slate-100 shadow-sm hover:shadow-lg hover:border-indigo-100 transition-all duration-300"> 2750 <div class="w-14 h-14 bg-indigo-50 rounded-xl flex items-center justify-center mb-5 group-hover:bg-indigo-100 transition-colors"> 2751 <i class="fa-solid fa-bolt text-indigo-600 text-2xl"></i> 2752 </div> 2753 <h3 class="text-xl font-bold text-slate-800 mb-2">One-Line API</h3> 2754 <p class="text-slate-600 text-sm">Show beautiful notifications with a single line of code. Zero configuration required.</p> 2755 </div> 2756 2757 <!-- Feature 2 - Framework Support --> 2758 <div class="group bg-white rounded-2xl p-8 border border-slate-100 shadow-sm hover:shadow-lg hover:border-indigo-100 transition-all duration-300"> 2759 <div class="w-14 h-14 bg-indigo-50 rounded-xl flex items-center justify-center mb-5 group-hover:bg-indigo-100 transition-colors"> 2760 <i class="fa-brands fa-laravel text-indigo-600 text-2xl"></i> 2761 </div> 2762 <h3 class="text-xl font-bold text-slate-800 mb-2">Framework Ready</h3> 2763 <p class="text-slate-600 text-sm">Native support for Laravel, Symfony, Livewire, and Inertia.js out of the box.</p> 2764 </div> 2765 2766 <!-- Feature 3 - Multiple Libraries --> 2767 <div class="group bg-white rounded-2xl p-8 border border-slate-100 shadow-sm hover:shadow-lg hover:border-indigo-100 transition-all duration-300"> 2768 <div class="w-14 h-14 bg-indigo-50 rounded-xl flex items-center justify-center mb-5 group-hover:bg-indigo-100 transition-colors"> 2769 <i class="fa-solid fa-layer-group text-indigo-600 text-2xl"></i> 2770 </div> 2771 <h3 class="text-xl font-bold text-slate-800 mb-2">Library Agnostic</h3> 2772 <p class="text-slate-600 text-sm">Works with SweetAlert2, Toastr, Noty, Pnotify, and more. Switch anytime.</p> 2773 </div> 2774 2775 <!-- Feature 4 - TypeScript --> 2776 <div class="group bg-white rounded-2xl p-8 border border-slate-100 shadow-sm hover:shadow-lg hover:border-indigo-100 transition-all duration-300"> 2777 <div class="w-14 h-14 bg-indigo-50 rounded-xl flex items-center justify-center mb-5 group-hover:bg-indigo-100 transition-colors"> 2778 <i class="fa-solid fa-code text-indigo-600 text-2xl"></i> 2779 </div> 2780 <h3 class="text-xl font-bold text-slate-800 mb-2">TypeScript Support</h3> 2781 <p class="text-slate-600 text-sm">Full TypeScript definitions with IDE autocomplete for a better DX.</p> 2782 </div> 2783 2784 <!-- Feature 5 - Zero Config --> 2785 <div class="group bg-white rounded-2xl p-8 border border-slate-100 shadow-sm hover:shadow-lg hover:border-indigo-100 transition-all duration-300"> 2786 <div class="w-14 h-14 bg-indigo-50 rounded-xl flex items-center justify-center mb-5 group-hover:bg-indigo-100 transition-colors"> 2787 <i class="fa-solid fa-gauge-high text-indigo-600 text-2xl"></i> 2788 </div> 2789 <h3 class="text-xl font-bold text-slate-800 mb-2">Zero Config</h3> 2790 <p class="text-slate-600 text-sm">Install and use immediately. Sensible defaults that work out of the box.</p> 2791 </div> 2792 2793 <!-- Feature 6 - Production Ready --> 2794 <div class="group bg-white rounded-2xl p-8 border border-slate-100 shadow-sm hover:shadow-lg hover:border-indigo-100 transition-all duration-300"> 2795 <div class="w-14 h-14 bg-indigo-50 rounded-xl flex items-center justify-center mb-5 group-hover:bg-indigo-100 transition-colors"> 2796 <i class="fa-solid fa-shield-check text-indigo-600 text-2xl"></i> 2797 </div> 2798 <h3 class="text-xl font-bold text-slate-800 mb-2">Production Ready</h3> 2799 <p class="text-slate-600 text-sm">Battle-tested in production. Comprehensive test coverage and reliable.</p> 2800 </div> 2801 </div> 2802 2803 <!-- Stats Section --> 2804 <div class="mt-16 grid grid-cols-2 md:grid-cols-4 gap-6 max-w-4xl mx-auto"> 2805 <div class="text-center"> 2806 <div class="text-3xl md:text-4xl font-bold text-indigo-600 mb-1">6+</div> 2807 <div class="text-slate-600 text-sm">Framework Integrations</div> 2808 </div> 2809 <div class="text-center"> 2810 <div class="text-3xl md:text-4xl font-bold text-indigo-600 mb-1">5+</div> 2811 <div class="text-slate-600 text-sm">Notification Libraries</div> 2812 </div> 2813 <div class="text-center"> 2814 <div class="text-3xl md:text-4xl font-bold text-indigo-600 mb-1">10+</div> 2815 <div class="text-slate-600 text-sm">Available Themes</div> 2816 </div> 2817 <div class="text-center"> 2818 <div class="text-3xl md:text-4xl font-bold text-indigo-600 mb-1">100%</div> 2819 <div class="text-slate-600 text-sm">
2819TypeScript Coverage</div> 2820 </div> 2821 </div> 2822 </section> 2823 2824 <!-- Library Showcase Section --> 2825 <section class="container mx-auto px-4 mb-20"> 2826 <div class="text-center mb-16"> 2827 <div class="inline-block px-3 py-1 bg-indigo-50 text-indigo-700 rounded-full text-sm font-medium mb-3">Libraries</div> 2828 <h2 class="text-3xl sm:text-4xl font-bold text-slate-800 mb-4">Choose Your Preferred Library</h2> 2829 <p class="text-slate-600 max-w-2xl mx-auto text-lg">Seamlessly integrate with the notification library you already love</p> 2830 </div> 2831 2832 <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-5 max-w-5xl mx-auto"> 2833 <!-- Toastr --> 2834 <a href="/library/toastr/" class="group bg-white rounded-2xl p-6 border border-slate-100 hover:border-indigo-200 hover:shadow-lg transition-all duration-300 flex flex-col items-center text-center"> 2835 <div class="w-14 h-14 bg-indigo-50 rounded-xl flex items-center justify-center mb-4 group-hover:bg-indigo-100 transition-colors"> 2836 <i class="fa-solid fa-message text-indigo-600 text-xl"></i> 2837 </div> 2838 <h3 class="font-bold text-lg text-slate-800 mb-2">Toastr.js</h3> 2839 <p class="text-slate-500 text-sm">Simple, elegant toast notifications</p> 2840 </a> 2841 2842 <!-- SweetAlert2 --> 2843 <a href="/library/sweetalert/" class="group bg-white rounded-2xl p-6 border border-slate-100 hover:border-indigo-200 hover:shadow-lg transition-all duration-300 flex flex-col items-center text-center"> 2844 <div class="w-14 h-14 bg-indigo-50 rounded-xl flex items-center justify-center mb-4 group-hover:bg-indigo-100 transition-colors"> 2845 <i class="fa-solid fa-star text-indigo-600 text-xl"></i> 2846 </div> 2847 <h3 class="font-bold text-lg text-slate-800 mb-2">SweetAlert2</h3> 2848 <p class="text-slate-500 text-sm">Beautiful, responsive alerts</p> 2849 </a> 2850 2851 <!-- Noty --> 2852 <a href="/library/noty/" class="group bg-white rounded-2xl p-6 border border-slate-100 hover:border-indigo-200 hover:shadow-lg transition-all duration-300 flex flex-col items-center text-center"> 2853 <div class="w-14 h-14 bg-indigo-50 rounded-xl flex items-center justify-center mb-4 group-hover:bg-indigo-100 transition-colors"> 2854 <i class="fa-solid fa-bell text-indigo-600 text-xl"></i> 2855 </div> 2856 <h3 class="font-bold text-lg text-slate-800 mb-2">Noty</h3> 2857 <p class="text-slate-500 text-sm">Highly customizable notifications</p> 2858 </a> 2859 2860 <!-- Notyf --> 2861 <a href="/library/notyf/" class="group bg-white rounded-2xl p-6 border border-slate-100 hover:border-indigo-200 hover:shadow-lg transition-all duration-300 flex flex-col items-center text-center"> 2862 <div class="w-14 h-14 bg-indigo-50 rounded-xl flex items-center justify-center mb-4 group-hover:bg-indigo-100 transition-colors"> 2863 <i class="fa-solid fa-check text-indigo-600 text-xl"></i> 2864 </div> 2865 <h3 class="font-bold text-lg text-slate-800 mb-2">Notyf</h3> 2866 <p class="text-slate-500 text-sm">Minimalist toast notifications</p> 2867 </a> 2868 </div> 2869 2870 <div class="text-center mt-10"> 2871 <a href="/library/toastr/" class="inline-flex items-center px-6 py-3 bg-indigo-600 hover:bg-indigo-700 text-white rounded-xl font-medium transition-all duration-300 shadow-md hover:shadow-lg"> 2872 <i class="fa-solid fa-th-large mr-2"></i> Compare All Libraries 2873 </a> 2874 </div> 2875 </section> 2876 2877 <!-- Code Example Section --> 2878 <section class="container mx-auto px-4 mb-16"> 2879 <div class="text-center mb-12"> 2880 <div class="inline-block px-3 py-1 bg-indigo-50 text-indigo-700 rounded-full text-sm font-medium mb-2">Code Examples</div> 2881 <h2 class="text-2xl md:text-3xl font-bold text-slate-800 mb-2">Simple Implementation</h2> 2882 <p class="text-slate-600 max-w-2xl mx-auto">Just a few lines of code to get started</p> 2883 </div> 2884 2885 <div class="flex flex-col gap-8 max-w-4xl mx-auto"> 2886 <!-- PHP Example --> 2887 <div class="bg-white rounded-xl shadow-md overflow-hidden border border-slate-100"> 2888 <div class="bg-slate-800 px-4 py-3 flex items-center"> 2889 <div class="flex space-x-1.5 mr-3"> 2890 <div class="w-2.5 h-2.5 rounded-full bg-red-500"></div> 2891 <div class="w-2.5 h-2.5 rounded-full bg-yellow-500"></div> 2892 <div class="w-2.5 h-2.5 rounded-full bg-green-500"></div> 2893 </div> 2894 <div class="text-white opacity-80 text-xs font-medium">Controller.php</div> 2895 </div> 2896 <div> 2897 <pre class="bg-slate-50 rounded-lg p-4 text-sm overflow-x-auto"><code class="language-php"><?php 2898 2899namespace App\Http\Controllers; 2900 2901class ProfileController 2902{
2903 public function update() 2904 { 2905 // Update user profile logic 2906 2907 // Show success notification 2908 flash()->success('Profile updated successfully!'); 2909 2910 // Or add a title 2911 flash()->success('Your changes have been saved.', [], 'Profile Updated'); 2912 2913 // Or add a title and options 2914 flash() 2915 ->option('timeout', 5000) 2916 ->option('position', 'top-right') 2917 ->success('Changes saved with custom settings'); 2918 2919 // Change notification options 2920 flash()->options([ 2921 'timeout' => 5000, 2922 'position' => 'top-right' 2923 ])->success('Changes saved with custom settings'); 2924 2925 return back(); 2926 } 2927}</code></pre> 2928 </div> 2929 </div> 2930 2931 <!-- JavaScript Example --> 2932 <div class="bg-white rounded-xl shadow-md overflow-hidden border border-slate-100"> 2933 <div class="bg-slate-800 px-4 py-3 flex items-center"> 2934 <div class="flex space-x-1.5 mr-3"> 2935 <div class="w-2.5 h-2.5 rounded-full bg-red-500"></div> 2936 <div class="w-2.5 h-2.5 rounded-full bg-yellow-500"></div> 2937 <div class="w-2.5 h-2.5 rounded-full bg-green-500"></div> 2938 </div> 2939 <div class="text-white opacity-80 text-xs font-medium">app.js</div> 2940 </div> 2941 <div> 2942 <pre class="bg-slate-50 rounded-lg p-4 text-sm overflow-x-auto"><code class="language-javascript">// Form submission example 2943document.getElementById('contact-form').addEventListener('submit', async function(e) { 2944 e.preventDefault(); 2945 2946 try { 2947 const response = await submitForm(this); 2948 2949 if (response.success) { 2950 // Show success notification 2951 flasher.success('Your message has been sent!', 'Thank You'); 2952 } else { 2953 // Show error notification 2954 flasher.error('Please check your form inputs', 'Error'); 2955 } 2956 } catch (error) { 2957 // Show error notification with details 2958 flasher.error('Server error, please try again later.', 'Error'); 2959 console.error(error); 2960 } 2961});</code></pre> 2962 </div> 2963 </div> 2964 </div> 2965 </section> 2966</div> 2967 2968 </div> 2969 2970 <div class="flex flex-col sm:flex-row items-center justify-between border-t border-slate-200 mt-12 pt-6 text-sm"> 2971 <a class="link-previous mb-4 sm:mb-0 hidden previous-link px-3 py-1.5 bg-white hover:bg-slate-50 text-slate-700 border border-slate-200 rounded-md shadow-sm flex items-center transition-colors" href="./"> 2972 <i class="fa-solid fa-chevron-left mr-2 text-slate-400"></i> 2973 <span class="label">Previous Page</span> 2974 </a> 2975 2976 <a class="link-next hidden previous-next px-3 py-1.5 bg-white hover:bg-slate-50 text-slate-700 border border-slate-200 rounded-md shadow-sm flex items-center transition-colors" href="./"> 2977 <span class="label">Next Page</span> 2978 <i class="fa-solid fa-chevron-right ml-2 text-slate-400"></i> 2979 </a> 2980</div> 2981 2982 </div> 2983 </main> 2984 2985 <!-- Table of Contents --> 2986 <aside class="hidden xl:block w-56 shrink-0" id="anchor-navigation"> 2987 <div class="sticky top-8"> 2988 <h4 class="text-sm font-semibold text-indigo-600 uppercase tracking-wider mb-4"> 2989 <i class="fa-duotone fa-list-tree"></i> On This Page 2990 </h4> 2991 <nav class="toc"> 2992 <ul class="list-none space-y-2 text-sm"></ul> 2993 </nav> 2994 </div> 2995 </aside> 2996 </div> 2997 </div> 2998 2999 <footer class="bg-slate-900 mt-12 pt-12 pb-8 text-white"> 3000 <div class="container max-w-7xl mx-auto px-4 lg:px-6"> 3001 <div class="grid grid-cols-1 md:grid-cols-3 gap-12"> 3002 <!-- About Section --> 3003 <div> 3004 <h3 class="text-lg font-semibold mb-4"> 3005 PHPFlasher 3006 </h3> 3007 <p class="text-slate-400 mb-6 text-sm leading-relaxed"> 3008 A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. 3009 Provides feedback to users, improves engagement & enhances user experience. 3010 </p> 3011 <div class="flex space-x-4"> 3012 <a href="https://github.com/php-flasher/php-flasher" class="text-slate-400 hover:text-white transition-colors"> 3013 <i class="fa-brands fa-github text-lg"></i> 3014 </a> 3015 <a href="https://twitter.com/phpflasher" class="text-slate-400 hover:text-white transition-colors"> 3016 <i class="fa-brands fa-twitter text-lg"></i> 3017 </a> 3018 <a href="https://www.linkedin.com/in/yoeunes/" class="text-slate-400 hover:text-white transition-colors"> 3019 <i class="fa-brands fa-linkedin text-lg"></i> 3020 </a> 3021 </div> 3022 </div> 3023 3024 <!-- Quick Links --> 3025 <div> 3026 <h3 class="text-lg font-semibold mb-4">Documentation</h3> 3027 <ul class="space-y-2 text-sm text-slate-400"> 3028 <li> 3029 <a href="/" class="text-slate-400 hover:text-white transition-colors">Introduction</a> 3030 </li> 3031 <li> 3032 <a href="/laravel/" class="text-slate-400 hover:text-white transition-colors">Laravel Integration</a> 3033 </li> 3034 <li> 3035 <a href="/symfony/" class="text-slate-400 hover:text-white transition-colors">Symfony Integration</a> 3036 </li> 3037 <li> 3038 <a href="/livewire/" class="text-slate-400 hover:text-white transition-colors">Livewire Integration</a> 3039 </li> 3040 </ul> 3041 </div> 3042 3043 <!-- Author --> 3044 <div> 3045 <h3 class="text-lg font-semibold mb-4">Author</h3> 3046 <div class="flex items-center"> 3047 <img src="/static/images/younes-ennaji.jpeg" alt="Younes ENNAJI" 3048 class="h-12 w-12 rounded-full mr-3"> 3049 <div> 3050 <h4 class="font-medium text-white">Younes ENNAJI</h4> 3051 <a href="https://www.linkedin.com/in/yoeunes/" 3052 class="text-slate-400 hover:text-white text-sm inline-flex items-center gap-1 mt-1 transition-colors"> 3053 <i class="fa-brands fa-linkedin"></i> LinkedIn 3054 </a> 3055 </div> 3056 </div> 3057 </div> 3058 </div> 3059 3060 <div class="mt-12 pt-6 border-t border-slate-800 text-center text-slate-500 text-sm"> 3061 <p>© 2026 PHPFlasher. Released under the MIT License.</p> 3062 </div> 3063 </div> 3064</footer> 3065 3066
3066<script> 3067 // Mobile menu toggle 3068 document.addEventListener('DOMContentLoaded', function() { 3069 const menuToggle = document.getElementById('menu-toggle'); 3070 const mobileMenu = document.getElementById('mobile-menu'); 3071 const closeMenu = document.getElementById('close-menu'); 3072 3073 if (menuToggle && mobileMenu) { 3074 menuToggle.addEventListener('click', function() { 3075 mobileMenu.classList.toggle('hidden'); 3076 document.body.classList.toggle('overflow-hidden'); 3077 }); 3078 3079 closeMenu.addEventListener('click', function() { 3080 mobileMenu.classList.add('hidden'); 3081 document.body.classList.remove('overflow-hidden'); 3082 }); 3083 } 3084 3085 // Run example buttons 3086 const exampleButtons = document.querySelectorAll('.run-example'); 3087 exampleButtons.forEach(button => { 3088 button.addEventListener('click', function() { 3089 const id = this.getAttribute('data-id'); 3090 if (window.messages && window.messages[id]) { 3091 const notification = window.messages[id]; 3092 // This assumes there's a global function to show notifications 3093 if (window.flasher) { 3094 window.flasher.flash( 3095 notification.type, 3096 notification.message, 3097 notification.options, 3098 notification.title 3099 ); 3100 } 3101 } 3102 }); 3103 }); 3104 3105 // Smooth scroll for anchor links 3106 document.querySelectorAll('a[href^="#"]').forEach(anchor => { 3107 anchor.addEventListener('click', function(e) { 3108 const target = document.querySelector(this.getAttribute('href')); 3109 if (target) { 3110 e.preventDefault(); 3111 window.scrollTo({ 3112 top: target.offsetTop - 100, // Adjust for header height 3113 behavior: 'smooth' 3114 }); 3115 } 3116 }); 3117 }); 3118 3119 // Generate table of contents 3120 const headings = document.querySelectorAll('main h2, main h3'); 3121 const tocList = document.querySelector('#anchor-navigation ul'); 3122 3123 if (headings.length > 0 && tocList) {
3124 headings.forEach((heading, index) => { 3125 // Add ID to heading if not present 3126 if (!heading.id) { 3127 heading.id = 'heading-' + index; 3128 } 3129 3130 const isH3 = heading.tagName.toLowerCase() === 'h3'; 3131 const listItem = document.createElement('li'); 3132 const link = document.createElement('a'); 3133 3134 link.href = '#' + heading.id; 3135 link.className = isH3 3136 ? 'pl-4 text-slate-600 hover:text-indigo-600 border-l-2 border-slate-200 hover:border-indigo-400 block py-1 transition-all' 3137 : 'text-slate-700 hover:text-indigo-600 font-medium block py-1 transition-colors'; 3138 link.textContent = heading.textContent; 3139 3140 listItem.appendChild(link); 3141 tocList.appendChild(listItem); 3142 }); 3143 3144 document.getElementById('anchor-navigation').classList.remove('hidden'); 3145 } 3146 3147 // Highlight active TOC item on scroll 3148 const tocLinks = document.querySelectorAll('#anchor-navigation a'); 3149 if (tocLinks.length > 0) { 3150 window.addEventListener('scroll', function() { 3151 let currentSection = ''; 3152
3153 headings.forEach(heading => { 3154 const sectionTop = heading.offsetTop - 120; 3155 if (window.pageYOffset >= sectionTop) { 3156 currentSection = '#' + heading.id; 3157 } 3158 }); 3159 3160 tocLinks.forEach(link => { 3161 link.classList.remove('text-indigo-600', 'border-indigo-400', 'font-medium'); 3162 if (link.getAttribute('href') === currentSection) { 3163 link.classList.add('text-indigo-600'); 3164 if (link.classList.contains('border-l-2')) { 3165 link.classList.add('border-indigo-400'); 3166 } else { 3167 link.classList.add('font-medium'); 3168 } 3169 } 3170 }); 3171 }); 3172 } 3173 }); 3174</script>
3174 3175 3176
3176<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"9e5222752344421a826ad5b0f804b052","r":1,"spa":2}' crossorigin="anonymous"></script>
3176 3177</body> 3178</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.