396 lines
12 KiB
PHP
396 lines
12 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\MobileTask;
|
|
use App\Models\MobileSubtask;
|
|
use App\Models\MobileTaskPin;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class TaskApiController extends Controller
|
|
{
|
|
public function index(Request $request)
|
|
{
|
|
$user = $request->user();
|
|
|
|
$query = MobileTask::with(['assignee', 'creator', 'subtasks', 'pins']);
|
|
|
|
if ($request->has('status') && $request->status !== 'all') {
|
|
$query->where('status', $request->status);
|
|
}
|
|
|
|
if ($request->has('project_id')) {
|
|
$query->where('project_id', $request->project_id);
|
|
}
|
|
|
|
if ($request->has('assigned_to_me') && $request->assigned_to_me === 'true') {
|
|
$query->where('assignee_id', $user->id);
|
|
}
|
|
|
|
$tasks = $query->latest()->get()->map(function ($task) use ($user) {
|
|
$isPinned = $task->pins->contains('user_id', $user->id);
|
|
return [
|
|
'id' => $task->id,
|
|
'title' => $task->title,
|
|
'description' => $task->description,
|
|
'status' => $task->status,
|
|
'priority' => $task->priority,
|
|
'due_date' => $task->due_date ? $task->due_date->format('Y-m-d') : null,
|
|
'assignee_id' => $task->assignee_id,
|
|
'assignee_name' => $task->assignee ? $task->assignee->name : 'Unassigned',
|
|
'assignee_avatar' => $task->assignee && !empty($task->assignee->avatar) ? (check_file($task->assignee->avatar) ? get_file($task->assignee->avatar) : $task->assignee->avatar) : null,
|
|
'project_id' => $task->project_id,
|
|
'is_pinned' => $isPinned,
|
|
'subtasks_count' => $task->subtasks->count(),
|
|
'completed_subtasks_count' => $task->subtasks->where('is_completed', true)->count(),
|
|
'subtasks' => $task->subtasks->map(fn($s) => [
|
|
'id' => $s->id,
|
|
'title' => $s->title,
|
|
'is_completed' => (bool)$s->is_completed,
|
|
]),
|
|
'created_at' => $task->created_at->toIso8601String(),
|
|
];
|
|
});
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $tasks,
|
|
'message' => null,
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$request->validate([
|
|
'title' => 'required|string|max:255',
|
|
'description' => 'nullable|string',
|
|
'priority' => 'nullable|string|in:low,medium,high,urgent',
|
|
'due_date' => 'nullable|date',
|
|
'assignee_id' => 'nullable|exists:users,id',
|
|
'project_id' => 'nullable|exists:projects,id',
|
|
]);
|
|
|
|
$user = $request->user();
|
|
|
|
$task = MobileTask::create([
|
|
'title' => $request->title,
|
|
'description' => $request->description,
|
|
'priority' => $request->priority ?? 'medium',
|
|
'due_date' => $request->due_date,
|
|
'assignee_id' => $request->assignee_id ?? $user->id,
|
|
'project_id' => $request->project_id,
|
|
'created_by' => $user->id,
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $task->load(['assignee', 'subtasks']),
|
|
'message' => 'Task created successfully',
|
|
'errors' => null,
|
|
], 201);
|
|
}
|
|
|
|
public function show(Request $request, $id)
|
|
{
|
|
$user = $request->user();
|
|
$task = MobileTask::with(['assignee', 'creator', 'subtasks', 'pins'])->find($id);
|
|
|
|
if (!$task) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'data' => null,
|
|
'message' => 'Task not found',
|
|
'errors' => null,
|
|
], 404);
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => [
|
|
'id' => $task->id,
|
|
'title' => $task->title,
|
|
'description' => $task->description,
|
|
'status' => $task->status,
|
|
'priority' => $task->priority,
|
|
'due_date' => $task->due_date ? $task->due_date->format('Y-m-d') : null,
|
|
'assignee_id' => $task->assignee_id,
|
|
'assignee_name' => $task->assignee ? $task->assignee->name : 'Unassigned',
|
|
'project_id' => $task->project_id,
|
|
'is_pinned' => $task->pins->contains('user_id', $user->id),
|
|
'subtasks' => $task->subtasks->map(fn($s) => [
|
|
'id' => $s->id,
|
|
'title' => $s->title,
|
|
'is_completed' => (bool)$s->is_completed,
|
|
]),
|
|
],
|
|
'message' => null,
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function update(Request $request, $id)
|
|
{
|
|
$task = MobileTask::find($id);
|
|
if (!$task) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'data' => null,
|
|
'message' => 'Task not found',
|
|
'errors' => null,
|
|
], 404);
|
|
}
|
|
|
|
$task->update($request->only([
|
|
'title',
|
|
'description',
|
|
'status',
|
|
'priority',
|
|
'due_date',
|
|
'assignee_id',
|
|
'project_id',
|
|
]));
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $task->fresh(['assignee', 'subtasks']),
|
|
'message' => 'Task updated successfully',
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function destroy(Request $request, $id)
|
|
{
|
|
$task = MobileTask::find($id);
|
|
if (!$task) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'data' => null,
|
|
'message' => 'Task not found',
|
|
'errors' => null,
|
|
], 404);
|
|
}
|
|
|
|
$task->delete();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => null,
|
|
'message' => 'Task deleted successfully',
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function claim(Request $request, $id)
|
|
{
|
|
$user = $request->user();
|
|
$task = MobileTask::find($id);
|
|
|
|
if (!$task) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'data' => null,
|
|
'message' => 'Task not found',
|
|
'errors' => null,
|
|
], 404);
|
|
}
|
|
|
|
$task->update(['assignee_id' => $user->id]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $task->fresh(['assignee']),
|
|
'message' => 'Task claimed successfully',
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function pin(Request $request, $id)
|
|
{
|
|
$user = $request->user();
|
|
$task = MobileTask::find($id);
|
|
|
|
if (!$task) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'data' => null,
|
|
'message' => 'Task not found',
|
|
'errors' => null,
|
|
], 404);
|
|
}
|
|
|
|
$existing = MobileTaskPin::where('user_id', $user->id)->where('task_id', $id)->first();
|
|
if ($existing) {
|
|
$existing->delete();
|
|
$isPinned = false;
|
|
} else {
|
|
MobileTaskPin::create(['user_id' => $user->id, 'task_id' => $id]);
|
|
$isPinned = true;
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => ['is_pinned' => $isPinned],
|
|
'message' => $isPinned ? 'Task pinned' : 'Task unpinned',
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function status(Request $request, $id)
|
|
{
|
|
$request->validate([
|
|
'status' => 'required|string|in:todo,in_progress,done,archived',
|
|
]);
|
|
|
|
$task = MobileTask::find($id);
|
|
if (!$task) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'data' => null,
|
|
'message' => 'Task not found',
|
|
'errors' => null,
|
|
], 404);
|
|
}
|
|
|
|
$task->update(['status' => $request->status]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $task,
|
|
'message' => 'Task status updated',
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function addSubtask(Request $request, $id)
|
|
{
|
|
$request->validate([
|
|
'title' => 'required|string|max:255',
|
|
]);
|
|
|
|
$task = MobileTask::find($id);
|
|
if (!$task) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'data' => null,
|
|
'message' => 'Task not found',
|
|
'errors' => null,
|
|
], 404);
|
|
}
|
|
|
|
$subtask = MobileSubtask::create([
|
|
'task_id' => $task->id,
|
|
'title' => $request->title,
|
|
'is_completed' => false,
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $subtask,
|
|
'message' => 'Subtask added successfully',
|
|
'errors' => null,
|
|
], 201);
|
|
}
|
|
|
|
public function toggleSubtask(Request $request, $taskId, $subtaskId)
|
|
{
|
|
$subtask = MobileSubtask::where('task_id', $taskId)->where('id', $subtaskId)->first();
|
|
if (!$subtask) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'data' => null,
|
|
'message' => 'Subtask not found',
|
|
'errors' => null,
|
|
], 404);
|
|
}
|
|
|
|
$subtask->update(['is_completed' => !$subtask->is_completed]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $subtask,
|
|
'message' => 'Subtask toggled successfully',
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function toggleSubtaskDirect(Request $request, $id)
|
|
{
|
|
$subtask = MobileSubtask::find($id);
|
|
if (!$subtask) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'data' => null,
|
|
'message' => 'Subtask not found',
|
|
'errors' => null,
|
|
], 404);
|
|
}
|
|
|
|
$subtask->update(['is_completed' => !$subtask->is_completed]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $subtask,
|
|
'message' => 'Subtask toggled successfully',
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function unassignedTasks(Request $request, $projectId)
|
|
{
|
|
$tasks = MobileTask::where('project_id', $projectId)
|
|
->whereNull('assignee_id')
|
|
->latest()
|
|
->get();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $tasks,
|
|
'message' => null,
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function files(Request $request, $id)
|
|
{
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => [],
|
|
'message' => null,
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function archive(Request $request, $id)
|
|
{
|
|
$task = MobileTask::find($id);
|
|
if ($task) {
|
|
$task->update(['status' => 'archived']);
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $task,
|
|
'message' => 'Task archived successfully',
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function destroySubtask(Request $request, $id)
|
|
{
|
|
$subtask = MobileSubtask::find($id);
|
|
if ($subtask) {
|
|
$subtask->delete();
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => null,
|
|
'message' => 'Subtask deleted successfully',
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
}
|