34591-vm/index.php
Flatlogic Bot 94b10ba1f5 1
2025-10-02 10:14:38 +00:00

476 lines
17 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Marketplace Business Assistant</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&display=swap" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
:root {
--font-family: 'Poppins', sans-serif;
--pastel-grey: #EAEAEA;
--pastel-blue: #d1e3f3;
--text-light: #888;
--text-dark: #333;
--card-bg: rgba(255, 255, 255, 0.85);
}
body {
font-family: var(--font-family);
margin: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
color: var(--text-dark);
overflow: hidden;
background: linear-gradient(45deg, var(--pastel-grey), var(--pastel-blue));
}
.background-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}
#lava-canvas {
position: absolute;
width: 100%;
height: 100%;
z-index: 0;
top: 0;
left: 0;
}
.chat-container {
width: 100%;
max-width: 800px;
height: 90vh;
max-height: 800px;
display: flex;
flex-direction: column;
background: var(--card-bg);
backdrop-filter: blur(10px);
border-radius: 24px;
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
border: 1px solid rgba(255, 255, 255, 0.18);
overflow: hidden;
z-index: 1;
}
.chat-main {
display: flex;
flex-direction: column;
flex-grow: 1;
overflow: hidden;
}
.chat-header {
background: rgba(255, 255, 255, 0.5);
padding: 1rem 1.5rem;
text-align: center;
font-size: 1.2rem;
font-weight: 600;
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
flex-shrink: 0;
}
.chat-messages {
flex-grow: 1;
padding: 1.5rem;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 1rem;
}
.message {
padding: 0.75rem 1.25rem;
border-radius: 18px;
max-width: 85%;
line-height: 1.6;
font-weight: 400;
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.message.assistant {
background-color: rgba(255, 255, 255, 0.9);
align-self: flex-start;
border-bottom-left-radius: 4px;
}
.message.user {
background: linear-gradient(45deg, #a8e6cf, #bde6d9);
color: var(--text-dark);
align-self: flex-end;
border-bottom-right-radius: 4px;
}
.quick-actions-container {
padding: 1rem 1.5rem 0.5rem;
border-top: 1px solid rgba(255, 255, 255, 0.3);
flex-shrink: 0;
}
.quick-actions {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
justify-content: flex-start;
}
.quick-action {
background-color: rgba(255, 255, 255, 0.7);
border: 1px solid transparent;
color: var(--text-dark);
padding: 0.6rem 1.1rem;
border-radius: 16px;
cursor: pointer;
font-size: 0.85rem;
font-weight: 500;
transition: all 0.3s ease;
box-shadow: 0 1px 4px rgba(0,0,0,0.05);
}
.quick-action:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
background: white;
}
.chat-input-container {
padding: 1rem 1.5rem;
border-top: 1px solid rgba(255, 255, 255, 0.2);
flex-shrink: 0;
}
.chat-input {
display: flex;
align-items: center;
background: white;
border-radius: 25px;
padding: 0.25rem;
box-shadow: 0 2px 10px rgba(0,0,0,0.08);
}
.chat-input input[type="text"] {
flex-grow: 1;
border: none;
background: transparent;
border-radius: 20px;
padding: 0.75rem 1rem;
font-size: 1rem;
outline: none;
color: var(--text-dark);
}
.chat-input input[type="file"] {
display: none;
}
.chat-input button, .chat-input .file-upload-label {
background: linear-gradient(45deg, #ffd3b6, #d2b4de);
color: white;
border: none;
border-radius: 50%;
width: 40px;
height: 40px;
cursor: pointer;
font-size: 1.5rem;
display: flex;
justify-content: center;
align-items: center;
transition: transform 0.2s ease;
margin-left: 5px;
}
.chat-input button:hover, .chat-input .file-upload-label:hover {
transform: scale(1.1);
}
.file-upload-label {
background: transparent;
color: #888;
font-size: 1.2rem;
}
.file-upload-label:hover {
color: #333;
}
</style>
</head>
<body>
<div class="background-container">
<canvas id="lava-canvas"></canvas>
</div>
<div class="chat-container" id="chat-container">
<div class="chat-main">
<div class="chat-header">
Marketplace Business Assistant
</div>
<div class="chat-messages" id="chat-messages">
<div class="message assistant">
Hello! I'm your Marketplace Assistant. How can I help you today? You can select one of the quick actions below or upload a file to analyze.
</div>
</div>
<div class="quick-actions-container">
<div class="quick-actions" id="quick-actions">
<button class="quick-action" data-task="summarize_feedback_weekly">Summarize feedback</button>
<button class="quick-action" data-task="analyze_complaints">Analyze complaints</button>
<button class="quick-action" data-task="generate_seller_dashboard">Generate seller dashboard</button>
<button class="quick-action" data-task="summarize_refunds">Summarize refunds</button>
<button class="quick-action" data-task="draft_response_templates">Draft response templates</button>
<button class="quick-action" data-task="generate_sales_chart">Generate sales chart</button>
</div>
</div>
<div class="chat-input-container">
<div class="chat-input">
<input type="file" id="file-input" accept=".txt,.csv">
<label for="file-input" class="file-upload-label">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"></path></svg>
</label>
<input type="text" id="user-input" placeholder="Type your message...">
<button id="send-button">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
</button>
</div>
</div>
</div>
</div>
<script>
const chatMessages = document.getElementById('chat-messages');
const userInput = document.getElementById('user-input');
const sendButton = document.getElementById('send-button');
const quickActionsContainer = document.getElementById('quick-actions');
const fileInput = document.getElementById('file-input');
const assistantResponses = {
summarize_feedback_weekly: "This weeks customer feedback summary: Top 5 issues are 1. Late deliveries (23%), 2. Incorrect item received (15%), 3. Product not as described (12%), 4. Difficulty applying discounts (8%), 5. Slow seller response time (7%).",
draft_response_templates: "Here are some automated response templates: \n**Refunds:** 'Weve received your refund request for order #[Order ID] and are processing it. Youll receive an update within 2-3 business days.' \n**Shipping Delays:** 'We apologize for the delay in your order #[Order ID]. We are looking into it and will provide a status update shortly.'",
analyze_complaints: "Analysis of customer complaints shows that 65% of delivery time issues are concentrated in the West region, primarily with one shipping carrier. I recommend diversifying our shipping partners in that region.",
generate_seller_dashboard: "Weekly Seller Performance Dashboard: \n**Top Performers:** SellerA (99% positive feedback), SellerB (fastest shipping), SellerC (most new products). \n**Needs Attention:** SellerX (rating dropped to 85%), SellerY (2 open disputes).",
summarize_refunds: "Monthly Refund Summary: A total of 152 refunds were processed this month. Top reasons: 1. Item arrived damaged (45%), 2. Item not as described (30%), 3. Accidental order (15%). There is a 20% increase in 'damaged item' refunds for electronics.",
generate_sales_chart: 'Here is the sales report for the last 6 months:<br><canvas id="salesChart" width="400" height="200"></canvas>'
};
const taskMap = {};
document.querySelectorAll('.quick-action').forEach(button => {
taskMap[button.textContent] = button.dataset.task;
});
function renderChart() {
const chartCanvas = document.getElementById('salesChart');
if (!chartCanvas) return;
const ctx = chartCanvas.getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June'],
datasets: [{
label: 'Sales',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 1
}]
},
options: { scales: { y: { beginAtZero: true } } }
});
}
function addMessage(text, sender) {
const messageElement = document.createElement('div');
messageElement.classList.add('message', sender);
if (sender === 'assistant' && text.includes('<canvas')) {
messageElement.innerHTML = text;
} else {
messageElement.innerHTML = text.replace(/\n/g, '<br>');
}
chatMessages.appendChild(messageElement);
chatMessages.scrollTop = chatMessages.scrollHeight;
}
function processMessage(text) {
const trimmedText = text.trim();
if (!trimmedText) return;
addMessage(trimmedText, 'user');
userInput.value = '';
const task = taskMap[trimmedText];
setTimeout(() => {
const response = assistantResponses[task] || "I'm a demo assistant. My capabilities are limited to the quick actions for now. Please select one of the options or upload a file.";
addMessage(response, 'assistant');
if (task === 'generate_sales_chart') {
setTimeout(renderChart, 10);
}
}, 1200);
}
function analyzeFile(file) {
const reader = new FileReader();
reader.onload = (e) => {
const content = e.target.result;
let analysis = '';
if (file.type === 'text/csv') {
const lines = content.split('\n').filter(line => line.trim() !== '');
const rowCount = lines.length;
const columnCount = lines.length > 0 ? lines[0].split(',').length : 0;
analysis = `**File Analysis: ${file.name}**\n- **Type:** CSV\n- **Rows:** ${rowCount}\n- **Columns:** ${columnCount}`;
} else { // Default to text
const lineCount = content.split('\n').length;
const wordCount = content.split(/\s+/).filter(Boolean).length;
analysis = `**File Analysis: ${file.name}**\n- **Type:** Text File\n- **Lines:** ${lineCount}\n- **Words:** ${wordCount}`;
}
addMessage(analysis, 'assistant');
};
reader.readAsText(file);
}
fileInput.addEventListener('change', (event) => {
const file = event.target.files[0];
if (file) {
addMessage(`You uploaded ${file.name}. Analyzing...`, 'user');
setTimeout(() => analyzeFile(file), 1200);
}
});
quickActionsContainer.addEventListener('click', (event) => {
if (event.target.classList.contains('quick-action')) {
processMessage(event.target.textContent);
}
});
sendButton.addEventListener('click', () => processMessage(userInput.value));
userInput.addEventListener('keypress', (event) => {
if (event.key === 'Enter') {
processMessage(userInput.value);
}
});
// Lava lamp animation script
const canvas = document.getElementById('lava-canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
class Blob {
constructor(x, y, size, color) {
this.x = x;
this.y = y;
this.size = size;
this.color = color;
this.vx = (Math.random() - 0.5) * 0.8;
this.vy = (Math.random() - 0.5) * 0.8;
this.numPoints = Math.floor(Math.random() * 5) + 5;
this.radii = [];
this.angles = [];
this.angleOffsets = [];
for (let i = 0; i < this.numPoints; i++) {
this.radii.push(Math.random() * 0.2 + 0.9);
this.angles.push((i / this.numPoints) * Math.PI * 2);
this.angleOffsets.push(Math.random() * Math.PI * 2);
}
this.time = Math.random() * 1000;
}
update() {
this.x += this.vx;
this.y += this.vy;
this.time += 0.01;
if (this.x < this.size || this.x > canvas.width - this.size) this.vx *= -1;
if (this.y < this.size || this.y > canvas.height - this.size) this.vy *= -1;
for (let i = 0; i < this.numPoints; i++) {
const phase = Math.sin(this.time + this.angleOffsets[i]);
this.radii[i] = 0.9 + 0.1 * phase;
}
}
draw() {
ctx.save();
ctx.translate(this.x, this.y);
ctx.fillStyle = this.color;
ctx.beginPath();
const startAngle = this.angles[this.numPoints - 1];
const startRadius = this.radii[this.numPoints - 1] * this.size;
ctx.moveTo(Math.cos(startAngle) * startRadius, Math.sin(startAngle) * startRadius);
for (let i = 0; i < this.numPoints; i++) {
const radius = this.radii[i] * this.size;
const nextRadius = this.radii[(i + 1) % this.numPoints] * this.size;
const angle = this.angles[i];
const nextAngle = this.angles[(i + 1) % this.numPoints];
const xc = (Math.cos(angle) * radius + Math.cos(nextAngle) * nextRadius) / 2;
const yc = (Math.sin(angle) * radius + Math.sin(nextAngle) * nextRadius) / 2;
ctx.quadraticCurveTo(Math.cos(angle) * radius, Math.sin(angle) * radius, xc, yc);
}
ctx.closePath();
ctx.fill();
ctx.restore();
}
}
let blobs = [];
const colors = [
'rgba(234, 234, 234, 0.4)',
'rgba(209, 227, 243, 0.4)',
'rgba(192, 217, 234, 0.4)',
'rgba(175, 207, 225, 0.4)'
];
function init() {
blobs = [];
let numBlobs = Math.floor(window.innerWidth / 150);
for (let i = 0; i < numBlobs; i++) {
let size = Math.random() * 80 + 80;
let x = Math.random() * (canvas.width - size * 2) + size;
let y = Math.random() * (canvas.height - size * 2) + size;
let color = colors[i % colors.length];
blobs.push(new Blob(x, y, size, color));
}
}
function animate() {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'lighter';
blobs.forEach(blob => {
blob.update();
blob.draw();
});
}
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
init();
});
init();
animate();
</script>
</body>
</html>