Spaces:
Running
Running
make the pdf which is going to be generated more visually appealing with matching layout and professional touch - Initial Deployment
bb3183e
verified
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Aqua Builder | Green Souq Aquariums</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<style> | |
.tooltip { | |
position: relative; | |
display: inline-block; | |
} | |
.tooltip .tooltiptext { | |
visibility: hidden; | |
width: 200px; | |
background-color: #333; | |
color: #fff; | |
text-align: center; | |
border-radius: 6px; | |
padding: 5px; | |
position: absolute; | |
z-index: 1; | |
bottom: 125%; | |
left: 50%; | |
margin-left: -100px; | |
opacity: 0; | |
transition: opacity 0.3s; | |
} | |
.tooltip:hover .tooltiptext { | |
visibility: visible; | |
opacity: 1; | |
} | |
input[type=number]::-webkit-inner-spin-button, | |
input[type=number]::-webkit-outer-spin-button { | |
-webkit-appearance: none; | |
margin: 0; | |
} | |
.summary-item { | |
transition: all 0.3s ease; | |
} | |
.summary-item:hover { | |
background-color: #f0fdf4; | |
} | |
</style> | |
</head> | |
<body class="bg-gray-50"> | |
<div class="container mx-auto px-4 py-8 max-w-6xl"> | |
<!-- Company Header --> | |
<div class="bg-green-700 text-white py-3 px-4 mb-8 rounded-lg shadow-md"> | |
<div class="container mx-auto flex flex-col md:flex-row justify-between items-center"> | |
<div class="flex items-center mb-2 md:mb-0"> | |
<div class="bg-white text-green-700 p-2 rounded-full mr-3"> | |
<i class="fas fa-fish text-xl"></i> | |
</div> | |
<h1 class="text-xl md:text-2xl font-bold">Green Souq Aquariums</h1> | |
</div> | |
<div class="text-sm md:text-base"> | |
<i class="fas fa-map-marker-alt mr-1"></i> Doha, Qatar | |
</div> | |
</div> | |
</div> | |
<!-- App Header --> | |
<header class="mb-8 text-center"> | |
<div class="flex justify-center mb-4"> | |
<div class="bg-green-600 text-white p-4 rounded-full shadow-lg"> | |
<i class="fas fa-water text-4xl"></i> | |
</div> | |
</div> | |
<h1 class="text-3xl md:text-4xl font-bold text-green-800 mb-2">Aqua Builder</h1> | |
<p class="text-lg text-gray-600">Build your dream aquarium and get an instant quotation</p> | |
</header> | |
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8"> | |
<!-- Configuration Panel --> | |
<div class="lg:col-span-2 bg-white rounded-xl shadow-md p-6"> | |
<h2 class="text-2xl font-semibold text-green-700 mb-6 border-b pb-2">Aquarium Configuration</h2> | |
<!-- Dimensions Section --> | |
<div class="mb-8"> | |
<h3 class="text-xl font-medium text-gray-800 mb-4 flex items-center"> | |
<i class="fas fa-ruler-combined mr-2 text-green-600"></i> Aquarium Dimensions | |
</h3> | |
<div class="grid grid-cols-1 md:grid-cols-3 gap-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Length (cm)</label> | |
<input type="number" id="length" min="30" value="30" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Breadth (cm)</label> | |
<input type="number" id="breadth" min="30" value="30" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Height (cm)</label> | |
<input type="number" id="height" min="30" value="30" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"> | |
</div> | |
</div> | |
<div id="volume-display" class="mt-3 text-sm text-gray-600"> | |
Volume: 27 liters (30×30×30 cm) | |
</div> | |
</div> | |
<!-- Add-Ons Section --> | |
<div class="mb-8"> | |
<h3 class="text-xl font-medium text-gray-800 mb-4 flex items-center"> | |
<i class="fas fa-plus-circle mr-2 text-green-600"></i> Add-On Products | |
</h3> | |
<!-- Filters --> | |
<div class="mb-6"> | |
<h4 class="text-lg font-medium text-gray-700 mb-3 flex items-center"> | |
<i class="fas fa-filter mr-2 text-blue-500"></i> Filters | |
</h4> | |
<div class="grid grid-cols-1 md:grid-cols-3 gap-3"> | |
<div class="flex items-center"> | |
<input type="radio" id="filter-hangon" name="filter" value="Hang-on Filter" data-price="50" class="mr-2"> | |
<label for="filter-hangon" class="flex-1">Hang-on Filter <span class="text-green-600 font-medium">50 QAR</span></label> | |
</div> | |
<div class="flex items-center"> | |
<input type="radio" id="filter-internal" name="filter" value="Internal Filter" data-price="50" class="mr-2"> | |
<label for="filter-internal" class="flex-1">Internal Filter <span class="text-green-600 font-medium">50 QAR</span></label> | |
</div> | |
<div class="flex items-center"> | |
<input type="radio" id="filter-canister" name="filter" value="Canister Filter" data-price="200" class="mr-2"> | |
<label for="filter-canister" class="flex-1">Canister Filter <span class="text-green-600 font-medium">200 QAR</span></label> | |
</div> | |
</div> | |
</div> | |
<!-- Lights --> | |
<div class="mb-6"> | |
<h4 class="text-lg font-medium text-gray-700 mb-3 flex items-center"> | |
<i class="fas fa-lightbulb mr-2 text-yellow-400"></i> Lights | |
</h4> | |
<div class="grid grid-cols-1 md:grid-cols-3 gap-3"> | |
<div class="flex items-center"> | |
<input type="radio" id="light-side" name="light" value="Side Light" data-price="50" class="mr-2"> | |
<label for="light-side" class="flex-1">Side Light <span class="text-green-600 font-medium">50 QAR</span></label> | |
</div> | |
<div class="flex items-center"> | |
<input type="radio" id="light-spot" name="light" value="Spot Light" data-price="30" class="mr-2"> | |
<label for="light-spot" class="flex-1">Spot Light <span class="text-green-600 font-medium">30 QAR</span></label> | |
</div> | |
<div class="flex items-center"> | |
<input type="radio" id="light-spectrum" name="light" value="Spectrum Light" data-price="90" class="mr-2"> | |
<label for="light-spectrum" class="flex-1">Spectrum Light <span class="text-green-600 font-medium">90 QAR</span></label> | |
</div> | |
</div> | |
</div> | |
<!-- Stones --> | |
<div class="mb-6"> | |
<h4 class="text-lg font-medium text-gray-700 mb-3 flex items-center"> | |
<i class="fas fa-mountain mr-2 text-gray-500"></i> Stones | |
</h4> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Dragon Stone (15 QAR/kg)</label> | |
<div class="flex"> | |
<input type="number" id="dragon-stone-qty" min="0" value="0" class="w-20 px-3 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-green-500"> | |
<span class="inline-flex items-center px-3 rounded-r-md bg-gray-50 text-gray-500">kg</span> | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Seriyu Stone (12 QAR/kg)</label> | |
<div class="flex"> | |
<input type="number" id="seriyu-stone-qty" min="0" value="0" class="w-20 px-3 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-green-500"> | |
<span class="inline-flex items-center px-3 rounded-r-md bg-gray-50 text-gray-500">kg</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Driftwood --> | |
<div class="mb-6"> | |
<h4 class="text-lg font-medium text-gray-700 mb-3 flex items-center"> | |
<i class="fas fa-tree mr-2 text-amber-800"></i> Driftwood | |
</h4> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Black Wood (70 QAR/kg)</label> | |
<div class="flex"> | |
<input type="number" id="black-wood-qty" min="0" value="0" class="w-20 px-3 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-green-500"> | |
<span class="inline-flex items-center px-3 rounded-r-md bg-gray-50 text-gray-500">kg</span> | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Normal Wood (90 QAR/kg)</label> | |
<div class="flex"> | |
<input type="number" id="normal-wood-qty" min="0" value="0" class="w-20 px-3 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-green-500"> | |
<span class="inline-flex items-center px-3 rounded-r-md bg-gray-50 text-gray-500">kg</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Plants --> | |
<div class="mb-6"> | |
<h4 class="text-lg font-medium text-gray-700 mb-3 flex items-center"> | |
<i class="fas fa-leaf mr-2 text-green-500"></i> Plants | |
</h4> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Moss (10 QAR/piece)</label> | |
<div class="flex"> | |
<input type="number" id="moss-qty" min="0" value="0" class="w-20 px-3 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-green-500"> | |
<span class="inline-flex items-center px-3 rounded-r-md bg-gray-50 text-gray-500">pieces</span> | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Hanubias (30 QAR/piece)</label> | |
<div class="flex"> | |
<input type="number" id="hanubias-qty" min="0" value="0" class="w-20 px-3 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-green-500"> | |
<span class="inline-flex items-center px-3 rounded-r-md bg-gray-50 text-gray-500">pieces</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Soil --> | |
<div class="mb-6"> | |
<h4 class="text-lg font-medium text-gray-700 mb-3 flex items-center"> | |
<i class="fas fa-seedling mr-2 text-amber-600"></i> Soil | |
</h4> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Week Aqua Soil (40 QAR/3L)</label> | |
<div class="flex"> | |
<input type="number" id="week-aqua-qty" min="0" value="0" class="w-20 px-3 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-green-500"> | |
<span class="inline-flex items-center px-3 rounded-r-md bg-gray-50 text-gray-500">packs</span> | |
</div> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Amazonia Soil (40 QAR/3L)</label> | |
<div class="flex"> | |
<input type="number" id="amazonia-qty" min="0" value="0" class="w-20 px-3 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-green-500"> | |
<span class="inline-flex items-center px-3 rounded-r-md bg-gray-50 text-gray-500">packs</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Finish Options --> | |
<div class="mb-6"> | |
<h4 class="text-lg font-medium text-gray-700 mb-3 flex items-center"> | |
<i class="fas fa-gem mr-2 text-blue-400"></i> Finish Options | |
</h4> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-3"> | |
<div class="flex items-center"> | |
<input type="radio" id="finish-unpolished" name="finish" value="Unpolished" data-price="0" checked class="mr-2"> | |
<label for="finish-unpolished" class="flex-1">Unpolished <span class="text-green-600 font-medium">No extra charge</span></label> | |
</div> | |
<div class="flex items-center"> | |
<input type="radio" id="finish-polished" name="finish" value="Polished Glass" data-price="40" class="mr-2"> | |
<label for="finish-polished" class="flex-1">Polished Glass <span class="text-green-600 font-medium">+40 QAR</span></label> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Customer Info --> | |
<div class="mb-6"> | |
<h3 class="text-xl font-medium text-gray-800 mb-4 flex items-center"> | |
<i class="fas fa-user-circle mr-2 text-green-600"></i> Your Information (Optional) | |
</h3> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Name</label> | |
<input type="text" id="customer-name" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500" placeholder="Enter your name"> | |
</div> | |
</div> | |
</div> | |
<!-- Summary Panel --> | |
<div class="lg:col-span-1"> | |
<div class="bg-white rounded-xl shadow-md p-6 sticky top-4"> | |
<h2 class="text-2xl font-semibold text-green-700 mb-6 border-b pb-2">Quotation Summary</h2> | |
<div id="summary-content" class="mb-6"> | |
<div class="summary-item mb-3 pb-3 border-b"> | |
<div class="flex justify-between"> | |
<span class="font-medium">Base Tank (27L)</span> | |
<span>70.00 QAR</span> | |
</div> | |
<div class="text-sm text-gray-500 mt-1">30×30×30 cm</div> | |
</div> | |
<div id="additional-volume" class="hidden summary-item mb-3 pb-3 border-b"> | |
<div class="flex justify-between"> | |
<span class="font-medium">Additional Volume</span> | |
<span>0.00 QAR</span> | |
</div> | |
</div> | |
<div id="filter-summary" class="hidden summary-item mb-3 pb-3 border-b"> | |
<div class="flex justify-between"> | |
<span class="font-medium">Filter</span> | |
<span>0.00 QAR</span> | |
</div> | |
</div> | |
<div id="light-summary" class="hidden summary-item mb-3 pb-3 border-b"> | |
<div class="flex justify-between"> | |
<span class="font-medium">Light</span> | |
<span>0.00 QAR</span> | |
</div> | |
</div> | |
<div id="stones-summary" class="hidden summary-item mb-3 pb-3 border-b"> | |
<div class="flex justify-between"> | |
<span class="font-medium">Stones</span> | |
<span>0.00 QAR</span> | |
</div> | |
</div> | |
<div id="driftwood-summary" class="hidden summary-item mb-3 pb-3 border-b"> | |
<div class="flex justify-between"> | |
<span class="font-medium">Driftwood</span> | |
<span>0.00 QAR</span> | |
</div> | |
</div> | |
<div id="plants-summary" class="hidden summary-item mb-3 pb-3 border-b"> | |
<div class="flex justify-between"> | |
<span class="font-medium">Plants</span> | |
<span>0.00 QAR</span> | |
</div> | |
</div> | |
<div id="soil-summary" class="hidden summary-item mb-3 pb-3 border-b"> | |
<div class="flex justify-between"> | |
<span class="font-medium">Soil</span> | |
<span>0.00 QAR</span> | |
</div> | |
</div> | |
<div id="finish-summary" class="hidden summary-item mb-3 pb-3 border-b"> | |
<div class="flex justify-between"> | |
<span class="font-medium">Finish</span> | |
<span>0.00 QAR</span> | |
</div> | |
</div> | |
</div> | |
<div class="bg-green-50 p-4 rounded-lg mb-6"> | |
<div class="flex justify-between items-center"> | |
<span class="font-bold text-lg text-green-800">Total</span> | |
<span id="grand-total" class="font-bold text-2xl text-green-800">70.00 QAR</span> | |
</div> | |
</div> | |
<div class="grid grid-cols-1 gap-3"> | |
<button id="download-btn" class="w-full bg-green-600 hover:bg-green-700 text-white font-medium py-3 px-4 rounded-md flex items-center justify-center transition duration-300"> | |
<i class="fas fa-file-pdf mr-2"></i> Download Quotation (PDF) | |
</button> | |
<button id="whatsapp-btn" class="w-full bg-green-500 hover:bg-green-600 text-white font-medium py-3 px-4 rounded-md flex items-center justify-center transition duration-300"> | |
<i class="fab fa-whatsapp mr-2"></i> Share via WhatsApp | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Hidden div for PDF generation --> | |
<div id="pdf-content" class="hidden p-8" style="width: 210mm; min-height: 297mm; background: white; margin: 0 auto;"> | |
<div class="flex justify-between items-center mb-6 border-b pb-4"> | |
<div> | |
<h1 class="text-3xl font-bold text-green-800">Green Souq Aquariums</h1> | |
<p class="text-gray-600">Doha, Qatar</p> | |
</div> | |
<div class="text-right"> | |
<p class="text-gray-600">Date: <span id="pdf-date"></span></p> | |
<p class="text-gray-600">Quotation #: <span id="pdf-quote-id"></span></p> | |
</div> | |
</div> | |
<div class="mb-6"> | |
<h2 class="text-xl font-semibold text-green-700 mb-2">Customer Information</h2> | |
<p id="pdf-customer-name" class="text-gray-700">Name: Not provided</p> | |
</div> | |
<h2 class="text-xl font-semibold text-green-700 mb-2">Aquarium Specifications</h2> | |
<table class="w-full mb-6"> | |
<thead> | |
<tr class="bg-green-100"> | |
<th class="text-left py-2 px-4">Item</th> | |
<th class="text-right py-2 px-4">Quantity</th> | |
<th class="text-right py-2 px-4">Price</th> | |
<th class="text-right py-2 px-4">Total</th> | |
</tr> | |
</thead> | |
<tbody id="pdf-items"> | |
<tr class="border-b"> | |
<td class="py-2 px-4">Base Tank</td> | |
<td class="text-right py-2 px-4" id="pdf-tank-size">30×30×30 cm</td> | |
<td class="text-right py-2 px-4">70.00 QAR</td> | |
<td class="text-right py-2 px-4">70.00 QAR</td> | |
</tr> | |
</tbody> | |
</table> | |
<div class="flex justify-end mb-8"> | |
<div class="w-64"> | |
<div class="flex justify-between py-2 border-b"> | |
<span class="font-medium">Subtotal</span> | |
<span id="pdf-subtotal">70.00 QAR</span> | |
</div> | |
<div class="flex justify-between py-2 font-bold text-lg"> | |
<span>Total</span> | |
<span id="pdf-total">70.00 QAR</span> | |
</div> | |
</div> | |
</div> | |
<div class="text-xs text-gray-500 border-t pt-4"> | |
<p class="font-medium mb-2">Terms & Conditions:</p> | |
<p>1. Prices are valid for 30 days from the date of this quotation.</p> | |
<p>2. Delivery charges may apply depending on location.</p> | |
<p>3. Installation services available at additional cost.</p> | |
<p>4. Custom designs may require additional time and cost.</p> | |
</div> | |
<div class="mt-8 pt-4 border-t text-center text-sm text-gray-500"> | |
<p>Green Souq Aquariums - Doha, Qatar</p> | |
<p>Phone: +974 3138 8895 | Web: www.greensouq.qa</p> | |
<p>© 2025 Green Souq Aquariums. All rights reserved.</p> | |
</div> | |
</div> | |
<script> | |
// Check if required libraries are loaded | |
if (!window.jspdf || !window.html2canvas) { | |
console.error('Required PDF libraries not loaded'); | |
document.getElementById('download-btn').disabled = true; | |
document.getElementById('download-btn').innerHTML = '<i class="fas fa-exclamation-triangle mr-2"></i> PDF Unavailable'; | |
document.getElementById('download-btn').classList.add('bg-gray-400'); | |
document.getElementById('download-btn').classList.remove('bg-green-600', 'hover:bg-green-700'); | |
} | |
// Initialize jsPDF | |
const { jsPDF } = window.jspdf; | |
// DOM Elements | |
const lengthInput = document.getElementById('length'); | |
const breadthInput = document.getElementById('breadth'); | |
const heightInput = document.getElementById('height'); | |
const volumeDisplay = document.getElementById('volume-display'); | |
// Pricing variables | |
const baseVolume = 27; // liters (30x30x30 cm) | |
const basePrice = 70; // QAR | |
const additionalLiterPrice = 2.59; // QAR per liter over base | |
// Summary elements | |
const additionalVolumeSummary = document.getElementById('additional-volume'); | |
const filterSummary = document.getElementById('filter-summary'); | |
const lightSummary = document.getElementById('light-summary'); | |
const stonesSummary = document.getElementById('stones-summary'); | |
const driftwoodSummary = document.getElementById('driftwood-summary'); | |
const plantsSummary = document.getElementById('plants-summary'); | |
const soilSummary = document.getElementById('soil-summary'); | |
const finishSummary = document.getElementById('finish-summary'); | |
const grandTotalElement = document.getElementById('grand-total'); | |
// Buttons | |
const downloadBtn = document.getElementById('download-btn'); | |
const whatsappBtn = document.getElementById('whatsapp-btn'); | |
// PDF elements | |
const pdfContent = document.getElementById('pdf-content'); | |
// Initialize calculation | |
let currentVolume = baseVolume; | |
let currentDimensions = '30×30×30 cm'; | |
let currentTotal = basePrice; | |
let selectedFilter = null; | |
let selectedLight = null; | |
let selectedFinish = 'Unpolished'; | |
// Event listeners for dimensions | |
[lengthInput, breadthInput, heightInput].forEach(input => { | |
input.addEventListener('input', calculateVolume); | |
}); | |
// Event listeners for radio buttons | |
document.querySelectorAll('input[type="radio"]').forEach(radio => { | |
radio.addEventListener('change', updateSelection); | |
}); | |
// Event listeners for quantity inputs | |
document.querySelectorAll('input[type="number"]:not(#length):not(#breadth):not(#height):not(#customer-name)').forEach(input => { | |
input.addEventListener('input', calculateTotal); | |
}); | |
// Download button | |
downloadBtn.addEventListener('click', generatePDF); | |
// WhatsApp button | |
whatsappBtn.addEventListener('click', shareOnWhatsApp); | |
// Initial calculation | |
calculateTotal(); | |
// Functions | |
function calculateVolume() { | |
// Ensure minimum 30cm for each dimension | |
let length = Math.max(30, parseInt(lengthInput.value) || 30); | |
let breadth = Math.max(30, parseInt(breadthInput.value) || 30); | |
let height = Math.max(30, parseInt(heightInput.value) || 30); | |
// Update input values | |
lengthInput.value = length; | |
breadthInput.value = breadth; | |
heightInput.value = height; | |
// Calculate volume in cm³ and convert to liters | |
const volumeCm3 = length * breadth * height; | |
const volumeLiters = volumeCm3 / 1000; | |
currentVolume = volumeLiters; | |
currentDimensions = `${length}×${breadth}×${height} cm`; | |
// Update display | |
volumeDisplay.textContent = `Volume: ${volumeLiters.toFixed(1)} liters (${length}×${breadth}×${height} cm)`; | |
// Recalculate total | |
calculateTotal(); | |
} | |
function updateSelection(e) { | |
if (e.target.name === 'filter') { | |
selectedFilter = { | |
name: e.target.value, | |
price: parseFloat(e.target.dataset.price) | |
}; | |
} else if (e.target.name === 'light') { | |
selectedLight = { | |
name: e.target.value, | |
price: parseFloat(e.target.dataset.price) | |
}; | |
} else if (e.target.name === 'finish') { | |
selectedFinish = e.target.value; | |
} | |
calculateTotal(); | |
} | |
function calculateTotal() { | |
// Base tank price | |
let additionalLiters = Math.max(0, currentVolume - baseVolume); | |
let additionalPrice = additionalLiters * additionalLiterPrice; | |
let tankPrice = basePrice + additionalPrice; | |
// Filter price | |
let filterPrice = selectedFilter ? selectedFilter.price : 0; | |
// Light price | |
let lightPrice = selectedLight ? selectedLight.price : 0; | |
// Stones | |
let dragonStoneQty = parseInt(document.getElementById('dragon-stone-qty').value) || 0; | |
let seriyuStoneQty = parseInt(document.getElementById('seriyu-stone-qty').value) || 0; | |
let stonesPrice = (dragonStoneQty * 15) + (seriyuStoneQty * 12); | |
let stonesText = []; | |
if (dragonStoneQty > 0) stonesText.push(`${dragonStoneQty}kg Dragon Stone`); | |
if (seriyuStoneQty > 0) stonesText.push(`${seriyuStoneQty}kg Seriyu Stone`); | |
// Driftwood | |
let blackWoodQty = parseInt(document.getElementById('black-wood-qty').value) || 0; | |
let normalWoodQty = parseInt(document.getElementById('normal-wood-qty').value) || 0; | |
let driftwoodPrice = (blackWoodQty * 70) + (normalWoodQty * 90); | |
let driftwoodText = []; | |
if (blackWoodQty > 0) driftwoodText.push(`${blackWoodQty}kg Black Wood`); | |
if (normalWoodQty > 0) driftwoodText.push(`${normalWoodQty}kg Normal Wood`); | |
// Plants | |
let mossQty = parseInt(document.getElementById('moss-qty').value) || 0; | |
let hanubiasQty = parseInt(document.getElementById('hanubias-qty').value) || 0; | |
let plantsPrice = (mossQty * 10) + (hanubiasQty * 30); | |
let plantsText = []; | |
if (mossQty > 0) plantsText.push(`${mossQty} Moss`); | |
if (hanubiasQty > 0) plantsText.push(`${hanubiasQty} Hanubias`); | |
// Soil | |
let weekAquaQty = parseInt(document.getElementById('week-aqua-qty').value) || 0; | |
let amazoniaQty = parseInt(document.getElementById('amazonia-qty').value) || 0; | |
let soilPrice = (weekAquaQty * 40) + (amazoniaQty * 40); | |
let soilText = []; | |
if (weekAquaQty > 0) soilText.push(`${weekAquaQty} Week Aqua Soil`); | |
if (amazoniaQty > 0) soilText.push(`${amazoniaQty} Amazonia Soil`); | |
// Finish | |
let finishPrice = selectedFinish === 'Polished Glass' ? 40 : 0; | |
// Calculate total | |
currentTotal = tankPrice + filterPrice + lightPrice + stonesPrice + driftwoodPrice + plantsPrice + soilPrice + finishPrice; | |
// Update summary display | |
updateSummaryDisplay( | |
additionalLiters, additionalPrice, | |
selectedFilter, filterPrice, | |
selectedLight, lightPrice, | |
stonesText, stonesPrice, | |
driftwoodText, driftwoodPrice, | |
plantsText, plantsPrice, | |
soilText, soilPrice, | |
selectedFinish, finishPrice | |
); | |
// Update grand total | |
grandTotalElement.textContent = currentTotal.toFixed(2) + ' QAR'; | |
} | |
function updateSummaryDisplay( | |
additionalLiters, additionalPrice, | |
filter, filterPrice, | |
light, lightPrice, | |
stonesText, stonesPrice, | |
driftwoodText, driftwoodPrice, | |
plantsText, plantsPrice, | |
soilText, soilPrice, | |
finish, finishPrice | |
) { | |
// Base tank and additional volume | |
if (additionalLiters > 0) { | |
additionalVolumeSummary.classList.remove('hidden'); | |
additionalVolumeSummary.innerHTML = ` | |
<div class="flex justify-between"> | |
<span class="font-medium">Additional Volume (${additionalLiters.toFixed(1)}L)</span> | |
<span>${additionalPrice.toFixed(2)} QAR</span> | |
</div> | |
`; | |
} else { | |
additionalVolumeSummary.classList.add('hidden'); | |
} | |
// Filter | |
if (filter) { | |
filterSummary.classList.remove('hidden'); | |
filterSummary.innerHTML = ` | |
<div class="flex justify-between"> | |
<span class="font-medium">${filter.name}</span> | |
<span>${filterPrice.toFixed(2)} QAR</span> | |
</div> | |
`; | |
} else { | |
filterSummary.classList.add('hidden'); | |
} | |
// Light | |
if (light) { | |
lightSummary.classList.remove('hidden'); | |
lightSummary.innerHTML = ` | |
<div class="flex justify-between"> | |
<span class="font-medium">${light.name}</span> | |
<span>${lightPrice.toFixed(2)} QAR</span> | |
</div> | |
`; | |
} else { | |
lightSummary.classList.add('hidden'); | |
} | |
// Stones | |
if (stonesText.length > 0) { | |
stonesSummary.classList.remove('hidden'); | |
stonesSummary.innerHTML = ` | |
<div class="flex justify-between"> | |
<span class="font-medium">${stonesText.join(', ')}</span> | |
<span>${stonesPrice.toFixed(2)} QAR</span> | |
</div> | |
`; | |
} else { | |
stonesSummary.classList.add('hidden'); | |
} | |
// Driftwood | |
if (driftwoodText.length > 0) { | |
driftwoodSummary.classList.remove('hidden'); | |
driftwoodSummary.innerHTML = ` | |
<div class="flex justify-between"> | |
<span class="font-medium">${driftwoodText.join(', ')}</span> | |
<span>${driftwoodPrice.toFixed(2)} QAR</span> | |
</div> | |
`; | |
} else { | |
driftwoodSummary.classList.add('hidden'); | |
} | |
// Plants | |
if (plantsText.length > 0) { | |
plantsSummary.classList.remove('hidden'); | |
plantsSummary.innerHTML = ` | |
<div class="flex justify-between"> | |
<span class="font-medium">${plantsText.join(', ')}</span> | |
<span>${plantsPrice.toFixed(2)} QAR</span> | |
</div> | |
`; | |
} else { | |
plantsSummary.classList.add('hidden'); | |
} | |
// Soil | |
if (soilText.length > 0) { | |
soilSummary.classList.remove('hidden'); | |
soilSummary.innerHTML = ` | |
<div class="flex justify-between"> | |
<span class="font-medium">${soilText.join(', ')}</span> | |
<span>${soilPrice.toFixed(2)} QAR</span> | |
</div> | |
`; | |
} else { | |
soilSummary.classList.add('hidden'); | |
} | |
// Finish | |
if (finishPrice > 0) { | |
finishSummary.classList.remove('hidden'); | |
finishSummary.innerHTML = ` | |
<div class="flex justify-between"> | |
<span class="font-medium">${finish}</span> | |
<span>${finishPrice.toFixed(2)} QAR</span> | |
</div> | |
`; | |
} else { | |
finishSummary.classList.add('hidden'); | |
} | |
} | |
function generatePDF() { | |
const downloadBtn = document.getElementById('download-btn'); | |
const originalText = downloadBtn.innerHTML; | |
downloadBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Generating PDF...'; | |
downloadBtn.disabled = true; | |
try { | |
// Create a new PDF document | |
const doc = new jsPDF(); | |
// Add header with logo and info | |
doc.setFillColor(22, 163, 74); // Green-600 | |
doc.rect(0, 0, 210, 30, 'F'); | |
// Add logo text | |
doc.setFontSize(20); | |
doc.setTextColor(255, 255, 255); | |
doc.text('Green Souq Trading', 105, 20, { align: 'center' }); | |
// Add quotation title | |
doc.setFontSize(16); | |
doc.setTextColor(22, 163, 74); // Green-600 | |
doc.text('Aquarium Quotation', 105, 45, { align: 'center' }); | |
// Add customer info section | |
doc.setFontSize(12); | |
doc.setTextColor(0, 0, 0); | |
const customerName = document.getElementById('customer-name').value || 'Not provided'; | |
const today = new Date(); | |
doc.setDrawColor(22, 163, 74); | |
doc.setLineWidth(0.5); | |
doc.line(15, 55, 195, 55); | |
doc.text(`Customer: ${customerName}`, 15, 65); | |
doc.text(`Date: ${today.toLocaleDateString()}`, 15, 75); | |
doc.text(`Quotation #: ${Math.floor(100000 + Math.random() * 900000)}`, 15, 85); | |
// Add aquarium details section | |
doc.setFontSize(14); | |
doc.setTextColor(22, 163, 74); | |
doc.text('Aquarium Specifications', 15, 105); | |
doc.setFontSize(12); | |
doc.setTextColor(0, 0, 0); | |
doc.text(`Dimensions: ${currentDimensions}`, 20, 115); | |
doc.text(`Volume: ${currentVolume.toFixed(1)} liters`, 20, 125); | |
// Add items table header | |
doc.setFillColor(240, 253, 244); // Green-50 | |
doc.rect(15, 135, 180, 10, 'F'); | |
doc.setFontSize(12); | |
doc.setTextColor(0, 0, 0); | |
doc.setFont(undefined, 'bold'); | |
doc.text('Item', 20, 142); | |
doc.text('Price', 180, 142, { align: 'right' }); | |
// Add items | |
let yPosition = 150; | |
doc.setFont(undefined, 'normal'); | |
// Base tank | |
doc.text('Base Tank', 20, yPosition); | |
doc.text(`${basePrice.toFixed(2)} QAR`, 180, yPosition, { align: 'right' }); | |
yPosition += 10; | |
// Additional volume if any | |
const additionalLiters = Math.max(0, currentVolume - baseVolume); | |
if (additionalLiters > 0) { | |
const additionalPrice = additionalLiters * additionalLiterPrice; | |
doc.text(`Additional Volume (${additionalLiters.toFixed(1)}L)`, 20, yPosition); | |
doc.text(`${additionalPrice.toFixed(2)} QAR`, 180, yPosition, { align: 'right' }); | |
yPosition += 10; | |
} | |
// Add selected items | |
if (selectedFilter) { | |
doc.text(`${selectedFilter.name}`, 20, yPosition); | |
doc.text(`${selectedFilter.price.toFixed(2)} QAR`, 180, yPosition, { align: 'right' }); | |
yPosition += 10; | |
} | |
if (selectedLight) { | |
doc.text(`${selectedLight.name}`, 20, yPosition); | |
doc.text(`${selectedLight.price.toFixed(2)} QAR`, 180, yPosition, { align: 'right' }); | |
yPosition += 10; | |
} | |
// Add stones, driftwood, plants, etc. if any | |
const dragonStoneQty = parseInt(document.getElementById('dragon-stone-qty').value) || 0; | |
const seriyuStoneQty = parseInt(document.getElementById('seriyu-stone-qty').value) || 0; | |
if (dragonStoneQty > 0) { | |
doc.text(`Dragon Stone (${dragonStoneQty}kg)`, 20, yPosition); | |
doc.text(`${(dragonStoneQty * 15).toFixed(2)} QAR`, 180, yPosition, { align: 'right' }); | |
yPosition += 10; | |
} | |
if (seriyuStoneQty > 0) { | |
doc.text(`Seriyu Stone (${seriyuStoneQty}kg)`, 20, yPosition); | |
doc.text(`${(seriyuStoneQty * 12).toFixed(2)} QAR`, 180, yPosition, { align: 'right' }); | |
yPosition += 10; | |
} | |
// Add total section | |
doc.setDrawColor(22, 163, 74); | |
doc.setLineWidth(0.5); | |
doc.line(15, yPosition + 5, 195, yPosition + 5); | |
doc.setFontSize(14); | |
doc.setFont(undefined, 'bold'); | |
doc.text('Total:', 20, yPosition + 15); | |
doc.text(`${currentTotal.toFixed(2)} QAR`, 180, yPosition + 15, { align: 'right' }); | |
// Add footer | |
doc.setFontSize(10); | |
doc.setTextColor(100, 100, 100); | |
doc.text('Thank you for choosing Green Souq Trading!', 105, 280, { align: 'center' }); | |
doc.text('Phone: +974 3138 8895 | Web: www.greensouqtrading.com', 105, 285, { align: 'center' }); | |
// Add validity note | |
doc.setFontSize(8); | |
doc.text('* This quotation is valid for 30 days from the date of issue', 15, 290); | |
// Save the PDF | |
doc.save(`Aquarium_Quote_${today.getTime()}.pdf`); | |
} catch (error) { | |
console.error('PDF generation error:', error); | |
alert('Error generating PDF. Please try again.'); | |
} finally { | |
downloadBtn.innerHTML = originalText; | |
downloadBtn.disabled = false; | |
} | |
} | |
function resetDownloadButton(button, originalText) { | |
button.innerHTML = originalText; | |
button.disabled = false; | |
} | |
function addPdfItem(container, name, quantity, price) { | |
const row = document.createElement('tr'); | |
row.className = 'border-b'; | |
row.innerHTML = ` | |
<td class="py-2 px-4">${name}</td> | |
<td class="text-right py-2 px-4">${quantity}</td> | |
<td class="text-right py-2 px-4">${price.toFixed(2)} QAR</td> | |
<td class="text-right py-2 px-4">${price.toFixed(2)} QAR</td> | |
`; | |
container.appendChild(row); | |
} | |
function shareOnWhatsApp() { | |
// Build message | |
let message = `Hello Green Souq Trading, I would like to place an order for this aquarium setup:\n\n`; | |
message += `- Dimensions: ${currentDimensions}\n`; | |
message += `- Volume: ${currentVolume.toFixed(1)} liters\n`; | |
message += `- Total Price: ${currentTotal.toFixed(2)} QAR\n\n`; | |
message += `Accessories:\n`; | |
// Add filter if selected | |
if (selectedFilter) { | |
message += `- ${selectedFilter.name}: ${selectedFilter.price.toFixed(2)} QAR\n`; | |
} | |
// Add light if selected | |
if (selectedLight) { | |
message += `- ${selectedLight.name}: ${selectedLight.price.toFixed(2)} QAR\n`; | |
} | |
// Add stones | |
const dragonStoneQty = parseInt(document.getElementById('dragon-stone-qty').value) || 0; | |
const seriyuStoneQty = parseInt(document.getElementById('seriyu-stone-qty').value) || 0; | |
if (dragonStoneQty > 0) message += `- Dragon Stone: ${dragonStoneQty} kg\n`; | |
if (seriyuStoneQty > 0) message += `- Seriyu Stone: ${seriyuStoneQty} kg\n`; | |
// Add driftwood | |
const blackWoodQty = parseInt(document.getElementById('black-wood-qty').value) || 0; | |
const normalWoodQty = parseInt(document.getElementById('normal-wood-qty').value) || 0; | |
if (blackWoodQty > 0) message += `- Black Wood: ${blackWoodQty} kg\n`; | |
if (normalWoodQty > 0) message += `- Normal Wood: ${normalWoodQty} kg\n`; | |
// Add plants | |
const mossQty = parseInt(document.getElementById('moss-qty').value) || 0; | |
const hanubiasQty = parseInt(document.getElementById('hanubias-qty').value) || 0; | |
if (mossQty > 0) message += `- Moss: ${mossQty} pieces\n`; | |
if (hanubiasQty > 0) message += `- Hanubias: ${hanubiasQty} pieces\n`; | |
// Add soil | |
const weekAquaQty = parseInt(document.getElementById('week-aqua-qty').value) || 0; | |
const amazoniaQty = parseInt(document.getElementById('amazonia-qty').value) || 0; | |
if (weekAquaQty > 0) message += `- Week Aqua Soil: ${weekAquaQty} packs\n`; | |
if (amazoniaQty > 0) message += `- Amazonia Soil: ${amazoniaQty} packs\n`; | |
// Add finish | |
if (selectedFinish === 'Polished Glass') { | |
message += `- Polished Glass: 40.00 QAR\n`; | |
} | |
// Add customer name if provided | |
const customerName = document.getElementById('customer-name').value; | |
if (customerName) { | |
message += `\nCustomer Name: ${customerName}`; | |
} | |
// Encode message for URL | |
const encodedMessage = encodeURIComponent(message); | |
// Open WhatsApp | |
window.open(`https://wa.me/97431388895?text=${encodedMessage}`, '_blank'); | |
} | |
</script> | |
<!-- Footer --> | |
<footer class="bg-gray-100 mt-12 py-6 border-t"> | |
<div class="container mx-auto px-4"> | |
<div class="flex flex-col md:flex-row justify-between items-center"> | |
<div class="mb-4 md:mb-0 text-center md:text-left"> | |
<h3 class="text-lg font-medium text-gray-800 mb-1">Green Souq Aquariums</h3> | |
<p class="text-sm text-gray-600">Doha, Qatar</p> | |
</div> | |
<div class="text-center mb-4 md:mb-0"> | |
<p class="text-gray-700 mb-1"> | |
<i class="fas fa-phone-alt mr-2"></i> +974 3138 8895 | |
</p> | |
<p class="text-gray-700"> | |
<i class="fas fa-globe mr-2"></i> www.greensouqtrading.com | |
</p> | |
</div> | |
<div class="text-center md:text-right"> | |
<p class="text-sm text-gray-500"> | |
© 2025 Green Souq Aquariums. All rights reserved. | |
</p> | |
<p class="text-xs text-gray-400 mt-1"> | |
Developed by Green Souq Aquariums | |
</p> | |
</div> | |
</div> | |
</div> | |
</footer> | |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=gradsyntax/aqua-builder" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |