Add initial implementation of Fantacalcio application

This commit is contained in:
Simone
2026-03-07 17:15:34 +01:00
parent 6e74a538ea
commit dc6fc7b7e0
41 changed files with 2086 additions and 0 deletions
+192
View File
@@ -0,0 +1,192 @@
<?php
require_once 'logic.php';
/**
* IMPORTA GIOCATORI
* CSV → JSON { "numero": { "nome": "...", "cognome": "...", ... } }
*/
function importaGiocatori(string $csvContent): string|false
{
$separators = detectSeparators($csvContent);
$delimiter = $separators['delimiter'];
$result = [];
$lines = preg_split('/\r\n|\n|\r/', trim($csvContent));
$headers = null;
foreach ($lines as $index => $line) {
$row = str_getcsv($line, $delimiter);
if (empty($row) || trim(implode('', $row)) === '') {
continue;
}
if ($headers === null) {
$headers = array_map('trim', $row);
continue;
}
$data = [];
foreach ($headers as $i => $header) {
$value = isset($row[$i]) ? trim($row[$i]) : '';
if ($value !== '') {
$data[$header] = $value;
}
}
$key = $data['numero'] ?? '';
if ($key === '') continue;
unset($data['numero']);
// conversioni tipi speciali (isDestro rimane booleano)
if (isset($data['isDestro'])) {
$lower = strtolower($data['isDestro']);
$data['isDestro'] = in_array($lower, ['true', '1', 'si', 'yes', 'vero', 't']) ? true : false;
}
// Conversione esplicita per i campi che devono essere numeri interi
foreach (['partiteGiocate', 'assist', 'goal'] as $field) {
if (isset($data[$field]) && is_numeric($data[$field])) {
$data[$field] = (int)$data[$field];
}
}
$result[$key] = $data;
}
ksort($result, SORT_NATURAL);
return json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}
/**
* ESPORTA GIOCATORI
* JSON → CSV
*/
function esportaGiocatori(string|array $giocatoriJson, string $delimiter = ';'): string
{
$data = is_string($giocatoriJson) ? json_decode($giocatoriJson, true) : $giocatoriJson;
if (!is_array($data) || empty($data)) {
return '';
}
// raccogliamo tutte le chiavi possibili (per gestire giocatori con campi extra)
$allKeys = ['numero'];
foreach ($data as $obj) {
$allKeys = array_merge($allKeys, array_keys($obj));
}
$allKeys = array_unique($allKeys);
$csvLines = [];
$csvLines[] = implode($delimiter, array_map(fn($k) => csvEscape($k), $allKeys));
foreach ($data as $numero => $giocatore) {
$row = ['numero' => $numero];
foreach ($allKeys as $key) {
if ($key === 'numero') continue;
$value = $giocatore[$key] ?? '';
// Gestione speciale per i booleani
if ($key === 'isDestro' && is_bool($value)) {
$row[$key] = $value ? 'true' : 'false';
} else {
$row[$key] = $value;
}
}
$csvLines[] = implode($delimiter, array_map('csvEscape', $row));
}
return implode("\n", $csvLines);
}
/**
* IMPORTA VOTI
* CSV → JSON { "numero": [voto1, voto2, ...] }
*/
function importaVoti(string $csvContent): string|false
{
$separators = detectSeparators($csvContent);
$delimiter = $separators['delimiter'];
$result = [];
$lines = preg_split('/\r\n|\n|\r/', trim($csvContent));
foreach ($lines as $index => $line) {
if ($index === 0) continue; // skip header
$row = str_getcsv($line, $delimiter);
if (empty($row) || trim($row[0] ?? '') === '') continue;
$key = trim($row[0]);
if ($key === '') continue;
$voti = [];
// I voti sono tutti gli elementi dalla seconda colonna in poi
for ($i = 1; $i < count($row); $i++) {
$val = trim($row[$i]);
// Normalizza SEMPRE la virgola in punto per gestire contenuti misti.
// Questo è sicuro per i voti, che non usano separatori per le migliaia.
$normalizedVal = str_replace(',', '.', $val);
if ($val !== '' && is_numeric($normalizedVal)) {
$voti[] = (float)$normalizedVal;
}
}
if (!empty($voti)) {
$result[(string)$key] = $voti;
}
}
ksort($result, SORT_NATURAL);
return json_encode($result, JSON_PRETTY_PRINT);
}
/**
* ESPORTA VOTI
* JSON → CSV
*/
function esportaVoti(string|array $votiJson, string $delimiter = ';', string $decimal = '.'): string
{
$data = is_string($votiJson) ? json_decode($votiJson, true) : $votiJson;
if (!is_array($data) || empty($data)) {
return '';
}
$csvLines = [];
$csvLines[] = 'numero' . $delimiter . 'voti'; // Intestazione
foreach ($data as $numero => $votiArray) {
if (!is_array($votiArray)) {
continue;
}
// Converti i voti nel formato decimale richiesto
$formattedVoti = array_map(function($voto) use ($decimal) {
return str_replace('.', $decimal, (string)$voto);
}, $votiArray);
// Crea una riga con il numero del giocatore seguito dai suoi voti
$row = array_merge([$numero], $formattedVoti);
// Implode della riga con il delimitatore
$csvLines[] = implode($delimiter, $row);
}
return implode("\n", $csvLines);
}
/**
* Utility: escaping CSV
*/
function csvEscape($value): string
{
$value = (string)$value;
if (str_contains($value, ',') || str_contains($value, '"') || str_contains($value, "\n")) {
return '"' . str_replace('"', '""', $value) . '"';
}
return $value;
}
Executable
+12
View File
@@ -0,0 +1,12 @@
<?php
$squadre = json_decode(file_get_contents('squadre.json'), true);
$giocatori = json_decode(file_get_contents('giocatori.json'), true);
$voti = json_decode(file_get_contents('voti.json'), true);
$partite = json_decode(file_get_contents('partite.json'), true);
?>
<script>
const squadre = <?php echo json_encode($squadre); ?>;
const giocatori = <?php echo json_encode($giocatori); ?>;
const voti = <?php echo json_encode($voti); ?>;
const partite = <?php echo json_encode($partite); ?>;
</script>
Executable
+39
View File
@@ -0,0 +1,39 @@
<?php
require 'conversioni.php';
if (!isset($_GET['type'])) {
die('Tipo di esportazione non specificato.');
}
$type = $_GET['type'];
$sourceFile = '';
$outputFilename = '';
$exportFunction = '';
if ($type === 'giocatori') {
$sourceFile = 'giocatori.json';
$outputFilename = 'giocatori.csv';
$exportFunction = 'esportaGiocatori';
} elseif ($type === 'voti') {
$sourceFile = 'voti.json';
$outputFilename = 'voti.csv';
$exportFunction = 'esportaVoti';
} else {
die('Tipo di esportazione non valido.');
}
if (!file_exists($sourceFile)) {
die("File di origine non trovato: $sourceFile");
}
$jsonContent = file_get_contents($sourceFile);
$csvContent = $exportFunction($jsonContent);
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="' . $outputFilename . '"');
// Pulisce il buffer di output prima di inviare il file
ob_end_clean();
echo $csvContent;
exit;
Executable
+26
View File
@@ -0,0 +1,26 @@
home-> classifica top 5 + ultimi risultati
pagine tutte le squade cliccabili->lista giocatori cliccabili->punteggi giocatori
gol
parata
assist
2 Ben Adam
3 Bonanno
4 Borgonovo
5 Casiraghi
6 Celli
8 Civita
9 Redaelli
10 Costamagna
11 Ferlin
12 Foglieni
13 Fusillo
14 Gilardi
15 Meroni
16 Nava
17 Riva
19 Santarlasci
21 Turiello
22 Varenna
Executable
+78
View File
@@ -0,0 +1,78 @@
# Formati file .json
## Formato giocatore (giocatori.json)
```json
{
"string->[numero_giocatore]": {
"nome": "string->[nome]",
"cognome": "string->[cognome]",
"soprannome": "string->[soprannome]",
"ruolo": "string->[ruolo]",
"isDestro": "boolean->[true/false]",
"partiteGiocate": "int->[numero partite giocate]",
"assist": "int->[numero assist]",
"goal": "int->[numero goal]"
},
"10 (esempio)": {
"nome": "Test",
"cognome": "Giocatore",
"soprannome": "Il Goat",
"ruolo": "Portiere",
"isDestro": true,
"partiteGiocate": 5,
"assist": 2,
"goal": 3
}
}
```
formato foto: ``` <nome>_<cognome>.png ``` (tutto minuscolo)
##
## Formato squadra (squadre.json)
```json
{
"string->[squadraX](x = string->[numero squadra])": [
"array[int]->[numero giocatori]"
],
"squadra0 (esempio)": [
1, 5, 19, 31
]
}
```
##
## Formato voti (voti.json)
```json
{
"string->[numero_giocatore]": [
"array[int->[voti 2=>10]"
],
"10 (esempio)": [
5, 9, 7.5
]
}
```
---
---
---
---
# Formati file .csv
## Formato giocatore (giocatori.csv)
### Esempio:
```csv
numero, nome, cognome, soprannome, ruolo, isDestro, partiteGiocate, assist, goal, assenze
10, Test, Giocatore, Il Goat, Portiere, true, 5, 2, 3 , 1
```
formato foto: ``` <nome>_<cognome>.png ``` (tutto minuscolo)
#
## Formato voti (voti.csv)
```csv
numero, voti
10, 5.5, 2.5, 0, 4.0
```
Executable
+170
View File
@@ -0,0 +1,170 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #66b3ff 0%, #3a6ea5 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 60vw;
margin: 0 auto;
display: flex;
flex-direction: column;
gap: 20px;
align-items: center;
}
.sinistra {
width: 100%;
text-align: center;
}
.sinistra img {
max-width: 100%;
width: 300px;
height: auto;
border-radius: 15px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
border: 4px solid white;
margin-bottom: 20px;
transition: transform 0.3s ease;
}
.sinistra img:hover {
transform: scale(1.05);
}
.sinistra button {
position: fixed;
top: 20px;
left: 20px;
background: linear-gradient(135deg, #ff6700 0%, #66b3ff 100%);
color: white;
border: 1px solid rgba(0, 0, 0);
padding: 12px 30px;
border-radius: 25px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
box-shadow: 0 4px 15px rgba(102,179,255,0.4);
transition: all 0.3s ease;
}
.sinistra button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(102,179,255,0.6);
}
.destra {
width: 100%;
background: white;
padding: 40px;
border-radius: 15px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 15px;
align-content: start;
}
.destra h2 {
font-size: 36px;
color: #333;
margin-bottom: 15px;
border-bottom: 4px solid #3a6ea5;
padding-bottom: 15px;
grid-column: 1 / -1;
text-align: center;
}
.destra p {
font-size: 14px;
color: #555;
margin: 0;
padding: 15px;
background: #ebebeb;
border-radius: 8px;
border: 1px solid #c0c0c0;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
}
.destra p:last-child {
border-bottom: 1px solid #c0c0c0;
}
table {
width: 90%;
max-width: 900px;
margin: 30px auto;
border-collapse: collapse;
background: white;
border-radius: 15px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
overflow: hidden;
}
table th {
background: linear-gradient(135deg, #66b3ff 0%, #3a6ea5 100%);
color: white;
padding: 15px;
text-align: center;
font-weight: 600;
font-size: 14px;
}
table td {
padding: 15px;
text-align: center;
border-bottom: 1px solid #eee;
color: #333;
font-size: 14px;
}
table tr:hover {
background: #ebebeb;
}
/* Responsive */
@media (max-width: 768px) {
.container {
flex-direction: column;
gap: 20px;
}
.destra {
padding: 20px;
}
.destra h2 {
font-size: 28px;
}
.destra p {
font-size: 16px;
}
table {
width: 95%;
}
table th, table td {
padding: 12px 8px;
font-size: 13px;
}
}
h1 {
color: white;
text-align: center;
font-size: 32px;
text-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
}
Executable
+81
View File
@@ -0,0 +1,81 @@
<?php
require 'dati.php';
if (isset($_GET['giocatore'])) {
$numero = $_GET['giocatore'];
$title = $giocatori[$numero]['nome'] . ' ' . $giocatori[$numero]['cognome'];
$error = false;
} else {
$title = 'Errore';
$error = true;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo $title ?></title>
<link rel="stylesheet" href="giocatore.css">
</head>
<body>
<?php if ($error): ?>
<h1>Errore: Giocatore non trovato</h1>
<?php else: ?>
<!-- formato immagine: nome_cognome.png (tutto miuscolo) -->
<?php
$giocatore = $giocatori[$numero];
$valutazioni = $voti[$numero];
?>
<div class="container">
<div class="sinistra">
<img src="<?php echo '.\\img\\' . strtolower($giocatore['nome'] . '_' . ''.str_replace(" ", "_", $giocatore['cognome'])) . '.png'; ?>" alt="Foto di <?php echo $title; ?>">
<button onclick="history.back()">Torna indietro</button>
</div>
<div class="destra">
<!--
formato dati giocatore:
"test": {
"nome": "Test",
"cognome": "Player",
"soprannome": "Il Tester",
"ruolo": "Centrocampista",
"isDestro": true,
"partiteGiocate": 0,
"assist": 0,
"goal": 0,
"assenze": 1
}
formato voti:
"test": [voto1, voto2, voto3]
-->
<?php
echo "<h2>" . $numero . " " . $giocatore['nome'] . " " . $giocatore['cognome'];
echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MV: " . number_format(array_sum($valutazioni) / (count($valutazioni) - $giocatore['assenze']), decimals: 2) . "</h2>";
echo "<p>Soprannome: " . $giocatore['soprannome'] . "</p>";
echo "<p>Ruolo: " . $giocatore['ruolo'] . "</p>";
echo "<p>Piede: " . ($giocatore['isDestro'] ? 'Destro' : 'Sinistro') . "</p>";
echo "<p>Partite Giocate: " . $giocatore['partiteGiocate'] . "</p>";
echo "<p>Assist: " . $giocatore['assist'] . "</p>";
echo "<p>Goal: " . $giocatore['goal'] . "</p>";
?>
</div>
</div>
<table style="display: <?php echo empty($valutazioni) ? "none" : "block"; ?>;">
<?php
$riga1 = "<tr><th>Partita</th>";
$riga2 = "<tr><th>Voto</th>";
for ($i = 0; $i < count($valutazioni); $i++) {
$riga1 .= "<td>" . ($i + 1) . "</td>";
$voto = $valutazioni[$i] == 0 ? 'Assente' : $valutazioni[$i];
$riga2 .= "<td>" . $voto . "</td>";
}
$riga1 .= "</tr>";
$riga2 .= "</tr>";
echo $riga1;
echo $riga2;
?>
</table>
<?php endif; ?>
</body>
</html>
Executable
+211
View File
@@ -0,0 +1,211 @@
{
"2": {
"nome": "Adam",
"cognome": "Ben Ameur",
"soprannome": "",
"ruolo": "Difensore",
"isDestro": true,
"partiteGiocate": 1,
"assist": 0,
"goal": 0,
"assenze": 0
},
"3": {
"nome": "Samuele",
"cognome": "Bonanno",
"soprannome": "",
"ruolo": "Difensore",
"isDestro": false,
"partiteGiocate": 1,
"assist": 0,
"goal": 0,
"assenze": 0
},
"4": {
"nome": "Gabriele",
"cognome": "Borgonovo",
"soprannome": "",
"ruolo": "",
"isDestro": false,
"partiteGiocate": 1,
"assist": 0,
"goal": 0,
"assenze": 0
},
"5": {
"nome": "Diego",
"cognome": "Casiraghi",
"soprannome": "",
"ruolo": "",
"isDestro": true,
"partiteGiocate": 0,
"assist": 0,
"goal": 0,
"assenze": 0
},
"6": {
"nome": "Luca",
"cognome": "Celli",
"soprannome": "",
"ruolo": "Centrocampista",
"isDestro": true,
"partiteGiocate": 0,
"assist": 0,
"goal": 0,
"assenze": 0
},
"8": {
"nome": "Mattia",
"cognome": "Civita",
"soprannome": "isDisponibile",
"ruolo": "Centrocampista",
"isDestro": false,
"partiteGiocate": 1,
"assist": 0,
"goal": 0,
"assenze": 0
},
"9": {
"nome": "Cristian",
"cognome": "Redaelli",
"soprannome": "",
"ruolo": "Attaccante",
"isDestro": false,
"partiteGiocate": 1,
"assist": 0,
"goal": 0,
"assenze": 0
},
"10": {
"nome": "Daniele",
"cognome": "Costamagna",
"soprannome": "",
"ruolo": "",
"isDestro": true,
"partiteGiocate": 1,
"assist": 0,
"goal": 0,
"assenze": 0
},
"11": {
"nome": "Marco",
"cognome": "Ferlin",
"soprannome": "Epstein",
"ruolo": "Centrocampista",
"isDestro": true,
"partiteGiocate": 0,
"assist": 0,
"goal": 0,
"assenze": 0
},
"12": {
"nome": "Mattia",
"cognome": "Foglieni",
"soprannome": "",
"ruolo": "",
"isDestro": true,
"partiteGiocate": 1,
"assist": 0,
"goal": 0,
"assenze": 0
},
"13": {
"nome": "Alessandro",
"cognome": "Fusillo",
"soprannome": "",
"ruolo": "",
"isDestro": false,
"partiteGiocate": 0,
"assist": 0,
"goal": 0,
"assenze": 0
},
"14": {
"nome": "Filippo",
"cognome": "Gilardi",
"soprannome": "",
"ruolo": "Difensore",
"isDestro": true,
"partiteGiocate": 0,
"assist": 0,
"goal": 0,
"assenze": 0
},
"15": {
"nome": "Samuele",
"cognome": "Meroni",
"soprannome": "",
"ruolo": "Attaccante",
"isDestro": true,
"partiteGiocate": 1,
"assist": 0,
"goal": 0,
"assenze": 0
},
"16": {
"nome": "Mattia",
"cognome": "Nava",
"soprannome": "",
"ruolo": "Centrocampista",
"isDestro": true,
"partiteGiocate": 0,
"assist": 0,
"goal": 0,
"assenze": 0
},
"17": {
"nome": "Tommaso",
"cognome": "Riva",
"soprannome": "",
"ruolo": "Centrocampista",
"isDestro": true,
"partiteGiocate": 0,
"assist": 0,
"goal": 0,
"assenze": 0
},
"19": {
"nome": "Andrea",
"cognome": "Santarlasci",
"soprannome": "",
"ruolo": "Difensore",
"isDestro": true,
"partiteGiocate": 1,
"assist": 0,
"goal": 0,
"assenze": 0
},
"21": {
"nome": "Mattia",
"cognome": "Turiello",
"soprannome": "",
"ruolo": "",
"isDestro": false,
"partiteGiocate": 1,
"assist": 0,
"goal": 0,
"assenze": 0
},
"22": {
"nome": "Marco",
"cognome": "Varenna",
"soprannome": "",
"ruolo": "Portiere",
"isDestro": false,
"partiteGiocate": 1,
"assist": 0,
"goal": 0,
"assenze": 0
},
"test": {
"nome": "Test",
"cognome": "Player",
"soprannome": "Il Tester",
"ruolo": "Centrocampista",
"isDestro": true,
"partiteGiocate": 1,
"assist": 0,
"goal": 0,
"assenze": 1
}
}
+1
View File
@@ -0,0 +1 @@
numero;nome;cognome;soprannome;ruolo;isDestro;partiteGiocate;assist;goal
1 numero nome cognome soprannome ruolo isDestro partiteGiocate assist goal
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 831 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 740 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 589 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 820 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 763 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 840 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 849 KiB

Executable
+297
View File
@@ -0,0 +1,297 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #66b3ff 0%, #3a6ea5 100%);
min-height: 100vh;
padding: 20px;
}
h1 {
color: white;
text-align: center;
font-size: 32px;
text-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
margin-bottom: 20px;
}
.inizia {
font-size: 16px;
display: block;
margin: 20px auto 0 auto;
}
.container {
max-width: 90%;
margin: 0 auto;
display: flex;
justify-content: space-around;
gap: 30px;
align-items: flex-start;
}
/* Squadre più ampie, classifica più stretta */
.sinistra {
width: 60%;
background: white;
padding: 30px;
border-radius: 15px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
}
.destra {
width: 40%;
background: white;
padding: 30px;
border-radius: 15px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
}
.sinistra h2, .destra h2 {
font-size: 24px;
color: #333;
margin-bottom: 15px;
border-bottom: 4px solid #66b3ff;
padding-bottom: 15px;
text-align: center;
}
#listaSquadre {
margin: 0;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24px;
padding: 0;
align-items: stretch;
}
#listaSquadre > div {
background: linear-gradient(180deg, #ffffff 0%, #ebebeb 100%);
padding: 18px 22px;
border-radius: 12px;
border: 1px solid #c0c0c0;
box-shadow: 0 4px 15px rgba(58, 110, 165, 0.08);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 120px;
}
#listaSquadre > div:hover {
transform: translateY(-4px);
box-shadow: 0 8px 25px rgba(58, 110, 165, 0.12);
border-color: #66b3ff;
}
#listaSquadre h2 {
font-size: 16px;
color: #333;
margin-bottom: 12px;
text-align: center;
}
#listaSquadre ul {
list-style: none;
display: flex;
flex-direction: column;
gap: 8px;
}
#classificaGiocatori {
display: flex;
flex-direction: column;
gap: 10px;
counter-reset: rank-counter;
}
#classificaGiocatori li {
counter-increment: rank-counter;
display: flex;
align-items: center;
gap: 16px;
}
#classificaGiocatori li::before {
content: counter(rank-counter);
display: inline-flex;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
background: linear-gradient(135deg, #66b3ff 0%, #3a6ea5 100%);
color: white;
border-radius: 50%;
font-weight: 700;
font-size: 12px;
}
.giocatore {
cursor: pointer;
padding: 12px 14px;
border-radius: 8px;
transition: all 0.3s ease;
color: #333;
background: linear-gradient(180deg, #ffffff 0%, #ebebeb 100%);
border: 1px solid #c0c0c0;
font-size: 14px;
}
.giocatore:hover {
transform: translateX(4px);
}
#classificaGiocatori .giocatore {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 14px;
background: linear-gradient(180deg, #ffffff 0%, #ebebeb 100%);
border: 1px solid #c0c0c0;
margin-bottom: 4px;
border-radius: 8px;
}
#classificaGiocatori .giocatore span:first-child {
flex: 1;
}
button, .btn {
background: linear-gradient(135deg, #ff6700 0%, #66b3ff 100%);
color: white;
border: 1px solid rgba(0, 0, 0);
padding: 11px 24px;
border-radius: 20px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
box-shadow: 0 4px 15px rgba(102,179,255,0.25);
transition: all 0.3s ease;
display: inline-block;
}
button:hover, .btn:hover {
transform: translateY(-2px);
}
button:active, .btn:active {
transform: translateY(0);
}
summary {
cursor: pointer;
font-weight: 600;
color: #66b3ff;
padding: 8px 12px;
margin: 8px 0;
transition: all 0.3s ease;
}
summary:hover {
color: #3a6ea5;
transform: translateX(2px);
}
/* Responsive */
@media (max-width: 1024px) {
.container {
gap: 24px;
}
.sinistra {
width: calc(60% - 12px);
padding: 24px;
}
.destra {
width: calc(40% - 12px);
padding: 24px;
}
}
@media (max-width: 768px) {
.container {
flex-direction: column;
gap: 20px;
}
.sinistra, .destra {
width: 100%;
padding: 20px;
}
.sinistra h2, .destra h2 {
font-size: 20px;
}
#listaSquadre {
grid-template-columns: repeat(2, 1fr);
gap: 20px;
}
#listaSquadre > div {
min-width: 0;
padding: 16px;
min-height: 100px;
}
h1 {
font-size: 28px;
margin-bottom: 16px;
}
}
@media (max-width: 480px) {
body {
padding: 12px;
}
h1 {
font-size: 24px;
margin-bottom: 12px;
}
.container {
gap: 12px;
}
.sinistra, .destra {
padding: 16px;
}
.sinistra h2, .destra h2 {
font-size: 18px;
padding-bottom: 12px;
margin-bottom: 12px;
}
#listaSquadre {
grid-template-columns: 1fr;
gap: 12px;
}
#listaSquadre > div {
min-width: 0;
padding: 12px;
}
.giocatore {
padding: 10px 12px;
font-size: 13px;
}
button, .btn {
padding: 10px 16px;
font-size: 13px;
}
#classificaGiocatori li::before {
width: 26px;
height: 26px;
font-size: 11px;
}
}
Executable
+31
View File
@@ -0,0 +1,31 @@
console.log(squadre);
console.log(giocatori);
const listaSquadre = document.getElementById('listaSquadre');
const classificaGiocatori = document.getElementById('classificaGiocatori');
listaSquadre.innerHTML = '';
Object.keys(squadre).forEach((squadra) => {
let squadraCompleta = `<div><h2>${squadra}</h2><ul>`;
squadre[squadra].forEach((giocatore) => {
let player = giocatori[giocatore];
console.log(giocatore);
squadraCompleta += `<li class="giocatore" onclick="window.location='giocatore.php?giocatore=${giocatore}'">${giocatore} ${player.nome} ${player.cognome}</li>`;
});
squadraCompleta += `</ul></div>`;
listaSquadre.innerHTML += squadraCompleta;
});
function media(voti) {
let somma = 0;
for (let voto in voti) {
somma += parseFloat(voti[voto]);
}
return somma / voti.length;
};
let classifica = Object.keys(giocatori).sort((a, b) => {
return media(voti[a]) - media(voti[b]);
}).reverse();
classifica.forEach((giocatore) => {
let player = giocatori[giocatore];
classificaGiocatori.innerHTML += `<li class="giocatore" onclick="window.location='giocatore.php?giocatore=${giocatore}'"><span>${player.nome} ${player.cognome}</span><span>MV: ${media(voti[giocatore]).toFixed(2)}</span></li>`;
})
Executable
+29
View File
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fantacalcio 4°H</title>
<link rel="stylesheet" href="index.css">
<script src="index.js" defer></script>
<?php include 'dati.php'; ?>
</head>
<body>
<h1 class="titolo">Fantacalcio 4°H</h1>
<div class="container">
<div class="sinistra">
<h2 style="text-align: center;">Squadre <button onclick="window.location='./squadre.php';">Gestisci squadre</button></h2>
<div id="listaSquadre" style="margin: 0; display: flex; flex-direction: row; gap: 40px;">
<!-- Riempito da JS -->
</div>
<button onclick="window.location='./partita.php';" class="inizia">Inizia giornata</button>
</div>
<div class="destra">
<h2>Classifica giocatori</h2>
<ol id="classificaGiocatori">
<!-- Riempito da JS -->
</ol>
</div>
</div>
</body>
</html>
Executable
+53
View File
@@ -0,0 +1,53 @@
<?php
/**
* Detects the field delimiter (';' or ',') for a CSV file.
* It bases the detection on the character count in the header row.
*/
function detectSeparators(string $csvContent): array
{
$lines = preg_split('/\r\n|\n|\r/', trim($csvContent));
$header = $lines[0] ?? '';
$semicolonCount = substr_count($header, ';');
$commaCount = substr_count($header, ',');
// If comma count is higher, we assume comma is the delimiter.
// Otherwise, we default to semicolon, which is common in many European locales.
if ($commaCount > $semicolonCount) {
$delimiter = ',';
} else {
$delimiter = ';';
}
// The decimal separator is no longer detected here,
// as it will be handled on a per-value basis.
return [
'delimiter' => $delimiter
];
}
/**
* Recursively traverses an array and converts numeric strings to int or float.
* Non-numeric strings are left unchanged.
*
* @param array $array The array to process, passed by reference.
*/
function recursively_convert_numeric_strings(array &$array)
{
foreach ($array as &$value) {
if (is_array($value)) {
// If the value is an array, recurse into it
recursively_convert_numeric_strings($value);
} elseif (is_string($value) && is_numeric($value)) {
// If the value is a string and represents a number, convert it
// Check if it's an integer or a float
if ((float)$value == (int)$value) {
$value = (int)$value;
} else {
$value = (float)$value;
}
}
// If it's not a string, not numeric, or not an array, it's left as is.
}
}
Executable
+150
View File
@@ -0,0 +1,150 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #66b3ff 0%, #3a6ea5 100%);
min-height: 100vh;
padding: 20px;
color: #222;
}
header {
max-width: 89%;
margin: 0 auto 18px;
display: flex;
gap: 64px;
align-items: center;
}
header h1 {
color: white;
font-size: 30px;
text-shadow: 0 4px 6px rgba(0,0,0,0.25);
}
.partite {
max-width: 89%;
margin: 0 auto 18px;
display: flex;
gap: 16px;
}
button, .btn {
background: linear-gradient(135deg, #ff6700 0%, #66b3ff 100%);
color: white;
border: 1px solid rgba(0, 0, 0);
padding: 8px 14px;
border-radius: 18px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
box-shadow: 0 6px 18px rgba(102,179,255,0.18);
transition: all 0.3s ease;
}
button:hover, .btn:hover { transform: translateY(-2px); }
.container {
display: flex;
justify-content: space-around;
gap: 24px;
max-width: 90%;
margin: 0 auto;
align-items: flex-start;
}
.sinistra, .destra {
background: rgba(255,255,255,0.98);
padding: 24px;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0,0,0,0.12);
width: 48%;
}
.sinistra h2, .destra h2 {
font-size: 20px;
color: #333;
margin-bottom: 12px;
border-bottom: 4px solid #66b3ff;
padding-bottom: 12px;
text-align: center;
}
#elenco-sq1, #elenco-sq2 {
margin: 12px 0 0 0;
display: flex;
flex-direction: column;
gap: 10px;
}
#elenco-sq1 li, #elenco-sq2 li {
background: linear-gradient(180deg, #ffffff 0%, #f3f6fb 100%);
padding: 12px 14px;
border-radius: 10px;
border: 1px solid #d6dfe9;
box-shadow: 0 4px 12px rgba(58,110,165,0.04);
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
}
hr {
border: none;
height: 1px;
background: rgba(255,255,255,0.12);
margin: 18px 0;
}
input {
width: 60px;
padding: 1.3% 2.3%;
border: 1px solid #c0c0c0;
text-align: center;
font-size: 14px;
border-radius: 10px;
}
span {
background-color:#41b776;
padding: 1.3%;
border-radius: 10px;
padding-left: 2.3%;
padding-right: 2.3%;
}
.salvaVoti {
margin: 0 auto;
display: block;
margin-bottom: 16px;
}
/* Responsive */
@media (max-width: 900px) {
.container {
flex-direction: column;
align-items: stretch;
gap: 16px;
padding: 10px;
}
.sinistra, .destra {
width: 100%;
padding: 18px;
}
header {
padding: 0 10px;
}
}
@media (max-width: 480px) {
header h1 { font-size: 18px; }
button { padding: 8px 10px; font-size: 13px; }
.sinistra h2, .destra h2 { font-size: 18px; padding-bottom: 10px; }
#elenco-sq1 li, #elenco-sq2 li { padding: 10px; font-size: 14px; }
}
Executable
+97
View File
@@ -0,0 +1,97 @@
let numeroPartita = 1;
const SQUADRE_PARTITA = {
1: ['squadra1', 'squadra2'],
2: ['squadra1', 'squadra3'],
3: ['squadra2', 'squadra3']
}
function setPartita(n) {
numeroPartita = n;
let s1 = SQUADRE_PARTITA[n][0];
let s2 = SQUADRE_PARTITA[n][1]
document.getElementById('sq1').innerText = s1;
document.getElementById('sq2').innerText = s2;
riempi(s1, sq1);
riempi(s2, sq2);
}
const sq1 = document.getElementById('elenco-sq1');
const sq2 = document.getElementById('elenco-sq2');
function riempi(nome, lista) {
lista.innerHTML = '';
squadre[nome].forEach((n) => {
let li = document.createElement('li');
let giocatore = giocatori[n];
li.innerHTML = `${giocatore.nome} ${giocatore.cognome} | Assist: <input id='assist${n}' type='number' min='0' value='${giocatore.assist}'> | Goal: <input id='goal${n}' type='number' min='0' value='${giocatore.goal}'> | Voto: <span id='voto${n}'>6</span>`;
li.id = 'giocatore' + n;
lista.appendChild(li);
// Aggiungi event listener per aggiornare il voto quando assist o goal cambiano
document.getElementById(`assist${n}`).addEventListener('input', () => {
aggiornaVoto(n);
});
document.getElementById(`goal${n}`).addEventListener('input', () => {
aggiornaVoto(n);
});
});
}
function aggiornaVoto(n) {
let assist = parseInt(document.getElementById(`assist${n}`).value) || 0;
let goal = parseInt(document.getElementById(`goal${n}`).value) || 0;
let voto = 6 + (assist * 1) + (goal * 3);
if (voto>=6){
document.getElementById(`voto${n}`).style.backgroundColor = "#41b776";
} else {
document.getElementById(`voto${n}`).style.backgroundColor = "red";
}
document.getElementById(`voto${n}`).innerText = voto;
}
setPartita(1);
function salvaVoti() {
if (!confirm("Vuoi salvare i voti delle partite?")) return;
// Aggiorna assist e goal
Object.keys(giocatori).forEach(n => {
let assistInput = document.getElementById(`assist${n}`);
let goalInput = document.getElementById(`goal${n}`);
if (assistInput && goalInput) {
giocatori[n].assist = parseInt(assistInput.value) || 0;
giocatori[n].goal = parseInt(goalInput.value) || 0;
giocatori[n].partiteGiocate = (giocatori[n].partiteGiocate || 0) + 1;
}
});
// Aggiunge i voti
Object.keys(voti).forEach(n => {
let votoSpan = document.getElementById(`voto${n}`);
if (!votoSpan) return; // se non esiste lo span, salta
if (!Array.isArray(voti[n])) return; // se non è array, salta
let nuovoVoto = parseFloat(votoSpan.innerText);
if (isNaN(nuovoVoto)) return; // se non è numero, salta
voti[n].push(nuovoVoto);
});
fetch("salva_voti.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ voti, giocatori })
})
.then(res => res.json())
.then(data => console.log("Server risponde:", data))
.catch(err => console.error("Errore:", err));
}
function home(){
if (!confirm("Tutti i dati non salvati andranno persi. Vuoi tornare alla home?")) return;
window.location = './';
}
Executable
+39
View File
@@ -0,0 +1,39 @@
<?php
define('OGGI', date('d/m/Y'));
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Statistiche partita</title>
<link rel="stylesheet" href="partita.css">
<script src="partita.js" defer></script>
<?php require 'dati.php'; ?>
</head>
<body>
<header>
<h1>Partite del giorno: <?php echo OGGI; ?></h1>
<button onclick="home();">Home</button>
</header>
<div class="partite">
<button onclick="setPartita(1);">Partita 1</button>
<button onclick="setPartita(2);">Partita 2</button>
<button onclick="setPartita(3);">Partita 3</button>
</div>
<hr>
<main>
<button onclick="salvaVoti();" class="salvaVoti">Salva voti partita</button>
<div class="container">
<div class="sinistra">
<h2 id="sq1"></h2>
<ul id="elenco-sq1"></ul>
</div>
<div class="destra">
<h2 id="sq2"></h2>
<ul id="elenco-sq2"></ul>
</div>
</div>
</main>
</body>
</html>
Executable
+1
View File
@@ -0,0 +1 @@
{}
+42
View File
@@ -0,0 +1,42 @@
<?php
header('Content-Type: application/json');
require_once 'logic.php'; // Include the logic file
$response = [
'success' => false,
'message' => 'Errore sconosciuto.'
];
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
$response['message'] = 'Metodo non valido.';
echo json_encode($response);
exit;
}
// Legge il corpo della richiesta JSON inviato da JavaScript
$jsonPayload = file_get_contents('php://input');
$data = json_decode($jsonPayload, true);
if ($data === null) {
$response['message'] = 'Dati JSON non validi.';
echo json_encode($response);
exit;
}
// Applica la conversione dinamica delle stringhe numeriche
recursively_convert_numeric_strings($data);
// Formatta il JSON in modo leggibile prima di salvarlo
$prettyJson = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
// Salva i dati nel file squadre.json
$destinationFile = 'squadre.json';
if (file_put_contents($destinationFile, $prettyJson) !== false) {
$response['success'] = true;
$response['message'] = 'Squadre salvate con successo!';
} else {
$response['message'] = 'Errore durante il salvataggio del file squadre.json.';
}
echo json_encode($response);
Executable
+65
View File
@@ -0,0 +1,65 @@
<?php
header('Content-Type: application/json');
// Percorsi dei file JSON
$votiFile = 'voti.json';
$giocatoriFile = 'giocatori.json';
$response = [
'success' => false,
'message' => 'Errore sconosciuto.'
];
// Controlla che sia POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
$response['message'] = 'Metodo non valido.';
echo json_encode($response);
exit;
}
// Legge il corpo della richiesta JSON
$jsonPayload = file_get_contents('php://input');
$data = json_decode($jsonPayload, true);
if ($data === null) {
$response['message'] = 'Dati JSON non validi.';
echo json_encode($response);
exit;
}
// Funzione per convertire stringhe numeriche in numeri (come nel tuo salva_squadre)
function recursively_convert_numeric_strings(&$arr) {
foreach ($arr as $key => &$value) {
if (is_array($value)) {
recursively_convert_numeric_strings($value);
} elseif (is_string($value) && is_numeric($value)) {
$value = $value + 0;
}
}
}
recursively_convert_numeric_strings($data);
// Salva voti
if (isset($data['voti'])) {
$prettyVoti = json_encode($data['voti'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
if (file_put_contents($votiFile, $prettyVoti) === false) {
$response['message'] = 'Errore durante il salvataggio di voti.json';
echo json_encode($response);
exit;
}
}
// Salva giocatori
if (isset($data['giocatori'])) {
$prettyGiocatori = json_encode($data['giocatori'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
if (file_put_contents($giocatoriFile, $prettyGiocatori) === false) {
$response['message'] = 'Errore durante il salvataggio di giocatori.json';
echo json_encode($response);
exit;
}
}
$response['success'] = true;
$response['message'] = 'Voti e giocatori salvati con successo!';
echo json_encode($response);
?>
Executable
+119
View File
@@ -0,0 +1,119 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #66b3ff 0%, #3a6ea5 100%);
min-height: 100vh;
padding: 20px;
color: #222;
}
.container {
display: flex;
flex-direction: row;
justify-content: space-around;
gap: 24px;
max-width: 1200px;
margin: 0 auto;
align-items: flex-start;
}
.squadre, .giocatori {
background: rgba(255,255,255,0.98);
padding: 20px;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0,0,0,0.12);
}
.squadre {
width: 360px;
}
.giocatori {
flex: 1;
max-width: 680px;
}
h1 {
color: #333;
font-size: 22px;
margin-bottom: 12px;
text-align: left;
}
button, .btn {
background: linear-gradient(135deg, #ff6700 0%, #66b3ff 100%);
color: white;
border: 1px solid rgba(0, 0, 0);
padding: 10px 16px;
border-radius: 20px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
box-shadow: 0 6px 18px rgba(102,179,255,0.18);
margin: 6px 6px 12px 0;
display: inline-block;
transition: all 0.3s ease;
}
button:hover, .btn:hover {
transform: translateY(-2px);
}
select#elencoSquadre {
width: 100%;
padding: 10px;
border-radius: 8px;
border: 1px solid #c0c0c0;
margin-bottom: 12px;
}
#giocatoriSquadra, #elencoGiocatori {
display: flex;
flex-direction: column;
gap: 8px;
}
.giocatore {
cursor: pointer;
padding: 12px 14px;
border-radius: 8px;
transition: all 0.3s ease;
color: #333;
background: linear-gradient(180deg, #ffffff 0%, #ebebeb 100%);
border: 1px solid #c0c0c0;
font-size: 14px;
}
.giocatore:hover {
background: linear-gradient(135deg, rgba(58,110,165,0.06) 0%, rgba(102,179,255,0.04) 100%);
border-color: #3a6ea5;
transform: translateX(4px);
box-shadow: 0 2px 8px rgba(58,110,165,0.08);
}
a > button {
padding: 8px 14px;
}
/* Responsive */
@media (max-width: 900px) {
.container {
flex-direction: column;
align-items: stretch;
gap: 16px;
padding: 10px;
}
.squadre {
width: 100%;
}
.giocatori {
width: 100%;
}
}
Executable
+119
View File
@@ -0,0 +1,119 @@
Object.keys(giocatori).forEach(numero => {
let giocatore = giocatori[numero];
document.getElementById('elencoGiocatori').innerHTML += `<div class="giocatore" onclick="window.location='giocatore.php?giocatore=${numero}'">${numero} ${giocatore.nome} ${giocatore.cognome}</div>`;
});
Object.keys(squadre).forEach(squadra => {
document.getElementById('elencoSquadre').innerHTML += `<option value="${squadra}">${squadra}</option>`;
});
elencoSquadre.addEventListener('change', (event) => {
let squadra = event.target.value;
giocatoriSquadra.innerHTML = '';
squadre[squadra].forEach(numero => {
let giocatore = giocatori[numero];
giocatoriSquadra.innerHTML += `<div class="giocatore" onclick="window.location='giocatore.php?giocatore=${numero}'">${numero} ${giocatore.nome} ${giocatore.cognome}</div>`;
});
});
function generaSquadre() {
// Chiedi conferma prima di procedere
if (!confirm('Sei sicuro di voler generare nuove squadre? Le squadre attuali verranno sovrascritte.')) {
return;
}
// Crea un nuovo oggetto squadre per non modificare quello globale prima del salvataggio
const giocatoriForti = shuffleArray([15, 17, 19]); // Capitani
tuttiGiocatori = shuffleArray(Object.keys(giocatori).filter(giocatore => !giocatoriForti.includes(parseInt(giocatore))));
const nuoveSquadre = {
"squadra1": [giocatoriForti[0], ...tuttiGiocatori.slice(0, 5)],
"squadra2": [giocatoriForti[1], ...tuttiGiocatori.slice(5, 10)],
"squadra3": [giocatoriForti[2], ...tuttiGiocatori.slice(10, 15)]
};
// Invia i dati al server per il salvataggio
fetch('salva_squadre.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(nuoveSquadre)
})
.then(response => response.json())
.then(data => {
alert(data.message); // Mostra il messaggio di successo o errore
if (data.success) {
// Ricarica la pagina per visualizzare le nuove squadre salvate
window.location.reload();
}
})
.catch(error => {
console.error('Errore durante il salvataggio delle squadre:', error);
alert('Si è verificato un errore di rete durante il salvataggio.');
});
}
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
// Logica di Import
const fileInput = document.getElementById('file-input');
let importType = '';
document.getElementById('import-giocatori').addEventListener('click', () => {
importType = 'giocatori';
fileInput.click();
});
document.getElementById('import-voti').addEventListener('click', () => {
importType = 'voti';
fileInput.click();
});
fileInput.addEventListener('change', (event) => {
const file = event.target.files[0];
if (!file) {
return;
}
// Validazione del nome del file
let expectedFileName = '';
if (importType === 'giocatori') {
expectedFileName = 'giocatori.csv';
} else if (importType === 'voti') {
expectedFileName = 'voti.csv';
}
if (!file.name.toLowerCase().endsWith(expectedFileName)) {
alert(`Per favore, seleziona un file chiamato "${expectedFileName}".`);
event.target.value = ''; // Reset file input
return;
}
const formData = new FormData();
formData.append('csv-file', file);
formData.append('type', importType);
fetch('upload.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
alert(data.message);
if (data.success) {
window.location.reload();
}
})
.catch(error => {
console.error('Errore:', error);
alert('Si è verificato un errore durante il caricamento.');
});
// Reset file input
event.target.value = '';
});
Executable
+26
View File
@@ -0,0 +1,26 @@
{
"squadra1": [
17,
13,
5,
6,
8,
14
],
"squadra2": [
19,
22,
9,
21,
4,
2
],
"squadra3": [
15,
16,
"test",
11,
12,
3
]
}
Executable
+40
View File
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Squadre</title>
<link rel="stylesheet" href="squadre.css">
<script src="squadre.js" defer></script>
<?php require 'dati.php'; ?>
</head>
<body>
<div class="container">
<div class="squadre">
<button id="import-giocatori">Importa giocatori</button>
<button id="import-voti">Importa voti</button><br>
<a href="download.php?type=giocatori"><button>Esporta giocatori</button></a>
<a href="download.php?type=voti"><button>Esporta voti</button></a>
<input type="file" id="file-input" style="display: none;" accept=".csv" />
<h1>Lista squadre</h1>
<select name="elencoSquadre" id="elencoSquadre">
<option value="">Seleziona una squadra</option>
<!-- Squadre inserite con JS -->
</select>
<button onclick="generaSquadre();">Genera squadre</button>
<button onclick="window.location='./';">Home</button>
<br>
<h1>Giocatori della squadra</h1>
<div id="giocatoriSquadra">
<!-- Riempito da JS -->
</div>
</div>
<div class="giocatori">
<h1>Lista giocatori</h1>
<div id="elencoGiocatori">
<!-- Lista giocatori inserita da JS -->
</div>
</div>
</div>
</body>
</html>
Executable
+57
View File
@@ -0,0 +1,57 @@
<?php
header('Content-Type: application/json');
require 'conversioni.php';
$response = [
'success' => false,
'message' => 'Si è verificato un errore sconosciuto.'
];
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
$response['message'] = 'Metodo di richiesta non valido.';
echo json_encode($response);
exit;
}
if (!isset($_POST['type']) || !isset($_FILES['csv-file'])) {
$response['message'] = 'Dati mancanti nella richiesta.';
echo json_encode($response);
exit;
}
if ($_FILES['csv-file']['error'] !== UPLOAD_ERR_OK) {
$response['message'] = 'Errore durante il caricamento del file. Codice: ' . $_FILES['csv-file']['error'];
echo json_encode($response);
exit;
}
$type = $_POST['type'];
$csvContent = file_get_contents($_FILES['csv-file']['tmp_name']);
$jsonResult = false;
$destinationFile = '';
if ($type === 'giocatori') {
$jsonResult = importaGiocatori($csvContent);
$destinationFile = 'giocatori.json';
$response['message'] = 'Giocatori importati con successo!';
} elseif ($type === 'voti') {
$jsonResult = importaVoti($csvContent);
$destinationFile = 'voti.json';
$response['message'] = 'Voti importati con successo!';
} else {
$response['message'] = 'Tipo di importazione non valido.';
echo json_encode($response);
exit;
}
if ($jsonResult === false) {
$response['message'] = 'Errore durante la conversione del file CSV.';
} else {
if (file_put_contents($destinationFile, $jsonResult) !== false) {
$response['success'] = true;
} else {
$response['message'] = 'Errore durante il salvataggio del file JSON.';
}
}
echo json_encode($response);
Executable
+110
View File
@@ -0,0 +1,110 @@
{
"2": [
5.5,
4.5,
7,
6
],
"3": [
9.5,
2.5,
5,
6
],
"4": [
6,
4,
7.5,
6
],
"5": [
3.5,
7.5,
9.5
],
"6": [
8.5,
10,
2.5
],
"8": [
6.5,
7,
7.5,
6
],
"9": [
8,
4.5,
9.5,
6
],
"10": [
7,
4,
5,
6
],
"11": [
6,
8,
2
],
"12": [
6,
9.5,
4.5,
6
],
"13": [
3.5,
2,
9
],
"14": [
4,
7,
4.5
],
"15": [
10,
4,
9,
6
],
"16": [
8,
7.5,
9
],
"17": [
2.5,
9.5,
6
],
"19": [
2,
2.5,
3,
6
],
"21": [
9.5,
4,
9,
6
],
"22": [
8,
9.5,
4,
6
],
"test": [
5.5,
2.5,
0,
4,
6
]
}
+1
View File
@@ -0,0 +1 @@
numero;voti
1 numero voti