From 2123b5464f70eb05c6295bcd71c66055c598e82f Mon Sep 17 00:00:00 2001 From: Constantin Simonis Date: Wed, 4 Dec 2024 22:23:28 +0100 Subject: [PATCH] minor changes --- assets/app.js | 1 + assets/bootstrap.js | 5 + assets/controllers.json | 4 + assets/controllers/upload_file_controller.js | 10 + assets/icons/file/upload.svg | 3 + assets/styles/app.css | 5 + composer.json | 7 + composer.lock | 822 ++++++++++++++++++- config/bundles.php | 3 + config/packages/web_profiler.yaml | 17 + config/routes/web_profiler.yaml | 8 + importmap.php | 6 + src/Controller/HomeController.php | 22 +- src/Forms/UploadFileForm.php | 18 + src/Objects/UploadedFileData.php | 13 + src/Service/FileSystemService.php | 15 +- symfony.lock | 30 + tailwind.config.js | 12 + templates/_partials/_row.html.twig | 14 +- templates/_partials/_table.html.twig | 49 +- templates/base.html.twig | 6 +- templates/home.html.twig | 2 +- 22 files changed, 1045 insertions(+), 27 deletions(-) create mode 100644 assets/bootstrap.js create mode 100644 assets/controllers.json create mode 100644 assets/controllers/upload_file_controller.js create mode 100644 assets/icons/file/upload.svg create mode 100644 config/packages/web_profiler.yaml create mode 100644 config/routes/web_profiler.yaml create mode 100644 src/Forms/UploadFileForm.php create mode 100644 src/Objects/UploadedFileData.php create mode 100644 tailwind.config.js diff --git a/assets/app.js b/assets/app.js index 6174cc6..8725cc5 100644 --- a/assets/app.js +++ b/assets/app.js @@ -1,3 +1,4 @@ +import './bootstrap.js'; /* * Welcome to your app's main JavaScript file! * diff --git a/assets/bootstrap.js b/assets/bootstrap.js new file mode 100644 index 0000000..d4e50c9 --- /dev/null +++ b/assets/bootstrap.js @@ -0,0 +1,5 @@ +import { startStimulusApp } from '@symfony/stimulus-bundle'; + +const app = startStimulusApp(); +// register any custom, 3rd party controllers here +// app.register('some_controller_name', SomeImportedController); diff --git a/assets/controllers.json b/assets/controllers.json new file mode 100644 index 0000000..a1c6e90 --- /dev/null +++ b/assets/controllers.json @@ -0,0 +1,4 @@ +{ + "controllers": [], + "entrypoints": [] +} diff --git a/assets/controllers/upload_file_controller.js b/assets/controllers/upload_file_controller.js new file mode 100644 index 0000000..9c59c4b --- /dev/null +++ b/assets/controllers/upload_file_controller.js @@ -0,0 +1,10 @@ +import { Controller } from '@hotwired/stimulus'; + +export default class extends Controller { + connect() { + console.log(this.element); + this.element.querySelector('input').addEventListener('change', () => { + this.element.querySelector('button[type="submit"]').click(); + }); + } +} diff --git a/assets/icons/file/upload.svg b/assets/icons/file/upload.svg new file mode 100644 index 0000000..f25b3de --- /dev/null +++ b/assets/icons/file/upload.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/assets/styles/app.css b/assets/styles/app.css index ce1b1dd..81015c8 100644 --- a/assets/styles/app.css +++ b/assets/styles/app.css @@ -1,3 +1,8 @@ body { background-color: transparent; } + +.upload-btn:hover { + color: darkblue; + cursor: pointer; +} \ No newline at end of file diff --git a/composer.json b/composer.json index 5d649bb..4460c9e 100644 --- a/composer.json +++ b/composer.json @@ -13,11 +13,14 @@ "symfony/dotenv": "7.1.*", "symfony/finder": "7.1.*", "symfony/flex": "^2", + "symfony/form": "^7.1", "symfony/framework-bundle": "7.1.*", "symfony/runtime": "7.1.*", + "symfony/stimulus-bundle": "^2.22", "symfony/twig-bundle": "7.1.*", "symfony/ux-icons": "^2.22", "symfony/yaml": "7.1.*", + "symfonycasts/tailwind-bundle": "^0.6.1", "twig/extra-bundle": "^2.12|^3.0", "twig/twig": "^2.12|^3.0" }, @@ -70,5 +73,9 @@ "allow-contrib": false, "require": "7.1.*" } + }, + "require-dev": { + "symfony/stopwatch": "7.1.*", + "symfony/web-profiler-bundle": "7.1.*" } } diff --git a/composer.lock b/composer.lock index bb4d834..8706be0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "30e7d11432b7e0d9c34ff0d9d2c62e21", + "content-hash": "8278464727736866734f277693979fb2", "packages": [ { "name": "composer/semver", @@ -1385,6 +1385,103 @@ ], "time": "2024-10-07T08:51:54+00:00" }, + { + "name": "symfony/form", + "version": "v7.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/form.git", + "reference": "7a48dda96fe16711fc042df38ca1a7dd4d9d6387" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/form/zipball/7a48dda96fe16711fc042df38ca1a7dd4d9d6387", + "reference": "7a48dda96fe16711fc042df38ca1a7dd4d9d6387", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/options-resolver": "^6.4|^7.0", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/polyfill-mbstring": "~1.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/error-handler": "<6.4", + "symfony/framework-bundle": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/translation": "<6.4.3|>=7.0,<7.0.3", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<6.4" + }, + "require-dev": { + "doctrine/collections": "^1.0|^2.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/html-sanitizer": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/security-core": "^6.4|^7.0", + "symfony/security-csrf": "^6.4|^7.0", + "symfony/translation": "^6.4.3|^7.0.3", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Form\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows to easily create, process and reuse HTML forms", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/form/tree/v7.1.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-09T08:46:59+00:00" + }, { "name": "symfony/framework-bundle", "version": "v7.1.6", @@ -1896,6 +1993,73 @@ ], "time": "2024-11-13T14:25:32+00:00" }, + { + "name": "symfony/options-resolver", + "version": "v7.1.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "0f4099f5306a92487d13b2a4589068c36a93c447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/0f4099f5306a92487d13b2a4589068c36a93c447", + "reference": "0f4099f5306a92487d13b2a4589068c36a93c447", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v7.1.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-20T11:08:58+00:00" + }, { "name": "symfony/polyfill-intl-grapheme", "version": "v1.31.0", @@ -1974,6 +2138,90 @@ ], "time": "2024-09-09T11:45:10+00:00" }, + { + "name": "symfony/polyfill-intl-icu", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-icu.git", + "reference": "d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78", + "reference": "d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance and support of other locales than \"en\"" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Icu\\": "" + }, + "classmap": [ + "Resources/stubs" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's ICU-related data and classes", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "icu", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, { "name": "symfony/polyfill-intl-normalizer", "version": "v1.31.0", @@ -2211,6 +2459,226 @@ ], "time": "2024-09-09T11:45:10+00:00" }, + { + "name": "symfony/process", + "version": "v7.1.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "42783370fda6e538771f7c7a36e9fa2ee3a84892" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/42783370fda6e538771f7c7a36e9fa2ee3a84892", + "reference": "42783370fda6e538771f7c7a36e9fa2ee3a84892", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v7.1.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-06T14:23:19+00:00" + }, + { + "name": "symfony/property-access", + "version": "v7.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-access.git", + "reference": "975d7f7fd8fcb952364c6badc46d01a580532bf9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-access/zipball/975d7f7fd8fcb952364c6badc46d01a580532bf9", + "reference": "975d7f7fd8fcb952364c6badc46d01a580532bf9", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/property-info": "^6.4|^7.0" + }, + "require-dev": { + "symfony/cache": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyAccess\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides functions to read and write from/to an object or array using a simple string notation", + "homepage": "https://symfony.com", + "keywords": [ + "access", + "array", + "extraction", + "index", + "injection", + "object", + "property", + "property-path", + "reflection" + ], + "support": { + "source": "https://github.com/symfony/property-access/tree/v7.1.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/property-info", + "version": "v7.1.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-info.git", + "reference": "e9a7b2a4984457c3849afd2b1a1ec7f2994cb1b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-info/zipball/e9a7b2a4984457c3849afd2b1a1ec7f2994cb1b5", + "reference": "e9a7b2a4984457c3849afd2b1a1ec7f2994cb1b5", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/string": "^6.4|^7.0", + "symfony/type-info": "^7.1" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<5.2", + "phpdocumentor/type-resolver": "<1.5.1", + "symfony/dependency-injection": "<6.4" + }, + "require-dev": { + "phpdocumentor/reflection-docblock": "^5.2", + "phpstan/phpdoc-parser": "^1.0|^2.0", + "symfony/cache": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "dunglas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Extracts information about PHP class' properties using metadata of popular sources", + "homepage": "https://symfony.com", + "keywords": [ + "doctrine", + "phpdoc", + "property", + "symfony", + "type", + "validator" + ], + "support": { + "source": "https://github.com/symfony/property-info/tree/v7.1.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-27T09:50:41+00:00" + }, { "name": "symfony/routing", "version": "v7.1.6", @@ -2454,6 +2922,75 @@ ], "time": "2024-04-18T09:32:20+00:00" }, + { + "name": "symfony/stimulus-bundle", + "version": "v2.22.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/stimulus-bundle.git", + "reference": "2e840a3b12f06b33441cc3eb8907f51b806a7e4b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stimulus-bundle/zipball/2e840a3b12f06b33441cc3eb8907f51b806a7e4b", + "reference": "2e840a3b12f06b33441cc3eb8907f51b806a7e4b", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/deprecation-contracts": "^2.0|^3.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "twig/twig": "^2.15.3|^3.8" + }, + "require-dev": { + "symfony/asset-mapper": "^6.3|^7.0", + "symfony/framework-bundle": "^5.4|^6.0|^7.0", + "symfony/phpunit-bridge": "^5.4|^6.0|^7.0", + "symfony/twig-bundle": "^5.4|^6.0|^7.0", + "zenstruck/browser": "^1.4" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\UX\\StimulusBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Integration with your Symfony app & Stimulus!", + "keywords": [ + "symfony-ux" + ], + "support": { + "source": "https://github.com/symfony/stimulus-bundle/tree/v2.22.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-20T07:57:38+00:00" + }, { "name": "symfony/string", "version": "v7.1.8", @@ -2812,6 +3349,88 @@ ], "time": "2024-09-25T14:20:29+00:00" }, + { + "name": "symfony/type-info", + "version": "v7.1.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/type-info.git", + "reference": "51535dde21c7abf65c9d000a30bb15f6478195e6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/type-info/zipball/51535dde21c7abf65c9d000a30bb15f6478195e6", + "reference": "51535dde21c7abf65c9d000a30bb15f6478195e6", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/container": "^1.1|^2.0" + }, + "conflict": { + "phpstan/phpdoc-parser": "<1.0", + "symfony/dependency-injection": "<6.4", + "symfony/property-info": "<6.4" + }, + "require-dev": { + "phpstan/phpdoc-parser": "^1.0|^2.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\TypeInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mathias Arlaud", + "email": "mathias.arlaud@gmail.com" + }, + { + "name": "Baptiste LEDUC", + "email": "baptiste.leduc@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Extracts PHP types information.", + "homepage": "https://symfony.com", + "keywords": [ + "PHPStan", + "phpdoc", + "symfony", + "type" + ], + "support": { + "source": "https://github.com/symfony/type-info/tree/v7.1.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-07T15:49:33+00:00" + }, { "name": "symfony/ux-icons", "version": "v2.22.0", @@ -3131,6 +3750,61 @@ ], "time": "2024-09-25T14:20:29+00:00" }, + { + "name": "symfonycasts/tailwind-bundle", + "version": "v0.6.1", + "source": { + "type": "git", + "url": "https://github.com/SymfonyCasts/tailwind-bundle.git", + "reference": "28db7cfe23758cffc79f25a7c75cdb2fca52e9d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SymfonyCasts/tailwind-bundle/zipball/28db7cfe23758cffc79f25a7c75cdb2fca52e9d9", + "reference": "28db7cfe23758cffc79f25a7c75cdb2fca52e9d9", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/asset-mapper": "^6.3|^7.0", + "symfony/cache": "^6.3|^7.0", + "symfony/console": "^5.4|^6.3|^7.0", + "symfony/http-client": "^5.4|^6.3|^7.0", + "symfony/process": "^5.4|^6.3|^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6", + "symfony/filesystem": "^6.3|^7.0", + "symfony/framework-bundle": "^6.3|^7.0", + "symfony/phpunit-bridge": "^6.3.9|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfonycasts\\TailwindBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ryan Weaver", + "homepage": "https://symfonycasts.com" + } + ], + "description": "Delightful Tailwind Support for Symfony + AssetMapper", + "keywords": [ + "asset-mapper", + "tailwind" + ], + "support": { + "issues": "https://github.com/SymfonyCasts/tailwind-bundle/issues", + "source": "https://github.com/SymfonyCasts/tailwind-bundle/tree/v0.6.1" + }, + "time": "2024-11-06T18:41:22+00:00" + }, { "name": "twig/extra-bundle", "version": "v3.16.0", @@ -3286,7 +3960,151 @@ "time": "2024-11-29T08:27:05+00:00" } ], - "packages-dev": [], + "packages-dev": [ + { + "name": "symfony/stopwatch", + "version": "v7.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "8b4a434e6e7faf6adedffb48783a5c75409a1a05" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/8b4a434e6e7faf6adedffb48783a5c75409a1a05", + "reference": "8b4a434e6e7faf6adedffb48783a5c75409a1a05", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v7.1.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/web-profiler-bundle", + "version": "v7.1.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/web-profiler-bundle.git", + "reference": "6f26474e0e8ff746cb0abaddf9ebe0b067172fb1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/6f26474e0e8ff746cb0abaddf9ebe0b067172fb1", + "reference": "6f26474e0e8ff746cb0abaddf9ebe0b067172fb1", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/config": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/twig-bundle": "^6.4|^7.0", + "twig/twig": "^3.10" + }, + "conflict": { + "symfony/form": "<6.4", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4" + }, + "require-dev": { + "symfony/browser-kit": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\WebProfilerBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a development tool that gives detailed information about the execution of any request", + "homepage": "https://symfony.com", + "keywords": [ + "dev" + ], + "support": { + "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.1.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-19T10:11:44+00:00" + } + ], "aliases": [], "minimum-stability": "stable", "stability-flags": {}, diff --git a/config/bundles.php b/config/bundles.php index eb998b7..7942e2f 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -5,4 +5,7 @@ return [ Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true], Symfony\UX\Icons\UXIconsBundle::class => ['all' => true], + Symfonycasts\TailwindBundle\SymfonycastsTailwindBundle::class => ['all' => true], + Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true], + Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], ]; diff --git a/config/packages/web_profiler.yaml b/config/packages/web_profiler.yaml new file mode 100644 index 0000000..b946111 --- /dev/null +++ b/config/packages/web_profiler.yaml @@ -0,0 +1,17 @@ +when@dev: + web_profiler: + toolbar: true + intercept_redirects: false + + framework: + profiler: + only_exceptions: false + collect_serializer_data: true + +when@test: + web_profiler: + toolbar: false + intercept_redirects: false + + framework: + profiler: { collect: false } diff --git a/config/routes/web_profiler.yaml b/config/routes/web_profiler.yaml new file mode 100644 index 0000000..8d85319 --- /dev/null +++ b/config/routes/web_profiler.yaml @@ -0,0 +1,8 @@ +when@dev: + web_profiler_wdt: + resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml' + prefix: /_wdt + + web_profiler_profiler: + resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml' + prefix: /_profiler diff --git a/importmap.php b/importmap.php index 70ebf14..cbb8293 100644 --- a/importmap.php +++ b/importmap.php @@ -16,4 +16,10 @@ return [ 'path' => './assets/app.js', 'entrypoint' => true, ], + '@hotwired/stimulus' => [ + 'version' => '3.2.2', + ], + '@symfony/stimulus-bundle' => [ + 'path' => './vendor/symfony/stimulus-bundle/assets/dist/loader.js', + ], ]; diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php index 30f87e8..447f38b 100644 --- a/src/Controller/HomeController.php +++ b/src/Controller/HomeController.php @@ -2,6 +2,8 @@ namespace App\Controller; +use App\Forms\UploadFileForm; +use App\Objects\UploadedFileData; use App\Service\FileSystemService; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; @@ -10,11 +12,25 @@ use Symfony\Component\Routing\Attribute\Route; class HomeController extends AbstractController { - #[Route(path: '/', name: 'app_home', methods: Request::METHOD_GET)] + #[Route(path: '/', name: 'app_home', methods: [Request::METHOD_GET, Request::METHOD_POST])] public function __invoke( - FileSystemService $fileSystemService + FileSystemService $fileSystemService, + Request $request, ): Response { - return $this->render('home.html.twig', ['content' => $fileSystemService->getDirs()]); + $fileData = new UploadedFileData(); + $form = $this->createForm(UploadFileForm::class, $fileData)->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + dd($form->getData(), $form->getExtraData()); + $fileSystemService->uploadFile($fileData->file); + + return $this->redirectToRoute('app_home'); + } + + return $this->render('home.html.twig', [ + 'content' => $fileSystemService->getDirs(), + 'fileForm' => $form, + ]); } } \ No newline at end of file diff --git a/src/Forms/UploadFileForm.php b/src/Forms/UploadFileForm.php new file mode 100644 index 0000000..e52045a --- /dev/null +++ b/src/Forms/UploadFileForm.php @@ -0,0 +1,18 @@ +add('file', FileType::class, [ + 'attr' => ['class' => 'hidden'], + 'multiple' => true, + ]); + } +} \ No newline at end of file diff --git a/src/Objects/UploadedFileData.php b/src/Objects/UploadedFileData.php new file mode 100644 index 0000000..76b917a --- /dev/null +++ b/src/Objects/UploadedFileData.php @@ -0,0 +1,13 @@ +filesystem->dumpFile($this->dir . '/' . $file->getClientOriginalName(), $file->getContent()); + } + } } \ No newline at end of file diff --git a/symfony.lock b/symfony.lock index 6e8d916..3fdedfa 100644 --- a/symfony.lock +++ b/symfony.lock @@ -82,6 +82,20 @@ "config/routes.yaml" ] }, + "symfony/stimulus-bundle": { + "version": "2.22", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "2.13", + "ref": "6acd9ff4f7fd5626d2962109bd4ebab351d43c43" + }, + "files": [ + "assets/bootstrap.js", + "assets/controllers.json", + "assets/controllers/hello_controller.js" + ] + }, "symfony/twig-bundle": { "version": "7.1", "recipe": { @@ -107,6 +121,22 @@ "assets/icons/symfony.svg" ] }, + "symfony/web-profiler-bundle": { + "version": "7.1", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "6.1", + "ref": "e42b3f0177df239add25373083a564e5ead4e13a" + }, + "files": [ + "config/packages/web_profiler.yaml", + "config/routes/web_profiler.yaml" + ] + }, + "symfonycasts/tailwind-bundle": { + "version": "v0.6.1" + }, "twig/extra-bundle": { "version": "v3.16.0" } diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..5e30753 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,12 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + "./assets/**/*.js", + "./templates/**/*.html.twig", + ], + plugins: [ + require("@tailwindcss/forms") + ], + darkMode: 'class', +} + diff --git a/templates/_partials/_row.html.twig b/templates/_partials/_row.html.twig index 28d93b2..cf570e4 100644 --- a/templates/_partials/_row.html.twig +++ b/templates/_partials/_row.html.twig @@ -1,11 +1,15 @@ - - + + {% if file.type == 'dir' %} {{ ux_icon('folder:closed', {height: '32px', width: '32px'}) }} {% else %} {{ ux_icon('file:default', {height: '32px', width: '32px'}) }} {% endif %} + + + {{ file.name }} - {{ file.name }} - {{ file.size }} - \ No newline at end of file + + {{ file.size }} + + diff --git a/templates/_partials/_table.html.twig b/templates/_partials/_table.html.twig index 37fc141..d1d9fef 100644 --- a/templates/_partials/_table.html.twig +++ b/templates/_partials/_table.html.twig @@ -1,13 +1,36 @@ - - - - - - - - - {% for dirContent in content %} - {% include '_partials/_row.html.twig' with {file: dirContent} %} - {% endfor %} - -
ExpandNameSize
\ No newline at end of file +
+ + + + + + + + + + {% for dirContent in content %} + {% include '_partials/_row.html.twig' with {file: dirContent} %} + {% endfor %} + +
+ - + + name + + Size +
+
+ + +{{ form_start(fileForm, {'attr': {'data-controller': 'upload-file'}}) }} +
+ +
+{{ form_end(fileForm) }} \ No newline at end of file diff --git a/templates/base.html.twig b/templates/base.html.twig index 9467f26..bdf9a00 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -4,7 +4,9 @@ Files | {% block title %}{% endblock %} - + + + {% block stylesheets %} {% endblock %} @@ -12,7 +14,7 @@ {% block importmap %}{{ importmap('app') }}{% endblock %} {% endblock %} - + {% block body %}{% endblock %} diff --git a/templates/home.html.twig b/templates/home.html.twig index 086fe10..82351e1 100644 --- a/templates/home.html.twig +++ b/templates/home.html.twig @@ -3,7 +3,7 @@ {% block title %}Home{% endblock %} {% block body %} -
+

Welcome to the File Explorer

Use the navigation bar to explore the files and directories.

{% include '_partials/_table.html.twig' %}