diff --git a/app/Http/Controllers/Auth/ApiAuthController.php b/app/Http/Controllers/Auth/ApiAuthController.php index 230aef3..c5be14c 100644 --- a/app/Http/Controllers/Auth/ApiAuthController.php +++ b/app/Http/Controllers/Auth/ApiAuthController.php @@ -38,7 +38,8 @@ class ApiAuthController extends Controller return response()->json([ 'access_token' => $token, 'token_type' => 'Bearer', - ]); + ], 201 + ); } } @@ -52,11 +53,13 @@ class ApiAuthController extends Controller $user = User::where('email', $request['email'])->firstOrFail(); - $token = $user->createToken('auth_token')->plainTextToken; + $token = $user->createToken('auth_token') + ->plainTextToken; return response()->json([ 'access_token' => $token, 'token_type' => 'Bearer', + 'message' => 'Login successful, please remember to logout!' ]); } @@ -64,4 +67,14 @@ class ApiAuthController extends Controller { return $request->user(); } + + public function logout(Request $request) + { + $request->user()->currentAccessToken()->delete(); + return response()->json([ + 'message' => 'Logged out' + ], 200 + ); + } + } diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index 2b42e5b..36031cb 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -22,16 +22,20 @@ use Illuminate\Support\Facades\Response; class ProjectController extends Controller { + protected mixed $project_api_route_pattern = 'api/*'; /** * Display Listing of all Projects. + * @throws AuthorizationException */ public function index(Request $request): View|Factory|Application|JsonResponse|ProjectResource { // Check if API Call, get userID from request - if ($request->is('api/*')) { + if ($request->expectsJson()) { $user = Auth::user(); + $this->authorize('viewAny', Project::class); $projects = $user->projects()->paginate(4); + return new ProjectResource($projects); } @@ -77,13 +81,15 @@ class ProjectController extends Controller $data = $request->validated(); // Check if API Call, get userID from request - if ($request->is('api/*')) { - $user = User::find($request->user_id); - if (!$user) { - return response()->json(['error' => 'User not found'], 404); - } + if ($request->expectsJson()) { + $user = Auth::user(); + + $this->authorize('create', Project::class); + $user->projects()->create($data); + $data = $user->projects()->latest()->first(); + return response()->json([ 'message' => 'Project created successfully', 'data' => $data, @@ -103,11 +109,8 @@ class ProjectController extends Controller public function show(Request $request, $project_id): RedirectResponse|JsonResponse { // Check if API Call, get userID from request - if ($request->is('api/*')) { - $user = User::find($request->user_id); - if (!$user) { - return response()->json(['error' => 'User not found'], 404); - } + if ($request->expectsJson()) { + $user = Auth::user(); $project = $user->projects()->find($project_id); @@ -117,6 +120,8 @@ class ProjectController extends Controller ], 404); } + $this->authorize('view', $project); + return response()->json([ 'message' => 'Project retrieved successfully', 'data' => $project, @@ -152,11 +157,8 @@ class ProjectController extends Controller $data = $request->validatedWithCompletedAt(); // API Call - if ($request->is('api/*')) { - $user = User::find($request->user_id); - if (!$user) { - return response()->json(['error' => 'User not found'], 404); - } + if ($request->expectsJson()) { + $user = Auth::user(); $project = $user->projects()->find($project_id); @@ -166,6 +168,8 @@ class ProjectController extends Controller ], 404); } + $this->authorize('update', $project); + $project->update($data); return response()->json([ @@ -201,12 +205,8 @@ class ProjectController extends Controller public function destroy($project_id, Request $request): RedirectResponse|JsonResponse { // Check if API Call and $project_id is provided - if ($request->is('api/*')) { - $user_id = $request->user_id; - $user = User::find($user_id); - if (!$user) { - return response()->json(['error' => 'User not found'], 404); - } + if ($request->expectsJson() && $project_id) { + $user = Auth::user(); $project = $user->projects()->find($project_id); @@ -217,6 +217,8 @@ class ProjectController extends Controller ], 404); } + $this->authorize('delete', $project); + $project->delete(); return response()->json([ diff --git a/app/Http/Controllers/ProjectTodoController.php b/app/Http/Controllers/ProjectTodoController.php index bc54398..ebe4dd1 100644 --- a/app/Http/Controllers/ProjectTodoController.php +++ b/app/Http/Controllers/ProjectTodoController.php @@ -4,13 +4,17 @@ namespace App\Http\Controllers; use App\Http\Requests\Project\StoreTodoRequest; use App\Http\Requests\Project\UpdateTodoRequest; +use App\Http\Resources\TodoResource; use App\Models\Todo; use App\Models\User; use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\View; use Illuminate\Foundation\Application; +use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\Auth; +use Illuminate\Http\Request; class ProjectTodoController extends Controller { @@ -19,13 +23,23 @@ class ProjectTodoController extends Controller /** * Display a listing of all Todos for a Project. */ - public function index($project_id): Factory|Application|View|\Illuminate\Contracts\Foundation\Application|RedirectResponse + public function index(Request $request, $project_id): + Factory|Application|View|\Illuminate\Contracts\Foundation\Application|RedirectResponse|TodoResource { - $user = User::find(auth()->user()->id); - $projects = $user->projects; + $user = Auth::user(); + $projects = $user->projects(); $project = $projects->find($project_id); - if (!$project || $project->user->id !== auth()->user()->id) + if ($request->expectsJson()) { + $this->authorize('viewAny', [Todo::class, $project]); + + $todos = $project->todos()->paginate(4); + + return new TodoResource($todos); + } + + + if (!$project || $project->user->id !== $user->id) return back() ->with('error', 'Project not found'); @@ -43,7 +57,7 @@ class ProjectTodoController extends Controller */ public function create($project_id): Factory|View|Application { - $project = auth()->user()->projects->find($project_id); + $project = Auth::user()->projects->find($project_id); return view('todo.create', [ 'project' => $project, ]); @@ -52,33 +66,55 @@ class ProjectTodoController extends Controller /** * Store a newly created Todo in storage. */ - public function store($project_id, StoreTodoRequest $request): RedirectResponse + public function store($project_id, StoreTodoRequest $request): RedirectResponse|JsonResponse { - $user = User::find(auth()->user()->id); + $validatedData = $request->validated(); + $user = Auth::user(); + $project = $user->projects->find($project_id); + $this->authorize('create', [Todo::class, $user]); - $validatedData = $request->validated(); - - $project = $user->projects->find($project_id); // Add the Todo to the Project $project->todos()->save(new Todo($validatedData)); + if ($request->expectsJson()) { + return response()->json([ + 'message' => 'Todo created successfully.', + 'data' => $project->todos()->latest()->first(), + ], 201); + } + return redirect()->route('project.todo.index', $project_id) ->with('success', 'Todo created successfully.'); } + /** * Display the specified resource. */ - public function show($project_id, Todo $todo) + public function show(Request $request, $project_id) { - $user = User::find(auth()->user()->id); - $projects = $user->projects; - $project = $projects->find($project_id); + if ($request->expectsJson()) { + $user = Auth::user(); + $project = $user->projects->find($project_id); + $todo = $project->todos->find($request->todo_id); - $this->authorize('view', [Todo::class, $project, $todo]); + $this->authorize('view', [Todo::class, $project, $todo]); - return view('todo.show', compact('project', 'todo')); + return response()->json([ + 'message' => 'Todo retrieved successfully.', + 'data' => $todo, + ], 200); + } + + return redirect()->route('project.todo.index', $project_id); +// $user = Auth::user(); +// $projects = $user->projects; +// $project = $projects->find($project_id); +// +// $this->authorize('view', [Todo::class, $project, $project->todos->find($request->todo_id)]); +// +// return view('todo.show', compact('project', 'todo')); } /** @@ -99,37 +135,49 @@ class ProjectTodoController extends Controller public function update($project_id, UpdateTodoRequest $request, Todo $todo) { $project = auth()->user()->projects->find($project_id); - $this->authorize('update', [Todo::class, $project, $todo]); // Update other fields $todo->fill($request->validated()); - $todo->due_start = $request->due_start ? - strtotime(Carbon::parse($request->due_start)) : - ($todo->due_start ?: null); + $dueStart = $request->due_start ? strtotime(Carbon::parse($request->due_start)) : null; + $dueEnd = $request->due_end ? strtotime(Carbon::parse($request->due_end)) : null; - $todo->due_end = $request->due_end ? - strtotime(Carbon::parse($request->due_end)) : - ($todo->due_end ?: - ($todo->due_start ? strtotime(Carbon::parse($todo->due_start)) : null)); + if ($dueEnd === null && $dueStart !== null) { + $dueEnd = strtotime(Carbon::parse($todo->due_start)); + } + $todo->due_start = $dueStart; + $todo->due_end = $dueEnd; $todo->save(); - return back() - ->with('success', 'Todo updated successfully'); + if ($request->expectsJson()) { + return response()->json([ + 'message' => 'Todo updated successfully', + 'data' => $todo, + ], 200); + } + + return back()->with('success', 'Todo updated successfully'); } + /** * Remove the specified resource from storage. */ - public function destroy($project_id, Todo $todo): RedirectResponse + public function destroy($project_id, Request $request, Todo $todo): RedirectResponse|JsonResponse { $this->authorize('delete', [Todo::class, $todo]); $todo->delete(); + if (request()->expectsJson()) { + return response()->json([ + 'message' => 'Todo deleted successfully', + ], 200); + } + return redirect()->route('project.todo.index', $project_id) ->with('success', 'Todo deleted successfully'); } diff --git a/app/Http/Resources/ProjectResource.php b/app/Http/Resources/ProjectResource.php index c61696c..b93ad66 100644 --- a/app/Http/Resources/ProjectResource.php +++ b/app/Http/Resources/ProjectResource.php @@ -16,6 +16,9 @@ class ProjectResource extends ResourceCollection { return [ 'data' => $this->collection, + 'links' => [ + 'self' => 'link-value', + ], ]; } } diff --git a/app/Http/Resources/TodoResource.php b/app/Http/Resources/TodoResource.php new file mode 100644 index 0000000..9739010 --- /dev/null +++ b/app/Http/Resources/TodoResource.php @@ -0,0 +1,24 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'data' => $this->collection, + 'links' => [ + 'self' => 'link-value', + ], + ]; + } +} diff --git a/app/Policies/ProjectPolicy.php b/app/Policies/ProjectPolicy.php index fd2a527..499c77d 100644 --- a/app/Policies/ProjectPolicy.php +++ b/app/Policies/ProjectPolicy.php @@ -13,7 +13,7 @@ class ProjectPolicy */ public function viewAny(User $user): bool { - // + return true; } /** diff --git a/app/Policies/TodoPolicy.php b/app/Policies/TodoPolicy.php index df133d4..ac18f54 100644 --- a/app/Policies/TodoPolicy.php +++ b/app/Policies/TodoPolicy.php @@ -14,7 +14,7 @@ class TodoPolicy */ public function viewAny(User $user): bool { - return false; + return true; } /** diff --git a/config/sanctum.php b/config/sanctum.php index 529cfdc..da6e738 100644 --- a/config/sanctum.php +++ b/config/sanctum.php @@ -46,7 +46,7 @@ return [ | */ - 'expiration' => null, + 'expiration' => 525600, /* |-------------------------------------------------------------------------- diff --git a/resources/views/project/load-projects.blade.php b/resources/views/project/load-projects.blade.php index d8d2e30..adff529 100644 --- a/resources/views/project/load-projects.blade.php +++ b/resources/views/project/load-projects.blade.php @@ -1,6 +1,7 @@ @foreach($projects as $project)
{{ $timeRemaining }} ago
@endif @endif + + + @if ($todo->completed_at) + ++ Completed {{ \Carbon\Carbon::parse($todo->completed_at)->diffForHumans() }} +