Skip to main content

Cómo acceder al dashboard

El dashboard es el panel privado donde el dueño edita TODO su negocio — productos, servicios, diseño, analytics. El acceso es secreto para que los clientes que visitan la página no lo vean.

Desde desktop

Presionar Alt + S en cualquier parte de la página web.

Desde móvil

Mantener presionado el logo del negocio por 3 segundos.
Este atajo secreto está pensado para que el dueño pueda editar su página desde el celular sin necesidad de computadora.

Protección por PIN

Al acceder, el sistema pide un PIN numérico de 4 dígitos. Por defecto es 1234 (se asigna al crear el negocio en el wizard).
// OnboardingController.php:113
'edit_pin' => bcrypt('1234')
El dueño puede cambiar el PIN desde el dashboard en Config → Seguridad.
// DashboardController.php:1010-1045
public function updatePin(Request $request, int $tenantId): JsonResponse
{
    $validated = $request->validate([
        'current_pin' => 'required|string|size:4|regex:/^[0-9]{4}$/',
        'new_pin' => 'required|string|size:4|regex:/^[0-9]{4}$/',
        'new_pin_confirmation' => 'required|string|same:new_pin'
    ]);

    // Verificar PIN actual
    if (!Hash::check($validated['current_pin'], $tenant->pin_hash)) {
        return response()->json(['success' => false, 'message' => 'El PIN actual es incorrecto'], 422);
    }

    // Actualizar PIN
    $tenant->pin_hash = Hash::make($validated['new_pin']);
    $tenant->save();
}

Tabs del dashboard

El dashboard tiene 6 pestañas principales:

Info

Datos del negocio: nombre, slogan, teléfonos, email, dirección, ciudad, descripción, horarios.
// DashboardController.php:200-320
public function updateInfo(Request $request, int $tenantId): JsonResponse
{
    $validated = $request->validate([
        'business_name' => 'sometimes|required|string|max:255',
        'slogan' => 'nullable|string|max:255',
        'phone' => 'nullable|string|max:20',
        'whatsapp_sales' => 'nullable|string|max:20',
        'email' => 'nullable|email|max:255',
        'city' => 'nullable|string|max:100',
        'description' => 'nullable|string|max:1000'
    ]);

    $tenant->update($validated);
}

Productos

Crear, editar, eliminar productos o ítems del catálogo. Límite según el plan:
  • Plan Oportunidad: 20 productos
  • Plan Crecimiento: 50 productos
  • Plan Visión: ilimitado
// DashboardController.php:443-492
public function createProduct(Request $request, int $tenantId): JsonResponse
{
    $maxItems = $tenant->getMaxItems();
    $currentCount = $tenant->products->count();

    if ($currentCount >= $maxItems) {
        return response()->json([
            'success' => false,
            'message' => "Has alcanzado el límite de {$maxItems} productos"
        ], 422);
    }
}

Servicios

Gestión de servicios ofrecidos. Límite por plan:
  • Plan Oportunidad: 3 servicios
  • Plan Crecimiento: 6 servicios
  • Plan Visión: 9 servicios

Diseño

Paletas de color: Seleccionar entre temas Preline disponibles según el plan. Moneda: Configurar cómo se muestran los precios (solo REF, solo Bs, toggle REF/Bs, ocultar). Custom palette: Solo Plan Visión — crear paleta personalizada.
// DashboardController.php:751-829
public function updateTheme(Request $request, int $tenantId): JsonResponse
{
    $allowedThemes = PrelineThemeService::getThemesByPlan($tenant->plan_id);

    $validated = $request->validate([
        'theme_slug' => ['required', 'string', Rule::in($allowedThemes)]
    ]);

    $customization->theme_slug = $validated['theme_slug'];
    $customization->save();
}

Analytics

Estadísticas de tráfico: visitantes únicos hoy, esta semana, clics WhatsApp, escaneos QR, tiempo promedio en página.
El dashboard carga analytics en vivo con Alpine.js — se actualizan cada 30 segundos sin recargar la página.

Config

Opciones avanzadas:
  • Cambiar PIN de acceso
  • Métodos de pago (Plan 2+)
  • Header Top promocional (Plan 2+)
  • Sucursales (Plan Visión)
  • Sección FAQ (Plan Visión)
  • Testimonios (Plan Visión)

Blueprint system

El dashboard adapta su interfaz según el blueprint del tenant:
// DashboardController.php:82-85
$blueprint = $tenant->getBlueprintSlug(); // 'studio' | 'food' | 'cat'
$maxItems = $tenant->getMaxItems();
$itemLabel = $tenant->getItemLabel();     // 'productos' | 'ítems' | 'platos'
$itemSingular = $tenant->getItemSingular(); // 'producto' | 'ítem' | 'plato'
Ejemplo: Si el tenant es SYNTIfood, el tab “Productos” cambia a “Menú” y muestra categorías con ítems en lugar de productos individuales.

Datos cargados

Al entrar al dashboard, el controlador carga TODO en una sola query con Eloquent eager loading:
// DashboardController.php:41-55
$tenant = Tenant::with([
    'plan',
    'customization',
    'products' => fn($q) => $q->orderBy('position')->orderByDesc('created_at'),
    'products.galleryImages',
    'services' => fn($q) => $q->orderBy('position')->orderByDesc('created_at'),
    'branches'
])->where('id', $tenantId)->whereIn('status', ['active', 'frozen'])->firstOrFail();
La query incluye whereIn('status', ['active', 'frozen']) porque los tenants congelados (mora de pago) pueden acceder al dashboard para renovar, pero los marcados como 'inactive' no.

URL del dashboard

/tenant/{id}/dashboard Ejemplo: Para el tenant ID 5 → /tenant/5/dashboard

Build docs developers (and LLMs) love