├── .editorconfig ├── .env.example ├── .gitattributes ├── .github └── workflows │ └── pint.yml ├── .gitignore ├── .gitpod.yml ├── .styleci.yml ├── LICENSE.md ├── README.md ├── app ├── Console │ ├── Commands │ │ └── GetRandomImages.php │ └── Kernel.php ├── Enums │ └── OrderStatus.php ├── Exceptions │ └── Handler.php ├── Filament │ ├── App │ │ └── Pages │ │ │ ├── RegisterTeam.php │ │ │ └── Settings.php │ ├── Clusters │ │ ├── Products.php │ │ └── Products │ │ │ └── Resources │ │ │ ├── BrandResource.php │ │ │ ├── BrandResource │ │ │ ├── Pages │ │ │ │ ├── CreateBrand.php │ │ │ │ ├── EditBrand.php │ │ │ │ └── ListBrands.php │ │ │ └── RelationManagers │ │ │ │ ├── AddressesRelationManager.php │ │ │ │ └── ProductsRelationManager.php │ │ │ ├── CategoryResource.php │ │ │ ├── CategoryResource │ │ │ ├── Pages │ │ │ │ ├── CreateCategory.php │ │ │ │ ├── EditCategory.php │ │ │ │ └── ListCategories.php │ │ │ └── RelationManagers │ │ │ │ └── ProductsRelationManager.php │ │ │ ├── ProductResource.php │ │ │ └── ProductResource │ │ │ ├── Pages │ │ │ ├── CreateProduct.php │ │ │ ├── EditProduct.php │ │ │ └── ListProducts.php │ │ │ ├── RelationManagers │ │ │ └── CommentsRelationManager.php │ │ │ └── Widgets │ │ │ └── ProductStats.php │ ├── Exports │ │ ├── Blog │ │ │ └── AuthorExporter.php │ │ └── Shop │ │ │ └── BrandExporter.php │ ├── Imports │ │ ├── Blog │ │ │ └── CategoryImporter.php │ │ └── Shop │ │ │ └── CategoryImporter.php │ ├── Pages │ │ ├── Auth │ │ │ └── Login.php │ │ └── Dashboard.php │ ├── Resources │ │ ├── Blog │ │ │ ├── AuthorResource.php │ │ │ ├── AuthorResource │ │ │ │ └── Pages │ │ │ │ │ └── ManageAuthors.php │ │ │ ├── CategoryResource.php │ │ │ ├── CategoryResource │ │ │ │ └── Pages │ │ │ │ │ └── ManageCategories.php │ │ │ ├── LinkResource.php │ │ │ ├── LinkResource │ │ │ │ └── Pages │ │ │ │ │ ├── CreateLink.php │ │ │ │ │ ├── EditLink.php │ │ │ │ │ ├── ListLinks.php │ │ │ │ │ └── ViewLink.php │ │ │ ├── PostResource.php │ │ │ └── PostResource │ │ │ │ └── Pages │ │ │ │ ├── CreatePost.php │ │ │ │ ├── EditPost.php │ │ │ │ ├── ListPosts.php │ │ │ │ ├── ManagePostComments.php │ │ │ │ └── ViewPost.php │ │ └── Shop │ │ │ ├── CustomerResource.php │ │ │ ├── CustomerResource │ │ │ ├── Pages │ │ │ │ ├── CreateCustomer.php │ │ │ │ ├── EditCustomer.php │ │ │ │ └── ListCustomers.php │ │ │ └── RelationManagers │ │ │ │ ├── AddressesRelationManager.php │ │ │ │ └── PaymentsRelationManager.php │ │ │ ├── OrderResource.php │ │ │ └── OrderResource │ │ │ ├── Pages │ │ │ ├── CreateOrder.php │ │ │ ├── EditOrder.php │ │ │ └── ListOrders.php │ │ │ ├── RelationManagers │ │ │ └── PaymentsRelationManager.php │ │ │ └── Widgets │ │ │ └── OrderStats.php │ └── Widgets │ │ ├── CustomersChart.php │ │ ├── LatestOrders.php │ │ ├── OrdersChart.php │ │ └── StatsOverviewWidget.php ├── Forms │ └── Components │ │ └── AddressForm.php ├── Http │ ├── Controllers │ │ └── Controller.php │ ├── Kernel.php │ ├── Middleware │ │ ├── Authenticate.php │ │ ├── EncryptCookies.php │ │ ├── PreventRequestsDuringMaintenance.php │ │ ├── RedirectIfAuthenticated.php │ │ ├── TrimStrings.php │ │ ├── TrustHosts.php │ │ ├── TrustProxies.php │ │ └── VerifyCsrfToken.php │ └── Resources │ │ └── Team.php ├── Livewire │ ├── .gitkeep │ ├── Form.php │ └── Notifications.php ├── Models │ ├── Address.php │ ├── Blog │ │ ├── Author.php │ │ ├── Category.php │ │ ├── Link.php │ │ └── Post.php │ ├── Comment.php │ ├── Shop │ │ ├── Brand.php │ │ ├── Category.php │ │ ├── Customer.php │ │ ├── Order.php │ │ ├── OrderAddress.php │ │ ├── OrderItem.php │ │ ├── Payment.php │ │ └── Product.php │ ├── Team.php │ └── User.php └── Providers │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── EventServiceProvider.php │ ├── Filament │ ├── AdminPanelProvider.php │ └── AppPanelProvider.php │ ├── HorizonServiceProvider.php │ └── RouteServiceProvider.php ├── artisan ├── bootstrap ├── app.php └── cache │ └── .gitignore ├── composer-local.json ├── composer.json ├── composer.lock ├── config ├── app.php ├── auth.php ├── blade-icons.php ├── broadcasting.php ├── cache.php ├── cors.php ├── database.php ├── debugbar.php ├── filament.php ├── filesystems.php ├── hashing.php ├── horizon.php ├── logging.php ├── mail.php ├── queue.php ├── sanctum.php ├── services.php ├── session.php └── view.php ├── database ├── .gitignore ├── factories │ ├── AddressFactory.php │ ├── Blog │ │ ├── AuthorFactory.php │ │ ├── CategoryFactory.php │ │ ├── LinkFactory.php │ │ └── PostFactory.php │ ├── CommentFactory.php │ ├── Concerns │ │ └── CanCreateImages.php │ ├── Shop │ │ ├── BrandFactory.php │ │ ├── CategoryFactory.php │ │ ├── CustomerFactory.php │ │ ├── OrderAddressFactory.php │ │ ├── OrderFactory.php │ │ ├── OrderItemFactory.php │ │ ├── PaymentFactory.php │ │ └── ProductFactory.php │ └── UserFactory.php ├── migrations │ ├── 2014_10_12_000000_create_users_table.php │ ├── 2014_10_12_100000_create_password_resets_table.php │ ├── 2019_08_19_000000_create_failed_jobs_table.php │ ├── 2019_12_14_000001_create_personal_access_tokens_table.php │ ├── 2021_12_13_055514_create_media_table.php │ ├── 2021_12_13_072541_create_tag_tables.php │ ├── 2021_12_13_072624_create_settings_table.php │ ├── 2021_12_13_073001_create_blog_authors_table.php │ ├── 2021_12_13_073006_create_blog_categories_table.php │ ├── 2021_12_13_073022_create_blog_posts_table.php │ ├── 2021_12_13_153307_create_shop_customers_table.php │ ├── 2021_12_13_155621_create_shop_categories_table.php │ ├── 2021_12_13_164316_create_shop_brands_table.php │ ├── 2021_12_13_164519_create_shop_products_table.php │ ├── 2021_12_13_164524_create_shop_category_product_table.php │ ├── 2021_12_13_165855_create_shop_orders_table.php │ ├── 2021_12_13_182904_create_shop_order_items_table.php │ ├── 2021_12_13_184540_create_addresses_table.php │ ├── 2022_06_01_232533_alter_order_items_add_sort_column.php │ ├── 2022_06_09_091930_create_comments_table.php │ ├── 2022_06_09_092322_create_payments_table.php │ ├── 2022_06_09_155042_create_addressable_table.php │ ├── 2022_09_10_131605_create_notifications_table.php │ ├── 2022_10_27_140431_create_teams_table.php │ ├── 2023_11_29_144716_create_job_batches_table.php │ ├── 2023_11_29_144720_create_imports_table.php │ ├── 2023_11_29_144721_create_failed_import_rows_table.php │ ├── 2023_12_17_112735_create_blog_links_table.php │ └── 2024_01_01_105157_create_exports_table.php └── seeders │ ├── DatabaseSeeder.php │ ├── LocalImages.php │ └── local_images │ ├── 1280x720 │ ├── 05e68fd7-d7ac-46a3-837e-20937f8dc899.jpg │ ├── 3188fb8e-15a9-4afb-9182-1aebdcf11b83.jpg │ ├── 50f608f8-2549-4ecf-b6f6-a5997c13cb63.jpg │ ├── 5b22e6fe-5958-4a9c-99f1-33bf59085469.jpg │ ├── 609dd36a-1011-4185-b736-63971a6fb854.jpg │ ├── 708c814b-0bbf-40f9-af54-f15673585d99.jpg │ ├── 80043582-b25d-4403-8166-03baddfb96bc.jpg │ ├── 80654c36-50f4-4144-91e9-58fc49b83f90.jpg │ ├── 9144a5b3-efc6-42de-8b2d-fb77ea0656c6.jpg │ ├── 99b95dcc-4a4f-4523-922a-b6f776d09faa.jpg │ ├── 9b3227b0-584c-48f4-962f-b42318bade61.jpg │ ├── 9cc59994-a348-4a55-8885-b6d478e2d2c7.jpg │ ├── 9eda78f4-ac0c-4af9-b6a8-14f8727294dd.jpg │ ├── b5d43aee-bf02-4331-8916-b10523ef861f.jpg │ ├── cb6ca3f6-3643-4bc1-a0de-c113db3a92e0.jpg │ ├── ccd5cbc5-afa7-4709-b572-9f72c6716846.jpg │ ├── d970b8da-95e6-456e-9ddb-7cb1aad2de56.jpg │ ├── dc5d4460-1637-4ae5-ab05-6732b0e9d3b8.jpg │ ├── dd133d03-b444-4a19-a728-2eaab2a547ee.jpg │ ├── e837e969-cbfe-4995-aaea-ee32cf4ba4d0.jpg │ ├── f4e246e7-8bee-4011-8c8d-debff845d198.jpg │ ├── f9697b3c-72df-4917-8317-6c3bdc530225.jpg │ └── ffe9e024-8a9c-4bbb-ae13-e99a620ae2f7.jpg │ └── 200x200 │ ├── 1aa69e68-a504-4495-bc38-5c520d035d8b.jpg │ ├── 20d2e61e-3273-4521-9c47-e56a68c892fb.jpg │ ├── 248eadf6-5227-42f3-ad31-1c320febdb7b.jpg │ ├── 2f5c09b5-6268-47b2-8e0b-c4890850e727.jpg │ ├── 3b95f9cc-e3e3-48d3-b743-443210fa19ec.jpg │ ├── 3b9f504b-d276-4d4a-9997-68979f1bddcc.jpg │ ├── 447a4c77-e7a2-49a3-8015-2dc5ba055c24.jpg │ ├── 482659c5-764a-4071-848a-fa1fbd786fd5.jpg │ ├── 503a4fac-68d7-4b64-ad44-5c2ec3986b94.jpg │ ├── 57623f03-f7c2-4179-a366-f1530993bc09.jpg │ ├── 680520bc-e880-4704-8dc7-a425d55b7a81.jpg │ ├── 74d81728-0dc2-43e2-a7da-332e2e2e6c89.jpg │ ├── 7e4b0b96-99df-4d1e-84fa-dad2b398f172.jpg │ ├── 873353ff-3d3a-4bfc-a02d-22949e6e4558.jpg │ ├── 948bfac1-6d9b-430f-86fc-8d2d6ef680ed.jpg │ ├── b02337ca-473b-4ae1-957b-0c7854161f8e.jpg │ ├── b14d2dca-4d45-4cc0-8d8b-864e10081dac.jpg │ ├── b37987d1-a9ad-4671-9066-9812a033fdf4.jpg │ ├── cf755312-0709-4f40-be4a-bba7edbcdabb.jpg │ ├── dce10027-9b5d-44a5-91ed-7caeb23100bd.jpg │ ├── e5d18094-036b-4c48-8232-8e0d9971cca0.jpg │ ├── edc07898-49a5-4eb0-8af8-2a9ceeb3baf5.jpg │ ├── f3f0ce20-b7a3-47db-b907-c77c5e6ca038.jpg │ └── f8c8557d-bd70-4cf7-978c-89f35e918c8f.jpg ├── package-lock.json ├── package.json ├── phpstan.neon ├── phpunit.xml ├── pint.json ├── postcss.config.js ├── public ├── .htaccess ├── css │ └── filament │ │ ├── filament │ │ └── app.css │ │ ├── forms │ │ └── forms.css │ │ └── support │ │ └── support.css ├── favicon.ico ├── index.php ├── js │ └── filament │ │ ├── filament │ │ ├── app.js │ │ └── echo.js │ │ ├── forms │ │ ├── components │ │ │ ├── color-picker.js │ │ │ ├── date-time-picker.js │ │ │ ├── file-upload.js │ │ │ ├── key-value.js │ │ │ ├── markdown-editor.js │ │ │ ├── rich-editor.js │ │ │ ├── select.js │ │ │ ├── tags-input.js │ │ │ ├── text-input.js │ │ │ └── textarea.js │ │ └── forms.js │ │ ├── notifications │ │ └── notifications.js │ │ ├── support │ │ ├── async-alpine.js │ │ └── support.js │ │ ├── tables │ │ ├── components │ │ │ └── table.js │ │ └── tables.js │ │ └── widgets │ │ └── components │ │ ├── chart.js │ │ └── stats-overview │ │ ├── card │ │ └── chart.js │ │ └── stat │ │ └── chart.js ├── mix-manifest.json ├── robots.txt ├── vendor │ └── horizon │ │ ├── app-dark.css │ │ ├── app.css │ │ ├── app.js │ │ ├── img │ │ ├── favicon.png │ │ ├── horizon.svg │ │ └── sprite.svg │ │ └── mix-manifest.json └── web.config ├── resources ├── css │ └── app.css ├── js │ └── app.js ├── lang │ └── en │ │ ├── auth.php │ │ ├── pagination.php │ │ ├── passwords.php │ │ └── validation.php ├── svg │ ├── github.svg │ └── twitter.svg └── views │ ├── components │ └── layouts │ │ └── app.blade.php │ ├── filament │ └── app │ │ ├── logo.blade.php │ │ └── pages │ │ └── settings.blade.php │ ├── livewire │ ├── form.blade.php │ └── notifications.blade.php │ └── maintenance.blade.php ├── routes ├── api.php ├── channels.php ├── console.php └── web.php ├── screenshot.png ├── server.php ├── storage ├── app │ └── .gitignore ├── debugbar │ └── .gitignore ├── framework │ ├── .gitignore │ ├── cache │ │ ├── .gitignore │ │ └── data │ │ │ └── .gitignore │ ├── sessions │ │ └── .gitignore │ ├── testing │ │ └── .gitignore │ └── views │ │ └── .gitignore └── logs │ └── .gitignore ├── tailwind.config.js ├── tests ├── CreatesApplication.php ├── Feature │ └── ExampleTest.php ├── TestCase.php └── Unit │ └── ExampleTest.php └── vite.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.{yml,yaml}] 15 | indent_size = 2 16 | 17 | [docker-compose.yml] 18 | indent_size = 4 19 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME="Filament Demo" 2 | APP_ENV=local 3 | APP_KEY= 4 | APP_DEBUG=true 5 | APP_URL=http://127.0.0.1:8000 6 | 7 | LOG_CHANNEL=stack 8 | LOG_DEPRECATIONS_CHANNEL=null 9 | LOG_LEVEL=debug 10 | 11 | DB_CONNECTION=sqlite 12 | 13 | BROADCAST_DRIVER=log 14 | CACHE_DRIVER=file 15 | FILESYSTEM_DRIVER=local 16 | QUEUE_CONNECTION=sync 17 | SESSION_DRIVER=file 18 | SESSION_LIFETIME=120 19 | 20 | MEMCACHED_HOST=127.0.0.1 21 | 22 | REDIS_HOST=127.0.0.1 23 | REDIS_PASSWORD=null 24 | REDIS_PORT=6379 25 | 26 | MAIL_MAILER=smtp 27 | MAIL_HOST=mailhog 28 | MAIL_PORT=1025 29 | MAIL_USERNAME=null 30 | MAIL_PASSWORD=null 31 | MAIL_ENCRYPTION=null 32 | MAIL_FROM_ADDRESS=null 33 | MAIL_FROM_NAME="${APP_NAME}" 34 | 35 | AWS_ACCESS_KEY_ID= 36 | AWS_SECRET_ACCESS_KEY= 37 | AWS_DEFAULT_REGION=us-east-1 38 | AWS_BUCKET= 39 | AWS_USE_PATH_STYLE_ENDPOINT=false 40 | 41 | FLARE_KEY= 42 | 43 | PUSHER_APP_ID= 44 | PUSHER_APP_KEY= 45 | PUSHER_APP_SECRET= 46 | PUSHER_APP_CLUSTER=mt1 47 | 48 | VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 49 | VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 50 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.js linguist-vendored 5 | CHANGELOG.md export-ignore 6 | -------------------------------------------------------------------------------- /.github/workflows/pint.yml: -------------------------------------------------------------------------------- 1 | name: Check & fix styling 2 | 3 | on: [push] 4 | 5 | jobs: 6 | pint: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout code 10 | uses: actions/checkout@v2 11 | with: 12 | ref: ${{ github.head_ref }} 13 | - name: Setup PHP 14 | uses: shivammathur/setup-php@v2 15 | with: 16 | php-version: '8.2' 17 | - name: Install dependencies 18 | run: composer install --no-interaction 19 | - name: Run Pint 20 | run: ./vendor/bin/pint 21 | - name: Commit changes 22 | uses: stefanzweifel/git-auto-commit-action@v4 23 | with: 24 | commit_message: Fix styling 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/hot 3 | /public/build 4 | /public/storage 5 | /storage/*.key 6 | /vendor 7 | .env 8 | .env.backup 9 | .phpunit.result.cache 10 | docker-compose.override.yml 11 | Homestead.json 12 | Homestead.yaml 13 | npm-debug.log 14 | yarn-error.log 15 | /.idea 16 | /.vscode 17 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - name: Setup environment and launch 3 | init: | 4 | cp .env.example .env 5 | sed -i "s#APP_URL=http://127.0.0.1:8000#APP_URL=$(gp url 8000)#g" .env 6 | composer install --ignore-platform-reqs 7 | php artisan key:generate 8 | php artisan storage:link 9 | touch database/database.sqlite 10 | php artisan migrate:fresh --seed 11 | php artisan serve 12 | 13 | # Configure vscode 14 | vscode: 15 | extensions: 16 | - bmewburn.vscode-intelephense-client 17 | - ms-azuretools.vscode-docker 18 | - ecmel.vscode-html-css 19 | - MehediDracula.php-namespace-resolver 20 | - Equinusocio.vsc-community-material-theme 21 | - EditorConfig.EditorConfig 22 | - streetsidesoftware.code-spell-checker 23 | -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | php: 2 | preset: laravel 3 | version: 8 4 | disabled: 5 | - no_unused_imports 6 | finder: 7 | not-name: 8 | - index.php 9 | - server.php 10 | js: 11 | finder: 12 | not-name: 13 | - webpack.mix.js 14 | css: true 15 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) Filament 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Filament Demo App 2 | 3 | A demo application to illustrate how Filament Admin works. 4 | 5 | ![Filament Demo](https://github.com/filamentphp/demo/assets/171715/899161a9-3c85-4dc9-9599-13928d3a4412) 6 | 7 | [Open in Gitpod](https://gitpod.io/#https://github.com/filamentphp/demo) to edit it and preview your changes with no setup required. 8 | 9 | ## Installation 10 | 11 | Clone the repo locally: 12 | 13 | ```sh 14 | git clone https://github.com/laravel-filament/demo.git filament-demo && cd filament-demo 15 | ``` 16 | 17 | Install PHP dependencies: 18 | 19 | ```sh 20 | composer install 21 | ``` 22 | 23 | Setup configuration: 24 | 25 | ```sh 26 | cp .env.example .env 27 | ``` 28 | 29 | Generate application key: 30 | 31 | ```sh 32 | php artisan key:generate 33 | ``` 34 | 35 | Create an SQLite database. You can also use another database (MySQL, Postgres), simply update your configuration accordingly. 36 | 37 | ```sh 38 | touch database/database.sqlite 39 | ``` 40 | 41 | Run database migrations: 42 | 43 | ```sh 44 | php artisan migrate 45 | ``` 46 | 47 | Run database seeder: 48 | 49 | ```sh 50 | php artisan db:seed 51 | ``` 52 | 53 | > **Note** 54 | > If you get an "Invalid datetime format (1292)" error, this is probably related to the timezone setting of your database. 55 | > Please see https://dba.stackexchange.com/questions/234270/incorrect-datetime-value-mysql 56 | 57 | 58 | Create a symlink to the storage: 59 | 60 | ```sh 61 | php artisan storage:link 62 | ``` 63 | 64 | Run the dev server (the output will give the address): 65 | 66 | ```sh 67 | php artisan serve 68 | ``` 69 | 70 | You're ready to go! Visit the url in your browser, and login with: 71 | 72 | - **Username:** admin@filamentphp.com 73 | - **Password:** password 74 | 75 | ## Features to explore 76 | 77 | ### Relations 78 | 79 | #### BelongsTo 80 | - ProductResource 81 | - OrderResource 82 | - PostResource 83 | 84 | #### BelongsToMany 85 | - CategoryResource\RelationManagers\ProductsRelationManager 86 | 87 | #### HasMany 88 | - OrderResource\RelationManagers\PaymentsRelationManager 89 | 90 | #### HasManyThrough 91 | - CustomerResource\RelationManagers\PaymentsRelationManager 92 | 93 | #### MorphOne 94 | - OrderResource -> Address 95 | 96 | #### MorphMany 97 | - ProductResource\RelationManagers\CommentsRelationManager 98 | - PostResource\RelationManagers\CommentsRelationManager 99 | 100 | #### MorphToMany 101 | - BrandResource\RelationManagers\AddressRelationManager 102 | - CustomerResource\RelationManagers\AddressRelationManager 103 | -------------------------------------------------------------------------------- /app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | load(__DIR__ . '/Commands'); 28 | 29 | require base_path('routes/console.php'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Enums/OrderStatus.php: -------------------------------------------------------------------------------- 1 | 'New', 25 | self::Processing => 'Processing', 26 | self::Shipped => 'Shipped', 27 | self::Delivered => 'Delivered', 28 | self::Cancelled => 'Cancelled', 29 | }; 30 | } 31 | 32 | public function getColor(): string | array | null 33 | { 34 | return match ($this) { 35 | self::New => 'info', 36 | self::Processing => 'warning', 37 | self::Shipped, self::Delivered => 'success', 38 | self::Cancelled => 'danger', 39 | }; 40 | } 41 | 42 | public function getIcon(): ?string 43 | { 44 | return match ($this) { 45 | self::New => 'heroicon-m-sparkles', 46 | self::Processing => 'heroicon-m-arrow-path', 47 | self::Shipped => 'heroicon-m-truck', 48 | self::Delivered => 'heroicon-m-check-badge', 49 | self::Cancelled => 'heroicon-m-x-circle', 50 | }; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | > 14 | */ 15 | protected $dontReport = [ 16 | // 17 | ]; 18 | 19 | /** 20 | * A list of the inputs that are never flashed for validation exceptions. 21 | * 22 | * @var array 23 | */ 24 | protected $dontFlash = [ 25 | 'current_password', 26 | 'password', 27 | 'password_confirmation', 28 | ]; 29 | 30 | /** 31 | * Register the exception handling callbacks for the application. 32 | * 33 | * @return void 34 | */ 35 | public function register() 36 | { 37 | $this->reportable(function (Throwable $e) { 38 | // 39 | }); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/Filament/App/Pages/RegisterTeam.php: -------------------------------------------------------------------------------- 1 | schema([ 20 | TextInput::make('name')->required(), 21 | ]); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Filament/App/Pages/Settings.php: -------------------------------------------------------------------------------- 1 | exporter(BrandExporter::class), 19 | Actions\CreateAction::make(), 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Filament/Clusters/Products/Resources/BrandResource/RelationManagers/AddressesRelationManager.php: -------------------------------------------------------------------------------- 1 | schema([ 22 | Forms\Components\TextInput::make('street'), 23 | 24 | Forms\Components\TextInput::make('zip'), 25 | 26 | Forms\Components\TextInput::make('city'), 27 | 28 | Forms\Components\TextInput::make('state'), 29 | 30 | Forms\Components\Select::make('country') 31 | ->searchable() 32 | ->getSearchResultsUsing(fn (string $query) => Country::where('name', 'like', "%{$query}%")->pluck('name', 'id')) 33 | ->getOptionLabelUsing(fn ($value): ?string => Country::firstWhere('id', $value)?->getAttribute('name')), 34 | ]); 35 | } 36 | 37 | public function table(Table $table): Table 38 | { 39 | return $table 40 | ->columns([ 41 | Tables\Columns\TextColumn::make('street'), 42 | 43 | Tables\Columns\TextColumn::make('zip'), 44 | 45 | Tables\Columns\TextColumn::make('city'), 46 | 47 | Tables\Columns\TextColumn::make('country') 48 | ->formatStateUsing(fn ($state): ?string => Country::find($state)?->name ?? null), 49 | ]) 50 | ->filters([ 51 | // 52 | ]) 53 | ->headerActions([ 54 | Tables\Actions\AttachAction::make(), 55 | Tables\Actions\CreateAction::make(), 56 | ]) 57 | ->actions([ 58 | Tables\Actions\EditAction::make(), 59 | Tables\Actions\DetachAction::make(), 60 | Tables\Actions\DeleteAction::make(), 61 | ]) 62 | ->groupedBulkActions([ 63 | Tables\Actions\DetachBulkAction::make(), 64 | Tables\Actions\DeleteBulkAction::make(), 65 | ]); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/Filament/Clusters/Products/Resources/BrandResource/RelationManagers/ProductsRelationManager.php: -------------------------------------------------------------------------------- 1 | headerActions([ 26 | Tables\Actions\CreateAction::make(), 27 | ]) 28 | ->actions([ 29 | Tables\Actions\DeleteAction::make(), 30 | ]) 31 | ->groupedBulkActions([ 32 | Tables\Actions\DeleteBulkAction::make(), 33 | ]); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/Filament/Clusters/Products/Resources/CategoryResource/Pages/CreateCategory.php: -------------------------------------------------------------------------------- 1 | importer(CategoryImporter::class), 19 | Actions\CreateAction::make(), 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Filament/Clusters/Products/Resources/CategoryResource/RelationManagers/ProductsRelationManager.php: -------------------------------------------------------------------------------- 1 | headerActions([ 26 | Tables\Actions\CreateAction::make(), 27 | ]) 28 | ->actions([ 29 | Tables\Actions\DeleteAction::make(), 30 | ]) 31 | ->groupedBulkActions([ 32 | Tables\Actions\DeleteBulkAction::make(), 33 | ]); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/Filament/Clusters/Products/Resources/ProductResource/Pages/CreateProduct.php: -------------------------------------------------------------------------------- 1 | getPageTableQuery()->count()), 25 | Stat::make('Product Inventory', $this->getPageTableQuery()->sum('qty')), 26 | Stat::make('Average price', number_format($this->getPageTableQuery()->avg('price'), 2)), 27 | ]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/Filament/Exports/Blog/AuthorExporter.php: -------------------------------------------------------------------------------- 1 | label('ID'), 19 | ExportColumn::make('name'), 20 | ExportColumn::make('email') 21 | ->label('Email address'), 22 | ExportColumn::make('github_handle') 23 | ->label('GitHub'), 24 | ExportColumn::make('twitter_handle') 25 | ->label('Twitter'), 26 | ExportColumn::make('created_at'), 27 | ExportColumn::make('updated_at'), 28 | ]; 29 | } 30 | 31 | public static function getCompletedNotificationBody(Export $export): string 32 | { 33 | $body = 'Your author export has completed and ' . number_format($export->successful_rows) . ' ' . str('row')->plural($export->successful_rows) . ' exported.'; 34 | 35 | if ($failedRowsCount = $export->getFailedRowsCount()) { 36 | $body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to export.'; 37 | } 38 | 39 | return $body; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/Filament/Exports/Shop/BrandExporter.php: -------------------------------------------------------------------------------- 1 | label('ID'), 19 | ExportColumn::make('name'), 20 | ExportColumn::make('slug'), 21 | ExportColumn::make('website'), 22 | ExportColumn::make('created_at'), 23 | ExportColumn::make('updated_at'), 24 | ]; 25 | } 26 | 27 | public static function getCompletedNotificationBody(Export $export): string 28 | { 29 | $body = 'Your brand export has completed and ' . number_format($export->successful_rows) . ' ' . str('row')->plural($export->successful_rows) . ' exported.'; 30 | 31 | if ($failedRowsCount = $export->getFailedRowsCount()) { 32 | $body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to export.'; 33 | } 34 | 35 | return $body; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/Filament/Imports/Blog/CategoryImporter.php: -------------------------------------------------------------------------------- 1 | requiredMapping() 19 | ->rules(['required', 'max:255']) 20 | ->example('Category A'), 21 | ImportColumn::make('slug') 22 | ->requiredMapping() 23 | ->rules(['required', 'max:255']) 24 | ->example('category-a'), 25 | ImportColumn::make('description') 26 | ->example('This is the description for Category A.'), 27 | ImportColumn::make('is_visible') 28 | ->label('Visibility') 29 | ->requiredMapping() 30 | ->boolean() 31 | ->rules(['required', 'boolean']) 32 | ->example('yes'), 33 | ImportColumn::make('seo_title') 34 | ->label('SEO title') 35 | ->rules(['max:60']) 36 | ->example('Awesome Category A'), 37 | ImportColumn::make('seo_description') 38 | ->label('SEO description') 39 | ->rules(['max:160']) 40 | ->example('Wow! It\'s just so amazing.'), 41 | ]; 42 | } 43 | 44 | public function resolveRecord(): ?Category 45 | { 46 | return Category::firstOrNew([ 47 | 'slug' => $this->data['slug'], 48 | ]); 49 | } 50 | 51 | public static function getCompletedNotificationBody(Import $import): string 52 | { 53 | $body = 'Your blog category import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.'; 54 | 55 | if ($failedRowsCount = $import->getFailedRowsCount()) { 56 | $body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to import.'; 57 | } 58 | 59 | return $body; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/Filament/Imports/Shop/CategoryImporter.php: -------------------------------------------------------------------------------- 1 | requiredMapping() 19 | ->rules(['required', 'max:255']) 20 | ->example('Category A'), 21 | ImportColumn::make('slug') 22 | ->requiredMapping() 23 | ->rules(['required', 'max:255']) 24 | ->example('category-a'), 25 | ImportColumn::make('parent') 26 | ->relationship(resolveUsing: ['name', 'slug']) 27 | ->example('Category B'), 28 | ImportColumn::make('description') 29 | ->example('This is the description for Category A.'), 30 | ImportColumn::make('position') 31 | ->requiredMapping() 32 | ->numeric() 33 | ->rules(['required', 'integer']) 34 | ->example('1'), 35 | ImportColumn::make('is_visible') 36 | ->label('Visibility') 37 | ->requiredMapping() 38 | ->boolean() 39 | ->rules(['required', 'boolean']) 40 | ->example('yes'), 41 | ImportColumn::make('seo_title') 42 | ->label('SEO title') 43 | ->rules(['max:60']) 44 | ->example('Awesome Category A'), 45 | ImportColumn::make('seo_description') 46 | ->label('SEO description') 47 | ->rules(['max:160']) 48 | ->example('Wow! It\'s just so amazing.'), 49 | ]; 50 | } 51 | 52 | public function resolveRecord(): ?Category 53 | { 54 | return Category::firstOrNew([ 55 | 'slug' => $this->data['slug'], 56 | ]); 57 | } 58 | 59 | public static function getCompletedNotificationBody(Import $import): string 60 | { 61 | $body = 'Your shop category import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.'; 62 | 63 | if ($failedRowsCount = $import->getFailedRowsCount()) { 64 | $body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to import.'; 65 | } 66 | 67 | return $body; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/Filament/Pages/Auth/Login.php: -------------------------------------------------------------------------------- 1 | form->fill([ 14 | 'email' => 'admin@filamentphp.com', 15 | 'password' => 'password', 16 | 'remember' => true, 17 | ]); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/Filament/Pages/Dashboard.php: -------------------------------------------------------------------------------- 1 | schema([ 20 | Section::make() 21 | ->schema([ 22 | Select::make('businessCustomersOnly') 23 | ->boolean(), 24 | DatePicker::make('startDate') 25 | ->maxDate(fn (Get $get) => $get('endDate') ?: now()), 26 | DatePicker::make('endDate') 27 | ->minDate(fn (Get $get) => $get('startDate') ?: now()) 28 | ->maxDate(now()), 29 | ]) 30 | ->columns(3), 31 | ]); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Filament/Resources/Blog/AuthorResource/Pages/ManageAuthors.php: -------------------------------------------------------------------------------- 1 | exporter(AuthorExporter::class), 19 | Actions\CreateAction::make(), 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Filament/Resources/Blog/CategoryResource/Pages/ManageCategories.php: -------------------------------------------------------------------------------- 1 | importer(CategoryImporter::class), 19 | Actions\CreateAction::make(), 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Filament/Resources/Blog/LinkResource/Pages/CreateLink.php: -------------------------------------------------------------------------------- 1 | getRecord(); 19 | 20 | return $record->title; 21 | } 22 | 23 | protected function getActions(): array 24 | { 25 | return [ 26 | Actions\DeleteAction::make(), 27 | ]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/Filament/Resources/Blog/PostResource/Pages/ListPosts.php: -------------------------------------------------------------------------------- 1 | getRecord(); 18 | 19 | return $record->title; 20 | } 21 | 22 | protected function getActions(): array 23 | { 24 | return []; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Filament/Resources/Shop/CustomerResource/Pages/CreateCustomer.php: -------------------------------------------------------------------------------- 1 | schema([ 22 | Forms\Components\TextInput::make('street'), 23 | 24 | Forms\Components\TextInput::make('zip'), 25 | 26 | Forms\Components\TextInput::make('city'), 27 | 28 | Forms\Components\TextInput::make('state'), 29 | 30 | Forms\Components\Select::make('country') 31 | ->searchable() 32 | ->getSearchResultsUsing(fn (string $query) => Country::where('name', 'like', "%{$query}%")->pluck('name', 'id')) 33 | ->getOptionLabelUsing(fn ($value): ?string => Country::firstWhere('id', $value)?->getAttribute('name')), 34 | ]); 35 | } 36 | 37 | public function table(Table $table): Table 38 | { 39 | return $table 40 | ->columns([ 41 | Tables\Columns\TextColumn::make('street'), 42 | 43 | Tables\Columns\TextColumn::make('zip'), 44 | 45 | Tables\Columns\TextColumn::make('city'), 46 | 47 | Tables\Columns\TextColumn::make('country') 48 | ->formatStateUsing(fn ($state): ?string => Country::find($state)?->name ?? null), 49 | ]) 50 | ->filters([ 51 | // 52 | ]) 53 | ->headerActions([ 54 | Tables\Actions\AttachAction::make(), 55 | Tables\Actions\CreateAction::make(), 56 | ]) 57 | ->actions([ 58 | Tables\Actions\EditAction::make(), 59 | Tables\Actions\DetachAction::make(), 60 | Tables\Actions\DeleteAction::make(), 61 | ]) 62 | ->groupedBulkActions([ 63 | Tables\Actions\DetachBulkAction::make(), 64 | Tables\Actions\DeleteBulkAction::make(), 65 | ]); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/Filament/Resources/Shop/OrderResource/Pages/CreateOrder.php: -------------------------------------------------------------------------------- 1 | schema([ 27 | Wizard::make($this->getSteps()) 28 | ->startOnStep($this->getStartStep()) 29 | ->cancelAction($this->getCancelFormAction()) 30 | ->submitAction($this->getSubmitFormAction()) 31 | ->skippable($this->hasSkippableSteps()) 32 | ->contained(false), 33 | ]) 34 | ->columns(null); 35 | } 36 | 37 | protected function afterCreate(): void 38 | { 39 | /** @var Order $order */ 40 | $order = $this->record; 41 | 42 | /** @var User $user */ 43 | $user = auth()->user(); 44 | 45 | Notification::make() 46 | ->title('New order') 47 | ->icon('heroicon-o-shopping-bag') 48 | ->body("**{$order->customer?->name} ordered {$order->items->count()} products.**") 49 | ->actions([ 50 | Action::make('View') 51 | ->url(OrderResource::getUrl('edit', ['record' => $order])), 52 | ]) 53 | ->sendToDatabase($user); 54 | } 55 | 56 | /** @return Step[] */ 57 | protected function getSteps(): array 58 | { 59 | return [ 60 | Step::make('Order Details') 61 | ->schema([ 62 | Section::make()->schema(OrderResource::getDetailsFormSchema())->columns(), 63 | ]), 64 | 65 | Step::make('Order Items') 66 | ->schema([ 67 | Section::make()->schema([ 68 | OrderResource::getItemsRepeater(), 69 | ]), 70 | ]), 71 | ]; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /app/Filament/Resources/Shop/OrderResource/Pages/EditOrder.php: -------------------------------------------------------------------------------- 1 | Tab::make('All'), 33 | 'new' => Tab::make()->query(fn ($query) => $query->where('status', 'new')), 34 | 'processing' => Tab::make()->query(fn ($query) => $query->where('status', 'processing')), 35 | 'shipped' => Tab::make()->query(fn ($query) => $query->where('status', 'shipped')), 36 | 'delivered' => Tab::make()->query(fn ($query) => $query->where('status', 'delivered')), 37 | 'cancelled' => Tab::make()->query(fn ($query) => $query->where('status', 'cancelled')), 38 | ]; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/Filament/Resources/Shop/OrderResource/Widgets/OrderStats.php: -------------------------------------------------------------------------------- 1 | between( 28 | start: now()->subYear(), 29 | end: now(), 30 | ) 31 | ->perMonth() 32 | ->count(); 33 | 34 | return [ 35 | Stat::make('Orders', $this->getPageTableQuery()->count()) 36 | ->chart( 37 | $orderData 38 | ->map(fn (TrendValue $value) => $value->aggregate) 39 | ->toArray() 40 | ), 41 | Stat::make('Open orders', $this->getPageTableQuery()->whereIn('status', ['open', 'processing'])->count()), 42 | Stat::make('Average price', number_format($this->getPageTableQuery()->avg('total_price'), 2)), 43 | ]; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/Filament/Widgets/CustomersChart.php: -------------------------------------------------------------------------------- 1 | [ 22 | [ 23 | 'label' => 'Customers', 24 | 'data' => [4344, 5676, 6798, 7890, 8987, 9388, 10343, 10524, 13664, 14345, 15753, 17332], 25 | 'fill' => 'start', 26 | ], 27 | ], 28 | 'labels' => ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Filament/Widgets/LatestOrders.php: -------------------------------------------------------------------------------- 1 | query(OrderResource::getEloquentQuery()) 22 | ->defaultPaginationPageOption(5) 23 | ->defaultSort('created_at', 'desc') 24 | ->columns([ 25 | Tables\Columns\TextColumn::make('created_at') 26 | ->label('Order Date') 27 | ->date() 28 | ->sortable(), 29 | Tables\Columns\TextColumn::make('number') 30 | ->searchable() 31 | ->sortable(), 32 | Tables\Columns\TextColumn::make('customer.name') 33 | ->searchable() 34 | ->sortable(), 35 | Tables\Columns\TextColumn::make('status') 36 | ->badge(), 37 | Tables\Columns\TextColumn::make('currency') 38 | ->getStateUsing(fn ($record): ?string => Currency::find($record->currency)?->name ?? null) 39 | ->searchable() 40 | ->sortable(), 41 | Tables\Columns\TextColumn::make('total_price') 42 | ->searchable() 43 | ->sortable(), 44 | Tables\Columns\TextColumn::make('shipping_price') 45 | ->label('Shipping cost') 46 | ->searchable() 47 | ->sortable(), 48 | ]) 49 | ->actions([ 50 | Tables\Actions\Action::make('open') 51 | ->url(fn (Order $record): string => OrderResource::getUrl('edit', ['record' => $record])), 52 | ]); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/Filament/Widgets/OrdersChart.php: -------------------------------------------------------------------------------- 1 | [ 22 | [ 23 | 'label' => 'Orders', 24 | 'data' => [2433, 3454, 4566, 3300, 5545, 5765, 6787, 8767, 7565, 8576, 9686, 8996], 25 | 'fill' => 'start', 26 | ], 27 | ], 28 | 'labels' => ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Filament/Widgets/StatsOverviewWidget.php: -------------------------------------------------------------------------------- 1 | filters['startDate'] ?? null) ? 21 | Carbon::parse($this->filters['startDate']) : 22 | null; 23 | 24 | $endDate = ! is_null($this->filters['endDate'] ?? null) ? 25 | Carbon::parse($this->filters['endDate']) : 26 | now(); 27 | 28 | $isBusinessCustomersOnly = $this->filters['businessCustomersOnly'] ?? null; 29 | $businessCustomerMultiplier = match (true) { 30 | boolval($isBusinessCustomersOnly) => 2 / 3, 31 | blank($isBusinessCustomersOnly) => 1, 32 | default => 1 / 3, 33 | }; 34 | 35 | $diffInDays = $startDate ? $startDate->diffInDays($endDate) : 0; 36 | 37 | $revenue = (int) (($startDate ? ($diffInDays * 137) : 192100) * $businessCustomerMultiplier); 38 | $newCustomers = (int) (($startDate ? ($diffInDays * 7) : 1340) * $businessCustomerMultiplier); 39 | $newOrders = (int) (($startDate ? ($diffInDays * 13) : 3543) * $businessCustomerMultiplier); 40 | 41 | $formatNumber = function (int $number): string { 42 | if ($number < 1000) { 43 | return (string) Number::format($number, 0); 44 | } 45 | 46 | if ($number < 1000000) { 47 | return Number::format($number / 1000, 2) . 'k'; 48 | } 49 | 50 | return Number::format($number / 1000000, 2) . 'm'; 51 | }; 52 | 53 | return [ 54 | Stat::make('Revenue', '$' . $formatNumber($revenue)) 55 | ->description('32k increase') 56 | ->descriptionIcon('heroicon-m-arrow-trending-up') 57 | ->chart([7, 2, 10, 3, 15, 4, 17]) 58 | ->color('success'), 59 | Stat::make('New customers', $formatNumber($newCustomers)) 60 | ->description('3% decrease') 61 | ->descriptionIcon('heroicon-m-arrow-trending-down') 62 | ->chart([17, 16, 14, 15, 14, 13, 12]) 63 | ->color('danger'), 64 | Stat::make('New orders', $formatNumber($newOrders)) 65 | ->description('7% increase') 66 | ->descriptionIcon('heroicon-m-arrow-trending-up') 67 | ->chart([15, 4, 10, 2, 12, 4, 12]) 68 | ->color('success'), 69 | ]; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | protected $middleware = [ 17 | // \App\Http\Middleware\TrustHosts::class, 18 | \App\Http\Middleware\TrustProxies::class, 19 | \App\Http\Middleware\PreventRequestsDuringMaintenance::class, 20 | \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, 21 | \App\Http\Middleware\TrimStrings::class, 22 | \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, 23 | ]; 24 | 25 | /** 26 | * The application's route middleware groups. 27 | * 28 | * @var array> 29 | */ 30 | protected $middlewareGroups = [ 31 | 'web' => [ 32 | \App\Http\Middleware\EncryptCookies::class, 33 | \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, 34 | \Illuminate\Session\Middleware\StartSession::class, 35 | // \Illuminate\Session\Middleware\AuthenticateSession::class, 36 | \Illuminate\View\Middleware\ShareErrorsFromSession::class, 37 | \App\Http\Middleware\VerifyCsrfToken::class, 38 | \Illuminate\Routing\Middleware\SubstituteBindings::class, 39 | ], 40 | 41 | 'api' => [ 42 | // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 43 | 'throttle:api', 44 | \Illuminate\Routing\Middleware\SubstituteBindings::class, 45 | ], 46 | ]; 47 | 48 | /** 49 | * The application's route middleware. 50 | * 51 | * These middleware may be assigned to groups or used individually. 52 | * 53 | * @var array 54 | */ 55 | protected $routeMiddleware = [ 56 | 'auth' => \App\Http\Middleware\Authenticate::class, 57 | 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 58 | 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 59 | 'can' => \Illuminate\Auth\Middleware\Authorize::class, 60 | 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 61 | 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, 62 | 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 63 | 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 64 | 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 65 | ]; 66 | } 67 | -------------------------------------------------------------------------------- /app/Http/Middleware/Authenticate.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /app/Http/Middleware/PreventRequestsDuringMaintenance.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 25 | return redirect(RouteServiceProvider::HOME); 26 | } 27 | } 28 | 29 | return $next($request); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | 'current_password', 16 | 'password', 17 | 'password_confirmation', 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrustHosts.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function hosts() 15 | { 16 | return [ 17 | $this->allSubdomainsOfApplicationUrl(), 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrustProxies.php: -------------------------------------------------------------------------------- 1 | |string|null 14 | */ 15 | protected $proxies = '*'; 16 | 17 | /** 18 | * The headers that should be used to detect proxies. 19 | * 20 | * @var int 21 | */ 22 | protected $headers = 23 | Request::HEADER_X_FORWARDED_FOR | 24 | Request::HEADER_X_FORWARDED_HOST | 25 | Request::HEADER_X_FORWARDED_PORT | 26 | Request::HEADER_X_FORWARDED_PROTO | 27 | Request::HEADER_X_FORWARDED_AWS_ELB; 28 | } 29 | -------------------------------------------------------------------------------- /app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /app/Http/Resources/Team.php: -------------------------------------------------------------------------------- 1 | |\Illuminate\Contracts\Support\Arrayable|\JsonSerializable 14 | */ 15 | public function toArray($request) 16 | { 17 | return parent::toArray($request); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/Livewire/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/app/Livewire/.gitkeep -------------------------------------------------------------------------------- /app/Livewire/Form.php: -------------------------------------------------------------------------------- 1 | */ 19 | public $data = []; 20 | 21 | public function mount(): void 22 | { 23 | if (! app()->environment('local')) { 24 | abort(404); 25 | } 26 | 27 | $this->form->fill(); 28 | } 29 | 30 | /** @return Forms\Components\Component[] */ 31 | protected function getFormSchema(): array 32 | { 33 | return [ 34 | Forms\Components\Builder::make('test') 35 | ->blocks([ 36 | Forms\Components\Builder\Block::make('one') 37 | ->schema([ 38 | Forms\Components\TextInput::make('one'), 39 | ]), 40 | Forms\Components\Builder\Block::make('two') 41 | ->schema([ 42 | Forms\Components\TextInput::make('two'), 43 | ]), 44 | ]), 45 | ]; 46 | } 47 | 48 | public function submit(): never 49 | { 50 | dd($this->form->getState()); 51 | } 52 | 53 | protected function getFormStatePath(): ?string 54 | { 55 | return 'data'; 56 | } 57 | 58 | public function render(): View 59 | { 60 | return view('livewire.form'); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/Livewire/Notifications.php: -------------------------------------------------------------------------------- 1 | */ 18 | public function customers(): MorphToMany 19 | { 20 | return $this->morphedByMany(Customer::class, 'addressable'); 21 | } 22 | 23 | /** @return MorphToMany */ 24 | public function brands(): MorphToMany 25 | { 26 | return $this->morphedByMany(Brand::class, 'addressable'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Models/Blog/Author.php: -------------------------------------------------------------------------------- 1 | */ 19 | public function posts(): HasMany 20 | { 21 | return $this->hasMany(Post::class, 'blog_author_id'); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Models/Blog/Category.php: -------------------------------------------------------------------------------- 1 | 20 | */ 21 | protected $casts = [ 22 | 'is_visible' => 'boolean', 23 | ]; 24 | 25 | /** @return HasMany */ 26 | public function posts(): HasMany 27 | { 28 | return $this->hasMany(Post::class, 'blog_category_id'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Models/Blog/Link.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | protected $casts = [ 26 | 'published_at' => 'date', 27 | ]; 28 | 29 | /** @return BelongsTo */ 30 | public function author(): BelongsTo 31 | { 32 | return $this->belongsTo(Author::class, 'blog_author_id'); 33 | } 34 | 35 | /** @return BelongsTo */ 36 | public function category(): BelongsTo 37 | { 38 | return $this->belongsTo(Category::class, 'blog_category_id'); 39 | } 40 | 41 | /** @return MorphMany */ 42 | public function comments(): MorphMany 43 | { 44 | return $this->morphMany(Comment::class, 'commentable'); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/Models/Comment.php: -------------------------------------------------------------------------------- 1 | 'boolean', 21 | ]; 22 | 23 | /** @return BelongsTo */ 24 | public function customer(): BelongsTo 25 | { 26 | return $this->belongsTo(Customer::class); 27 | } 28 | 29 | /** @return MorphTo */ 30 | public function commentable(): MorphTo 31 | { 32 | return $this->morphTo(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Models/Shop/Brand.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | protected $casts = [ 27 | 'is_visible' => 'boolean', 28 | ]; 29 | 30 | /** @return MorphToMany
*/ 31 | public function addresses(): MorphToMany 32 | { 33 | return $this->morphToMany(Address::class, 'addressable', 'addressables'); 34 | } 35 | 36 | /** @return HasMany */ 37 | public function products(): HasMany 38 | { 39 | return $this->hasMany(Product::class, 'shop_brand_id'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/Models/Shop/Category.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | protected $casts = [ 27 | 'is_visible' => 'boolean', 28 | ]; 29 | 30 | /** @return HasMany */ 31 | public function children(): HasMany 32 | { 33 | return $this->hasMany(Category::class, 'parent_id'); 34 | } 35 | 36 | /** @return BelongsTo */ 37 | public function parent(): BelongsTo 38 | { 39 | return $this->belongsTo(Category::class, 'parent_id'); 40 | } 41 | 42 | /** @return BelongsToMany */ 43 | public function products(): BelongsToMany 44 | { 45 | return $this->belongsToMany(Product::class, 'shop_category_product', 'shop_category_id', 'shop_product_id'); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/Models/Shop/Customer.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | protected $casts = [ 28 | 'birthday' => 'date', 29 | ]; 30 | 31 | /** @return MorphToMany
*/ 32 | public function addresses(): MorphToMany 33 | { 34 | return $this->morphToMany(Address::class, 'addressable'); 35 | } 36 | 37 | /** @return HasMany */ 38 | public function comments(): HasMany 39 | { 40 | return $this->hasMany(Comment::class); 41 | } 42 | 43 | /** @return HasManyThrough */ 44 | public function payments(): HasManyThrough 45 | { 46 | return $this->hasManyThrough(Payment::class, Order::class, 'shop_customer_id'); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/Models/Shop/Order.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | protected $fillable = [ 27 | 'number', 28 | 'total_price', 29 | 'status', 30 | 'currency', 31 | 'shipping_price', 32 | 'shipping_method', 33 | 'notes', 34 | ]; 35 | 36 | protected $casts = [ 37 | 'status' => OrderStatus::class, 38 | ]; 39 | 40 | /** @return MorphOne */ 41 | public function address(): MorphOne 42 | { 43 | return $this->morphOne(OrderAddress::class, 'addressable'); 44 | } 45 | 46 | /** @return BelongsTo */ 47 | public function customer(): BelongsTo 48 | { 49 | return $this->belongsTo(Customer::class, 'shop_customer_id'); 50 | } 51 | 52 | /** @return HasMany */ 53 | public function items(): HasMany 54 | { 55 | return $this->hasMany(OrderItem::class, 'shop_order_id'); 56 | } 57 | 58 | /** @return HasMany */ 59 | public function payments(): HasMany 60 | { 61 | return $this->hasMany(Payment::class); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/Models/Shop/OrderAddress.php: -------------------------------------------------------------------------------- 1 | */ 16 | public function addressable(): MorphTo 17 | { 18 | return $this->morphTo(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Models/Shop/OrderItem.php: -------------------------------------------------------------------------------- 1 | */ 18 | public function order(): BelongsTo 19 | { 20 | return $this->belongsTo(Order::class); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Models/Shop/Product.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | protected $casts = [ 28 | 'featured' => 'boolean', 29 | 'is_visible' => 'boolean', 30 | 'backorder' => 'boolean', 31 | 'requires_shipping' => 'boolean', 32 | 'published_at' => 'date', 33 | ]; 34 | 35 | /** @return BelongsTo */ 36 | public function brand(): BelongsTo 37 | { 38 | return $this->belongsTo(Brand::class, 'shop_brand_id'); 39 | } 40 | 41 | /** @return BelongsToMany */ 42 | public function categories(): BelongsToMany 43 | { 44 | return $this->belongsToMany(Category::class, 'shop_category_product', 'shop_product_id', 'shop_category_id')->withTimestamps(); 45 | } 46 | 47 | /** @return MorphMany */ 48 | public function comments(): MorphMany 49 | { 50 | return $this->morphMany(Comment::class, 'commentable'); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/Models/Team.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | protected $hidden = [ 26 | 'password', 27 | 'remember_token', 28 | ]; 29 | 30 | /** 31 | * @var array 32 | */ 33 | protected $casts = [ 34 | 'email_verified_at' => 'datetime', 35 | ]; 36 | 37 | public function canAccessPanel(Panel $panel): bool 38 | { 39 | return true; 40 | } 41 | 42 | public function canAccessTenant(Model $tenant): bool 43 | { 44 | return true; 45 | } 46 | 47 | /** @return Collection */ 48 | public function getTenants(Panel $panel): Collection 49 | { 50 | return Team::all(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | environment('production')) { 31 | URL::forceScheme('https'); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Providers/AuthServiceProvider.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $policies = [ 15 | // 'App\Models\Model' => 'App\Policies\ModelPolicy', 16 | ]; 17 | 18 | /** 19 | * Register any authentication / authorization services. 20 | * 21 | * @return void 22 | */ 23 | public function boot() 24 | { 25 | // 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | > 15 | */ 16 | protected $listen = [ 17 | Registered::class => [ 18 | SendEmailVerificationNotification::class, 19 | ], 20 | ]; 21 | 22 | /** 23 | * Register any events for your application. 24 | * 25 | * @return void 26 | */ 27 | public function boot() 28 | { 29 | // 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Providers/Filament/AdminPanelProvider.php: -------------------------------------------------------------------------------- 1 | default() 28 | ->id('admin') 29 | ->login(Login::class) 30 | ->discoverClusters(in: app_path('Filament/Clusters'), for: 'App\\Filament\\Clusters') 31 | ->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources') 32 | ->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages') 33 | ->pages([ 34 | Dashboard::class, 35 | ]) 36 | ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets') 37 | ->widgets([ 38 | Widgets\AccountWidget::class, 39 | Widgets\FilamentInfoWidget::class, 40 | ]) 41 | ->unsavedChangesAlerts() 42 | ->brandLogo(fn () => view('filament.app.logo')) 43 | ->brandLogoHeight('1.25rem') 44 | ->navigationGroups([ 45 | 'Shop', 46 | 'Blog', 47 | ]) 48 | ->databaseNotifications() 49 | ->middleware([ 50 | EncryptCookies::class, 51 | AddQueuedCookiesToResponse::class, 52 | StartSession::class, 53 | AuthenticateSession::class, 54 | ShareErrorsFromSession::class, 55 | VerifyCsrfToken::class, 56 | SubstituteBindings::class, 57 | DisableBladeIconComponents::class, 58 | DispatchServingFilamentEvent::class, 59 | ]) 60 | ->authMiddleware([ 61 | Authenticate::class, 62 | ]) 63 | ->plugin( 64 | SpatieLaravelTranslatablePlugin::make() 65 | ->defaultLocales(['en', 'es', 'nl']), 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/Providers/Filament/AppPanelProvider.php: -------------------------------------------------------------------------------- 1 | id('app') 27 | ->path('app') 28 | ->login(Login::class) 29 | ->registration() 30 | ->passwordReset() 31 | ->emailVerification() 32 | ->tenant(Team::class) 33 | ->tenantRegistration(RegisterTeam::class) 34 | ->discoverResources(in: app_path('Filament/App/Resources'), for: 'App\\Filament\\App\\Resources') 35 | ->discoverPages(in: app_path('Filament/App/Pages'), for: 'App\\Filament\\App\\Pages') 36 | ->discoverWidgets(in: app_path('Filament/App/Widgets'), for: 'App\\Filament\\App\\Widgets') 37 | ->middleware([ 38 | EncryptCookies::class, 39 | AddQueuedCookiesToResponse::class, 40 | StartSession::class, 41 | AuthenticateSession::class, 42 | ShareErrorsFromSession::class, 43 | VerifyCsrfToken::class, 44 | SubstituteBindings::class, 45 | DisableBladeIconComponents::class, 46 | DispatchServingFilamentEvent::class, 47 | ]) 48 | ->authMiddleware([ 49 | Authenticate::class, 50 | ]); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/Providers/HorizonServiceProvider.php: -------------------------------------------------------------------------------- 1 | configureRateLimiting(); 28 | 29 | $this->routes(function () { 30 | Route::prefix('api') 31 | ->middleware('api') 32 | ->namespace($this->namespace) 33 | ->group(base_path('routes/api.php')); 34 | 35 | Route::middleware('web') 36 | ->namespace($this->namespace) 37 | ->group(base_path('routes/web.php')); 38 | }); 39 | } 40 | 41 | /** 42 | * Configure the rate limiters for the application. 43 | * 44 | * @return void 45 | */ 46 | protected function configureRateLimiting() 47 | { 48 | RateLimiter::for('api', function (Request $request) { 49 | return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip()); 50 | }); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 34 | 35 | $status = $kernel->handle( 36 | $input = new Symfony\Component\Console\Input\ArgvInput, 37 | new Symfony\Component\Console\Output\ConsoleOutput 38 | ); 39 | 40 | /* 41 | |-------------------------------------------------------------------------- 42 | | Shutdown The Application 43 | |-------------------------------------------------------------------------- 44 | | 45 | | Once Artisan has finished running, we will fire off the shutdown events 46 | | so that any final work may be done by the application before we shut 47 | | down the process. This is the last thing to happen to the request. 48 | | 49 | */ 50 | 51 | $kernel->terminate($input, $status); 52 | 53 | exit($status); 54 | -------------------------------------------------------------------------------- /bootstrap/app.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Http\Kernel::class, 31 | App\Http\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Console\Kernel::class, 36 | App\Console\Kernel::class 37 | ); 38 | 39 | $app->singleton( 40 | Illuminate\Contracts\Debug\ExceptionHandler::class, 41 | App\Exceptions\Handler::class 42 | ); 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Return The Application 47 | |-------------------------------------------------------------------------- 48 | | 49 | | This script returns the application instance. The instance is given to 50 | | the calling script so we can separate the building of the instances 51 | | from the actual running of the application and sending responses. 52 | | 53 | */ 54 | 55 | return $app; 56 | -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel/laravel", 3 | "type": "project", 4 | "description": "The Laravel Framework.", 5 | "keywords": [ 6 | "framework", 7 | "laravel" 8 | ], 9 | "license": "MIT", 10 | "require": { 11 | "php": "^8.2", 12 | "filament/filament": "^3.0", 13 | "filament/spatie-laravel-media-library-plugin": "^3.0", 14 | "filament/spatie-laravel-settings-plugin": "^3.0", 15 | "filament/spatie-laravel-tags-plugin": "^3.0", 16 | "filament/spatie-laravel-translatable-plugin": "^3.0", 17 | "flowframe/laravel-trend": "^0.2.0", 18 | "guzzlehttp/guzzle": "^7.2", 19 | "laravel/framework": "^11.0", 20 | "laravel/horizon": "^5.21", 21 | "laravel/sanctum": "^4.0", 22 | "laravel/tinker": "^2.8", 23 | "squirephp/countries-en": "^3.3", 24 | "squirephp/currencies-en": "^3.3" 25 | }, 26 | "require-dev": { 27 | "barryvdh/laravel-debugbar": "^3.6", 28 | "fakerphp/faker": "^1.9.1", 29 | "laravel/pint": "^1.0", 30 | "laravel/sail": "^1.18", 31 | "mockery/mockery": "^1.4.4", 32 | "nunomaduro/collision": "^8.1", 33 | "larastan/larastan": "^2.1", 34 | "phpstan/phpstan-deprecation-rules": "^1.1", 35 | "phpunit/phpunit": "^10.1", 36 | "spatie/laravel-ignition": "^2.0" 37 | }, 38 | "autoload": { 39 | "psr-4": { 40 | "App\\": "app/", 41 | "Database\\Factories\\": "database/factories/", 42 | "Database\\Seeders\\": "database/seeders/" 43 | } 44 | }, 45 | "autoload-dev": { 46 | "psr-4": { 47 | "Tests\\": "tests/" 48 | } 49 | }, 50 | "scripts": { 51 | "post-autoload-dump": [ 52 | "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", 53 | "@php artisan package:discover --ansi", 54 | "@php artisan filament:upgrade" 55 | ], 56 | "post-update-cmd": [ 57 | "@php artisan vendor:publish --tag=laravel-assets --ansi --force" 58 | ], 59 | "post-root-package-install": [ 60 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 61 | ], 62 | "post-create-project-cmd": [ 63 | "@php artisan key:generate --ansi" 64 | ], 65 | "cs": [ 66 | "pint" 67 | ], 68 | "pint": "pint", 69 | "test:phpstan": "phpstan analyse", 70 | "test": [ 71 | "@test:phpstan" 72 | ] 73 | }, 74 | "extra": { 75 | "laravel": { 76 | "dont-discover": [] 77 | } 78 | }, 79 | "config": { 80 | "optimize-autoloader": true, 81 | "preferred-install": "dist", 82 | "sort-packages": true, 83 | "allow-plugins": { 84 | "composer/package-versions-deprecated": true 85 | } 86 | }, 87 | "minimum-stability": "dev", 88 | "prefer-stable": true 89 | } 90 | -------------------------------------------------------------------------------- /config/broadcasting.php: -------------------------------------------------------------------------------- 1 | env('BROADCAST_DRIVER', 'null'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Broadcast Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the broadcast connections that will be used 26 | | to broadcast events to other systems or over websockets. Samples of 27 | | each available type of connection are provided inside this array. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'pusher' => [ 34 | 'driver' => 'pusher', 35 | 'key' => env('PUSHER_APP_KEY'), 36 | 'secret' => env('PUSHER_APP_SECRET'), 37 | 'app_id' => env('PUSHER_APP_ID'), 38 | 'options' => [ 39 | 'cluster' => env('PUSHER_APP_CLUSTER'), 40 | 'useTLS' => true, 41 | ], 42 | ], 43 | 44 | 'ably' => [ 45 | 'driver' => 'ably', 46 | 'key' => env('ABLY_KEY'), 47 | ], 48 | 49 | 'redis' => [ 50 | 'driver' => 'redis', 51 | 'connection' => 'default', 52 | ], 53 | 54 | 'log' => [ 55 | 'driver' => 'log', 56 | ], 57 | 58 | 'null' => [ 59 | 'driver' => 'null', 60 | ], 61 | 62 | ], 63 | 64 | ]; 65 | -------------------------------------------------------------------------------- /config/cors.php: -------------------------------------------------------------------------------- 1 | ['api/*', 'sanctum/csrf-cookie'], 19 | 20 | 'allowed_methods' => ['*'], 21 | 22 | 'allowed_origins' => ['*'], 23 | 24 | 'allowed_origins_patterns' => [], 25 | 26 | 'allowed_headers' => ['*'], 27 | 28 | 'exposed_headers' => [], 29 | 30 | 'max_age' => 0, 31 | 32 | 'supports_credentials' => false, 33 | 34 | ]; 35 | -------------------------------------------------------------------------------- /config/filament.php: -------------------------------------------------------------------------------- 1 | [ 18 | 19 | // 'echo' => [ 20 | // 'broadcaster' => 'pusher', 21 | // 'key' => env('VITE_PUSHER_APP_KEY'), 22 | // 'cluster' => env('VITE_PUSHER_APP_CLUSTER'), 23 | // 'forceTLS' => true, 24 | // ], 25 | 26 | ], 27 | 28 | /* 29 | |-------------------------------------------------------------------------- 30 | | Default Filesystem Disk 31 | |-------------------------------------------------------------------------- 32 | | 33 | | This is the storage disk Filament will use to put media. You may use any 34 | | of the disks defined in the `config/filesystems.php`. 35 | | 36 | */ 37 | 38 | 'default_filesystem_disk' => env('FILAMENT_FILESYSTEM_DISK', 'public'), 39 | 40 | ]; 41 | -------------------------------------------------------------------------------- /config/filesystems.php: -------------------------------------------------------------------------------- 1 | env('FILESYSTEM_DRIVER', 'local'), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Filesystem Disks 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Here you may configure as many filesystem "disks" as you wish, and you 24 | | may even configure multiple disks of the same driver. Defaults have 25 | | been setup for each driver as an example of the required options. 26 | | 27 | | Supported Drivers: "local", "ftp", "sftp", "s3" 28 | | 29 | */ 30 | 31 | 'disks' => [ 32 | 33 | 'local' => [ 34 | 'driver' => 'local', 35 | 'root' => storage_path('app'), 36 | ], 37 | 38 | 'public' => [ 39 | 'driver' => 'local', 40 | 'root' => storage_path('app/public'), 41 | 'url' => env('APP_URL') . '/storage', 42 | 'visibility' => 'public', 43 | ], 44 | 45 | 's3' => [ 46 | 'driver' => 's3', 47 | 'key' => env('AWS_ACCESS_KEY_ID'), 48 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 49 | 'region' => env('AWS_DEFAULT_REGION'), 50 | 'bucket' => env('AWS_BUCKET'), 51 | 'url' => env('AWS_URL'), 52 | 'endpoint' => env('AWS_ENDPOINT'), 53 | 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), 54 | ], 55 | 56 | ], 57 | 58 | /* 59 | |-------------------------------------------------------------------------- 60 | | Symbolic Links 61 | |-------------------------------------------------------------------------- 62 | | 63 | | Here you may configure the symbolic links that will be created when the 64 | | `storage:link` Artisan command is executed. The array keys should be 65 | | the locations of the links and the values should be their targets. 66 | | 67 | */ 68 | 69 | 'links' => [ 70 | public_path('storage') => storage_path('app/public'), 71 | ], 72 | 73 | ]; 74 | -------------------------------------------------------------------------------- /config/hashing.php: -------------------------------------------------------------------------------- 1 | 'bcrypt', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Bcrypt Options 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may specify the configuration options that should be used when 26 | | passwords are hashed using the Bcrypt algorithm. This will allow you 27 | | to control the amount of time it takes to hash the given password. 28 | | 29 | */ 30 | 31 | 'bcrypt' => [ 32 | 'rounds' => env('BCRYPT_ROUNDS', 10), 33 | ], 34 | 35 | /* 36 | |-------------------------------------------------------------------------- 37 | | Argon Options 38 | |-------------------------------------------------------------------------- 39 | | 40 | | Here you may specify the configuration options that should be used when 41 | | passwords are hashed using the Argon algorithm. These will allow you 42 | | to control the amount of time it takes to hash the given password. 43 | | 44 | */ 45 | 46 | 'argon' => [ 47 | 'memory' => 1024, 48 | 'threads' => 2, 49 | 'time' => 2, 50 | ], 51 | 52 | ]; 53 | -------------------------------------------------------------------------------- /config/sanctum.php: -------------------------------------------------------------------------------- 1 | explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( 17 | '%s%s', 18 | 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', 19 | env('APP_URL') ? ',' . parse_url(env('APP_URL'), PHP_URL_HOST) : '' 20 | ))), 21 | 22 | /* 23 | |-------------------------------------------------------------------------- 24 | | Sanctum Guards 25 | |-------------------------------------------------------------------------- 26 | | 27 | | This array contains the authentication guards that will be checked when 28 | | Sanctum is trying to authenticate a request. If none of these guards 29 | | are able to authenticate the request, Sanctum will use the bearer 30 | | token that's present on an incoming request for authentication. 31 | | 32 | */ 33 | 34 | 'guard' => ['web'], 35 | 36 | /* 37 | |-------------------------------------------------------------------------- 38 | | Expiration Minutes 39 | |-------------------------------------------------------------------------- 40 | | 41 | | This value controls the number of minutes until an issued token will be 42 | | considered expired. If this value is null, personal access tokens do 43 | | not expire. This won't tweak the lifetime of first-party sessions. 44 | | 45 | */ 46 | 47 | 'expiration' => null, 48 | 49 | /* 50 | |-------------------------------------------------------------------------- 51 | | Sanctum Middleware 52 | |-------------------------------------------------------------------------- 53 | | 54 | | When authenticating your first-party SPA with Sanctum you may need to 55 | | customize some of the middleware Sanctum uses while processing the 56 | | request. You may change the middleware listed below as required. 57 | | 58 | */ 59 | 60 | 'middleware' => [ 61 | 'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class, 62 | 'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class, 63 | ], 64 | 65 | ]; 66 | -------------------------------------------------------------------------------- /config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | ], 22 | 23 | 'postmark' => [ 24 | 'token' => env('POSTMARK_TOKEN'), 25 | ], 26 | 27 | 'ses' => [ 28 | 'key' => env('AWS_ACCESS_KEY_ID'), 29 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 30 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 31 | ], 32 | 33 | ]; 34 | -------------------------------------------------------------------------------- /config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('views'), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => env( 32 | 'VIEW_COMPILED_PATH', 33 | realpath(storage_path('framework/views')) 34 | ), 35 | 36 | ]; 37 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite* 2 | -------------------------------------------------------------------------------- /database/factories/AddressFactory.php: -------------------------------------------------------------------------------- 1 | strtolower($this->faker->countryCode()), 16 | 'street' => $this->faker->streetAddress(), 17 | 'state' => $this->faker->state(), 18 | 'city' => $this->faker->city(), 19 | 'zip' => $this->faker->postcode(), 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /database/factories/Blog/AuthorFactory.php: -------------------------------------------------------------------------------- 1 | $this->faker->name(), 19 | 'email' => $this->faker->unique()->safeEmail(), 20 | 'bio' => $this->faker->realTextBetween(), 21 | 'github_handle' => $this->faker->userName(), 22 | 'twitter_handle' => $this->faker->userName(), 23 | 'created_at' => $this->faker->dateTimeBetween('-1 year', '-6 month'), 24 | 'updated_at' => $this->faker->dateTimeBetween('-5 month', 'now'), 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /database/factories/Blog/CategoryFactory.php: -------------------------------------------------------------------------------- 1 | $name = $this->faker->unique()->words(3, true), 20 | 'slug' => Str::slug($name), 21 | 'description' => $this->faker->realText(), 22 | 'is_visible' => $this->faker->boolean(), 23 | 'created_at' => $this->faker->dateTimeBetween('-1 year', '-6 month'), 24 | 'updated_at' => $this->faker->dateTimeBetween('-5 month', 'now'), 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /database/factories/Blog/LinkFactory.php: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | class LinkFactory extends Factory 14 | { 15 | use CanCreateImages; 16 | 17 | /** 18 | * Define the model's default state. 19 | * 20 | * @return array 21 | */ 22 | public function definition(): array 23 | { 24 | return [ 25 | 'url' => $this->faker->url(), 26 | 'title' => [ 27 | 'en' => Str::title($this->faker->words(asText: true)), 28 | 'es' => Str::title($this->faker->words(asText: true)), 29 | 'nl' => Str::title($this->faker->words(asText: true)), 30 | ], 31 | 'description' => [ 32 | 'en' => $this->faker->sentence(), 33 | 'es' => $this->faker->sentence(), 34 | 'nl' => $this->faker->sentence(), 35 | ], 36 | 'color' => $this->faker->hexColor(), 37 | 'image' => $this->createImage(LocalImages::SIZE_1280x720), 38 | ]; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /database/factories/Blog/PostFactory.php: -------------------------------------------------------------------------------- 1 | $title = $this->faker->unique()->sentence(4), 23 | 'slug' => Str::slug($title), 24 | 'content' => $this->faker->realText(), 25 | 'image' => $this->createImage(), 26 | 'published_at' => $this->faker->dateTimeBetween('-6 month', '+1 month'), 27 | 'created_at' => $this->faker->dateTimeBetween('-1 year', '-6 month'), 28 | 'updated_at' => $this->faker->dateTimeBetween('-5 month', 'now'), 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /database/factories/CommentFactory.php: -------------------------------------------------------------------------------- 1 | $this->faker->catchPhrase(), 19 | 'content' => $this->faker->text(), 20 | 'is_visible' => $this->faker->boolean(), 21 | 'created_at' => $this->faker->dateTimeBetween('-1 year', '-6 month'), 22 | 'updated_at' => $this->faker->dateTimeBetween('-5 month', 'now'), 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /database/factories/Concerns/CanCreateImages.php: -------------------------------------------------------------------------------- 1 | getPathname()); 16 | 17 | $filename = Str::uuid() . '.jpg'; 18 | 19 | Storage::disk('public')->put($filename, $image); 20 | 21 | return $filename; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /database/factories/Shop/BrandFactory.php: -------------------------------------------------------------------------------- 1 | $name = $this->faker->unique()->company(), 20 | 'slug' => Str::slug($name), 21 | 'website' => 'https://www.' . $this->faker->domainName(), 22 | 'description' => $this->faker->realText(), 23 | 'is_visible' => $this->faker->boolean(), 24 | 'created_at' => $this->faker->dateTimeBetween('-1 year', '-6 month'), 25 | 'updated_at' => $this->faker->dateTimeBetween('-5 month', 'now'), 26 | ]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /database/factories/Shop/CategoryFactory.php: -------------------------------------------------------------------------------- 1 | $name = $this->faker->unique()->words(3, true), 20 | 'slug' => Str::slug($name), 21 | 'description' => $this->faker->realText(), 22 | 'is_visible' => $this->faker->boolean(), 23 | 'created_at' => $this->faker->dateTimeBetween('-1 year', '-6 month'), 24 | 'updated_at' => $this->faker->dateTimeBetween('-5 month', 'now'), 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /database/factories/Shop/CustomerFactory.php: -------------------------------------------------------------------------------- 1 | $this->faker->name(), 19 | 'email' => $this->faker->unique()->safeEmail(), 20 | 'phone' => $this->faker->phoneNumber(), 21 | 'birthday' => $this->faker->dateTimeBetween('-35 years', '-18 years'), 22 | 'gender' => $this->faker->randomElement(['male', 'female']), 23 | 'created_at' => $this->faker->dateTimeBetween('-1 year', '-6 month'), 24 | 'updated_at' => $this->faker->dateTimeBetween('-5 month', 'now'), 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /database/factories/Shop/OrderAddressFactory.php: -------------------------------------------------------------------------------- 1 | strtolower($this->faker->countryCode()), 16 | 'street' => $this->faker->streetAddress(), 17 | 'state' => $this->faker->state(), 18 | 'city' => $this->faker->city(), 19 | 'zip' => $this->faker->postcode(), 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /database/factories/Shop/OrderFactory.php: -------------------------------------------------------------------------------- 1 | 'OR' . $this->faker->unique()->randomNumber(6), 19 | 'currency' => strtolower($this->faker->currencyCode()), 20 | 'total_price' => $this->faker->randomFloat(2, 100, 2000), 21 | 'status' => $this->faker->randomElement(['new', 'processing', 'shipped', 'delivered', 'cancelled']), 22 | 'shipping_price' => $this->faker->randomFloat(2, 100, 500), 23 | 'shipping_method' => $this->faker->randomElement(['free', 'flat', 'flat_rate', 'flat_rate_per_item']), 24 | 'notes' => $this->faker->realText(100), 25 | 'created_at' => $this->faker->dateTimeBetween('-1 year', 'now'), 26 | 'updated_at' => $this->faker->dateTimeBetween('-5 month', 'now'), 27 | ]; 28 | } 29 | 30 | public function configure(): Factory 31 | { 32 | return $this->afterCreating(function (Order $order) { 33 | $order->address()->save(OrderAddressFactory::new()->make()); 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /database/factories/Shop/OrderItemFactory.php: -------------------------------------------------------------------------------- 1 | $this->faker->numberBetween(1, 10), 19 | 'unit_price' => $this->faker->randomFloat(2, 100, 500), 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /database/factories/Shop/PaymentFactory.php: -------------------------------------------------------------------------------- 1 | 'PAY' . $this->faker->unique()->randomNumber(6), 17 | 'currency' => $this->faker->randomElement(collect(Currency::getCurrencies())->keys()), 18 | 'amount' => $this->faker->randomFloat(2, 100, 2000), 19 | 'provider' => $this->faker->randomElement(['stripe', 'paypal']), 20 | 'method' => $this->faker->randomElement(['credit_card', 'bank_transfer', 'paypal']), 21 | 'created_at' => $this->faker->dateTimeBetween('-1 year', '-6 month'), 22 | 'updated_at' => $this->faker->dateTimeBetween('-5 month', 'now'), 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /database/factories/Shop/ProductFactory.php: -------------------------------------------------------------------------------- 1 | $name = $this->faker->unique()->catchPhrase(), 22 | 'slug' => Str::slug($name), 23 | 'sku' => $this->faker->unique()->ean8(), 24 | 'barcode' => $this->faker->ean13(), 25 | 'description' => $this->faker->realText(), 26 | 'qty' => $this->faker->randomDigitNotNull(), 27 | 'security_stock' => $this->faker->randomDigitNotNull(), 28 | 'featured' => $this->faker->boolean(), 29 | 'is_visible' => $this->faker->boolean(), 30 | 'old_price' => $this->faker->randomFloat(2, 100, 500), 31 | 'price' => $this->faker->randomFloat(2, 80, 400), 32 | 'cost' => $this->faker->randomFloat(2, 50, 200), 33 | 'type' => $this->faker->randomElement(['deliverable', 'downloadable']), 34 | 'published_at' => $this->faker->dateTimeBetween('-1 year', '+1 year'), 35 | 'created_at' => $this->faker->dateTimeBetween('-1 year', '-6 month'), 36 | 'updated_at' => $this->faker->dateTimeBetween('-5 month', 'now'), 37 | ]; 38 | } 39 | 40 | public function configure(): ProductFactory 41 | { 42 | return $this->afterCreating(function (Product $product) { 43 | try { 44 | $product 45 | ->addMedia(LocalImages::getRandomFile()) 46 | ->preservingOriginal() 47 | ->toMediaCollection('product-images'); 48 | } catch (UnreachableUrl $exception) { 49 | return; 50 | } 51 | }); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | $this->faker->name(), 14 | 'email' => $this->faker->unique()->safeEmail(), 15 | 'email_verified_at' => now(), 16 | 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 17 | 'remember_token' => Str::random(10), 18 | ]; 19 | } 20 | 21 | public function unverified(): Factory 22 | { 23 | return $this->state(function (array $attributes) { 24 | return [ 25 | 'email_verified_at' => null, 26 | ]; 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('name'); 19 | $table->string('email')->unique(); 20 | $table->timestamp('email_verified_at')->nullable(); 21 | $table->string('password'); 22 | $table->rememberToken(); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('users'); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_100000_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 18 | $table->string('token'); 19 | $table->timestamp('created_at')->nullable(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('password_resets'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /database/migrations/2019_08_19_000000_create_failed_jobs_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('uuid')->unique(); 19 | $table->text('connection'); 20 | $table->text('queue'); 21 | $table->longText('payload'); 22 | $table->longText('exception'); 23 | $table->timestamp('failed_at')->useCurrent(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('failed_jobs'); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->morphs('tokenable'); 19 | $table->string('name'); 20 | $table->string('token', 64)->unique(); 21 | $table->text('abilities')->nullable(); 22 | $table->timestamp('last_used_at')->nullable(); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('personal_access_tokens'); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /database/migrations/2021_12_13_055514_create_media_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 13 | 14 | $table->morphs('model'); 15 | $table->uuid('uuid')->nullable()->unique(); 16 | $table->string('collection_name'); 17 | $table->string('name'); 18 | $table->string('file_name'); 19 | $table->string('mime_type')->nullable(); 20 | $table->string('disk'); 21 | $table->string('conversions_disk')->nullable(); 22 | $table->unsignedBigInteger('size'); 23 | $table->json('manipulations'); 24 | $table->json('custom_properties'); 25 | $table->json('generated_conversions'); 26 | $table->json('responsive_images'); 27 | $table->unsignedInteger('order_column')->nullable(); 28 | 29 | $table->nullableTimestamps(); 30 | }); 31 | } 32 | 33 | public function down() 34 | { 35 | Schema::dropIfExists('media'); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /database/migrations/2021_12_13_072541_create_tag_tables.php: -------------------------------------------------------------------------------- 1 | id(); 13 | 14 | $table->json('name'); 15 | $table->json('slug'); 16 | $table->string('type')->nullable(); 17 | $table->integer('order_column')->nullable(); 18 | 19 | $table->timestamps(); 20 | }); 21 | 22 | Schema::create('taggables', function (Blueprint $table) { 23 | $table->foreignId('tag_id')->constrained()->cascadeOnDelete(); 24 | 25 | $table->morphs('taggable'); 26 | 27 | $table->unique(['tag_id', 'taggable_id', 'taggable_type']); 28 | }); 29 | } 30 | 31 | public function down() 32 | { 33 | Schema::dropIfExists('taggables'); 34 | Schema::dropIfExists('tags'); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /database/migrations/2021_12_13_072624_create_settings_table.php: -------------------------------------------------------------------------------- 1 | id(); 13 | 14 | $table->string('group')->index(); 15 | $table->string('name'); 16 | $table->boolean('locked'); 17 | $table->json('payload'); 18 | 19 | $table->timestamps(); 20 | }); 21 | } 22 | 23 | public function down() 24 | { 25 | Schema::dropIfExists('settings'); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /database/migrations/2021_12_13_073001_create_blog_authors_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('name'); 19 | $table->string('email')->unique(); 20 | $table->string('photo')->nullable(); 21 | $table->longText('bio')->nullable(); 22 | $table->string('github_handle')->nullable(); 23 | $table->string('twitter_handle')->nullable(); 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('blog_authors'); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /database/migrations/2021_12_13_073006_create_blog_categories_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('name'); 19 | $table->string('slug')->unique(); 20 | $table->longText('description')->nullable(); 21 | $table->boolean('is_visible')->default(false); 22 | $table->string('seo_title', 60)->nullable(); 23 | $table->string('seo_description', 160)->nullable(); 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('blog_categories'); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /database/migrations/2021_12_13_073022_create_blog_posts_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->foreignId('blog_author_id')->nullable()->cascadeOnDelete(); 19 | $table->foreignId('blog_category_id')->nullable()->nullOnDelete(); 20 | $table->string('title'); 21 | $table->string('slug')->unique(); 22 | $table->longText('content'); 23 | $table->date('published_at')->nullable(); 24 | $table->string('seo_title', 60)->nullable(); 25 | $table->string('seo_description', 160)->nullable(); 26 | $table->string('image')->nullable(); 27 | $table->timestamps(); 28 | }); 29 | } 30 | 31 | /** 32 | * Reverse the migrations. 33 | * 34 | * @return void 35 | */ 36 | public function down() 37 | { 38 | Schema::dropIfExists('blog_posts'); 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /database/migrations/2021_12_13_153307_create_shop_customers_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('name'); 19 | $table->string('email')->unique(); 20 | $table->string('photo')->nullable(); 21 | $table->enum('gender', ['male', 'female']); 22 | $table->string('phone')->nullable(); 23 | $table->date('birthday')->nullable(); 24 | $table->timestamps(); 25 | $table->softDeletes(); 26 | }); 27 | } 28 | 29 | /** 30 | * Reverse the migrations. 31 | * 32 | * @return void 33 | */ 34 | public function down() 35 | { 36 | Schema::dropIfExists('shop_customers'); 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /database/migrations/2021_12_13_155621_create_shop_categories_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->foreignId('parent_id')->nullable()->constrained('shop_categories')->cascadeOnDelete(); 19 | $table->string('name'); 20 | $table->string('slug')->unique(); 21 | $table->longText('description')->nullable(); 22 | $table->unsignedSmallInteger('position')->default(0); 23 | $table->boolean('is_visible')->default(false); 24 | $table->string('seo_title', 60)->nullable(); 25 | $table->string('seo_description', 160)->nullable(); 26 | $table->timestamps(); 27 | }); 28 | } 29 | 30 | /** 31 | * Reverse the migrations. 32 | * 33 | * @return void 34 | */ 35 | public function down() 36 | { 37 | Schema::dropIfExists('shop_categories'); 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /database/migrations/2021_12_13_164316_create_shop_brands_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('name'); 19 | $table->string('slug')->unique(); 20 | $table->string('website')->nullable(); 21 | $table->longText('description')->nullable(); 22 | $table->unsignedSmallInteger('position')->default(0); 23 | $table->boolean('is_visible')->default(false); 24 | $table->string('seo_title', 60)->nullable(); 25 | $table->string('seo_description', 160)->nullable(); 26 | $table->integer('sort')->nullable(); 27 | $table->timestamps(); 28 | }); 29 | } 30 | 31 | /** 32 | * Reverse the migrations. 33 | * 34 | * @return void 35 | */ 36 | public function down() 37 | { 38 | Schema::dropIfExists('shop_brands'); 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /database/migrations/2021_12_13_164519_create_shop_products_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->foreignId('shop_brand_id')->nullable()->constrained()->nullOnDelete(); 19 | $table->string('name'); 20 | $table->string('slug')->unique()->nullable(); 21 | $table->string('sku')->unique()->nullable(); 22 | $table->string('barcode')->unique()->nullable(); 23 | $table->longText('description')->nullable(); 24 | $table->unsignedBigInteger('qty')->default(0); 25 | $table->unsignedBigInteger('security_stock')->default(0); 26 | $table->boolean('featured')->default(false); 27 | $table->boolean('is_visible')->default(false); 28 | $table->decimal('old_price', 10, 2)->nullable(); 29 | $table->decimal('price', 10, 2)->nullable(); 30 | $table->decimal('cost', 10, 2)->nullable(); 31 | $table->enum('type', ['deliverable', 'downloadable'])->nullable(); 32 | $table->boolean('backorder')->default(false); 33 | $table->boolean('requires_shipping')->default(false); 34 | $table->date('published_at')->nullable(); 35 | $table->string('seo_title', 60)->nullable(); 36 | $table->string('seo_description', 160)->nullable(); 37 | $table->decimal('weight_value', 10, 2)->nullable() 38 | ->default(0.00) 39 | ->unsigned(); 40 | $table->string('weight_unit')->default('kg'); 41 | $table->decimal('height_value', 10, 2)->nullable() 42 | ->default(0.00) 43 | ->unsigned(); 44 | $table->string('height_unit')->default('cm'); 45 | $table->decimal('width_value', 10, 2)->nullable() 46 | ->default(0.00) 47 | ->unsigned(); 48 | $table->string('width_unit')->default('cm'); 49 | $table->decimal('depth_value', 10, 2)->nullable() 50 | ->default(0.00) 51 | ->unsigned(); 52 | $table->string('depth_unit')->default('cm'); 53 | $table->decimal('volume_value', 10, 2)->nullable() 54 | ->default(0.00) 55 | ->unsigned(); 56 | $table->string('volume_unit')->default('l'); 57 | $table->timestamps(); 58 | }); 59 | } 60 | 61 | /** 62 | * Reverse the migrations. 63 | * 64 | * @return void 65 | */ 66 | public function down() 67 | { 68 | Schema::dropIfExists('shop_products'); 69 | } 70 | }; 71 | -------------------------------------------------------------------------------- /database/migrations/2021_12_13_164524_create_shop_category_product_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->foreignId('shop_category_id'); 19 | $table->foreignId('shop_product_id'); 20 | $table->timestamps(); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Schema::dropIfExists('shop_category_product'); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /database/migrations/2021_12_13_165855_create_shop_orders_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->foreignId('shop_customer_id')->nullable()->constrained()->nullOnDelete(); 19 | $table->string('number', 32)->unique(); 20 | $table->decimal('total_price', 12, 2)->nullable(); 21 | $table->enum('status', ['new', 'processing', 'shipped', 'delivered', 'cancelled'])->default('new'); 22 | $table->string('currency'); 23 | $table->decimal('shipping_price')->nullable(); 24 | $table->string('shipping_method')->nullable(); 25 | $table->text('notes')->nullable(); 26 | $table->timestamps(); 27 | $table->softDeletes(); 28 | }); 29 | } 30 | 31 | /** 32 | * Reverse the migrations. 33 | * 34 | * @return void 35 | */ 36 | public function down() 37 | { 38 | Schema::dropIfExists('shop_orders'); 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /database/migrations/2021_12_13_182904_create_shop_order_items_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->foreignId('shop_order_id')->nullable()->constrained()->cascadeOnDelete(); 19 | $table->foreignId('shop_product_id')->nullable()->constrained()->cascadeOnDelete(); 20 | $table->integer('qty'); 21 | $table->decimal('unit_price', 10, 2); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('shop_order_items'); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /database/migrations/2021_12_13_184540_create_addresses_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->morphs('addressable'); 19 | $table->string('country')->nullable(); 20 | $table->string('street')->nullable(); 21 | $table->string('city')->nullable(); 22 | $table->string('state')->nullable(); 23 | $table->string('zip')->nullable(); 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('shop_order_addresses'); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /database/migrations/2022_06_01_232533_alter_order_items_add_sort_column.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('sort')->default(0)->after('id'); 13 | }); 14 | } 15 | 16 | public function down() 17 | { 18 | Schema::table('shop_order_items', function (Blueprint $table) { 19 | $table->dropColumn('sort'); 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /database/migrations/2022_06_09_091930_create_comments_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | 17 | $table->foreignIdFor(Customer::class)->nullable()->constrained('shop_customers')->cascadeOnDelete(); 18 | $table->morphs('commentable'); 19 | $table->text('title')->nullable(); 20 | $table->text('content')->nullable(); 21 | $table->boolean('is_visible')->default(false); 22 | 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | public function down() 28 | { 29 | Schema::dropIfExists('comments'); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /database/migrations/2022_06_09_092322_create_payments_table.php: -------------------------------------------------------------------------------- 1 | id(); 14 | 15 | $table->foreignIdFor(Order::class); 16 | 17 | $table->string('reference'); 18 | 19 | $table->string('provider'); 20 | 21 | $table->string('method'); 22 | 23 | $table->decimal('amount'); 24 | 25 | $table->string('currency'); 26 | 27 | $table->timestamps(); 28 | }); 29 | } 30 | 31 | public function down() 32 | { 33 | Schema::dropIfExists('shop_payments'); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /database/migrations/2022_06_09_155042_create_addressable_table.php: -------------------------------------------------------------------------------- 1 | id(); 13 | $table->string('country')->nullable(); 14 | $table->string('street')->nullable(); 15 | $table->string('city')->nullable(); 16 | $table->string('state')->nullable(); 17 | $table->string('zip')->nullable(); 18 | 19 | // Determine database type and use appropriate syntax for generated columns 20 | if (DB::getDriverName() === 'pgsql') { 21 | // PostgreSQL requires stored columns with || for concatenation 22 | $table->string('full_address')->storedAs("street || ', ' || zip || ' ' || city"); 23 | } elseif (DB::getDriverName() === 'sqlite') { 24 | // SQLite uses || for concatenation, virtualAs is used 25 | $table->string('full_address')->virtualAs("street || ', ' || zip || ' ' || city"); 26 | } else { 27 | // MySQL uses CONCAT for string concatenation 28 | $table->string('full_address')->virtualAs("CONCAT(street, ', ', zip, ' ', city)"); 29 | } 30 | 31 | $table->timestamps(); 32 | }); 33 | 34 | Schema::create('addressables', function (Blueprint $table) { 35 | $table->foreignId('address_id'); 36 | $table->morphs('addressable'); 37 | }); 38 | } 39 | 40 | public function down() 41 | { 42 | Schema::dropIfExists('addresses'); 43 | Schema::dropIfExists('addressables'); 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /database/migrations/2022_09_10_131605_create_notifications_table.php: -------------------------------------------------------------------------------- 1 | uuid('id')->primary(); 18 | $table->string('type'); 19 | $table->morphs('notifiable'); 20 | $table->text('data'); 21 | $table->timestamp('read_at')->nullable(); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('notifications'); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /database/migrations/2022_10_27_140431_create_teams_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('name'); 19 | $table->timestamps(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('teams'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /database/migrations/2023_11_29_144716_create_job_batches_table.php: -------------------------------------------------------------------------------- 1 | string('id')->primary(); 16 | $table->string('name'); 17 | $table->integer('total_jobs'); 18 | $table->integer('pending_jobs'); 19 | $table->integer('failed_jobs'); 20 | $table->longText('failed_job_ids'); 21 | $table->mediumText('options')->nullable(); 22 | $table->integer('cancelled_at')->nullable(); 23 | $table->integer('created_at'); 24 | $table->integer('finished_at')->nullable(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | */ 31 | public function down(): void 32 | { 33 | Schema::dropIfExists('job_batches'); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /database/migrations/2023_11_29_144720_create_imports_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->timestamp('completed_at')->nullable(); 17 | $table->string('file_name'); 18 | $table->string('file_path'); 19 | $table->string('importer'); 20 | $table->unsignedInteger('processed_rows')->default(0); 21 | $table->unsignedInteger('total_rows'); 22 | $table->unsignedInteger('successful_rows')->default(0); 23 | $table->foreignId('user_id')->constrained()->cascadeOnDelete(); 24 | $table->timestamps(); 25 | }); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /database/migrations/2023_11_29_144721_create_failed_import_rows_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->json('data'); 17 | $table->foreignId('import_id')->constrained()->cascadeOnDelete(); 18 | $table->text('validation_error')->nullable(); 19 | $table->timestamps(); 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /database/migrations/2023_12_17_112735_create_blog_links_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->string('url'); 17 | $table->json('title'); 18 | $table->json('description'); 19 | $table->string('color'); 20 | $table->string('image')->nullable(); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | */ 28 | public function down(): void 29 | { 30 | Schema::dropIfExists('blog_links'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /database/migrations/2024_01_01_105157_create_exports_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->timestamp('completed_at')->nullable(); 17 | $table->string('file_disk'); 18 | $table->string('file_name')->nullable(); 19 | $table->string('exporter'); 20 | $table->unsignedInteger('processed_rows')->default(0); 21 | $table->unsignedInteger('total_rows'); 22 | $table->unsignedInteger('successful_rows')->default(0); 23 | $table->foreignId('user_id')->constrained()->cascadeOnDelete(); 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | */ 31 | public function down(): void 32 | { 33 | Schema::dropIfExists('exports'); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /database/seeders/LocalImages.php: -------------------------------------------------------------------------------- 1 | random(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/05e68fd7-d7ac-46a3-837e-20937f8dc899.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/05e68fd7-d7ac-46a3-837e-20937f8dc899.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/3188fb8e-15a9-4afb-9182-1aebdcf11b83.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/3188fb8e-15a9-4afb-9182-1aebdcf11b83.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/50f608f8-2549-4ecf-b6f6-a5997c13cb63.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/50f608f8-2549-4ecf-b6f6-a5997c13cb63.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/5b22e6fe-5958-4a9c-99f1-33bf59085469.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/5b22e6fe-5958-4a9c-99f1-33bf59085469.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/609dd36a-1011-4185-b736-63971a6fb854.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/609dd36a-1011-4185-b736-63971a6fb854.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/708c814b-0bbf-40f9-af54-f15673585d99.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/708c814b-0bbf-40f9-af54-f15673585d99.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/80043582-b25d-4403-8166-03baddfb96bc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/80043582-b25d-4403-8166-03baddfb96bc.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/80654c36-50f4-4144-91e9-58fc49b83f90.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/80654c36-50f4-4144-91e9-58fc49b83f90.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/9144a5b3-efc6-42de-8b2d-fb77ea0656c6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/9144a5b3-efc6-42de-8b2d-fb77ea0656c6.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/99b95dcc-4a4f-4523-922a-b6f776d09faa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/99b95dcc-4a4f-4523-922a-b6f776d09faa.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/9b3227b0-584c-48f4-962f-b42318bade61.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/9b3227b0-584c-48f4-962f-b42318bade61.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/9cc59994-a348-4a55-8885-b6d478e2d2c7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/9cc59994-a348-4a55-8885-b6d478e2d2c7.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/9eda78f4-ac0c-4af9-b6a8-14f8727294dd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/9eda78f4-ac0c-4af9-b6a8-14f8727294dd.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/b5d43aee-bf02-4331-8916-b10523ef861f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/b5d43aee-bf02-4331-8916-b10523ef861f.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/cb6ca3f6-3643-4bc1-a0de-c113db3a92e0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/cb6ca3f6-3643-4bc1-a0de-c113db3a92e0.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/ccd5cbc5-afa7-4709-b572-9f72c6716846.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/ccd5cbc5-afa7-4709-b572-9f72c6716846.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/d970b8da-95e6-456e-9ddb-7cb1aad2de56.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/d970b8da-95e6-456e-9ddb-7cb1aad2de56.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/dc5d4460-1637-4ae5-ab05-6732b0e9d3b8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/dc5d4460-1637-4ae5-ab05-6732b0e9d3b8.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/dd133d03-b444-4a19-a728-2eaab2a547ee.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/dd133d03-b444-4a19-a728-2eaab2a547ee.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/e837e969-cbfe-4995-aaea-ee32cf4ba4d0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/e837e969-cbfe-4995-aaea-ee32cf4ba4d0.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/f4e246e7-8bee-4011-8c8d-debff845d198.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/f4e246e7-8bee-4011-8c8d-debff845d198.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/f9697b3c-72df-4917-8317-6c3bdc530225.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/f9697b3c-72df-4917-8317-6c3bdc530225.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/1280x720/ffe9e024-8a9c-4bbb-ae13-e99a620ae2f7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/1280x720/ffe9e024-8a9c-4bbb-ae13-e99a620ae2f7.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/1aa69e68-a504-4495-bc38-5c520d035d8b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/1aa69e68-a504-4495-bc38-5c520d035d8b.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/20d2e61e-3273-4521-9c47-e56a68c892fb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/20d2e61e-3273-4521-9c47-e56a68c892fb.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/248eadf6-5227-42f3-ad31-1c320febdb7b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/248eadf6-5227-42f3-ad31-1c320febdb7b.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/2f5c09b5-6268-47b2-8e0b-c4890850e727.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/2f5c09b5-6268-47b2-8e0b-c4890850e727.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/3b95f9cc-e3e3-48d3-b743-443210fa19ec.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/3b95f9cc-e3e3-48d3-b743-443210fa19ec.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/3b9f504b-d276-4d4a-9997-68979f1bddcc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/3b9f504b-d276-4d4a-9997-68979f1bddcc.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/447a4c77-e7a2-49a3-8015-2dc5ba055c24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/447a4c77-e7a2-49a3-8015-2dc5ba055c24.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/482659c5-764a-4071-848a-fa1fbd786fd5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/482659c5-764a-4071-848a-fa1fbd786fd5.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/503a4fac-68d7-4b64-ad44-5c2ec3986b94.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/503a4fac-68d7-4b64-ad44-5c2ec3986b94.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/57623f03-f7c2-4179-a366-f1530993bc09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/57623f03-f7c2-4179-a366-f1530993bc09.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/680520bc-e880-4704-8dc7-a425d55b7a81.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/680520bc-e880-4704-8dc7-a425d55b7a81.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/74d81728-0dc2-43e2-a7da-332e2e2e6c89.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/74d81728-0dc2-43e2-a7da-332e2e2e6c89.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/7e4b0b96-99df-4d1e-84fa-dad2b398f172.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/7e4b0b96-99df-4d1e-84fa-dad2b398f172.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/873353ff-3d3a-4bfc-a02d-22949e6e4558.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/873353ff-3d3a-4bfc-a02d-22949e6e4558.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/948bfac1-6d9b-430f-86fc-8d2d6ef680ed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/948bfac1-6d9b-430f-86fc-8d2d6ef680ed.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/b02337ca-473b-4ae1-957b-0c7854161f8e.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/b02337ca-473b-4ae1-957b-0c7854161f8e.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/b14d2dca-4d45-4cc0-8d8b-864e10081dac.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/b14d2dca-4d45-4cc0-8d8b-864e10081dac.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/b37987d1-a9ad-4671-9066-9812a033fdf4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/b37987d1-a9ad-4671-9066-9812a033fdf4.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/cf755312-0709-4f40-be4a-bba7edbcdabb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/cf755312-0709-4f40-be4a-bba7edbcdabb.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/dce10027-9b5d-44a5-91ed-7caeb23100bd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/dce10027-9b5d-44a5-91ed-7caeb23100bd.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/e5d18094-036b-4c48-8232-8e0d9971cca0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/e5d18094-036b-4c48-8232-8e0d9971cca0.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/edc07898-49a5-4eb0-8af8-2a9ceeb3baf5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/edc07898-49a5-4eb0-8af8-2a9ceeb3baf5.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/f3f0ce20-b7a3-47db-b907-c77c5e6ca038.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/f3f0ce20-b7a3-47db-b907-c77c5e6ca038.jpg -------------------------------------------------------------------------------- /database/seeders/local_images/200x200/f8c8557d-bd70-4cf7-978c-89f35e918c8f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/database/seeders/local_images/200x200/f8c8557d-bd70-4cf7-978c-89f35e918c8f.jpg -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "filament-demo", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build" 8 | }, 9 | "devDependencies": { 10 | "@alpinejs/focus": "^3.10.3", 11 | "@tailwindcss/forms": "^0.5.3", 12 | "@tailwindcss/typography": "^0.5.9", 13 | "alpinejs": "^3.10.3", 14 | "autoprefixer": "^10.4.14", 15 | "laravel-vite-plugin": "^0.5.0", 16 | "postcss": "^8.4.28", 17 | "postcss-nesting": "^12.0.1", 18 | "tailwindcss": "^3.3.3", 19 | "tippy.js": "^6.3.7", 20 | "vite": "^3.0.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | includes: 2 | - ./vendor/larastan/larastan/extension.neon 3 | - ./vendor/phpstan/phpstan-deprecation-rules/rules.neon 4 | 5 | parameters: 6 | paths: 7 | - app 8 | level: 8 9 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | tests/Unit 10 | 11 | 12 | tests/Feature 13 | 14 | 15 | 16 | 17 | app 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /pint.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "laravel", 3 | "rules": { 4 | "blank_line_before_statement": true, 5 | "concat_space": { 6 | "spacing": "one" 7 | }, 8 | "method_argument_space": true, 9 | "single_trait_insert_per_statement": true, 10 | "types_spaces": { 11 | "space": "single" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | 'tailwindcss/nesting': 'postcss-nesting', 4 | tailwindcss: {}, 5 | autoprefixer: {}, 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Send Requests To Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /public/css/filament/support/support.css: -------------------------------------------------------------------------------- 1 | .fi-pagination-items,.fi-pagination-overview,.fi-pagination-records-per-page-select:not(.fi-compact){display:none}@supports (container-type:inline-size){.fi-pagination{container-type:inline-size}@container (min-width: 28rem){.fi-pagination-records-per-page-select.fi-compact{display:none}.fi-pagination-records-per-page-select:not(.fi-compact){display:inline}}@container (min-width: 56rem){.fi-pagination:not(.fi-simple)>.fi-pagination-previous-btn{display:none}.fi-pagination-overview{display:inline}.fi-pagination:not(.fi-simple)>.fi-pagination-next-btn{display:none}.fi-pagination-items{display:flex}}}@supports not (container-type:inline-size){@media (min-width:640px){.fi-pagination-records-per-page-select.fi-compact{display:none}.fi-pagination-records-per-page-select:not(.fi-compact){display:inline}}@media (min-width:768px){.fi-pagination:not(.fi-simple)>.fi-pagination-previous-btn{display:none}.fi-pagination-overview{display:inline}.fi-pagination:not(.fi-simple)>.fi-pagination-next-btn{display:none}.fi-pagination-items{display:flex}}}.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{background-color:#333;border-radius:4px;color:#fff;font-size:14px;line-height:1.4;outline:0;position:relative;transition-property:transform,visibility,opacity;white-space:normal}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{border-top-color:initial;border-width:8px 8px 0;bottom:-7px;left:0;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:initial;border-width:0 8px 8px;left:0;top:-7px;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-left-color:initial;border-width:8px 0 8px 8px;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{border-right-color:initial;border-width:8px 8px 8px 0;left:-7px;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{color:#333;height:16px;width:16px}.tippy-arrow:before{border-color:transparent;border-style:solid;content:"";position:absolute}.tippy-content{padding:5px 9px;position:relative;z-index:1}.tippy-box[data-theme~=light]{background-color:#fff;box-shadow:0 0 20px 4px #9aa1b126,0 4px 80px -8px #24282f40,0 4px 4px -2px #5b5e6926;color:#26323d}.tippy-box[data-theme~=light][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=light][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff}.tippy-box[data-theme~=light][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=light][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff}.tippy-box[data-theme~=light]>.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=light]>.tippy-svg-arrow{fill:#fff}.fi-sortable-ghost{opacity:.3} -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/public/favicon.ico -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class); 50 | 51 | $response = $kernel->handle( 52 | $request = Request::capture() 53 | )->send(); 54 | 55 | $kernel->terminate($request, $response); 56 | -------------------------------------------------------------------------------- /public/js/filament/forms/components/key-value.js: -------------------------------------------------------------------------------- 1 | function r({state:o}){return{state:o,rows:[],shouldUpdateRows:!0,init:function(){this.updateRows(),this.rows.length<=0?this.rows.push({key:"",value:""}):this.updateState(),this.$watch("state",(t,e)=>{let s=i=>i===null?0:Array.isArray(i)?i.length:typeof i!="object"?0:Object.keys(i).length;s(t)===0&&s(e)===0||this.updateRows()})},addRow:function(){this.rows.push({key:"",value:""}),this.updateState()},deleteRow:function(t){this.rows.splice(t,1),this.rows.length<=0&&this.addRow(),this.updateState()},reorderRows:function(t){let e=Alpine.raw(this.rows);this.rows=[];let s=e.splice(t.oldIndex,1)[0];e.splice(t.newIndex,0,s),this.$nextTick(()=>{this.rows=e,this.updateState()})},updateRows:function(){if(!this.shouldUpdateRows){this.shouldUpdateRows=!0;return}let t=[];for(let[e,s]of Object.entries(this.state??{}))t.push({key:e,value:s});this.rows=t},updateState:function(){let t={};this.rows.forEach(e=>{e.key===""||e.key===null||(t[e.key]=e.value)}),this.shouldUpdateRows=!1,this.state=t}}}export{r as default}; 2 | -------------------------------------------------------------------------------- /public/js/filament/forms/components/tags-input.js: -------------------------------------------------------------------------------- 1 | function i({state:a,splitKeys:n}){return{newTag:"",state:a,createTag:function(){if(this.newTag=this.newTag.trim(),this.newTag!==""){if(this.state.includes(this.newTag)){this.newTag="";return}this.state.push(this.newTag),this.newTag=""}},deleteTag:function(t){this.state=this.state.filter(e=>e!==t)},reorderTags:function(t){let e=this.state.splice(t.oldIndex,1)[0];this.state.splice(t.newIndex,0,e),this.state=[...this.state]},input:{["x-on:blur"]:"createTag()",["x-model"]:"newTag",["x-on:keydown"](t){["Enter",...n].includes(t.key)&&(t.preventDefault(),t.stopPropagation(),this.createTag())},["x-on:paste"](){this.$nextTick(()=>{if(n.length===0){this.createTag();return}let t=n.map(e=>e.replace(/[/\-\\^$*+?.()|[\]{}]/g,"\\$&")).join("|");this.newTag.split(new RegExp(t,"g")).forEach(e=>{this.newTag=e,this.createTag()})})}}}}export{i as default}; 2 | -------------------------------------------------------------------------------- /public/js/filament/forms/components/textarea.js: -------------------------------------------------------------------------------- 1 | function r({initialHeight:t,shouldAutosize:i,state:s}){return{state:s,wrapperEl:null,init:function(){this.wrapperEl=this.$el.parentNode,this.setInitialHeight(),i?this.$watch("state",()=>{this.resize()}):this.setUpResizeObserver()},setInitialHeight:function(){this.$el.scrollHeight<=0||(this.wrapperEl.style.height=t+"rem")},resize:function(){if(this.setInitialHeight(),this.$el.scrollHeight<=0)return;let e=this.$el.scrollHeight+"px";this.wrapperEl.style.height!==e&&(this.wrapperEl.style.height=e)},setUpResizeObserver:function(){new ResizeObserver(()=>{this.wrapperEl.style.height=this.$el.style.height}).observe(this.$el)}}}export{r as default}; 2 | -------------------------------------------------------------------------------- /public/js/filament/forms/forms.js: -------------------------------------------------------------------------------- 1 | (()=>{})(); 2 | -------------------------------------------------------------------------------- /public/js/filament/tables/tables.js: -------------------------------------------------------------------------------- 1 | (()=>{})(); 2 | -------------------------------------------------------------------------------- /public/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/js/app.js": "/js/app.js", 3 | "/css/app.css": "/css/app.css" 4 | } 5 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /public/vendor/horizon/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/public/vendor/horizon/img/favicon.png -------------------------------------------------------------------------------- /public/vendor/horizon/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/app.js": "/app.js?id=4999da9248177ed487693daec2a7d3fe", 3 | "/app-dark.css": "/app-dark.css?id=dcaca44a9f0f1d019e3cd3d76c3cb8fd", 4 | "/app.css": "/app.css?id=14e3bcd1f1b1cf88e63e945529c4d0ce", 5 | "/img/favicon.png": "/img/favicon.png?id=1542bfe8a0010dcbee710da13cce367f", 6 | "/img/horizon.svg": "/img/horizon.svg?id=904d5b5185fefb09035384e15bfca765", 7 | "/img/sprite.svg": "/img/sprite.svg?id=afc4952b74895bdef3ab4ebe9adb746f" 8 | } 9 | -------------------------------------------------------------------------------- /public/web.config: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /resources/css/app.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /resources/js/app.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filamentphp/demo/d1784c8d6c0c724105b3dd3abb9449297f2e5f0b/resources/js/app.js -------------------------------------------------------------------------------- /resources/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'password' => 'The provided password is incorrect.', 18 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 19 | 20 | ]; 21 | -------------------------------------------------------------------------------- /resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /resources/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Your password has been reset!', 17 | 'sent' => 'We have emailed your password reset link!', 18 | 'throttled' => 'Please wait before retrying.', 19 | 'token' => 'This password reset token is invalid.', 20 | 'user' => "We can't find a user with that email address.", 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /resources/svg/github.svg: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /resources/svg/twitter.svg: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /resources/views/components/layouts/app.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {{ config('app.name') }} 11 | 12 | 17 | 18 | @filamentStyles 19 | @vite('resources/css/app.css') 20 | 21 | 22 | 23 | {{ $slot }} 24 | 25 | @filamentScripts 26 | @vite('resources/js/app.js') 27 | 28 | 29 | -------------------------------------------------------------------------------- /resources/views/filament/app/pages/settings.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /resources/views/livewire/form.blade.php: -------------------------------------------------------------------------------- 1 |
2 | {{ $this->form }} 3 | 4 | {{ json_encode($this->data) }} 5 | 6 | 7 | Submit 8 | 9 |
10 | -------------------------------------------------------------------------------- /resources/views/livewire/notifications.blade.php: -------------------------------------------------------------------------------- 1 |
2 | {{-- Do your work, then step back. --}} 3 |
4 | -------------------------------------------------------------------------------- /resources/views/maintenance.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors::minimal') 2 | 3 | @section('title', 'Be right back') 4 | @section('code', 'Be right back') 5 | @section('message', 'Demo is being refreshed.') 6 | -------------------------------------------------------------------------------- /routes/api.php: -------------------------------------------------------------------------------- 1 | get('/user', function (Request $request) { 18 | return $request->user(); 19 | }); 20 | -------------------------------------------------------------------------------- /routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 18 | }); 19 | -------------------------------------------------------------------------------- /routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 19 | })->purpose('Display an inspiring quote'); 20 | -------------------------------------------------------------------------------- /routes/web.php: -------------------------------------------------------------------------------- 1 | 7 | */ 8 | $uri = urldecode( 9 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 10 | ); 11 | 12 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the 13 | // built-in PHP web server. This provides a convenient way to test a Laravel 14 | // application without having installed a "real" web server software here. 15 | if ($uri !== '/' && file_exists(__DIR__ . '/public' . $uri)) { 16 | return false; 17 | } 18 | 19 | require_once __DIR__ . '/public/index.php'; 20 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/debugbar/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | compiled.php 2 | config.php 3 | down 4 | events.scanned.php 5 | maintenance.php 6 | routes.php 7 | routes.scanned.php 8 | schedule-* 9 | services.json 10 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | import preset from './vendor/filament/support/tailwind.config.preset' 2 | 3 | export default { 4 | presets: [preset], 5 | content: [ 6 | './app/Filament/**/*.php', 7 | './resources/views/**/*.blade.php', 8 | './vendor/filament/**/*.blade.php', 9 | ], 10 | } 11 | -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/login'); 17 | 18 | $response->assertStatus(200); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import laravel, { refreshPaths } from 'laravel-vite-plugin' 3 | 4 | export default defineConfig({ 5 | plugins: [ 6 | laravel.default({ 7 | input: ['resources/css/app.css', 'resources/js/app.js'], 8 | refresh: [ 9 | ...refreshPaths, 10 | 'app/Filament/**', 11 | 'app/Forms/Components/**', 12 | 'app/Livewire/**', 13 | 'app/Infolists/Components/**', 14 | 'app/Providers/Filament/**', 15 | 'app/Tables/Columns/**', 16 | ], 17 | }), 18 | ], 19 | }) 20 | --------------------------------------------------------------------------------