From 32fa189e4f0f9ba1cea145f852116a534ee515bf Mon Sep 17 00:00:00 2001 From: Aji Kamaludin Date: Wed, 24 May 2023 22:25:50 +0700 Subject: [PATCH] prepare page for admin and user --- .../Auth/AuthenticatedSessionController.php | 5 +- .../Auth/NewPasswordController.php | 2 +- .../Controllers/Customer/HomeController.php | 13 ++ app/Http/Kernel.php | 4 +- app/Http/Middleware/Authenticate.php | 2 +- .../HandleInertiaCustomerRequests.php | 42 +++++++ app/Http/Middleware/HandleInertiaRequests.php | 3 +- .../Middleware/RedirectIfAuthenticated.php | 5 +- app/Models/CoinReward.php | 1 - app/Models/Customer.php | 1 - app/Providers/RouteServiceProvider.php | 2 +- config/auth.php | 4 +- .../Components/Defaults/ApplicationLogo.jsx | 10 +- resources/js/Layouts/CustomerLayout.jsx | 19 +++ resources/js/Layouts/Partials/SidebarNav.jsx | 56 +++++---- resources/js/Pages/Auth/Login.jsx | 63 +++++----- resources/js/Pages/Auth/Register.jsx | 51 ++++---- resources/js/Pages/Home/Index/Index.jsx | 12 ++ resources/js/Pages/Welcome.jsx | 111 +++++++++++++----- resources/js/admin.jsx | 22 ++++ resources/views/admin.blade.php | 21 ++++ routes/admin.php | 43 +++++++ routes/web.php | 31 +---- 23 files changed, 378 insertions(+), 145 deletions(-) create mode 100644 app/Http/Controllers/Customer/HomeController.php create mode 100644 app/Http/Middleware/HandleInertiaCustomerRequests.php create mode 100644 resources/js/Layouts/CustomerLayout.jsx create mode 100644 resources/js/Pages/Home/Index/Index.jsx create mode 100644 resources/js/admin.jsx create mode 100644 resources/views/admin.blade.php create mode 100644 routes/admin.php diff --git a/app/Http/Controllers/Auth/AuthenticatedSessionController.php b/app/Http/Controllers/Auth/AuthenticatedSessionController.php index c7369c3..9d85138 100644 --- a/app/Http/Controllers/Auth/AuthenticatedSessionController.php +++ b/app/Http/Controllers/Auth/AuthenticatedSessionController.php @@ -4,7 +4,6 @@ namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Http\Requests\Auth\LoginRequest; -use App\Providers\RouteServiceProvider; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -34,7 +33,7 @@ class AuthenticatedSessionController extends Controller $request->session()->regenerate(); - return redirect()->intended(RouteServiceProvider::HOME); + return redirect()->route('dashboard'); } /** @@ -48,6 +47,6 @@ class AuthenticatedSessionController extends Controller $request->session()->regenerateToken(); - return redirect()->route('login'); + return redirect()->route('admin.login'); } } diff --git a/app/Http/Controllers/Auth/NewPasswordController.php b/app/Http/Controllers/Auth/NewPasswordController.php index 394cc4a..db3313f 100644 --- a/app/Http/Controllers/Auth/NewPasswordController.php +++ b/app/Http/Controllers/Auth/NewPasswordController.php @@ -59,7 +59,7 @@ class NewPasswordController extends Controller // the application's home authenticated view. If there is an error we can // redirect them back to where they came from with their error message. if ($status == Password::PASSWORD_RESET) { - return redirect()->route('login')->with('status', __($status)); + return redirect()->route('admin.login')->with('status', __($status)); } throw ValidationException::withMessages([ diff --git a/app/Http/Controllers/Customer/HomeController.php b/app/Http/Controllers/Customer/HomeController.php new file mode 100644 index 0000000..f51b472 --- /dev/null +++ b/app/Http/Controllers/Customer/HomeController.php @@ -0,0 +1,13 @@ + \App\Http\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + 'inertia.admin' => \App\Http\Middleware\HandleInertiaRequests::class, + 'inertia.customer' => \App\Http\Middleware\HandleInertiaCustomerRequests::class, ]; } diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index 704089a..a9fb04a 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -15,7 +15,7 @@ class Authenticate extends Middleware protected function redirectTo($request) { if (! $request->expectsJson()) { - return route('login'); + return route('admin.login'); } } } diff --git a/app/Http/Middleware/HandleInertiaCustomerRequests.php b/app/Http/Middleware/HandleInertiaCustomerRequests.php new file mode 100644 index 0000000..8f6cb14 --- /dev/null +++ b/app/Http/Middleware/HandleInertiaCustomerRequests.php @@ -0,0 +1,42 @@ + + */ + public function share(Request $request): array + { + return array_merge(parent::share($request), [ + 'auth' => [ + 'user' => $request->user(), + ], + 'flash' => [ + 'message' => fn () => $request->session()->get('message'), + ], + 'app_name' => env('APP_NAME', 'App Name'), + ]); + } +} diff --git a/app/Http/Middleware/HandleInertiaRequests.php b/app/Http/Middleware/HandleInertiaRequests.php index 9dc5ef9..6d5b532 100644 --- a/app/Http/Middleware/HandleInertiaRequests.php +++ b/app/Http/Middleware/HandleInertiaRequests.php @@ -12,7 +12,7 @@ class HandleInertiaRequests extends Middleware * * @var string */ - protected $rootView = 'app'; + protected $rootView = 'admin'; /** * Determine the current asset version. @@ -36,6 +36,7 @@ class HandleInertiaRequests extends Middleware 'flash' => [ 'message' => fn () => $request->session()->get('message'), ], + 'app_name' => env('APP_NAME', 'App Name'), ]); } } diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php index 4e7c24b..fa25bf6 100644 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -22,7 +22,10 @@ class RedirectIfAuthenticated foreach ($guards as $guard) { if (Auth::guard($guard)->check()) { - return redirect(RouteServiceProvider::HOME); + if ($guard == 'web') { + return redirect()->route('dashboard'); + } + return redirect()->route('home.index'); } } diff --git a/app/Models/CoinReward.php b/app/Models/CoinReward.php index 828babc..fc30fe4 100644 --- a/app/Models/CoinReward.php +++ b/app/Models/CoinReward.php @@ -2,7 +2,6 @@ namespace App\Models; - class CoinReward extends Model { protected $fillable = [ diff --git a/app/Models/Customer.php b/app/Models/Customer.php index 6642a2d..a8f36d1 100644 --- a/app/Models/Customer.php +++ b/app/Models/Customer.php @@ -8,7 +8,6 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Foundation\Auth\User as Authenticatable; - class Customer extends Authenticatable { use HasFactory, HasUlids, UserTrackable, SoftDeletes; diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 52dabc1..1694d8e 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -17,7 +17,7 @@ class RouteServiceProvider extends ServiceProvider * * @var string */ - public const HOME = '/dashboard'; + // public const HOME = '/dashboard'; /** * Define your route model bindings, pattern filters, and other route configuration. diff --git a/config/auth.php b/config/auth.php index 43444c6..e0a73ad 100644 --- a/config/auth.php +++ b/config/auth.php @@ -42,8 +42,8 @@ return [ ], 'customer' => [ 'driver' => 'session', - 'provider' => 'customers' - ] + 'provider' => 'customers', + ], ], /* diff --git a/resources/js/Components/Defaults/ApplicationLogo.jsx b/resources/js/Components/Defaults/ApplicationLogo.jsx index 08b4984..e374fdc 100644 --- a/resources/js/Components/Defaults/ApplicationLogo.jsx +++ b/resources/js/Components/Defaults/ApplicationLogo.jsx @@ -1,7 +1,9 @@ -import React from 'react'; +import { usePage } from '@inertiajs/react' +import React from 'react' export default function ApplicationLogo({ className }) { - return ( -

App Name

- ); + const { + props: { app_name }, + } = usePage() + return

{app_name}

} diff --git a/resources/js/Layouts/CustomerLayout.jsx b/resources/js/Layouts/CustomerLayout.jsx new file mode 100644 index 0000000..a27c6fb --- /dev/null +++ b/resources/js/Layouts/CustomerLayout.jsx @@ -0,0 +1,19 @@ +import React from 'react' +import ApplicationLogo from '@/Components/Defaults/ApplicationLogo' +import { Link } from '@inertiajs/react' + +export default function CustomerLayout({ children }) { + return ( +
+
+ + + +
+ +
+ {children} +
+
+ ) +} diff --git a/resources/js/Layouts/Partials/SidebarNav.jsx b/resources/js/Layouts/Partials/SidebarNav.jsx index c7fb390..df2571b 100644 --- a/resources/js/Layouts/Partials/SidebarNav.jsx +++ b/resources/js/Layouts/Partials/SidebarNav.jsx @@ -1,13 +1,16 @@ -import React from 'react'; -import { router } from '@inertiajs/react'; -import { Sidebar } from 'flowbite-react'; -import { HiLogout } from 'react-icons/hi'; -import { filterOpenMenu } from './helpers'; -import routes from './routes'; -import { formatDate } from '@/utils'; +import React from 'react' +import { router, usePage } from '@inertiajs/react' +import { Sidebar } from 'flowbite-react' +import { HiLogout } from 'react-icons/hi' +import { filterOpenMenu } from './helpers' +import routes from './routes' export default function SidebarNav({ user }) { - const menus = routes.filter(item => { + const { + props: { app_name }, + } = usePage() + + const menus = routes.filter((item) => { item.open = false if (!item.show) { return null @@ -15,7 +18,7 @@ export default function SidebarNav({ user }) { if (+user.is_superadmin === 1) { return filterOpenMenu(user, item) } - if(user.role.permissions.find(p => p.name === item.permission)) { + if (user.role.permissions.find((p) => p.name === item.permission)) { return item } @@ -26,33 +29,36 @@ export default function SidebarNav({ user }) { - {menus.map(item => ( + {menus.map((item) => (
{item.items === undefined ? ( - router.visit(item.route)} - icon={item.icon} - active={route().current(item.active)} - > - {item.name} - + router.visit(item.route)} + icon={item.icon} + active={route().current(item.active)} + > + {item.name} + ) : ( - {item.items.map(item => ( - ( + router.visit(item.route)} + onClick={() => + router.visit(item.route) + } icon={item.icon} - active={route().current(item.active)} + active={route().current( + item.active + )} > {item.name} ))} - )}
@@ -64,10 +70,10 @@ export default function SidebarNav({ user }) { Logout
-

- App Name © {(new Date()).getFullYear()} +

+ {app_name} © {new Date().getFullYear()}

) -} \ No newline at end of file +} diff --git a/resources/js/Pages/Auth/Login.jsx b/resources/js/Pages/Auth/Login.jsx index ef9e826..47f64de 100644 --- a/resources/js/Pages/Auth/Login.jsx +++ b/resources/js/Pages/Auth/Login.jsx @@ -1,43 +1,52 @@ -import React, { useEffect } from 'react'; -import GuestLayout from '@/Layouts/GuestLayout'; -import InputError from '@/Components/Defaults/InputError'; -import { Head, Link, useForm } from '@inertiajs/react'; -import { Button, TextInput,Label, Checkbox, Spinner } from 'flowbite-react'; +import React, { useEffect } from 'react' +import GuestLayout from '@/Layouts/GuestLayout' +import InputError from '@/Components/Defaults/InputError' +import { Head, Link, useForm } from '@inertiajs/react' +import { Button, TextInput, Label, Checkbox, Spinner } from 'flowbite-react' export default function Login({ status }) { const { data, setData, post, processing, errors, reset } = useForm({ email: '', password: '', remember: '', - }); + }) useEffect(() => { return () => { - reset('password'); - }; - }, []); + reset('password') + } + }, []) const onHandleChange = (event) => { - setData(event.target.name, event.target.type === 'checkbox' ? event.target.checked : event.target.value); - }; + setData( + event.target.name, + event.target.type === 'checkbox' + ? event.target.checked + : event.target.value + ) + } - const handleKeyDown = e => { - if(e.code === 'Enter') { - post(route('login')) + const handleKeyDown = (e) => { + if (e.code === 'Enter') { + post(route('admin.login')) } } const submit = (e) => { - e.preventDefault(); + e.preventDefault() - post(route('login')); - }; + post(route('admin.login')) + } return ( - {status &&
{status}
} + {status && ( +
+ {status} +
+ )}
@@ -66,7 +75,7 @@ export default function Login({ status }) { className="mt-1 block w-full" autoComplete="current-password" onChange={onHandleChange} - onKeyDownCapture={e => handleKeyDown(e)} + onKeyDownCapture={(e) => handleKeyDown(e)} /> @@ -74,21 +83,21 @@ export default function Login({ status }) {
- ); + ) } diff --git a/resources/js/Pages/Auth/Register.jsx b/resources/js/Pages/Auth/Register.jsx index 1ffebe9..e9f5417 100644 --- a/resources/js/Pages/Auth/Register.jsx +++ b/resources/js/Pages/Auth/Register.jsx @@ -1,10 +1,10 @@ -import React, { useEffect } from 'react'; -import GuestLayout from '@/Layouts/GuestLayout'; -import InputError from '@/Components/Defaults/InputError'; -import InputLabel from '@/Components/Defaults/InputLabel'; -import PrimaryButton from '@/Components/Defaults/PrimaryButton'; -import TextInput from '@/Components/Defaults/TextInput'; -import { Head, Link, useForm } from '@inertiajs/react'; +import React, { useEffect } from 'react' +import GuestLayout from '@/Layouts/GuestLayout' +import InputError from '@/Components/Defaults/InputError' +import InputLabel from '@/Components/Defaults/InputLabel' +import PrimaryButton from '@/Components/Defaults/PrimaryButton' +import TextInput from '@/Components/Defaults/TextInput' +import { Head, Link, useForm } from '@inertiajs/react' export default function Register() { const { data, setData, post, processing, errors, reset } = useForm({ @@ -12,23 +12,28 @@ export default function Register() { email: '', password: '', password_confirmation: '', - }); + }) useEffect(() => { return () => { - reset('password', 'password_confirmation'); - }; - }, []); + reset('password', 'password_confirmation') + } + }, []) const onHandleChange = (event) => { - setData(event.target.name, event.target.type === 'checkbox' ? event.target.checked : event.target.value); - }; + setData( + event.target.name, + event.target.type === 'checkbox' + ? event.target.checked + : event.target.value + ) + } const submit = (e) => { - e.preventDefault(); + e.preventDefault() - post(route('register')); - }; + post(route('register')) + } return ( @@ -85,7 +90,10 @@ export default function Register() {
- + - +
Already registered? @@ -113,5 +124,5 @@ export default function Register() {
- ); + ) } diff --git a/resources/js/Pages/Home/Index/Index.jsx b/resources/js/Pages/Home/Index/Index.jsx new file mode 100644 index 0000000..76b9e2c --- /dev/null +++ b/resources/js/Pages/Home/Index/Index.jsx @@ -0,0 +1,12 @@ +import React from 'react' +import { Head } from '@inertiajs/react' +import CustomerLayout from '@/Layouts/CustomerLayout' + +export default function Index({ status }) { + return ( + + +

This is HOME

+
+ ) +} diff --git a/resources/js/Pages/Welcome.jsx b/resources/js/Pages/Welcome.jsx index bc02a86..eb4ae6b 100644 --- a/resources/js/Pages/Welcome.jsx +++ b/resources/js/Pages/Welcome.jsx @@ -1,5 +1,5 @@ -import React from 'react'; -import { Link, Head } from '@inertiajs/react'; +import React from 'react' +import { Link, Head } from '@inertiajs/react' export default function Welcome(props) { return ( @@ -8,12 +8,18 @@ export default function Welcome(props) {
{props.auth.user ? ( - + Dashboard ) : ( <> - + Log in @@ -69,9 +75,13 @@ export default function Welcome(props) {
- Laravel has wonderful, thorough documentation covering every aspect of the - framework. Whether you are new to the framework or have previous experience with - Laravel, we recommend reading all of the documentation from beginning to end. + Laravel has wonderful, thorough + documentation covering every aspect of + the framework. Whether you are new to + the framework or have previous + experience with Laravel, we recommend + reading all of the documentation from + beginning to end.
@@ -103,9 +113,11 @@ export default function Welcome(props) {
- Laracasts offers thousands of video tutorials on Laravel, PHP, and JavaScript - development. Check them out, see for yourself, and massively level up your - development skills in the process. + Laracasts offers thousands of video + tutorials on Laravel, PHP, and + JavaScript development. Check them out, + see for yourself, and massively level up + your development skills in the process.
@@ -136,9 +148,11 @@ export default function Welcome(props) {
- Laravel News is a community driven portal and newsletter aggregating all of the - latest and most important news in the Laravel ecosystem, including new package - releases and tutorials. + Laravel News is a community driven + portal and newsletter aggregating all of + the latest and most important news in + the Laravel ecosystem, including new + package releases and tutorials.
@@ -164,45 +178,77 @@ export default function Welcome(props) {
- Laravel's robust library of first-party tools and libraries, such as{' '} - + Laravel's robust library of first-party + tools and libraries, such as{' '} + Forge ,{' '} - + Vapor ,{' '} - + Nova , and{' '} - + Envoyer {' '} - help you take your projects to the next level. Pair them with powerful open + help you take your projects to the next + level. Pair them with powerful open source libraries like{' '} - + Cashier ,{' '} - + Dusk ,{' '} - + Echo ,{' '} - + Horizon ,{' '} - + Sanctum ,{' '} - + Telescope , and more. @@ -227,7 +273,10 @@ export default function Welcome(props) { - + Shop @@ -243,18 +292,22 @@ export default function Welcome(props) { - + Sponsor
- Laravel v{props.laravelVersion} (PHP v{props.phpVersion}) + Laravel v{props.laravelVersion} (PHP v + {props.phpVersion})
- ); + ) } diff --git a/resources/js/admin.jsx b/resources/js/admin.jsx new file mode 100644 index 0000000..03f1064 --- /dev/null +++ b/resources/js/admin.jsx @@ -0,0 +1,22 @@ +import './bootstrap'; +import '../css/app.css'; +import 'flowbite'; +import 'react-toastify/dist/ReactToastify.css'; + +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import { createInertiaApp } from '@inertiajs/react'; +import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'; + +const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel'; + +createInertiaApp({ + title: (title) => `${title} - ${appName}`, + resolve: (name) => resolvePageComponent(`./Pages/${name}.jsx`, import.meta.glob('./Pages/**/*.jsx')), + setup({ el, App, props }) { + const root = createRoot(el); + + root.render(); + }, + progress: { color: '#003bf1' , showSpinner: true, includeCSS: true}, +}); diff --git a/resources/views/admin.blade.php b/resources/views/admin.blade.php new file mode 100644 index 0000000..e161368 --- /dev/null +++ b/resources/views/admin.blade.php @@ -0,0 +1,21 @@ + + + + + + + {{ config('app.name', 'Laravel') }} + + + + + + @routes + @viteReactRefresh + @vite(['resources/js/admin.jsx', "resources/js/Pages/{$page['component']}.jsx"]) + @inertiaHead + + + @inertia + + diff --git a/routes/admin.php b/routes/admin.php new file mode 100644 index 0000000..cc03a84 --- /dev/null +++ b/routes/admin.php @@ -0,0 +1,43 @@ +prefix('admin') + ->group(function () { + Route::middleware(['guest:web'])->group(function () { + Route::get('login', [AuthenticatedSessionController::class, 'create']) + ->name('admin.login'); + + Route::post('login', [AuthenticatedSessionController::class, 'store']); + }); + + Route::middleware(['auth'])->group(function () { + + Route::get('/dashboard', [GeneralController::class, 'index'])->name('dashboard'); + Route::get('/maintance', [GeneralController::class, 'maintance'])->name('maintance'); + + // Admin Profile + Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit'); + Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update'); + Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy'); + + // Logout + Route::post('logout', [AuthenticatedSessionController::class, 'destroy']) + ->name('logout'); + + // User + Route::get('/users', [UserController::class, 'index'])->name('user.index'); + Route::post('/users', [UserController::class, 'store'])->name('user.store'); + Route::put('/users/{user}', [UserController::class, 'update'])->name('user.update'); + Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('user.destroy'); + + // Role + Route::resource('/roles', RoleController::class); + }); + }); diff --git a/routes/web.php b/routes/web.php index 0ad6d53..249ad29 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,9 +1,6 @@ route('login'); +Route::middleware(['inertia.customer'])->group(function () { + Route::get('/', [HomeController::class, 'index'])->name('home.index'); }); -Route::middleware(['auth'])->group(function () { - Route::get('/dashboard', [GeneralController::class, 'index'])->name('dashboard'); - Route::get('/maintance', [GeneralController::class, 'maintance'])->name('maintance'); - - // User - Route::get('/users', [UserController::class, 'index'])->name('user.index'); - Route::post('/users', [UserController::class, 'store'])->name('user.store'); - Route::put('/users/{user}', [UserController::class, 'update'])->name('user.update'); - Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('user.destroy'); - - // Role - Route::resource('/roles', RoleController::class); -}); - -Route::middleware('auth')->group(function () { - Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit'); - Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update'); - Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy'); -}); - -require __DIR__.'/auth.php'; +require_once 'admin.php';