diff --git a/.idea/php.xml b/.idea/php.xml
index 8bf6439..8ffcd24 100644
--- a/.idea/php.xml
+++ b/.idea/php.xml
@@ -108,6 +108,7 @@
+
diff --git a/.idea/symfony_crud.iml b/.idea/symfony_crud.iml
index 291bebd..82cda5d 100644
--- a/.idea/symfony_crud.iml
+++ b/.idea/symfony_crud.iml
@@ -3,7 +3,6 @@
-
@@ -102,6 +101,7 @@
+
diff --git a/composer.json b/composer.json
index 16158d2..202f989 100644
--- a/composer.json
+++ b/composer.json
@@ -12,6 +12,7 @@
"doctrine/orm": "^2.17",
"phpdocumentor/reflection-docblock": "^5.3",
"phpstan/phpdoc-parser": "^1.25",
+ "symfony/asset": "7.0.*",
"symfony/console": "7.0.*",
"symfony/dotenv": "7.0.*",
"symfony/flex": "^2",
diff --git a/composer.lock b/composer.lock
index b20f88a..80134c7 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": "0adc3b632a4a91ce75e26a1d5abf763c",
+ "content-hash": "948a7d7c4f60d2cead1e331bc1f1c5b4",
"packages": [
{
"name": "doctrine/cache",
@@ -1794,6 +1794,75 @@
},
"time": "2021-07-14T16:46:02+00:00"
},
+ {
+ "name": "symfony/asset",
+ "version": "v7.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/asset.git",
+ "reference": "82cd3961bc7fc1b3c3f85e8f2b9a287a1dfd6f2f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/asset/zipball/82cd3961bc7fc1b3c3f85e8f2b9a287a1dfd6f2f",
+ "reference": "82cd3961bc7fc1b3c3f85e8f2b9a287a1dfd6f2f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "conflict": {
+ "symfony/http-foundation": "<6.4"
+ },
+ "require-dev": {
+ "symfony/http-client": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Asset\\": ""
+ },
+ "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": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/asset/tree/v7.0.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": "2023-10-31T17:59:56+00:00"
+ },
{
"name": "symfony/cache",
"version": "v7.0.2",
diff --git a/public/js/frontend.js b/public/js/frontend.js
new file mode 100644
index 0000000..45642e4
--- /dev/null
+++ b/public/js/frontend.js
@@ -0,0 +1,181 @@
+function addTableData(tableRow, data, id, printer) {
+ const tableData = document.createElement('td');
+ tableData.id = `printer${printer.id}:${id}`;
+ tableData.textContent = data;
+
+ tableRow.appendChild(tableData);
+}
+
+function removePrinterFromTable(printerId) {
+ const tableBody = document.getElementById(`printer${printerId}`);
+ tableBody.remove();
+}
+
+function deletePrinter(printerId) {
+ fetch(`/printer/${printerId}`, {method: 'DELETE'}).then(response => {
+ if (response.ok) {
+ removePrinterFromTable(printerId);
+ }
+ });
+}
+
+
+function addDeleteButton(tableData, printer) {
+ const deleteButton = setButtonAttributes('btn-danger');
+ deleteButton.textContent = 'Delete';
+
+ deleteButton.onclick = function () {
+ document.getElementById('deleteModalText').textContent = `Are you sure that you want to delete ${printer.name}?`;
+ document.getElementById('deleteModalConfirm').setAttribute('onclick', `deletePrinter(${printer.id})`);
+ }
+
+ tableData.appendChild(deleteButton);
+}
+
+function setButtonAttributes(buttonType) {
+ const button = document.createElement('button');
+ button.setAttribute('data-bs-target', '#viewModal');
+ button.setAttribute('data-bs-toggle', 'modal');
+ button.setAttribute('class', `btn ${buttonType}`);
+ return button;
+}
+
+function addViewButton(tableData, printer) {
+ const viewButton = setButtonAttributes('btn-primary');
+ viewButton.textContent = 'View';
+ viewButton.id = `printer${printer.id}:viewButton`;
+
+ viewButton.onclick = function() {
+ document.getElementById('viewModalName').textContent = `Name: ${printer.name}`;
+ document.getElementById('viewModalPrice').textContent = `Price: ${printer.price.toFixed(2)}$`;
+ document.getElementById('viewModalBuildVolume').textContent = `Build Volume: ${printer.build_volume}`;
+ document.getElementById('viewModalMaxSpeed').textContent = `Max Speed: ${printer.max_speed}mm/s`;
+ }
+
+ tableData.appendChild(viewButton);
+}
+
+function editPrinter(printerId) {
+ const nameInput = document.getElementById('editInputName').value;
+ const priceInput = document.getElementById('editInputPrice').value;
+ const buildVolumeInput = document.getElementById('editInputBuildVolume').value;
+ const maxSpeedInput = document.getElementById('editInputMaxSpeed').value;
+
+ fetch(`/printer/${printerId}`, {method: 'PUT', body: JSON.stringify({
+ name: nameInput,
+ price: Number(priceInput),
+ build_volume: buildVolumeInput,
+ max_speed: Number(maxSpeedInput),
+ })}).then(response => {
+ if (response.ok) {
+ response.json().then(printer => {
+ document.getElementById(`printer${printer.id}:name`).textContent = printer.name;
+ document.getElementById(`printer${printer.id}:price`).textContent = printer.price;
+ document.getElementById(`printer${printer.id}:build_volume`).textContent = printer.build_volume;
+ document.getElementById(`printer${printer.id}:max_speed`).textContent = printer.max_speed;
+
+ const editButton = document.getElementById(`printer${printer.id}:editButton`);
+ editButton.onclick = function() {
+ document.getElementById('editInputName').value = printer.name;
+ document.getElementById('editInputPrice').value = printer.price;
+ document.getElementById('editInputBuildVolume').value = printer.build_volume;
+ document.getElementById('editInputMaxSpeed').value = printer.max_speed;
+ }
+
+ const viewButton = document.getElementById(`printer${printer.id}:viewButton`);
+ viewButton.onclick = function() {
+ document.getElementById('viewModalName').textContent = `Name: ${printer.name}`;
+ document.getElementById('viewModalPrice').textContent = `Price: ${printer.price.toFixed(2)}$`;
+ document.getElementById('viewModalBuildVolume').textContent = 'Build Volume: ' + printer.build_volume;
+ document.getElementById('viewModalMaxSpeed').textContent = `Max Speed: ${printer.max_speed}mm/s`;
+ }
+ });
+ }
+ });
+}
+
+function addEditButton(tableData, printer) {
+ const editButton = document.createElement('button');
+ editButton.setAttribute('data-bs-target', '#editModal');
+ editButton.setAttribute('data-bs-toggle', 'modal');
+ editButton.setAttribute('class', 'btn btn-primary');
+ editButton.id = `printer${printer.id}:editButton`
+ editButton.textContent = 'Edit';
+
+ editButton.onclick = function() {
+ document.getElementById('editInputName').value = printer.name;
+ document.getElementById('editInputPrice').value = printer.price;
+ document.getElementById('editInputBuildVolume').value = printer.build_volume;
+ document.getElementById('editInputMaxSpeed').value = printer.max_speed;
+
+ document.getElementById('editModalConfirm').setAttribute('onclick', `editPrinter(${printer.id})`);
+ }
+
+ tableData.appendChild(editButton);
+}
+
+function addTableActions(tableRow, printer) {
+
+ const tableData = document.createElement('td');
+
+ addViewButton(tableData, printer);
+ addEditButton(tableData, printer);
+ addDeleteButton(tableData, printer);
+
+ tableRow.appendChild(tableData);
+}
+
+function addPrinterToTable(tableBody, printer) {
+ const tableRow = document.createElement('tr');
+ addTableData(tableRow, printer.name, 'name', printer);
+ addTableData(tableRow, `${printer.price.toFixed(2)}$`, 'price', printer);
+ addTableData(tableRow, printer.build_volume, 'build_volume', printer);
+ addTableData(tableRow, printer.max_speed + 'mm/s', 'max_speed', printer);
+
+ addTableActions(tableRow, printer);
+
+ tableRow.id = `printer${printer.id}`;
+ tableBody.appendChild(tableRow);
+}
+
+function loadTable() {
+ fetch('/printer', {method: 'GET'}).then(response => {
+ response.json().then(json => {
+ const tableBody = document.getElementById('table-body');
+ tableBody.innerHTML = null;
+ for (printer of json) {
+ addPrinterToTable(tableBody, printer);
+ }
+ });
+ });
+}
+
+function createPrinter() {
+ const nameInput = document.getElementById('inputName').value;
+ const priceInput = document.getElementById('inputPrice').value;
+ const buildVolumeInput = document.getElementById('inputBuildVolume').value;
+ const maxSpeedInput = document.getElementById('inputMaxSpeed').value;
+
+ document.getElementById('inputName').value = '';
+ document.getElementById('inputPrice').value = '';
+ document.getElementById('inputBuildVolume').value = '';
+ document.getElementById('inputMaxSpeed').value = '';
+
+ fetch('/printer', {method: 'POST', body: JSON.stringify({
+ name: nameInput,
+ price: Number(priceInput),
+ build_volume: buildVolumeInput,
+ max_speed: Number(maxSpeedInput),
+ })}).then(response => {
+ if (response.ok) {
+ const tableBody = document.getElementById('table-body');
+ response.json().then(printer => {
+ addPrinterToTable(tableBody, printer);
+ });
+ }
+ });
+}
+
+document.addEventListener("DOMContentLoaded", function() {
+ loadTable();
+});
\ No newline at end of file
diff --git a/templates/frontend/index.html.twig b/templates/frontend/index.html.twig
index 7a90719..051e961 100644
--- a/templates/frontend/index.html.twig
+++ b/templates/frontend/index.html.twig
@@ -1,184 +1,7 @@
{% extends 'base.html.twig' %}
{% block javascripts %}
-
+
{% endblock %}
{% block body %}