From c8e6af689670cdbdbd5092218eb610d113eb5f43 Mon Sep 17 00:00:00 2001 From: lubiana Date: Sat, 21 Jun 2025 15:15:47 +0200 Subject: [PATCH 1/3] #97: add emojis to foodvendor --- assets/app.js | 2 + assets/javascript/emoji-button.js | 14 ++++ importmap.php | 4 +- src/Entity/FoodVendor.php | 31 ++++++- src/Form/FoodVendorType.php | 1 + templates/food_vendor/edit.html.twig | 116 +++++++++++++++++++++++++++ tests/Unit/Entity/FoodVendorTest.php | 12 +++ 7 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 assets/javascript/emoji-button.js diff --git a/assets/app.js b/assets/app.js index 88672ac..0194a77 100644 --- a/assets/app.js +++ b/assets/app.js @@ -14,9 +14,11 @@ import './javascript/theme.js'; import './javascript/emoji-footprint.js'; import './javascript/modes.js'; import './javascript/htmx.js'; +import emojiButtonListener from './javascript/emoji-button.js'; import 'bootstrap'; import { initRadioState } from './javascript/radioState.js'; document.addEventListener('DOMContentLoaded', () => { initRadioState(); + emojiButtonListener(); }); \ No newline at end of file diff --git a/assets/javascript/emoji-button.js b/assets/javascript/emoji-button.js new file mode 100644 index 0000000..8fc3825 --- /dev/null +++ b/assets/javascript/emoji-button.js @@ -0,0 +1,14 @@ +const emojiButtonListener = function () { + const buttons = document.querySelectorAll('.emoji-buttons .btn.btn-primary'); + + buttons.forEach(button => { + button.addEventListener('click', function() { + const emojiField = document.querySelector('#food_vendor_emojis'); + if (emojiField) { + emojiField.value += this.textContent; + } + }); + }); +} + +export default emojiButtonListener; \ No newline at end of file diff --git a/importmap.php b/importmap.php index 36a6905..525e4a7 100644 --- a/importmap.php +++ b/importmap.php @@ -1,4 +1,4 @@ - 'css', ], 'htmx.org' => [ - 'version' => '1.9.12', + 'version' => '2.0.5', ], ]; diff --git a/src/Entity/FoodVendor.php b/src/Entity/FoodVendor.php index a0b3708..48b0c48 100644 --- a/src/Entity/FoodVendor.php +++ b/src/Entity/FoodVendor.php @@ -7,23 +7,27 @@ use App\Repository\FoodVendorRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; +use InvalidArgumentException; use Symfony\Bridge\Doctrine\IdGenerator\UlidGenerator; use Symfony\Bridge\Doctrine\Types\UlidType; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Uid\Ulid; +use Symfony\Component\Validator\Constraints\Length; +use function mb_strlen; + #[ORM\Entity(repositoryClass: FoodVendorRepository::class)] #[ApiResource] class FoodVendor { #[ORM\Column(length: 50)] - #[Groups(['food_order:latest'])] + #[Groups(['food_order:latest', 'food_vendor:read'])] private string|null $name = null; #[ORM\Column(length: 50, nullable: true, options: [ 'default' => '', ])] - #[Groups(['food_order:latest'])] + #[Groups(['food_order:latest', 'food_vendor:read'])] private string|null $phone = null; /** @@ -42,6 +46,14 @@ class FoodVendor #[Groups(['food_order:latest'])] private string|null $menuLink = null; + /** + * String of emojis (max 30 characters) + */ + #[ORM\Column(length: 30, nullable: true)] + #[Groups(['food_order:latest', 'food_vendor:read'])] + #[Length(max: 10)] + private string|null $emojis = null; + public function __construct( #[ORM\Id] #[ORM\GeneratedValue(strategy: 'CUSTOM')] @@ -155,4 +167,19 @@ class FoodVendor $this->phone = $phone; return $this; } + + public function getEmojis(): string|null + { + return $this->emojis; + } + + public function setEmojis(string|null $emojis): static + { + if ($emojis !== null && mb_strlen($emojis) > 30) { + throw new InvalidArgumentException('A maximum of 30 characters is allowed for emojis'); + } + + $this->emojis = $emojis; + return $this; + } } diff --git a/src/Form/FoodVendorType.php b/src/Form/FoodVendorType.php index 7ff61da..466d9e2 100644 --- a/src/Form/FoodVendorType.php +++ b/src/Form/FoodVendorType.php @@ -17,6 +17,7 @@ final class FoodVendorType extends AbstractType ->add('name') ->add('menuLink') ->add('phone') + ->add('emojis') ; } diff --git a/templates/food_vendor/edit.html.twig b/templates/food_vendor/edit.html.twig index 83e4bd3..51daaf7 100644 --- a/templates/food_vendor/edit.html.twig +++ b/templates/food_vendor/edit.html.twig @@ -9,5 +9,121 @@ {{ include('food_vendor/_form.html.twig', {'button_label': 'Update'}) }} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ back to list {% endblock %} diff --git a/tests/Unit/Entity/FoodVendorTest.php b/tests/Unit/Entity/FoodVendorTest.php index 88ab094..ee00ece 100644 --- a/tests/Unit/Entity/FoodVendorTest.php +++ b/tests/Unit/Entity/FoodVendorTest.php @@ -5,6 +5,7 @@ namespace App\Tests\Unit\Entity; use App\Entity\FoodOrder; use App\Entity\FoodVendor; use App\Entity\MenuItem; +use InvalidArgumentException; use Symfony\Component\Uid\Ulid; use function describe; @@ -20,6 +21,17 @@ describe(FoodVendor::class, function (): void { $vendor->setPhone('1234567890'); $this->assertEquals('1234567890', $vendor->getPhone()); + // Test emojis field + $this->assertNull($vendor->getEmojis()); + $emojis = '😀😂🎉👍❤️'; + $vendor->setEmojis($emojis); + $this->assertEquals($emojis, $vendor->getEmojis()); + + // Test emojis validation + $tooManyEmojis = '😀😂🎉👍❤️🚀🎈🎁🎊🎋🎍🎎🎏🎐🎑🎒🎓🎔🎕🎖🎗🎘🎙🎚🎛🎜🎝🎞🎟🎠🎡🎢'; + $this->expectException(InvalidArgumentException::class); + $vendor->setEmojis($tooManyEmojis); + $this->assertCount(0, $vendor->getFoodOrders()); $order1 = new FoodOrder; $vendor->addFoodOrder($order1); From 98feafa3fcb5e566bb0d34cbd6200a6f4b110a83 Mon Sep 17 00:00:00 2001 From: lubiana Date: Sat, 21 Jun 2025 15:20:08 +0200 Subject: [PATCH 2/3] ammend --- importmap.php | 2 +- migrations/Version20250621131822.php | 47 ++++++++++++++++++++++++++++ src/Entity/FoodVendor.php | 2 +- 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 migrations/Version20250621131822.php diff --git a/importmap.php b/importmap.php index 525e4a7..3f89e51 100644 --- a/importmap.php +++ b/importmap.php @@ -1,4 +1,4 @@ -addSql(<<<'SQL' + ALTER TABLE food_vendor ADD COLUMN emojis VARCHAR(30) DEFAULT NULL + SQL); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql(<<<'SQL' + CREATE TEMPORARY TABLE __temp__food_vendor AS SELECT name, phone, menu_link, id FROM food_vendor + SQL); + $this->addSql(<<<'SQL' + DROP TABLE food_vendor + SQL); + $this->addSql(<<<'SQL' + CREATE TABLE food_vendor (name VARCHAR(50) NOT NULL, phone VARCHAR(50) DEFAULT '', menu_link VARCHAR(255) DEFAULT NULL, id BLOB NOT NULL, PRIMARY KEY(id)) + SQL); + $this->addSql(<<<'SQL' + INSERT INTO food_vendor (name, phone, menu_link, id) SELECT name, phone, menu_link, id FROM __temp__food_vendor + SQL); + $this->addSql(<<<'SQL' + DROP TABLE __temp__food_vendor + SQL); + } +} diff --git a/src/Entity/FoodVendor.php b/src/Entity/FoodVendor.php index 48b0c48..83bef71 100644 --- a/src/Entity/FoodVendor.php +++ b/src/Entity/FoodVendor.php @@ -12,8 +12,8 @@ use Symfony\Bridge\Doctrine\IdGenerator\UlidGenerator; use Symfony\Bridge\Doctrine\Types\UlidType; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Uid\Ulid; - use Symfony\Component\Validator\Constraints\Length; + use function mb_strlen; #[ORM\Entity(repositoryClass: FoodVendorRepository::class)] From 4d2ae3a6ab518d12a3d93e1b11accbce7b0872cc Mon Sep 17 00:00:00 2001 From: lubiana Date: Sat, 21 Jun 2025 15:30:44 +0200 Subject: [PATCH 3/3] #98 make background more bonkers --- assets/styles/modes.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/styles/modes.css b/assets/styles/modes.css index 383815b..39dd41e 100644 --- a/assets/styles/modes.css +++ b/assets/styles/modes.css @@ -86,6 +86,9 @@ /* 🎭 BONKERS MODE CLASSES 🎭 */ .bonkers-mode { + background: linear-gradient(270deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan), var(--bs-yellow), var(--bs-green), var(--bs-orange), var(--bs-red), var(--bs-pink)); + background-size: 1600% 1600%; + animation: rainbowGradient 10s ease infinite; transition: all 0.3s ease-in-out; }