126 lines
4.1 KiB
PHP
126 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Tenant;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\Tenant\NotificationMarkRequest;
|
|
use App\Models\TenantNotificationLog;
|
|
use App\Models\TenantNotificationReceipt;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class NotificationLogController extends Controller
|
|
{
|
|
public function index(Request $request): JsonResponse
|
|
{
|
|
$tenant = $request->attributes->get('tenant') ?? $request->user()?->tenant;
|
|
|
|
if (! $tenant) {
|
|
return response()->json([
|
|
'error' => [
|
|
'code' => 'tenant_context_missing',
|
|
'title' => 'Tenant context missing',
|
|
'message' => 'Unable to resolve tenant for notification logs.',
|
|
],
|
|
], 403);
|
|
}
|
|
|
|
$user = $request->user();
|
|
|
|
$query = TenantNotificationLog::query()
|
|
->where('tenant_id', $tenant->id)
|
|
->with('receipts')
|
|
->latest();
|
|
|
|
if ($type = $request->query('type')) {
|
|
$query->where('type', $type);
|
|
}
|
|
|
|
if ($status = $request->query('status')) {
|
|
$query->where('status', $status);
|
|
}
|
|
|
|
if ($scope = $request->query('scope')) {
|
|
$query->where(function (Builder $inner) use ($scope) {
|
|
$inner->where('type', $scope)
|
|
->orWhere(function (Builder $ctx) use ($scope) {
|
|
$ctx->whereJsonContains('context->scope', $scope);
|
|
});
|
|
});
|
|
}
|
|
|
|
if ($eventId = $request->query('event_id')) {
|
|
$query->where(function (Builder $inner) use ($eventId) {
|
|
$inner->where('context->event_id', (int) $eventId)
|
|
->orWhere('context->eventId', (int) $eventId);
|
|
});
|
|
}
|
|
|
|
$perPage = (int) $request->query('per_page', 20);
|
|
$perPage = max(1, min($perPage, 100));
|
|
|
|
$logs = $query->paginate($perPage);
|
|
|
|
$receipts = collect($logs->items())
|
|
->map(fn ($log) => $log->receipts ?? collect())
|
|
->flatten();
|
|
|
|
$unreadCount = $receipts
|
|
->filter(fn ($receipt) => $user && $receipt->user_id === $user->id && $receipt->status !== 'read')
|
|
->count();
|
|
|
|
$data = collect($logs->items())->map(function (TenantNotificationLog $log) use ($user) {
|
|
$receipt = $user
|
|
? $log->receipts->firstWhere('user_id', $user->id)
|
|
: null;
|
|
|
|
return array_merge($log->toArray(), [
|
|
'is_read' => $receipt ? $receipt->status === 'read' : false,
|
|
]);
|
|
})->all();
|
|
|
|
return response()->json([
|
|
'data' => $data,
|
|
'meta' => [
|
|
'current_page' => $logs->currentPage(),
|
|
'last_page' => $logs->lastPage(),
|
|
'per_page' => $logs->perPage(),
|
|
'total' => $logs->total(),
|
|
'unread_count' => $unreadCount,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function mark(NotificationMarkRequest $request): JsonResponse
|
|
{
|
|
$tenant = $request->attributes->get('tenant') ?? $request->user()?->tenant;
|
|
|
|
if (! $tenant) {
|
|
return response()->json([
|
|
'error' => [
|
|
'code' => 'tenant_context_missing',
|
|
'title' => 'Tenant context missing',
|
|
'message' => 'Unable to resolve tenant for notification logs.',
|
|
],
|
|
], 403);
|
|
}
|
|
|
|
$userId = $request->user()?->id;
|
|
$status = $request->validated('status');
|
|
$ids = $request->validated('ids');
|
|
|
|
TenantNotificationReceipt::query()
|
|
->where('tenant_id', $tenant->id)
|
|
->whereIn('notification_log_id', $ids)
|
|
->when($userId, fn ($q) => $q->where(function ($inner) use ($userId) {
|
|
$inner->whereNull('user_id')->orWhere('user_id', $userId);
|
|
}))
|
|
->update(['status' => $status]);
|
|
|
|
return response()->json([
|
|
'message' => 'Notifications updated.',
|
|
]);
|
|
}
|
|
}
|