home-erp

git clone git://archive.git.mtrnord.blog/MTRNord/home-erp.git
Log | Files | Refs | README

commit a5d15e451487aee468e68757c8692fa4cbf96288
parent 4b53df042c77ee9db7369280485b7dd2c4f7d93f
Author: MTRNord <mtrnord1@gmail.com>
Date:   Sat, 21 Oct 2023 19:05:34 +0200

Implement basic room page

Diffstat:
Aapp/Http/CSPPolicy.php | 26++++++++++++++++++++++++++
Mapp/Http/Kernel.php | 7++++---
Aapp/Http/LaravelViteNonceGenerator.php | 14++++++++++++++
Mapp/Models/Room.php | 7+++++++
Mapp/Providers/AppServiceProvider.php | 6+++++-
Mcomposer.json | 3++-
Mcomposer.lock | 178+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Aconfig/csp.php | 36++++++++++++++++++++++++++++++++++++
Mdatabase/migrations/2023_10_18_142931_create_rooms_table.php | 2+-
Mdatabase/migrations/2023_10_18_145921_create_cabinets_table.php | 2+-
Mdatabase/migrations/2023_10_18_160707_create_compartments_table.php | 2+-
Mlang/en/tokens.php | 3++-
Mresources/views/dashboard.blade.php | 2+-
Mresources/views/layouts/app.blade.php | 8+++++---
Mresources/views/layouts/guest.blade.php | 6++++--
Aresources/views/livewire/dashboard/overview.blade.php | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mresources/views/livewire/layout/navigation.blade.php | 37++++++++++++++++++++++++-------------
17 files changed, 437 insertions(+), 46 deletions(-)

diff --git a/app/Http/CSPPolicy.php b/app/Http/CSPPolicy.php @@ -0,0 +1,26 @@ +<?php +namespace App\Http; + +use Spatie\Csp\Directive; +use Spatie\Csp\Keyword; +use Spatie\Csp\Policies\Basic; +use Spatie\Csp\Scheme; + +class CSPPolicy extends Basic +{ + public function configure() + { + parent::configure(); + + $this->addDirective(Directive::SCRIPT, Keyword::UNSAFE_EVAL) + ->addDirective(Directive::STYLE, Keyword::UNSAFE_INLINE) + ->addDirective(Directive::CONNECT, Scheme::WSS) + ->addDirective(Directive::CONNECT, Scheme::WS) + ->addDirective(Directive::IMG, Scheme::DATA); + + if (app()->environment() === 'local') { + $this + ->addDirective(Directive::SCRIPT, Keyword::UNSAFE_INLINE); + } + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php @@ -14,7 +14,7 @@ class Kernel extends HttpKernel * @var array<int, class-string|string> */ protected $middleware = [ - // \App\Http\Middleware\TrustHosts::class, + // \App\Http\Middleware\TrustHosts::class, \App\Http\Middleware\TrustProxies::class, \Illuminate\Http\Middleware\HandleCors::class, \App\Http\Middleware\PreventRequestsDuringMaintenance::class, @@ -36,11 +36,12 @@ class Kernel extends HttpKernel \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, + \Spatie\Csp\AddCspHeaders::class, ], 'api' => [ - // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, - \Illuminate\Routing\Middleware\ThrottleRequests::class.':api', + // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, + \Illuminate\Routing\Middleware\ThrottleRequests::class . ':api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ]; diff --git a/app/Http/LaravelViteNonceGenerator.php b/app/Http/LaravelViteNonceGenerator.php @@ -0,0 +1,14 @@ +<?php +namespace App\Http; + +use Illuminate\Support\Facades\Vite; +use Spatie\Csp\Nonce\NonceGenerator; + +class LaravelViteNonceGenerator implements NonceGenerator +{ + public function generate(): string + { + return Vite::useCspNonce(); + } +} + diff --git a/app/Models/Room.php b/app/Models/Room.php @@ -13,6 +13,13 @@ class Room extends Model use HasUuids; /** + * The attributes that are mass assignable. + * + * @var array + */ + protected $fillable = ['name', 'description']; + + /** * Get the cabinets in a room. */ public function cabinets(): HasMany diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -19,6 +20,9 @@ class AppServiceProvider extends ServiceProvider */ public function boot(): void { - // + Model::shouldBeStrict( + // It will only be enabled outside of production, though. + !app()->isProduction() + ); } } diff --git a/composer.json b/composer.json @@ -12,7 +12,8 @@ "laravel/sanctum": "^3.2", "laravel/tinker": "^2.8", "livewire/livewire": "^3.0", - "livewire/volt": "^1.0" + "livewire/volt": "^1.0", + "spatie/laravel-csp": "^2.8" }, "require-dev": { "fakerphp/faker": "^1.9.1", diff --git a/composer.lock b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9e2d008d090a204d31b7d0fd4f63a3a6", + "content-hash": "9194311c195ba536290f9018fac6fa70", "packages": [ { "name": "brick/math", @@ -1818,16 +1818,16 @@ }, { "name": "livewire/livewire", - "version": "v3.0.9", + "version": "v3.0.10", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "53db28bcf433e63b7ce6346244091a33adcd9f2f" + "reference": "cae998aa9a474dc0de81869ab1536014c7b31a64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/53db28bcf433e63b7ce6346244091a33adcd9f2f", - "reference": "53db28bcf433e63b7ce6346244091a33adcd9f2f", + "url": "https://api.github.com/repos/livewire/livewire/zipball/cae998aa9a474dc0de81869ab1536014c7b31a64", + "reference": "cae998aa9a474dc0de81869ab1536014c7b31a64", "shasum": "" }, "require": { @@ -1880,7 +1880,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v3.0.9" + "source": "https://github.com/livewire/livewire/tree/v3.0.10" }, "funding": [ { @@ -1888,7 +1888,7 @@ "type": "github" } ], - "time": "2023-10-17T16:42:14+00:00" + "time": "2023-10-18T11:18:12+00:00" }, { "name": "livewire/volt", @@ -3252,6 +3252,148 @@ "time": "2023-04-15T23:01:58+00:00" }, { + "name": "spatie/laravel-csp", + "version": "2.8.3", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-csp.git", + "reference": "0790c05731f738fd20486307cd510f3cca75009a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-csp/zipball/0790c05731f738fd20486307cd510f3cca75009a", + "reference": "0790c05731f738fd20486307cd510f3cca75009a", + "shasum": "" + }, + "require": { + "illuminate/http": "^8.0|^9.0|^10.0", + "illuminate/support": "^8.0|^9.0|^10.0", + "php": "^8.0", + "spatie/laravel-package-tools": "^1.11" + }, + "require-dev": { + "mockery/mockery": "^1.3.3", + "orchestra/testbench": "^6.0|^7.0|^8.0", + "pestphp/pest": "^1.21.2", + "roave/security-advisories": "dev-master" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Csp\\CspServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Csp\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Thomas Verhelst", + "email": "tvke91@gmail.com", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Add CSP headers to the responses of a Laravel app", + "homepage": "https://github.com/spatie/laravel-csp", + "keywords": [ + "content-security-policy", + "csp", + "headers", + "laravel", + "laravel-csp", + "security", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/laravel-csp/tree/2.8.3" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + } + ], + "time": "2023-02-01T12:22:53+00:00" + }, + { + "name": "spatie/laravel-package-tools", + "version": "1.16.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-package-tools.git", + "reference": "cc7c991555a37f9fa6b814aa03af73f88026a83d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/cc7c991555a37f9fa6b814aa03af73f88026a83d", + "reference": "cc7c991555a37f9fa6b814aa03af73f88026a83d", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^9.28|^10.0", + "php": "^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "orchestra/testbench": "^7.7|^8.0", + "pestphp/pest": "^1.22", + "phpunit/phpunit": "^9.5.24", + "spatie/pest-plugin-test-time": "^1.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\LaravelPackageTools\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Tools for creating Laravel packages", + "homepage": "https://github.com/spatie/laravel-package-tools", + "keywords": [ + "laravel-package-tools", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-package-tools/issues", + "source": "https://github.com/spatie/laravel-package-tools/tree/1.16.1" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2023-08-23T09:04:39+00:00" + }, + { "name": "symfony/console", "version": "v6.3.4", "source": { @@ -8345,16 +8487,16 @@ }, { "name": "spatie/ignition", - "version": "1.11.2", + "version": "1.11.3", "source": { "type": "git", "url": "https://github.com/spatie/ignition.git", - "reference": "48b23411ca4bfbc75c75dfc638b6b36159c375aa" + "reference": "3d886de644ff7a5b42e4d27c1e1f67c8b5f00044" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/ignition/zipball/48b23411ca4bfbc75c75dfc638b6b36159c375aa", - "reference": "48b23411ca4bfbc75c75dfc638b6b36159c375aa", + "url": "https://api.github.com/repos/spatie/ignition/zipball/3d886de644ff7a5b42e4d27c1e1f67c8b5f00044", + "reference": "3d886de644ff7a5b42e4d27c1e1f67c8b5f00044", "shasum": "" }, "require": { @@ -8363,19 +8505,19 @@ "php": "^8.0", "spatie/backtrace": "^1.5.3", "spatie/flare-client-php": "^1.4.0", - "symfony/console": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0" + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "require-dev": { - "illuminate/cache": "^9.52", + "illuminate/cache": "^9.52|^10.0|^11.0", "mockery/mockery": "^1.4", - "pestphp/pest": "^1.20", + "pestphp/pest": "^1.20|^2.0", "phpstan/extension-installer": "^1.1", "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-phpunit": "^1.0", "psr/simple-cache-implementation": "*", - "symfony/cache": "^6.0", - "symfony/process": "^5.4|^6.0", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", "vlucas/phpdotenv": "^5.5" }, "suggest": { @@ -8424,7 +8566,7 @@ "type": "github" } ], - "time": "2023-09-19T15:29:52+00:00" + "time": "2023-10-18T14:09:40+00:00" }, { "name": "spatie/laravel-ignition", diff --git a/config/csp.php b/config/csp.php @@ -0,0 +1,36 @@ +<?php + +return [ + + /* + * A policy will determine which CSP headers will be set. A valid CSP policy is + * any class that extends `Spatie\Csp\Policies\Policy` + */ + 'policy' => \App\Http\CSPPolicy::class, + + /* + * This policy which will be put in report only mode. This is great for testing out + * a new policy or changes to existing csp policy without breaking anything. + */ + 'report_only_policy' => '', + + /* + * All violations against the policy will be reported to this url. + * A great service you could use for this is https://report-uri.com/ + * + * You can override this setting by calling `reportTo` on your policy. + */ + 'report_uri' => env('CSP_REPORT_URI', ''), + + /* + * Headers will only be added if this setting is set to true. + * + * Currently broken due to livewire + */ + 'enabled' => env('CSP_ENABLED', false), + + /* + * The class responsible for generating the nonces used in inline tags and headers. + */ + 'nonce_generator' => \App\Http\LaravelViteNonceGenerator::class, +]; diff --git a/database/migrations/2023_10_18_142931_create_rooms_table.php b/database/migrations/2023_10_18_142931_create_rooms_table.php @@ -12,7 +12,7 @@ return new class extends Migration { public function up(): void { Schema::create('rooms', function (Blueprint $table) { - $table->id(); + $table->uuid('id'); $table->timestamps(); $table->string("name"); $table->string("description"); diff --git a/database/migrations/2023_10_18_145921_create_cabinets_table.php b/database/migrations/2023_10_18_145921_create_cabinets_table.php @@ -12,7 +12,7 @@ return new class extends Migration { public function up(): void { Schema::create('cabinets', function (Blueprint $table) { - $table->id(); + $table->uuid('id'); $table->timestamps(); $table->string("name"); $table->string("description"); diff --git a/database/migrations/2023_10_18_160707_create_compartments_table.php b/database/migrations/2023_10_18_160707_create_compartments_table.php @@ -14,7 +14,7 @@ return new class extends Migration { public function up(): void { Schema::create('compartments', function (Blueprint $table) { - $table->id(); + $table->uuid('id'); $table->timestamps(); $table->string("name"); $table->string("description"); diff --git a/lang/en/tokens.php b/lang/en/tokens.php @@ -1,5 +1,6 @@ <?php return [ - "token_created" => "Created token: :token" + "token_created" => "Created token: :token", + "uuid" => "UUID for NFC: :uuid" ]; diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php @@ -9,7 +9,7 @@ <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> <div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg"> <div class="p-6 text-gray-900 dark:text-gray-100"> - {{ __("You're logged in!") }} + <livewire:dashboard.overview /> </div> </div> </div> diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php @@ -5,11 +5,12 @@ <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="csrf-token" content="{{ csrf_token() }}"> + <meta property="csp-nonce" content="{{ csp_nonce() }}"> <title>{{ config('app.name', 'Home ERP') }}</title> <!-- Scripts --> - @vite(['resources/css/app.css', 'resources/js/app.js']) + @vite(['resources/css/app.css']) </head> <body class="font-sans antialiased"> @@ -30,12 +31,13 @@ {{ $slot }} </main> - <footer class="py-12 max-w-7xl mx-auto sm:px-6 lg:px-8"> - <div class="ml-4 text-center text-sm text-gray-500 dark:text-gray-400 sm:text-right sm:ml-0"> + <footer class="py-6 max-w-7xl mx-auto sm:px-6 lg:px-8 border-t-2 border-slate-700"> + <div class="ml-4 text-center text-sm text-gray-700 dark:text-gray-400 sm:text-right sm:ml-0"> Laravel v{{ Illuminate\Foundation\Application::VERSION }} (PHP v{{ PHP_VERSION }}) </div> </footer> </div> + @vite(['resources/js/app.js']) </body> </html> diff --git a/resources/views/layouts/guest.blade.php b/resources/views/layouts/guest.blade.php @@ -5,11 +5,12 @@ <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="csrf-token" content="{{ csrf_token() }}"> + <meta property="csp-nonce" content="{{ csp_nonce() }}"> <title>{{ config('app.name', 'Home ERP') }}</title> <!-- Scripts --> - @vite(['resources/css/app.css', 'resources/js/app.js']) + @vite(['resources/css/app.css']) </head> <body class="font-sans text-gray-900 antialiased"> @@ -26,11 +27,12 @@ </main> <footer class="py-12 max-w-7xl mx-auto sm:px-6 lg:px-8"> - <div class="ml-4 text-center text-sm text-gray-500 dark:text-gray-400 sm:text-right sm:ml-0"> + <div class="ml-4 text-center text-sm text-gray-700 dark:text-gray-400 sm:text-right sm:ml-0"> Laravel v{{ Illuminate\Foundation\Application::VERSION }} (PHP v{{ PHP_VERSION }}) </div> </footer> </div> + @vite(['resources/js/app.js']) </body> </html> diff --git a/resources/views/livewire/dashboard/overview.blade.php b/resources/views/livewire/dashboard/overview.blade.php @@ -0,0 +1,144 @@ +<?php + +use function Livewire\Volt\{state}; +use Livewire\Attributes\Rule; +use App\Models\Room; +use Livewire\Volt\Component; +use Livewire\WithPagination; + +new class extends Component { + use WithPagination; + + #[Rule(['required', 'string'])] + public string $roomname = ''; + + #[Rule(['required', 'string'])] + public string $description = ''; + + public function createRoom(): void + { + $this->validate(); + $newRoom = Room::create([ + 'name' => $this->roomname, + 'description' => $this->description, + ]); + session()->flash('uuid', $newRoom->id); + } + + public function with(): array + { + return [ + 'rooms' => Room::cursorPaginate(10), + ]; + } +}; ?> + +<section class="space-y-6"> + <header class="flex item justify-between"> + <div> + <h2 class="text-lg font-medium text-gray-900 dark:text-gray-100"> + {{ __('Rooms') }} + </h2> + + <p class="mt-1 text-sm text-gray-600 dark:text-gray-400"> + {{ __('The rooms in your house') }} + </p> + </div> + + <button x-on:click.prevent="$dispatch('open-modal', 'create-room')" + class="px-4 py-2 bg-gray-800 dark:bg-gray-200 border border-transparent rounded-md font-semibold text-xs text-white dark:text-gray-800 uppercase tracking-widest hover:bg-gray-700 dark:hover:bg-white focus:bg-gray-700 dark:focus:bg-white active:bg-gray-900 dark:active:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150"> + {{ __('Create Room') }} + </button> + </header> + + + <x-modal name="create-room" :show="$errors->isNotEmpty()" focusable> + <form wire:submit="createRoom" class="p-6"> + @if (session('uuid')) + <h2 class="text-lg font-medium text-gray-900 dark:text-gray-100"> + {{ __('Room successfully created') }} + </h2> + <div class="mt-6"> + <!-- TODO: Allow writing to the nfc tag directly --> + <p class="mr-3 text-sm text-gray-800 dark:text-gray-200"> + {{ __('tokens.uuid', ['uuid' => session('uuid')]) }} + </p> + </div> + <div class="mt-6 flex justify-end items-center"> + + <x-secondary-button x-on:click="$dispatch('close')"> + {{ __('Close') }} + </x-secondary-button> + </div> + @else + <h2 class="text-lg font-medium text-gray-900 dark:text-gray-100"> + {{ __('Create Room') }} + </h2> + <div class="mt-6"> + <x-input-label for="roomname" value="{{ __('Roomname') }}" class="sr-only" /> + + <x-text-input wire:model="roomname" id="roomname" name="roomname" type="text" + class="mt-1 block w-full" placeholder="{{ __('Roomname') }}" /> + + <x-input-error :messages="$errors->get('roomname')" class="mt-2" /> + </div> + + <div class="mt-3"> + <x-input-label for="description" value="{{ __('Description') }}" class="sr-only" /> + + <x-text-input wire:model="description" id="description" name="description" type="text" + class="mt-1 block w-full" placeholder="{{ __('Description') }}" /> + + <x-input-error :messages="$errors->get('description')" class="mt-2" /> + </div> + <div class="mt-6 flex justify-end"> + <x-secondary-button x-on:click="$dispatch('close')"> + {{ __('Cancel') }} + </x-secondary-button> + + <x-primary-button class="ml-3"> + {{ __('Create Room') }} + </x-primary-button> + </div> + @endif + </form> + </x-modal> + + @if ($rooms->items() > 0) + <table class="table-fixed w-full border-separate border-spacing-0 rounded-lg text-sm"> + <thead class="bg-gray-700 font-medium text-slate-300 dark:text-slate-200 text-left"> + <tr> + <th class="border-b dark:border-slate-600 p-4 pl-8 pt-3 pb-3"> + {{ __('Name') }} + </th> + <th class="border-b dark:border-slate-600 p-4 pl-8 pt-3 pb-3"> + {{ __('Description') }} + </th> + <th class="border-b dark:border-slate-600 p-4 pl-8 pt-3 pb-3"> + {{ __('UUID') }} + </th> + </tr> + </thead> + <tbody class="bg-white dark:bg-gray-900 text-slate-700 dark:text-slate-400"> + @foreach ($rooms as $room) + <tr> + <td class="border-b border-slate-100 dark:border-slate-700 p-4 pl-8"> + {{ $room->name }} + </td> + <td class="border-b border-slate-100 dark:border-slate-700 p-4 pl-8"> + {{ $room->description }} + </td> + <td class="border-b border-slate-100 dark:border-slate-700 p-4 pl-8"> + {{ $room->id }} + </td> + </tr> + @endforeach + </tbody> + </table> + {{ $rooms->links() }} + @else + <p class="mt-1 text-base text-gray-800 dark:text-gray-200"> + {{ __('No rooms found. Please create a new Room') }} + </p> + @endif +</section> diff --git a/resources/views/livewire/layout/navigation.blade.php b/resources/views/livewire/layout/navigation.blade.php @@ -2,11 +2,12 @@ use Livewire\Volt\Component; -new class extends Component -{ +new class extends Component { public function logout(): void { - auth()->guard('web')->logout(); + auth() + ->guard('web') + ->logout(); session()->invalidate(); session()->regenerateToken(); @@ -39,12 +40,17 @@ new class extends Component <div class="hidden sm:flex sm:items-center sm:ml-6"> <x-dropdown align="right" width="48"> <x-slot name="trigger"> - <button class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 hover:text-gray-700 dark:hover:text-gray-300 focus:outline-none transition ease-in-out duration-150"> - <div x-data="{ name: '{{ auth()->user()->name }}' }" x-text="name" x-on:profile-updated.window="name = $event.detail.name"></div> + <button + class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 hover:text-gray-700 dark:hover:text-gray-300 focus:outline-none transition ease-in-out duration-150"> + <div x-data="{ name: '{{ auth()->user()->name }}' }" x-text="name" + x-on:profile-updated.window="name = $event.detail.name"></div> <div class="ml-1"> - <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"> - <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" /> + <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 20 20"> + <path fill-rule="evenodd" + d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" + clip-rule="evenodd" /> </svg> </div> </button> @@ -67,10 +73,14 @@ new class extends Component <!-- Hamburger --> <div class="-mr-2 flex items-center sm:hidden"> - <button @click="open = ! open" class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 dark:text-gray-500 hover:text-gray-500 dark:hover:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-900 focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-900 focus:text-gray-500 dark:focus:text-gray-400 transition duration-150 ease-in-out"> + <button @click="open = ! open" + class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 dark:text-gray-500 hover:text-gray-500 dark:hover:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-900 focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-900 focus:text-gray-500 dark:focus:text-gray-400 transition duration-150 ease-in-out"> <svg class="h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24"> - <path :class="{'hidden': open, 'inline-flex': ! open }" class="inline-flex" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> - <path :class="{'hidden': ! open, 'inline-flex': open }" class="hidden" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> + <path :class="{ 'hidden': open, 'inline-flex': !open }" class="inline-flex" + stroke-linecap="round" stroke-linejoin="round" stroke-width="2" + d="M4 6h16M4 12h16M4 18h16" /> + <path :class="{ 'hidden': !open, 'inline-flex': open }" class="hidden" stroke-linecap="round" + stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> </svg> </button> </div> @@ -78,7 +88,7 @@ new class extends Component </div> <!-- Responsive Navigation Menu --> - <div :class="{'block': open, 'hidden': ! open}" class="hidden sm:hidden"> + <div :class="{ 'block': open, 'hidden': !open }" class="hidden sm:hidden"> <div class="pt-2 pb-3 space-y-1"> <x-responsive-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')" wire:navigate> {{ __('Dashboard') }} @@ -88,8 +98,9 @@ new class extends Component <!-- Responsive Settings Options --> <div class="pt-4 pb-1 border-t border-gray-200 dark:border-gray-600"> <div class="px-4"> - <div class="font-medium text-base text-gray-800 dark:text-gray-200" x-data="{ name: '{{ auth()->user()->name }}' }" x-text="name" x-on:profile-updated.window="name = $event.detail.name"></div> - <div class="font-medium text-sm text-gray-500">{{ auth()->user()->email }}</div> + <div class="font-medium text-base text-gray-800 dark:text-gray-200" x-data="{ name: '{{ auth()->user()->name }}' }" + x-text="name" x-on:profile-updated.window="name = $event.detail.name"></div> + <div class="font-medium text-sm text-gray-800">{{ auth()->user()->email }}</div> </div> <div class="mt-3 space-y-1">