Files
HRM-System/app/Http/Controllers/Api/ConversationApiController.php

367 lines
12 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class ConversationApiController extends Controller
{
private function ensureUserConversation($user)
{
// Return existing conversation ID for user, or null if none created
return DB::table('mobile_conversation_participants')
->where('user_id', $user->id)
->value('conversation_id');
}
public function conversations(Request $request)
{
$user = $request->user();
$convIds = DB::table('mobile_conversation_participants')
->where('user_id', $user->id)
->pluck('conversation_id');
$typeFilter = $request->query('type');
$conversations = DB::table('mobile_conversations')
->whereIn('id', $convIds)
->when($typeFilter, function ($query, $type) {
return $query->where('type', $type);
})
->get()
->map(function ($c) use ($user) {
$lastMsg = DB::table('mobile_messages')
->where('conversation_id', $c->id)
->latest()
->first();
$unreadCount = DB::table('mobile_messages')
->where('conversation_id', $c->id)
->where('sender_id', '!=', $user->id)
->where('is_read', false)
->count();
$participantIds = DB::table('mobile_conversation_participants')
->where('conversation_id', $c->id)
->pluck('user_id');
$participants = User::whereIn('id', $participantIds)
->select('id', 'name', 'email', 'avatar', 'type')
->get()
->map(function ($u) {
$u->avatar = check_file($u->avatar) ? get_file($u->avatar) : $u->avatar;
return $u;
});
$otherUser = $participants->firstWhere('id', '!=', $user->id);
return [
'id' => $c->id,
'type' => $c->type,
'name' => $c->type === 'direct' && $otherUser ? $otherUser->name : ($c->name ?? 'Chat'),
'avatar' => $c->type === 'direct' && $otherUser ? $otherUser->avatar : null,
'last_message' => $lastMsg ? $lastMsg->content : 'No messages yet',
'last_message_at' => $lastMsg && $lastMsg->created_at ? date('h:i A', strtotime($lastMsg->created_at)) : date('h:i A'),
'unread_count' => $unreadCount,
'participants' => $participants,
];
});
return response()->json([
'success' => true,
'data' => $conversations,
'message' => null,
'errors' => null,
]);
}
public function store(Request $request)
{
$isGroup = $request->boolean('is_group') || $request->filled('name') || (is_array($request->participant_ids) && count($request->participant_ids) > 1);
if ($isGroup) {
return $this->createGroup($request);
}
return $this->createDirect($request);
}
public function createDirect(Request $request)
{
$recipientId = $request->recipient_id ?? ($request->participant_ids[0] ?? null);
if (!$recipientId) {
return response()->json([
'success' => false,
'data' => null,
'message' => 'The recipient_id or participant_ids field is required.',
'errors' => ['recipient_id' => ['Recipient required']],
], 422);
}
$user = $request->user();
$recipient = User::find($recipientId);
if (!$recipient) {
return response()->json([
'success' => false,
'data' => null,
'message' => 'Recipient user not found',
'errors' => null,
], 404);
}
$myConvs = DB::table('mobile_conversation_participants')
->where('user_id', $user->id)
->pluck('conversation_id');
$existing = DB::table('mobile_conversation_participants')
->whereIn('conversation_id', $myConvs)
->where('user_id', $recipientId)
->first();
if ($existing) {
$conv = DB::table('mobile_conversations')->where('id', $existing->conversation_id)->first();
$participants = User::whereIn('id', [$user->id, $recipientId])->select('id', 'name', 'email', 'avatar', 'type')->get();
return response()->json([
'id' => $conv->id,
'name' => $recipient->name,
'type' => 'direct',
'participants' => $participants,
'success' => true,
'data' => [
'id' => $conv->id,
'name' => $recipient->name,
'type' => 'direct',
'participants' => $participants,
],
'message' => 'Conversation existing',
'errors' => null,
]);
}
$convId = DB::table('mobile_conversations')->insertGetId([
'name' => $recipient->name,
'type' => 'direct',
'created_by' => $user->id,
'created_at' => now(),
'updated_at' => now(),
]);
DB::table('mobile_conversation_participants')->insert([
['conversation_id' => $convId, 'user_id' => $user->id, 'created_at' => now(), 'updated_at' => now()],
['conversation_id' => $convId, 'user_id' => $recipientId, 'created_at' => now(), 'updated_at' => now()],
]);
$participants = User::whereIn('id', [$user->id, $recipientId])->select('id', 'name', 'email', 'avatar', 'type')->get();
return response()->json([
'id' => $convId,
'name' => $recipient->name,
'type' => 'direct',
'participants' => $participants,
'success' => true,
'data' => [
'id' => $convId,
'name' => $recipient->name,
'type' => 'direct',
'participants' => $participants,
],
'message' => 'Direct conversation created',
'errors' => null,
], 201);
}
public function createGroup(Request $request)
{
$request->validate([
'name' => 'nullable|string|max:255',
'participant_ids' => 'required|array',
'participant_ids.*' => 'integer|exists:users,id',
]);
$user = $request->user();
$groupName = $request->name ?? 'New Team Group';
$convId = DB::table('mobile_conversations')->insertGetId([
'name' => $groupName,
'type' => 'group',
'created_by' => $user->id,
'created_at' => now(),
'updated_at' => now(),
]);
$participants = array_unique(array_merge([$user->id], $request->participant_ids));
foreach ($participants as $pId) {
DB::table('mobile_conversation_participants')->insert([
'conversation_id' => $convId,
'user_id' => $pId,
'created_at' => now(),
'updated_at' => now(),
]);
}
$participantUsers = User::whereIn('id', $participants)->select('id', 'name', 'email', 'avatar', 'type')->get();
return response()->json([
'id' => $convId,
'name' => $groupName,
'type' => 'group',
'participants' => $participantUsers,
'success' => true,
'data' => [
'id' => $convId,
'name' => $groupName,
'type' => 'group',
'participant_count' => count($participants),
'participants' => $participantUsers,
],
'message' => 'Group conversation created',
'errors' => null,
], 201);
}
public function messages(Request $request, $id)
{
$user = $request->user();
$isParticipant = DB::table('mobile_conversation_participants')
->where('conversation_id', $id)
->where('user_id', $user->id)
->exists();
if (!$isParticipant) {
return response()->json([
'success' => false,
'data' => [],
'message' => 'Unauthorized access to this conversation',
'errors' => null,
], 403);
}
DB::table('mobile_messages')
->where('conversation_id', $id)
->where('sender_id', '!=', $user->id)
->update(['is_read' => true]);
$messages = DB::table('mobile_messages')
->where('conversation_id', $id)
->orderBy('created_at', 'asc')
->get()
->map(function ($m) {
$sender = User::find($m->sender_id);
if ($sender && !empty($sender->avatar)) {
$sender->avatar = get_file($sender->avatar);
}
return [
'id' => $m->id,
'conversation_id' => (int)$m->conversation_id,
'sender_id' => $m->sender_id,
'sender_name' => $sender ? $sender->name : 'User',
'sender' => $sender ? [
'id' => $sender->id,
'name' => $sender->name,
'avatar' => $sender->avatar,
] : null,
'content' => $m->content,
'created_at' => date('M d, h:i A', strtotime($m->created_at)),
];
});
return response()->json([
'success' => true,
'data' => $messages,
'message' => null,
'errors' => null,
]);
}
public function sendMessage(Request $request, $id)
{
$request->validate([
'content' => 'required|string',
]);
$user = $request->user();
$isParticipant = DB::table('mobile_conversation_participants')
->where('conversation_id', $id)
->where('user_id', $user->id)
->exists();
if (!$isParticipant) {
return response()->json([
'success' => false,
'data' => null,
'message' => 'Unauthorized access to this conversation',
'errors' => null,
], 403);
}
$messageId = DB::table('mobile_messages')->insertGetId([
'conversation_id' => $id,
'sender_id' => $user->id,
'content' => $request->content,
'is_read' => false,
'created_at' => now(),
'updated_at' => now(),
]);
return response()->json([
'success' => true,
'message' => 'Message sent',
'data' => [
'id' => $messageId,
'conversation_id' => (int)$id,
'sender_id' => $user->id,
'sender_name' => $user->name,
'content' => $request->content,
'created_at' => date('M d, h:i A'),
],
'errors' => null,
], 201);
}
public function unreadCount(Request $request)
{
$user = $request->user();
$convIds = DB::table('mobile_conversation_participants')
->where('user_id', $user->id)
->pluck('conversation_id');
$unreadCount = DB::table('mobile_messages')
->whereIn('conversation_id', $convIds)
->where('sender_id', '!=', $user->id)
->where('is_read', false)
->count();
return response()->json([
'success' => true,
'unread_count' => $unreadCount,
'data' => ['unread_count' => $unreadCount],
'message' => null,
'errors' => null,
]);
}
public function users(Request $request)
{
$users = User::where('id', '!=', $request->user()->id)
->select('id', 'name', 'email', 'type', 'avatar')
->limit(20)
->get();
return response()->json([
'success' => true,
'data' => $users,
'message' => null,
'errors' => null,
]);
}
}