224 lines
6.5 KiB
PHP
224 lines
6.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Tenant;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\Tenant\EventStoreRequest;
|
|
use Illuminate\Support\Str;
|
|
use App\Http\Resources\Tenant\EventResource;
|
|
use App\Models\Event;
|
|
use App\Models\Tenant;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Support\Facades\Gate;
|
|
use Illuminate\Validation\ValidationException;
|
|
|
|
class EventController extends Controller
|
|
{
|
|
/**
|
|
* Display a listing of the tenant's events.
|
|
*/
|
|
public function index(Request $request): AnonymousResourceCollection
|
|
{
|
|
$tenantId = $request->attributes->get('tenant_id');
|
|
|
|
if (!$tenantId) {
|
|
throw ValidationException::withMessages([
|
|
'tenant_id' => 'Tenant ID not found in request context.',
|
|
]);
|
|
}
|
|
|
|
$query = Event::where('tenant_id', $tenantId)
|
|
->with(['eventType', 'photos'])
|
|
->orderBy('created_at', 'desc');
|
|
|
|
// Apply filters
|
|
if ($request->has('status')) {
|
|
$query->where('status', $request->status);
|
|
}
|
|
|
|
if ($request->has('type_id')) {
|
|
$query->where('event_type_id', $request->type_id);
|
|
}
|
|
|
|
// Pagination
|
|
$perPage = $request->get('per_page', 15);
|
|
$events = $query->paginate($perPage);
|
|
|
|
return EventResource::collection($events);
|
|
}
|
|
|
|
/**
|
|
* Store a newly created event in storage.
|
|
*/
|
|
public function store(EventStoreRequest $request): JsonResponse
|
|
{
|
|
$tenantId = $request->attributes->get('tenant_id');
|
|
|
|
// Check credits balance
|
|
$tenant = Tenant::findOrFail($tenantId);
|
|
if ($tenant->event_credits_balance <= 0) {
|
|
return response()->json([
|
|
'error' => 'Insufficient event credits. Please purchase more credits.',
|
|
], 402);
|
|
}
|
|
|
|
$validated = $request->validated();
|
|
|
|
$event = Event::create(array_merge($validated, [
|
|
'tenant_id' => $tenantId,
|
|
'status' => 'draft', // Default status
|
|
'slug' => $this->generateUniqueSlug($validated['name'], $tenantId),
|
|
]));
|
|
|
|
// Decrement credits
|
|
$tenant->decrement('event_credits_balance', 1);
|
|
|
|
$event->load(['eventType', 'tenant']);
|
|
|
|
return response()->json([
|
|
'message' => 'Event created successfully',
|
|
'data' => new EventResource($event),
|
|
], 201);
|
|
}
|
|
|
|
/**
|
|
* Display the specified event.
|
|
*/
|
|
public function show(Request $request, Event $event): JsonResponse
|
|
{
|
|
$tenantId = $request->attributes->get('tenant_id');
|
|
|
|
// Ensure event belongs to tenant
|
|
if ($event->tenant_id !== $tenantId) {
|
|
return response()->json(['error' => 'Event not found'], 404);
|
|
}
|
|
|
|
$event->load([
|
|
'eventType',
|
|
'photos' => fn ($query) => $query->with('likes')->latest(),
|
|
'tasks',
|
|
'tenant' => fn ($query) => $query->select('id', 'name', 'event_credits_balance')
|
|
]);
|
|
|
|
return response()->json([
|
|
'data' => new EventResource($event),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Update the specified event in storage.
|
|
*/
|
|
public function update(EventStoreRequest $request, Event $event): JsonResponse
|
|
{
|
|
$tenantId = $request->attributes->get('tenant_id');
|
|
|
|
// Ensure event belongs to tenant
|
|
if ($event->tenant_id !== $tenantId) {
|
|
return response()->json(['error' => 'Event not found'], 404);
|
|
}
|
|
|
|
$validated = $request->validated();
|
|
|
|
// Update slug if name changed
|
|
if ($validated['name'] !== $event->name) {
|
|
$validated['slug'] = $this->generateUniqueSlug($validated['name'], $tenantId, $event->id);
|
|
}
|
|
|
|
$event->update($validated);
|
|
|
|
$event->load(['eventType', 'tenant']);
|
|
|
|
return response()->json([
|
|
'message' => 'Event updated successfully',
|
|
'data' => new EventResource($event),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Remove the specified event from storage.
|
|
*/
|
|
public function destroy(Request $request, Event $event): JsonResponse
|
|
{
|
|
$tenantId = $request->attributes->get('tenant_id');
|
|
|
|
// Ensure event belongs to tenant
|
|
if ($event->tenant_id !== $tenantId) {
|
|
return response()->json(['error' => 'Event not found'], 404);
|
|
}
|
|
|
|
// Soft delete
|
|
$event->delete();
|
|
|
|
return response()->json([
|
|
'message' => 'Event deleted successfully',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Bulk update event status (publish/unpublish)
|
|
*/
|
|
public function bulkUpdateStatus(Request $request): JsonResponse
|
|
{
|
|
$tenantId = $request->attributes->get('tenant_id');
|
|
$validated = $request->validate([
|
|
'event_ids' => 'required|array',
|
|
'event_ids.*' => 'exists:events,id',
|
|
'status' => 'required|in:draft,published,archived',
|
|
]);
|
|
|
|
$updatedCount = Event::whereIn('id', $validated['event_ids'])
|
|
->where('tenant_id', $tenantId)
|
|
->update(['status' => $validated['status']]);
|
|
|
|
return response()->json([
|
|
'message' => "{$updatedCount} events updated successfully",
|
|
'updated_count' => $updatedCount,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Generate unique slug for event name
|
|
*/
|
|
private function generateUniqueSlug(string $name, int $tenantId, ?int $excludeId = null): string
|
|
{
|
|
$slug = Str::slug($name);
|
|
$originalSlug = $slug;
|
|
|
|
$counter = 1;
|
|
while (Event::where('slug', $slug)
|
|
->where('tenant_id', $tenantId)
|
|
->where('id', '!=', $excludeId)
|
|
->exists()) {
|
|
$slug = $originalSlug . '-' . $counter;
|
|
$counter++;
|
|
}
|
|
|
|
return $slug;
|
|
}
|
|
|
|
/**
|
|
* Search events by name or description
|
|
*/
|
|
public function search(Request $request): AnonymousResourceCollection
|
|
{
|
|
$tenantId = $request->attributes->get('tenant_id');
|
|
$query = $request->get('q', '');
|
|
|
|
if (strlen($query) < 2) {
|
|
return EventResource::collection(collect([]));
|
|
}
|
|
|
|
$events = Event::where('tenant_id', $tenantId)
|
|
->where(function ($q) use ($query) {
|
|
$q->where('name', 'like', "%{$query}%")
|
|
->orWhere('description', 'like', "%{$query}%");
|
|
})
|
|
->with('eventType')
|
|
->limit(10)
|
|
->get();
|
|
|
|
return EventResource::collection($events);
|
|
}
|
|
} |