diff --git a/app/Http/Controllers/AdminCuratedRegisterController.php b/app/Http/Controllers/AdminCuratedRegisterController.php index 1bed66b7c..91400afb4 100644 --- a/app/Http/Controllers/AdminCuratedRegisterController.php +++ b/app/Http/Controllers/AdminCuratedRegisterController.php @@ -2,69 +2,72 @@ namespace App\Http\Controllers; -use Illuminate\Http\Request; -use App\Models\CuratedRegister; -use App\Models\CuratedRegisterActivity; -use Illuminate\Support\Str; -use Illuminate\Support\Facades\Mail; -use App\Mail\CuratedRegisterRequestDetailsFromUser; use App\Mail\CuratedRegisterAcceptUser; use App\Mail\CuratedRegisterRejectUser; +use App\Mail\CuratedRegisterRequestDetailsFromUser; +use App\Models\CuratedRegister; +use App\Models\CuratedRegisterActivity; +use App\Models\CuratedRegisterTemplate; use App\User; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Mail; +use Illuminate\Support\Str; class AdminCuratedRegisterController extends Controller { public function __construct() { - $this->middleware(['auth','admin']); + $this->middleware(['auth', 'admin']); } public function index(Request $request) { $this->validate($request, [ 'filter' => 'sometimes|in:open,all,awaiting,approved,rejected,responses', - 'sort' => 'sometimes|in:asc,desc' + 'sort' => 'sometimes|in:asc,desc', ]); $filter = $request->input('filter', 'open'); $sort = $request->input('sort', 'asc'); - $records = CuratedRegister::when($filter, function($q, $filter) { - if($filter === 'open') { - return $q->where('is_rejected', false) - ->where(function($query) { + $records = CuratedRegister::when($filter, function ($q, $filter) { + if ($filter === 'open') { + return $q->where('is_rejected', false) + ->where(function ($query) { return $query->where('user_has_responded', true)->orWhere('is_awaiting_more_info', false); }) ->whereNotNull('email_verified_at') ->whereIsClosed(false); - } else if($filter === 'all') { - return $q; - } else if($filter === 'responses') { - return $q->whereIsClosed(false) - ->whereNotNull('email_verified_at') - ->where('user_has_responded', true) - ->where('is_awaiting_more_info', true); - } elseif ($filter === 'awaiting') { - return $q->whereIsClosed(false) - ->where('is_rejected', false) - ->where('is_approved', false) - ->where('user_has_responded', false) - ->where('is_awaiting_more_info', true); - } elseif ($filter === 'approved') { - return $q->whereIsClosed(true)->whereIsApproved(true); - } elseif ($filter === 'rejected') { - return $q->whereIsClosed(true)->whereIsRejected(true); - } - }) - ->when($sort, function($query, $sort) { + } elseif ($filter === 'all') { + return $q; + } elseif ($filter === 'responses') { + return $q->whereIsClosed(false) + ->whereNotNull('email_verified_at') + ->where('user_has_responded', true) + ->where('is_awaiting_more_info', true); + } elseif ($filter === 'awaiting') { + return $q->whereIsClosed(false) + ->where('is_rejected', false) + ->where('is_approved', false) + ->where('user_has_responded', false) + ->where('is_awaiting_more_info', true); + } elseif ($filter === 'approved') { + return $q->whereIsClosed(true)->whereIsApproved(true); + } elseif ($filter === 'rejected') { + return $q->whereIsClosed(true)->whereIsRejected(true); + } + }) + ->when($sort, function ($query, $sort) { return $query->orderBy('id', $sort); }) ->paginate(10) ->withQueryString(); + return view('admin.curated-register.index', compact('records', 'filter')); } public function show(Request $request, $id) { $record = CuratedRegister::findOrFail($id); + return view('admin.curated-register.show', compact('record')); } @@ -80,10 +83,10 @@ class AdminCuratedRegisterController extends Controller 'message' => null, 'link' => null, 'timestamp' => $record->created_at, - ] + ], ]); - if($record->email_verified_at) { + if ($record->email_verified_at) { $res->push([ 'id' => 3, 'action' => 'email_verified_at', @@ -99,10 +102,11 @@ class AdminCuratedRegisterController extends Controller $idx = 4; $userResponses = collect([]); - foreach($activities as $activity) { + foreach ($activities as $activity) { $idx++; - if($activity->from_user) { + if ($activity->from_user) { $userResponses->push($activity); + continue; } $res->push([ @@ -116,20 +120,22 @@ class AdminCuratedRegisterController extends Controller ]); } - foreach($userResponses as $ur) { - $res = $res->map(function($r) use($ur) { - if(!isset($r['aid'])) { + foreach ($userResponses as $ur) { + $res = $res->map(function ($r) use ($ur) { + if (! isset($r['aid'])) { return $r; } - if($ur->reply_to_id === $r['aid']) { + if ($ur->reply_to_id === $r['aid']) { $r['user_response'] = $ur; + return $r; } + return $r; }); } - if($record->is_approved) { + if ($record->is_approved) { $idx++; $res->push([ 'id' => $idx, @@ -139,7 +145,7 @@ class AdminCuratedRegisterController extends Controller 'link' => null, 'timestamp' => $record->action_taken_at, ]); - } else if ($record->is_rejected) { + } elseif ($record->is_rejected) { $idx++; $res->push([ 'id' => $idx, @@ -157,13 +163,14 @@ class AdminCuratedRegisterController extends Controller public function apiMessagePreviewStore(Request $request, $id) { $record = CuratedRegister::findOrFail($id); + return $request->all(); } public function apiMessageSendStore(Request $request, $id) { $this->validate($request, [ - 'message' => 'required|string|min:5|max:1000' + 'message' => 'required|string|min:5|max:1000', ]); $record = CuratedRegister::findOrFail($id); abort_if($record->email_verified_at === null, 400, 'Cannot message an unverified email'); @@ -179,6 +186,7 @@ class AdminCuratedRegisterController extends Controller $record->user_has_responded = false; $record->save(); Mail::to($record->email)->send(new CuratedRegisterRequestDetailsFromUser($record, $activity)); + return $request->all(); } @@ -188,22 +196,23 @@ class AdminCuratedRegisterController extends Controller abort_if($record->email_verified_at === null, 400, 'Cannot message an unverified email'); $activity = new CuratedRegisterActivity; $activity->message = $request->input('message'); + return new \App\Mail\CuratedRegisterRequestDetailsFromUser($record, $activity); } - public function previewMessageShow(Request $request, $id) { $record = CuratedRegister::findOrFail($id); abort_if($record->email_verified_at === null, 400, 'Cannot message an unverified email'); $record->message = $request->input('message'); + return new \App\Mail\CuratedRegisterSendMessage($record); } public function apiHandleReject(Request $request, $id) { $this->validate($request, [ - 'action' => 'required|in:reject-email,reject-silent' + 'action' => 'required|in:reject-email,reject-silent', ]); $action = $request->input('action'); $record = CuratedRegister::findOrFail($id); @@ -212,9 +221,10 @@ class AdminCuratedRegisterController extends Controller $record->is_closed = true; $record->action_taken_at = now(); $record->save(); - if($action === 'reject-email') { + if ($action === 'reject-email') { Mail::to($record->email)->send(new CuratedRegisterRejectUser($record)); } + return [200]; } @@ -233,10 +243,89 @@ class AdminCuratedRegisterController extends Controller 'password' => $record->password, 'app_register_ip' => $record->ip_address, 'email_verified_at' => now(), - 'register_source' => 'cur_onboarding' + 'register_source' => 'cur_onboarding', ]); Mail::to($record->email)->send(new CuratedRegisterAcceptUser($record)); + return [200]; } + + public function templates(Request $request) + { + $templates = CuratedRegisterTemplate::paginate(10); + + return view('admin.curated-register.templates', compact('templates')); + } + + public function templateCreate(Request $request) + { + return view('admin.curated-register.template-create'); + } + + public function templateEdit(Request $request, $id) + { + $template = CuratedRegisterTemplate::findOrFail($id); + + return view('admin.curated-register.template-edit', compact('template')); + } + + public function templateEditStore(Request $request, $id) + { + $this->validate($request, [ + 'name' => 'required|string|max:30', + 'content' => 'required|string|min:5|max:3000', + 'description' => 'nullable|sometimes|string|max:1000', + 'active' => 'sometimes', + ]); + $template = CuratedRegisterTemplate::findOrFail($id); + $template->name = $request->input('name'); + $template->content = $request->input('content'); + $template->description = $request->input('description'); + $template->is_active = $request->boolean('active'); + $template->save(); + + return redirect()->back()->with('status', 'Successfully updated template!'); + } + + public function templateDelete(Request $request, $id) + { + $template = CuratedRegisterTemplate::findOrFail($id); + $template->delete(); + + return redirect(route('admin.curated-onboarding.templates'))->with('status', 'Successfully deleted template!'); + } + + public function templateStore(Request $request) + { + $this->validate($request, [ + 'name' => 'required|string|max:30', + 'content' => 'required|string|min:5|max:3000', + 'description' => 'nullable|sometimes|string|max:1000', + 'active' => 'sometimes', + ]); + CuratedRegisterTemplate::create([ + 'name' => $request->input('name'), + 'content' => $request->input('content'), + 'description' => $request->input('description'), + 'is_active' => $request->boolean('active'), + ]); + + return redirect(route('admin.curated-onboarding.templates'))->with('status', 'Successfully created new template!'); + } + + public function getActiveTemplates(Request $request) + { + $templates = CuratedRegisterTemplate::whereIsActive(true) + ->orderBy('order') + ->get() + ->map(function ($tmp) { + return [ + 'name' => $tmp->name, + 'content' => $tmp->content, + ]; + }); + + return response()->json($templates); + } } diff --git a/app/Models/CuratedRegisterTemplate.php b/app/Models/CuratedRegisterTemplate.php new file mode 100644 index 000000000..a5def0cef --- /dev/null +++ b/app/Models/CuratedRegisterTemplate.php @@ -0,0 +1,19 @@ + 'boolean', + ]; +} diff --git a/database/migrations/2024_02_24_105641_create_curated_register_templates_table.php b/database/migrations/2024_02_24_105641_create_curated_register_templates_table.php new file mode 100644 index 000000000..4829fefb2 --- /dev/null +++ b/database/migrations/2024_02_24_105641_create_curated_register_templates_table.php @@ -0,0 +1,32 @@ +id(); + $table->string('name')->nullable(); + $table->text('description')->nullable(); + $table->text('content')->nullable(); + $table->boolean('is_active')->default(false)->index(); + $table->tinyInteger('order')->default(10)->unsigned()->index(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('curated_register_templates'); + } +}; diff --git a/resources/views/admin/curated-register/partials/activity-log.blade.php b/resources/views/admin/curated-register/partials/activity-log.blade.php index 1d7701f44..d141a4424 100644 --- a/resources/views/admin/curated-register/partials/activity-log.blade.php +++ b/resources/views/admin/curated-register/partials/activity-log.blade.php @@ -46,6 +46,21 @@
Request Additional Details
Use this form to request additional details. Once you press Send, we'll send the potential user an email with a special link they can visit with a form that they can provide additional details with. You can also Preview the email before it's sent.
+Template Responses
+ +@{{ composeMessage && composeMessage.length ? composeMessage.length : 0 }} / - 500 + 2000
Send Message
Use this form to send a message to the applicant. Once you press Send, we'll send the potential user an email with your message. You can also Preview the email before it's sent.
+Template Responses
+ +Curated Onboarding
+The ideal solution for communities seeking a balance between open registration and invite-only membership
+Create re-usable templates of messages and application requests.
+{{ $error }}
+ @endforeach +Curated Onboarding
+The ideal solution for communities seeking a balance between open registration and invite-only membership
+{{ $error }}
+ @endforeach +Curated Onboarding
+The ideal solution for communities seeking a balance between open registration and invite-only membership
+Create and manage re-usable templates of messages and application requests.
+ Create new Template +ID | +Shortcut/Name | +Content | +Active | +Created | +
---|---|---|---|---|
+ + {{ $template->id }} + + | ++ {{ $template->name }} + | ++ {{ str_limit($template->content, 80) }} + | ++ {{ $template->is_active ? '✅' : '❌' }} + | ++ {{ $template->created_at->format('M d Y') }} + | +