minor changes

This commit is contained in:
Constantin Simonis 2025-01-29 19:06:48 +01:00
parent ce2ee30efd
commit 77ba8687a6
Signed by: csimonis
GPG Key ID: 3878FF77C24AF4D2
19 changed files with 529 additions and 131 deletions

View File

@ -1,10 +1,2 @@
import './bootstrap.js'; import './bootstrap.js';
/*
* Welcome to your app's main JavaScript file!
*
* This file will be included onto the page via the importmap() Twig function,
* which should already be in your base.html.twig.
*/
import './styles/app.css'; import './styles/app.css';
console.log('This log comes from assets/app.js - welcome to AssetMapper! 🎉');

2
assets/bootstrap.js vendored
View File

@ -1,5 +1,3 @@
import { startStimulusApp } from '@symfony/stimulus-bundle'; import { startStimulusApp } from '@symfony/stimulus-bundle';
const app = startStimulusApp(); const app = startStimulusApp();
// register any custom, 3rd party controllers here
// app.register('some_controller_name', SomeImportedController);

View File

@ -2,32 +2,54 @@ import {Controller} from "@hotwired/stimulus";
export default class extends Controller { export default class extends Controller {
static targets = ['ticket', 'afterShowTicket', 'kid12yo', 'kid6yo', 'meat', 'vegetarian', 'vegan', 'error'] addEntry(event) {
event.preventDefault();
connect() { const formClone = this.element.querySelector('form').cloneNode(true);
this.element.addEventListener('submit', (e) => this.submit(e))
formClone.querySelectorAll("select").forEach(input => {
input.value = "1";
});
formClone.querySelector('input').value = '';
this.element.querySelector('.forms').appendChild(formClone);
} }
submit(e) { removeEntry(event) {
e.preventDefault(); event.preventDefault();
const ticketCount = this.getTotalTicketCount();
const foodCount = this.getTotalFoodCount();
if (foodCount > ticketCount) { if (document.querySelector('.forms').childElementCount === 1) {
this.errorTarget.textContent = 'Sie können nicht mehr Essen als Tickets bestellen'; return;
} }
event.target.closest('form').remove();
} }
getTotalTicketCount() { submit(event) {
return parseInt(this.ticketTarget.value) event.preventDefault();
+ parseInt(this.kid12yoTarget.value)
+ parseInt(this.kid6yoTarget.value) const forms = document.querySelectorAll('form');
+ parseInt(this.afterShowTicketTarget.value); const formData = this.getFormData(forms);
fetch('/ticket/submit', {
method: 'POST',
body: JSON.stringify(formData),
headers: {
'Content-Type': 'application/json'
}
}).then(response => {
if (!response.ok) {
alert('An error occurred');
}
});
} }
getTotalFoodCount() { getFormData(forms) {
return parseInt(this.meatTarget.value) const formData = [];
+ parseInt(this.vegetarianTarget.value) forms.forEach(form => {
+ parseInt(this.veganTarget.value); formData.push(Object.fromEntries(new FormData(form).entries()));
})
return formData;
} }
} }

View File

@ -1,16 +0,0 @@
import { Controller } from '@hotwired/stimulus';
/*
* This is an example Stimulus controller!
*
* Any element with a data-controller="hello" attribute will cause
* this controller to be executed. The name "hello" comes from the filename:
* hello_controller.js -> "hello"
*
* Delete this file or adapt it for your use!
*/
export default class extends Controller {
connect() {
this.element.textContent = 'Hello Stimulus! Edit me in assets/controllers/hello_controller.js';
}
}

1
assets/icons/delete.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 11v6m-4-6v6M6 7v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V7M4 7h16M7 7l2-4h6l2 4"/></svg>

After

Width:  |  Height:  |  Size: 276 B

1
assets/icons/plus.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 1024 1024"><path fill="currentColor" d="M512 0C229.232 0 0 229.232 0 512c0 282.784 229.232 512 512 512c282.784 0 512-229.216 512-512C1024 229.232 794.784 0 512 0m0 961.008c-247.024 0-448-201.984-448-449.01c0-247.024 200.976-448 448-448s448 200.977 448 448s-200.976 449.01-448 449.01M736 480H544V288c0-17.664-14.336-32-32-32s-32 14.336-32 32v192H288c-17.664 0-32 14.336-32 32s14.336 32 32 32h192v192c0 17.664 14.336 32 32 32s32-14.336 32-32V544h192c17.664 0 32-14.336 32-32s-14.336-32-32-32"/></svg>

After

Width:  |  Height:  |  Size: 576 B

View File

@ -22,8 +22,12 @@
"symfony/framework-bundle": "7.2.*", "symfony/framework-bundle": "7.2.*",
"symfony/mailer": "7.2.*", "symfony/mailer": "7.2.*",
"symfony/runtime": "7.2.*", "symfony/runtime": "7.2.*",
"symfony/serializer": "7.2.*",
"symfony/twig-bundle": "7.2.*", "symfony/twig-bundle": "7.2.*",
"symfony/ux-icons": "^2.22",
"symfony/ux-turbo": "^2.22", "symfony/ux-turbo": "^2.22",
"symfony/ux-twig-component": "^2.22",
"symfony/validator": "7.2.*",
"symfony/yaml": "7.2.*", "symfony/yaml": "7.2.*",
"symfonycasts/tailwind-bundle": "^0.7.1", "symfonycasts/tailwind-bundle": "^0.7.1",
"twig/extra-bundle": "^2.12|^3.0", "twig/extra-bundle": "^2.12|^3.0",

369
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "7bf03fa2d3a15763608c71cc0c5ad00c", "content-hash": "51f020bf0346145a2eaa666b7a83d36b",
"packages": [ "packages": [
{ {
"name": "composer/semver", "name": "composer/semver",
@ -4860,6 +4860,104 @@
], ],
"time": "2024-11-06T11:43:25+00:00" "time": "2024-11-06T11:43:25+00:00"
}, },
{
"name": "symfony/serializer",
"version": "v7.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/serializer.git",
"reference": "320f30beb419ce4f96363ada5e225c41f1ef08ab"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/serializer/zipball/320f30beb419ce4f96363ada5e225c41f1ef08ab",
"reference": "320f30beb419ce4f96363ada5e225c41f1ef08ab",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-ctype": "~1.8"
},
"conflict": {
"phpdocumentor/reflection-docblock": "<3.2.2",
"phpdocumentor/type-resolver": "<1.4.0",
"symfony/dependency-injection": "<6.4",
"symfony/property-access": "<6.4",
"symfony/property-info": "<6.4",
"symfony/uid": "<6.4",
"symfony/validator": "<6.4",
"symfony/yaml": "<6.4"
},
"require-dev": {
"phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0",
"phpstan/phpdoc-parser": "^1.0|^2.0",
"seld/jsonlint": "^1.10",
"symfony/cache": "^6.4|^7.0",
"symfony/config": "^6.4|^7.0",
"symfony/console": "^6.4|^7.0",
"symfony/dependency-injection": "^7.2",
"symfony/error-handler": "^6.4|^7.0",
"symfony/filesystem": "^6.4|^7.0",
"symfony/form": "^6.4|^7.0",
"symfony/http-foundation": "^6.4|^7.0",
"symfony/http-kernel": "^6.4|^7.0",
"symfony/messenger": "^6.4|^7.0",
"symfony/mime": "^6.4|^7.0",
"symfony/property-access": "^6.4|^7.0",
"symfony/property-info": "^6.4|^7.0",
"symfony/translation-contracts": "^2.5|^3",
"symfony/type-info": "^7.1",
"symfony/uid": "^6.4|^7.0",
"symfony/validator": "^6.4|^7.0",
"symfony/var-dumper": "^6.4|^7.0",
"symfony/var-exporter": "^6.4|^7.0",
"symfony/yaml": "^6.4|^7.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Serializer\\": ""
},
"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": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/serializer/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-29T07:13:55+00:00"
},
{ {
"name": "symfony/service-contracts", "name": "symfony/service-contracts",
"version": "v3.5.1", "version": "v3.5.1",
@ -5508,6 +5606,95 @@
], ],
"time": "2024-12-20T13:38:37+00:00" "time": "2024-12-20T13:38:37+00:00"
}, },
{
"name": "symfony/ux-icons",
"version": "v2.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/ux-icons.git",
"reference": "3a6fd4293fc200530b09960c41941a71354bc5fc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/ux-icons/zipball/3a6fd4293fc200530b09960c41941a71354bc5fc",
"reference": "3a6fd4293fc200530b09960c41941a71354bc5fc",
"shasum": ""
},
"require": {
"php": ">=8.1",
"symfony/framework-bundle": "^6.4|^7.0",
"symfony/twig-bundle": "^6.4|^7.0"
},
"conflict": {
"symfony/flex": "<1.13",
"symfony/ux-twig-component": "<2.21"
},
"require-dev": {
"psr/log": "^2|^3",
"symfony/asset-mapper": "^6.4|^7.0",
"symfony/console": "^6.4|^7.0",
"symfony/http-client": "6.4|^7.0",
"symfony/phpunit-bridge": "^6.3|^7.0",
"symfony/ux-twig-component": "^2.14",
"zenstruck/console-test": "^1.5"
},
"type": "symfony-bundle",
"extra": {
"thanks": {
"url": "https://github.com/symfony/ux",
"name": "symfony/ux"
}
},
"autoload": {
"psr-4": {
"Symfony\\UX\\Icons\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Kevin Bond",
"email": "kevinbond@gmail.com"
},
{
"name": "Simon André",
"email": "smn.andre@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Renders local and remote SVG icons in your Twig templates.",
"homepage": "https://symfony.com",
"keywords": [
"icons",
"svg",
"symfony-ux",
"twig"
],
"support": {
"source": "https://github.com/symfony/ux-icons/tree/v2.22.1"
},
"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-04T11:34:13+00:00"
},
{ {
"name": "symfony/ux-turbo", "name": "symfony/ux-turbo",
"version": "v2.22.1", "version": "v2.22.1",
@ -5606,6 +5793,186 @@
], ],
"time": "2024-12-05T14:25:02+00:00" "time": "2024-12-05T14:25:02+00:00"
}, },
{
"name": "symfony/ux-twig-component",
"version": "v2.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/ux-twig-component.git",
"reference": "9b347f6ca2d9e18cee630787f0a6aa453982bf18"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/ux-twig-component/zipball/9b347f6ca2d9e18cee630787f0a6aa453982bf18",
"reference": "9b347f6ca2d9e18cee630787f0a6aa453982bf18",
"shasum": ""
},
"require": {
"php": ">=8.1",
"symfony/dependency-injection": "^5.4|^6.0|^7.0",
"symfony/deprecation-contracts": "^2.2|^3.0",
"symfony/event-dispatcher": "^5.4|^6.0|^7.0",
"symfony/property-access": "^5.4|^6.0|^7.0",
"twig/twig": "^3.8"
},
"conflict": {
"symfony/config": "<5.4.0"
},
"require-dev": {
"symfony/console": "^5.4|^6.0|^7.0",
"symfony/css-selector": "^5.4|^6.0|^7.0",
"symfony/dom-crawler": "^5.4|^6.0|^7.0",
"symfony/framework-bundle": "^5.4|^6.0|^7.0",
"symfony/phpunit-bridge": "^6.0|^7.0",
"symfony/stimulus-bundle": "^2.9.1",
"symfony/twig-bundle": "^5.4|^6.0|^7.0",
"symfony/webpack-encore-bundle": "^1.15"
},
"type": "symfony-bundle",
"extra": {
"thanks": {
"url": "https://github.com/symfony/ux",
"name": "symfony/ux"
}
},
"autoload": {
"psr-4": {
"Symfony\\UX\\TwigComponent\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Twig components for Symfony",
"homepage": "https://symfony.com",
"keywords": [
"components",
"symfony-ux",
"twig"
],
"support": {
"source": "https://github.com/symfony/ux-twig-component/tree/v2.22.1"
},
"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-07T18:05:50+00:00"
},
{
"name": "symfony/validator",
"version": "v7.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/validator.git",
"reference": "6faf9f671d522b76ce87e46a1d2d7740b4385c6f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/validator/zipball/6faf9f671d522b76ce87e46a1d2d7740b4385c6f",
"reference": "6faf9f671d522b76ce87e46a1d2d7740b4385c6f",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php83": "^1.27",
"symfony/translation-contracts": "^2.5|^3"
},
"conflict": {
"doctrine/lexer": "<1.1",
"symfony/dependency-injection": "<6.4",
"symfony/doctrine-bridge": "<7.0",
"symfony/expression-language": "<6.4",
"symfony/http-kernel": "<6.4",
"symfony/intl": "<6.4",
"symfony/property-info": "<6.4",
"symfony/translation": "<6.4.3|>=7.0,<7.0.3",
"symfony/yaml": "<6.4"
},
"require-dev": {
"egulias/email-validator": "^2.1.10|^3|^4",
"symfony/cache": "^6.4|^7.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/finder": "^6.4|^7.0",
"symfony/http-client": "^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/mime": "^6.4|^7.0",
"symfony/property-access": "^6.4|^7.0",
"symfony/property-info": "^6.4|^7.0",
"symfony/translation": "^6.4.3|^7.0.3",
"symfony/type-info": "^7.1",
"symfony/yaml": "^6.4|^7.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Validator\\": ""
},
"exclude-from-classmap": [
"/Tests/",
"/Resources/bin/"
]
},
"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 validate values",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/validator/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/var-dumper", "name": "symfony/var-dumper",
"version": "v7.2.0", "version": "v7.2.0",

View File

@ -13,4 +13,6 @@ return [
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true], Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
Symfony\UX\Turbo\TurboBundle::class => ['all' => true], Symfony\UX\Turbo\TurboBundle::class => ['all' => true],
Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true],
Symfony\UX\Icons\UXIconsBundle::class => ['all' => true],
]; ];

View File

@ -3,7 +3,8 @@ framework:
secret: '%env(APP_SECRET)%' secret: '%env(APP_SECRET)%'
# Note that the session will be started ONLY if you read or write from it. # Note that the session will be started ONLY if you read or write from it.
session: true session:
cookie_samesite: 'lax'
#esi: true #esi: true
#fragments: true #fragments: true

View File

@ -0,0 +1,5 @@
twig_component:
anonymous_template_directory: 'components/'
defaults:
# Namespace & directory for components
App\Twig\Components\: 'components/'

View File

@ -0,0 +1,11 @@
framework:
validation:
# Enables validator auto-mapping support.
# For instance, basic validation constraints will be inferred from Doctrine's metadata.
#auto_mapping:
# App\Entity\: []
when@test:
framework:
validation:
not_compromised_password: false

0
public/test.txt Normal file
View File

View File

@ -5,20 +5,33 @@ namespace App\Controller;
use App\DataObjects\TicketData; use App\DataObjects\TicketData;
use App\Form\TicketForm; use App\Form\TicketForm;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Serializer\SerializerInterface;
final class TicketController extends AbstractController final class TicketController extends AbstractController
{ {
#[Route('/ticket', name: 'app_ticket')] #[Route('/ticket', name: 'app_ticket')]
public function index(Request $request): Response public function index(Request $request, Filesystem $f): Response
{ {
$data = new TicketData(); $f->dumpFile('test.txt', $request->getContent());
$form = $this->createForm(TicketForm::class, $data)->handleRequest($request);
return $this->render('ticket/index.html.twig', [ return $this->render('ticket/index.html.twig', [
'form' => $form->createView(), 'form' => $this->createForm(TicketForm::class)->createView(),
]); ]);
} }
#[Route(path: '/ticket/submit', name: 'app_submit', methods: Request::METHOD_POST)]
public function submit(Request $request, SerializerInterface $serializer): Response
{
$ticketData = $serializer->deserialize(
$request->getContent(),
TicketData::class.'[]',
'json',
['disable_type_enforcement' => true]
);
return $this->json([]);
}
} }

View File

@ -2,14 +2,21 @@
namespace App\DataObjects; namespace App\DataObjects;
use Symfony\Component\Serializer\Attribute\SerializedName;
use Symfony\Component\Validator\Constraints as Assert;
class TicketData class TicketData
{ {
public function __construct( public function __construct(
public string $notes = '', #[Assert\Range(min: 1, max: 3)]
public int $ticket = 0, #[SerializedName('ticket')]
public int $afterShowTicket = 0, public int $ticketType = 0,
public int $kids6yo = 0,
public int $kids12yo = 0, #[Assert\Range(min: 1, max: 3)]
#[SerializedName('food')]
public int $foodType = 0,
public string $note = ''
) { ) {
} }
} }

View File

@ -3,21 +3,12 @@
namespace App\Form; namespace App\Form;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
class TicketForm extends AbstractType class TicketForm extends AbstractType
{ {
public function buildForm(FormBuilderInterface $builder, array $options): void public function buildForm(FormBuilderInterface $builder, array $options): void
{ {
$builder $builder;
->add('ticket', NumberType::class)
->add('afterShowTicket', NumberType::class)
->add('kids6yo', NumberType::class)
->add('kids12yo', NumberType::class)
->add('notes', TextareaType::class);
} }
} }

View File

@ -165,6 +165,18 @@
"templates/base.html.twig" "templates/base.html.twig"
] ]
}, },
"symfony/ux-icons": {
"version": "2.22",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "2.17",
"ref": "803a3bbd5893f9584969ab8670290cdfb6a0a5b5"
},
"files": [
"assets/icons/symfony.svg"
]
},
"symfony/ux-turbo": { "symfony/ux-turbo": {
"version": "2.22", "version": "2.22",
"recipe": { "recipe": {
@ -174,6 +186,30 @@
"ref": "c85ff94da66841d7ff087c19cbcd97a2df744ef9" "ref": "c85ff94da66841d7ff087c19cbcd97a2df744ef9"
} }
}, },
"symfony/ux-twig-component": {
"version": "2.22",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "2.13",
"ref": "67814b5f9794798b885cec9d3f48631424449a01"
},
"files": [
"config/packages/twig_component.yaml"
]
},
"symfony/validator": {
"version": "7.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "7.0",
"ref": "8c1c4e28d26a124b0bb273f537ca8ce443472bfd"
},
"files": [
"config/packages/validator.yaml"
]
},
"symfony/web-profiler-bundle": { "symfony/web-profiler-bundle": {
"version": "7.2", "version": "7.2",
"recipe": { "recipe": {

View File

@ -0,0 +1,17 @@
<form>
<div class="border-b border-gray-100 pb-4 sm:pb-6 w-full flex inline-flex">
<select name="ticket" id="ticket" class="w-1/4 bg-white/90 text-gray-800 font-medium text-sm sm:text-base px-4 sm:px-6 py-2 sm:py-3 rounded-full border border-gray-100 focus:outline-none focus:ring-2 focus:ring-red-500 focus:border-transparent transition-all duration-300 mr-2">
<option value="1">All-Inclusive</option>
<option value="2">After-Show</option>
<option value="3">Kind (6-12)</option>
<option value="4">Kind (0-6)</option>
</select>
<select name="food" id="food" class="w-1/4 bg-white/90 text-gray-800 font-medium text-sm sm:text-base px-4 sm:px-6 py-2 sm:py-3 rounded-full border border-gray-100 focus:outline-none focus:ring-2 focus:ring-red-500 focus:border-transparent transition-all duration-300 mr-2">
<option value="1">Mit Fleisch</option>
<option value="2">Vegetarisch</option>
<option value="3">Vegan</option>
</select>
<input type="text" placeholder="z.B. Allergien" name="note" class="w-1/3 bg-white/90 text-gray-800 font-medium text-sm sm:text-base px-4 sm:px-6 py-2 sm:py-3 rounded-full border border-gray-100 focus:outline-none focus:ring-2 focus:ring-red-500 focus:border-transparent transition-all duration-300 mr-2" />
<button data-action="form#removeEntry" class="w-1/6"><twig:ux:icon name="delete" class="ml-5" height="27px" width="27px" /></button>
</div>
</form>

View File

@ -20,76 +20,22 @@
<h1 class="text-3xl sm:text-4xl md:text-5xl font-bold text-gray-800 text-center mb-6 sm:mb-8 tracking-tight leading-tight"> <h1 class="text-3xl sm:text-4xl md:text-5xl font-bold text-gray-800 text-center mb-6 sm:mb-8 tracking-tight leading-tight">
<span class="bg-clip-text text-transparent bg-gradient-to-r from-red-500 to-orange-500">Tickets kaufen</span> <span class="bg-clip-text text-transparent bg-gradient-to-r from-red-500 to-orange-500">Tickets kaufen</span>
</h1> </h1>
<div class="bg-white/80 backdrop-blur-md shadow-xl rounded-2xl sm:rounded-3xl p-6 sm:p-8 md:p-10 mb-12 sm:mb-16 transform transition-all duration-300 border border-gray-100"> <div class="bg-white/80 backdrop-blur-md shadow-xl rounded-2xl sm:rounded-3xl p-6 sm:p-8 md:p-10 mb-12 sm:mb-16 transform transition-all duration-300 border border-gray-100">
{{ form_start(form, { 'attr': { 'class': 'space-y-6', 'data-controller': 'form' } }) }} <div data-controller="form">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-6"> <div class="w-full flex inline-flex mb-5">
<h2>Tickets</h2> <div class="w-1/4 ml-6">Ticket</div>
<br> <div class="w-1/4 ml-5">Ernährung</div>
<div> <div class="w-1/3 ml-4">Anmerkungen</div>
<label for="ticket" class="block text-sm font-medium text-gray-700 mb-1">Normales Tickets</label> <div class="w-1/6 text-center"></div>
<input type="number" name="{{ field_name(form.ticket) }}" id="ticket" required value="0" data-form-target="ticket"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500 transition-colors">
</div> </div>
<div class="forms">
<div> {% include 'ticket/_partials/_form.html.twig' with {form: form} %}
<label for="afterShowTicket" class="block text-sm font-medium text-gray-700 mb-1">After-Show Tickets</label>
<input type="number" name="{{ field_name(form.afterShowTicket) }}" id="afterShowTicket" required value="0" data-form-target="afterShowTicket"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500 transition-colors">
</div> </div>
<div class="flex inline-flex w-full">
<div> <button class="ml-0" data-action="form#addEntry" type="button"><twig:ux:icon name="plus" height="32px" width="32px"/></button>
<label for="12yo" class="block text-sm font-medium text-gray-700 mb-1">Kinder 6-12</label> <button type="submit" data-action="form#submit" class="bg-gradient-to-r from-red-500 to-orange-500 hover:from-red-600 hover:to-orange-600 text-white px-4 sm:px-6 md:px-8 py-2 sm:py-2.5 rounded-full text-xs sm:text-sm font-medium shadow-md hover:shadow-lg transition-all duration-300 ml-auto">Submit</button>
<input type="number" name="{{ field_name(form.kids12yo) }}" id="12yo" required value="0" data-form-target="kid12yo"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500 transition-colors">
</div>
<div>
<label for="6yo" class="block text-sm font-medium text-gray-700 mb-1">Kinder 0-6</label>
<input type="number" name="{{ field_name(form.kids6yo) }}" id="6yo" required value="0" data-form-target="kid6yo"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500 transition-colors">
</div>
<h2>Essen</h2>
<div data-form-target="error"></div>
<div>
<label for="meat" class="block text-sm font-medium text-gray-700 mb-1">Fleisch</label>
<input type="number" name="{{ field_name(form.afterShowTicket) }}" id="meat" required value="0" data-form-target="meat"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500 transition-colors">
</div>
<div>
<label for="vegetarian" class="block text-sm font-medium text-gray-700 mb-1">Vegetarier</label>
<input type="number" name="{{ field_name(form.afterShowTicket) }}" id="vegetarian" required value="0" data-form-target="vegetarian"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500 transition-colors">
</div>
<div>
<label for="vegan" class="block text-sm font-medium text-gray-700 mb-1">Veganer</label>
<input type="number" name="{{ field_name(form.afterShowTicket) }}" id="vegan" required value="0" data-form-target="vegan"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500 transition-colors">
</div> </div>
</div> </div>
<div>
<label for="notes" class="block text-sm font-medium text-gray-700 mb-1">Anmerkungen</label>
<textarea name="{{ field_name(form.notes) }}" id="notes" rows="4"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500 transition-colors"
placeholder="Unverträglichkeiten, Allergien etc."></textarea>
</div>
<div class="text-center pt-4">
<button type="submit"
class="w-full sm:w-auto inline-block bg-gradient-to-r from-red-500 to-orange-500 hover:from-red-600 hover:to-orange-600 text-white px-8 sm:px-10 py-3 rounded-full text-base font-semibold shadow-xl hover:shadow-2xl transition-all duration-300">
Ticket bestellen
</button>
</div>
{{ form_end(form) }}
</div> </div>
</div> </div>
</main> </main>