59 lines
3.3 KiB
Python
59 lines
3.3 KiB
Python
from fastapi import APIRouter, Depends, HTTPException
|
|
from fastapi.responses import HTMLResponse
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select
|
|
import json
|
|
from app.database import get_db
|
|
from app.models.scan import Scan
|
|
from app.models.product import Product
|
|
|
|
router = APIRouter(prefix="/api", tags=["share"])
|
|
|
|
@router.get("/scan/{scan_id}/share", response_class=HTMLResponse)
|
|
async def share_scan(scan_id: int, db: AsyncSession = Depends(get_db)):
|
|
res = await db.execute(select(Scan).where(Scan.id == scan_id))
|
|
scan = res.scalar_one_or_none()
|
|
if not scan:
|
|
raise HTTPException(status_code=404, detail="Scan não encontrado")
|
|
|
|
analysis = json.loads(scan.analysis_json or '{}')
|
|
score = scan.score or 0
|
|
color = '#10B981' if score >= 70 else '#EAB308' if score >= 50 else '#F97316' if score >= 30 else '#EF4444'
|
|
label = 'Excelente' if score >= 90 else 'Bom' if score >= 70 else 'Regular' if score >= 50 else 'Ruim' if score >= 30 else 'Péssimo'
|
|
|
|
positives = ''.join(f'<li style="color:#10B981">✅ {p}</li>' for p in analysis.get("positives", []))
|
|
negatives = ''.join(f'<li style="color:#EF4444">❌ {n}</li>' for n in analysis.get("negatives", []))
|
|
|
|
html = f"""<!DOCTYPE html>
|
|
<html><head>
|
|
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<meta property="og:title" content="ALETHEIA: {scan.product_name} - Score {score}/100">
|
|
<meta property="og:description" content="{scan.summary or ''}">
|
|
<title>ALETHEIA - {scan.product_name}</title>
|
|
<style>
|
|
*{{margin:0;padding:0;box-sizing:border-box}}
|
|
body{{background:#0A0E17;color:white;font-family:Inter,system-ui,sans-serif;padding:20px;max-width:500px;margin:0 auto}}
|
|
.card{{background:#111827;border-radius:20px;padding:24px;margin-bottom:16px;border:1px solid rgba(255,255,255,0.05)}}
|
|
.score{{width:120px;height:120px;border-radius:50%;border:6px solid {color};display:flex;align-items:center;justify-content:center;margin:0 auto 16px;flex-direction:column}}
|
|
.score span{{font-size:36px;font-weight:900;color:{color}}}
|
|
.score small{{font-size:12px;color:#9CA3AF}}
|
|
h1{{font-size:20px;text-align:center;margin-bottom:4px}}
|
|
h2{{font-size:14px;color:#9CA3AF;text-align:center;margin-bottom:16px}}
|
|
.label{{display:inline-block;padding:4px 16px;border-radius:20px;font-weight:700;font-size:14px;color:{color};background:{color}15;text-align:center;margin:0 auto 20px;display:block;width:fit-content}}
|
|
ul{{list-style:none;padding:0}}li{{font-size:13px;margin-bottom:6px;color:#D1D5DB}}
|
|
.logo{{text-align:center;margin-top:24px;font-size:12px;color:#6B7280}}
|
|
.logo b{{background:linear-gradient(135deg,#00D4AA,#7C3AED);-webkit-background-clip:text;-webkit-text-fill-color:transparent}}
|
|
</style></head><body>
|
|
<div class="card">
|
|
<div class="score"><span>{score}</span><small>/100</small></div>
|
|
<h1>{scan.product_name or 'Produto'}</h1>
|
|
<h2>{scan.brand or ''}</h2>
|
|
<div class="label">{label}</div>
|
|
<p style="font-size:13px;color:#D1D5DB;text-align:center;margin-bottom:16px">{scan.summary or ''}</p>
|
|
{f'<ul>{positives}</ul>' if positives else ''}
|
|
{f'<ul style="margin-top:12px">{negatives}</ul>' if negatives else ''}
|
|
</div>
|
|
<div class="logo">Analisado por <b>ALETHEIA</b> — A verdade sobre o que você come</div>
|
|
</body></html>"""
|
|
return HTMLResponse(content=html)
|