From 3fe167e33f2a065258f7e42a0a6ae68b1ada1a98 Mon Sep 17 00:00:00 2001 From: ghassan Date: Sat, 16 May 2026 23:34:28 +0300 Subject: [PATCH] Notify super admins on new user registration (bell + email) When a new user registers, all super_admin users receive: - A database notification shown in the bell (type: new_user), with the new user's avatar and a link to their channel - An email congratulating them with the new member's name, email, join date, gender, and nationality, plus a View Profile CTA Notification rendering in app.blade.php refactored into notifHref() and notifThumb() helpers so new_user notifications link to /channel/{slug} and show a circular avatar instead of a video thumbnail. Also fixed the legacy /storage/thumbnails/ path to /media/thumbnails/ for video notifications. Co-Authored-By: Claude Sonnet 4.6 --- .../Auth/RegisteredUserController.php | 6 +++ app/Notifications/NewUserRegistered.php | 39 ++++++++++++++ .../emails/new-user-registered.blade.php | 51 +++++++++++++++++++ resources/views/layouts/app.blade.php | 26 +++++++--- 4 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 app/Notifications/NewUserRegistered.php create mode 100644 resources/views/emails/new-user-registered.blade.php diff --git a/app/Http/Controllers/Auth/RegisteredUserController.php b/app/Http/Controllers/Auth/RegisteredUserController.php index afa45b8..f9d31ca 100644 --- a/app/Http/Controllers/Auth/RegisteredUserController.php +++ b/app/Http/Controllers/Auth/RegisteredUserController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Models\User; +use App\Notifications\NewUserRegistered; use App\Rules\NotDisposableEmail; use Illuminate\Auth\Events\Registered; use Illuminate\Http\Request; @@ -45,6 +46,11 @@ class RegisteredUserController extends Controller event(new Registered($user)); + // Notify all super admins of the new registration + User::where('role', 'super_admin')->each(function (User $admin) use ($user) { + $admin->notify(new NewUserRegistered($user)); + }); + auth()->login($user); return redirect()->route('verification.notice'); diff --git a/app/Notifications/NewUserRegistered.php b/app/Notifications/NewUserRegistered.php new file mode 100644 index 0000000..d60ecc9 --- /dev/null +++ b/app/Notifications/NewUserRegistered.php @@ -0,0 +1,39 @@ + 'new_user', + 'user_id' => $this->newUser->id, + 'user_name' => $this->newUser->name, + 'user_email' => $this->newUser->email, + 'user_avatar' => $this->newUser->avatar_url, + 'user_channel' => $this->newUser->channel, + ]; + } + + public function toMail(object $notifiable): MailMessage + { + return (new MailMessage) + ->subject('New member joined TAKEONE 🎉') + ->view('emails.new-user-registered', [ + 'newUser' => $this->newUser, + 'admin' => $notifiable, + ]); + } +} diff --git a/resources/views/emails/new-user-registered.blade.php b/resources/views/emails/new-user-registered.blade.php new file mode 100644 index 0000000..268e070 --- /dev/null +++ b/resources/views/emails/new-user-registered.blade.php @@ -0,0 +1,51 @@ + + + {{-- Icon --}} +
🎉
+ +

New member joined!

+ + + + + + {{-- Info box --}} + + + {{-- CTA --}} + + + + + + +
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 69aa1d2..2e4d282 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -1219,17 +1219,34 @@ } function notifText(d) { - var actor = '' + escHtml(d.actor_name || d.uploader_name || '') + ''; + var actor = '' + escHtml(d.actor_name || d.uploader_name || d.user_name || '') + ''; var title = '"' + escHtml(d.video_title || '') + '"'; var preview = d.comment_preview ? ' "' + escHtml(d.comment_preview) + '"' : ''; switch (d.type) { case 'new_comment': return actor + ' commented on your video ' + title + ':' + preview; case 'new_reply': return actor + ' replied to your comment:' + preview; case 'comment_like':return actor + ' liked your comment on ' + title; + case 'new_user': return '🎉 ' + actor + ' just joined TAKEONE!'; default: return actor + ' uploaded a new video: ' + title; } } + function notifHref(d) { + if (d.type === 'new_user') return '/channel/' + encodeURIComponent(d.user_channel || ''); + return '/videos/' + escHtml(d.video_route_key || ''); + } + + function notifThumb(d) { + if (d.type === 'new_user') { + return d.user_avatar + ? '' + : '
'; + } + return d.video_thumbnail + ? '' + : '
'; + } + function renderNotifications(data) { var unread = data.unread_count; if (unread > 0) { @@ -1248,15 +1265,12 @@ list.innerHTML = data.notifications.map(function (n) { var d = n.data; - var thumb = d.video_thumbnail - ? '' - : '
'; var dot = !n.read ? '
' : ''; return '' - + thumb + + notifThumb(d) + '
' + '
' + notifText(d) + '
' + '
' + escHtml(n.time) + '
'