dev #5
@@ -1,73 +1,87 @@
|
|||||||
<form [formGroup]="form" (ngSubmit)="onSubmit()">
|
@if (sent()) {
|
||||||
<!-- Request Type -->
|
<div class="success-state">
|
||||||
<div class="form-group">
|
<div class="success-icon">
|
||||||
<label>{{ 'CONTACT.REQ_TYPE_LABEL' | translate }} *</label>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<select formControlName="requestType" class="form-control">
|
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path>
|
||||||
<option *ngFor="let type of requestTypes" [value]="type.value">
|
<polyline points="22 4 12 14.01 9 11.01"></polyline>
|
||||||
{{ type.label | translate }}
|
</svg>
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<!-- Phone -->
|
|
||||||
<app-input formControlName="email" type="email" [label]="'CONTACT.LABEL_EMAIL' | translate" [placeholder]="'CONTACT.PLACEHOLDER_EMAIL' | translate" class="col"></app-input>
|
|
||||||
<!-- Phone -->
|
|
||||||
<app-input formControlName="phone" type="tel" [label]="('CONTACT.PHONE' | translate)" [placeholder]="'CONTACT.PLACEHOLDER_PHONE' | translate" class="col"></app-input>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- User Type Selector (Segmented Control) -->
|
|
||||||
<div class="user-type-selector">
|
|
||||||
<div class="type-option" [class.selected]="!isCompany" (click)="setCompanyMode(false)">
|
|
||||||
{{ 'CONTACT.TYPE_PRIVATE' | translate }}
|
|
||||||
</div>
|
|
||||||
<div class="type-option" [class.selected]="isCompany" (click)="setCompanyMode(true)">
|
|
||||||
{{ 'CONTACT.TYPE_COMPANY' | translate }}
|
|
||||||
</div>
|
</div>
|
||||||
|
<h3>{{ 'CONTACT.SUCCESS_TITLE' | translate }}</h3>
|
||||||
|
<p>{{ 'CONTACT.SUCCESS_DESC' | translate }}</p>
|
||||||
|
<app-button (click)="resetForm()">{{ 'CONTACT.SEND_ANOTHER' | translate }}</app-button>
|
||||||
</div>
|
</div>
|
||||||
|
} @else {
|
||||||
<!-- Personal Name (Only if NOT Company) -->
|
<form [formGroup]="form" (ngSubmit)="onSubmit()">
|
||||||
<app-input *ngIf="!isCompany" formControlName="name" [label]="'CONTACT.LABEL_NAME' | translate" [placeholder]="'CONTACT.PLACEHOLDER_NAME' | translate"></app-input>
|
<!-- Request Type -->
|
||||||
|
<div class="form-group">
|
||||||
<!-- Company Fields (Only if Company) -->
|
<label>{{ 'CONTACT.REQ_TYPE_LABEL' | translate }} *</label>
|
||||||
<div *ngIf="isCompany" class="company-fields">
|
<select formControlName="requestType" class="form-control">
|
||||||
<app-input formControlName="companyName" [label]="('CONTACT.COMPANY_NAME' | translate) + ' *'" [placeholder]="'CONTACT.PLACEHOLDER_COMPANY' | translate"></app-input>
|
<option *ngFor="let type of requestTypes" [value]="type.value">
|
||||||
<app-input formControlName="referencePerson" [label]="('CONTACT.REF_PERSON' | translate) + ' *'" [placeholder]="'CONTACT.PLACEHOLDER_REF_PERSON' | translate"></app-input>
|
{{ type.label | translate }}
|
||||||
</div>
|
</option>
|
||||||
|
</select>
|
||||||
<div class="form-group">
|
|
||||||
<label>{{ 'CONTACT.LABEL_MESSAGE' | translate }}</label>
|
|
||||||
<textarea formControlName="message" class="form-control" rows="4"></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- File Upload Section -->
|
|
||||||
<div class="form-group">
|
|
||||||
<label>{{ 'CONTACT.UPLOAD_LABEL' | translate }}</label>
|
|
||||||
<p class="hint">{{ 'CONTACT.UPLOAD_HINT' | translate }}</p>
|
|
||||||
|
|
||||||
<div class="drop-zone" (click)="fileInput.click()"
|
|
||||||
(dragover)="onDragOver($event)" (drop)="onDrop($event)">
|
|
||||||
<input #fileInput type="file" multiple (change)="onFileSelected($event)" hidden
|
|
||||||
accept=".jpg,.jpeg,.png,.pdf,.stl,.step,.stp,.3mf,.obj">
|
|
||||||
<p>{{ 'CONTACT.DROP_FILES' | translate }}</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="file-grid" *ngIf="files().length > 0">
|
<div class="row">
|
||||||
<div class="file-item" *ngFor="let file of files(); let i = index">
|
<!-- Phone -->
|
||||||
<button type="button" class="remove-btn" (click)="removeFile(i)">×</button>
|
<app-input formControlName="email" type="email" [label]="'CONTACT.LABEL_EMAIL' | translate" [placeholder]="'CONTACT.PLACEHOLDER_EMAIL' | translate" class="col"></app-input>
|
||||||
<img *ngIf="file.type === 'image'" [src]="file.url" class="preview-img">
|
<!-- Phone -->
|
||||||
<div *ngIf="file.type !== 'image'" class="file-icon">
|
<app-input formControlName="phone" type="tel" [label]="('CONTACT.PHONE' | translate)" [placeholder]="'CONTACT.PLACEHOLDER_PHONE' | translate" class="col"></app-input>
|
||||||
<span *ngIf="file.type === 'pdf'">PDF</span>
|
</div>
|
||||||
<span *ngIf="file.type === '3d'">3D</span>
|
|
||||||
</div>
|
<!-- User Type Selector (Segmented Control) -->
|
||||||
<div class="file-name" [title]="file.file.name">{{ file.file.name }}</div>
|
<div class="user-type-selector">
|
||||||
|
<div class="type-option" [class.selected]="!isCompany" (click)="setCompanyMode(false)">
|
||||||
|
{{ 'CONTACT.TYPE_PRIVATE' | translate }}
|
||||||
|
</div>
|
||||||
|
<div class="type-option" [class.selected]="isCompany" (click)="setCompanyMode(true)">
|
||||||
|
{{ 'CONTACT.TYPE_COMPANY' | translate }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="actions">
|
<!-- Personal Name (Only if NOT Company) -->
|
||||||
<app-button type="submit" [disabled]="form.invalid || sent()">
|
<app-input *ngIf="!isCompany" formControlName="name" [label]="'CONTACT.LABEL_NAME' | translate" [placeholder]="'CONTACT.PLACEHOLDER_NAME' | translate"></app-input>
|
||||||
{{ sent() ? ('CONTACT.MSG_SENT' | translate) : ('CONTACT.SEND' | translate) }}
|
|
||||||
</app-button>
|
<!-- Company Fields (Only if Company) -->
|
||||||
</div>
|
<div *ngIf="isCompany" class="company-fields">
|
||||||
</form>
|
<app-input formControlName="companyName" [label]="('CONTACT.COMPANY_NAME' | translate) + ' *'" [placeholder]="'CONTACT.PLACEHOLDER_COMPANY' | translate"></app-input>
|
||||||
|
<app-input formControlName="referencePerson" [label]="('CONTACT.REF_PERSON' | translate) + ' *'" [placeholder]="'CONTACT.PLACEHOLDER_REF_PERSON' | translate"></app-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{ 'CONTACT.LABEL_MESSAGE' | translate }}</label>
|
||||||
|
<textarea formControlName="message" class="form-control" rows="4"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- File Upload Section -->
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{ 'CONTACT.UPLOAD_LABEL' | translate }}</label>
|
||||||
|
<p class="hint">{{ 'CONTACT.UPLOAD_HINT' | translate }}</p>
|
||||||
|
|
||||||
|
<div class="drop-zone" (click)="fileInput.click()"
|
||||||
|
(dragover)="onDragOver($event)" (drop)="onDrop($event)">
|
||||||
|
<input #fileInput type="file" multiple (change)="onFileSelected($event)" hidden
|
||||||
|
accept=".jpg,.jpeg,.png,.pdf,.stl,.step,.stp,.3mf,.obj">
|
||||||
|
<p>{{ 'CONTACT.DROP_FILES' | translate }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="file-grid" *ngIf="files().length > 0">
|
||||||
|
<div class="file-item" *ngFor="let file of files(); let i = index">
|
||||||
|
<button type="button" class="remove-btn" (click)="removeFile(i)">×</button>
|
||||||
|
<img *ngIf="file.type === 'image'" [src]="file.url" class="preview-img">
|
||||||
|
<div *ngIf="file.type !== 'image'" class="file-icon">
|
||||||
|
<span *ngIf="file.type === 'pdf'">PDF</span>
|
||||||
|
<span *ngIf="file.type === '3d'">3D</span>
|
||||||
|
</div>
|
||||||
|
<div class="file-name" [title]="file.file.name">{{ file.file.name }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="actions">
|
||||||
|
<app-button type="submit" [disabled]="form.invalid || sent()">
|
||||||
|
{{ sent() ? ('CONTACT.MSG_SENT' | translate) : ('CONTACT.SEND' | translate) }}
|
||||||
|
</app-button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
|||||||
@@ -131,3 +131,41 @@ app-input.col { width: 100%; }
|
|||||||
display: flex; align-items: center; justify-content: center; line-height: 1;
|
display: flex; align-items: center; justify-content: center; line-height: 1;
|
||||||
&:hover { background: red; }
|
&:hover { background: red; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Success State */
|
||||||
|
.success-state {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
padding: var(--space-8) var(--space-4);
|
||||||
|
gap: var(--space-4);
|
||||||
|
min-height: 300px; /* Ensure visual balance */
|
||||||
|
|
||||||
|
.success-icon {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
color: var(--color-success, #10b981);
|
||||||
|
margin-bottom: var(--space-2);
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
max-width: 400px;
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -161,13 +161,14 @@ export class ContactFormComponent {
|
|||||||
console.log('Form Submit:', formData);
|
console.log('Form Submit:', formData);
|
||||||
|
|
||||||
this.sent.set(true);
|
this.sent.set(true);
|
||||||
setTimeout(() => {
|
|
||||||
this.sent.set(false);
|
|
||||||
this.form.reset({ requestType: 'custom', isCompany: false });
|
|
||||||
this.files.set([]);
|
|
||||||
}, 3000);
|
|
||||||
} else {
|
} else {
|
||||||
this.form.markAllAsTouched();
|
this.form.markAllAsTouched();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetForm() {
|
||||||
|
this.sent.set(false);
|
||||||
|
this.form.reset({ requestType: 'custom', isCompany: false });
|
||||||
|
this.files.set([]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,6 +126,9 @@
|
|||||||
"LABEL_EMAIL": "Email *",
|
"LABEL_EMAIL": "Email *",
|
||||||
"LABEL_NAME": "Name *",
|
"LABEL_NAME": "Name *",
|
||||||
"MSG_SENT": "Sent!",
|
"MSG_SENT": "Sent!",
|
||||||
"ERR_MAX_FILES": "Max 15 files limit reached."
|
"ERR_MAX_FILES": "Max 15 files limit reached.",
|
||||||
|
"SUCCESS_TITLE": "Message Sent Successfully",
|
||||||
|
"SUCCESS_DESC": "Thank you for contacting us. We have received your message and will send you a recap email shortly.",
|
||||||
|
"SEND_ANOTHER": "Send Another Message"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,9 @@
|
|||||||
"LABEL_EMAIL": "Email *",
|
"LABEL_EMAIL": "Email *",
|
||||||
"LABEL_NAME": "Nome *",
|
"LABEL_NAME": "Nome *",
|
||||||
"MSG_SENT": "Inviato!",
|
"MSG_SENT": "Inviato!",
|
||||||
"ERR_MAX_FILES": "Limite massimo di 15 file raggiunto."
|
"ERR_MAX_FILES": "Limite massimo di 15 file raggiunto.",
|
||||||
|
"SUCCESS_TITLE": "Messaggio Inviato con Successo",
|
||||||
|
"SUCCESS_DESC": "Grazie per averci contattato. Abbiamo ricevuto il tuo messaggio e ti invieremo una email di riepilogo a breve.",
|
||||||
|
"SEND_ANOTHER": "Invia un altro messaggio"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user