Initial commit: Animexe Laravel platform
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Frontend;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\AnimeSwipe;
|
||||
use App\Models\Comment;
|
||||
use App\Models\Watchlist;
|
||||
use App\Models\ContinueWatching;
|
||||
use App\Models\UserAchievement;
|
||||
use App\Models\EpisodeNote;
|
||||
use App\Services\AchievementService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
public function show()
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
$recentComments = Comment::where('user_id', $user->id)
|
||||
->where('status', 'approved')
|
||||
->orderByDesc('created_at')
|
||||
->limit(10)
|
||||
->get();
|
||||
|
||||
$commentCount = Comment::where('user_id', $user->id)
|
||||
->where('status', 'approved')
|
||||
->count();
|
||||
|
||||
// İzleme listesi (status gruplu)
|
||||
$watchlistItems = Watchlist::where('user_id', $user->id)
|
||||
->with('anime:id,title,slug,cover_image,type,rating')
|
||||
->orderByDesc('created_at')
|
||||
->get()
|
||||
->filter(fn($wl) => $wl->anime !== null)
|
||||
->groupBy('status');
|
||||
|
||||
// Devam et listesi
|
||||
$continueItems = ContinueWatching::where('user_id', $user->id)
|
||||
->with('anime:id,title,slug,cover_image')
|
||||
->where('percent_complete', '<', 95)
|
||||
->orderByDesc('updated_at')
|
||||
->limit(12)
|
||||
->get();
|
||||
|
||||
// İzleme istatistikleri
|
||||
$watchStats = [
|
||||
'episodes' => ContinueWatching::where('user_id', $user->id)->where('percent_complete', '>=', 70)->count(),
|
||||
'hours' => round(ContinueWatching::where('user_id', $user->id)->sum('seconds_watched') / 3600, 1),
|
||||
'watchlist'=> Watchlist::where('user_id', $user->id)->count(),
|
||||
'ratings' => DB::table('anime_ratings')->where('user_id', $user->id)->count(),
|
||||
];
|
||||
|
||||
// Başarımlar
|
||||
AchievementService::check($user); // yeni kazanılanları kontrol et
|
||||
$achievements = UserAchievement::where('user_id', $user->id)
|
||||
->with('achievement')
|
||||
->orderByDesc('earned_at')
|
||||
->get();
|
||||
|
||||
$allAchievements = \App\Models\Achievement::all();
|
||||
|
||||
// İzleme Heatmap (son 365 gün)
|
||||
$heatmapRaw = DB::table('analytics_watch_events')
|
||||
->where('user_id', $user->id)
|
||||
->where('created_at', '>=', now()->subDays(365))
|
||||
->selectRaw('DATE(created_at) as d, COUNT(DISTINCT episode_id) as cnt')
|
||||
->groupBy('d')
|
||||
->pluck('cnt', 'd')
|
||||
->toArray();
|
||||
|
||||
// Bölüm notları (son 20)
|
||||
$episodeNotes = EpisodeNote::where('user_id', $user->id)
|
||||
->with('episode:id,title,episode_number,anime_id', 'anime:id,title,slug')
|
||||
->orderByDesc('created_at')
|
||||
->limit(20)
|
||||
->get();
|
||||
|
||||
// Keşfet geçmişi (beğenilenler + geçilenler)
|
||||
$swipeHistory = AnimeSwipe::where('user_id', $user->id)
|
||||
->with('anime:id,title,slug,cover_image,rating,release_year,type')
|
||||
->orderByDesc('created_at')
|
||||
->limit(60)
|
||||
->get()
|
||||
->filter(fn($s) => $s->anime !== null);
|
||||
|
||||
return view('frontend.profile', compact(
|
||||
'user', 'recentComments', 'commentCount',
|
||||
'watchlistItems', 'continueItems', 'watchStats',
|
||||
'achievements', 'allAchievements',
|
||||
'heatmapRaw', 'episodeNotes', 'swipeHistory'
|
||||
));
|
||||
}
|
||||
|
||||
public function publicProfile(\App\Models\User $user)
|
||||
{
|
||||
$commentCount = Comment::where('user_id', $user->id)->where('status', 'approved')->count();
|
||||
|
||||
$watchlistItems = Watchlist::where('user_id', $user->id)
|
||||
->with('anime:id,title,slug,cover_image,type,rating')
|
||||
->orderByDesc('created_at')
|
||||
->get()
|
||||
->filter(fn($wl) => $wl->anime !== null)
|
||||
->groupBy('status');
|
||||
|
||||
$watchStats = [
|
||||
'episodes' => ContinueWatching::where('user_id', $user->id)->where('percent_complete', '>=', 70)->count(),
|
||||
'hours' => round(ContinueWatching::where('user_id', $user->id)->sum('seconds_watched') / 3600, 1),
|
||||
'watchlist'=> Watchlist::where('user_id', $user->id)->count(),
|
||||
'ratings' => DB::table('anime_ratings')->where('user_id', $user->id)->count(),
|
||||
];
|
||||
|
||||
$achievements = UserAchievement::where('user_id', $user->id)
|
||||
->with('achievement')
|
||||
->where('earned_at', '!=', null)
|
||||
->orderByDesc('earned_at')
|
||||
->get();
|
||||
|
||||
$recentComments = Comment::where('user_id', $user->id)
|
||||
->where('status', 'approved')
|
||||
->orderByDesc('created_at')
|
||||
->limit(6)
|
||||
->get();
|
||||
|
||||
$isOwnProfile = Auth::id() === $user->id;
|
||||
$isFollowing = Auth::check() && !$isOwnProfile ? Auth::user()->isFollowing($user->id) : false;
|
||||
$followerCount = \App\Models\UserFollow::where('following_id', $user->id)->count();
|
||||
$followingCount= \App\Models\UserFollow::where('follower_id', $user->id)->count();
|
||||
$compatibility = (Auth::check() && !$isOwnProfile)
|
||||
? Auth::user()->compatibilityWith($user)
|
||||
: null;
|
||||
|
||||
return view('frontend.public-profile', compact(
|
||||
'user', 'commentCount', 'watchlistItems',
|
||||
'watchStats', 'achievements', 'recentComments', 'isOwnProfile',
|
||||
'isFollowing', 'followerCount', 'followingCount', 'compatibility'
|
||||
));
|
||||
}
|
||||
|
||||
public function settings()
|
||||
{
|
||||
return view('frontend.profile-settings', ['user' => Auth::user()]);
|
||||
}
|
||||
|
||||
public function update(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
$data = $request->validate([
|
||||
'name' => 'required|string|max:60',
|
||||
'username' => 'nullable|string|max:30|alpha_dash|unique:users,username,' . $user->id,
|
||||
'bio' => 'nullable|string|max:300',
|
||||
'website' => 'nullable|url|max:200',
|
||||
'twitter' => 'nullable|string|max:50',
|
||||
'instagram' => 'nullable|string|max:50',
|
||||
'discord' => 'nullable|string|max:80',
|
||||
'profile_color' => 'nullable|regex:/^#[0-9a-fA-F]{6}$/',
|
||||
'show_watchlist' => 'boolean',
|
||||
'show_activity' => 'boolean',
|
||||
]);
|
||||
|
||||
// Checkboxlar false gelince request'te bulunmaz
|
||||
$data['show_watchlist'] = $request->boolean('show_watchlist');
|
||||
$data['show_activity'] = $request->boolean('show_activity');
|
||||
|
||||
// @ işaretlerini temizle
|
||||
if (isset($data['twitter'])) $data['twitter'] = ltrim($data['twitter'], '@');
|
||||
if (isset($data['instagram'])) $data['instagram'] = ltrim($data['instagram'], '@');
|
||||
|
||||
$user->update($data);
|
||||
|
||||
return back()->with('success', 'Profil güncellendi.');
|
||||
}
|
||||
|
||||
public function updateAvatar(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'avatar' => 'required|image|mimes:jpg,jpeg,png,webp,gif|max:2048',
|
||||
]);
|
||||
|
||||
$user = Auth::user();
|
||||
|
||||
// Eski avatarı sil
|
||||
if ($user->avatar && Storage::disk('public')->exists($user->avatar)) {
|
||||
Storage::disk('public')->delete($user->avatar);
|
||||
}
|
||||
|
||||
$path = $request->file('avatar')->store('avatars', 'public');
|
||||
$user->update(['avatar' => $path]);
|
||||
|
||||
return back()->with('success', 'Profil fotoğrafı güncellendi.');
|
||||
}
|
||||
|
||||
public function updateBanner(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'banner' => 'required|image|mimes:jpg,jpeg,png,webp|max:5120',
|
||||
]);
|
||||
|
||||
$user = Auth::user();
|
||||
|
||||
if ($user->banner_image && Storage::disk('public')->exists($user->banner_image)) {
|
||||
Storage::disk('public')->delete($user->banner_image);
|
||||
}
|
||||
|
||||
$path = $request->file('banner')->store('banners', 'public');
|
||||
$user->update(['banner_image' => $path]);
|
||||
|
||||
return back()->with('success', 'Profil kapak fotoğrafı güncellendi.');
|
||||
}
|
||||
|
||||
public function updatePassword(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'current_password' => 'required',
|
||||
'password' => ['required', 'confirmed', Password::min(8)],
|
||||
]);
|
||||
|
||||
$user = Auth::user();
|
||||
|
||||
if (!Hash::check($request->current_password, $user->password)) {
|
||||
return back()->withErrors(['current_password' => 'Mevcut şifre yanlış.']);
|
||||
}
|
||||
|
||||
$user->update(['password' => $request->password]);
|
||||
|
||||
return back()->with('success', 'Şifre güncellendi.');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user