Skip to content

Commit

Permalink
added feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
tareq1988 committed Jan 18, 2024
1 parent 37c67a6 commit 45b5856
Show file tree
Hide file tree
Showing 11 changed files with 588 additions and 10 deletions.
113 changes: 113 additions & 0 deletions app/Http/Controllers/Admin/FeedbackController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php

namespace App\Http\Controllers\Admin;

use App\Models\Post;
use App\Models\Board;
use App\Models\Status;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Comment;
use App\Notifications\FeedbackStatusChanged;

class FeedbackController extends Controller
{
public function index(Request $request)
{
$board = $request->input('board');
$status = $request->input('status');
$sort = $request->input('sort') ?? 'voted';

$boards = Board::select('id', 'name', 'posts', 'slug')->get();
$statuses = Status::select('id', 'name', 'color')->get();
$query = Post::with('user', 'board', 'status');

if ($board && $board !== 'all') {
$query->where('board_id', $board);
}

if ($status && $status !== 'all') {
$query->where('status_id', $status);
}

if ($sort) {
if ($sort === 'oldest') {
$query->orderBy('created_at', 'asc');
} elseif ($sort === 'voted') {
$query->orderBy('vote', 'desc');
} elseif ($sort === 'commented') {
$query->orderBy('comments', 'desc');
} elseif ($sort === 'latest') {
$query->orderBy('created_at', 'desc');
}
}

$posts = $query->paginate(30)->withQueryString();

return inertia('Admin/Feedbacks/Index', [
'posts' => $posts,
'boards' => $boards,
'statuses' => $statuses,
]);
}

public function show(Post $post)
{
$post->load('creator', 'board', 'status');

$boards = Board::select('id', 'name', 'posts', 'slug')->get();
$statuses = Status::select('id', 'name', 'color')->get();

return inertia('Admin/Feedbacks/Show', [
'post' => $post,
'boards' => $boards,
'statuses' => $statuses,
]);
}

public function update(Request $request, Post $post)
{
$request->validate([
'board_id' => 'required|exists:boards,id',
'status_id' => 'required|exists:statuses,id',
'comment' => 'nullable|string',
'notify' => 'nullable|boolean'
]);

if ($post->status_id !== $request->input('status_id')) {
Comment::create([
'post_id' => $post->id,
'user_id' => auth()->user()->id,
'body' => $request->input('comment') ?? '',
'status_id' => $request->input('status_id'),
]);

if ($request->input('notify') === true) {
$this->notify($post);
}
}

$post->update([
'board_id' => $request->input('board_id'),
'status_id' => $request->input('status_id'),
]);

return redirect()->back()->with('success', 'Feedback updated successfully.');
}

private function notify($post)
{
// get all voters
$voters = $post->votes()->with('user')
->where('user_id', '!=', auth()->user()->id)
->get();

if (!$voters->count()) {
return;
}

$voters->each(function ($voter) use ($post) {
$voter->user->notify(new FeedbackStatusChanged($post));
});
}
}
2 changes: 1 addition & 1 deletion app/Models/Comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Comment extends Model
{
use HasFactory;

protected $fillable = ['post_id', 'parent_id', 'user_id', 'body'];
protected $fillable = ['post_id', 'parent_id', 'status_id', 'user_id', 'body'];

protected static function boot()
{
Expand Down
57 changes: 57 additions & 0 deletions app/Notifications/FeedbackStatusChanged.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace App\Notifications;

use App\Models\Post;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class FeedbackStatusChanged extends Notification
{
use Queueable;

/**
* Create a new notification instance.
*/
public function __construct(protected Post $post)
{
//
}

/**
* Get the notification's delivery channels.
*
* @return array<int, string>
*/
public function via(object $notifiable): array
{
return ['mail'];
}

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->subject('Feedback Status Changed')
->greeting('Hello, ' . $notifiable->name . '!')
->line('The status of your feedback has been changed to ' . $this->post->status->name . '.')
->action('View Feedback', route('post.show', [$this->post->board, $this->post]))
->line('Thank you for using our application!');
}

/**
* Get the array representation of the notification.
*
* @return array<string, mixed>
*/
public function toArray(object $notifiable): array
{
return [
//
];
}
}
41 changes: 41 additions & 0 deletions resources/js/Components/Pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import { Link } from '@inertiajs/react';
import classnames from 'classnames';
import { PaginatedLink } from '@/types';

type Props = {
links: PaginatedLink[];
};

const Pagination = ({ links }: Props) => {
return (
<div className="isolate inline-flex -space-x-px rounded-md shadow-sm">
{links.map((link, index) => {
const linkClasses = classnames(
'inline-flex px-4 py-2 text-sm font-semibold focus:outline-offset-0',
link.active
? 'z-10 bg-indigo-600 text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600'
: 'hover:bg-gray-50 ring-1 ring-inset ring-gray-300 text-gray-900',
{
'text-gray-400 border-gray-300': !link.url,
}
);

return (
<Link
key={index}
href={link.url}
className={linkClasses}
dangerouslySetInnerHTML={{ __html: link.label }}
onClick={(e) => {
if (!link.url) e.preventDefault();
}}
preserveScroll
/>
);
})}
</div>
);
};

export default Pagination;
11 changes: 9 additions & 2 deletions resources/js/Layouts/AuthenticatedLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ export default function Authenticated({
Dashboard
</NavLink>

<NavLink
href={route('admin.feedbacks.index')}
active={route().current('admin.feedbacks.index')}
>
Feedback
</NavLink>

<NavLink
href={route('admin.statuses.index')}
active={route().current('admin.statuses.index')}
Expand Down Expand Up @@ -191,13 +198,13 @@ export default function Authenticated({

<main className="max-w-7xl mx-auto sm:px-6 lg:px-8 py-12 ">
{error && (
<div className="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div className="max-w-7xl mx-auto">
<Notice type="error" label={error} className="mb-4" />
</div>
)}

{success && (
<div className="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div className="max-w-7xl mx-auto">
<Notice type="success" label={success} className="mb-4" />
</div>
)}
Expand Down
8 changes: 3 additions & 5 deletions resources/js/Pages/Admin/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import { PageProps } from '@/types';

const Dashboard = ({ auth }: PageProps) => {
return (
<div className="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div className="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
<Head title="Dashboard" />

<div className="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
<div className="p-6 text-gray-900 dark:text-gray-100">
You're logged in!
</div>
<div className="p-6 text-gray-900 dark:text-gray-100">
You're logged in!
</div>
</div>
);
Expand Down
Loading

0 comments on commit 45b5856

Please sign in to comment.