- Contratos, tarjetas, postulaciones, categorías y reportes - Servicios: auth, ichamba, env, language, firebase, interceptor - Guards, modelos, componentes y páginas de verificación - Configuración: angular.json, tsconfig, polyfills, environments - Capacitor: capacitor.config.json y android settings Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
87 lines
1.9 KiB
TypeScript
87 lines
1.9 KiB
TypeScript
import { Component, Input, Output, EventEmitter, forwardRef } from '@angular/core';
|
|
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
|
|
@Component({
|
|
selector: 'rating',
|
|
template: `
|
|
<div class="rating-container" [class.readonly]="readonly === 'true'">
|
|
<ion-icon
|
|
*ngFor="let star of stars; let i = index"
|
|
[name]="i < value ? 'star' : 'star-outline'"
|
|
[class.selected]="i < value"
|
|
[class.large]="size === 'large'"
|
|
(click)="onStarClick(i + 1)">
|
|
</ion-icon>
|
|
</div>
|
|
`,
|
|
styles: [`
|
|
.rating-container {
|
|
display: flex;
|
|
justify-content: center;
|
|
gap: 8px;
|
|
}
|
|
ion-icon {
|
|
font-size: 24px;
|
|
color: #ffc107;
|
|
cursor: pointer;
|
|
}
|
|
ion-icon.large {
|
|
font-size: 36px;
|
|
}
|
|
ion-icon.selected {
|
|
color: #ffc107;
|
|
}
|
|
ion-icon:not(.selected) {
|
|
color: #ccc;
|
|
}
|
|
.readonly ion-icon {
|
|
cursor: default;
|
|
}
|
|
`],
|
|
providers: [
|
|
{
|
|
provide: NG_VALUE_ACCESSOR,
|
|
useExisting: forwardRef(() => RatingComponent),
|
|
multi: true
|
|
}
|
|
],
|
|
standalone: false
|
|
})
|
|
export class RatingComponent implements ControlValueAccessor {
|
|
@Input() readonly: string = 'false';
|
|
@Input() size: string = 'default';
|
|
@Input() max: number = 5;
|
|
@Output() rateChange = new EventEmitter<number>();
|
|
|
|
value: number = 0;
|
|
stars: number[] = [];
|
|
|
|
private onChange: (value: number) => void = () => {};
|
|
private onTouched: () => void = () => {};
|
|
|
|
ngOnInit() {
|
|
this.stars = Array(this.max).fill(0);
|
|
}
|
|
|
|
onStarClick(rating: number) {
|
|
if (this.readonly !== 'true') {
|
|
this.value = rating;
|
|
this.onChange(this.value);
|
|
this.onTouched();
|
|
this.rateChange.emit(this.value);
|
|
}
|
|
}
|
|
|
|
writeValue(value: number): void {
|
|
this.value = value || 0;
|
|
}
|
|
|
|
registerOnChange(fn: (value: number) => void): void {
|
|
this.onChange = fn;
|
|
}
|
|
|
|
registerOnTouched(fn: () => void): void {
|
|
this.onTouched = fn;
|
|
}
|
|
}
|