add initial template

This commit is contained in:
Alessio Prato 2025-08-01 23:41:32 +02:00
parent 4ed1e88dc2
commit 45a93e5a23
13 changed files with 457 additions and 13 deletions

58
.gitignore vendored
View file

@ -1,2 +1,56 @@
.idea
backend/.env
# Virtual environment
venv/
env/
.venv/
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# OS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Logs
*.log
# Environment variables
.env
.env.local
.env.*.local
# Node modules (se installi http-server globalmente)
node_modules/
# Docker
.dockerignore

View file

@ -1,2 +1,18 @@
# Team NPT
# Template per Hackathon
## 🚀 Avvio Rapido
```bash
# Avvia tutto con un comando
./start.sh
#Comandi utili per vedere dati db su mongosh
mongosh
show dbs
use simple_db
show collections
db.items.find()
```
Il frontend sarà disponibile su http://localhost:3000
Il backend sarà hostato localmente su http://localhost:8000

View file

97
app/index.html Normal file
View file

@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Template APP</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 50px auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 {
color: #333;
text-align: center;
margin-bottom: 30px;
}
.button-group {
display: flex;
gap: 20px;
justify-content: center;
margin-bottom: 30px;
}
button {
padding: 15px 30px;
font-size: 16px;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}
.btn-get {
background-color: #4CAF50;
color: white;
}
.btn-get:hover {
background-color: #45a049;
}
.btn-post {
background-color: #2196F3;
color: white;
}
.btn-post:hover {
background-color: #1976D2;
}
.result {
background-color: #f9f9f9;
border: 1px solid #ddd;
border-radius: 5px;
padding: 20px;
margin-top: 20px;
white-space: pre-wrap;
font-family: monospace;
max-height: 400px;
overflow-y: auto;
}
.status {
padding: 10px;
border-radius: 5px;
margin-bottom: 10px;
}
.success {
background-color: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.error {
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
</style>
</head>
<body>
<div class="container">
<h1>🚀 Simple Fullstack App</h1>
<div class="button-group">
<button class="btn-get" onclick="getData()">📥 GET Data</button>
<button class="btn-post" onclick="createData()">📤 POST Data</button>
</div>
<div id="status"></div>
<div id="result" class="result" style="display: none;"></div>
</div>
<script src="script.js"></script>
</body>
</html>

76
app/script.js Normal file
View file

@ -0,0 +1,76 @@
const API_BASE_URL = 'http://localhost:8000';
// Funzione per mostrare messaggi di status
function showStatus(message, isSuccess = true) {
const statusDiv = document.getElementById('status');
statusDiv.innerHTML = `<div class="status ${isSuccess ? 'success' : 'error'}">${message}</div>`;
}
// Funzione per mostrare i risultati
function showResult(data) {
const resultDiv = document.getElementById('result');
resultDiv.style.display = 'block';
resultDiv.textContent = JSON.stringify(data, null, 2);
}
// GET: Ottiene dati dal database
async function getData() {
try {
console.log('📥 Richiesta GET in corso...');
showStatus('📥 Richiesta GET in corso...', true);
const response = await fetch(`${API_BASE_URL}/api/data`);
const data = await response.json();
if (response.ok) {
showStatus('✅ Dati ottenuti con successo!', true);
showResult(data);
} else {
showStatus(`❌ Errore: ${data.detail || 'Errore sconosciuto'}`, false);
}
} catch (error) {
console.error('Errore GET:', error);
showStatus(`❌ Errore di connessione: ${error.message}`, false);
}
}
// POST: Inserisce dati nel database
async function createData() {
try {
console.log('📤 Richiesta POST in corso...');
showStatus('📤 Richiesta POST in corso...', true);
const response = await fetch(`${API_BASE_URL}/api/data`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
});
const data = await response.json();
if (response.ok) {
showStatus('✅ Dato inserito con successo!', true);
showResult(data);
} else {
showStatus(`❌ Errore: ${data.detail || 'Errore sconosciuto'}`, false);
}
} catch (error) {
console.error('Errore POST:', error);
showStatus(`❌ Errore di connessione: ${error.message}`, false);
}
}
// Test di connessione all'avvio
window.addEventListener('load', async () => {
try {
const response = await fetch(`${API_BASE_URL}/`);
if (response.ok) {
console.log('✅ Backend connesso!');
} else {
console.log('❌ Backend non raggiungibile');
}
} catch (error) {
console.log('❌ Backend non raggiungibile:', error.message);
}
});

View file

@ -1,3 +0,0 @@
# ENV
- MONGO_INITDB_ROOT_USERNAME=
- MONGO_INITDB_ROOT_PASSWORD=

View file

View file

View file

@ -1,15 +1,30 @@
version: '3.8'
services:
mongodb:
image: mongo:8.0.0
container_name: mongodb
restart: unless-stopped
image: mongo:7.0
container_name: simple_mongodb
ports:
- "27017:27017"
environment:
- MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME}
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: password
volumes:
- mongo-data:/data/db
- mongodb_data:/data/db
restart: unless-stopped
mongo-express:
image: mongo-express:latest
container_name: mongo_express
ports:
- "8081:8081"
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: admin
ME_CONFIG_MONGODB_ADMINPASSWORD: password
ME_CONFIG_MONGODB_URL: mongodb://admin:password@mongodb:27017/
depends_on:
- mongodb
restart: unless-stopped
volumes:
mongo-data:
mongodb_data:

22
backend/main.py Normal file
View file

@ -0,0 +1,22 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from routes import router
app = FastAPI(title="Simple Fullstack API")
# CORS per permettere richieste dal frontend
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Includi le route
app.include_router(router)
if __name__ == "__main__":
import uvicorn
print("🚀 Avvio server FastAPI...")
uvicorn.run(app, host="0.0.0.0", port=8000)

View file

@ -0,0 +1,4 @@
fastapi==0.104.1
uvicorn[standard]==0.24.0
pymongo==4.6.0
python-multipart==0.0.6

50
backend/routes.py Normal file
View file

@ -0,0 +1,50 @@
from fastapi import APIRouter, HTTPException
from pymongo import MongoClient
from datetime import datetime
# Router per le API
router = APIRouter()
# Connessione MongoDB
client = MongoClient("mongodb://localhost:27017/")
db = client["simple_db"]
collection = db["items"]
@router.get("/")
def read_root():
"""Root endpoint per test connessione"""
return {"message": "Simple Fullstack API is running!"}
@router.get("/api/data")
def get_data():
"""GET: Ottiene il primo documento dal database"""
try:
# Trova il primo documento disponibile
document = collection.find_one()
if document:
# Converti ObjectId in stringa per JSON serialization
document["_id"] = str(document["_id"])
return {"success": True, "data": document}
else:
return {"success": False, "message": "Nessun dato trovato nel database"}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Errore database: {str(e)}")
@router.post("/api/data")
def create_data():
"""POST: Inserisce un dato hardcoded nel database"""
try:
# Dato hardcoded da inserire
new_item = {
"name": "Item di esempio",
"description": "Questo è un item creato tramite API",
"timestamp": datetime.now().isoformat(),
"value": 42
}
result = collection.insert_one(new_item)
new_item["_id"] = str(result.inserted_id)
return {"success": True, "message": "Dato inserito con successo", "data": new_item}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Errore inserimento: {str(e)}")

113
start.sh Executable file
View file

@ -0,0 +1,113 @@
#!/bin/bash
echo "🚀 Avvio Simple Fullstack App..."
# Colori per output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Funzione per stampare messaggi colorati
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
# Controlla se Python3 è installato
if ! command -v python3 &> /dev/null; then
echo "❌ Python3 non trovato. Installa Python3 prima di continuare."
exit 1
fi
# Controlla se Docker è installato
if ! command -v docker &> /dev/null; then
echo "❌ Docker non trovato. Installa Docker prima di continuare."
exit 1
fi
# Controlla se http-server è installato
if ! command -v http-server &> /dev/null; then
print_warning "http-server non trovato. Installando..."
npm install -g http-server
fi
# Crea virtual environment se non esiste
if [ ! -d "venv" ]; then
print_status "Creazione virtual environment..."
python3 -m venv venv
print_success "Virtual environment creato!"
else
print_status "Virtual environment già esistente"
fi
# Attiva virtual environment
print_status "Attivazione virtual environment..."
source venv/bin/activate
# Installa dipendenze
print_status "Installazione dipendenze Python..."
pip install -r backend/requirements.txt
print_success "Dipendenze installate!"
# Avvia MongoDB con Docker
print_status "Avvio MongoDB con Docker..."
cd backend
docker-compose up -d
cd ..
# Aspetta che MongoDB sia pronto
print_status "Attesa MongoDB..."
sleep 5
# Avvia backend in background
print_status "Avvio backend FastAPI..."
cd backend
python main.py &
BACKEND_PID=$!
cd ..
# Aspetta che il backend sia pronto
print_status "Attesa backend..."
sleep 3
# Avvia frontend
print_status "Avvio frontend..."
cd app
http-server -p 3000 -o &
FRONTEND_PID=$!
cd ..
print_success "🎉 Tutto avviato!"
echo ""
echo "📱 Frontend: http://localhost:3000"
echo "🔧 Backend API: http://localhost:8000"
echo "🗄️ MongoDB: localhost:27017"
echo ""
echo "💡 Premi Ctrl+C per fermare tutto"
# Funzione per cleanup
cleanup() {
echo ""
print_status "Fermando servizi..."
kill $BACKEND_PID 2>/dev/null
kill $FRONTEND_PID 2>/dev/null
cd backend
docker-compose down
cd ..
print_success "Servizi fermati!"
exit 0
}
# Intercetta Ctrl+C
trap cleanup SIGINT
# Mantieni lo script in esecuzione
wait