Files
gkachele-saas/demo/routes/customizer.py
2026-02-12 19:05:58 +01:00

135 lines
4.7 KiB
Python

from flask import Blueprint, render_template, request, jsonify, session, current_app
import sqlite3
import json
import time
import os
from config import MAIN_DB, THEMES_DIR
from utils.theme_engine import scan_available_themes, get_theme_config, render_gkachele_template
from utils.auth_decorators import login_required
customizer_bp = Blueprint('customizer', __name__)
@customizer_bp.route('/api/themes')
def list_themes():
"""Listar todos los templates disponibles filtrados por plan"""
from utils.theme_engine import get_themes_by_rubro
rubro = request.args.get('rubro', None)
user_id = session.get('user_id')
user_plan = 'base'
if user_id:
conn = sqlite3.connect(MAIN_DB)
c = conn.cursor()
c.execute('SELECT plan FROM users WHERE id = ?', (user_id,))
res = c.fetchone()
conn.close()
if res: user_plan = res[0]
themes = get_themes_by_rubro(rubro, user_plan) if rubro else scan_available_themes()
return jsonify({'success': True, 'themes': themes, 'total': len(themes)})
@customizer_bp.route('/customizer/<int:site_id>')
def customizer_view(site_id):
"""Customizer: Sidebar + Preview"""
conn = sqlite3.connect(MAIN_DB)
c = conn.cursor()
c.execute('SELECT user_id, slug, theme, content_json FROM sites WHERE id = ?', (site_id,))
site = c.fetchone()
conn.close()
if not site:
return "Sitio no encontrado", 404
if 'user_id' in session and site[0] != session['user_id']:
return "No autorizado", 403
content = json.loads(site[3]) if site[3] else {}
theme = site[2]
theme_template = None
theme_path = os.path.join(THEMES_DIR, theme, 'template.html')
if os.path.exists(theme_path):
with open(theme_path, 'r', encoding='utf-8') as f:
theme_template = f.read()
theme_config = get_theme_config(theme)
# Obtener plan del usuario para filtrar templates
c = conn.cursor()
c.execute('SELECT plan, rubro FROM users WHERE id = ?', (site[0],))
user_data = c.fetchone()
user_plan = user_data[0] if user_data else 'base'
user_rubro = user_data[1] if user_data else 'restaurante'
from utils.theme_engine import get_themes_by_rubro
available_themes = get_themes_by_rubro(user_rubro, user_plan)
return render_template('customizer.html',
site_id=site_id,
slug=site[1],
theme=theme,
content=content,
theme_template=theme_template,
theme_config=theme_config,
available_themes=available_themes,
user_plan=user_plan)
@customizer_bp.route('/api/customizer/save', methods=['POST'])
def save_customizer():
data = request.get_json()
site_id = data.get('site_id')
content = data.get('content')
new_theme = data.get('theme')
conn = sqlite3.connect(MAIN_DB)
c = conn.cursor()
if new_theme:
c.execute('UPDATE sites SET theme = ? WHERE id = ?', (new_theme, site_id))
c.execute('UPDATE sites SET content_json = ? WHERE id = ?', (json.dumps(content), site_id))
conn.commit()
conn.close()
return jsonify({'success': True})
@customizer_bp.route('/api/customizer/add-block', methods=['POST'])
def add_block():
data = request.get_json()
site_id = data.get('site_id')
block_type = data.get('block_type')
conn = sqlite3.connect(MAIN_DB)
c = conn.cursor()
c.execute('SELECT content_json FROM sites WHERE id = ?', (site_id,))
result = c.fetchone()
content = json.loads(result[0]) if result[0] else {}
if 'blocks' not in content: content['blocks'] = []
new_block = {
'id': f'block_{int(time.time() * 1000)}',
'type': block_type,
'content': data.get('content', {}),
'order': len(content['blocks'])
}
content['blocks'].append(new_block)
c.execute('UPDATE sites SET content_json = ? WHERE id = ?', (json.dumps(content), site_id))
conn.commit()
conn.close()
return jsonify({'success': True, 'block': new_block})
@customizer_bp.route('/api/customizer/preview-frame/<int:site_id>')
def preview_frame(site_id):
conn = sqlite3.connect(MAIN_DB)
c = conn.cursor()
c.execute('SELECT theme, content_json, user_id FROM sites WHERE id = ?', (site_id,))
site = c.fetchone()
conn.close()
if not site: return "Sitio no encontrado", 404
try:
return render_gkachele_template(site[0], json.loads(site[1]), site_id, site[2])
except Exception as e:
return f"Error renderizando preview: {e}", 500