Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

marge fron develop #14

Open
wants to merge 45 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
d431523
HEY-1: create factories and auth login local
rafael-pozzebon Oct 26, 2023
7d38e40
HEY-1: criar send question
rafael-pozzebon Oct 26, 2023
6688183
create a question
rafael-pozzebon Oct 26, 2023
ac42ae2
wip
rafael-pozzebon Oct 26, 2023
a76b477
HEY-8: list questions data
rafael-pozzebon Oct 26, 2023
9f598f7
DashboardController
rafael-pozzebon Oct 27, 2023
5a3635c
like vote
rafael-pozzebon Oct 30, 2023
11149dd
code like controller
rafael-pozzebon Oct 30, 2023
fdfd42b
HEY-4: onclik like and question only once
rafael-pozzebon Oct 30, 2023
2895fc2
composer dump function Help
rafael-pozzebon Oct 30, 2023
8c7dca8
adding like button to vote
rafael-pozzebon Nov 11, 2023
31611f2
Hey-6: chenge route question.like
rafael-pozzebon Nov 11, 2023
53c9e0e
Hey-6: n + 1 query ajuste
rafael-pozzebon Nov 12, 2023
64277b2
HEY-9: should create as a draft all the time
rafael-pozzebon Nov 12, 2023
9754f69
HEY-9: should be able to publish a question
rafael-pozzebon Nov 12, 2023
0fe027f
HEY-9: wip
rafael-pozzebon Nov 12, 2023
9fea5ee
HEY-9: should make sure that only the person who has created the ques…
rafael-pozzebon Nov 13, 2023
04a3f05
HEY-9: should make sure that only the person who has created the ques…
rafael-pozzebon Nov 13, 2023
078e662
HEY-9: only authenticated user can create a new question
rafael-pozzebon Nov 13, 2023
8e96999
HEY-9: myquestio test
rafael-pozzebon Nov 13, 2023
cafeae9
HEY-9: publish and destroy
rafael-pozzebon Nov 18, 2023
4e5518d
HEY-10: should make sure that only question with status Draft can be …
rafael-pozzebon Nov 18, 2023
db7168b
HEY-10: should make sure that only question with status Draft can be …
rafael-pozzebon Nov 18, 2023
bc599b2
HEY-10: should make sure that only the person who has created the que…
rafael-pozzebon Nov 18, 2023
3521719
HEY-10: shoul be able to update a question
rafael-pozzebon Nov 18, 2023
4c919f4
HEY-10: should make sure that only the person who has created the que…
rafael-pozzebon Nov 18, 2023
9ac9682
HEY-10: edit and update a question ok
rafael-pozzebon Nov 18, 2023
3d4ad5b
HEY-12: paginate questions
rafael-pozzebon Nov 18, 2023
42b0160
HEY-12: paginate dashboard resource
rafael-pozzebon Nov 18, 2023
4247dd0
wip
rafael-pozzebon Nov 18, 2023
332e0b2
wip
rafael-pozzebon Nov 18, 2023
52053be
update project laravel
rafael-pozzebon Nov 18, 2023
cea9c32
HEY-13: implement softdelete
rafael-pozzebon Nov 18, 2023
dad29ca
HEY-13: implemente model:pune runtine
rafael-pozzebon Nov 18, 2023
aad83bf
HEY-13: it should run model:prune daily
rafael-pozzebon Nov 18, 2023
8a356b9
HEY-13: message for delete
rafael-pozzebon Nov 18, 2023
c522047
HEY-15: question should be unique
rafael-pozzebon Nov 18, 2023
aa07bfe
HEY-16: filter back and
rafael-pozzebon Nov 19, 2023
d9cbac4
HEY-16: persquisar uma pergunta
rafael-pozzebon Nov 19, 2023
feb861c
HEY-17: instaling laravel socialite
rafael-pozzebon Nov 19, 2023
98feeae
HEY-17: instaling laravel socialite
rafael-pozzebon Nov 19, 2023
b1f5efa
wip
rafael-pozzebon Nov 20, 2023
437f546
HEY-17: criete login via github
rafael-pozzebon Nov 20, 2023
847ff4c
develop
rafael-pozzebon Nov 20, 2023
3233b51
Merge pull request #18 from rafael-pozzebon/main
rafael-pozzebon Nov 20, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="[email protected]"
MAIL_FROM_NAME="${APP_NAME}"

GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GITHUB_REDIRECT_URL="${APP_URL}/login/github/callback"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
Expand Down
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
/node_modules
/public/build
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.env.backup
Expand Down
2 changes: 1 addition & 1 deletion app/Console/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Kernel extends ConsoleKernel
*/
protected function schedule(Schedule $schedule): void
{
// $schedule->command('inspire')->hourly();
$schedule->command('model:prune')->daily();
}

/**
Expand Down
28 changes: 28 additions & 0 deletions app/Http/Controllers/Auth/Github/CallBackController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Http\Controllers\Auth\Github;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\{RedirectResponse, Request};
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;
use Str;

class CallBackController extends Controller
{
public function __invoke(): RedirectResponse
{
$githubUser = Socialite::driver('github')->user();

$user = User::query()
->updateOrCreate(
['nickname' => $githubUser->getNickname(), 'email' => $githubUser->getEmail()],
['name' => $githubUser->getName(), 'password' => Str::random(40), 'email_verified_at' => now()]
);

Auth::login($user);

return to_route('dashboard');
}
}
14 changes: 14 additions & 0 deletions app/Http/Controllers/Auth/Github/RedirectController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace App\Http\Controllers\Auth\Github;

use App\Http\Controllers\Controller;
use Laravel\Socialite\Facades\Socialite;

class RedirectController extends Controller
{
public function __invoke()
{
return Socialite::driver('github')->redirect();
}
}
26 changes: 26 additions & 0 deletions app/Http/Controllers/DashboardController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace App\Http\Controllers;

use App\Models\Question;
use Illuminate\Database\Eloquent\Builder;

class DashboardController extends Controller
{
public function __invoke()
{
return view('dashboard', [
'questions' => Question::query()
->when(request()->has('search'), function (Builder $query) {
$query->where('question', 'like', '%' . request()->search . '%');
})
->withSum('votes', 'like')
->withSum('votes', 'unlike')
->orderByRaw('
case when votes_sum_like is null then 0 else votes_sum_like end desc,
case when votes_sum_unlike is null then 0 else votes_sum_unlike end
')
->paginate(5),
]);
}
}
16 changes: 16 additions & 0 deletions app/Http/Controllers/Question/LikeController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace App\Http\Controllers\Question;

use App\Http\Controllers\Controller;
use App\Models\{Question, Vote};

class LikeController extends Controller
{
public function __invoke(Question $question): \Illuminate\Http\RedirectResponse
{
user()->like($question);

return back();
}
}
20 changes: 20 additions & 0 deletions app/Http/Controllers/Question/PublishController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace App\Http\Controllers\Question;

use App\Http\Controllers\Controller;
use App\Models\Question;

class PublishController extends Controller
{
public function __invoke(Question $question)
{
$this->authorize('publish', $question);

$question->update([
'draft' => false,
]);

return back();
}
}
16 changes: 16 additions & 0 deletions app/Http/Controllers/Question/UnlikeController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace App\Http\Controllers\Question;

use App\Http\Controllers\Controller;
use App\Models\Question;

class UnlikeController extends Controller
{
public function __invoke(Question $question): \Illuminate\Http\RedirectResponse
{
user()->unlike($question);

return back();
}
}
76 changes: 74 additions & 2 deletions app/Http/Controllers/QuestionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,54 @@
namespace App\Http\Controllers;

use App\Models\Question;
use App\Rules\SameQuestionRule;
use Closure;

class QuestionController extends Controller
{
public function index()
{
return view('question.index', [
'questions' => user()->questions,
'archivedQuestions' => user()->questions()->onlyTrashed()->get(),
]);
}

public function store()
{
request()->validate([
'question' => [
'required',
'min:10',
function (string $attribute, mixed $value, Closure $fail) {
if ($value[strlen($value) - 1] != '?') {
$fail('Are you sure that is a question? It is missing the question mark in the end.');
}
},
new SameQuestionRule(),
],
]);

user()->questions()
->create([
'question' => request()->question,
'draft' => true,
]);

return back();
}

public function edit(Question $question)
{
$this->authorize('update', $question);

return view('question.edit', compact('question'));
}

public function update(Question $question)
{
$this->authorize('update', $question);

$this->validate(request(), [
'question' => [
'required',
Expand All @@ -20,10 +63,39 @@ function (string $attribute, mixed $value, \Closure $fail) {
],
]);

Question::query()->create([
$question->update([
'question' => request('question'),
]);

return to_route('dashboard');
return to_route('question.index');
}

public function archive(Question $question)
{
$this->authorize('destroy', $question);

$question->delete();

return back();
}

public function restore(int $id)
{
$question = Question::withTrashed()->findOrFail($id);

$this->authorize('destroy', $question);

$question->restore();

return back();
}

public function destroy(Question $question)
{
$this->authorize('destroy', $question);

$question->forceDelete();

return back();
}
}
35 changes: 34 additions & 1 deletion app/Models/Question.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,43 @@

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\{BelongsTo, HasMany};
use Illuminate\Database\Eloquent\{Builder, Model, Prunable, SoftDeletes};

class Question extends Model
{
use HasFactory;
use SoftDeletes;
use Prunable;

protected $casts = [
'draft' => 'boolean',
];

public function votes(): HasMany
{
return $this->hasMany(Vote::class);
}

public function likes(): Attribute
{
return new Attribute(get: fn () => $this->votes->sum('like'));
}

public function unlikes(): Attribute
{
return new Attribute(get: fn () => $this->votes->sum('unlike'));
}

public function createdBy(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}

public function prunable(): Builder
{
return static::where('deleted_at', '<=', now()->subMonth());
}
}
33 changes: 33 additions & 0 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
Expand Down Expand Up @@ -45,4 +46,36 @@ class User extends Authenticatable implements MustVerifyEmail
'email_verified_at' => 'datetime',
'password' => 'hashed',
];

public function votes(): HasMany
{
return $this->hasMany(Vote::class);
}

public function questions(): HasMany
{
return $this->hasMany(Question::class, 'created_by');
}

public function like(Question $question): void
{
$this->votes()->updateOrCreate(
['question_id' => $question->id],
[
'like' => 1,
'unlike' => 0,
]
);
}

public function unlike(Question $question): void
{
$this->votes()->updateOrCreate(
['question_id' => $question->id],
[
'like' => 0,
'unlike' => 1,
]
);
}
}
11 changes: 11 additions & 0 deletions app/Models/Vote.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Vote extends Model
{
use HasFactory;
}
23 changes: 23 additions & 0 deletions app/Policies/QuestionPolicy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Policies;

use App\Models\{Question, User};

class QuestionPolicy
{
public function publish(User $user, Question $question): bool
{
return $question->createdBy()->is($user);
}

public function destroy(User $user, Question $question): bool
{
return $question->createdBy()->is($user);
}

public function update(User $user, Question $question): bool
{
return $question->draft && $question->createdBy()->is($user);
}
}
1 change: 1 addition & 0 deletions app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ public function register(): void
public function boot(): void
{
Model::unguard();
Model::preventLazyLoading(!app()->isProduction());
}
}
Loading
Loading