diff --git a/app/Http/Controllers/Web/Auth/LoginController.php b/app/Http/Controllers/Web/Auth/LoginController.php index cc7361d..cf40d2c 100644 --- a/app/Http/Controllers/Web/Auth/LoginController.php +++ b/app/Http/Controllers/Web/Auth/LoginController.php @@ -102,7 +102,7 @@ class LoginController extends Controller } elseif ($user->hasRole('teacher')) { return redirect()->to('userarea/teacher.php'); } elseif ($user->hasRole('school_owner')) { - return redirect()->to('userarea/school.php'); + return redirect()->to('userarea/school_dashboard.php'); } // Fallback nel caso il ruolo non corrisponda diff --git a/public/userarea/get_product_classes.php b/public/userarea/get_product_classes.php index f67eec5..ffaf8b1 100644 --- a/public/userarea/get_product_classes.php +++ b/public/userarea/get_product_classes.php @@ -1,14 +1,14 @@ getConnection(); // Verifica che iduserlogin sia definito if (!isset($iduserlogin)) { - die("Errore: ID utente non definito."); + http_response_code(400); + echo json_encode(['error' => 'ID utente non definito']); + exit; } // Recupera i dati della scuola in base all'utente loggato @@ -20,22 +20,80 @@ $stmt = $pdo->prepare(" $stmt->execute([$iduserlogin]); $school = $stmt->fetch(); if (!$school) { - die("Errore: Nessuna scuola trovata per l'utente loggato."); + http_response_code(404); + echo json_encode(['error' => 'Nessuna scuola trovata per l\'utente loggato']); + exit; } $school_id = $school['id']; $product_id = $_GET['product_id'] ?? 0; +$variation_id = $_GET['variation_id'] ?? 0; -// Verifica che il prodotto appartenga alla scuola -$stmt = $pdo->prepare("SELECT id FROM products WHERE id = ? AND school_id = ?"); -$stmt->execute([$product_id, $school_id]); -if (!$stmt->fetch()) { - die("Errore: Prodotto non trovato o non autorizzato."); +if ($product_id <= 0) { + http_response_code(400); + echo json_encode(['error' => 'ID prodotto non valido']); + exit; +} + +// Recupera i dettagli del prodotto (inclusi is_full_access e auto_propagate_to_order) +$stmt = $pdo->prepare(" + SELECT id, is_full_access, auto_propagate_to_order + FROM products + WHERE id = ? AND school_id = ? +"); +$stmt->execute([$product_id, $school_id]); +$product = $stmt->fetch(PDO::FETCH_ASSOC); +if (!$product) { + http_response_code(404); + echo json_encode(['error' => 'Prodotto non trovato o non autorizzato']); + exit; +} + +// Inizializza l'array di risposta con i dettagli del prodotto +$response = [ + 'is_full_access' => $product['is_full_access'], + 'auto_propagate_to_order' => $product['auto_propagate_to_order'], + 'class_types' => [] +]; + +// Se variation_id è specificato, recupera i dettagli della variazione +if ($variation_id > 0) { + $stmt = $pdo->prepare(" + SELECT id, auto_propagate_to_order + FROM product_variations + WHERE id = ? AND product_id = ? + "); + $stmt->execute([$variation_id, $product_id]); + $variation = $stmt->fetch(PDO::FETCH_ASSOC); + if (!$variation) { + http_response_code(404); + echo json_encode(['error' => 'Variazione non trovata o non autorizzata']); + exit; + } + // Sovrascrivi auto_propagate_to_order con il valore della variazione + $response['auto_propagate_to_order'] = $variation['auto_propagate_to_order']; +} + +// Recupera le classi associate +if ($variation_id > 0) { + $stmt = $pdo->prepare(" + SELECT class_type_id + FROM product_class_types + WHERE product_id = ? AND variation_id = ? + "); + $stmt->execute([$product_id, $variation_id]); +} else { + $stmt = $pdo->prepare(" + SELECT class_type_id + FROM product_class_types + WHERE product_id = ? AND variation_id IS NULL + "); + $stmt->execute([$product_id]); } -$stmt = $pdo->prepare("SELECT class_type_id FROM product_class_types WHERE product_id = ?"); -$stmt->execute([$product_id]); $class_types = $stmt->fetchAll(PDO::FETCH_COLUMN); +$response['class_types'] = $class_types; header('Content-Type: application/json'); -echo json_encode($class_types); +echo json_encode($response); +exit; diff --git a/public/userarea/photoclass/1-1744291511-Screenshot 2023-11-01 184252.png b/public/userarea/photoclass/1-1744291511-Screenshot 2023-11-01 184252.png new file mode 100644 index 0000000..d680be5 Binary files /dev/null and b/public/userarea/photoclass/1-1744291511-Screenshot 2023-11-01 184252.png differ diff --git a/public/userarea/product_detail.php b/public/userarea/product_detail.php new file mode 100644 index 0000000..799b110 --- /dev/null +++ b/public/userarea/product_detail.php @@ -0,0 +1,149 @@ +getConnection(); + +$product_id = $_GET['product_id'] ?? 0; + +// Recupera i dettagli del prodotto +$stmt = $pdo->prepare(" + SELECT p.id, p.name AS product_name, + c.name AS class_name, c.description AS class_description, c.photo AS class_photo + FROM products p + LEFT JOIN product_class_types pct ON p.id = pct.product_id AND pct.variation_id IS NULL + LEFT JOIN class_types ct ON pct.class_type_id = ct.id + LEFT JOIN classes c ON ct.class_id = c.id + WHERE p.id = ? + GROUP BY p.id +"); +$stmt->execute([$product_id]); +$product = $stmt->fetch(PDO::FETCH_ASSOC); + +if (!$product) { + die("Prodotto non trovato."); +} + +// Recupera le variazioni del prodotto +$stmt = $pdo->prepare(" + SELECT id, name, price + FROM product_variations + WHERE product_id = ? AND status = 'active' +"); +$stmt->execute([$product_id]); +$variations = $stmt->fetchAll(PDO::FETCH_ASSOC); + +// Recupera le variazioni delle classi associate al prodotto +$stmt = $pdo->prepare(" + SELECT ct.id, ct.level, ct.day_of_week + FROM product_class_types pct + JOIN class_types ct ON pct.class_type_id = ct.id + WHERE pct.product_id = ? AND pct.variation_id IS NULL +"); +$stmt->execute([$product_id]); +$class_types = $stmt->fetchAll(PDO::FETCH_ASSOC); +?> + + + + + + + + Dettaglio Prodotto - <?php echo htmlspecialchars($product['product_name']); ?> + + + + + +
+

+
+
+ <?php echo htmlspecialchars($product['class_name']); ?> +
+
+

+

+ +
+ + +
+ +
+ + +
+ +
Prezzo: -- €
+ + +
+
+
+ + + + + + + \ No newline at end of file diff --git a/public/userarea/products.php b/public/userarea/products.php index e60ba50..1141161 100644 --- a/public/userarea/products.php +++ b/public/userarea/products.php @@ -29,21 +29,65 @@ if (!$school) { $school_id = $school['id']; $school_name = $school['name']; -// Recupera i prodotti della scuola con classi e variazioni associate +// Recupera i prodotti della scuola con variazioni, classi e variazioni associate $stmt = $pdo->prepare(" SELECT p.*, - GROUP_CONCAT(DISTINCT c.name) AS class_names, - GROUP_CONCAT(DISTINCT CONCAT(ct.level, ' (', ct.day_of_week, ')')) AS variation_names + p.auto_propagate_to_order AS product_auto_propagate, + pv.id AS variation_id, pv.name AS variation_name, pv.price, pv.duration_days, pv.max_entries, pv.weekly_limit, pv.max_recoveries, pv.recovery_validity_days, pv.allow_freeze, pv.freeze_max_days, pv.max_inventory, pv.current_inventory, pv.status AS variation_status, pv.auto_propagate_to_order AS variation_auto_propagate, + GROUP_CONCAT(DISTINCT CASE WHEN pct.variation_id IS NULL THEN c.name END) AS class_names, + GROUP_CONCAT(DISTINCT CASE WHEN pct.variation_id IS NULL THEN CONCAT(ct.level, ' (', ct.day_of_week, ')') END) AS variation_names, + GROUP_CONCAT(DISTINCT CASE WHEN pct.variation_id = pv.id THEN c.name END) AS variation_class_names, + GROUP_CONCAT(DISTINCT CASE WHEN pct.variation_id = pv.id THEN CONCAT(ct.level, ' (', ct.day_of_week, ')') END) AS variation_variation_names FROM products p - LEFT JOIN product_class_types pct ON p.id = pct.product_id + LEFT JOIN product_variations pv ON p.id = pv.product_id + LEFT JOIN product_class_types pct ON (p.id = pct.product_id AND (pct.variation_id = pv.id OR pct.variation_id IS NULL)) LEFT JOIN class_types ct ON pct.class_type_id = ct.id LEFT JOIN classes c ON ct.class_id = c.id WHERE p.school_id = ? - GROUP BY p.id - ORDER BY p.created_at DESC + GROUP BY p.id, pv.id + ORDER BY p.created_at DESC, pv.created_at DESC "); $stmt->execute([$school_id]); -$products = $stmt->fetchAll(); +$raw_products = $stmt->fetchAll(); + +// Organizza i prodotti in una struttura gerarchica: prodotto -> variazioni +$products = []; +foreach ($raw_products as $row) { + $product_id = $row['id']; + if (!isset($products[$product_id])) { + $products[$product_id] = [ + 'id' => $row['id'], + 'name' => $row['name'], + 'type' => $row['type'], + 'is_full_access' => $row['is_full_access'], + 'status' => $row['status'], + 'auto_propagate_to_order' => $row['product_auto_propagate'], + 'class_names' => $row['class_names'], + 'variation_names' => $row['variation_names'], + 'variations' => [] + ]; + } + if ($row['variation_id']) { + $products[$product_id]['variations'][] = [ + 'variation_id' => $row['variation_id'], + 'variation_name' => $row['variation_name'], + 'price' => $row['price'], + 'duration_days' => $row['duration_days'], + 'max_entries' => $row['max_entries'], + 'weekly_limit' => $row['weekly_limit'], + 'max_recoveries' => $row['max_recoveries'], + 'recovery_validity_days' => $row['recovery_validity_days'], + 'allow_freeze' => $row['allow_freeze'], + 'freeze_max_days' => $row['freeze_max_days'], + 'max_inventory' => $row['max_inventory'], + 'current_inventory' => $row['current_inventory'], + 'variation_status' => $row['variation_status'], + 'auto_propagate_to_order' => $row['variation_auto_propagate'], + 'class_names' => $row['variation_class_names'], + 'variation_names' => $row['variation_variation_names'] + ]; + } +} // Recupera tutte le classi e le loro variazioni per il modale di aggiunta/modifica prodotti $stmt = $pdo->prepare(" @@ -81,10 +125,12 @@ $error = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $action = $_POST['action'] ?? ''; + // Aggiungi un prodotto // Aggiungi un prodotto if ($action === 'add_product') { $name = $_POST['name'] ?? ''; $type = $_POST['type'] ?? ''; + $variation_name = $_POST['variation_name'] ?? ''; $price = $_POST['price'] ?? 0; $duration_days = $_POST['duration_days'] ?: null; $max_entries = $_POST['max_entries'] ?: null; @@ -94,20 +140,30 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $allow_freeze = $_POST['allow_freeze'] ?? 0; $freeze_max_days = $_POST['freeze_max_days'] ?: null; $max_inventory = $_POST['max_inventory'] ?: null; + $is_full_access = $_POST['is_full_access'] ?? 0; + $auto_propagate_to_order = $_POST['auto_propagate_to_order'] ?? 0; // Nuovo campo $class_types = $_POST['class_types'] ?? []; - if (empty($name) || empty($type) || $price <= 0) { - $error = "Nome, tipo e prezzo sono obbligatori."; + if (empty($name) || empty($type) || empty($variation_name) || $price <= 0) { + $error = "Nome, tipo, nome variazione e prezzo sono obbligatori."; } else { - $current_inventory = $max_inventory; // All'inizio, l'inventario corrente è uguale al massimo + // Inserisci il prodotto principale $stmt = $pdo->prepare(" - INSERT INTO products (school_id, name, type, price, duration_days, max_entries, weekly_limit, max_recoveries, recovery_validity_days, allow_freeze, freeze_max_days, max_inventory, current_inventory) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - "); + INSERT INTO products (school_id, name, type, is_full_access, auto_propagate_to_order) + VALUES (?, ?, ?, ?, ?) + "); + $stmt->execute([$school_id, $name, $type, $is_full_access, $auto_propagate_to_order]); + $product_id = $pdo->lastInsertId(); + + // Inserisci la variazione del prodotto + $current_inventory = $max_inventory; + $stmt = $pdo->prepare(" + INSERT INTO product_variations (product_id, name, price, duration_days, max_entries, weekly_limit, max_recoveries, recovery_validity_days, allow_freeze, freeze_max_days, max_inventory, current_inventory, auto_propagate_to_order) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + "); $stmt->execute([ - $school_id, - $name, - $type, + $product_id, + $variation_name, $price, $duration_days, $max_entries, @@ -117,13 +173,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $allow_freeze, $freeze_max_days, $max_inventory, - $current_inventory + $current_inventory, + $auto_propagate_to_order // Propaga lo stesso valore del prodotto ]); - $product_id = $pdo->lastInsertId(); - - // Associa le classi selezionate - if (!empty($class_types)) { + // Associa le classi selezionate (se non è full access) + if (!$is_full_access && !empty($class_types)) { $stmt = $pdo->prepare("INSERT INTO product_class_types (product_id, class_type_id, entry_cost) VALUES (?, ?, 1)"); foreach ($class_types as $class_type_id) { $stmt->execute([$product_id, $class_type_id]); @@ -136,11 +191,101 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { } } + // add product variation + + // Aggiungi una variazione + // Aggiungi una variazione + if ($action === 'add_variation') { + $product_id = $_POST['product_id'] ?? 0; + $variation_name = $_POST['variation_name'] ?? ''; + $price = $_POST['price'] ?? 0; + $duration_days = $_POST['duration_days'] ?: null; + $max_entries = $_POST['max_entries'] ?: null; + $weekly_limit = $_POST['weekly_limit'] ?: null; + $max_recoveries = $_POST['max_recoveries'] ?: null; + $recovery_validity_days = $_POST['recovery_validity_days'] ?: null; + $allow_freeze = $_POST['allow_freeze'] ?? 0; + $freeze_max_days = $_POST['freeze_max_days'] ?: null; + $max_inventory = $_POST['max_inventory'] ?: null; + $current_inventory = $_POST['current_inventory'] ?? $max_inventory; + $status = $_POST['status'] ?? 'active'; + $auto_propagate_to_order = $_POST['auto_propagate_to_order'] ?? 0; // Nuovo campo + $class_types = $_POST['class_types'] ?? []; + + if ($product_id <= 0 || empty($variation_name) || $price <= 0) { + $error = "ID prodotto, nome variazione e prezzo sono obbligatori."; + } else { + // Verifica che il prodotto appartenga alla scuola e recupera is_full_access + $stmt = $pdo->prepare("SELECT id, is_full_access FROM products WHERE id = ? AND school_id = ?"); + $stmt->execute([$product_id, $school_id]); + $product = $stmt->fetch(); + if (!$product) { + $error = "Prodotto non trovato."; + } else { + $is_full_access = $product['is_full_access']; + + // Inserisci la nuova variazione + $stmt = $pdo->prepare(" + INSERT INTO product_variations (product_id, name, price, duration_days, max_entries, weekly_limit, max_recoveries, recovery_validity_days, allow_freeze, freeze_max_days, max_inventory, current_inventory, status, auto_propagate_to_order) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + "); + $stmt->execute([ + $product_id, + $variation_name, + $price, + $duration_days, + $max_entries, + $weekly_limit, + $max_recoveries, + $recovery_validity_days, + $allow_freeze, + $freeze_max_days, + $max_inventory, + $current_inventory, + $status, + $auto_propagate_to_order + ]); + + // Recupera l'ID della variazione appena creata + $variation_id = $pdo->lastInsertId(); + + // Associa le classi alla variazione (se non è full access) + if (!$is_full_access) { + if (!empty($class_types)) { + // Usa le classi selezionate nel modale + $stmt = $pdo->prepare("INSERT INTO product_class_types (product_id, variation_id, class_type_id, entry_cost) VALUES (?, ?, ?, 1)"); + foreach ($class_types as $class_type_id) { + $stmt->execute([$product_id, $variation_id, $class_type_id]); + } + } else { + // Se non sono state selezionate classi, eredita quelle del prodotto + $stmt = $pdo->prepare("SELECT class_type_id FROM product_class_types WHERE product_id = ? AND variation_id IS NULL"); + $stmt->execute([$product_id]); + $inherited_class_types = $stmt->fetchAll(PDO::FETCH_COLUMN); + + if (!empty($inherited_class_types)) { + $stmt = $pdo->prepare("INSERT INTO product_class_types (product_id, variation_id, class_type_id, entry_cost) VALUES (?, ?, ?, 1)"); + foreach ($inherited_class_types as $class_type_id) { + $stmt->execute([$product_id, $variation_id, $class_type_id]); + } + } + } + } + + $success_message = "Variazione aggiunta con successo!"; + header("Location: products.php"); + exit; + } + } + } + // Modifica un prodotto // Modifica un prodotto if ($action === 'edit_product') { $id = $_POST['id'] ?? 0; + $variation_id = $_POST['variation_id'] ?? 0; $name = $_POST['name'] ?? ''; $type = $_POST['type'] ?? ''; + $variation_name = $_POST['variation_name'] ?? ''; $price = $_POST['price'] ?? 0; $duration_days = $_POST['duration_days'] ?: null; $max_entries = $_POST['max_entries'] ?: null; @@ -151,49 +296,86 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $freeze_max_days = $_POST['freeze_max_days'] ?: null; $max_inventory = $_POST['max_inventory'] ?: null; $current_inventory = $_POST['current_inventory'] ?: null; + $is_full_access = $_POST['is_full_access'] ?? 0; $status = $_POST['status'] ?? 'active'; + $auto_propagate_to_order = $_POST['auto_propagate_to_order'] ?? 0; // Nuovo campo $class_types = $_POST['class_types'] ?? []; - if ($id <= 0 || empty($name) || empty($type) || $price <= 0) { - $error = "ID, nome, tipo e prezzo sono obbligatori."; + if ($id <= 0 || empty($name) || empty($type)) { + $error = "ID, nome e tipo sono obbligatori."; + } elseif ($variation_id > 0 && (empty($variation_name) || $price <= 0)) { + $error = "Nome variazione e prezzo sono obbligatori per la variazione."; } else { - $stmt = $pdo->prepare(" + // Verifica che il prodotto appartenga alla scuola + $stmt = $pdo->prepare("SELECT id FROM products WHERE id = ? AND school_id = ?"); + $stmt->execute([$id, $school_id]); + if (!$stmt->fetch()) { + $error = "Prodotto non trovato."; + } else { + // Aggiorna il prodotto principale + $stmt = $pdo->prepare(" UPDATE products - SET name = ?, type = ?, price = ?, duration_days = ?, max_entries = ?, weekly_limit = ?, max_recoveries = ?, recovery_validity_days = ?, allow_freeze = ?, freeze_max_days = ?, max_inventory = ?, current_inventory = ?, status = ? - WHERE id = ? AND school_id = ? + SET name = ?, type = ?, is_full_access = ?, status = ?, auto_propagate_to_order = ? + WHERE id = ? "); - $stmt->execute([ - $name, - $type, - $price, - $duration_days, - $max_entries, - $weekly_limit, - $max_recoveries, - $recovery_validity_days, - $allow_freeze, - $freeze_max_days, - $max_inventory, - $current_inventory, - $status, - $id, - $school_id - ]); + $stmt->execute([$name, $type, $is_full_access, $status, $auto_propagate_to_order, $id]); - // Aggiorna le classi associate - $stmt = $pdo->prepare("DELETE FROM product_class_types WHERE product_id = ?"); - $stmt->execute([$id]); - - if (!empty($class_types)) { - $stmt = $pdo->prepare("INSERT INTO product_class_types (product_id, class_type_id, entry_cost) VALUES (?, ?, 1)"); - foreach ($class_types as $class_type_id) { - $stmt->execute([$id, $class_type_id]); + // Aggiorna la variazione, se presente + if ($variation_id > 0) { + $stmt = $pdo->prepare(" + UPDATE product_variations + SET name = ?, price = ?, duration_days = ?, max_entries = ?, weekly_limit = ?, max_recoveries = ?, recovery_validity_days = ?, allow_freeze = ?, freeze_max_days = ?, max_inventory = ?, current_inventory = ?, status = ?, auto_propagate_to_order = ? + WHERE id = ? AND product_id = ? + "); + $stmt->execute([ + $variation_name, + $price, + $duration_days, + $max_entries, + $weekly_limit, + $max_recoveries, + $recovery_validity_days, + $allow_freeze, + $freeze_max_days, + $max_inventory, + $current_inventory, + $status, + $auto_propagate_to_order, + $variation_id, + $id + ]); } - } - $success_message = "Prodotto modificato con successo!"; - header("Location: products.php"); - exit; + // Aggiorna le classi associate + if ($variation_id > 0) { + // Se stiamo modificando una variazione, aggiorna le classi associate alla variazione + $stmt = $pdo->prepare("DELETE FROM product_class_types WHERE product_id = ? AND variation_id = ?"); + $stmt->execute([$id, $variation_id]); + } else { + // Se stiamo modificando il prodotto, aggiorna le classi associate al prodotto + $stmt = $pdo->prepare("DELETE FROM product_class_types WHERE product_id = ? AND variation_id IS NULL"); + $stmt->execute([$id]); + } + + if (!$is_full_access && !empty($class_types)) { + $stmt = $pdo->prepare("INSERT INTO product_class_types (product_id, variation_id, class_type_id, entry_cost) VALUES (?, ?, ?, 1)"); + foreach ($class_types as $class_type_id) { + $class_type_id = (int)$class_type_id; + if ($class_type_id > 0) { + // Verifica che il class_type_id esista + $checkStmt = $pdo->prepare("SELECT id FROM class_types WHERE id = ?"); + $checkStmt->execute([$class_type_id]); + if ($checkStmt->fetch()) { + $stmt->execute([$id, $variation_id > 0 ? $variation_id : null, $class_type_id]); + } + } + } + } + + $success_message = "Prodotto modificato con successo!"; + header("Location: products.php"); + exit; + } } } @@ -211,6 +393,34 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { exit; } } + + //delete variations product + + if ($action === 'delete_variation') { + $variation_id = $_POST['variation_id'] ?? 0; + + if ($variation_id <= 0) { + $error = "ID variazione non valido."; + } else { + // Verifica che la variazione appartenga a un prodotto della scuola + $stmt = $pdo->prepare(" + SELECT pv.id + FROM product_variations pv + JOIN products p ON pv.product_id = p.id + WHERE pv.id = ? AND p.school_id = ? + "); + $stmt->execute([$variation_id, $school_id]); + if (!$stmt->fetch()) { + $error = "Variazione non trovata."; + } else { + $stmt = $pdo->prepare("DELETE FROM product_variations WHERE id = ?"); + $stmt->execute([$variation_id]); + $success_message = "Variazione eliminata con successo!"; + header("Location: products.php"); + exit; + } + } + } } ?> @@ -225,6 +435,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { + + @@ -265,56 +487,132 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
-
- - +
+ + + + + + + + + + + + + + + + - - - - - - - - + - - - + + + - + + + + + + + + + + - - - - + + + + + - - - + + + + - - -
NomeVariazioneTipoPrezzoDurata (giorni)IngressiInventarioAccesso CompletoClassi AssociateAzioni
NomeTipoPrezzoDurata (giorni)IngressiInventarioClassi AssociateAzioniNessun prodotto trovato.
Nessun prodotto trovato.- + 'Carnet', + 'subscription' => 'Abbonamento', + 'drop_in' => 'Lezione Singola' + ]; + echo $type_labels[$product['type']] ?? $product['type']; + ?> + ---- + ' . htmlspecialchars($variation_names) . ''; + } + } else { + echo 'Nessuna classe associata'; + } + ?> + + + +
+ + + +
+
'Carnet', - 'subscription' => 'Abbonamento', - 'drop_in' => 'Lezione Singola' - ]; echo $type_labels[$product['type']] ?? $product['type']; ?> ' . htmlspecialchars($variation_names) . ''; @@ -328,124 +626,242 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { -
- - -
-
+ + + +
-