De las ~508 líneas de partials/my-account.html, solo la parte superior es dinámica
(datos de cuenta, estado, puntos, token, personajes); el resto son paneles de
navegación estáticos (enlaces), que se quedan en Django.
- API: account_me_api -> /api/account/me/ (protegido por sesión, 401 si no hay):
user_info, account_status, dp/vp, créditos Battlepay, token de seguridad y
personajes. Reutiliza get_account_characters/get_account_status/formatear_fecha.
Resiliente si acore no está disponible.
- React: AccountDashboard.tsx (fieldsets de datos + estado con contador de baneo en
vivo + rejilla de personajes). Entry my_account.
- partials/my-account.html: los 2 fieldsets + la rejilla de personajes + el script
del contador se sustituyen por #account-dashboard-app; los paneles de utilidades
e historiales siguen en Django.
Verificado: check OK, /api/account/me/ 401 sin sesión, my-account redirige a login.
(El render con datos reales requiere sesión + BD AzerothCore.)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El selector de cuenta de juego (bnet con varias) pasa a isla React y la selección
se hace vía GET (a petición), no POST:
- Nuevo endpoint GET /api/account/select/?account_id=<id> (account_select_api):
idempotente y solo permite elegir cuentas ligadas a la bnet en sesión; fija la
cuenta en sesión y devuelve {success, redirect}. 401 si no hay sesión bnet.
- select_account_view: se elimina el manejo de POST (queda solo la lógica GET:
redirect si no hay bnet, autoseleccionar si hay una, render si hay varias).
- SelectAccount.tsx lee las cuentas embebidas con json_script y, al pulsar, hace
fetch GET y redirige. Nueva entry 'select_account'.
- select_account.html: el <form> POST se sustituye por la isla + json_script.
Verificado: check OK, endpoint 401 sin sesión, /select-account/ redirige a login.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Segunda isla de la home: la tabla de estado (nombre, online, login, hora,
dirección) pasa de plantilla Django a componente React.
- API: home_status_api -> /api/home/status/ (server_name, address, expansion,
online_characters, status). Reutiliza check_server_status y
get_online_characters_count de views/pages.
- React: ServerStatus.tsx (fetch + reloj en vivo con setInterval, mismas clases
CSS). El entry home.tsx ahora monta dos islas: #home-news-app y #home-status-app.
- partials/noticias.html: la <table> de estado se sustituye por el contenedor.
Verificado: check OK, ambos endpoints 200, la home monta las dos islas.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Arquitectura elegida: islas React/TSX montadas sobre las plantillas Django
existentes (django-vite), alimentadas por endpoints JSON bajo /api/. El backend,
las URLs y la auth por sesión se mantienen; se migra sección a sección.
Fase 0 (tooling):
- frontend/ con Vite + React 18 + TypeScript. Build a static/dist con manifest.
- django-vite 3.1 en INSTALLED_APPS + DJANGO_VITE (dev_mode=DEBUG,
static_url_prefix='dist'). STATIC_URL pasa a '/static/' (absoluto) para que los
assets no choquen con el <base href> de la plantilla. WhiteNoise sirve el bundle.
- .gitignore: frontend/node_modules y static/dist (artefactos de build).
Fase 1 (piloto: lista de noticias de la portada):
- API: home/views/api.py -> home_news_api (JsonResponse); ruta /api/home/news/
montada en home/api_urls.py fuera de i18n_patterns.
- React: NewsList.tsx hace fetch de la API y renderiza las noticias (mismas clases
CSS que el HTML original). Entry src/entries/home.tsx monta en #home-news-app.
- partials/noticias.html: el bucle {% for noticia %} se reemplaza por el contenedor
de montaje + {% vite_asset %}.
Verificado en producción: manage.py check OK, /api/home/news/ 200, la home incluye
el mount y el <script> del bundle, y el bundle se sirve (200).
Build en deploy: cd frontend && npm run build && collectstatic (ver frontend/README.md).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>