{"id":31952977,"url":"https://github.com/elishamutang/saas-jokes-api","last_synced_at":"2026-04-16T18:36:55.497Z","repository":{"id":316882538,"uuid":"1065205713","full_name":"elishamutang/saas-jokes-api","owner":"elishamutang","description":"REST API for Jokes Management System built using Laravel","archived":false,"fork":false,"pushed_at":"2025-10-05T07:55:23.000Z","size":688,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-05T09:19:12.076Z","etag":null,"topics":["laravel","laravel-sanctum","php","rest-api","test-driven-development"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elishamutang.png","metadata":{"files":{"readme":"ReadMe-Development-Log.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-27T09:01:45.000Z","updated_at":"2025-10-05T07:55:27.000Z","dependencies_parsed_at":"2025-09-27T11:26:34.882Z","dependency_job_id":"b3df617b-24f0-4774-8d81-a8782e6a6642","html_url":"https://github.com/elishamutang/saas-jokes-api","commit_stats":null,"previous_names":["elishamutang/saas-jokes-api"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/elishamutang/saas-jokes-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elishamutang%2Fsaas-jokes-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elishamutang%2Fsaas-jokes-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elishamutang%2Fsaas-jokes-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elishamutang%2Fsaas-jokes-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elishamutang","download_url":"https://codeload.github.com/elishamutang/saas-jokes-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elishamutang%2Fsaas-jokes-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279018705,"owners_count":26086608,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["laravel","laravel-sanctum","php","rest-api","test-driven-development"],"created_at":"2025-10-14T13:26:59.783Z","updated_at":"2025-10-14T13:27:01.647Z","avatar_url":"https://github.com/elishamutang.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Install Laravel installer \u0026 Update\n\n```shell≈\ncomposer global require laravel/installer\ncomposer global update\n```\n\n## Create Application from Scratch\n\n```shell\nlaravel new l12-base\n```\n\n| Step                  | Value    |\n|-----------------------|----------|\n| Project Name          | l12-base |\n| Starter Kit           | None     |\n| Test Framework        | Pest     |\n| Database (dev)        | SQLite   |\n| NPM install and Build | Yes      |\n\n## Add Sanctum, and other Packages\n\nWe will add:\n\n- [Laravel Breeze](https://laravel.com/docs/sanctum) (with Sanctum Authentication)\n- Laravel Pint (Code Tidy +)\n- [Laravel PHP Stan](https://github.com/larastan/larastan) (Static Testing)\n- [Laravel Debug Bar](https://laraveldebugbar.com) (Development toolbar)\n- [Laravel Livewire](https://livewire.laravel.com) (SPA components in PHP)\n- [Laravel Telescope](https://laravel.com/docs/telescope) (Application Monitoring)\n\nNote that with Windows Systems not having the `pcntl` extension for PHP we cannot install Laravel Pail.\n\nFor non Windows users, or those using Windows Subsystem for Linux, please feel free to install and use Laravel Pail, a\nlog streaming package.\n\n---\n\n### Installing Breeze\n\n```shell\ncd l12-base\n\ncomposer require laravel/breeze\n\nphp artisan breeze:install\n```\n\n| Step      | Value             |\n|-----------|-------------------|\n| Framework | Blade with Alpine |\n| Dark Mode | No                |\n| Testing   | Pest              |\n\n#### Remove the postcss.config.js\n\n```shell\nrm postconfig.config.js\n```\n\n#### Add FontAwesome NPM Package\n\n```shell\nnpm install @forawesome/fontawesome-free\nnpm update\n```\n\n#### Update any node dependencies\n\n```shell\nnpm update\n```\n\n#### Update the following files:\n\n- vite.config.js\n- tailwind.config.js\n- resources/css/app.css\n- resources/js/app.js\n\n##### vite.config.js\n\nOpen the `vite.config.js` file and update the contents to be:\n\n```js\nimport {defineConfig} from 'vite';\nimport laravel from 'laravel-vite-plugin';\nimport tailwindcss from '@tailwindcss/vite';\n\nexport default defineConfig({\n    plugins: [\n        laravel({\n            input: ['resources/css/app.css', 'resources/js/app.js'],\n            refresh: true,\n        }),\n        tailwindcss(),\n    ]\n});\n```\n\n##### tailwind.config.js\n\nOpen the `tailwind.config.js` file and update the contents to be:\n\n```js\nimport defaultTheme from 'tailwindcss/defaultTheme';\nimport forms from '@tailwindcss/forms';\n\n/** @type {import('tailwindcss').Config} */\nexport default {\n    content: [\n        './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',\n        './storage/framework/views/*.php',\n        './resources/views/**/*.blade.php',\n    ],\n\n    theme: {\n        extend: {\n            fontFamily: {\n                sans: ['Figtree', ...defaultTheme.fontFamily.sans],\n            },\n        },\n    },\n\n    plugins: [forms],\n};\n```\n\n##### resources/css/app.css\n\nOpen the `resources/css/app.css` file and update the contents to be:\n\n```css\n@import 'tailwindcss';\n@import \"@fortawesome/fontawesome-free/css/all.css\";\n\n@theme {\n    --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',\n    'Segoe UI Symbol', 'Noto Color Emoji';\n}\n```\n\n##### resources/js/app.js\n\nOpen the `resources/js/app.js` file and update the contents to be:\n\n```js\nimport './bootstrap';\n```\n\n---\n\n### Install Laravel Pint (Code Tidy +)\n\nInstall the composer package for \"development mode only\":\n\n```shell\ncomposer require laravel/pint --dev\n```\n\n---\n\n### Install Laravel Stan (Static Testing)\n\nInstall the composer package for \"development mode only\",\nand create new file `phpstan.neon` in the root folder of the project:\n\n```shell\ncomposer require --dev \"larastan/larastan\"\n\ntouch phpstan.neon\n```\n\nEdit the `phpstan.neon` (this is a YAML style file) and add:\n\n```neon\nincludes:\n    - vendor/larastan/larastan/extension.neon\n    - vendor/nesbot/carbon/extension.neon\n\nparameters:\n\n    paths:\n        - app/\n\n    # Level 10 is the highest level\n    level: 5\n\n#    ignoreErrors:\n#        - '#PHPDoc tag @var#'\n#\n#    excludePaths:\n#        - ./*/*/FileToBeExcluded.php\n```\n\n---\n\n### Install Laravel Debug Bar (Development toolbar)\n\nInstall the composer package for \"development mode only\":\n\n```shell\ncomposer require barryvdh/laravel-debugbar --dev\n```\n\n---\n\n### Install Laravel Livewire (SPA components in PHP)\n\nInstall Livewire and publish its assets:\n\n```shell\ncomposer require livewire/livewire\n\nphp artisan vendor:publish --tag=livewire:assets --ansi --force\n```\n\n---\n\n### Install Laravel Telescope (Application Monitoring)\n\n```shell\ncomposer require laravel/telescope\nphp artisan telescope:install\nphp artisan migrate\n```\n\n## Publish Assets (Error messages, pagination et al.)\n\nWe will publish a number of assets so that they may be customized as we write our code.\n\n```shell\nphp artisan vendor:publish --tag=laravel-errors\nphp artisan vendor:publish --tag=laravel-mail\nphp artisan vendor:publish --tag=laravel-pagination\nphp artisan vendor:publish --tag=livewire:pagination\n```\n\n### Execute First Static Analysis\n\nRun PHPStan using:\n\n```shell\n./vendor/bin/phpstan analyse --memory-limit=2G\n```\n\n\u003e ###### Note:\n\u003e\n\u003e The memory limit of 2GB is needed, the default 128MB is simply not enough for\n\u003e analysing Laravel Apps.\n\n\nAny errors? Fix them at this point.\n\n#### Example PhpStan Output\n\n```text\nNote: Using configuration file C:\\Users\\goulda\\Source\\Repos\\l12-base\\phpstan.neon.\n 104/104 [============================] 100%\n\n ------ ---------------------------------------------------------------------------\n  Line   app\\Http\\Controllers\\StaticPageController.php\n ------ ---------------------------------------------------------------------------\n  22     Method App\\Http\\Controllers\\StaticPageController::about() should return\n         Illuminate\\View\\View but return statement is missing.\n  27     Method App\\Http\\Controllers\\StaticPageController::contact() should return\n         Illuminate\\View\\View but return statement is missing.\n  32     Method App\\Http\\Controllers\\StaticPageController::privacy() should return\n         Illuminate\\View\\View but return statement is missing.\n  37     Method App\\Http\\Controllers\\StaticPageController::terms() should return\n         Illuminate\\View\\View but return statement is missing.\n ------ ---------------------------------------------------------------------------\n\n [ERROR] Found 4 errors\n\n```\n\n\n\n#### Must Verify Email Error\n\nThe following is a fix we discovered, **BUT** it is important **NOT** to use this for **EVERY** error\nyou encounter, as that defeats the purpose of the static analysis:\n\nOpen the `app/Http/Controllers/Auth/VerifyEmailController.php` file and locate the lines:\n\n```php\n        if ($request-\u003euser()-\u003emarkEmailAsVerified()) {\n            event(new Verified($request-\u003euser()));\n        }\n```\n\nAdd a single line as shown below:\n\n```php\n        if ($request-\u003euser()-\u003emarkEmailAsVerified()) {\n        /** @phpstan-ignore-next-line  */\n            event(new Verified($request-\u003euser()));\n        }\n```\n\n\u003e ###### Aside:\n\u003e\n\u003e We may need to see of Taylor and the Laravel crew will look\n\u003e at this error and publish a patch.\n\n### Execute First Laravel Pint\n\nExecute Laravel Pint to fix any code structure errors.\n\nThis will ensure your code matches the Laravel style.\n\n```shell\n./vendor/bin/pint\n```\n\n### Add New Environment Variable\n\nOpen the `.env` file and between the `APP_URL` and `APP_LOCALE` add the `APP_VERSION` (also update the Locale to `en_AU`\nas shown):\n\n```ini\nAPP_URL = http://localhost:8000\n\nAPP_VERSION = \"0.0 α\"\n\nAPP_LOCALE = en_AU\n```\n\n## Execute the Development Instance\n\nWe can run a development server in a number of different ways.\n\nFor this we will use the Terminal and execute the \"dev\" server script.\n\nEither:\nSplit the current terminal into 2 halves, or\nOpen a new terminal instance\n\nVerify you are in the correct folder, if not use the cd command:\n\n\u003e This presumes you are in a folder location such as `Source/Repos`.\n\n```shell\ncd l12-base\ncomposer run dev\n```\n\nThis will execute the dev script that is in the `composer.json` file.\n\nAfter a few moments, you will be able to open the `http://localhost:8000` location in a\nbrowser and see the default home page:\n\n![img.png](_docs/images/default-landing-page.png)\n\n## Adding Default Users\n\nTo make it easier to test the application we will add a \"seeder\" that will fill the database\nwith some default users.\n\nThis is ideal for the development and testing process.\n\n### Create a User Seeder\n\nExecute:\n\n```shell\nphp artisan make:seeder UserSeeder\n```\n\nOpen the newly created `database/seeders/UserSeeder.php` file and update the `run` method to\nread:\n\n```php\n$seedUsers = [           \n    [\n        'id' =\u003e 99,\n        'name' =\u003e 'Super Admin',\n        'email' =\u003e 'supervisor@example.com',\n        'password' =\u003e 'Password1',\n        'email_verified_at' =\u003e now(),\n        'roles' =\u003e ['super-user', 'admin',],\n        'permissions' =\u003e [],\n    ],\n\n    [\n        'id' =\u003e 100,\n        'name' =\u003e 'Admin I Strator',\n        'email' =\u003e 'admin@example.com',\n        'password' =\u003e 'Password1',\n        'email_verified_at' =\u003e now(),\n        'roles' =\u003e ['admin',],\n        'permissions' =\u003e [],\n    ],\n\n    [\n        'id' =\u003e 200,\n        'name' =\u003e 'Staff User',\n        'email' =\u003e 'staff@example.com',\n        'password' =\u003e 'Password1',\n        'email_verified_at' =\u003e now(),\n        'roles' =\u003e ['staff',],\n        'permissions' =\u003e [],\n    ],\n\n    [\n        'id' =\u003e 300,\n        'name' =\u003e 'Client User',\n        'email' =\u003e 'client@example.com',\n        'password' =\u003e 'Password1',\n        'email_verified_at' =\u003e now(),\n        'roles' =\u003e ['client',],\n        'permissions' =\u003e [],\n    ],\n\n    [\n        'id' =\u003e 301,\n        'name' =\u003e 'Client User II',\n        'email' =\u003e 'client2@example.com',\n        'password' =\u003e 'Password1',\n        'email_verified_at' =\u003e null,\n        'roles' =\u003e ['client',],\n        'permissions' =\u003e [],\n    ],\n\n    [\n        'id' =\u003e 302,\n        'name' =\u003e 'Client User III',\n        'email' =\u003e 'client3@example.com',\n        'password' =\u003e 'Password1',\n        'email_verified_at' =\u003e null,\n        'roles' =\u003e ['client',],\n        'permissions' =\u003e [],\n    ],\n        ];\n\nforeach ($seedUsers as $newUser) {\n\n    // grab the roles \u0026 additional permissions from the seed users\n    $roles = $newUser['roles'];\n    unset($newUser['roles']);\n    \n    $permissions = $newUser['permissions'];\n    unset($newUser['permissions']);\n    \n    $user = User::updateOrCreate(\n        ['id' =\u003e $newUser['id']],\n        $newUser\n    );\n    \n    // Uncomment these lines when using Spatie Permissions, to\n    // assign the role and additional permissions to the users:\n    // $user-\u003eassignRole($roles);\n    // $user-\u003eassignPermissions($permissions);\n\n}\n\n// Uncomment the line below to create (10) randomly named users using the User Factory.\n// User::factory(10)-\u003ecreate();\n```\n\nTo run this seeder only we can use:\n\n```shell\nphp artisan db:seed UserSeeder\n```\n\nTo add the seeder to execute when performing a fresh migration and seed use:\n\nEdit the `database/migrations/DatabaseSeeder.php` file, and update the code tobe:\n\n```php\n    public function run(): void\n    {\n\n        $this-\u003ecall(\n            [\n                // When using Spatie Permissions, perform the Role / Permission seeding FIRST\n                UserSeeder::class,\n                // Add further seeder classes here                \n            ]\n        );\n\n    }\n```\n\n\u003e ### ⚠️ WARNING:\n\u003e\n\u003e This performs a total database reset and SHOULD NOT be used on production applications.\n\u003e\n\u003e\n\u003e To execute this and reset the database and any logged-in sessions in one go use:\n\u003e\n\u003e ```shell\n\u003e php artisan migrate:fresh --seed\n\u003e ```\n\n## Add Static page Controller\n\nWe will creat a static page controller that will handle pages that do not perform any\nadd/edit/delete actions.\n\nGenerally, we look at these pages being:\n\n- Home (Welcome)\n- Privacy\n- License\n- About\n- Contact Us\n- Terms\n\nand so on.\n\nCreate the static page controller using:\n\n```shell\nphp artisan make:controller StaticPageController\n```\n\n\u003e ###### Important:\n\u003e\n\u003e Always name controllers with `Controller` as the last word in the name.\n\n### Add the Static Page Methods to the Controller\n\nOpen the new `app/Http/Controllers/StatsicPageController.php` file and add the following\nstatic page methods:\n\n```php\n    /**\n     * Display site 'Welcome/Index' page\n     * \n     * @return View\n     */\n    public function home(): View\n    {\n        return view('static.welcome');\n    }\n\n    /**\n     * Display 'About Us' page\n     * \n     * @return View\n     */\n    public function about(): View\n    {\n        // return view('static.about');\n    }\n```\n\n### Edit the Routes\n\nOpen the `routes/web.php` file and update it..\n\nAdd the required `use` lines:\n\n```php\nuse App\\Http\\Controllers\\DashboardController;\nuse App\\Http\\Controllers\\ProfileController;\nuse App\\Http\\Controllers\\StaticPageController;\nuse Illuminate\\Support\\Facades\\Route;\n```\n\nUpdate the Home (Welcome) page route\n\n```php\n\nRoute::get('/', [StaticPageController::class, 'home'])\n    -\u003ename('home');\n\nRoute::middleware(['auth', 'verified'])-\u003egroup(function () {\n    Route::get('/dashboard', [DashboardController::class, 'dashboard'])\n        -\u003ename('dashboard');\n});\n\nRoute::middleware('auth')-\u003egroup(function () {\n    Route::get('/profile', [ProfileController::class, 'edit'])-\u003ename('profile.edit');\n    Route::patch('/profile', [ProfileController::class, 'update'])-\u003ename('profile.update');\n    Route::delete('/profile', [ProfileController::class, 'destroy'])-\u003ename('profile.destroy');\n});\n\nrequire __DIR__ . '/auth.php';\n```\n\n## Test USers\n\nFor this template, we have the following test users:\n\n| Name            | Username               | Password  | Role        | Verified |\n|-----------------|------------------------|-----------|-------------|----------|\n| Super Admin     | supervisor@example.com | Password1 | Super-Admin | Y        |\n| Admin I Strator | admin@example.com      | Password1 | Admin       | Y        |\n| Staff User      | staff@example.com      | Password1 | Staff       | Y        |\n| Client User     | client@example.com     | Password1 | Client      | Y        |\n| Client User II  | client2@example.com    | Password1 | Client      | N        |\n| Client User III | client3@example.com    | Password1 | Client      | N        |\n\n### Create a Dashboard Controller:\n\n```shell\nphp artisan make DashboardController\n```\n\nEdit the new `app/Http/Controllers/DashboardController.php` file, adding the missing lines\nfrom the code below:\n\n```php\nclass DashboardController extends Controller\n{\n\n    public function dashboard(): View\n    {\n        $user = auth()-\u003euser();\n\n        return view('static.dashboard')\n            -\u003ewith('user', $user);\n    }\n}\n\n```\n\nWe updated the dashboard route in the previous step.\n\n## Admin Page Layout\n\n- Create Admin Layout Component\n- Move the view to resource/views/layout and rename to admin.blade.php\n- Create an Admin Page Controller\n- Create Admin Home page view\n- Create Admin Navigation layout view\n- Create admin route in routes/web.php\n\n```shell\nphp artisan make:component AdminLayout\n\nmv resources/views/components/admin-layout.blade.php resources/views/layout/admin.blade.php\n\nphg artisan make:controller Admin/AdminController\n\nmkdir resources/views/admin\ntouch resources/views/admin/index.blade.php\ntouch resources/views/layouts/admin-navigation.blade.php\n```\n\n#### Admin Page Layout\n\nIn the `admin/index.blade.php` file add:\n\n```php\n\u003cx-admin-layout\u003e\n    \u003cx-slot name=\"header\"\u003e\n        \u003ch2 class=\"font-semibold text-xl text-white leading-tight\"\u003e\n            {{ __('Admin Zone') }}\n        \u003c/h2\u003e\n    \u003c/x-slot\u003e\n\n    \u003csection class=\"py-12 mx-12 space-y-4\"\u003e\n\n        \u003cheader\u003e\n            \u003ch3 class=\"text-2xl font-bold text-zinc-700\"\u003e\n                {{__('Statistics')}}\n            \u003c/h3\u003e\n        \u003c/header\u003e\n\n        \u003cdiv class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\"\u003e\n            \u003carticle\n                class=\"items-center rounded-lg bg-white shadow hover:shadow-none align-middle hover:bg-zinc-700 transition duration-500 group overflow-hidden border border-zinc-700/75\"\u003e\n                \u003cdiv class=\"flex\"\u003e\n                    \u003cheader\n                        class=\"w-1/4 bg-zinc-700 text-white  flex items-center justify-center py-6 transition-colors duration-500\"\u003e\n                        \u003ci class=\"fa-solid fa-laugh-squint text-4xl group-hover:-rotate-45 duration-500 transition-transform\"\u003e\u003c/i\u003e\n                    \u003c/header\u003e\n\n                    \u003csection class=\"w-3/4 p-6 flex flex-col justify-center\"\u003e\n                        \u003cp class=\"text-2xl font-bold text-gray-800 group-hover:text-white mb-1 transition-colors duration-500\"\u003e\n                            1,234\n                        \u003c/p\u003e\n\n                        \u003cp class=\"text-gray-600 group-hover:text-white text-sm uppercase tracking-wide transition-colors duration-500\"\u003e\n                            {{ __('Jokes') }}\n                        \u003c/p\u003e\n                    \u003c/section\u003e\n                \u003c/div\u003e\n            \u003c/article\u003e\n\n            \u003carticle\n                class=\"items-center rounded-lg bg-white shadow hover:shadow-none align-middle hover:bg-zinc-700 transition-colors duration-500 group overflow-hidden border border-zinc-700/75\"\u003e\n                \u003cdiv class=\"flex\"\u003e\n                    \u003cheader\n                        class=\"w-1/4 bg-zinc-700 text-white  flex items-center justify-center py-6 transition-colors duration-500\"\u003e\n                        \u003ci class=\"fa-solid fa-list-check text-4xl group-hover:-rotate-12 duration-500 transition-transform\"\u003e\u003c/i\u003e\n                    \u003c/header\u003e\n\n                    \u003csection class=\"w-3/4 p-6 flex flex-col justify-center\"\u003e\n                        \u003cp class=\"text-2xl font-bold text-gray-800 group-hover:text-white mb-1 transition-colors duration-500\"\u003e\n                            65\n                        \u003c/p\u003e\n\n                        \u003cp class=\"text-gray-600 group-hover:text-white text-sm uppercase tracking-wide transition-colors duration-500\"\u003e\n                            {{ __('Categories') }}\n                        \u003c/p\u003e\n                    \u003c/section\u003e\n                \u003c/div\u003e\n            \u003c/article\u003e\n\n            \u003carticle\n                class=\"items-center rounded-lg bg-white shadow hover:shadow-none align-middle hover:bg-zinc-700 transition-colors duration-500 group overflow-hidden border border-zinc-700/75\"\u003e\n                \u003cdiv class=\"flex\"\u003e\n                    \u003cheader\n                        class=\"w-1/4 bg-zinc-700 text-white  flex items-center justify-center py-6 transition-colors duration-500\"\u003e\n                        \u003ci class=\"fa-solid fa-users text-4xl group-hover:-rotate-12 duration-500 transition-transform\"\u003e\u003c/i\u003e\n                    \u003c/header\u003e\n\n                    \u003csection class=\"w-3/4 p-6 flex flex-col justify-center\"\u003e\n                        \u003cp class=\"text-2xl font-bold text-gray-800 group-hover:text-white mb-1 transition-colors duration-500\"\u003e\n                            {{ $userCount }}\n                        \u003c/p\u003e\n\n                        \u003cp class=\"text-gray-600 group-hover:text-white text-sm uppercase tracking-wide transition-colors duration-500\"\u003e\n                            {{ __('Users') }}\n                        \u003c/p\u003e\n                    \u003c/section\u003e\n                \u003c/div\u003e\n            \u003c/article\u003e\n\n            \u003carticle\n                class=\"items-center rounded-lg bg-white shadow hover:shadow-none align-middle hover:bg-zinc-700 transition-colors duration-500 group overflow-hidden border border-zinc-700/75\"\u003e\n                \u003cdiv class=\"flex\"\u003e\n                    \u003cheader\n                        class=\"w-1/4 bg-zinc-700 text-white  flex items-center justify-center py-6 transition-colors duration-500\"\u003e\n                        \u003ci class=\"fa-solid fa-passport text-4xl group-hover:-rotate-12 duration-500 transition-transform\"\u003e\u003c/i\u003e\n                    \u003c/header\u003e\n\n                    \u003csection class=\"w-3/4 p-6 flex flex-col justify-center\"\u003e\n                        \u003cp class=\"text-2xl font-bold text-gray-800 group-hover:text-white mb-1 transition-colors duration-500\"\u003e\n                            674,865\n                        \u003c/p\u003e\n\n                        \u003cp class=\"text-gray-600 group-hover:text-white text-sm uppercase tracking-wide transition-colors duration-500\"\u003e\n                            {{ __('Passengers') }}\n                        \u003c/p\u003e\n                    \u003c/section\u003e\n                \u003c/div\u003e\n            \u003c/article\u003e\n\n            \u003carticle\n                class=\"items-center rounded-lg bg-white shadow hover:shadow-none align-middle hover:bg-zinc-700 transition-colors duration-500 group overflow-hidden border border-zinc-700/75\"\u003e\n                \u003cdiv class=\"flex\"\u003e\n                    \u003cheader\n                        class=\"w-1/4 bg-zinc-700 text-white  flex items-center justify-center py-6 transition-colors duration-500\"\u003e\n                        \u003ci class=\"fa-solid fa-user-secret text-4xl group-hover:-rotate-12 duration-500 transition-transform\"\u003e\u003c/i\u003e\n                    \u003c/header\u003e\n\n                    \u003csection class=\"w-3/4 p-6 flex flex-col justify-center\"\u003e\n                        \u003cp class=\"text-2xl font-bold text-gray-800 group-hover:text-white mb-1 transition-colors duration-500\"\u003e\n                            3\n                        \u003c/p\u003e\n\n                        \u003cp class=\"text-gray-600 group-hover:text-white text-sm uppercase tracking-wide transition-colors duration-500\"\u003e\n                            {{ __('Roles') }}\n                        \u003c/p\u003e\n                    \u003c/section\u003e\n                \u003c/div\u003e\n            \u003c/article\u003e\n\n            \u003carticle\n                class=\"items-center rounded-lg bg-white shadow hover:shadow-none align-middle hover:bg-zinc-700 transition-colors duration-500 group overflow-hidden border border-zinc-700/75\"\u003e\n                \u003cdiv class=\"flex\"\u003e\n                    \u003cheader\n                        class=\"w-1/4 bg-zinc-700 text-white  flex items-center justify-center py-6 transition-colors duration-500\"\u003e\n                        \u003ci class=\"fa-solid fa-earth-asia text-4xl group-hover:-rotate-12 duration-500 transition-transform\"\u003e\u003c/i\u003e\n                    \u003c/header\u003e\n\n                    \u003csection class=\"w-3/4 p-6 flex flex-col justify-center\"\u003e\n                        \u003cp class=\"text-2xl font-bold text-gray-800 group-hover:text-white mb-1 transition-colors duration-500\"\u003e\n                            23,567,890\n                        \u003c/p\u003e\n\n                        \u003cp class=\"text-gray-600 group-hover:text-white text-sm uppercase tracking-wide transition-colors duration-500\"\u003e\n                            {{ __('Unique Visitors') }}\n                        \u003c/p\u003e\n                    \u003c/section\u003e\n                \u003c/div\u003e\n            \u003c/article\u003e\n\n            \u003carticle\n                class=\"items-center rounded-lg bg-white shadow hover:shadow-none align-middle hover:bg-zinc-700 transition-colors duration-500 group overflow-hidden border border-zinc-700/75\"\u003e\n                \u003cdiv class=\"flex\"\u003e\n                    \u003cheader\n                        class=\"w-1/4 bg-zinc-700 text-white  flex items-center justify-center py-6 transition-colors duration-500\"\u003e\n                        \u003ci class=\"fa-solid fa-universal-access text-4xl group-hover:-rotate-12 duration-500 transition-transform\"\u003e\u003c/i\u003e\n                    \u003c/header\u003e\n\n                    \u003csection class=\"w-3/4 p-6 flex flex-col justify-center\"\u003e\n                        \u003cp class=\"text-2xl font-bold text-gray-800 group-hover:text-white mb-1 transition-colors duration-500\"\u003e\n                            219\n                        \u003c/p\u003e\n\n                        \u003cp class=\"text-gray-600 group-hover:text-white text-sm uppercase tracking-wide transition-colors duration-500\"\u003e\n                            {{ __('Logged In') }}\n                        \u003c/p\u003e\n                    \u003c/section\u003e\n                \u003c/div\u003e\n            \u003c/article\u003e\n\n        \u003c/div\u003e\n    \u003c/section\u003e\n\n    \u003csection class=\"mx-12 space-y-4\"\u003e\n\n        \u003cheader\u003e\n            \u003ch3 class=\"text-2xl font-bold text-zinc-700\"\u003e\n                {{__('System')}}\n            \u003c/h3\u003e\n        \u003c/header\u003e\n\n        \u003cdiv class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\"\u003e\n\n            \u003carticle\n                class=\"items-center rounded-lg bg-white shadow hover:shadow-none align-middle hover:bg-zinc-700 transition duration-500 group overflow-hidden border border-zinc-700/75\"\u003e\n                \u003cdiv class=\"flex\"\u003e\n                    \u003cheader\n                        class=\"w-1/4 bg-zinc-700 text-white  flex items-center justify-center py-6 transition-colors duration-500\"\u003e\n                        \u003ci class=\"fa-solid fa-info-circle text-4xl group-hover:-rotate-12 duration-500 transition-transform\"\u003e\u003c/i\u003e\n                    \u003c/header\u003e\n\n                    \u003csection class=\"w-3/4 p-6 flex flex-col justify-center\"\u003e\n                        \u003cp class=\"text-2xl font-bold text-gray-800 group-hover:text-white mb-1 transition-colors duration-500\"\u003e\n                            {{ env('APP_VERSION')??\"development\" }}\n                        \u003c/p\u003e\n\n                        \u003cp class=\"text-gray-600 group-hover:text-white text-sm uppercase tracking-wide transition-colors duration-500\"\u003e\n                            {{__('Version')}}\n                        \u003c/p\u003e\n                    \u003c/section\u003e\n                \u003c/div\u003e\n            \u003c/article\u003e\n\n            \u003cp style=\"background-color:#74fdc5\"\u003e\u003c/p\u003e\n            \u003carticle\n                class=\"items-center rounded-lg bg-white shadow hover:shadow-none align-middle hover:bg-zinc-700 transition duration-500 group overflow-hidden border border-zinc-700/75\"\u003e\n                \u003cdiv class=\"flex\"\u003e\n                    \u003cheader\n                        class=\"w-1/4 bg-zinc-700 text-white  flex items-center justify-center py-6 transition-colors duration-500\"\u003e\n                        \u003ci class=\"fa-solid fa-computer text-4xl group-hover:-rotate-12 duration-500 transition-transform\"\u003e\u003c/i\u003e\n                    \u003c/header\u003e\n\n                    \u003csection class=\"w-3/4 p-6 flex flex-col justify-center\"\u003e\n                        \u003cp class=\"text-2xl font-bold text-gray-800 group-hover:text-white mb-1 transition-colors duration-500\"\u003e\n                            {{ env('APP_ENV')??'Unknown' }}\n                        \u003c/p\u003e\n\n                        \u003cp class=\"text-gray-600 group-hover:text-white text-sm uppercase tracking-wide transition-colors duration-500\"\u003e\n                            {{__('Environment')}}\n                        \u003c/p\u003e\n                    \u003c/section\u003e\n                \u003c/div\u003e\n            \u003c/article\u003e\n\n        \u003c/div\u003e\n\n    \u003c/section\u003e\n\n\u003c/x-admin-layout\u003e\n\n\n```\n\n#### Admin Navigation Layout\n\nin the `admin/layouts/admin-navigation.blade.php` add:\n\n```php\n\u003cdiv class=\"flex h-screen flex-col justify-between border-e border-gray-100 bg-white\"\u003e\n    \u003cdiv class=\"px-0 py-4\"\u003e\n        \u003cp class=\"grid h-10 w-full place-content-center text-xs text-gray-600\"\u003e\n            \u003ca class=\"block\" href=\"{{route('home')}} \"\u003e\n                \u003cspan class=\"sr-only\"\u003eHome\u003c/span\u003e\n\n                \u003cx-application-logo\n                    class=\"w-14 h-14 fill-current text-gray-700 hover:text-teal-700 transition duration-350\"/\u003e\n            \u003c/a\u003e\n        \u003c/p\u003e\n\n        \u003csection class=\"mt-6 space-y-1\"\u003e\n\n            \u003cx-side-nav-link :href=\"route('admin.index')\" :active=\"request()-\u003erouteIs('admin.*')\"\u003e\n                \u003ci class=\"fa-solid fa-cog group-hover:text-zinc-500\"\u003e\u003c/i\u003e\n                {{ __('Admin Home') }}\n            \u003c/x-side-nav-link\u003e\n\n            \u003cx-side-nav-link :href=\"route('dashboard')\" :active=\"request()-\u003erouteIs('home')\"\u003e\n                \u003ci class=\"fa-solid fa-dashboard group-hover:text-zinc-500\"\u003e\u003c/i\u003e\n                {{ __('Dashboard') }}\n            \u003c/x-side-nav-link\u003e\n\n            \u003cdetails class=\"group [\u0026_summary::-webkit-details-marker]:hidden\"\u003e\n                \u003csummary\n                    class=\"flex cursor-pointer items-center justify-between px-4 py-2\n                           text-gray-500 hover:text-gray-700\n                            hover:bg-gray-200\n                            transition duration-150\"\n                \u003e\n                        \u003cspan class=\"text-sm font-medium hover:text-zinc-500 transition duration-150\"\u003e\n                            \u003ci class=\"fa-solid fa-users\"\u003e\u003c/i\u003e\n                            {{ __('Users') }}\n                        \u003c/span\u003e\n\n                    \u003cspan class=\"shrink-0 transition duration-300 group-open:-rotate-180\"\u003e\n                          \u003ci class=\"fa-solid fa-chevron-down text-sm\"\u003e\u003c/i\u003e\n                        \u003c/span\u003e\n                \u003c/summary\u003e\n\n                \u003csection class=\"mt-2 space-y-1\"\u003e\n\n                        \u003cx-side-nav-link :href=\"route('home')\" :active=\"request()-\u003erouteIs('home')\" class=\"px-12 py-2\"\u003e\n                            {{ __('Accounts') }}\n                        \u003c/x-side-nav-link\u003e\n\n                        \u003cx-side-nav-link :href=\"route('home')\" :active=\"request()-\u003erouteIs('home')\" class=\"px-12 py-2\"\u003e\n                            {{ __('Suspended') }}\n                        \u003c/x-side-nav-link\u003e\n\n                        \u003cx-side-nav-link :href=\"route('home')\" :active=\"request()-\u003erouteIs('home')\" class=\"px-12 py-2\"\u003e\n                            {{ __('Banned Users') }}\n                        \u003c/x-side-nav-link\u003e\n\n                \u003c/section\u003e\n\n            \u003c/details\u003e\n\n            \u003cx-side-nav-link :href=\"route('home')\" :active=\"request()-\u003erouteIs('home')\"\u003e\n                \u003ci class=\"fa-solid fa-laugh group-hover:text-zinc-500\"\u003e\u003c/i\u003e\n                {{ __('Jokes') }}\n            \u003c/x-side-nav-link\u003e\n\n            \u003cx-side-nav-link :href=\"route('home')\" :active=\"request()-\u003erouteIs('home')\"\u003e\n                \u003ci class=\"fa-solid fa-cat group-hover:text-zinc-500\"\u003e\u003c/i\u003e\n                {{ __('Categories') }}\n            \u003c/x-side-nav-link\u003e\n\n            \u003cdetails class=\"group [\u0026_summary::-webkit-details-marker]:hidden\"\u003e\n                \u003csummary\n                    class=\"flex cursor-pointer items-center justify-between px-4 py-2\n                         text-gray-500 hover:text-gray-700\n                         hover:bg-gray-200\n                         transition duration-150\"\n                \u003e\n                        \u003cspan class=\"text-sm font-medium hover:text-zinc-500 transition duration-150\"\u003e\n                            \u003ci class=\"fa-solid fa-shield\"\u003e\u003c/i\u003e\n                            {{ __('Security') }}\n                        \u003c/span\u003e\n\n                    \u003cspan class=\"shrink-0 transition duration-300 group-open:-rotate-180\"\u003e\n                          \u003ci class=\"fa-solid fa-chevron-down text-sm\"\u003e\u003c/i\u003e\n                        \u003c/span\u003e\n                \u003c/summary\u003e\n\n                \u003csection class=\"mt-2 space-y-1\"\u003e\n                    \u003cx-side-nav-link :href=\"route('home')\" :active=\"request()-\u003erouteIs('home')\" class=\"px-12 py-2\"\u003e\n                        {{ __('Roles') }}\n                    \u003c/x-side-nav-link\u003e\n\n                    \u003cx-side-nav-link :href=\"route('home')\" :active=\"request()-\u003erouteIs('home')\" class=\"px-12 py-2\"\u003e\n                        {{ __('Permissions') }}\n                    \u003c/x-side-nav-link\u003e\n                \u003c/section\u003e\n\n            \u003c/details\u003e\n\n            \u003cx-side-nav-link :href=\"route('home')\" :active=\"request()-\u003erouteIs('home')\"\u003e\n                \u003ci class=\"fa-solid fa-plane-arrival group-hover:text-zinc-500\"\u003e\u003c/i\u003e\n                {{ __('Link X') }}\n            \u003c/x-side-nav-link\u003e\n\n        \u003c/section\u003e\n    \u003c/div\u003e\n\n    \u003csection class=\"sticky inset-x-0 bottom-0 border-t border-gray-200\"\u003e\n\n        \u003c!-- Authentication --\u003e\n        \u003cform method=\"POST\" action=\"{{ route('logout') }}\"\u003e\n            @csrf\n\n            \u003ca\n                class=\"block px-4 py-2 [text-align:_inherit] text-sm font-medium text-gray-500 hover:bg-gray-100 hover:text-gray-700\"\n                href=\"{{ route('logout') }}\"\n                onclick=\"event.preventDefault();\n                                                this.closest('form').submit();\"\u003e\n                \u003ci class=\"fa-solid fa-sign-out group-hover:text-zinc-500\"\u003e\u003c/i\u003e\n\n                {{ __('Log Out') }}\n            \u003c/a\u003e\n        \u003c/form\u003e\n\n        \u003ca href=\"#\" class=\"flex items-center gap-2 bg-white p-4 hover:bg-gray-50\"\u003e\n            \u003cdiv\n                class=\"bg-gray-500 text-gray-300 w-10 h-10 rounded-lg flex items-center justify-center font-bold text-md\"\u003e\n                AIM\n            \u003c/div\u003e\n\n            \u003cdiv\u003e\n                \u003cp class=\"text-xs\"\u003e\n                    \u003cstrong class=\"block font-medium\"\u003eAdmin Istrator\u003c/strong\u003e\n\n                    \u003cspan\u003e admin@example.com \u003c/span\u003e\n                \u003c/p\u003e\n            \u003c/div\u003e\n        \u003c/a\u003e\n    \u003c/section\u003e\n\u003c/div\u003e\n\n```\n\n\u003e #### ℹ️ Remember \n\u003e \n\u003e The repository will always have the most up-to-date version of the template code.\n\n#### Side Nav Link Component\n\nCreate a new nav component using:\n\n```shell\ntouch resources/views/components/side-nav-link.blade.php\n```\n\nAdd the following:\n\n```php\n@props(['active'])\n\n@php\n    $classes = ($active ?? false)\n                ? 'block px-4 py-2 text-sm font-medium\n                   text-gray-500 hover:text-gray-700\n                   hover:bg-gray-200\n                   focus:border-indigo-700\n                   focus:outline-none\n                   transition duration-250 ease-in-out'\n                : 'block px-4 py-2 text-sm font-medium\n                   text-gray-500 hover:text-gray-700 focus:text-gray-700\n                   hover:bg-gray-200\n                   hover:border-gray-300 focus:border-gray-300\n                   focus:outline-none\n                   transition duration-250 ease-in-out';\n@endphp\n\n\u003ca\n    {{ $attributes-\u003emerge(['class' =\u003e $classes]) }}\n\u003e\n    {{ $slot }}\n\u003c/a\u003e\n\n```\n\nEdit the `routes/web.php` file, and find the lines:\n\n```php\n\nRoute::middleware('auth')-\u003egroup(function () {\n    Route::get('/profile', [ProfileController::class, 'edit'])-\u003ename('profile.edit');\n    Route::patch('/profile', [ProfileController::class, 'update'])-\u003ename('profile.update');\n    Route::delete('/profile', [ProfileController::class, 'destroy'])-\u003ename('profile.destroy');\n});\n```\n\nImmediately BEFORE this, add:\n\n```php\nRoute::middleware(['auth', 'verified'])\n    -\u003eprefix('admin')\n    -\u003ename('admin.')\n    -\u003egroup(function () {\n        Route::get('/', [AdminController::class, 'index'])-\u003ename('index');\n    });\n```\n\n### Run Pint\n\nExecute Laravel Pint to tidy code:\n\n```shell\n  ./vendor/bin/pint\n```\n\nExample of output, actually run on this code:\n\n```text\n  ✓........✓.✓.✓..........................✓✓...✓...........\n\n  ───────────────────────────────────────────────────────────────────────── Laravel\n    FIXED   ........................................ 57 files, 7 style issues fixed\n  ✓ app\\Http\\Controllers\\Admin\\AdminController.php method_argument_space, no_unuse…\n  ✓ app\\Http\\Controllers\\Auth\\VerifyEmailController.php               phpdoc_indent\n  ✓ app\\Http\\Controllers\\DashboardController.php class_attributes_separation, no_u…\n  ✓ app\\Http\\Controllers\\StaticPageController.php class_attributes_separation, no_…\n  ✓ database\\seeders\\DatabaseSeeder.php no_unused_imports, blank_line_after_namesp…\n  ✓ database\\seeders\\UserSeeder.php no_trailing_comma_in_singleline, no_unused_imp…\n  ✓ routes\\web.php                               concat_space, no_extra_blank_lines\n\n```\n\n\n\n---\n\n- Blade Templates circa Laravel 11\n- Navigation bar on guest and app layouts\n- Footer in guest and app layouts\n- Email Verification enabled\n- [Font Awesome 6 (Free)](https://fontawesome.com)\n\n# After Cloning\n\nThe following steps will be done:\n\n- cd into folder\n- create a database.sqlite file\n- install npm packages\n- install composer packages\n- migrate and seed\n\n```shell\ncd FOLDRE_NAME\ntouch database/database.sqlite\nnpm i\nnpm update\ncomposer install\ncomposer update\nphp artisan migrate:fresh --seed\n\n```\n\n## Tutorials, Articles \u0026 References\n\nTutorials and Articles on the individual components\n\nMcDougall, S. (2022, June 20). Running PHPStan on max with Laravel - Laravel News. Laravel\nNews. https://laravel-news.com/running-phpstan-on-max-with-laravel\n\nLaravel.io. (2024). How to get your Laravel app from 0 to 9 with Larastan | Laravel.io.\nLaravel.io. https://laravel.io/articles/how-to-get-your-laravel-app-from-0-to-9-with-larastan\n\nLarastan. (2025, June 20). GitHub - larastan/larastan: ⚗️ Adds code analysis to Laravel improving developer productivity\nand code quality. GitHub. https://github.com/larastan/larastan\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felishamutang%2Fsaas-jokes-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felishamutang%2Fsaas-jokes-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felishamutang%2Fsaas-jokes-api/lists"}