Files
print-calculator/frontend/src/app/quote/advanced-quote/advanced-quote.component.html
2026-01-29 15:59:08 +01:00

153 lines
5.2 KiB
HTML

<div class="container fade-in">
<header class="section-header">
<a routerLink="/" class="back-link">
<span class="material-icons">arrow_back</span> Back
</a>
<h1>Advanced Quote</h1>
<p>Configure detailed print parameters for your project.</p>
</header>
<div class="grid-2 quote-layout">
<!-- Left: Inputs -->
<div class="card p-0 overflow-hidden">
<!-- Upload Area -->
<div class="upload-area small"
[class.drag-over]="isDragOver"
[class.has-file]="selectedFile"
(dragover)="onDragOver($event)"
(dragleave)="onDragLeave($event)"
(drop)="onDrop($event)">
<input #fileInput type="file" hidden (change)="onFileSelected($event)" accept=".stl">
<!-- Empty State -->
<div class="empty-state" *ngIf="!selectedFile" (click)="fileInput.click()">
<span class="material-icons">cloud_upload</span>
<p>Click or Drop STL here</p>
</div>
<!-- Selected State -->
<div *ngIf="selectedFile">
<div class="viewer-wrapper">
<app-stl-viewer [file]="selectedFile"></app-stl-viewer>
</div>
<div class="file-action-bar border-top">
<div class="file-info">
<span class="material-icons">description</span>
<span class="file-name">{{ selectedFile.name }}</span>
</div>
<button class="btn-icon danger" (click)="removeFile($event)" title="Remove">
<span class="material-icons">delete</span>
</button>
</div>
</div>
</div>
<!-- Parameters Form -->
<div class="params-form">
<h3>Print Settings</h3>
<div class="form-group">
<label>Material</label>
<select [(ngModel)]="params.filament">
<option *ngFor="let m of materialOptions" [value]="m.value">{{ m.label }}</option>
</select>
</div>
<div class="form-group">
<label>Color</label>
<select [(ngModel)]="params.material_color">
<option *ngFor="let c of colorOptions" [value]="c">{{ c }}</option>
</select>
</div>
<div class="form-group">
<label>Quality</label>
<select [(ngModel)]="params.quality">
<option *ngFor="let q of qualityOptions" [value]="q.value">{{ q.label }}</option>
</select>
</div>
<div class="form-group">
<label>Infill Density (%)</label>
<div class="range-wrapper">
<input type="range" [(ngModel)]="params.infill_density" min="0" max="100" step="5">
<span>{{ params.infill_density }}%</span>
</div>
</div>
<div class="form-group">
<label>Infill Pattern</label>
<select [(ngModel)]="params.infill_pattern">
<option *ngFor="let p of infillPatternOptions" [value]="p.value">{{ p.label }}</option>
</select>
</div>
</div>
<div class="actions">
<button class="btn btn-primary btn-block"
[disabled]="!selectedFile || isCalculating"
(click)="calculate()">
<span *ngIf="!isCalculating">Calculate Price</span>
<span *ngIf="isCalculating">Calculating...</span>
</button>
</div>
</div>
<!-- Right: Results -->
<div class="results-area" *ngIf="quoteResult">
<div class="card result-card">
<h2>Estimated Cost</h2>
<div class="price-big">
{{ quoteResult?.cost?.total | currency:'CHF' }}
</div>
<div class="specs-list">
<div class="spec-item">
<span>Print Time</span>
<strong>{{ quoteResult?.print_time_formatted }}</strong>
</div>
<div class="spec-item">
<span>Material Weight</span>
<strong>{{ quoteResult?.material_grams | number:'1.0-0' }}g</strong>
</div>
</div>
<!-- Param Summary (Future Proofing) -->
<div class="specs-list secondary">
<div class="spec-header">Request Specs</div>
<div class="spec-item compact">
<span>Infill</span>
<span>{{ params.infill_density }}%</span>
</div>
<div class="spec-item compact">
<span>Infill Pattern</span>
<span>{{ infillPatternLabel }}</span>
</div>
<div class="spec-item compact">
<span>Material</span>
<span>{{ materialLabel }}</span>
</div>
<div class="spec-item compact">
<span>Color</span>
<span>{{ params.material_color }}</span>
</div>
</div>
<div class="note-box">
<p>Note: Color does not affect the estimate. Printer is fixed to Bambu Lab A1.</p>
</div>
</div>
</div>
<!-- Empty State -->
<div class="results-area empty" *ngIf="!quoteResult">
<div class="card placeholder-card">
<span class="material-icons">science</span>
<h3>Advanced Quote</h3>
<p>Configure settings and calculate.</p>
</div>
</div>
</div>
</div>