# Panel Customer (`/my-projects`)

> Panel del cliente final pagante. Live en `bewpro.com/my-projects` desde 2026-05-05.
> Estado: ✅ Production-ready (15/15 ejes del standard de madurez).
>
> Última actualización: 2026-05-12

---

## Quién es el usuario

Cliente final que compró un sitio en BewPro vía marketplace, reseller, o canje. Tiene rol Spatie `Client` (o `Reseller` también, si es reseller con proyectos propios).

**Lo que el usuario espera del panel:**
- Ver sus sitios + estado en tiempo real
- Pagar / gestionar suscripción sin fricción
- Resolver dudas sin abrir ticket
- Contacto directo con soporte cuando lo necesite

**Lo que NO espera:**
- Documentación técnica
- Términos de Airtable / cPanel / Stripe IDs
- Jerga de provisión

---

## Rutas implementadas

| Ruta | Método | Vista | Propósito |
|------|--------|-------|-----------|
| `/my-projects` | GET | `index.blade.php` | Dashboard (stats + lista + filtros) |
| `/my-projects/help` | GET | `help.blade.php` | Centro de Ayuda FAQs |
| `/my-projects/billing` | GET | `billing.blade.php` | Historial de facturas (Cashier) |
| `/my-projects/billing/{invoice}/pdf` | GET | (binario) | Descarga PDF factura |
| `/my-projects/profile` | GET | `profile.blade.php` | Perfil + cambio password |
| `/my-projects/profile` | PATCH | — | Update info personal |
| `/my-projects/profile/password` | PATCH | — | Update password |
| `/my-projects/{id}` | GET | `show.blade.php` | Detalle de un proyecto |
| `/my-projects/{id}/billing` | POST | (redirect Stripe) | Apertura Stripe Billing Portal |
| `/my-projects/support` | GET | `support/index.blade.php` | Listado de tickets |
| `/my-projects/support/new` | GET | `support/create.blade.php` | Form nuevo ticket |
| `/my-projects/support/{id}` | GET | `support/show.blade.php` | Detalle + thread |
| `/my-projects/support/{id}/reply` | POST | — | Responder ticket |
| `/my-projects/support/{id}/close` | POST | — | Cerrar ticket |

Middleware: `ensure.main.site` + `auth` + `verified` + `role:Client|Reseller`.

---

## Features clave

### Dashboard (`/my-projects`)

1. **Onboarding 3-pasos** para users fresh sin proyectos (Bloque A — agregado 2026-05-12).
2. **Trial banner** amarillo cuando algún proyecto tiene `trial_ends_at` en los próximos 7 días, con CTA "Configurar pago" → Stripe Portal o "Contactar soporte" si no hay billing usable (Bloque B — agregado 2026-05-12).
3. **Stats bar**: Total / Activos / En curso / Suspendidos / USD mensual.
4. **Status filters** (badges) cuando hay ≥2 proyectos: Todos · Activos · En desarrollo · Preparando · Suspendidos · Archivados (Bloque D — agregado 2026-05-12).
5. **Tabla de proyectos** con primary action "Entrar al admin" + secondary icons (ver detalle, billing).
6. **Progress bar + ETA** para proyectos en provisión.
7. **Welcome card legacy** para users fresh con proyecto en provisión.

### Detalle proyecto (`/my-projects/{id}`)

- Authorization vía Policy (proyecto ajeno → 403).
- Datos: project_name, domain, status descriptivo, subscription details.
- Vista resolveSubscriptionDetails (Cashier) para mostrar plan + period_end.

### Billing history

- Lista de invoices del User (`$user->invoices()` Cashier).
- Descarga PDF por invoice.
- Empty state si no hay facturas todavía.

### Profile

- Form para first_name, last_name, country, phone (email es readonly).
- Form separado para change password con current_password validation.

### Support

- Módulo integrado (no es parte de Clients/, vive en `app/Modules/Support/`).
- Tickets propios del user (no ve ajenos).
- Thread de conversación con admin.
- Close ticket explícito.

### Centro de Ayuda (`/my-projects/help` — agregado 2026-05-12)

- 4 secciones de FAQs estáticos:
  - **Provisión** (4 preguntas): cuánto tarda, cómo veo progreso, qué pasa si falla, cómo accedo al admin.
  - **Pagos** (4 preguntas): cambiar método, cobranza falla, dónde veo facturas, cómo cancelo.
  - **Soporte** (3 preguntas): cómo abrir ticket, tiempo de respuesta, urgencias.
  - **Reembolsos** (3 preguntas): política, cómo solicitar, cambio de plan.
- Accordion Bootstrap (collapse).
- CTA final: "Abrir ticket" → `/my-projects/support/new`.

---

## Cambios 2026-05-12 (Bloques A/B/C/D)

Antes de esta fecha el panel cubría ~80% del journey. Cerramos 4 gaps UX:

| Bloque | Gap | Solución |
|--------|-----|----------|
| A | Welcome solo aparecía si había proyecto en provisión. User fresh con 0 proyectos veía panel vacío. | Welcome 3-pasos también para 0 proyectos (replica del Reseller dashboard pattern). |
| B | `trial_ends_at` invisible en panel. Cliente solo se entera del fin de trial por email → churn silencioso. | Banner amarillo computado sobre TODOS los proyectos (no filtrados), con CTA Stripe Portal o soporte. |
| C | Sin Help / FAQs in-panel. Cliente abría ticket por dudas básicas → volumen soporte alto. | Vista `/help` con 14 FAQs estáticos en 4 temas. |
| D | Lista de proyectos plana. Cliente con 3+ no podía filtrar por status. | Badges de filtros (con counts) cuando hay ≥2 proyectos. |

**Modelos / código afectado**:
- `app/Models/TenantProject.php`: +3 métodos (`isOnTrial`, `isTrialEndingSoon`, accessor `trial_days_left`).
- `app/Modules/Clients/Controllers/MyProjectsController.php`: `index()` ampliado, nuevo método `help()`, const `FAQS` + `FILTERABLE_STATUSES`.
- `resources/views/modules/clients/my-projects/index.blade.php`: nuevo welcome card no-projects, trial banner, status filters.
- `resources/views/modules/clients/my-projects/help.blade.php`: NUEVO.
- `routes/modules/clients.php`: +ruta `/my-projects/help`.
- `config/demo1/menu.php`: +item sidebar "Centro de Ayuda".

---

## Standard de Madurez — checklist por eje

| Eje | Status | Notas |
|-----|--------|-------|
| 1. Estructura base | ✅ | Todas las vistas usan x-base-layout + x-admin-header + breadcrumbs |
| 2. Onboarding | ✅ | Welcome 3-pasos para 0 proyectos + variante in-progress (Bloque A) |
| 3. Stats top | ✅ | Total/Activos/En curso/Suspendidos/USD con responsive col-6 col-md-auto |
| 4. Filtros | ✅ | Status badges con counts cuando ≥2 proyectos (Bloque D) |
| 5. Empty states | ✅ | Tipados: "sin proyectos" vs "filtro no matchea" — ambos con CTA |
| 6. Lifecycle banners | ✅ | Trial expirando banner amarillo (Bloque B) |
| 7. Progress + ETA | ✅ | TenantProject::provisioning_eta accessor con 0-95% + texto |
| 8. Primary + secondary | ✅ | "Entrar al admin" primary + icons (detalle/billing) secondary |
| 9. Help in-panel | ✅ | Centro de Ayuda con 14 FAQs (Bloque C) |
| 10. Integraciones | ✅ | Stripe Portal + Support tickets + downloadInvoice |
| 11. Auth + permisos | ✅ | role:Client\|Reseller + Policy en show + ensure.main.site |
| 12. Responsive | ✅ | Mobile validado 2026-05-12 |
| 13. Flash + alerts | ✅ | session('success/error') + ?verified=1 alert + SweetAlert |
| 14. Footer útil | ✅ | Soporte + Refund link + last_synced_at info |
| 15. Idioma + tono | ✅ | 100% español argentino, tuteo |

**Score: 15/15 ✅ Production-ready.**

---

## Validación E2E

Última validación completa: 2026-05-12 (manual en navegador post-Bloques A/B/C/D).

Para revalidar después de cambios, seguir el checklist en `docs/bewpro2.0/paneles/checklist-e2e-customer.md` (TODO crear si lo querés explícito como playbook).

---

## Gaps futuros (no bloqueantes)

Diferidos a próximas iteraciones — NO comprometen production-ready status actual:

- **Email security**: welcome email manda password plain → mejor one-time login link.
- **In-app notifications**: toast/banner sistema para milestones de provisión.
- **Cancel subscription in-app**: hoy solo vía Stripe Portal.
- **Bulk billing PDF download**: ZIP de todas las facturas.
- **Localización adicional**: hoy ES-AR, futuro EN/PT-BR.

Estos quedan documentados para una sesión futura "Customer Panel v3".

---

## Referencias

- Roadmap original: `docs/bewpro2.0/roadmap/06-user-portal.md`
- Standard de madurez: `docs/bewpro2.0/paneles/standard-de-madurez.md`
- Reseller panel: `docs/bewpro2.0/paneles/02-reseller.md`
- Soporte module: `app/Modules/Support/`
