Files
quality_recticel/py_app/app/templates/create_template copy.html
2025-09-17 20:47:22 +03:00

440 lines
16 KiB
HTML

{% extends "base.html" %}
{% block title %}Create Template{% endblock %}
{% block head %}
<style>
.btn-secondary {
background: #6c757d !important;
color: white !important;
border: 1px solid #6c757d !important;
padding: 8px 12px;
border-radius: 4px;
cursor: pointer;
}
.btn-outline {
background: white !important;
color: #333 !important;
border: 1px solid #ddd !important;
}
.btn-outline:hover {
background: #f8f9fa !important;
border-color: #007bff !important;
}
.template-field {
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
user-select: none;
}
.database-field {
background: linear-gradient(135deg, #e3f2fd, #bbdefb) !important;
border: 2px solid #2196f3 !important;
}
.database-field:hover {
transform: scale(1.02);
box-shadow: 0 4px 8px rgba(33, 150, 243, 0.3);
}
#label-preview {
background: #fafafa;
min-width: 300px;
min-height: 200px;
position: relative;
overflow: hidden;
}
.column-btn {
transition: all 0.2s ease;
}
.table-btn {
transition: all 0.2s ease;
}
.table-btn:hover {
transform: translateX(5px);
}
#tables-container h5,
#columns-container h5 {
color: #333;
border-bottom: 2px solid #007bff;
padding-bottom: 5px;
margin-bottom: 10px;
}
</style>
{% endblock %}
{% block content %}
<div class="card-container" style="display: flex; gap: 20px;">
<!-- Left Column -->
<div class="left-column" style="flex: 1; max-width: 33%;">
<div class="dashboard-card">
<h3>Template Settings</h3>
<p>Set the dimensions and retrieve database headers for the label template:</p>
<!-- Dimensions Section -->
<div>
<h4>Dimensions</h4>
<form id="dimensions-form">
<div style="margin-bottom: 10px;">
<label for="label-width">Width (mm):</label>
<input type="number" id="label-width" name="label_width" required>
</div>
<div style="margin-bottom: 10px;">
<label for="label-height">Height (mm):</label>
<input type="number" id="label-height" name="label_height" required>
</div>
<button type="button" id="set-dimensions-btn" class="btn">Set Label Dimensions</button>
</form>
</div>
<hr style="margin: 20px 0;">
<!-- Add Fields Section -->
<div>
<h4>Add Fields</h4>
<button type="button" class="btn add-field-btn" data-type="text-label">Add Text Label</button>
.big-card {
box-shadow: 0 4px 12px rgba(0,0,0,0.12);
border-radius: 10px;
padding: 30px 24px;
min-height: 600px;
background: #f5faff;
}
.small-card {
box-shadow: 0 2px 6px rgba(0,0,0,0.10);
border-radius: 10px;
padding: 18px 12px;
min-height: 300px;
background: #fff;
}
<button type="button" class="btn add-field-btn" data-type="text-input">Add Text Input</button>
<button type="button" class="btn add-field-btn" data-type="barcode">Add Barcode</button>
<button type="button" class="btn add-field-btn" data-type="qrcode">Add QR Code</button>
</div>
<!-- Get Database Headers Section -->
<div>
<h4>Get Database Headers</h4>
<p>Retrieve column names from a selected database table:</p>
<button type="button" id="get-tables-btn" class="btn">Get Database Tables</button>
<div id="tables-container" style="margin-top: 10px;">
<!-- Tables will be dynamically populated here -->
</div>
<div id="columns-container" style="margin-top: 10px;">
<!-- Columns will be dynamically populated here -->
</div>
</div>
<hr style="margin: 20px 0;">
</div>
</div>
<!-- Right Column -->
<div class="right-column" style="flex: 2;">
<div class="dashboard-card">
<h3>Interactive Label Preview</h3>
<p>Drag and drop fields to design your label:</p>
<div class="label-preview-container" style="display: flex; justify-content: center; align-items: center; height: 100%; position: relative;">
<div id="label-preview" style="border: 1px solid #ddd; padding: 10px; min-height: 400px; position: relative;">
<!-- Fields will be dynamically added here -->
</div>
</div>
<button type="button" id="preview-btn" class="btn" style="margin-top: 10px;">Preview</button>
</div>
</div>
</div>
<script src="{{ url_for('static', filename='pdfjs/pdf.worker.js') }}"></script>
<script>
// Set the worker source for PDF.js
pdfjsLib.GlobalWorkerOptions.workerSrc = "{{ url_for('static', filename='pdfjs/pdf.worker.min.js') }}";
// Database Tables Functionality
document.addEventListener('DOMContentLoaded', function() {
const getTablesBtn = document.getElementById('get-tables-btn');
const tablesContainer = document.getElementById('tables-container');
const columnsContainer = document.getElementById('columns-container');
// Handle Get Database Tables button click
getTablesBtn.addEventListener('click', function() {
getTablesBtn.textContent = 'Loading...';
getTablesBtn.disabled = true;
fetch('/get_database_tables')
.then(response => response.json())
.then(data => {
if (data.success) {
displayTables(data.tables, data.recommended);
} else {
showError('Failed to load tables: ' + data.error);
}
})
.catch(error => {
showError('Error: ' + error.message);
})
.finally(() => {
getTablesBtn.textContent = 'Get Database Tables';
getTablesBtn.disabled = false;
});
});
function displayTables(tables, recommended) {
if (tables.length === 0) {
tablesContainer.innerHTML = '<p style="color: #999;">No relevant tables found.</p>';
return;
}
let html = '<h5>Available Tables:</h5><div style="margin-top: 10px;">';
tables.forEach(table => {
const isRecommended = table === recommended;
const buttonClass = isRecommended ? 'btn' : 'btn-secondary';
const recommendedText = isRecommended ? ' ⭐ (Recommended)' : '';
html += `
<button type="button"
class="table-btn ${buttonClass}"
data-table="${table}"
style="display: block; margin: 5px 0; width: 100%; text-align: left;">
${table}${recommendedText}
</button>
`;
});
html += '</div>';
tablesContainer.innerHTML = html;
// Add event listeners to table buttons
document.querySelectorAll('.table-btn').forEach(btn => {
btn.addEventListener('click', function() {
const tableName = this.getAttribute('data-table');
loadTableColumns(tableName);
// Update button states
document.querySelectorAll('.table-btn').forEach(b => {
b.classList.remove('btn');
b.classList.add('btn-secondary');
});
this.classList.remove('btn-secondary');
this.classList.add('btn');
});
});
// Auto-load recommended table
if (recommended) {
setTimeout(() => {
const recommendedBtn = document.querySelector(`[data-table="${recommended}"]`);
if (recommendedBtn) {
recommendedBtn.click();
}
}, 100);
}
}
function loadTableColumns(tableName) {
columnsContainer.innerHTML = '<p>Loading columns...</p>';
fetch(`/get_table_columns/${tableName}`)
.then(response => response.json())
.then(data => {
if (data.success) {
displayColumns(data.table, data.columns);
} else {
showError('Failed to load columns: ' + data.error);
}
})
.catch(error => {
showError('Error loading columns: ' + error.message);
});
}
function displayColumns(tableName, columns) {
if (columns.length === 0) {
columnsContainer.innerHTML = '<p style="color: #999;">No columns found.</p>';
return;
}
let html = `
<h5>Columns from "${tableName}" table:</h5>
<p style="font-size: 12px; color: #666; margin: 5px 0;">
Click on a column to add it as a database field to your label template.
</p>
<div style="margin-top: 10px; max-height: 300px; overflow-y: auto;">
`;
columns.forEach(column => {
// Determine icon based on column type
let icon = '📝'; // Default text icon
if (column.name.toLowerCase().includes('id')) icon = '🔢';
else if (column.name.toLowerCase().includes('date') || column.name.toLowerCase().includes('time')) icon = '📅';
else if (column.name.toLowerCase().includes('quantity') || column.name.toLowerCase().includes('cantitate')) icon = '🔢';
else if (column.name.toLowerCase().includes('code') || column.name.toLowerCase().includes('cod')) icon = '🏷️';
else if (column.name.toLowerCase().includes('customer') || column.name.toLowerCase().includes('client')) icon = '👤';
else if (column.name.toLowerCase().includes('product') || column.name.toLowerCase().includes('articol')) icon = '📦';
html += `
<button type="button"
class="column-btn btn-outline"
data-column="${column.name}"
data-field-id="${column.field_id}"
data-description="${column.description}"
style="display: block; margin: 3px 0; padding: 8px; width: 100%; text-align: left; border: 1px solid #ddd; background: white; border-radius: 4px; cursor: pointer;">
<div style="display: flex; align-items: center;">
<span style="margin-right: 8px; font-size: 16px;">${icon}</span>
<div style="flex: 1;">
<strong>${column.name}</strong>
<br>
<small style="color: #666;">${column.description}</small>
<br>
<small style="color: #999; font-style: italic;">${column.type}</small>
</div>
</div>
</button>
`;
});
html += '</div>';
columnsContainer.innerHTML = html;
// Add event listeners to column buttons
document.querySelectorAll('.column-btn').forEach(btn => {
btn.addEventListener('click', function() {
const columnName = this.getAttribute('data-column');
const fieldId = this.getAttribute('data-field-id');
const description = this.getAttribute('data-description');
addDatabaseFieldToTemplate(columnName, fieldId, description);
// Visual feedback
this.style.background = '#e7f3ff';
this.style.borderColor = '#007bff';
setTimeout(() => {
this.style.background = 'white';
this.style.borderColor = '#ddd';
}, 1000);
});
// Hover effects
btn.addEventListener('mouseenter', function() {
this.style.background = '#f8f9fa';
this.style.borderColor = '#007bff';
});
btn.addEventListener('mouseleave', function() {
if (this.style.background !== 'rgb(231, 243, 255)') {
this.style.background = 'white';
this.style.borderColor = '#ddd';
}
});
});
}
function addDatabaseFieldToTemplate(columnName, fieldId, description) {
const labelPreview = document.getElementById('label-preview');
// Create a database field element
const fieldElement = document.createElement('div');
fieldElement.className = 'template-field database-field';
fieldElement.id = fieldId;
fieldElement.style.cssText = `
position: absolute;
left: 20px;
top: ${20 + (document.querySelectorAll('.template-field').length * 30)}px;
padding: 5px 10px;
background: #e3f2fd;
border: 2px solid #2196f3;
border-radius: 4px;
cursor: move;
font-size: 12px;
min-width: 120px;
text-align: center;
`;
fieldElement.innerHTML = `
<div style="font-weight: bold; color: #1976d2;">${'{{'}${columnName}${'}}'}}</div>
<div style="font-size: 10px; color: #666;">${description}</div>
`;
// Add data attributes
fieldElement.setAttribute('data-field-type', 'database');
fieldElement.setAttribute('data-column-name', columnName);
fieldElement.setAttribute('data-description', description);
labelPreview.appendChild(fieldElement);
// Make it draggable (basic implementation)
makeDraggable(fieldElement);
console.log(`Added database field: ${columnName} (${description})`);
}
function makeDraggable(element) {
let isDragging = false;
let currentX;
let currentY;
let initialX;
let initialY;
let xOffset = 0;
let yOffset = 0;
element.addEventListener('mousedown', dragStart);
document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', dragEnd);
function dragStart(e) {
initialX = e.clientX - xOffset;
initialY = e.clientY - yOffset;
if (e.target === element) {
isDragging = true;
}
}
function drag(e) {
if (isDragging) {
e.preventDefault();
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
xOffset = currentX;
yOffset = currentY;
element.style.left = currentX + 'px';
element.style.top = currentY + 'px';
}
}
function dragEnd() {
initialX = currentX;
initialY = currentY;
isDragging = false;
}
}
function showError(message) {
const errorDiv = document.createElement('div');
errorDiv.style.cssText = `
background: #ffe6e6;
border: 1px solid #ff9999;
color: #cc0000;
padding: 10px;
border-radius: 4px;
margin: 10px 0;
`;
errorDiv.textContent = message;
tablesContainer.appendChild(errorDiv);
setTimeout(() => {
errorDiv.remove();
}, 5000);
}
});
</script>
{% endblock %}