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); } }