mirror of
https://github.com/marcogll/AnchorOS.git
synced 2026-03-15 10:24:26 +00:00
feat: Integrate Formbricks and webhook functionality, updating Docker configurations, deployment guides, and asset plans.
This commit is contained in:
@@ -34,8 +34,9 @@ deploy.sh
|
|||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
*.md
|
*.md
|
||||||
API_TESTING_GUIDE.md
|
# Keep deployment guides in production image
|
||||||
DEPLOYMENT_README.md
|
!DEPLOYMENT_README.md
|
||||||
|
!API_TESTING_GUIDE.md
|
||||||
|
|
||||||
# Testing
|
# Testing
|
||||||
coverage
|
coverage
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|||||||
# App
|
# App
|
||||||
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
||||||
|
|
||||||
|
# Formbricks (Surveys - Optional)
|
||||||
|
NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID=your-environment-id
|
||||||
|
NEXT_PUBLIC_FORMBRICKS_API_HOST=https://app.formbricks.com
|
||||||
|
|
||||||
# Optional: Redis para caching
|
# Optional: Redis para caching
|
||||||
REDIS_URL=redis://redis:6379
|
REDIS_URL=redis://redis:6379
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,74 @@
|
|||||||
- `POST /api/cron/reset-invitations` - Reset diario
|
- `POST /api/cron/reset-invitations` - Reset diario
|
||||||
- Buscar: Invitaciones expiradas reseteadas
|
- Buscar: Invitaciones expiradas reseteadas
|
||||||
|
|
||||||
|
### **📧 Webhooks (Formularios Públicos)**
|
||||||
|
- `POST https://flows.soul23.cloud/webhook-test/4YZ7RPfo1GT` - Webhook test
|
||||||
|
- Body: Payload completo con form type
|
||||||
|
- Buscar: 200 OK + acknowledgment
|
||||||
|
- `POST https://flows.soul23.cloud/webhook/4YZ7RPfo1GT` - Webhook prod
|
||||||
|
- Body: Payload completo con form type
|
||||||
|
- Buscar: 200 OK + acknowledgment
|
||||||
|
|
||||||
|
**Form Types disponibles:**
|
||||||
|
- `contact` - Formulario de contacto
|
||||||
|
- `franchise` - Solicitud de franquicia
|
||||||
|
- `membership` - Solicitud de membresía
|
||||||
|
|
||||||
|
**Payload Base:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"form": "contact|franchise|membership",
|
||||||
|
"timestamp_utc": "2026-01-18T04:26:30.187Z",
|
||||||
|
"device_type": "mobile|desktop|unknown"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Contact Payload:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"form": "contact",
|
||||||
|
"nombre": "Nombre Completo",
|
||||||
|
"email": "email@example.com",
|
||||||
|
"telefono": "+52 844 123 4567",
|
||||||
|
"motivo": "cita|membresia|franquicia|servicios|pago|resena|otro",
|
||||||
|
"mensaje": "Texto del mensaje",
|
||||||
|
"timestamp_utc": "2026-01-18T04:26:30.187Z",
|
||||||
|
"device_type": "mobile"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Franchise Payload:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"form": "franchise",
|
||||||
|
"nombre": "Nombre Completo",
|
||||||
|
"email": "email@example.com",
|
||||||
|
"telefono": "+52 844 123 4567",
|
||||||
|
"ciudad": "Monterrey",
|
||||||
|
"estado": "Nuevo León",
|
||||||
|
"socios": 2,
|
||||||
|
"experiencia_sector": "1-3-anos",
|
||||||
|
"experiencia_belleza": true,
|
||||||
|
"mensaje": "Mensaje adicional",
|
||||||
|
"timestamp_utc": "2026-01-18T04:26:30.187Z",
|
||||||
|
"device_type": "desktop"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Membership Payload:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"form": "membership",
|
||||||
|
"membership_id": "vip",
|
||||||
|
"nombre": "Nombre Completo",
|
||||||
|
"email": "email@example.com",
|
||||||
|
"telefono": "+52 844 123 4567",
|
||||||
|
"mensaje": "Pregunta específica",
|
||||||
|
"timestamp_utc": "2026-01-18T04:26:30.187Z",
|
||||||
|
"device_type": "mobile"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 🔍 **Qué Buscar en Cada Respuesta**
|
## 🔍 **Qué Buscar en Cada Respuesta**
|
||||||
|
|
||||||
### **✅ Éxito**
|
### **✅ Éxito**
|
||||||
|
|||||||
@@ -154,7 +154,30 @@ public/images/gallery/
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8. Logo SVG Original (@src/logo.svg)
|
## 8. Nuevos Componentes (@src/components/)
|
||||||
|
|
||||||
|
**Ubicación sugerida:** `components/`
|
||||||
|
|
||||||
|
**Componentes agregados:**
|
||||||
|
- `animated-logo.tsx` - Logo SVG animado con fade-in
|
||||||
|
- `rolling-phrases.tsx` - Frases rotativas para hero sections
|
||||||
|
- `formbricks-provider.tsx` - Provider para encuestas Formbricks
|
||||||
|
- `webhook-form.tsx` - Formulario unificado para webhooks
|
||||||
|
- `app-wrapper.tsx` - Wrapper de aplicación con contexto
|
||||||
|
- `loading-screen.tsx` - Pantalla de carga con animación
|
||||||
|
- `pattern-overlay.tsx` - Overlay de patrones decorativos
|
||||||
|
- `responsive-nav.tsx` - Navegación responsiva con menú móvil
|
||||||
|
|
||||||
|
**Iconos adicionales:**
|
||||||
|
- Diamond (check, success states)
|
||||||
|
- Crown (VIP tier)
|
||||||
|
|
||||||
|
**Colores actualizados:**
|
||||||
|
- `--charcoal-brown`: #3f362e (marrón oscuro elegante)
|
||||||
|
- `--deep-earth`: #6f5e4f (marrón medio)
|
||||||
|
- `--mocha-taupe`: #b8a89a (beige cálido)
|
||||||
|
|
||||||
|
## 9. Logo SVG Original (@src/logo.svg)
|
||||||
|
|
||||||
**Ruta:** `src/logo.svg`
|
**Ruta:** `src/logo.svg`
|
||||||
|
|
||||||
@@ -332,6 +355,30 @@ public/images/gallery/
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 📋 21. Formbricks Integration
|
||||||
|
|
||||||
|
**Ubicación:** `components/formbricks-provider.tsx`
|
||||||
|
|
||||||
|
**Configuración:**
|
||||||
|
- Environment ID para surveys
|
||||||
|
- API Host URL
|
||||||
|
- Device detection (mobile/desktop)
|
||||||
|
- Route change tracking
|
||||||
|
|
||||||
|
**Variables de entorno:**
|
||||||
|
```bash
|
||||||
|
NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID=your-id
|
||||||
|
NEXT_PUBLIC_FORMBRICKS_API_HOST=https://app.formbricks.com
|
||||||
|
```
|
||||||
|
|
||||||
|
**Uso previsto:**
|
||||||
|
- Encuestas post-experiencia
|
||||||
|
- Feedback de clientes
|
||||||
|
- NPS (Net Promoter Score)
|
||||||
|
- Estudios de satisfacción
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 📋 Checklist de Implementación
|
## 📋 Checklist de Implementación
|
||||||
|
|
||||||
| Tarea | Estado | Prioridad |
|
| Tarea | Estado | Prioridad |
|
||||||
@@ -340,6 +387,17 @@ public/images/gallery/
|
|||||||
| Optimizar imágenes A23_VIA_* | pending | alta |
|
| Optimizar imágenes A23_VIA_* | pending | alta |
|
||||||
| Implementar logo SVG en Hero sin animación | completed | alta |
|
| Implementar logo SVG en Hero sin animación | completed | alta |
|
||||||
| Implementar logo SVG en Loading sin fade-in| completed | alta |
|
| Implementar logo SVG en Loading sin fade-in| completed | alta |
|
||||||
|
| Crear componente animated-logo.tsx | completed | alta |
|
||||||
|
| Crear componente rolling-phrases.tsx | completed | alta |
|
||||||
|
| Crear componente webhook-form.tsx | completed | alta |
|
||||||
|
| Crear componente formbricks-provider.tsx | completed | media |
|
||||||
|
| Crear componente responsive-nav.tsx | completed | alta |
|
||||||
|
| Actualizar colores a #3E352E | completed | alta |
|
||||||
|
| Agregar campo motivo en contacto | completed | alta |
|
||||||
|
| Agregar campos estado/ciudad/socios en franchise | pending | alta |
|
||||||
|
| Agregar check experiencia belleza en franchise | pending | alta |
|
||||||
|
| Actualizar info franchise a $100k | completed | alta |
|
||||||
|
| Agregar link Contacto en nav/footer | completed | alta |
|
||||||
| Agregar imágenes Hero/Fundamento | pending | media |
|
| Agregar imágenes Hero/Fundamento | pending | media |
|
||||||
| Agregar imágenes Historia | pending | media |
|
| Agregar imágenes Historia | pending | media |
|
||||||
| Agregar testimonios | pending | media |
|
| Agregar testimonios | pending | media |
|
||||||
@@ -360,6 +418,12 @@ public/images/gallery/
|
|||||||
- **Background Loading:** #3F362E (Marrón oscuro elegante)
|
- **Background Loading:** #3F362E (Marrón oscuro elegante)
|
||||||
- **Gradient (alternativo):** #6f5e4f → #8B4513 → #5a4a3a
|
- **Gradient (alternativo):** #6f5e4f → #8B4513 → #5a4a3a
|
||||||
|
|
||||||
|
### Colores de Botones
|
||||||
|
- **Botón primario:** #3E352E (Marrón elegante) - reemplaza --deep-earth
|
||||||
|
- **Botón secundario:** Gradiente --bone-white → --soft-cream
|
||||||
|
- **Tarjetas featured:** #3E352E (Marrón elegante)
|
||||||
|
- **Hover effects:** #3E352E/90 (90% opacidad)
|
||||||
|
|
||||||
### Fondos de Secciones
|
### Fondos de Secciones
|
||||||
- **Hero:** #F5F5DC (Bone White)
|
- **Hero:** #F5F5DC (Bone White)
|
||||||
- **Services:** #F5F5DC
|
- **Services:** #F5F5DC
|
||||||
|
|||||||
@@ -25,6 +25,16 @@ NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJxxxxx
|
|||||||
SUPABASE_SERVICE_ROLE_KEY=eyJxxxxx
|
SUPABASE_SERVICE_ROLE_KEY=eyJxxxxx
|
||||||
RESEND_API_KEY=re_xxxxx
|
RESEND_API_KEY=re_xxxxx
|
||||||
NEXT_PUBLIC_APP_URL=https://tu-dominio.com
|
NEXT_PUBLIC_APP_URL=https://tu-dominio.com
|
||||||
|
|
||||||
|
# Formbricks (opcional - encuestas)
|
||||||
|
NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID=your-environment-id
|
||||||
|
NEXT_PUBLIC_FORMBRICKS_API_HOST=https://app.formbricks.com
|
||||||
|
|
||||||
|
# Optional: Redis para caching
|
||||||
|
REDIS_URL=redis://redis:6379
|
||||||
|
|
||||||
|
# Optional: Analytics
|
||||||
|
NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. **SSL Certificates**
|
### 3. **SSL Certificates**
|
||||||
@@ -165,6 +175,83 @@ docker-compose -f docker-compose.prod.yml restart
|
|||||||
- Query optimization
|
- Query optimization
|
||||||
- Redis caching (opcional)
|
- Redis caching (opcional)
|
||||||
|
|
||||||
|
## 📝 **Formbricks Integration**
|
||||||
|
|
||||||
|
### **Configuración de Encuestas**
|
||||||
|
```bash
|
||||||
|
# Activar Formbricks para recolección de feedback
|
||||||
|
NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID=clxxxxxxxx
|
||||||
|
NEXT_PUBLIC_FORMBRICKS_API_HOST=https://app.formbricks.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Webhooks**
|
||||||
|
```bash
|
||||||
|
# Endpoints de webhook para formularios
|
||||||
|
# Test: https://flows.soul23.cloud/webhook-test/4YZ7RPfo1GT
|
||||||
|
# Prod: https://flows.soul23.cloud/webhook/4YZ7RPfo1GT
|
||||||
|
|
||||||
|
# Formularios que envían a webhooks:
|
||||||
|
# - contact (Contacto)
|
||||||
|
# - franchise (Franquicias)
|
||||||
|
# - membership (Membresías)
|
||||||
|
|
||||||
|
# Payload structure:
|
||||||
|
{
|
||||||
|
"form": "contact|franchise|membership",
|
||||||
|
"timestamp_utc": "ISO-8601",
|
||||||
|
"device_type": "mobile|desktop|unknown",
|
||||||
|
"...": "campos específicos del formulario"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Form Types y Campos**
|
||||||
|
|
||||||
|
**Contact (contacto)**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"form": "contact",
|
||||||
|
"nombre": "string",
|
||||||
|
"email": "string",
|
||||||
|
"telefono": "string",
|
||||||
|
"motivo": "cita|membresia|franquicia|servicios|pago|resena|otro",
|
||||||
|
"mensaje": "string",
|
||||||
|
"timestamp_utc": "string",
|
||||||
|
"device_type": "string"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Franchise (franquicias)**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"form": "franchise",
|
||||||
|
"nombre": "string",
|
||||||
|
"email": "string",
|
||||||
|
"telefono": "string",
|
||||||
|
"ciudad": "string",
|
||||||
|
"estado": "string",
|
||||||
|
"socios": "number",
|
||||||
|
"experiencia_sector": "string",
|
||||||
|
"experiencia_belleza": "boolean",
|
||||||
|
"mensaje": "string",
|
||||||
|
"timestamp_utc": "string",
|
||||||
|
"device_type": "string"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Membership (membresías)**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"form": "membership",
|
||||||
|
"membership_id": "gold|black|vip",
|
||||||
|
"nombre": "string",
|
||||||
|
"email": "string",
|
||||||
|
"telefono": "string",
|
||||||
|
"mensaje": "string",
|
||||||
|
"timestamp_utc": "string",
|
||||||
|
"device_type": "string"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 🔒 **Seguridad**
|
## 🔒 **Seguridad**
|
||||||
|
|
||||||
- SSL/TLS 1.2+
|
- SSL/TLS 1.2+
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
# Dockerfile optimizado para Next.js production
|
# Dockerfile optimizado para Next.js production
|
||||||
FROM node:18-alpine AS base
|
FROM node:18-alpine AS base
|
||||||
|
|
||||||
# Instalar dependencias solo para producción
|
# Instalar dependencias para build
|
||||||
FROM base AS deps
|
FROM base AS deps
|
||||||
RUN apk add --no-cache libc6-compat
|
RUN apk add --no-cache libc6-compat
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Copiar archivos de dependencias
|
# Copiar archivos de dependencias
|
||||||
COPY package.json package-lock.json ./
|
COPY package.json package-lock.json ./
|
||||||
RUN npm ci --only=production --ignore-scripts && npm cache clean --force
|
RUN npm ci --ignore-scripts && npm cache clean --force
|
||||||
|
|
||||||
# Build stage
|
# Build stage
|
||||||
FROM base AS builder
|
FROM base AS builder
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
import { AnimatedLogo } from '@/components/animated-logo'
|
|
||||||
import { RollingPhrases } from '@/components/rolling-phrases'
|
|
||||||
|
|
||||||
/** @description Services page with home page style structure */
|
|
||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
|
import { useState, useEffect } from 'react'
|
||||||
import { AnimatedLogo } from '@/components/animated-logo'
|
import { AnimatedLogo } from '@/components/animated-logo'
|
||||||
import { RollingPhrases } from '@/components/rolling-phrases'
|
import { RollingPhrases } from '@/components/rolling-phrases'
|
||||||
|
|
||||||
/** @description Services page with home page style structure */
|
/** @description Services page with home page style structure */
|
||||||
import { useState, useEffect } from 'react'
|
|
||||||
|
|
||||||
interface Service {
|
interface Service {
|
||||||
id: string
|
id: string
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -14,6 +14,8 @@ services:
|
|||||||
- SUPABASE_SERVICE_ROLE_KEY=${SUPABASE_SERVICE_ROLE_KEY}
|
- SUPABASE_SERVICE_ROLE_KEY=${SUPABASE_SERVICE_ROLE_KEY}
|
||||||
- RESEND_API_KEY=${RESEND_API_KEY}
|
- RESEND_API_KEY=${RESEND_API_KEY}
|
||||||
- NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL}
|
- NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL}
|
||||||
|
- NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID=${NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID}
|
||||||
|
- NEXT_PUBLIC_FORMBRICKS_API_HOST=${NEXT_PUBLIC_FORMBRICKS_API_HOST}
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
networks:
|
networks:
|
||||||
@@ -23,7 +25,6 @@ services:
|
|||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
# Recursos optimizados
|
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
@@ -48,10 +49,6 @@ services:
|
|||||||
- anchoros
|
- anchoros
|
||||||
networks:
|
networks:
|
||||||
- anchoros_network
|
- anchoros_network
|
||||||
# SSL termination y caching
|
|
||||||
environment:
|
|
||||||
- NGINX_ENVSUBST_TEMPLATE_DIR=/etc/nginx/templates
|
|
||||||
- NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx/conf.d
|
|
||||||
|
|
||||||
# Opcional: Redis para caching adicional
|
# Opcional: Redis para caching adicional
|
||||||
redis:
|
redis:
|
||||||
@@ -70,4 +67,4 @@ volumes:
|
|||||||
|
|
||||||
networks:
|
networks:
|
||||||
anchoros_network:
|
anchoros_network:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { createClient } from '@supabase/supabase-js'
|
import { createClient } from '@supabase/supabase-js'
|
||||||
|
|
||||||
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
|
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL || 'https://your-project.supabase.co'
|
||||||
const supabaseServiceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY!
|
const supabaseServiceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY || 'your-service-role-key-here'
|
||||||
|
|
||||||
// Admin Supabase client for server-side operations with service role
|
// Admin Supabase client for server-side operations with service role
|
||||||
export const supabaseAdmin = createClient(
|
export const supabaseAdmin = createClient(
|
||||||
|
|||||||
Reference in New Issue
Block a user