Phases 0–18: core meetings, webinar, breakouts, team chat, live streaming, town hall, billing, and Ladill Mail calendar wiring. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Meet;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\Meet\Concerns\ScopesToAccount;
|
||||
use App\Models\ContactGroup;
|
||||
use App\Models\Invitation;
|
||||
use App\Models\Room;
|
||||
use App\Services\Meet\ContactService;
|
||||
use App\Services\Meet\InvitationService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class InvitationController extends Controller
|
||||
{
|
||||
use ScopesToAccount;
|
||||
|
||||
public function __construct(
|
||||
protected InvitationService $invitations,
|
||||
protected ContactService $contacts,
|
||||
) {}
|
||||
|
||||
public function index(Request $request, Room $room): View
|
||||
{
|
||||
$this->authorizeAbility($request, 'meetings.manage');
|
||||
$this->authorizeOwner($request, $room);
|
||||
|
||||
$room->load(['invitations' => fn ($q) => $q->orderByDesc('created_at')]);
|
||||
$groups = ContactGroup::owned($this->ownerRef($request))
|
||||
->where('organization_id', $room->organization_id)
|
||||
->withCount('members')
|
||||
->orderBy('name')
|
||||
->get();
|
||||
|
||||
return view('meet.invitations.index', compact('room', 'groups'));
|
||||
}
|
||||
|
||||
public function store(Request $request, Room $room): RedirectResponse
|
||||
{
|
||||
$this->authorizeAbility($request, 'meetings.manage');
|
||||
$this->authorizeOwner($request, $room);
|
||||
|
||||
$validated = $request->validate([
|
||||
'emails' => ['nullable', 'string'],
|
||||
'member_refs' => ['nullable', 'array'],
|
||||
'member_refs.*' => ['string'],
|
||||
'contact_group_id' => ['nullable', 'integer', 'exists:meet_contact_groups,id'],
|
||||
]);
|
||||
|
||||
$invites = [];
|
||||
|
||||
if ($emails = trim((string) ($validated['emails'] ?? ''))) {
|
||||
foreach (preg_split('/[\s,;]+/', $emails) as $email) {
|
||||
if ($email = trim($email)) {
|
||||
$invites[] = ['email' => $email];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($validated['member_refs'] ?? [] as $userRef) {
|
||||
$user = \App\Models\User::where('public_id', $userRef)->first();
|
||||
if ($user?->email) {
|
||||
$invites[] = ['email' => $user->email, 'name' => $user->name, 'user_ref' => $userRef];
|
||||
}
|
||||
}
|
||||
|
||||
if (! empty($validated['contact_group_id'])) {
|
||||
$group = ContactGroup::owned($this->ownerRef($request))->findOrFail($validated['contact_group_id']);
|
||||
$invites = array_merge($invites, $this->contacts->fromGroup($group)->all());
|
||||
}
|
||||
|
||||
$this->invitations->inviteToRoom($room, $invites, $request->user());
|
||||
|
||||
return back()->with('success', count($invites).' invitation(s) sent.');
|
||||
}
|
||||
|
||||
public function bulkCsv(Request $request, Room $room): RedirectResponse
|
||||
{
|
||||
$this->authorizeAbility($request, 'meetings.manage');
|
||||
$this->authorizeOwner($request, $room);
|
||||
|
||||
$request->validate(['csv' => ['required', 'file', 'mimes:csv,txt', 'max:2048']]);
|
||||
$count = $this->invitations->bulkFromCsv($room, $request->file('csv')->getContent(), $request->user());
|
||||
|
||||
return back()->with('success', "{$count} invitation(s) imported.");
|
||||
}
|
||||
|
||||
public function resend(Request $request, Invitation $invitation): RedirectResponse
|
||||
{
|
||||
$this->authorizeAbility($request, 'meetings.manage');
|
||||
$this->authorizeOwner($request, $invitation);
|
||||
|
||||
$this->invitations->resend($invitation, $request->user());
|
||||
|
||||
return back()->with('success', 'Invitation resent.');
|
||||
}
|
||||
|
||||
public function destroy(Request $request, Invitation $invitation): RedirectResponse
|
||||
{
|
||||
$this->authorizeAbility($request, 'meetings.manage');
|
||||
$this->authorizeOwner($request, $invitation);
|
||||
$room = $invitation->room;
|
||||
$invitation->delete();
|
||||
|
||||
return redirect()->route('meet.invitations.index', $room)->with('success', 'Invitation removed.');
|
||||
}
|
||||
|
||||
public function rsvp(Request $request, Invitation $invitation): View|RedirectResponse
|
||||
{
|
||||
abort_unless(hash_equals((string) $invitation->rsvp_token, (string) $request->query('token')), 403);
|
||||
|
||||
if ($request->isMethod('post')) {
|
||||
$validated = $request->validate(['status' => ['required', 'in:accepted,declined']]);
|
||||
$this->invitations->respond($invitation, $validated['status'], $invitation->rsvp_token);
|
||||
|
||||
return view('meet.invitations.rsvp-done', [
|
||||
'invitation' => $invitation->fresh(),
|
||||
'room' => $invitation->room,
|
||||
]);
|
||||
}
|
||||
|
||||
return view('meet.invitations.rsvp', [
|
||||
'invitation' => $invitation,
|
||||
'room' => $invitation->room,
|
||||
]);
|
||||
}
|
||||
|
||||
public function searchContacts(Request $request): JsonResponse
|
||||
{
|
||||
$this->authorizeAbility($request, 'meetings.create');
|
||||
$organization = $this->organization($request);
|
||||
$query = (string) $request->query('q', '');
|
||||
|
||||
$results = $this->contacts->search($organization->id, $this->ownerRef($request), $query);
|
||||
|
||||
return response()->json(['contacts' => $results]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user