Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions app/Events/TimelineMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace App\Events;

use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use App\Models\User;
use Illuminate\Support\Facades\Log;

class TimelineMessage
{
use Dispatchable, InteractsWithSockets, SerializesModels;

public function __construct($user, $message, $subject_type, $subject_id)
{
Log::info('reached event');
$this->user = $user;
$this->message = $message;
$this->origin_client_id = $user->client_id;
$this->subject_type = $subject_type;
$this->subject_id = $subject_id;
}
}
12 changes: 8 additions & 4 deletions app/Http/Controllers/Auth/RegisteredUserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class RegisteredUserController extends Controller
*/
public function create(): Response
{
return Inertia::render('auth/register');
return Inertia::render('Auth/Register');
}

/**
Expand All @@ -31,13 +31,17 @@ public function create(): Response
public function store(Request $request): RedirectResponse
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|lowercase|email|max:255|unique:'.User::class,
'fname' => 'required|string|max:255',
'mname' => 'nullable|string|max:255',
'lname' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:'.User::class,
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);

$user = User::create([
'name' => $request->name,
'fname' => $request->fname,
'mname' => $request->mname,
'lname' => $request->lname,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
Expand Down
67 changes: 67 additions & 0 deletions app/Http/Controllers/ClientAdmin/AdminDashboardController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace App\Http\Controllers\ClientAdmin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Role;
use App\Models\Timeline;
use Inertia\Inertia;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rule;
use App\Models\Task;
use Carbon\Carbon;

class AdminDashboardController extends Controller
{
public function index()
{
$clientId = auth()->user()->client->id;

// Get all tasks with their users
$tasks = Task::where('client_id', $clientId)
->with(['users' => function ($query) use ($clientId) {
$query->where('users.client_id', $clientId)
->select('users.id', 'users.fname', 'users.mname', 'users.lname', 'users.email');
}])
->get();

// Get task completion statistics
$taskStats = [
'total' => $tasks->count(),
'completed' => $tasks->where('status', 'completed')->count(),
'in_progress' => $tasks->where('status', 'in_progress')->count(),
'pending' => $tasks->where('status', 'pending')->count(),
];

// Get upcoming tasks (due in the next 7 days)
$upcomingTasks = $tasks->filter(function ($task) {
return $task->due_date &&
Carbon::parse($task->due_date)->isBetween(
now(),
now()->addDays(7)
);
})->values()->toArray();

// Get all users for the timeline
$users = User::where('client_id', $clientId)
->select('id', 'fname', 'mname', 'lname', 'email')
->get();

// Get recent timeline activities
$recentActivities = Timeline::where('origin_client_id', $clientId)
->with(['user:id,fname,mname,lname,email'])
->latest()
->take(10)
->get();

return Inertia::render('admin/admin-dashboard', [
'taskStats' => $taskStats,
'upcomingTasks' => $upcomingTasks,
'users' => $users,
'tasks' => $tasks,
'recentActivities' => $recentActivities
]);
}
}
182 changes: 182 additions & 0 deletions app/Http/Controllers/Crud/ClientAdmin/MeetingController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
<?php

namespace App\Http\Controllers\Crud\ClientAdmin;

use App\Http\Controllers\Controller;
use App\Models\Meeting;
use App\Models\User;
use App\Models\Task;
use App\Models\Agenda;
use Illuminate\Http\Request;
use Inertia\Inertia;

class MeetingController extends Controller
{
public function index()
{
$clientId = auth()->user()->client->id;

$meetings = Meeting::where('client_id', $clientId)
->with(['users' => function ($query) use ($clientId) {
$query->where('users.client_id', $clientId)
->select('users.id', 'users.fname', 'users.mname', 'users.lname', 'users.email');
}])
->with(['tasks' => function ($query) use ($clientId) {
$query->where('tasks.client_id', $clientId)
->select('tasks.id', 'tasks.name', 'tasks.status')
->withPivot('meeting_id');
}])
->get();

$availableUsers = User::where('client_id', $clientId)
->select('id', 'fname', 'mname', 'lname', 'email')
->get();

$availableTasks = Task::where('client_id', $clientId)
->select('id', 'name', 'status')
->get();

return Inertia::render('admin/admin-meeting-list', [
'meetings' => $meetings,
'users' => $availableUsers,
'tasks' => $availableTasks
]);
}

public function store(Request $request)
{
$request->validate([
'title' => 'required|string|max:255',
'date' => 'required|date',
'type' => 'required|string|max:255',
'agenda_text' => 'required|string',
'users' => 'nullable|array',
'users.*' => 'exists:users,id',
'tasks' => 'nullable|array',
'tasks.*' => 'exists:tasks,id'
]);

$clientId = auth()->user()->client->id;

// Create agenda first
$agenda = Agenda::create([
'text' => $request->agenda_text,
'client_id' => $clientId,
]);

$meeting = Meeting::create([
'title' => $request->title,
'date' => $request->date,
'type' => $request->type,
'agenda_id' => $agenda->id,
'client_id' => $clientId,
]);

if ($request->has('users')) {
$meeting->users()->attach($request->users);
}

if ($request->has('tasks')) {
$meeting->tasks()->attach($request->tasks);
}

session()->flash('success', 'Meeting created successfully!');
return back();
}

public function show(Meeting $meeting)
{
$clientId = auth()->user()->client->id;

// Ensure the meeting belongs to the client
if ($meeting->client_id !== $clientId) {
abort(403);
}

// Load the meeting with its relationships and agenda
$meeting->load(['users' => function ($query) use ($clientId) {
$query->where('users.client_id', $clientId)
->select('users.id', 'users.fname', 'users.mname', 'users.lname', 'users.email');
}])
->load(['tasks' => function ($query) use ($clientId) {
$query->where('tasks.client_id', $clientId)
->select('tasks.id', 'tasks.name', 'tasks.status');
}])
->load('agenda');

// Add agenda_text to the meeting data
$meeting->agenda_text = $meeting->agenda->text;

// Get all available users and tasks for the form
$availableUsers = User::where('client_id', $clientId)
->select('id', 'fname', 'mname', 'lname', 'email')
->get();

$availableTasks = Task::where('client_id', $clientId)
->select('id', 'name', 'status')
->get();

return Inertia::render('admin/admin-meeting-details', [
'meeting' => $meeting,
'users' => $availableUsers,
'tasks' => $availableTasks
]);
}

public function update(Request $request, Meeting $meeting)
{
// Ensure the meeting belongs to the client
if ($meeting->client_id !== auth()->user()->client->id) {
abort(403, 'Unauthorized');
}

$request->validate([
'title' => 'required|string|max:255',
'date' => 'required|date',
'type' => 'required|string|max:255',
'agenda_text' => 'required|string',
'users' => 'nullable|array',
'users.*' => 'exists:users,id',
'tasks' => 'nullable|array',
'tasks.*' => 'exists:tasks,id'
]);

// Update the meeting
$meeting->update([
'title' => $request->title,
'date' => $request->date,
'type' => $request->type,
]);

// Update the agenda
$meeting->agenda()->update([
'text' => $request->agenda_text
]);

// Sync users and tasks if they are provided
if ($request->has('users')) {
$meeting->users()->sync($request->users);
}

if ($request->has('tasks')) {
$meeting->tasks()->sync($request->tasks);
}

session()->flash('success', 'Meeting updated successfully!');
return back();
}

public function destroy(Meeting $meeting)
{
// Ensure the meeting belongs to the client
if ($meeting->client_id !== auth()->user()->client->id) {
abort(403, 'Unauthorized');
}

// Delete the meeting (this will cascade delete the agenda due to the relationship)
$meeting->delete();

session()->flash('success', 'Meeting deleted successfully!');
return redirect()->route('admin.meetings.index');
}
}
Loading