-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
506 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
<?php | ||
|
||
namespace App\Http\Controllers\Admin; | ||
|
||
use App\Models\Board; | ||
use Illuminate\Support\Str; | ||
use Illuminate\Http\Request; | ||
use App\Http\Controllers\Controller; | ||
|
||
class BoardController extends Controller | ||
{ | ||
public function index() | ||
{ | ||
$data = [ | ||
'boards' => Board::all(), | ||
]; | ||
|
||
return inertia('Admin/Boards/Index', $data); | ||
} | ||
|
||
public function show(Board $board) | ||
{ | ||
$data = [ | ||
'board' => $board, | ||
]; | ||
|
||
return inertia('Admin/Boards/Show', $data); | ||
} | ||
|
||
public function store(Request $request) | ||
{ | ||
$request->validate([ | ||
'name' => 'required|string|max:255', | ||
]); | ||
|
||
Board::create([ | ||
'name' => $request->name, | ||
'slug' => Str::slug($request->name), | ||
'privacy' => 'public', | ||
'allow_posts' => true, | ||
'order' => Board::count() + 1, | ||
'settings' => [ | ||
'form' => [ | ||
'heading' => 'Suggest a feature', | ||
'description' => 'What would you like to see in the future?', | ||
'button' => 'Feature title', | ||
'fields' => [ | ||
'title' => [ | ||
'label' => 'Title', | ||
'placeholder' => 'Enter a short title', | ||
], | ||
'details' => [ | ||
'label' => 'Details', | ||
'placeholder' => 'Enter a detailed description of your feature request', | ||
], | ||
], | ||
] | ||
], | ||
]); | ||
|
||
return redirect()->back()->with('success', 'Board created.'); | ||
} | ||
|
||
public function update(Request $request, Board $board) | ||
{ | ||
$request->validate([ | ||
'name' => 'required|string|max:255', | ||
'slug' => 'required|string|max:255', | ||
'privacy' => 'required|string|in:public,private', | ||
'allow_posts' => 'required|boolean', | ||
'settings' => 'required|array', | ||
'settings.heading' => 'required|string|max:255', | ||
'settings.description' => 'required|string|max:255', | ||
'settings.button' => 'required|string|max:50', | ||
'settings.fields.*.label' => 'required|string|max:100', | ||
'settings.fields.*.placeholder' => 'required|string|max:100', | ||
]); | ||
|
||
$board->update([ | ||
'name' => $request->name, | ||
'slug' => $request->slug, | ||
'privacy' => $request->privacy, | ||
'allow_posts' => $request->allow_posts, | ||
'settings' => [ | ||
'form' => [ | ||
'heading' => $request->settings['heading'], | ||
'description' => $request->settings['description'], | ||
'button' => $request->settings['button'], | ||
'fields' => [ | ||
'title' => [ | ||
'label' => $request->settings['fields']['title']['label'], | ||
'placeholder' => $request->settings['fields']['title']['placeholder'], | ||
], | ||
'details' => [ | ||
'label' => $request->settings['fields']['details']['label'], | ||
'placeholder' => $request->settings['fields']['details']['placeholder'], | ||
], | ||
], | ||
] | ||
], | ||
]); | ||
|
||
return redirect()->route('admin.boards.show', $board)->with('success', 'Board updated.'); | ||
} | ||
|
||
public function destroy(Board $board) | ||
{ | ||
if ($board->posts()->count() > 0) { | ||
return redirect()->back()->with('error', 'Board has posts. Delete posts first.'); | ||
} | ||
|
||
$board->delete(); | ||
|
||
return redirect()->route('admin.boards.index')->with('success', 'Board deleted.'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import React, { useState } from 'react'; | ||
import { Head, Link, useForm } from '@inertiajs/react'; | ||
import { | ||
Button, | ||
Modal, | ||
ModalActions, | ||
ModalBody, | ||
ModalHeader, | ||
SwitchInput, | ||
TextField, | ||
} from '@wedevs/tail-react'; | ||
|
||
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout'; | ||
import { PlusIcon } from '@heroicons/react/24/outline'; | ||
import { BoardType } from '@/types'; | ||
|
||
type Props = { | ||
boards: BoardType[]; | ||
}; | ||
|
||
const BoardsIndex = ({ boards }: Props) => { | ||
const [isModalOpen, setIsModalOpen] = useState(false); | ||
const form = useForm({ | ||
name: '', | ||
}); | ||
|
||
const createBoard = (e: React.FormEvent<HTMLFormElement>) => { | ||
e.preventDefault(); | ||
|
||
form.post(route('admin.boards.store'), { | ||
preserveScroll: true, | ||
onSuccess: () => { | ||
setIsModalOpen(false); | ||
form.reset(); | ||
}, | ||
}); | ||
}; | ||
|
||
return ( | ||
<AuthenticatedLayout | ||
header={ | ||
<div className="flex justify-between"> | ||
<h2 className="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight"> | ||
Boards | ||
</h2> | ||
|
||
<Button | ||
variant="primary" | ||
className="inline-flex" | ||
onClick={() => setIsModalOpen(true)} | ||
> | ||
<PlusIcon className="mr-2 h-5 w-5" aria-hidden="true" /> | ||
<span>Add Board</span> | ||
</Button> | ||
</div> | ||
} | ||
> | ||
<Head title="Boards" /> | ||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3"> | ||
{boards.map((board) => ( | ||
<Link | ||
key={board.id} | ||
className="rounded-lg bg-white shadow" | ||
href={route('admin.boards.show', [board])} | ||
> | ||
<div className="space-x-6 p-6"> | ||
<div className="flex items-center justify-between"> | ||
<span className="font-medium">{board.name}</span> | ||
<span className="text-sm">{board.posts}</span> | ||
</div> | ||
</div> | ||
</Link> | ||
))} | ||
</div> | ||
|
||
<Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)}> | ||
<form onSubmit={createBoard}> | ||
<ModalHeader>Add Board</ModalHeader> | ||
<ModalBody> | ||
<TextField | ||
label="Name" | ||
value={form.data.name} | ||
onChange={(value) => form.setData('name', value)} | ||
/> | ||
</ModalBody> | ||
<ModalActions> | ||
<Button variant="primary">Add Board</Button> | ||
<Button | ||
variant="secondary" | ||
onClick={() => setIsModalOpen(false)} | ||
className="mr-2" | ||
> | ||
Cancel | ||
</Button> | ||
</ModalActions> | ||
</form> | ||
</Modal> | ||
</AuthenticatedLayout> | ||
); | ||
}; | ||
|
||
export default BoardsIndex; |
Oops, something went wrong.