fr hide default values, app now modular, and easy to add templates + new template
Some checks failed
Deploy static content to Pages / deploy (push) Has been cancelled
Some checks failed
Deploy static content to Pages / deploy (push) Has been cancelled
This commit is contained in:
225
app.js
225
app.js
@@ -1,25 +1,13 @@
|
||||
// Garage Templates Configuration
|
||||
const garageTemplates = {
|
||||
'rs-auto': {
|
||||
name: 'RS AUTO',
|
||||
phone: '775 8999',
|
||||
logo: {
|
||||
type: 'svg',
|
||||
content: `
|
||||
<svg viewBox="0 0 80 80" class="logo-svg">
|
||||
<circle cx="40" cy="40" r="38" fill="none" stroke="#000" stroke-width="2"/>
|
||||
<text x="40" y="18" text-anchor="middle" font-size="8" font-weight="bold">RS AUTO</text>
|
||||
<text x="40" y="45" text-anchor="middle" font-size="24" font-weight="bold">S</text>
|
||||
<path d="M20 50 Q40 35 60 50" fill="none" stroke="#000" stroke-width="2"/>
|
||||
<text x="40" y="58" text-anchor="middle" font-size="6">P:0085037</text>
|
||||
<text x="40" y="70" text-anchor="middle" font-size="8" font-weight="bold">MALDIVES</text>
|
||||
</svg>
|
||||
`
|
||||
}
|
||||
}
|
||||
// Add more garage templates here as needed
|
||||
// Template cache
|
||||
const templateCache = {
|
||||
html: {},
|
||||
css: {}
|
||||
};
|
||||
|
||||
// Current template ID
|
||||
let currentTemplateId = null;
|
||||
let currentBarcodeNumber = null;
|
||||
|
||||
// DOM Elements
|
||||
const form = document.getElementById('stickerForm');
|
||||
const garageSelect = document.getElementById('garage');
|
||||
@@ -30,26 +18,114 @@ const modelNumberInput = document.getElementById('modelNumber');
|
||||
const chassisNumberInput = document.getElementById('chassisNumber');
|
||||
const engineSerialInput = document.getElementById('engineSerial');
|
||||
const engineCapacityInput = document.getElementById('engineCapacity');
|
||||
|
||||
// Preview Elements
|
||||
const previewRegNumber = document.getElementById('previewRegNumber');
|
||||
const previewBarcodeNumber = document.getElementById('previewBarcodeNumber');
|
||||
const previewBarcode = document.getElementById('previewBarcode');
|
||||
const previewFromDate = document.getElementById('previewFromDate');
|
||||
const previewToDate = document.getElementById('previewToDate');
|
||||
const previewModelNumber = document.getElementById('previewModelNumber');
|
||||
const previewChassisNumber = document.getElementById('previewChassisNumber');
|
||||
const previewEngineSerial = document.getElementById('previewEngineSerial');
|
||||
const previewEngineCapacity = document.getElementById('previewEngineCapacity');
|
||||
const previewGarageInfo = document.getElementById('previewGarageInfo');
|
||||
const garageLogo = document.getElementById('garageLogo');
|
||||
const stickerPreview = document.getElementById('stickerPreview');
|
||||
|
||||
// Initialize the application
|
||||
function init() {
|
||||
async function init() {
|
||||
setDefaultDates();
|
||||
await loadTemplateList();
|
||||
setupEventListeners();
|
||||
updatePreview();
|
||||
generateBarcode();
|
||||
generateBarcodeNumber();
|
||||
await loadTemplate(garageSelect.value);
|
||||
}
|
||||
|
||||
// Load template list from index.json
|
||||
async function loadTemplateList() {
|
||||
try {
|
||||
const response = await fetch('templates/index.json');
|
||||
const data = await response.json();
|
||||
|
||||
garageSelect.innerHTML = '';
|
||||
data.templates.forEach(template => {
|
||||
const option = document.createElement('option');
|
||||
option.value = template.id;
|
||||
option.textContent = template.name;
|
||||
garageSelect.appendChild(option);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to load template list:', error);
|
||||
showSnackbar('Failed to load templates', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// Load a specific template (HTML + CSS)
|
||||
async function loadTemplate(templateId) {
|
||||
if (currentTemplateId === templateId && templateCache.html[templateId]) {
|
||||
renderTemplate(templateId);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Load HTML if not cached
|
||||
if (!templateCache.html[templateId]) {
|
||||
const htmlResponse = await fetch(`templates/${templateId}.html`);
|
||||
templateCache.html[templateId] = await htmlResponse.text();
|
||||
}
|
||||
|
||||
// Load CSS if not cached
|
||||
if (!templateCache.css[templateId]) {
|
||||
const cssResponse = await fetch(`templates/${templateId}.css`);
|
||||
templateCache.css[templateId] = await cssResponse.text();
|
||||
|
||||
// Inject CSS into head
|
||||
const styleId = `template-style-${templateId}`;
|
||||
let styleEl = document.getElementById(styleId);
|
||||
if (!styleEl) {
|
||||
styleEl = document.createElement('style');
|
||||
styleEl.id = styleId;
|
||||
document.head.appendChild(styleEl);
|
||||
}
|
||||
styleEl.textContent = templateCache.css[templateId];
|
||||
}
|
||||
|
||||
currentTemplateId = templateId;
|
||||
renderTemplate(templateId);
|
||||
} catch (error) {
|
||||
console.error('Failed to load template:', error);
|
||||
showSnackbar('Failed to load template', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// Render template with current form values
|
||||
function renderTemplate(templateId) {
|
||||
const html = templateCache.html[templateId];
|
||||
if (!html) return;
|
||||
|
||||
// Get current values - show empty placeholders if no input
|
||||
const values = {
|
||||
regNumber: regNumberInput.value ? formatRegNumber(regNumberInput.value) : 'X 0 X 0 0 0 0',
|
||||
barcodeNumber: currentBarcodeNumber || 'XXXXXXXXXX',
|
||||
fromDate: formatDateForDisplay(fromDateInput.value) || 'XX-XX-XXXX',
|
||||
toDate: formatDateForDisplay(toDateInput.value) || 'XX-XX-XXXX',
|
||||
modelNumber: modelNumberInput.value || 'XXX000-000X',
|
||||
chassisNumber: chassisNumberInput.value || 'XXXXXXXXXXXXXXXXX',
|
||||
engineSerial: engineSerialInput.value || 'XXX-XXXXXX',
|
||||
engineCapacity: engineCapacityInput.value || 'XXX.XXX'
|
||||
};
|
||||
|
||||
// Replace placeholders
|
||||
let rendered = html;
|
||||
for (const [key, value] of Object.entries(values)) {
|
||||
rendered = rendered.replace(new RegExp(`{{${key}}}`, 'g'), value);
|
||||
}
|
||||
|
||||
stickerPreview.innerHTML = rendered;
|
||||
|
||||
// Generate barcode
|
||||
const barcodeEl = stickerPreview.querySelector('.barcode');
|
||||
if (barcodeEl && currentBarcodeNumber) {
|
||||
try {
|
||||
JsBarcode(barcodeEl, currentBarcodeNumber, {
|
||||
format: 'CODE128',
|
||||
width: 1.5,
|
||||
height: 25,
|
||||
displayValue: false,
|
||||
margin: 0
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Barcode generation failed:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set default dates (today and 1 year from today)
|
||||
@@ -84,12 +160,19 @@ function formatRegNumber(regNumber) {
|
||||
|
||||
// Generate a random barcode number (10 digits)
|
||||
function generateBarcodeNumber() {
|
||||
return Math.floor(1000000000 + Math.random() * 9000000000).toString();
|
||||
currentBarcodeNumber = Math.floor(1000000000 + Math.random() * 9000000000).toString();
|
||||
}
|
||||
|
||||
// Setup event listeners
|
||||
function setupEventListeners() {
|
||||
// Template change
|
||||
garageSelect.addEventListener('change', async () => {
|
||||
await loadTemplate(garageSelect.value);
|
||||
});
|
||||
|
||||
// Real-time preview updates
|
||||
const updatePreview = () => renderTemplate(currentTemplateId);
|
||||
|
||||
regNumberInput.addEventListener('input', updatePreview);
|
||||
fromDateInput.addEventListener('change', updatePreview);
|
||||
toDateInput.addEventListener('change', updatePreview);
|
||||
@@ -97,7 +180,6 @@ function setupEventListeners() {
|
||||
chassisNumberInput.addEventListener('input', updatePreview);
|
||||
engineSerialInput.addEventListener('input', updatePreview);
|
||||
engineCapacityInput.addEventListener('input', updatePreview);
|
||||
garageSelect.addEventListener('change', updatePreview);
|
||||
|
||||
// Auto-uppercase for certain fields
|
||||
regNumberInput.addEventListener('input', (e) => {
|
||||
@@ -117,53 +199,10 @@ function setupEventListeners() {
|
||||
const toDate = new Date(fromDate);
|
||||
toDate.setFullYear(toDate.getFullYear() + 1);
|
||||
toDateInput.value = formatDateForInput(toDate);
|
||||
updatePreview();
|
||||
renderTemplate(currentTemplateId);
|
||||
});
|
||||
}
|
||||
|
||||
// Update the sticker preview
|
||||
function updatePreview() {
|
||||
const garage = garageTemplates[garageSelect.value];
|
||||
|
||||
// Update registration number
|
||||
const regNumber = regNumberInput.value || 'X0X0000';
|
||||
previewRegNumber.textContent = formatRegNumber(regNumber);
|
||||
|
||||
// Update dates
|
||||
previewFromDate.textContent = formatDateForDisplay(fromDateInput.value) || 'DD-MM-YYYY';
|
||||
previewToDate.textContent = formatDateForDisplay(toDateInput.value) || 'DD-MM-YYYY';
|
||||
|
||||
// Update vehicle info
|
||||
previewModelNumber.textContent = modelNumberInput.value || 'XXXX-XXXXX';
|
||||
previewChassisNumber.textContent = chassisNumberInput.value || 'XXXXXXXXXXXXXXXXX';
|
||||
previewEngineSerial.textContent = engineSerialInput.value || 'XXX-XXXXXX';
|
||||
previewEngineCapacity.textContent = engineCapacityInput.value || '000.000';
|
||||
|
||||
// Update garage info
|
||||
if (garage) {
|
||||
previewGarageInfo.textContent = `${garage.name}, TEL: ${garage.phone}`;
|
||||
garageLogo.innerHTML = garage.logo.content;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate barcode
|
||||
function generateBarcode() {
|
||||
const barcodeNumber = generateBarcodeNumber();
|
||||
previewBarcodeNumber.textContent = barcodeNumber;
|
||||
|
||||
try {
|
||||
JsBarcode(previewBarcode, barcodeNumber, {
|
||||
format: 'CODE128',
|
||||
width: 1.5,
|
||||
height: 30,
|
||||
displayValue: false,
|
||||
margin: 0
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Barcode generation failed:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle form submission
|
||||
async function handleFormSubmit(e) {
|
||||
e.preventDefault();
|
||||
@@ -173,6 +212,13 @@ async function handleFormSubmit(e) {
|
||||
submitBtn.querySelector('.material-icons').textContent = 'autorenew';
|
||||
|
||||
try {
|
||||
// Generate new barcode for final PDF
|
||||
generateBarcodeNumber();
|
||||
renderTemplate(currentTemplateId);
|
||||
|
||||
// Wait for render
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
|
||||
await generatePDF();
|
||||
showSnackbar('Sticker generated successfully!', 'success');
|
||||
} catch (error) {
|
||||
@@ -187,17 +233,15 @@ async function handleFormSubmit(e) {
|
||||
// Generate PDF
|
||||
async function generatePDF() {
|
||||
const { jsPDF } = window.jspdf;
|
||||
const stickerElement = document.querySelector('.sticker');
|
||||
const stickerElement = stickerPreview.querySelector('.sticker, [class^="sticker-"]');
|
||||
|
||||
// Generate a new barcode number for this sticker
|
||||
generateBarcode();
|
||||
|
||||
// Wait for barcode to render
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
if (!stickerElement) {
|
||||
throw new Error('No sticker element found');
|
||||
}
|
||||
|
||||
// Capture the sticker as an image
|
||||
const canvas = await html2canvas(stickerElement, {
|
||||
scale: 3, // Higher resolution
|
||||
scale: 3,
|
||||
backgroundColor: '#ffffff',
|
||||
useCORS: true,
|
||||
logging: false
|
||||
@@ -206,7 +250,6 @@ async function generatePDF() {
|
||||
// Create PDF with sticker dimensions
|
||||
const imgData = canvas.toDataURL('image/png');
|
||||
|
||||
// Calculate dimensions (sticker is approximately 280px wide)
|
||||
const pdfWidth = 100; // mm
|
||||
const pdfHeight = (canvas.height / canvas.width) * pdfWidth;
|
||||
|
||||
@@ -216,7 +259,6 @@ async function generatePDF() {
|
||||
format: [pdfWidth + 10, pdfHeight + 10]
|
||||
});
|
||||
|
||||
// Center the sticker
|
||||
const x = 5;
|
||||
const y = 5;
|
||||
|
||||
@@ -226,7 +268,6 @@ async function generatePDF() {
|
||||
const regNumber = regNumberInput.value || 'sticker';
|
||||
const filename = `roadworthiness-${regNumber.replace(/\s/g, '')}-${Date.now()}.pdf`;
|
||||
|
||||
// Save the PDF
|
||||
pdf.save(filename);
|
||||
}
|
||||
|
||||
|
||||
52
index.html
52
index.html
@@ -38,7 +38,7 @@
|
||||
<label class="form-label" for="garage">Select Garage</label>
|
||||
<div class="select-wrapper">
|
||||
<select id="garage" class="form-select" required>
|
||||
<option value="rs-auto">RS AUTO</option>
|
||||
<!-- Populated dynamically from templates/index.json -->
|
||||
</select>
|
||||
<span class="material-icons select-icon">expand_more</span>
|
||||
</div>
|
||||
@@ -48,7 +48,7 @@
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="regNumber">Vehicle Registration Number</label>
|
||||
<input type="text" id="regNumber" class="form-input"
|
||||
placeholder="e.g., A0F7930" required
|
||||
placeholder="X0X0000" required
|
||||
pattern="[A-Za-z0-9]+" maxlength="10">
|
||||
<span class="form-hint">Letters and numbers only</span>
|
||||
</div>
|
||||
@@ -69,28 +69,28 @@
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="modelNumber">Model Number</label>
|
||||
<input type="text" id="modelNumber" class="form-input"
|
||||
placeholder="e.g., 55S400-010C" required>
|
||||
placeholder="XXX000-000X" required>
|
||||
</div>
|
||||
|
||||
<!-- Chassis Number -->
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="chassisNumber">Chassis Number</label>
|
||||
<input type="text" id="chassisNumber" class="form-input"
|
||||
placeholder="e.g., MH355S004DK117181" required>
|
||||
placeholder="XXXXXXXXXXXXXXXXX" required>
|
||||
</div>
|
||||
|
||||
<!-- Engine Serial Number -->
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="engineSerial">Engine Serial Number</label>
|
||||
<input type="text" id="engineSerial" class="form-input"
|
||||
placeholder="e.g., 55S-118388" required>
|
||||
placeholder="XXX-XXXXXX" required>
|
||||
</div>
|
||||
|
||||
<!-- Engine Capacity -->
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="engineCapacity">Engine Capacity (CC)</label>
|
||||
<input type="text" id="engineCapacity" class="form-input"
|
||||
placeholder="e.g., 135.000" required>
|
||||
placeholder="XXX.XXX" required>
|
||||
</div>
|
||||
|
||||
<!-- Generate Button -->
|
||||
@@ -109,45 +109,7 @@
|
||||
</div>
|
||||
<div class="preview-container">
|
||||
<div id="stickerPreview" class="sticker-preview">
|
||||
<!-- Sticker will be rendered here -->
|
||||
<div class="sticker">
|
||||
<div class="sticker-header">
|
||||
<span id="previewRegNumber">X 0 X 0 0 0 0</span>
|
||||
</div>
|
||||
<div class="sticker-barcode-row">
|
||||
<span id="previewBarcodeNumber">0000000000</span>
|
||||
<svg id="previewBarcode"></svg>
|
||||
</div>
|
||||
<div class="sticker-body">
|
||||
<div class="sticker-info">
|
||||
<div class="date-row">
|
||||
<span><strong>From:</strong> <span id="previewFromDate">DD-MM-YYYY</span></span>
|
||||
</div>
|
||||
<div class="date-row">
|
||||
<span><strong>To:</strong> <span id="previewToDate">DD-MM-YYYY</span></span>
|
||||
</div>
|
||||
<div id="previewModelNumber">XXXX-XXXXX</div>
|
||||
<div id="previewChassisNumber">XXXXXXXXXXXXXXXXX</div>
|
||||
<div id="previewEngineSerial">XXX-XXXXXX</div>
|
||||
<div id="previewEngineCapacity">000.000</div>
|
||||
</div>
|
||||
<div class="sticker-logo">
|
||||
<div id="garageLogo" class="garage-logo">
|
||||
<svg viewBox="0 0 80 80" class="logo-svg">
|
||||
<circle cx="40" cy="40" r="38" fill="none" stroke="#000" stroke-width="2"/>
|
||||
<text x="40" y="18" text-anchor="middle" font-size="8" font-weight="bold">RS AUTO</text>
|
||||
<text x="40" y="45" text-anchor="middle" font-size="24" font-weight="bold">S</text>
|
||||
<path d="M20 50 Q40 35 60 50" fill="none" stroke="#000" stroke-width="2"/>
|
||||
<text x="40" y="58" text-anchor="middle" font-size="6">P:0085037</text>
|
||||
<text x="40" y="70" text-anchor="middle" font-size="8" font-weight="bold">MALDIVES</text>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sticker-footer">
|
||||
<span id="previewGarageInfo">RS AUTO, TEL: 775 8999</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Sticker template loaded dynamically -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
81
styles.css
81
styles.css
@@ -289,87 +289,14 @@ body {
|
||||
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
|
||||
}
|
||||
|
||||
/* Sticker Preview */
|
||||
/* Sticker Preview Container */
|
||||
.sticker-preview {
|
||||
background-color: var(--md-sys-color-surface-container);
|
||||
padding: 8px;
|
||||
box-shadow: var(--md-sys-elevation-2);
|
||||
}
|
||||
|
||||
.sticker {
|
||||
width: 280px;
|
||||
border: 2px solid #000;
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.sticker-header {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 6px 8px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 4px;
|
||||
}
|
||||
|
||||
.sticker-barcode-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #000;
|
||||
padding: 4px 8px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.sticker-barcode-row span {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sticker-barcode-row svg {
|
||||
height: 30px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sticker-body {
|
||||
display: flex;
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
|
||||
.sticker-info {
|
||||
flex: 1;
|
||||
padding: 6px 8px;
|
||||
font-size: 10px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.sticker-info .date-row {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.sticker-logo {
|
||||
width: 80px;
|
||||
border-left: 1px solid #000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.garage-logo .logo-svg {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.sticker-footer {
|
||||
text-align: center;
|
||||
padding: 4px 8px;
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
border-top: 1px solid #000;
|
||||
}
|
||||
/* Sticker styles are loaded dynamically from templates/*.css */
|
||||
|
||||
/* Snackbar */
|
||||
.snackbar {
|
||||
@@ -481,10 +408,6 @@ body {
|
||||
.preview-container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.sticker {
|
||||
width: 260px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print Styles for PDF Export */
|
||||
|
||||
12
templates/index.json
Normal file
12
templates/index.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"templates": [
|
||||
{
|
||||
"id": "rs-auto",
|
||||
"name": "RS AUTO"
|
||||
},
|
||||
{
|
||||
"id": "motca",
|
||||
"name": "Min. of Transport & Civil Aviation"
|
||||
}
|
||||
]
|
||||
}
|
||||
73
templates/motca.css
Normal file
73
templates/motca.css
Normal file
@@ -0,0 +1,73 @@
|
||||
/* Min. of Transport & Civil Aviation Template Styles */
|
||||
.sticker-motca {
|
||||
width: 280px;
|
||||
border: 2px solid #000;
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.sticker-motca .sticker-header {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 6px 8px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sticker-motca .sticker-header .reg-number {
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.sticker-motca .sticker-header .barcode-number {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.sticker-motca .sticker-dates-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 4px 8px;
|
||||
font-size: 10px;
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
|
||||
.sticker-motca .sticker-body {
|
||||
display: flex;
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
|
||||
.sticker-motca .sticker-info {
|
||||
flex: 1;
|
||||
padding: 4px 8px;
|
||||
font-size: 10px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.sticker-motca .sticker-info .barcode {
|
||||
height: 25px;
|
||||
width: 100%;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.sticker-motca .sticker-values {
|
||||
width: 80px;
|
||||
padding: 4px 8px;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.sticker-motca .sticker-footer {
|
||||
text-align: center;
|
||||
padding: 4px 8px;
|
||||
font-size: 9px;
|
||||
font-weight: 500;
|
||||
}
|
||||
23
templates/motca.html
Normal file
23
templates/motca.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<div class="sticker sticker-motca">
|
||||
<div class="sticker-header">
|
||||
<span class="reg-number">{{regNumber}}</span>
|
||||
<span class="barcode-number">{{barcodeNumber}}</span>
|
||||
</div>
|
||||
<div class="sticker-dates-row">
|
||||
<span><strong>From</strong> {{fromDate}}</span>
|
||||
<span><strong>To</strong> {{toDate}}</span>
|
||||
</div>
|
||||
<div class="sticker-body">
|
||||
<div class="sticker-info">
|
||||
<div>{{modelNumber}}</div>
|
||||
<div>{{chassisNumber}}</div>
|
||||
<div>{{engineSerial}}</div>
|
||||
<svg class="barcode"></svg>
|
||||
</div>
|
||||
<div class="sticker-values">
|
||||
<div>0 sc</div>
|
||||
<div>{{engineCapacity}} cc</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sticker-footer">Min. of Transport & Civil Aviation</div>
|
||||
</div>
|
||||
74
templates/rs-auto.css
Normal file
74
templates/rs-auto.css
Normal file
@@ -0,0 +1,74 @@
|
||||
/* RS AUTO Template Styles */
|
||||
.sticker-rs-auto {
|
||||
width: 280px;
|
||||
border: 2px solid #000;
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.sticker-rs-auto .sticker-header {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 6px 8px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 4px;
|
||||
}
|
||||
|
||||
.sticker-rs-auto .sticker-barcode-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #000;
|
||||
padding: 4px 8px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.sticker-rs-auto .sticker-barcode-row .barcode-number {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sticker-rs-auto .sticker-barcode-row .barcode {
|
||||
height: 30px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sticker-rs-auto .sticker-body {
|
||||
display: flex;
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
|
||||
.sticker-rs-auto .sticker-info {
|
||||
flex: 1;
|
||||
padding: 6px 8px;
|
||||
font-size: 10px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.sticker-rs-auto .sticker-info .date-row {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.sticker-rs-auto .sticker-logo {
|
||||
width: 80px;
|
||||
border-left: 1px solid #000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.sticker-rs-auto .sticker-logo .logo-svg {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.sticker-rs-auto .sticker-footer {
|
||||
text-align: center;
|
||||
padding: 4px 8px;
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
}
|
||||
30
templates/rs-auto.html
Normal file
30
templates/rs-auto.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<div class="sticker sticker-rs-auto">
|
||||
<div class="sticker-header">
|
||||
<span class="reg-number">{{regNumber}}</span>
|
||||
</div>
|
||||
<div class="sticker-barcode-row">
|
||||
<span class="barcode-number">{{barcodeNumber}}</span>
|
||||
<svg class="barcode"></svg>
|
||||
</div>
|
||||
<div class="sticker-body">
|
||||
<div class="sticker-info">
|
||||
<div class="date-row"><strong>From:</strong> {{fromDate}}</div>
|
||||
<div class="date-row"><strong>To:</strong> {{toDate}}</div>
|
||||
<div>{{modelNumber}}</div>
|
||||
<div>{{chassisNumber}}</div>
|
||||
<div>{{engineSerial}}</div>
|
||||
<div>{{engineCapacity}}</div>
|
||||
</div>
|
||||
<div class="sticker-logo">
|
||||
<svg viewBox="0 0 80 80" class="logo-svg">
|
||||
<circle cx="40" cy="40" r="38" fill="none" stroke="#000" stroke-width="2"/>
|
||||
<text x="40" y="18" text-anchor="middle" font-size="8" font-weight="bold">RS AUTO</text>
|
||||
<text x="40" y="45" text-anchor="middle" font-size="24" font-weight="bold">S</text>
|
||||
<path d="M20 50 Q40 35 60 50" fill="none" stroke="#000" stroke-width="2"/>
|
||||
<text x="40" y="58" text-anchor="middle" font-size="6">P:0085037</text>
|
||||
<text x="40" y="70" text-anchor="middle" font-size="8" font-weight="bold">MALDIVES</text>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sticker-footer">RS AUTO, TEL: 775 8999</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user