|
|
class AppSidebar extends HTMLElement { |
|
|
connectedCallback() { |
|
|
this.attachShadow({ mode: 'open' }); |
|
|
this.shadowRoot.innerHTML = ` |
|
|
<style> |
|
|
:host { |
|
|
width: var(--sidebar-width, 320px); |
|
|
background-color: white; |
|
|
border-right: 1px solid #e2e8f0; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
height: 100%; |
|
|
overflow-y: auto; |
|
|
transition: transform 0.3s ease; |
|
|
flex-shrink: 0; |
|
|
z-index: 40; |
|
|
} |
|
|
.section { |
|
|
padding: 1.5rem 1rem; |
|
|
border-bottom: 1px solid #f1f5f9; |
|
|
} |
|
|
.section h3 { |
|
|
font-size: 0.875rem; |
|
|
font-weight: 700; |
|
|
text-transform: uppercase; |
|
|
color: #64748b; |
|
|
margin-bottom: 1rem; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 0.5rem; |
|
|
} |
|
|
label.file-label { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
gap: 0.5rem; |
|
|
width: 100%; |
|
|
padding: 0.75rem; |
|
|
background: #eff6ff; |
|
|
color: #2563eb; |
|
|
border: 1px dashed #bfdbfe; |
|
|
border-radius: 0.5rem; |
|
|
font-size: 0.875rem; |
|
|
font-weight: 500; |
|
|
cursor: pointer; |
|
|
transition: all 0.2s; |
|
|
text-align: center; |
|
|
} |
|
|
label.file-label:hover { |
|
|
background: #dbeafe; |
|
|
border-color: #3b82f6; |
|
|
} |
|
|
.file-upload-wrapper { |
|
|
position: relative; |
|
|
overflow: hidden; |
|
|
display: inline-block; |
|
|
width: 100%; |
|
|
} |
|
|
.file-upload-wrapper input[type=file] { |
|
|
position: absolute; |
|
|
left: 0; |
|
|
top: 0; |
|
|
opacity: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
cursor: pointer; |
|
|
} |
|
|
.file-name { |
|
|
font-size: 0.75rem; |
|
|
color: #94a3b8; |
|
|
margin-top: 0.25rem; |
|
|
white-space: nowrap; |
|
|
overflow: hidden; |
|
|
text-overflow: ellipsis; |
|
|
} |
|
|
button.action-btn { |
|
|
width: 100%; |
|
|
padding: 0.75rem; |
|
|
border-radius: 0.5rem; |
|
|
border: none; |
|
|
font-weight: 600; |
|
|
cursor: pointer; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
gap: 0.5rem; |
|
|
transition: all 0.2s; |
|
|
margin-bottom: 0.5rem; |
|
|
} |
|
|
.btn-primary { |
|
|
background: linear-gradient(135deg, #2563eb, #4f46e5); |
|
|
color: white; |
|
|
} |
|
|
.btn-primary:hover { |
|
|
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3); |
|
|
transform: translateY(-1px); |
|
|
} |
|
|
.btn-secondary { |
|
|
background: #f1f5f9; |
|
|
color: #475569; |
|
|
} |
|
|
.btn-secondary:hover { |
|
|
background: #e2e8f0; |
|
|
} |
|
|
.btn-indigo { |
|
|
background: #4f46e5; |
|
|
color: white; |
|
|
} |
|
|
.form-group { |
|
|
margin-bottom: 1rem; |
|
|
} |
|
|
select.form-control { |
|
|
width: 100%; |
|
|
padding: 0.5rem; |
|
|
border: 1px solid #cbd5e1; |
|
|
border-radius: 0.375rem; |
|
|
background: white; |
|
|
} |
|
|
/* Dark Mode Support via Host selector */ |
|
|
:host-context([data-theme="dark"]) { |
|
|
background-color: #1e293b; |
|
|
border-color: #334155; |
|
|
} |
|
|
:host-context([data-theme="dark"]) .section h3 { |
|
|
color: #94a3b8; |
|
|
} |
|
|
:host-context([data-theme="dark"]) label.file-label { |
|
|
background: #172554; |
|
|
color: #60a5fa; |
|
|
border-color: #1e3a8a; |
|
|
} |
|
|
:host-context([data-theme="dark"]) .file-name { |
|
|
color: #64748b; |
|
|
} |
|
|
:host-context([data-theme="dark"]) .btn-secondary { |
|
|
background: #334155; |
|
|
color: #e2e8f0; |
|
|
} |
|
|
:host-context([data-theme="dark"]) select.form-control { |
|
|
background: #0f172a; |
|
|
color: white; |
|
|
border-color: #475569; |
|
|
} |
|
|
</style> |
|
|
|
|
|
<!-- Standard Sidebar Content --> |
|
|
<div id="sidebar-standard"> |
|
|
<div class="section"> |
|
|
<h3><i data-feather="image"></i> Backgrounds</h3> |
|
|
<div class="form-group"> |
|
|
<div class="file-upload-wrapper"> |
|
|
<input type="file" id="bg1-file" accept="image/*,.pdf"> |
|
|
<label for="bg1-file" class="file-label"> |
|
|
<i data-feather="upload"></i> Page 1 Image |
|
|
</label> |
|
|
</div> |
|
|
<div id="bg1-name" class="file-name">No file selected</div> |
|
|
</div> |
|
|
<div class="form-group"> |
|
|
<div class="file-upload-wrapper"> |
|
|
<input type="file" id="bg2-file" accept="image/*,.pdf"> |
|
|
<label for="bg2-file" class="file-label"> |
|
|
<i data-feather="upload"></i> Page 2 Image |
|
|
</label> |
|
|
</div> |
|
|
<div id="bg2-name" class="file-name">No file selected</div> |
|
|
</div> |
|
|
<button id="btn-apply-bg" class="action-btn btn-primary"> |
|
|
<i data-feather="check"></i> Apply Backgrounds |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="section"> |
|
|
<h3><i data-feather="database"></i> Data Source</h3> |
|
|
<div class="form-group"> |
|
|
<div class="file-upload-wrapper"> |
|
|
<input type="file" id="json-file" accept=".json"> |
|
|
<label for="json-file" class="file-label"> |
|
|
<i data-feather="file-text"></i> Import JSON |
|
|
</label> |
|
|
</div> |
|
|
<div id="json-name" class="file-name">No file selected</div> |
|
|
</div> |
|
|
<div class="form-group"> |
|
|
<label class="text-xs font-bold text-slate-500 uppercase mb-1 block">Select Record</label> |
|
|
<select id="data-select" class="form-control" disabled> |
|
|
<option value="">-- No Data --</option> |
|
|
</select> |
|
|
</div> |
|
|
<button id="btn-load-sample" class="action-btn btn-indigo"> |
|
|
<i data-feather="box"></i> Load Sample |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="section"> |
|
|
<h3><i data-feather="book-open"></i> PDF Tools</h3> |
|
|
<div class="form-group"> |
|
|
<div class="file-upload-wrapper"> |
|
|
<input type="file" id="pdf-upload" accept="application/pdf"> |
|
|
<label for="pdf-upload" class="file-label"> |
|
|
<i data-feather="upload"></i> Import PDF |
|
|
</label> |
|
|
</div> |
|
|
<div id="pdf-name" class="file-name">No file selected</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="section"> |
|
|
<h3><i data-feather="download"></i> Export</h3> |
|
|
<button id="btn-download-pdf" class="action-btn btn-primary"> |
|
|
<i data-feather="download"></i> Download PDF |
|
|
</button> |
|
|
<button id="btn-download-all" class="action-btn btn-secondary"> |
|
|
<i data-feather="download-cloud"></i> Download All |
|
|
</button> |
|
|
<button id="btn-qr-modal" class="action-btn btn-indigo"> |
|
|
<i data-feather="grid"></i> Add QR & Download |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="section"> |
|
|
<h3><i data-feather="layout"></i> Layout Management</h3> |
|
|
<div class="form-group"> |
|
|
<input type="text" id="layout-name-input" placeholder="Layout name" class="form-control mb-2"> |
|
|
</div> |
|
|
<div class="form-group"> |
|
|
<div class="file-upload-wrapper"> |
|
|
<input type="file" id="layout-import" accept=".json"> |
|
|
<label for="layout-import" class="file-label"> |
|
|
<i data-feather="upload"></i> Import Layout |
|
|
</label> |
|
|
</div> |
|
|
<div id="layout-import-name" class="file-name">No file selected</div> |
|
|
</div> |
|
|
<button id="btn-export-layout" class="action-btn btn-secondary"> |
|
|
<i data-feather="save"></i> Export Layout |
|
|
</button> |
|
|
<button id="btn-save-layout" class="action-btn btn-primary"> |
|
|
<i data-feather="database"></i> Save to History |
|
|
</button> |
|
|
<button id="btn-new-layout" class="action-btn btn-secondary"> |
|
|
<i data-feather="file-plus"></i> New Layout |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
<!-- Design Mode Sidebar Content --> |
|
|
<div id="sidebar-design" style="display: none;"> |
|
|
<div class="section"> |
|
|
<h3><i data-feather="sliders"></i> Field Properties</h3> |
|
|
<div id="no-field-selected" class="text-center py-4 text-slate-500"> |
|
|
<i data-feather="mouse-pointer" class="w-8 h-8 mx-auto mb-2"></i> |
|
|
<p>Select a field to edit</p> |
|
|
</div> |
|
|
<div id="field-controls" style="display: none;"> |
|
|
<div class="form-group"> |
|
|
<label>Field ID</label> |
|
|
<div id="prop-id" class="font-mono text-sm p-2 bg-slate-100 dark:bg-slate-700 rounded"></div> |
|
|
</div> |
|
|
<div class="grid grid-cols-2 gap-2"> |
|
|
<div class="form-group"> |
|
|
<label for="prop-x">X Position</label> |
|
|
<input type="number" id="prop-x" class="form-control" step="1"> |
|
|
</div> |
|
|
<div class="form-group"> |
|
|
<label for="prop-y">Y Position</label> |
|
|
<input type="number" id="prop-y" class="form-control" step="1"> |
|
|
</div> |
|
|
</div> |
|
|
<div class="form-group"> |
|
|
<label for="prop-size">Font Size</label> |
|
|
<input type="number" id="prop-size" class="form-control" min="8" max="72"> |
|
|
</div> |
|
|
<div class="form-group"> |
|
|
<label for="prop-weight">Font Weight</label> |
|
|
<select id="prop-weight" class="form-control"> |
|
|
<option value="normal">Normal</option> |
|
|
<option value="bold">Bold</option> |
|
|
<option value="lighter">Light</option> |
|
|
</select> |
|
|
</div> |
|
|
<div class="form-group"> |
|
|
<label for="prop-color">Text Color</label> |
|
|
<input type="color" id="prop-color" class="form-control h-10"> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="section"> |
|
|
<h3><i data-feather="layout"></i> Layout Actions</h3> |
|
|
<div class="form-group"> |
|
|
<input type="text" id="design-layout-name" placeholder="Layout name" class="form-control mb-2"> |
|
|
</div> |
|
|
<button id="btn-export-design" class="action-btn btn-secondary"> |
|
|
<i data-feather="save"></i> Export Layout |
|
|
</button> |
|
|
<button id="btn-save-design" class="action-btn btn-primary"> |
|
|
<i data-feather="database"></i> Save to History |
|
|
</button> |
|
|
<button id="btn-new-design" class="action-btn btn-secondary"> |
|
|
<i data-feather="file-plus"></i> New Layout |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
|
|
|
|
|
|
feather.replace(); |
|
|
} |
|
|
} |
|
|
|
|
|
customElements.define('app-sidebar', AppSidebar); |
|
|
|
|
|
|