wheel

 avatar
FadadOussama
typescript
5 months ago
9.0 kB
2
Indexable
import { AfterViewInit, Component, OnInit, SimpleChanges, ViewEncapsulation } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { Subject, takeUntil } from "rxjs";
import { Wheel } from "spin-wheel-ts";
import { LasService } from "../core/services/las.service";
import { environment } from "src/environments/environment";
import { FormBuilder, FormControl, FormGroup, Validators } from "@angular/forms";
import { RestApiService } from "src/app/core/services/rest-api.service";

@Component({
	selector: "app-wheel",
	templateUrl: "./wheel.component.html",
	styleUrl: "./wheel.component.scss",
	encapsulation: ViewEncapsulation.None,
})
export class WheelComponent implements OnInit, AfterViewInit {
	unsubscriber: Subject<any> = new Subject<any>();
	backendURL = environment.backendURL;
	ngStyle: any;
	wheelInput: string = "";
	selectedRegion: string = "";

	wheel: any;
	wheelSpinned = false;
	wheelSpinning = false;
	wheelData: any = null;
	headerTitle: string;
	footerBtnText = "Faisons tourner la roue";

	products: any;
	props: any;
	slug: string;

	form: FormGroup;
	isUcNotFound: boolean = false;
	isUcUsed: boolean = false;
	isBtnDisabled: boolean = false;
	winningProduct: any = "";

	inputWarningMessage: string = "";

	// LAS Log
	lasData: any;
	stepName: string;

	constructor(
		private router: Router,
		private activatedRoute: ActivatedRoute,
		private lasService: LasService,
		private fb: FormBuilder,
		private restApiService: RestApiService
	) {
		const revealTouchGame = JSON.parse(localStorage.getItem("reveal-touch-game"));
		const chooseVenueObj = JSON.parse(localStorage.getItem("choose-venue-display"));
		const spotMlbGame = JSON.parse(localStorage.getItem("spot-mlb-game"));
		const hasValue = JSON.parse(localStorage.getItem("hasValue"));

		if (!(chooseVenueObj || hasValue || revealTouchGame)) {
			// Redirect to the game-chooser page if the user already won int the wheel
			this.router.navigate(["../game-chooser"], {
				relativeTo: this.activatedRoute,
			});
		}
	}

	ngOnInit() {
		this.lasService.campaignSubject.pipe(takeUntil(this.unsubscriber)).subscribe((data: any) => {
			if (data != null) {
				// Wheel Data
				this.wheelData = data.campaign.steps.filter((e) => e.__component === "wheel.wheel")[0];
				this.headerTitle = this.wheelData.headerTitle;
				this.footerBtnText = this.wheelData.ctaText;

				// Log step
				this.stepName = this.wheelData.stepLabel;
				this.lasService.lasSubject.pipe(takeUntil(this.unsubscriber)).subscribe((data) => {
					if (data != null) {
						this.lasData = data;
						this.createJourney(this.lasData.id, this.stepName);
					}
				});

				// Set theme --------------------
				const theme = data.campaign.theme;
				this.ngStyle = { color: theme.textColor, "background-color": theme.bgColor, "background-image": "url(" + this.backendURL + theme.bgImg.url + ")" };
				if (this.wheelData.bgImg != null) {
					console.log(this.wheelData.bgImg.url);
					this.ngStyle["background-image"] = "url(" + this.backendURL + this.wheelData.bgImg.url + ")";
				}
			}
		});

		this.form = this.fb.group({
			uc: ["", [Validators.required]],
			region: [null, Validators.required],
		});
	}

	ngAfterViewInit(): void {
		this.lasService.campaignSubject.pipe(takeUntil(this.unsubscriber)).subscribe((data: any) => {
			if (data != null) {
				// Product Data
				this.products = data.campaign.winnings.map((item: any) => ({
					image: this.backendURL + item.product.imgWheel.url,
					imageRadius: 0.6,
					imageScale: 0.4,
				}));

				// Slag
				this.slug = data.campaign.slug;

				// Add the wheel element and implement the wheel functionality
				this.props = {
					name: "Movies",
					isInteractive: false,

					borderWidth: 30,
					borderColor: "#D63231",

					itemBackgroundColors: ["#D63231", "#F9FAF4"],

					lineWidth: 2,
					lineColor: "#3f3f3f",

					rotationSpeedMax: 700,
					overlayImage: "/assets/las/images/wheelOverlay.png",
					rotationResistance: -70,

					items: this.products,
				};

				// Integration of the regular expression in the wheel input
				const inputElement = document.getElementById("wheelInputId") as HTMLInputElement;
				if (inputElement) {
					inputElement.addEventListener("input", (event: Event) => {
						const input = event.target as HTMLInputElement;
						const value = input.value;

						const newValue = value.replace(/[^a-zA-Z0-9]/g, "");

						if (value !== newValue) {
							input.value = newValue;
						}
					});
				}

				const container = document.querySelector(".wheel-wrapper");
				const btnSpin = document.getElementById("wheelBtn");
				if (container !== null) {
					// @ts-ignore
					this.wheel = new Wheel(container, this.props);

					this.wheel.onSpin = (e) => {
						this.wheelSpinning = true;
						this.winningProduct = data.campaign.winnings[e.targetItemIndex];
					};

					this.wheel.onRest = (e) => {
						this.wheelSpinned = true;
						this.wheelSpinning = false;
						this.footerBtnText = "Félicitations, Rejouer";

						localStorage.setItem("winningProduct", JSON.stringify(this.winningProduct));

						let storedProduct = JSON.parse(localStorage.getItem("winningProduct"));
						storedProduct.slug = this.slug;
						localStorage.setItem("winningProduct", JSON.stringify(storedProduct));

						setTimeout(() => {
							localStorage.removeItem("reveal-touch-game");
							localStorage.removeItem("choose-venue-display");
							localStorage.removeItem("spot-mlb-game");
							localStorage.setItem("hasValue", "false");

							this.router.navigate(["../result"], {
								relativeTo: this.activatedRoute,
							});
						}, 400);
					};
				}
			}
		});
	}

	// --------------------------------------------------------------------------------------------
	// @ Events
	// --------------------------------------------------------------------------------------------
	onRegionChange(event: Event) {
		this.selectedRegion = (event.target as HTMLSelectElement).value;
	}

	onFooterBtnClick() {
		// Form condition
		if (this.form.valid) {
			const uc = this.form.get("uc").value.toUpperCase();
			this.isBtnDisabled = true;

			this.restApiService
				.searchUC(uc)
				.pipe(takeUntil(this.unsubscriber))
				.subscribe({
					next: ({ data }) => {
						this.isUcUsed = data.used;

						// Use unique code
						if (!this.isUcUsed) {
							this.restApiService
								.useUC(uc)
								.pipe(takeUntil(this.unsubscriber))
								.subscribe({
									next: ({ data }) => {},
									error: (error) => {
										if (error.status === 404) {
											console.log(error.message);
										}
									},
								});
						}

						// Wheel condition
						if (!this.wheelSpinning && !this.isUcUsed) {
							if (!this.wheelSpinned) {
								this.wheel.spinToItem(this.getRandomIndex(this.products), 2000, false, 5);
								this.inputWarningMessage = "";
								this.isUcNotFound = false;
								this.isBtnDisabled = false;
								console.log(this.winningProduct.product.name);
								this.createJourney(this.lasData.id, this.stepName, { ucUsed: uc, productWon: this.winningProduct.product.name });
							} else {
								location.href = "/las/tutorial";
							}
						}

						// Enable button
						if (this.isUcUsed) {
							this.inputWarningMessage = "Le code est déja utilisé";
							this.isBtnDisabled = false;
						}
					},
					error: (error) => {
						if (error.status === 404) {
							this.isUcNotFound = true;
							this.inputWarningMessage = "Le code n’est pas valide";
							this.isBtnDisabled = false;
						}
					},
				});
		}
	}

	onSubmitForm() {}

	// --------------------------------------------------------------------------------------------
	// @ Functions
	// --------------------------------------------------------------------------------------------
	getRandomIndex(array: any[]): number {
		return Math.floor(Math.random() * array.length);
	}

	isRegionSelected(): boolean {
		return this.selectedRegion !== "";
	}

	isWheelInputFilled(): boolean {
		return this.wheelInput.trim().length >= 5;
	}

	handleButtonDisabled() {
		const wheelCondition = !this.wheelSpinned && (this.wheelSpinning || !(this.isRegionSelected() && this.isWheelInputFilled()));
		return this.isBtnDisabled || wheelCondition;
	}

	createJourney(lasId: number, stepLabel: string, additionalData = {}) {
		this.lasService
			.createJourney(lasId, stepLabel, additionalData)
			.pipe(takeUntil(this.unsubscriber))
			.subscribe({
				next: (response) => {
					console.log("Journey wheel created:", response);
				},
				error: (error) => {
					console.error("Error creating journey:", error);
				},
			});
	}
}
Leave a Comment