feat: funcionalidad de red social (feed, amigos, búsqueda)
- Migraciones: posts, post_likes, post_comments - Modelos Post, PostLike, PostComment con relaciones - User: métodos friendshipWith, isFriendWith, friendIds, posts - PostController: feed, crear publicación con imagen, like toggle, comentarios, eliminar - FriendshipController: listar solicitudes, enviar, aceptar, rechazar, toggle AJAX - SocialProfileController: perfil público con publicaciones y estado de amistad - UserSearchController: búsqueda AJAX por nombre con estado de amistad - FriendRequestNotification: notificación al recibir solicitud - Vistas: feed/index, feed/_post, friendships/index, social/profile - Header: barra de búsqueda con autocomplete AJAX (agregar amigo / mensaje) - Menú lateral: Comunidad, Amigos, Mensajes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Post;
|
||||
use App\Models\PostComment;
|
||||
use App\Models\PostLike;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class PostController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$me = auth()->user();
|
||||
$friendIds = $me->friendIds();
|
||||
$ids = array_merge($friendIds, [$me->id]);
|
||||
|
||||
$posts = Post::whereIn('user_id', $ids)
|
||||
->with(['author', 'likes', 'comments.author'])
|
||||
->latest()
|
||||
->paginate(15);
|
||||
|
||||
return view('feed.index', compact('posts'));
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'body' => 'nullable|string|max:2000',
|
||||
'image' => 'nullable|image|max:5120',
|
||||
]);
|
||||
|
||||
if (!$request->filled('body') && !$request->hasFile('image')) {
|
||||
return back()->with('error', 'Escribe algo o adjunta una imagen.');
|
||||
}
|
||||
|
||||
$imagePath = null;
|
||||
if ($request->hasFile('image')) {
|
||||
$imagePath = $request->file('image')->store('posts', 'public');
|
||||
}
|
||||
|
||||
Post::create([
|
||||
'user_id' => auth()->id(),
|
||||
'body' => $request->body,
|
||||
'image_path' => $imagePath,
|
||||
]);
|
||||
|
||||
return back()->with('success', 'Publicación creada.');
|
||||
}
|
||||
|
||||
public function like(Post $post)
|
||||
{
|
||||
$userId = auth()->id();
|
||||
$liked = PostLike::where('user_id', $userId)->where('post_id', $post->id)->first();
|
||||
|
||||
if ($liked) {
|
||||
$liked->delete();
|
||||
$liked = false;
|
||||
} else {
|
||||
PostLike::create(['user_id' => $userId, 'post_id' => $post->id]);
|
||||
$liked = true;
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'liked' => $liked,
|
||||
'count' => $post->likes()->count(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function comment(Request $request, Post $post)
|
||||
{
|
||||
$request->validate(['body' => 'required|string|max:500']);
|
||||
|
||||
$comment = PostComment::create([
|
||||
'user_id' => auth()->id(),
|
||||
'post_id' => $post->id,
|
||||
'body' => $request->body,
|
||||
]);
|
||||
|
||||
$comment->load('author');
|
||||
|
||||
return response()->json([
|
||||
'id' => $comment->id,
|
||||
'body' => $comment->body,
|
||||
'author' => $comment->author->name,
|
||||
'avatar' => $comment->author->profile_photo_url,
|
||||
'created_at' => $comment->created_at->diffForHumans(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function destroy(Post $post)
|
||||
{
|
||||
abort_unless($post->user_id === auth()->id(), 403);
|
||||
|
||||
if ($post->image_path) {
|
||||
Storage::disk('public')->delete($post->image_path);
|
||||
}
|
||||
|
||||
$post->delete();
|
||||
|
||||
return back()->with('success', 'Publicación eliminada.');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user