diff --git a/.env b/.env index 5a204fb..4d69617 100644 --- a/.env +++ b/.env @@ -16,4 +16,9 @@ DATABASE_URL="postgresql://${DB_USER:-db}:${DB_PW:-db}@${DB_HOST:-db}:${DB_PORT: ### STRIPE STRIPE_PUBLIC_KEY=${STRIPE_PUBLIC_KEY} STRIPE_SECRET_KEY=${STRIPE_PUBLIC_KEY} +### + +### ADMIN PANEL +USER_PASSWORD=${USER_PASSWORD} +ADMIN_PASSWORD=${ADMIN_PASSWORD} ### \ No newline at end of file diff --git a/.env.dev b/.env.dev index f248cd7..9350a9f 100644 --- a/.env.dev +++ b/.env.dev @@ -1,4 +1,6 @@ - ###> symfony/framework-bundle ### APP_SECRET=5a866a6ab3ce4ef99240ba643868b123 ###< symfony/framework-bundle ### + +USER_PASSWORD=\$2y\$13\$z/XlUykvakLzDR8TeFrQk.jmGuOKOcULlMY/m17aWmkY4f4NrIaam +ADMIN_PASSWORD=\$2y\$13\$z/XlUykvakLzDR8TeFrQk.jmGuOKOcULlMY/m17aWmkY4f4NrIaam \ No newline at end of file diff --git a/assets/controllers.json b/assets/controllers.json index 103b202..29ea244 100644 --- a/assets/controllers.json +++ b/assets/controllers.json @@ -1,15 +1,15 @@ { - "controllers": { - "@symfony/ux-turbo": { - "turbo-core": { - "enabled": true, - "fetch": "eager" - }, - "mercure-turbo-stream": { - "enabled": false, - "fetch": "eager" - } - } - }, - "entrypoints": [] + "controllers": { + "@symfony/ux-turbo": { + "turbo-core": { + "enabled": true, + "fetch": "eager" + }, + "mercure-turbo-stream": { + "enabled": false, + "fetch": "eager" + } + } + }, + "entrypoints": [] } diff --git a/composer.json b/composer.json index d1506a7..5c6700a 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ "doctrine/doctrine-bundle": "^2.13", "doctrine/doctrine-migrations-bundle": "^3.4", "doctrine/orm": "^3.3", + "easycorp/easyadmin-bundle": "^4.24", "php-flasher/flasher-noty-symfony": "^2.1", "phpdocumentor/reflection-docblock": "^5.6", "stripe/stripe-php": "^16.4", diff --git a/composer.lock b/composer.lock index 61a72ee..e377fcd 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": "8dc2a9d9e624cf61b3c68d2678e9d53c", + "content-hash": "6e7803d436b49242a4a3816fdc776d3a", "packages": [ { "name": "composer/semver", @@ -1378,6 +1378,107 @@ }, "time": "2024-10-21T18:21:57+00:00" }, + { + "name": "easycorp/easyadmin-bundle", + "version": "v4.24.0", + "source": { + "type": "git", + "url": "https://github.com/EasyCorp/EasyAdminBundle.git", + "reference": "f641b359bfe23406469453f274dde167ecafd3a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/EasyCorp/EasyAdminBundle/zipball/f641b359bfe23406469453f274dde167ecafd3a4", + "reference": "f641b359bfe23406469453f274dde167ecafd3a4", + "shasum": "" + }, + "require": { + "doctrine/doctrine-bundle": "^2.5", + "doctrine/orm": "^2.12|^3.0", + "ext-json": "*", + "php": ">=8.1", + "symfony/asset": "^5.4|^6.0|^7.0", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/deprecation-contracts": "^3.0", + "symfony/doctrine-bridge": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/form": "^5.4|^6.0|^7.0", + "symfony/framework-bundle": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/intl": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/security-bundle": "^5.4|^6.0|^7.0", + "symfony/string": "^5.4|^6.0|^7.0", + "symfony/translation": "^5.4|^6.0|^7.0", + "symfony/twig-bundle": "^5.4|^6.0|^7.0", + "symfony/uid": "^5.4|^6.0|^7.0", + "symfony/ux-twig-component": "^2.21", + "symfony/validator": "^5.4|^6.0|^7.0", + "twig/extra-bundle": "^3.17", + "twig/html-extra": "^3.17", + "twig/twig": "^3.15" + }, + "require-dev": { + "doctrine/doctrine-fixtures-bundle": "^3.4|3.5.x-dev", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-phpunit": "^1.2", + "phpstan/phpstan-strict-rules": "^1.4", + "phpstan/phpstan-symfony": "^1.2", + "psr/log": "^1.0", + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/debug-bundle": "^5.4|^6.0|^7.0", + "symfony/dom-crawler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/phpunit-bridge": "^6.1|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/web-link": "^5.4|^6.0|^7.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "EasyCorp\\Bundle\\EasyAdminBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Project Contributors", + "homepage": "https://github.com/EasyCorp/EasyAdminBundle/graphs/contributors" + } + ], + "description": "Admin generator for Symfony applications", + "homepage": "https://github.com/EasyCorp/EasyAdminBundle", + "keywords": [ + "admin", + "backend", + "generator" + ], + "support": { + "issues": "https://github.com/EasyCorp/EasyAdminBundle/issues", + "source": "https://github.com/EasyCorp/EasyAdminBundle/tree/v4.24.0" + }, + "funding": [ + { + "url": "https://github.com/javiereguiluz", + "type": "github" + } + ], + "time": "2025-01-31T19:11:07+00:00" + }, { "name": "egulias/email-validator", "version": "4.0.3", @@ -1992,6 +2093,54 @@ }, "time": "2021-02-03T23:26:27+00:00" }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, { "name": "psr/container", "version": "2.0.2", @@ -2526,6 +2675,80 @@ ], "time": "2024-09-25T14:20:29+00:00" }, + { + "name": "symfony/clock", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/clock.git", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/clock/zipball/b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/clock": "^1.0", + "symfony/polyfill-php83": "^1.28" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/now.php" + ], + "psr-4": { + "Symfony\\Component\\Clock\\": "" + }, + "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": "Decouples applications from the system clock", + "homepage": "https://symfony.com", + "keywords": [ + "clock", + "psr20", + "time" + ], + "support": { + "source": "https://github.com/symfony/clock/tree/v7.2.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-25T14:21:43+00:00" + }, { "name": "symfony/config", "version": "v7.2.0", @@ -4065,6 +4288,92 @@ ], "time": "2024-12-31T14:59:40+00:00" }, + { + "name": "symfony/intl", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/intl.git", + "reference": "76bb3462c6c308f8bd97d3c178c2626ae44d4dea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/intl/zipball/76bb3462c6c308f8bd97d3c178c2626ae44d4dea", + "reference": "76bb3462c6c308f8bd97d3c178c2626ae44d4dea", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/string": "<7.1" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Intl\\": "" + }, + "exclude-from-classmap": [ + "/Tests/", + "/Resources/data/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + }, + { + "name": "Eriksen Costa", + "email": "eriksen.costa@infranology.com.br" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides access to the localization data of the ICU library", + "homepage": "https://symfony.com", + "keywords": [ + "i18n", + "icu", + "internationalization", + "intl", + "l10n", + "localization" + ], + "support": { + "source": "https://github.com/symfony/intl/tree/v7.2.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-25T14:26:33+00:00" + }, { "name": "symfony/mailer", "version": "v7.2.0", @@ -4296,6 +4605,78 @@ ], "time": "2024-11-20T11:17:29+00:00" }, + { + "name": "symfony/password-hasher", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/password-hasher.git", + "reference": "d8bd3d66d074c0acba1214a0d42f5941a8e1e94d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/password-hasher/zipball/d8bd3d66d074c0acba1214a0d42f5941a8e1e94d", + "reference": "d8bd3d66d074c0acba1214a0d42f5941a8e1e94d", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "conflict": { + "symfony/security-core": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/security-core": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PasswordHasher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Robin Chalas", + "email": "robin.chalas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides password hashing utilities", + "homepage": "https://symfony.com", + "keywords": [ + "hashing", + "password" + ], + "support": { + "source": "https://github.com/symfony/password-hasher/tree/v7.2.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-25T14:21:43+00:00" + }, { "name": "symfony/polyfill-intl-grapheme", "version": "v1.31.0", @@ -4778,6 +5159,85 @@ ], "time": "2024-09-09T11:45:10+00:00" }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-uuid": "*" + }, + "suggest": { + "ext-uuid": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Uuid\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for uuid functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/polyfill-uuid/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/process", "version": "v7.2.0", @@ -5160,6 +5620,357 @@ ], "time": "2024-11-06T11:43:25+00:00" }, + { + "name": "symfony/security-bundle", + "version": "v7.2.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-bundle.git", + "reference": "721de227035c6e4c322fb7dd4839586d58bc0cf5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/721de227035c6e4c322fb7dd4839586d58bc0cf5", + "reference": "721de227035c6e4c322fb7dd4839586d58bc0cf5", + "shasum": "" + }, + "require": { + "composer-runtime-api": ">=2.1", + "ext-xml": "*", + "php": ">=8.2", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4.11|^7.1.4", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/password-hasher": "^6.4|^7.0", + "symfony/security-core": "^7.2", + "symfony/security-csrf": "^6.4|^7.0", + "symfony/security-http": "^7.2", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/browser-kit": "<6.4", + "symfony/console": "<6.4", + "symfony/framework-bundle": "<6.4", + "symfony/http-client": "<6.4", + "symfony/ldap": "<6.4", + "symfony/serializer": "<6.4", + "symfony/twig-bundle": "<6.4", + "symfony/validator": "<6.4" + }, + "require-dev": { + "symfony/asset": "^6.4|^7.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/ldap": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0", + "symfony/twig-bundle": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0", + "twig/twig": "^3.12", + "web-token/jwt-library": "^3.3.2|^4.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\SecurityBundle\\": "" + }, + "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 tight integration of the Security component into the Symfony full-stack framework", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/security-bundle/tree/v7.2.3" + }, + "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": "2025-01-07T09:39:55+00:00" + }, + { + "name": "symfony/security-core", + "version": "v7.2.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-core.git", + "reference": "466784ffcd0b5a16e05394335897f790b17d07e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-core/zipball/466784ffcd0b5a16e05394335897f790b17d07e4", + "reference": "466784ffcd0b5a16e05394335897f790b17d07e4", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/event-dispatcher-contracts": "^2.5|^3", + "symfony/password-hasher": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/http-foundation": "<6.4", + "symfony/ldap": "<6.4", + "symfony/translation": "<6.4.3|>=7.0,<7.0.3", + "symfony/validator": "<6.4" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "psr/container": "^1.1|^2.0", + "psr/log": "^1|^2|^3", + "symfony/cache": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/ldap": "^6.4|^7.0", + "symfony/string": "^6.4|^7.0", + "symfony/translation": "^6.4.3|^7.0.3", + "symfony/validator": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Security\\Core\\": "" + }, + "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": "Symfony Security Component - Core Library", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/security-core/tree/v7.2.3" + }, + "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": "2025-01-27T11:08:17+00:00" + }, + { + "name": "symfony/security-csrf", + "version": "v7.2.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-csrf.git", + "reference": "2b4b0c46c901729e4e90719eacd980381f53e0a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/2b4b0c46c901729e4e90719eacd980381f53e0a3", + "reference": "2b4b0c46c901729e4e90719eacd980381f53e0a3", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/security-core": "^6.4|^7.0" + }, + "conflict": { + "symfony/http-foundation": "<6.4" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Security\\Csrf\\": "" + }, + "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": "Symfony Security Component - CSRF Library", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/security-csrf/tree/v7.2.3" + }, + "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": "2025-01-02T18:42:10+00:00" + }, + { + "name": "symfony/security-http", + "version": "v7.2.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-http.git", + "reference": "d185c4126ef2ca8b89b6e81d67bf14a52532657f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-http/zipball/d185c4126ef2ca8b89b6e81d67bf14a52532657f", + "reference": "d185c4126ef2ca8b89b6e81d67bf14a52532657f", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/polyfill-mbstring": "~1.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/security-core": "^7.2", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/clock": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/http-client-contracts": "<3.0", + "symfony/security-bundle": "<6.4", + "symfony/security-csrf": "<6.4" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/cache": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/http-client-contracts": "^3.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/security-csrf": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "web-token/jwt-library": "^3.3.2|^4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Security\\Http\\": "" + }, + "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": "Symfony Security Component - HTTP Integration", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/security-http/tree/v7.2.3" + }, + "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": "2025-01-28T15:51:35+00:00" + }, { "name": "symfony/serializer", "version": "v7.2.3", @@ -5559,6 +6370,101 @@ ], "time": "2024-11-13T13:31:26+00:00" }, + { + "name": "symfony/translation", + "version": "v7.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "e2674a30132b7cc4d74540d6c2573aa363f05923" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/e2674a30132b7cc4d74540d6c2573aa363f05923", + "reference": "e2674a30132b7cc4d74540d6c2573aa363f05923", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.5|^3.0" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<6.4", + "symfony/yaml": "<6.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "nikic/php-parser": "^4.18|^5.0", + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "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 tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v7.2.2" + }, + "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-12-07T08:18:10+00:00" + }, { "name": "symfony/translation-contracts", "version": "v3.5.1", @@ -5906,6 +6812,80 @@ ], "time": "2024-12-20T13:38:37+00:00" }, + { + "name": "symfony/uid", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/uid.git", + "reference": "2d294d0c48df244c71c105a169d0190bfb080426" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/uid/zipball/2d294d0c48df244c71c105a169d0190bfb080426", + "reference": "2d294d0c48df244c71c105a169d0190bfb080426", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-uuid": "^1.15" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Uid\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to generate and represent UIDs", + "homepage": "https://symfony.com", + "keywords": [ + "UID", + "ulid", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/uid/tree/v7.2.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-25T14:21:43+00:00" + }, { "name": "symfony/ux-icons", "version": "v2.22.1", @@ -6633,6 +7613,74 @@ ], "time": "2024-09-26T19:22:23+00:00" }, + { + "name": "twig/html-extra", + "version": "v3.19.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/html-extra.git", + "reference": "c63b28e192c1b7c15bb60f81d2e48b140846239a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/html-extra/zipball/c63b28e192c1b7c15bb60f81d2e48b140846239a", + "reference": "c63b28e192c1b7c15bb60f81d2e48b140846239a", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/mime": "^5.4|^6.4|^7.0", + "twig/twig": "^3.13|^4.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Twig\\Extra\\Html\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + } + ], + "description": "A Twig extension for HTML", + "homepage": "https://twig.symfony.com", + "keywords": [ + "html", + "twig" + ], + "support": { + "source": "https://github.com/twigphp/html-extra/tree/v3.19.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2024-12-29T10:29:59+00:00" + }, { "name": "twig/twig", "version": "v3.18.0", diff --git a/config/bundles.php b/config/bundles.php index 6bf095b..30a3620 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -15,4 +15,6 @@ return [ Symfony\UX\Turbo\TurboBundle::class => ['all' => true], Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true], Symfony\UX\Icons\UXIconsBundle::class => ['all' => true], + Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], + EasyCorp\Bundle\EasyAdminBundle\EasyAdminBundle::class => ['all' => true], ]; diff --git a/config/packages/security.yaml b/config/packages/security.yaml new file mode 100644 index 0000000..d9edc6b --- /dev/null +++ b/config/packages/security.yaml @@ -0,0 +1,55 @@ +security: + # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords + password_hashers: + Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto' + # https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider + providers: + users_in_memory: + memory: + users: + user: { password: '%env(USER_PASSWORD)%', roles: ['ROLE_ADMIN'] } + admin: { password: '%env(ADMIN_PASSWORD)%', roles: ['ROLE_SUPER_ADMIN'] } + + firewalls: + dev: + pattern: ^/(_(profiler|wdt)|css|images|js)/ + security: false + main: + lazy: true + provider: users_in_memory + custom_authenticator: App\Security\AdminPanelAuthenticator + form_login: + login_path: /admin/login + check_path: /admin/login + logout: + path: /admin/logout + target: /admin/login + # activate different ways to authenticate + # https://symfony.com/doc/current/security.html#the-firewall + + # https://symfony.com/doc/current/security/impersonating_user.html + # switch_user: true + + # Easy way to control access for large sections of your site + # Note: Only the *first* access control that matches will be used + + role_hierarchy: + ROLE_SUPER_ADMIN: ROLE_ADMIN + + access_control: + - { path: ^/admin/login, roles: PUBLIC_ACCESS } + - { path: ^/admin, roles: ROLE_ADMIN } + # - { path: ^/profile, roles: ROLE_USER } + +when@test: + security: + password_hashers: + # By default, password hashers are resource intensive and take time. This is + # important to generate secure password hashes. In tests however, secure hashes + # are not important, waste resources and increase test times. The following + # reduces the work factor to the lowest possible values. + Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: + algorithm: auto + cost: 4 # Lowest possible value for bcrypt + time_cost: 3 # Lowest possible value for argon + memory_cost: 10 # Lowest possible value for argon diff --git a/config/packages/translation.yaml b/config/packages/translation.yaml new file mode 100644 index 0000000..4db0454 --- /dev/null +++ b/config/packages/translation.yaml @@ -0,0 +1,7 @@ +framework: + default_locale: de + translator: + default_path: '%kernel.project_dir%/translations' + fallbacks: + - de + providers: diff --git a/config/routes/security.yaml b/config/routes/security.yaml new file mode 100644 index 0000000..f853be1 --- /dev/null +++ b/config/routes/security.yaml @@ -0,0 +1,3 @@ +_security_logout: + resource: security.route_loader.logout + type: service diff --git a/src/Controller/Admin/CustomerCrudController.php b/src/Controller/Admin/CustomerCrudController.php new file mode 100644 index 0000000..0069cf6 --- /dev/null +++ b/src/Controller/Admin/CustomerCrudController.php @@ -0,0 +1,65 @@ +setCrudController(PaymentCrudController::class) + ->formatValue(fn(?Payment $payment) => ($payment?->getTotal() ?? 0.0) . ' €') + ->hideOnIndex() + ->hideOnForm(); + yield CollectionField::new('tickets') + ->allowAdd() + ->allowDelete() + ->setEntryType(TicketType::class) + ->setFormTypeOptions(['by_reference' => false]) + ->setTemplatePath('admin/customer_tickets.html.twig') + ->hideOnIndex(); + } + + + public function configureActions(Actions $actions): Actions + { + return $actions + ->add(Crud::PAGE_INDEX, Action::DETAIL) + ->disable(Action::DELETE) + ->setPermission(Action::NEW, 'ROLE_SUPER_ADMIN') + ->setPermission(Action::EDIT, 'ROLE_SUPER_ADMIN'); + } + + public function configureCrud(Crud $crud): Crud + { + return $crud + ->setPageTitle(Crud::PAGE_INDEX, 'Kunden') + ->setPageTitle(Crud::PAGE_DETAIL, 'Kunden') + ->showEntityActionsInlined(); + } +} diff --git a/src/Controller/Admin/PaymentCrudController.php b/src/Controller/Admin/PaymentCrudController.php new file mode 100644 index 0000000..ce3fcfe --- /dev/null +++ b/src/Controller/Admin/PaymentCrudController.php @@ -0,0 +1,44 @@ +setCrudController(CustomerCrudController::class) + ->formatValue(fn($value, $payment) => $payment->getCustomer()->getEmail()); + yield BooleanField::new('completed', 'Bezahlt')->renderAsSwitch(false); + } + + public function configureActions(Actions $actions): Actions + { + return $actions + ->add(Crud::PAGE_INDEX, Action::DETAIL) + ->disable(Action::DELETE) + ->disable(Action::NEW) + ->setPermission(Action::EDIT, 'ROLE_SUPER_ADMIN'); + } + + public function configureCrud(Crud $crud): Crud + { + return $crud + ->setPageTitle(Crud::PAGE_INDEX, 'Zahlungen') + ->setPageTitle(Crud::PAGE_DETAIL, 'Zahlung') + ->showEntityActionsInlined(); + } +} diff --git a/src/Controller/Admin/SecurityController.php b/src/Controller/Admin/SecurityController.php new file mode 100644 index 0000000..75e0239 --- /dev/null +++ b/src/Controller/Admin/SecurityController.php @@ -0,0 +1,22 @@ +render('admin/login.html.twig', [ + 'last_username' => $authenticationUtils->getLastUsername(), + 'error' => $authenticationUtils->getLastAuthenticationError(), + ]); + } +} \ No newline at end of file diff --git a/src/Controller/Admin/TicketCrudController.php b/src/Controller/Admin/TicketCrudController.php new file mode 100644 index 0000000..a61dc3e --- /dev/null +++ b/src/Controller/Admin/TicketCrudController.php @@ -0,0 +1,54 @@ +setChoices(TicketData::TYPES); + + yield ChoiceField::new('foodType', 'Ernährung') + ->setChoices(FoodData::TYPES); + + yield AssociationField::new('customer', 'Kunde') + ->setCrudController(CustomerCrudController::class) + ->formatValue(fn(Customer $customer) => $customer->getEmail()) + ->hideOnForm(); + } + + + public function configureActions(Actions $actions): Actions + { + return $actions + ->add(Crud::PAGE_INDEX, Action::DETAIL) + ->disable(Action::DELETE) + ->disable(Action::NEW) + ->setPermission(Action::EDIT, 'ROLE_SUPER_ADMIN'); + } + + public function configureCrud(Crud $crud): Crud + { + return $crud + ->setPageTitle(Crud::PAGE_INDEX, 'Tickets') + ->setPageTitle(Crud::PAGE_DETAIL, 'Ticket') + ->showEntityActionsInlined(); + } +} diff --git a/src/Controller/Admin/ViewController.php b/src/Controller/Admin/ViewController.php new file mode 100644 index 0000000..ccac25e --- /dev/null +++ b/src/Controller/Admin/ViewController.php @@ -0,0 +1,47 @@ +render('admin/dashboard.html.twig', [ + 'totalMoney' => $this->paymentRepository->getTotalMoneyMade(), + 'foodData' => $this->ticketRepository->getFoodData(), + 'totalTickets' => $this->ticketRepository->count(), + ]); + } + + public function configureDashboard(): Dashboard + { + return Dashboard::new()->setTitle('Abiball Admin Interface'); + } + + public function configureMenuItems(): iterable + { + yield MenuItem::linktoDashboard('Dashboard', 'fa fa-home'); + yield MenuItem::section('Daten'); + yield MenuItem::linkToCrud('Kunden', 'fa fa-users', Customer::class); + yield MenuItem::linkToCrud('Tickets', 'fa fa-ticket', Ticket::class); + yield MenuItem::linkToCrud('Zahlungen', 'fa fa-money', Payment::class); + } +} diff --git a/src/DataObjects/FoodData.php b/src/DataObjects/FoodData.php new file mode 100644 index 0000000..1cbd2cc --- /dev/null +++ b/src/DataObjects/FoodData.php @@ -0,0 +1,13 @@ +get('_username'), + $request->get('_password'), + ); + } +} \ No newline at end of file diff --git a/src/Entity/Customer.php b/src/Entity/Customer.php index 525fdeb..0101701 100644 --- a/src/Entity/Customer.php +++ b/src/Entity/Customer.php @@ -8,7 +8,7 @@ use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: CustomerRepository::class)] -class Customer +class Customer implements \Stringable { #[ORM\Id] #[ORM\GeneratedValue] @@ -149,4 +149,9 @@ class Customer return $this; } + + public function __toString(): string + { + return $this->firstname . ' ' . $this->lastname; + } } diff --git a/src/Entity/Payment.php b/src/Entity/Payment.php index 0e788af..80b6306 100644 --- a/src/Entity/Payment.php +++ b/src/Entity/Payment.php @@ -2,6 +2,7 @@ namespace App\Entity; +use App\Enum\TicketData; use App\Repository\PaymentRepository; use Doctrine\ORM\Mapping as ORM; @@ -63,4 +64,11 @@ class Payment return $this; } + + public function getTotal(): float + { + return $this->customer->getTickets()->reduce(function (float $total, Ticket $ticket) { + return $total + TicketData::TICKET_DATA[$ticket->getType()]['price']; + }, 0); + } } diff --git a/src/Entity/Ticket.php b/src/Entity/Ticket.php index 1bb91de..914c208 100644 --- a/src/Entity/Ticket.php +++ b/src/Entity/Ticket.php @@ -2,11 +2,12 @@ namespace App\Entity; +use App\Enum\TicketData; use App\Repository\TicketRepository; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: TicketRepository::class)] -class Ticket +class Ticket implements \Stringable { #[ORM\Id] #[ORM\GeneratedValue] @@ -78,4 +79,9 @@ class Ticket return $this; } + + public function __toString(): string + { + return TicketData::TICKET_DATA[$this->type]['name']; + } } diff --git a/src/Enum/FoodData.php b/src/Enum/FoodData.php new file mode 100644 index 0000000..dba7975 --- /dev/null +++ b/src/Enum/FoodData.php @@ -0,0 +1,18 @@ + 'Mit Fleisch', + 2 => 'Vegetarisch', + 3 => 'Vegan' + ]; + + public const TYPES = [ + 'Mit Fleisch' => 1, + 'Vegetarisch' => 2, + 'Vegan' => 3, + ]; +} \ No newline at end of file diff --git a/src/Enum/TicketData.php b/src/Enum/TicketData.php index 0ef2355..2f6e1d5 100644 --- a/src/Enum/TicketData.php +++ b/src/Enum/TicketData.php @@ -22,4 +22,11 @@ class TicketData 'price' => 0, ], ]; + + public const TYPES = [ + 'All-Inclusive Ticket' => 1, + 'After-Show Ticket' => 2, + 'Kind (6-12 Jahre)' => 3, + 'Kind (0-6 Jahre)' => 4, + ]; } diff --git a/src/Form/TicketType.php b/src/Form/TicketType.php new file mode 100644 index 0000000..2a740fb --- /dev/null +++ b/src/Form/TicketType.php @@ -0,0 +1,48 @@ +add('type', ChoiceType::class, [ + 'label' => 'Ticket Type', + 'choices' => TicketData::TYPES, + 'row_attr' => [ + 'style' => 'flex: 1;', + ], + ]) + ->add('foodType', ChoiceType::class, [ + 'label' => 'Ernährung', + 'choices' => FoodData::TYPES, + 'row_attr' => [ + 'style' => 'flex: 1;', + ], + ]) + ->add('note', TextType::class, [ + 'label' => 'Notiz', + 'required' => false, + 'row_attr' => [ + 'style' => 'flex: 2;', + ], + ]); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Ticket::class, + ]); + } +} \ No newline at end of file diff --git a/src/Repository/PaymentRepository.php b/src/Repository/PaymentRepository.php index bf97e4b..04c7030 100644 --- a/src/Repository/PaymentRepository.php +++ b/src/Repository/PaymentRepository.php @@ -15,4 +15,15 @@ class PaymentRepository extends ServiceEntityRepository { parent::__construct($registry, Payment::class); } + + public function getTotalMoneyMade(): float + { + $all = $this->findAll(); + $total = 0.0; + foreach ($all as $payment) { + $total += $payment->getTotal(); + } + + return $total; + } } diff --git a/src/Repository/TicketRepository.php b/src/Repository/TicketRepository.php index fce3bff..cd6e338 100644 --- a/src/Repository/TicketRepository.php +++ b/src/Repository/TicketRepository.php @@ -2,6 +2,7 @@ namespace App\Repository; +use App\DataObjects\FoodData; use App\Entity\Ticket; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -15,4 +16,22 @@ class TicketRepository extends ServiceEntityRepository { parent::__construct($registry, Ticket::class); } + + public function getFoodData(): FoodData + { + $qb = $this->createQueryBuilder('t') + ->select( + 'SUM(CASE WHEN t.foodType = 1 THEN 1 ELSE 0 END) as totalMeat', + 'SUM(CASE WHEN t.foodType = 2 THEN 1 ELSE 0 END) as totalVegetarian', + 'SUM(CASE WHEN t.foodType = 3 THEN 1 ELSE 0 END) as totalVegan' + ); + + $result = $qb->getQuery()->getSingleResult(); + + return new FoodData( + (int) $result['totalMeat'], + (int) $result['totalVegetarian'], + (int) $result['totalVegan'] + ); + } } diff --git a/src/Security/AdminPanelAuthenticator.php b/src/Security/AdminPanelAuthenticator.php new file mode 100644 index 0000000..afec9d5 --- /dev/null +++ b/src/Security/AdminPanelAuthenticator.php @@ -0,0 +1,45 @@ +getRequestUri(), '/admin') && $request->isMethod(Request::METHOD_POST); + } + + public function authenticate(Request $request): Passport + { + $data = LoginData::fromRequest($request); + + if ($request->isMethod(Request::METHOD_POST) && (!$data->password || !$data->username)) { + throw new CustomUserMessageAuthenticationException(); + } + + return new Passport(new UserBadge($data->username), new PasswordCredentials($data->password), [new RememberMeBadge()]); + } + + public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response + { + return new RedirectResponse('/admin'); + } + + public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response + { + return null; + } +} diff --git a/src/Twig/Ticket.php b/src/Twig/Ticket.php new file mode 100644 index 0000000..1515c91 --- /dev/null +++ b/src/Twig/Ticket.php @@ -0,0 +1,31 @@ +getFoodName(...)), + new TwigFilter('ticket', $this->getTicket(...)), + + ]; + } + + public function getFoodName(int $id): string + { + return FoodData::FOOD_DATA[$id] ?? 'N/A'; + } + + public function getTicket(int $id): array + { + return TicketData::TICKET_DATA[$id] ?? ['name' => 'N/A', 'price' => 'N/A']; + } +} \ No newline at end of file diff --git a/symfony.lock b/symfony.lock index 8377651..e488dc6 100644 --- a/symfony.lock +++ b/symfony.lock @@ -35,6 +35,15 @@ "migrations/.gitignore" ] }, + "easycorp/easyadmin-bundle": { + "version": "4.24", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "3.0", + "ref": "b131e6cbfe1b898a508987851963fff485986285" + } + }, "php-flasher/flasher-noty-symfony": { "version": "v2.1.2" }, @@ -146,6 +155,19 @@ "config/routes.yaml" ] }, + "symfony/security-bundle": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "6.4", + "ref": "2ae08430db28c8eb4476605894296c82a642028f" + }, + "files": [ + "config/packages/security.yaml", + "config/routes/security.yaml" + ] + }, "symfony/stimulus-bundle": { "version": "2.22", "recipe": { @@ -161,6 +183,19 @@ "assets/controllers/hello_controller.js" ] }, + "symfony/translation": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "6.3", + "ref": "e28e27f53663cc34f0be2837aba18e3a1bef8e7b" + }, + "files": [ + "config/packages/translation.yaml", + "translations/.gitignore" + ] + }, "symfony/twig-bundle": { "version": "7.2", "recipe": { @@ -174,6 +209,15 @@ "templates/base.html.twig" ] }, + "symfony/uid": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "7.0", + "ref": "0df5844274d871b37fc3816c57a768ffc60a43a5" + } + }, "symfony/ux-icons": { "version": "2.22", "recipe": { diff --git a/templates/admin/customer_tickets.html.twig b/templates/admin/customer_tickets.html.twig new file mode 100644 index 0000000..14f9b55 --- /dev/null +++ b/templates/admin/customer_tickets.html.twig @@ -0,0 +1,31 @@ + + + + + + + + + + + + {% for ticket in field.value %} + + + + + + + + {% else %} + + + + {% endfor %} + +
NameErnährungPreisAnmerkung
{{ (ticket.type | ticket)['name'] }}{{ ticket.foodType | food }}{{ (ticket.type | ticket)['price'] }}€{{ ticket.note }} + + View + +
No Orders Found
diff --git a/templates/admin/dashboard.html.twig b/templates/admin/dashboard.html.twig new file mode 100644 index 0000000..0d4416f --- /dev/null +++ b/templates/admin/dashboard.html.twig @@ -0,0 +1,34 @@ +{% extends '@EasyAdmin/page/content.html.twig' %} + +{% block content %} +
+
+
+
+
+
Ticketwert insgesamt
+

{{ totalMoney }} €

+
+
+
+
+
+
+
Essens Daten
+

Mit Fleisch: {{ foodData.totalMeat }}

+

Vegetarisch: {{ foodData.totalVegetarian }}

+

Vegan: {{ foodData.totalVegan }}

+
+
+
+
+
+
+
Ticket Anzahl
+

{{ totalTickets }}

+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/admin/login.html.twig b/templates/admin/login.html.twig new file mode 100644 index 0000000..36c515b --- /dev/null +++ b/templates/admin/login.html.twig @@ -0,0 +1,58 @@ +{% extends 'base.html.twig' %} + +{% block body %} +
+
+
+

Abiball Admin Panel

+
+ + {% if error %} + {{ error.message }} + {% endif %} + +
+ + +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+ +
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/translations/.gitignore b/translations/.gitignore new file mode 100644 index 0000000..e69de29