250 lines
7.7 KiB
PHP
250 lines
7.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\User;
|
|
use App\Models\Video;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
|
|
class SuperAdminController extends Controller
|
|
{
|
|
public function __construct()
|
|
{
|
|
$this->middleware('super_admin');
|
|
}
|
|
|
|
// Dashboard - Overview statistics
|
|
public function dashboard()
|
|
{
|
|
$stats = [
|
|
'total_users' => User::count(),
|
|
'total_videos' => Video::count(),
|
|
'total_views' => \DB::table('video_views')->count('id'),
|
|
'total_likes' => \DB::table('video_likes')->count('id'),
|
|
];
|
|
|
|
// Recent users
|
|
$recentUsers = User::latest()->take(5)->get();
|
|
|
|
// Recent videos
|
|
$recentVideos = Video::with('user')->latest()->take(5)->get();
|
|
|
|
// Videos by status
|
|
$videosByStatus = Video::select('status', \DB::raw('count(*) as count'))
|
|
->groupBy('status')
|
|
->pluck('count', 'status');
|
|
|
|
// Videos by visibility
|
|
$videosByVisibility = Video::select('visibility', \DB::raw('count(*) as count'))
|
|
->groupBy('visibility')
|
|
->pluck('count', 'visibility');
|
|
|
|
return view('admin.dashboard', compact('stats', 'recentUsers', 'recentVideos', 'videosByStatus', 'videosByVisibility'));
|
|
}
|
|
|
|
// List all users with search/filter
|
|
public function users(Request $request)
|
|
{
|
|
$query = User::query();
|
|
|
|
// Search by name or email
|
|
if ($request->has('search') && $request->search) {
|
|
$search = $request->search;
|
|
$query->where(function ($q) use ($search) {
|
|
$q->where('name', 'like', "%{$search}%")
|
|
->orWhere('email', 'like', "%{$search}%");
|
|
});
|
|
}
|
|
|
|
// Filter by role
|
|
if ($request->has('role') && $request->role) {
|
|
$query->where('role', $request->role);
|
|
}
|
|
|
|
// Sort by
|
|
$sort = $request->get('sort', 'latest');
|
|
switch ($sort) {
|
|
case 'oldest':
|
|
$query->oldest();
|
|
break;
|
|
case 'name_asc':
|
|
$query->orderBy('name', 'asc');
|
|
break;
|
|
case 'name_desc':
|
|
$query->orderBy('name', 'desc');
|
|
break;
|
|
default:
|
|
$query->latest();
|
|
}
|
|
|
|
$users = $query->paginate(20);
|
|
$users->appends($request->query());
|
|
|
|
return view('admin.users', compact('users'));
|
|
}
|
|
|
|
// Show edit user form
|
|
public function editUser(User $user)
|
|
{
|
|
return view('admin.edit-user', compact('user'));
|
|
}
|
|
|
|
// Update user
|
|
public function updateUser(Request $request, User $user)
|
|
{
|
|
$request->validate([
|
|
'name' => 'required|string|max:255',
|
|
'email' => 'required|email|max:255|unique:users,email,' . $user->id,
|
|
'role' => 'required|in:user,admin,super_admin',
|
|
'new_password' => 'nullable|min:8|confirmed',
|
|
]);
|
|
|
|
$data = [
|
|
'name' => $request->name,
|
|
'email' => $request->email,
|
|
'role' => $request->role,
|
|
];
|
|
|
|
// Update password if provided
|
|
if ($request->new_password) {
|
|
$data['password'] = Hash::make($request->new_password);
|
|
}
|
|
|
|
$user->update($data);
|
|
|
|
return redirect()->route('admin.users')->with('success', 'User updated successfully!');
|
|
}
|
|
|
|
// Delete user
|
|
public function deleteUser(User $user)
|
|
{
|
|
// Prevent deleting yourself
|
|
if (auth()->id() === $user->id) {
|
|
return back()->with('error', 'You cannot delete your own account!');
|
|
}
|
|
|
|
// Delete user's videos and associated files
|
|
foreach ($user->videos as $video) {
|
|
Storage::delete('public/videos/' . $video->filename);
|
|
if ($video->thumbnail) {
|
|
Storage::delete('public/thumbnails/' . $video->thumbnail);
|
|
}
|
|
}
|
|
$user->videos()->delete();
|
|
|
|
// Delete user likes and views - use direct query since relationship is named 'viewers'
|
|
\DB::table('video_likes')->where('user_id', $user->id)->delete();
|
|
\DB::table('video_views')->where('user_id', $user->id)->delete();
|
|
|
|
$user->delete();
|
|
|
|
return redirect()->route('admin.users')->with('success', 'User deleted successfully!');
|
|
}
|
|
|
|
// List all videos
|
|
public function videos(Request $request)
|
|
{
|
|
$query = Video::with('user');
|
|
|
|
// Search by title or description
|
|
if ($request->has('search') && $request->search) {
|
|
$search = $request->search;
|
|
$query->where(function ($q) use ($search) {
|
|
$q->where('title', 'like', "%{$search}%")
|
|
->orWhere('description', 'like', "%{$search}%");
|
|
});
|
|
}
|
|
|
|
// Filter by status
|
|
if ($request->has('status') && $request->status) {
|
|
$query->where('status', $request->status);
|
|
}
|
|
|
|
// Filter by visibility
|
|
if ($request->has('visibility') && $request->visibility) {
|
|
$query->where('visibility', $request->visibility);
|
|
}
|
|
|
|
// Filter by type
|
|
if ($request->has('type') && $request->type) {
|
|
$query->where('type', $request->type);
|
|
}
|
|
|
|
// Sort by
|
|
$sort = $request->get('sort', 'latest');
|
|
switch ($sort) {
|
|
case 'oldest':
|
|
$query->oldest();
|
|
break;
|
|
case 'title_asc':
|
|
$query->orderBy('title', 'asc');
|
|
break;
|
|
case 'title_desc':
|
|
$query->orderBy('title', 'desc');
|
|
break;
|
|
case 'views':
|
|
// Can't use withCount for views due to pivot table issue
|
|
$query->latest();
|
|
break;
|
|
case 'likes':
|
|
$query->withCount('likes')->orderBy('likes_count', 'desc');
|
|
break;
|
|
default:
|
|
$query->latest();
|
|
}
|
|
|
|
$videos = $query->paginate(20);
|
|
$videos->appends($request->query());
|
|
|
|
return view('admin.videos', compact('videos'));
|
|
}
|
|
|
|
// Show edit video form
|
|
public function editVideo(Video $video)
|
|
{
|
|
return view('admin.edit-video', compact('video'));
|
|
}
|
|
|
|
// Update video
|
|
public function updateVideo(Request $request, Video $video)
|
|
{
|
|
$request->validate([
|
|
'title' => 'required|string|max:255',
|
|
'description' => 'nullable|string',
|
|
'visibility' => 'required|in:public,unlisted,private',
|
|
'type' => 'required|in:generic,music,match',
|
|
'status' => 'required|in:pending,processing,ready,failed',
|
|
'is_shorts' => 'nullable|boolean',
|
|
]);
|
|
|
|
$data = $request->only(['title', 'description', 'visibility', 'type', 'status', 'is_shorts']);
|
|
|
|
$video->update($data);
|
|
|
|
return redirect()->route('admin.videos')->with('success', 'Video updated successfully!');
|
|
}
|
|
|
|
// Delete video
|
|
public function deleteVideo(Video $video)
|
|
{
|
|
$videoTitle = $video->title;
|
|
|
|
// Delete files
|
|
Storage::delete('public/videos/' . $video->filename);
|
|
if ($video->thumbnail) {
|
|
Storage::delete('public/thumbnails/' . $video->thumbnail);
|
|
}
|
|
|
|
// Delete likes and views - use direct queries since relationships have timestamp issues
|
|
\DB::table('video_likes')->where('video_id', $video->id)->delete();
|
|
\DB::table('video_views')->where('video_id', $video->id)->delete();
|
|
|
|
$video->delete();
|
|
|
|
return redirect()->route('admin.videos')->with('success', 'Video "' . $videoTitle . '" deleted successfully!');
|
|
}
|
|
}
|