212 lines
7.6 KiB
TypeScript
212 lines
7.6 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { dataService } from '@/lib/data-service';
|
|
import { CustomProductRequest } from '@/types';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
|
|
const EVOLUTION_API_URL = process.env.EVOLUTION_API_URL || 'https://evolution.almeira.com.co';
|
|
const EVOLUTION_API_KEY = process.env.EVOLUTION_API_KEY || 'EE49029EEB85-4568-8F81-C9FDFC6E2943';
|
|
const EVOLUTION_INSTANCE = process.env.EVOLUTION_INSTANCE_NAME || 'AutomataAlmeira';
|
|
const CARLOS_PHONE = '573167455877';
|
|
|
|
// Carpeta local para almacenar fotos de encargos especiales
|
|
const UPLOADS_DIR = path.join(process.cwd(), 'public', 'uploads', 'custom-requests');
|
|
|
|
function ensureUploadsDir() {
|
|
if (!fs.existsSync(UPLOADS_DIR)) {
|
|
fs.mkdirSync(UPLOADS_DIR, { recursive: true });
|
|
}
|
|
}
|
|
|
|
// Función auxiliar para enviar mensajes de WhatsApp vía Evolution API
|
|
async function sendWhatsAppMessage(number: string, text: string) {
|
|
try {
|
|
const cleanNumber = number.replace(/\D/g, '');
|
|
const fullNumber = cleanNumber.length === 10 ? `57${cleanNumber}` : cleanNumber;
|
|
|
|
const res = await fetch(`${EVOLUTION_API_URL}/message/sendText/${EVOLUTION_INSTANCE}`, {
|
|
method: 'POST',
|
|
headers: {
|
|
apikey: EVOLUTION_API_KEY,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
number: fullNumber,
|
|
text: text,
|
|
}),
|
|
});
|
|
return await res.json();
|
|
} catch (err) {
|
|
console.warn('Error enviando WhatsApp a ' + number + ':', err);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function GET(request: NextRequest) {
|
|
try {
|
|
const { searchParams } = new URL(request.url);
|
|
const userId = searchParams.get('userId') || undefined;
|
|
const requests = dataService.getCustomRequests(userId);
|
|
return NextResponse.json({ success: true, requests });
|
|
} catch (error: any) {
|
|
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
|
}
|
|
}
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const body = await request.json();
|
|
const {
|
|
userId,
|
|
customerName,
|
|
customerPhone,
|
|
customerEmail,
|
|
customerCity,
|
|
brand,
|
|
modelName,
|
|
size,
|
|
colorway,
|
|
targetBudget,
|
|
notes,
|
|
imageBase64,
|
|
} = body;
|
|
|
|
if (!customerName || !customerPhone || !brand || !modelName || !size) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: 'Faltan campos obligatorios: Nombre, Teléfono, Marca, Modelo y Talla.',
|
|
},
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
let finalImageUrl = body.imageUrl || '';
|
|
|
|
// Si el usuario envió una imagen en base64, guardarla en disco
|
|
if (imageBase64 && imageBase64.startsWith('data:image')) {
|
|
try {
|
|
ensureUploadsDir();
|
|
const matches = imageBase64.match(/^data:image\/([a-zA-Z0-9]+);base64,(.+)$/);
|
|
if (matches) {
|
|
const ext = matches[1] === 'jpeg' ? 'jpg' : matches[1];
|
|
const buffer = Buffer.from(matches[2], 'base64');
|
|
const filename = `encargo-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.${ext}`;
|
|
const filePath = path.join(UPLOADS_DIR, filename);
|
|
fs.writeFileSync(filePath, buffer);
|
|
finalImageUrl = `/uploads/custom-requests/${filename}`;
|
|
}
|
|
} catch (saveErr) {
|
|
console.warn('No se pudo guardar la imagen del encargo en disco:', saveErr);
|
|
}
|
|
}
|
|
|
|
// Crear la solicitud en DataService
|
|
const createdRequest = dataService.addCustomRequest({
|
|
userId,
|
|
customerName,
|
|
customerPhone,
|
|
customerEmail,
|
|
customerCity: customerCity || 'Colombia',
|
|
brand,
|
|
modelName,
|
|
size,
|
|
colorway: colorway || 'Original / Según Foto',
|
|
targetBudget: targetBudget ? parseInt(targetBudget, 10) : undefined,
|
|
notes: notes || '',
|
|
imageUrl: finalImageUrl,
|
|
status: 'pending',
|
|
});
|
|
|
|
// 1. Notificación inmediata a Carlos (+57 316 745 5877)
|
|
const budgetFormatted = createdRequest.targetBudget
|
|
? `$${createdRequest.targetBudget.toLocaleString('es-CO')}`
|
|
: 'A cotizar por bodega';
|
|
|
|
const adminMessage = `🚨 *NUEVA SOLICITUD DE ENCARGO ESPECIAL* 👟
|
|
-----------------------------------------
|
|
👤 *Cliente:* ${customerName}
|
|
📱 *WhatsApp:* ${customerPhone}
|
|
🏙️ *Ciudad:* ${customerCity || 'Colombia'}
|
|
${customerEmail ? `✉️ *Correo:* ${customerEmail}\n` : ''}
|
|
🏷️ *Marca:* ${brand}
|
|
👟 *Modelo:* ${modelName}
|
|
📏 *Talla Deseada:* ${size}
|
|
🎨 *Colorway:* ${colorway || 'Original / Ver Foto'}
|
|
💰 *Presupuesto Estimado:* ${budgetFormatted}
|
|
📝 *Notas del Cliente:* ${notes || 'Ninguna'}
|
|
📅 *Fecha:* ${new Date().toLocaleString('es-CO')}
|
|
-----------------------------------------
|
|
⚡ ¡Consulta de inmediato con tus proveedores mayoristas para enviar cotización al cliente!`;
|
|
|
|
sendWhatsAppMessage(CARLOS_PHONE, adminMessage).catch(() => {});
|
|
sendWhatsAppMessage('120363428012905103@g.us', adminMessage).catch(() => {});
|
|
|
|
// 2. Confirmación automática al cliente por WhatsApp
|
|
const clientMessage = `👋 ¡Hola *${customerName}*!
|
|
Recibimos con éxito tu solicitud por encargo para las *${brand} ${modelName}* en talla *${size}*. 👟🔥
|
|
|
|
Nuestro equipo ya está verificando disponibilidad y mejor precio con nuestras bodegas y proveedores mayoristas. Te responderemos a este mismo chat con la cotización exacta en el menor tiempo posible.
|
|
|
|
¡Gracias por confiar en DripZone! 🚀`;
|
|
|
|
sendWhatsAppMessage(customerPhone, clientMessage).catch(() => {});
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
message: '¡Solicitud de encargo recibida con éxito! Nuestro equipo te contactará por WhatsApp.',
|
|
request: createdRequest,
|
|
});
|
|
} catch (error: any) {
|
|
console.error('Error en POST /api/custom-requests:', error);
|
|
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
|
}
|
|
}
|
|
|
|
export async function PUT(request: NextRequest) {
|
|
try {
|
|
const body = await request.json();
|
|
const { id, updates, notifyCustomer } = body;
|
|
|
|
if (!id) {
|
|
return NextResponse.json({ success: false, error: 'ID de solicitud requerido' }, { status: 400 });
|
|
}
|
|
|
|
const updated = dataService.updateCustomRequest(id, updates);
|
|
if (!updated) {
|
|
return NextResponse.json({ success: false, error: 'Solicitud no encontrada' }, { status: 404 });
|
|
}
|
|
|
|
// Si el admin activó la notificación al cliente (por ejemplo al cotizar el producto)
|
|
if (notifyCustomer && updated.customerPhone && updated.quotedPrice) {
|
|
const quoteMessage = `👋 ¡Hola *${updated.customerName}*!
|
|
¡Buenas noticias! Encontramos tu par solicitado: *${updated.brand} ${updated.modelName}* en talla *${updated.size}*. 👟✨
|
|
|
|
💰 *Precio Cotizado:* $${updated.quotedPrice.toLocaleString('es-CO')} COP
|
|
🚚 *Envío:* Despacho directo a tu dirección con pago contraentrega disponible.
|
|
|
|
¿Deseas confirmar tu pedido para apartarlo de bodega de inmediato? Respóndenos a este mensaje para coordinar la entrega.`;
|
|
|
|
sendWhatsAppMessage(updated.customerPhone, quoteMessage).catch(() => {});
|
|
}
|
|
|
|
return NextResponse.json({ success: true, request: updated });
|
|
} catch (error: any) {
|
|
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
|
}
|
|
}
|
|
|
|
export async function DELETE(request: NextRequest) {
|
|
try {
|
|
const { searchParams } = new URL(request.url);
|
|
const id = searchParams.get('id');
|
|
if (!id) {
|
|
return NextResponse.json({ success: false, error: 'ID requerido' }, { status: 400 });
|
|
}
|
|
const deleted = dataService.deleteCustomRequest(id);
|
|
return NextResponse.json({ success: deleted });
|
|
} catch (error: any) {
|
|
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
|
}
|
|
}
|