Skip to content

Commit

Permalink
Follow Form episode complete
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffreyWay committed Apr 1, 2020
1 parent e92d3b4 commit 36dc366
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 57 deletions.
46 changes: 46 additions & 0 deletions app/Followable.php
@@ -0,0 +1,46 @@
<?php

namespace App;

trait Followable
{
public function follow(User $user)
{
return $this->follows()->save($user);
}

public function unfollow(User $user)
{
return $this->follows()->detach($user);
}

public function toggleFollow(User $user)
{
// Tip: You can also use the toggle() method.
// We'll cover this in the next episode.
// $this->follows()->toggle($user);

if ($this->following($user)) {
return $this->unfollow($user);
}

return $this->follow($user);
}

public function following(User $user)
{
return $this->follows()
->where('following_user_id', $user->id)
->exists();
}

public function follows()
{
return $this->belongsToMany(
User::class,
'follows',
'user_id',
'following_user_id'
);
}
}
17 changes: 17 additions & 0 deletions app/Http/Controllers/FollowsController.php
@@ -0,0 +1,17 @@
<?php

namespace App\Http\Controllers;

use App\User;

class FollowsController extends Controller
{
public function store(User $user)
{
auth()
->user()
->toggleFollow($user);

return back();
}
}
6 changes: 4 additions & 2 deletions app/Http/Controllers/TweetsController.php
Expand Up @@ -9,7 +9,9 @@ class TweetsController extends Controller
public function index()
{
return view('tweets.index', [
'tweets' => auth()->user()->timeline()
'tweets' => auth()
->user()
->timeline()
]);
}

Expand All @@ -24,6 +26,6 @@ public function store()
'body' => $attributes['body']
]);

return redirect('/home');
return redirect()->route('home');
}
}
37 changes: 10 additions & 27 deletions app/User.php
Expand Up @@ -7,38 +7,34 @@

class User extends Authenticatable
{
use Notifiable;
use Notifiable, Followable;

/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
protected $fillable = ['name', 'email', 'password'];

/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
protected $hidden = ['password', 'remember_token'];

/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
'email_verified_at' => 'datetime'
];

public function getAvatarAttribute()
{
return "https://i.pravatar.cc/200?u=".$this->email;
return "https://i.pravatar.cc/200?u=" . $this->email;
}

public function timeline()
Expand All @@ -47,30 +43,17 @@ public function timeline()

return Tweet::whereIn('user_id', $friends)
->orWhere('user_id', $this->id)
->latest()->get();
->latest()
->get();
}

public function tweets()
{
return $this->hasMany(Tweet::class);
}

public function follow(User $user)
{
return $this->follows()->save($user);
}

public function follows()
{
return $this->belongsToMany(
User::class,
'follows',
'user_id', 'following_user_id'
);
return $this->hasMany(Tweet::class)->latest();
}

public function getRouteKeyName()
public function path()
{
return 'name';
return route('profile', $this->name);
}
}
2 changes: 1 addition & 1 deletion resources/views/_friends-list.blade.php
Expand Up @@ -5,7 +5,7 @@
@foreach (auth()->user()->follows as $user)
<li class="mb-4">
<div>
<a href="{{ route('profile', $user) }}" class="flex items-center text-sm">
<a href="{{ $user->path() }}" class="flex items-center text-sm">
<img
src="{{ $user->avatar }}"
alt=""
Expand Down
2 changes: 1 addition & 1 deletion resources/views/_sidebar-links.blade.php
Expand Up @@ -56,7 +56,7 @@ class="font-bold text-lg mb-4 block"
<li>
<a
class="font-bold text-lg mb-4 block"
href="{{ route('profile', auth()->user()) }}"
href="{{ auth()->user()->path() }}"
>
Profile
</a>
Expand Down
6 changes: 3 additions & 3 deletions resources/views/_tweet.blade.php
@@ -1,6 +1,6 @@
<div class="flex p-4 border-b border-b-gray-400">
<div class="flex p-4 {{ $loop->last ? '' : 'border-b border-b-gray-400' }}">
<div class="mr-2 flex-shrink-0">
<a href="{{ route('profile', $tweet->user) }}">
<a href="{{ $tweet->user->path() }}">
<img
src="{{ $tweet->user->avatar }}"
alt=""
Expand All @@ -13,7 +13,7 @@ class="rounded-full mr-2"

<div>
<h5 class="font-bold mb-2">
<a href="{{ route('profile', $tweet->user) }}">
<a href="{{ $tweet->user->path() }}">
{{ $tweet->user->name }}
</a>
</h5>
Expand Down
2 changes: 1 addition & 1 deletion resources/views/components/app.blade.php
@@ -1,7 +1,7 @@
<x-master>
<section class="px-8">
<main class="container mx-auto">
<div class="lg:flex lg:justify-between">
<div class="lg:flex lg:justify-center">
<div class="lg:w-32">
@include ('_sidebar-links')
</div>
Expand Down
11 changes: 11 additions & 0 deletions resources/views/components/follow-button.blade.php
@@ -0,0 +1,11 @@
<form method="POST"
action="/profiles/{{ $user->name }}/follow"
>
@csrf

<button type="submit"
class="bg-blue-500 rounded-full shadow py-2 px-4 text-white text-xs"
>
{{ auth()->user()->following($user) ? 'Unfollow Me' : 'Follow Me' }}
</button>
</form>
44 changes: 23 additions & 21 deletions resources/views/profiles/show.blade.php
@@ -1,26 +1,33 @@
<x-app>
<header class="mb-6 relative">
<img
src="/images/default-profile-banner.jpg"
alt=""
class="mb-2"
>
<div class="relative">
<img src="/images/default-profile-banner.jpg"
alt=""
class="mb-2"
>

<div class="flex justify-between items-center mb-4">
<img src="{{ $user->avatar }}"
alt=""
class="rounded-full mr-2 absolute bottom-0 transform -translate-x-1/2 translate-y-1/2"
style="left: 50%"
width="150"
>
</div>

<div class="flex justify-between items-center mb-6">
<div>
<h2 class="font-bold text-2xl mb-0">{{ $user->name }}</h2>
<p class="text-sm">Joined {{ $user->created_at->diffForHumans() }}</p>
</div>

<div>
<a
href=""
class="rounded-full border border-gray-300 py-2 px-4 text-black text-xs mr-2"
>Edit Profile</a>
<a
href=""
class="bg-blue-500 rounded-full shadow py-2 px-4 text-white text-xs"
>Follow Me</a>
<div class="flex">
<a href=""
class="rounded-full border border-gray-300 py-2 px-4 text-black text-xs mr-2"
>
Edit Profile
</a>

<x-follow-button :user="$user"></x-follow-button>
</div>
</div>

Expand All @@ -31,12 +38,7 @@ class="bg-blue-500 rounded-full shadow py-2 px-4 text-white text-xs"
and his catch phrase "Eh...What's up, doc?"
</p>

<img
src="{{ $user->avatar }}"
alt=""
class="rounded-full mr-2 absolute"
style="width: 150px; left: calc(50% - 75px); top: 138px"
>

</header>

@include ('_timeline', [
Expand Down
4 changes: 3 additions & 1 deletion routes/web.php
Expand Up @@ -20,8 +20,10 @@
Route::middleware('auth')->group(function () {
Route::get('/tweets', 'TweetsController@index')->name('home');
Route::post('/tweets', 'TweetsController@store');

Route::post('/profiles/{user:name}/follow', 'FollowsController@store');
});

Route::get('/profiles/{user}', 'ProfilesController@show')->name('profile');
Route::get('/profiles/{user:name}', 'ProfilesController@show')->name('profile');

Auth::routes();

0 comments on commit 36dc366

Please sign in to comment.