1
0

CuratedOnboardingCommand.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Mail\CuratedRegisterConfirmEmail;
  4. use App\Models\CuratedRegister;
  5. use App\Models\CuratedRegisterActivity;
  6. use Illuminate\Console\Command;
  7. use Illuminate\Support\Facades\DB;
  8. use Illuminate\Support\Facades\Mail;
  9. use Illuminate\Support\Str;
  10. use function Laravel\Prompts\confirm;
  11. use function Laravel\Prompts\search;
  12. use function Laravel\Prompts\select;
  13. use function Laravel\Prompts\table;
  14. class CuratedOnboardingCommand extends Command
  15. {
  16. /**
  17. * The name and signature of the console command.
  18. *
  19. * @var string
  20. */
  21. protected $signature = 'app:curated-onboarding';
  22. /**
  23. * The console command description.
  24. *
  25. * @var string
  26. */
  27. protected $description = 'Manage curated onboarding applications';
  28. /**
  29. * Execute the console command.
  30. */
  31. public function handle()
  32. {
  33. $this->line(' ');
  34. $this->info(' Welcome to the Curated Onboarding manager');
  35. $this->line(' ');
  36. $action = select(
  37. label: 'Select an action:',
  38. options: ['Stats', 'Edit'],
  39. default: 'Stats',
  40. hint: 'You can manage this via the admin dashboard.'
  41. );
  42. switch ($action) {
  43. case 'Stats':
  44. return $this->stats();
  45. break;
  46. case 'Edit':
  47. return $this->edit();
  48. break;
  49. default:
  50. exit;
  51. break;
  52. }
  53. }
  54. protected function stats()
  55. {
  56. $total = CuratedRegister::count();
  57. $approved = CuratedRegister::whereIsApproved(true)->whereIsRejected(false)->whereNotNull('email_verified_at')->count();
  58. $awaitingMoreInfo = CuratedRegister::whereIsAwaitingMoreInfo(true)->whereIsRejected(false)->whereIsClosed(false)->whereNotNull('email_verified_at')->count();
  59. $open = CuratedRegister::whereIsApproved(false)->whereIsRejected(false)->whereIsClosed(false)->whereNotNull('email_verified_at')->whereIsAwaitingMoreInfo(false)->count();
  60. $nonVerified = CuratedRegister::whereIsApproved(false)->whereIsRejected(false)->whereIsClosed(false)->whereNull('email_verified_at')->whereIsAwaitingMoreInfo(false)->count();
  61. table(
  62. ['Total', 'Approved', 'Open', 'Awaiting More Info', 'Unverified Emails'],
  63. [
  64. [$total, $approved, $open, $awaitingMoreInfo, $nonVerified],
  65. ]
  66. );
  67. }
  68. protected function edit()
  69. {
  70. $id = search(
  71. label: 'Search for a username or email',
  72. options: fn (string $value) => strlen($value) > 0
  73. ? CuratedRegister::where(function ($query) use ($value) {
  74. $query->whereLike('username', "%{$value}%")
  75. ->orWhereLike('email', "%{$value}%");
  76. })->get()
  77. ->mapWithKeys(fn ($user) => [
  78. $user->id => "{$user->username} ({$user->email})",
  79. ])
  80. ->all()
  81. : []
  82. );
  83. $register = CuratedRegister::findOrFail($id);
  84. if ($register->is_approved) {
  85. $status = 'Approved';
  86. } elseif ($register->is_rejected) {
  87. $status = 'Rejected';
  88. } elseif ($register->is_closed) {
  89. $status = 'Closed';
  90. } elseif ($register->is_awaiting_more_info) {
  91. $status = 'Awaiting more info';
  92. } elseif ($register->user_has_responded) {
  93. $status = 'Awaiting Admin Response';
  94. } else {
  95. $status = 'Unknown';
  96. }
  97. table(
  98. ['Field', 'Value'],
  99. [
  100. ['ID', $register->id],
  101. ['Username', $register->username],
  102. ['Email', $register->email],
  103. ['Status', $status],
  104. ['Created At', $register->created_at->format('Y-m-d H:i')],
  105. ['Updated At', $register->updated_at->format('Y-m-d H:i')],
  106. ]
  107. );
  108. if (in_array($status, ['Approved', 'Rejected', 'Closed'])) {
  109. return;
  110. }
  111. $options = ['Cancel', 'Delete'];
  112. if ($register->email_verified_at == null) {
  113. $options[] = 'Resend Email Verification';
  114. }
  115. $action = select(
  116. label: 'Select an action:',
  117. options: $options,
  118. default: 'Cancel',
  119. );
  120. if ($action === 'Resend Email Verification') {
  121. $confirmed = confirm('Are you sure you want to send another email to '.$register->email.' ?');
  122. if (! $confirmed) {
  123. $this->error('Aborting...');
  124. exit;
  125. }
  126. DB::transaction(function () use ($register) {
  127. $register->verify_code = Str::random(40);
  128. $register->created_at = now();
  129. $register->save();
  130. Mail::to($register->email)->send(new CuratedRegisterConfirmEmail($register));
  131. $this->info('Mail sent!');
  132. });
  133. } elseif ($action === 'Delete') {
  134. $confirmed = confirm('Are you sure you want to delete the application from '.$register->email.' ?');
  135. if (! $confirmed) {
  136. $this->error('Aborting...');
  137. exit;
  138. }
  139. DB::transaction(function () use ($register) {
  140. CuratedRegisterActivity::whereRegisterId($register->id)->delete();
  141. $register->delete();
  142. $this->info('Successfully deleted!');
  143. });
  144. } else {
  145. $this->info('Cancelled.');
  146. exit;
  147. }
  148. }
  149. }