PageSourceSearch

https://www.pashushala.com/pashushla/static/js/custom/modules/user…=ece0bc61561a9520adb95ec79ee941dee56b61a8

js pashushala.com collected 2026-09-24 13:50:28 UTC 39,142 bytes, 1,033 lines download raw bytes

1const userJS = {
2	init: function() {
3		const self = this;
4		self.profileDeliveryAddresses = [];
5
6		self.readProfileAddresses = function() {
7			try {
8				self.profileDeliveryAddresses = JSON.parse($("#delivery_addresses_json").val() || "[]");
9				if(!Array.isArray(self.profileDeliveryAddresses)) {
10					self.profileDeliveryAddresses = [];
11				}
12			} catch(e) {
13				self.profileDeliveryAddresses = [];
14			}
15		}
16
17		self.writeProfileAddresses = function() {
18			$("#delivery_addresses_json").val(JSON.stringify(self.profileDeliveryAddresses.slice(0, 3)));
19			var primary = self.profileDeliveryAddresses[0] || {};
20			$("input[name='addressLine1']").val(primary.delivery_address_1 || "");
21			$("input[name='addressLine2']").val(primary.delivery_address_2 || "");
22			$("#pincode").val(primary.pincode || "");
23			$("#city").val(primary.city || "");
24			$("#district").val(primary.district || "");
25			$("#state").val(primary.state || "");
26		}
27
28		self.addressCardLines = function(address) {
29			var parts = [];
30			if(address.delivery_address_1) parts.push(address.delivery_address_1);
31			if(address.delivery_address_2) parts.push(address.delivery_address_2);
32			var location = [];
33			if(address.city) location.push(address.city);
34			if(address.district && address.district != address.city) location.push(address.district);
35			if(address.state) location.push(address.state);
36			if(address.pincode) location.push(address.pincode);
37			if(location.length > 0) parts.push(location.join(", "));
38			return parts;
39		}
40
41		self.renderProfileAddresses = function() {
42			var $list = $("#profile_address_list");
43			if(!$list.length) return;
44			$list.empty();
45			$(".click-profile-address-add").toggle(self.profileDeliveryAddresses.length < 3);
46			if(self.profileDeliveryAddresses.length == 0) {
47				$list.append('<div class="profile-address-empty">No saved address yet. Add an address for faster checkout.</div>');
48				return;
49			}
50			for(var i = 0; i < self.profileDeliveryAddresses.length; i++) {
51				var address = self.profileDeliveryAddresses[i] || {};
52				var title = address.label || address.city || address.district || ("Address " + (i + 1));
53				var $card = $('<div class="profile-address-card"></div>');
54				var $title = $('<div class="profile-address-card-title"></div>').text(title);
55				if(i == 0) {
56					$title.append(' ').append($('<span class="text-green ft-12"></span>').text('(Default)'));
57				}
58				$card.append($title);
59				var $body = $('<div class="profile-address-card-body"></div>');
60				var lines = self.addressCardLines(address);
61				for(var j = 0; j < lines.length; j++) {
62					if(j > 0) $body.append('<br>');
63					$body.append(document.createTextNode(lines[j]));
64				}
65				$card.append($body);
66				var $actions = $('<div class="profile-address-card-actions"></div>');
67				$actions.append('<button type="button" class="profile-address-link click-profile-address-edit" data-index="'+i+'">Edit</button>');
68				$actions.append('<button type="button" class="profile-address-link profile-address-remove click-profile-address-remove" data-index="'+i+'">Remove</button>');
69				$card.append($actions);
70				$list.append($card);
71			}
72		}
73
74		self.clearProfileAddressForm = function() {
75			$("#profile_address_index").val("");
76			$("#profile_address_label").val("");
77			$("#profile_address_pincode").val("");
78			$("#profile_address_city").val("");
79			$("#profile_address_district").val("");
80			$("#profile_address_state").val("");
81			$("#profile_address_line1").val("");
82			$("#profile_address_line2").val("");
83			$("#profileAddressPinLabel").html("");
84		}
85
86		self.openProfileAddressForm = function(index) {
87			self.clearProfileAddressForm();
88			if(index !== "" && index !== undefined && self.profileDeliveryAddresses[index]) {
89				var address = self.profileDeliveryAddresses[index];
90				$("#profile_address_index").val(index);
91				$("#profile_address_label").val(address.label || "");
92				$("#profile_address_pincode").val(address.pincode || "");
93				$("#profile_address_city").val(address.city || "");
94				$("#profile_address_district").val(address.district || "");
95				$("#profile_address_state").val(address.state || "");
96				$("#profile_address_line1").val(address.delivery_address_1 || "");
97				$("#profile_address_line2").val(address.delivery_address_2 || "");
98				if(address.pincode) pincodeJS.getPinCode('profile_address_pincode', 'profileAddressPinLabel');
99			}
100			$("#profile_address_form").show();
101			$("#profile_address_line1").focus();
102		}
103
104		self.saveProfileAddressFromForm = function() {
105			validationJS.clearError();
106			var requiredFields = ["profile_address_line1", "profile_address_pincode"];
107			for(var i = 0; i < requiredFields.length; i++) {
108				if($("#" + requiredFields[i]).val() == "") {
109					validationJS.raiseMandatoryError("#" + requiredFields[i]);
110					return false;
111				}
112			}
113			var pincode = validationJS.removeHeadingZero($("#profile_address_pincode").val());
114			if(!/^\d*$/.test(pincode) || pincode.length != 6) {
115				validationJS.raiseInputValidationError("#profile_address_pincode");
116				return false;
117			}
118			var index = $("#profile_address_index").val();
119			if(index === "" && self.profileDeliveryAddresses.length >= 3) {
120				utilJS.popupAlert("You can save maximum 3 addresses.");
121				return false;
122			}
123			var address = {
124				id: index !== "" && self.profileDeliveryAddresses[index] ? self.profileDeliveryAddresses[index].id : new Date().getTime().toString(),
125				label: $("#profile_address_label").val() || $("#profile_address_city").val() || $("#profile_address_district").val() || "Address",
126				delivery_address_1: $("#profile_address_line1").val(),
127				delivery_address_2: $("#profile_address_line2").val(),
128				pincode: parseInt(pincode),
129				city: $("#profile_address_city").val(),
130				district: $("#profile_address_district").val(),
131				state: $("#profile_address_state").val(),
132				createdAt: index !== "" && self.profileDeliveryAddresses[index] ? self.profileDeliveryAddresses[index].createdAt : new Date(),
133				updatedAt: new Date()
134			};
135			if(index !== "") {
136				self.profileDeliveryAddresses[parseInt(index)] = address;
137			} else {
138				self.profileDeliveryAddresses.push(address);
139			}
140			self.writeProfileAddresses();
141			self.renderProfileAddresses();
142			$("#profile_address_form").hide();
143		}
144
145		self.saveUserProfile = function(type='') {
146			self.writeProfileAddresses();
147			if(type!='profile'){
148				if ($("#aadhar_number") && $("#aadhar_number").val() != '') {
149					$("#aadhar_number").val(validationJS.removeHeadingZero($("#aadhar_number").val()));
150					if ($("#aadhar_number").val().length != 12) {
151						$("#aadhar_number").addClass("red_border");
152						$("#aadhar_number").focus();
153						return false;
154					}
155				}
156
157				if ($("#pan_number") && $("#pan_number").val() != '') {
158					var regex = /[A-Z]{5}[0-9]{4}[A-Z]{1}$/; 
159					if (!regex.test($("#pan_number").val())) {
160						$("#pan_number").addClass("red_border");
161						$("#pan_number").focus();
162						return false;
163					} 
164				}
165
166				if ($("#voter_number") && $("#voter_number").val() != '') {
167					var regex = /[a-zA-Z]{3}[0-9]{7}?$/; 
168					if (!regex.test($("#voter_number").val())) {
169						$("#voter_number").addClass("red_border");
170						$("#voter_number").focus();
171						return false;
172					} 
173				}
174			}
175			$("#saveBtn").addClass("d-none");
176			$(".loadMoreImg").removeClass("d-none");
177			$.ajax({
178				type: $("#updateProfileForm").attr("method"),
179				url: $("#updateProfileForm").attr("action"),
180				data: $("#updateProfileForm").serialize(),
181				success: function (data) {
182					$(".loadMoreImg").addClass("d-none");
183					if(data && data.status && data.status=="success") {
184						if(type!='profile'){
185							utilJS.popupAlert(data.message);
186						}
187					} else if(data && data.status && data.status=="fail") {
188						utilJS.popupAlert(data.message);
189					} else {
190						utilJS.popupAlert("Something Went Wrong, Try after sometime!");
191					} 
192					$("#saveBtn").removeClass("d-none");
193				},
194				error: function (XMLHttpRequest, textStatus, errorThrown) {
195					console.log(errorThrown);
196					$(".loadMoreImg").addClass("d-none");
197					$("#saveBtn").removeClass("d-none");
198					if(errorThrown=='Forbidden'){ utilJS.popupAlert("Access Denied, Please Contact Administrator") }else{ utilJS.popupAlert("Something Went Wrong, Try after sometime!"); }
199				},
200			});
201		}
202
203		self.uploadProfileImg = function(doc) {
204			if ($("#"+doc+"ImgUpload").val() != "") {
205				$("."+doc+"LoadMoreImg").removeClass("d-none");
206				var File = $("#"+doc+"ImgUpload").get(0).files[0];
207				var formData = new FormData();
208				formData.append("upload_file", File);
209				$.ajax({
210					type: "POST",
211					enctype: "multipart/form-data",
212					url: "/action/upload/uploadFile",
213					data: formData,
214					cache: false,
215					contentType: false,
216					processData: false,
217					success: function (data) {
218						$("."+doc+"LoadMoreImg").addClass("d-none");
219						if(data && data.status && data.status=="success") {
220							$("#"+doc+"Photo").val(data.id);
221							$("#"+doc+"Img").attr("src", data.url);
222							self.saveUserProfile(doc);
223						} else if (data && data.status && data.status=="fail") {
224							utilJS.popupAlert(data.message); 
225						} else {
226							utilJS.popupAlert("Something Went Wrong, Try after sometime!");
227						} 
228					},
229					error: function (XMLHttpRequest, textStatus, errorThrown) {
230						console.log(errorThrown);
231						$("."+doc+"LoadMoreImg").addClass("d-none");
232						if(errorThrown=='Forbidden'){ utilJS.popupAlert("Access Denied, Please Contact Administrator") }else{ utilJS.popupAlert("Something Went Wrong, Try after sometime!"); }
233					},
234				});
235			}
236		}
237
238		self.saveUser = function(collection='user') {
239			validationJS.clearError();
240
241			if ($("#phone").val() != "") {
242				var pat = /^\d*$/;
243				if (!pat.test($("#phone").val())) {
244					validationJS.raiseInputValidationError("#phone");
245					return false;
246				}
247
248				$("#phone").val(validationJS.removeHeadingZero($("#phone").val()));
249				if ($("#phone").val().length != 10) {
250					validationJS.raiseInputValidationError("#phone");
251					return false;
252				}
253			}
254
255
256			if ($("#email").val() != "") {
257				if (!validationJS.validateEmail($("#email").val())) {
258					validationJS.raiseInputValidationError("#email");
259					return false;
260				}
261			}
262
263			var feildList = [
264				"username",
265				"phone",
266			];
267			for (var i = 0; i < feildList.length; i++) {
268				if ($("#" + feildList[i]).val() == "" || $("#" + feildList[i]).val() == null) {
269					validationJS.raiseMandatoryError("#" + feildList[i]);
270					return false;
271				}
272			}
273
274			if ($("#user_id").val().trim() == "") {
275				if ($("#password").val() == "" || $("#password").val() == null) {
276					validationJS.raiseMandatoryError("#password");
277					return false;
278				}
279				if ($("#confirm_password").val() == "" || $("#confirm_password").val() == null) {
280					validationJS.raiseMandatoryError("#confirm_password");
281					return false;
282				}
283			}
284
285			if ($("#password").val() != "") {
286				if ($("#password").val() != $("#confirm_password").val()) {
287					validationJS.raiseInputValidationError("#confirm_password", "Password and Confirm Password Does not match");
288					return false;
289				}
290			}
291
292			$("#saveBtn").addClass("d-none");
293			$(".loader_img").fadeIn();
294			$.ajax({
295				type: $("#userSaveForm").attr("method"),
296				url: $("#userSaveForm").attr("action"),
297				data: $("#userSaveForm").serialize(),
298				success: function (data) {
299					if(data && data.status && data.status=="success") {
300						utilJS.popupSuccess(data.message, 'Success');
301						if($("#orgID").val() != ''){
302							mainJS.populatePageData("/page/common/updateCollection?collection=organisationInfo&id="+$("#orgID").val());
303						} else {
304							$("#saveBtn").removeClass("d-none");
305							$(".loader_img").fadeOut();
306							//commonJS.loadSearchCollection(collection);
307						}
308
309					} else if (data && data.status && data.status=="fail") {
310						utilJS.popupAlert(data.message);
311						$(".loader_img").fadeOut();
312						$("#saveBtn").removeClass("d-none");
313					} else {
314						utilJS.popupAlert("Something Went Wrong, Try after sometime!");
315						$(".loader_img").fadeOut();
316						$("#saveBtn").removeClass("d-none");
317					} 
318				},
319				error: function (XMLHttpRequest, textStatus, errorThrown) {
320					console.log(errorThrown);
321					$(".loader_img").fadeOut();
322					$("#saveBtn").removeClass("d-none");
323					if(errorThrown=='Forbidden'){ utilJS.popupAlert("Access Denied, Please Contact Administrator") }else{ utilJS.popupAlert("Something Went Wrong, Try after sometime!"); }
324				},
325			}).done(function (results) {});
326		}
327
328		self.onChangeUserType = function() {
329			$(".pmDiv, .orgDiv, .isHandlerDiv, .isMonitoredDiv").addClass("d-none");
330			var checkedValues = $(".change-userType:checked").map(function () {
331            	return this.value;
332        	}).get();
333			if (checkedValues.indexOf("Pashumitra") >= 0 ) {
334				$(".pmDiv").removeClass("d-none");
335			} 
336
337			if (checkedValues.indexOf("Super Admin") >= 0) {
338				$(".isMonitoredDiv").removeClass("d-none");
339				$(".isHandlerDiv").removeClass("d-none");
340			}
341
342			if (checkedValues.indexOf("Supplier") >= 0) {
343				$(".orgDiv").removeClass("d-none");
344				$(".isHandlerDiv").removeClass("d-none");
345			} 
346
347			if (checkedValues.indexOf("Insurer") >= 0) {
348				$(".isHandlerDiv").removeClass("d-none");
349			} 
350
351			if (checkedValues.indexOf("Vet") >= 0) {
352				$(".isHandlerDiv").removeClass("d-none");
353			} 
354		}
355
356		self.onChangeUserIsActive = function() {
357			if ($("#isActive").val() == "0") {
358				$("#isMonitored").val("0");
359				$("#isEnquiryHandler").val("0");
360			} 
361		}
362
363		self.saveUserScreens = function(collection='user', id='') {
364			$("#saveBtn").addClass("d-none");
365			$(".loader_img").fadeIn();
366			$.ajax({
367				type: $("#userScreenForm").attr("method"),
368				url: $("#userScreenForm").attr("action"),
369				data: $("#userScreenForm").serialize(),
370				success: function (data) {
371					if(data && data.status && data.status=="success") {
372						utilJS.popupSuccess('User screens updated successfully');
373						if(id!=''){
374							mainJS.populatePageData('/page/common/updateCollection?collection='+collection+'&id='+id);
375						} else {
376							commonJS.loadSearchCollection(collection);
377						}
378
379					} else if (data && data.status && data.status=="fail") {
380						utilJS.popupAlert(data.message);
381						$(".loader_img").fadeOut();
382						$("#saveBtn").removeClass("d-none");
383					} else {
384						utilJS.popupAlert("Something Went Wrong, Try after sometime!");
385						$(".loader_img").fadeOut();
386						$("#saveBtn").removeClass("d-none");
387					} 
388				},
389				error: function (XMLHttpRequest, textStatus, errorThrown) {
390					console.log(errorThrown);
391					$(".loader_img").fadeOut();
392					$("#saveBtn").removeClass("d-none");
393					if(errorThrown=='Forbidden'){ utilJS.popupAlert("Access Denied, Please Contact Administrator") }else{ utilJS.popupAlert("Something Went Wrong, Try after sometime!"); }
394				},
395			}).done(function (results) {});
396		}
397
398		self.saveUserPrivileges = function(collection='user', id='') {
399			$("#saveBtn").addClass("d-none");
400			$(".loader_img").fadeIn();
401			$.ajax({
402				type: $("#userPrivilegeForm").attr("method"),
403				url: $("#userPrivilegeForm").attr("action"),
404				data: $("#userPrivilegeForm").serialize(),
405				success: function (data) {
406					if(data && data.status && data.status=="success") {
407						utilJS.popupSuccess('User privileges updated successfully');
408						if(id!=''){
409							mainJS.populatePageData('/page/common/updateCollection?collection='+collection+'&id='+id);
410						} else {
411							commonJS.loadSearchCollection(collection);
412						}
413
414					} else if (data && data.status && data.status=="fail") {
415						utilJS.popupAlert(data.message);
416						$(".loader_img").fadeOut();
417						$("#saveBtn").removeClass("d-none");
418					} else {
419						utilJS.popupAlert("Something Went Wrong, Try after sometime!");
420						$(".loader_img").fadeOut();
421						$("#saveBtn").removeClass("d-none");
422					} 
423				},
424				error: function (XMLHttpRequest, textStatus, errorThrown) {
425					console.log(errorThrown);
426					$(".loader_img").fadeOut();
427					$("#saveBtn").removeClass("d-none");
428					if(errorThrown=='Forbidden'){ utilJS.popupAlert("Access Denied, Please Contact Administrator") }else{ utilJS.popupAlert("Something Went Wrong, Try after sometime!"); }
429				},
430			}).done(function (results) {});
431		}
432
433		self.markSoldFunction = function() {
434			let id = $("#animal_id").val();
435			$("#animal_"+id).addClass("d-none");
436			$.ajax({
437				type: $("#animalUpdateForm1").attr("method"),
438				url: $("#animalUpdateForm1").attr("action"),
439				data: $("#animalUpdateForm1").serialize(),
440				success: function (data) {
441					if(data && data.status && data.status=="success") {
442						utilJS.popupAlert("Animal marked as sold", function() { 
443							mainJS.populatePageData(window.location.href.replace(window.location.origin, ""));
444						});
445					} else if (data && data.status && data.status=="fail") {
446						utilJS.popupAlert(data.message);
447					} else {
448						utilJS.popupAlert("Something Went Wrong, Try after sometime!");
449					} 
450				},
451				error: function (XMLHttpRequest, textStatus, errorThrown) {
452					console.log(errorThrown);
453					if(errorThrown=='Forbidden'){ utilJS.popupAlert("Access Denied, Please Contact Administrator") }else{ utilJS.popupAlert("Something Went Wrong, Try after sometime!"); }
454				},
455			}).done(function (results) {});
456		}
457
458		self.blockUser = function() {
459			$(".click-blockUserBtn").addClass("d-none");
460			$("#saveBtn").addClass("d-none");
461			$(".loader_img").fadeIn();
462			$.ajax({
463				type: "POST",
464				url: "/action/user/blockUser",
465				data: $("#userSaveForm").serialize(),
466				success: function (data) {
467					if(data && data.status && data.status=="success") {
468						utilJS.popupSuccess(data.message, 'Success', function() { 
469							mainJS.populatePageData(window.location.href.replace(window.location.origin, ""));
470						});
471						$("#saveBtn").removeClass("d-none");
472						$(".loader_img").fadeOut();
473					} else if (data && data.status && data.status=="fail") {
474						utilJS.popupAlert(data.message);
475						$(".loader_img").fadeOut();
476						$("#saveBtn").removeClass("d-none");
477						$(".click-blockUserBtn").removeClass("d-none");
478					} else {
479						utilJS.popupAlert("Something Went Wrong, Try after sometime!");
480						$(".loader_img").fadeOut();
481						$("#saveBtn").removeClass("d-none");
482						$(".click-blockUserBtn").removeClass("d-none");
483					} 
484				},
485				error: function (XMLHttpRequest, textStatus, errorThrown) {
486					console.log(errorThrown);
487					$(".loader_img").fadeOut();
488					$("#saveBtn").removeClass("d-none");
489					$(".click-blockUserBtn").removeClass("d-none");
490					if(errorThrown=='Forbidden'){ utilJS.popupAlert("Access Denied, Please Contact Administrator") }else{ utilJS.popupAlert("Something Went Wrong, Try after sometime!"); }
491				},
492			}).done(function (results) {});
493		}
494
495
496		self.setupProfilePhotoUpload = function() {
497			var pcpWrap = document.getElementById('pcp-avatar-wrap');
498			var pcpInput = document.getElementById('pcp-file-input');
499			var pcpModal = document.getElementById('pcp-modal');
500			var pcpImg = document.getElementById('pcp-img');
501			var pcpViewport = document.getElementById('pcp-viewport');
502			if (!pcpWrap || !pcpInput || !pcpModal || !pcpImg) return;
503
504			var state = { scale: 1, rotation: 0, tx: 0, ty: 0, dragging: false, sx: 0, sy: 0, stx: 0, sty: 0 };
505			var vpSize = 280;
506
507			function applyTransform() {
508				pcpImg.style.transform = 'translate(calc(-50% + ' + state.tx + 'px), calc(-50% + ' + state.ty + 'px)) scale(' + state.scale + ') rotate(' + state.rotation + 'deg)';
509			}
510
511			function autoFit() {
512				var minScale = Math.max(vpSize / pcpImg.naturalWidth, vpSize / pcpImg.naturalHeight);
513				state.scale = Math.max(minScale, 1);
514				state.tx = 0; state.ty = 0;
515				document.getElementById('pcp-zoom-range').value = Math.round(state.scale * 100);
516				applyTransform();
517			}
518
519			// Open file picker
520			pcpWrap.addEventListener('click', function() {
521				pcpInput.value = '';
522				pcpInput.click();
523			});
524
525			// File selected → show modal
526			pcpInput.addEventListener('change', function() {
527				var file = this.files[0];
528				if (!file || !file.type.startsWith('image/')) return;
529				var reader = new FileReader();
530				reader.onload = function(e) {
531					state.rotation = 0; state.tx = 0; state.ty = 0; state.scale = 1;
532					pcpImg.onload = function() { autoFit(); };
533					pcpImg.src = e.target.result;
534					pcpModal.style.display = 'flex';
535					document.body.style.overflow = 'hidden';
536				};
537				reader.readAsDataURL(file);
538			});
539
540			// Mouse drag
541			pcpImg.addEventListener('mousedown', function(e) {
542				e.preventDefault();
543				state.dragging = true; state.sx = e.clientX; state.sy = e.clientY;
544				state.stx = state.tx; state.sty = state.ty;
545				pcpImg.classList.add('pcp-dragging');
546			});
547			document.addEventListener('mousemove', function(e) {
548				if (!state.dragging) return;
549				state.tx = state.stx + (e.clientX - state.sx);
550				state.ty = state.sty + (e.clientY - state.sy);
551				applyTransform();
552			});
553			document.addEventListener('mouseup', function() {
554				state.dragging = false;
555				pcpImg.classList.remove('pcp-dragging');
556			});
557
558			// Touch drag
559			pcpImg.addEventListener('touchstart', function(e) {
560				if (e.touches.length === 1) {
561					state.dragging = true;
562					state.sx = e.touches[0].clientX; state.sy = e.touches[0].clientY;
563					state.stx = state.tx; state.sty = state.ty;
564				}
565			}, { passive: true });
566			document.addEventListener('touchmove', function(e) {
567				if (!state.dragging || e.touches.length !== 1) return;
568				state.tx = state.stx + (e.touches[0].clientX - state.sx);
569				state.ty = state.sty + (e.touches[0].clientY - state.sy);
570				applyTransform();
571			}, { passive: true });
572			document.addEventListener('touchend', function() { state.dragging = false; });
573
574			// Zoom controls
575			document.getElementById('pcp-zoom-range').addEventListener('input', function() {
576				state.scale = parseInt(this.value) / 100;
577				applyTransform();
578			});
579			document.getElementById('pcp-zoom-in').addEventListener('click', function() {
580				state.scale = Math.min(state.scale + 0.15, 3);
581				document.getElementById('pcp-zoom-range').value = Math.round(state.scale * 100);
582				applyTransform();
583			});
584			document.getElementById('pcp-zoom-out').addEventListener('click', function() {
585				var minS = Math.max(vpSize / (pcpImg.naturalWidth || vpSize), vpSize / (pcpImg.naturalHeight || vpSize));
586				state.scale = Math.max(state.scale - 0.15, minS);
587				document.getElementById('pcp-zoom-range').value = Math.round(state.scale * 100);
588				applyTransform();
589			});
590
591			// Rotate
592			document.getElementById('pcp-rotate-left').addEventListener('click', function() {
593				state.rotation -= 90; applyTransform();
594			});
595			document.getElementById('pcp-rotate-right').addEventListener('click', function() {
596				state.rotation += 90; applyTransform();
597			});
598
599			// Close modal
600			function closeModal() {
601				pcpModal.style.display = 'none';
602				document.body.style.overflow = '';
603				pcpInput.value = '';
604			}
605			document.getElementById('pcp-modal-close').addEventListener('click', closeModal);
606			document.getElementById('pcp-cancel').addEventListener('click', closeModal);
607			document.getElementById('pcp-modal-backdrop').addEventListener('click', closeModal);
608
609			// Crop & Save
610			document.getElementById('pcp-crop-save').addEventListener('click', function() {
611				var outputSize = 400;
612				var canvas = document.createElement('canvas');
613				canvas.width = outputSize;
614				canvas.height = outputSize;
615				var ctx = canvas.getContext('2d');
616
617				// Replicate the visual transform: image center at (vpSize/2 + tx, vpSize/2 + ty)
618				// rotated by rotation and scaled by scale around that center.
619				var renderScale = state.scale * (outputSize / vpSize);
620				ctx.save();
621				ctx.translate(outputSize / 2 + state.tx * (outputSize / vpSize), outputSize / 2 + state.ty * (outputSize / vpSize));
622				ctx.rotate(state.rotation * Math.PI / 180);
623				ctx.scale(renderScale, renderScale);
624				ctx.drawImage(pcpImg, -pcpImg.naturalWidth / 2, -pcpImg.naturalHeight / 2);
625				ctx.restore();
626
627				// Show loader
628				document.getElementById('pcp-save-label').classList.add('d-none');
629				document.getElementById('pcp-save-loader').classList.remove('d-none');
630				document.getElementById('pcp-crop-save').disabled = true;
631
632				canvas.toBlob(function(blob) {
633					var fd = new FormData();
634					fd.append('upload_file', blob, 'profile.jpg');
635					$.ajax({
636						type: 'POST',
637						url: '/action/upload/uploadFile',
638						data: fd,
639						contentType: false,
640						processData: false,
641						success: function(data) {
642							if (data && data.status === 'success') {
643								document.getElementById('profilePhoto').value = data.id;
644								// Update displayed avatar
645								var existing = document.getElementById('profileAvatarImg');
646								var initial = document.getElementById('profileImage');
647								var newUrl = data.thumbnail_url || data.url;
648								if (existing) {
649									existing.src = newUrl;
650								} else {
651									var img = document.createElement('img');
652									img.id = 'profileAvatarImg';
653									img.src = newUrl;
654									img.className = 'pcp-avatar-img';
655									img.alt = 'Profile Photo';
656									if (initial) pcpWrap.removeChild(initial);
657									pcpWrap.insertBefore(img, document.getElementById('pcp-avatar-overlay'));
658								}
659								// Save link to profile via AJAX (avoid full-page navigation to raw JSON)
660								$.ajax({
661									type: 'POST',
662									url: '/action/user/saveProfilePhoto',
663									data: { id: $('#id').val(), profilePhoto: $('#profilePhoto').val() },
664									success: function(resp) {
665										try { sessionStorage.removeItem('pm_header_photo'); } catch(e) {}
666										closeModal();
667										utilJS.popupAlert((resp && resp.message) || 'Profile photo updated!');
668									},
669									error: function() {
670										closeModal();
671										utilJS.popupAlert('Could not save photo. Please try again.');
672									}
673								});
674							} else {
675								utilJS.popupAlert((data && data.message) || 'Upload failed. Please try again.');
676							}
677						},
678						error: function() { utilJS.popupAlert('Upload failed. Please check your connection.'); },
679						complete: function() {
680							document.getElementById('pcp-save-label').classList.remove('d-none');
681							document.getElementById('pcp-save-loader').classList.add('d-none');
682							document.getElementById('pcp-crop-save').disabled = false;
683						}
684					});
685				}, 'image/jpeg', 0.92);
686			});
687		};
688
689		self.setupActionsProfile = function () {
690			self.setupProfilePhotoUpload();
691
692			// Load profile stat counters
693			if($('#pcpAnimalCount').length) {
694				$.getJSON('/action/animal/myListingCount', function(d) {
695					$('#pcpAnimalCount').text(d.count !== undefined ? d.count : '0');
696				}).fail(function(){ $('#pcpAnimalCount').text('0'); });
697				$.getJSON('/action/animal/callCounts', function(d) {
698					$('#pcpCallsMade').text(d.calls_made !== undefined ? d.calls_made : '0');
699					$('#pcpCallsReceived').text(d.calls_received !== undefined ? d.calls_received : '0');
700				}).fail(function(){ $('#pcpCallsMade,#pcpCallsReceived').text('0'); });
701			}
702			$(".click-editProfile").unbind('click').click(function () {
703				mainJS.populatePageData('/page/user/editUserProfile');
704			});
705
706			// Profile-completeness "Add Photo" chip → reuse the avatar photo picker
707			$(".pcp-pc-photo").unbind('click').click(function () {
708				var w = document.getElementById('pcp-avatar-wrap');
709				if (w) { w.click(); }
710			});
711
712			$(".click-clearCache").unbind('click').click(function () {
713				$(".loader_img").fadeIn();
714				$.ajax({
715					type: 'GET',
716					url: '/clearCache',
717					success: function (data) {
718						$(".loader_img").fadeOut();
719						if(data && data.status && data.status =="success") {
720							utilJS.popupAlert("Cache Cleared") 
721						} else {
722							utilJS.popupAlert("Cache Clear Failed") 
723						}
724					},
725					error: function (XMLHttpRequest, textStatus, errorThrown) {
726						console.log(errorThrown);
727						$(".loader_img").fadeOut();
728						if(errorThrown=='Forbidden'){ 
729							utilJS.popupAlert("Access Denied, Please Contact Administrator") 
730						}else { 
731							utilJS.popupAlert("Something Went Wrong, Try after sometime!"); 
732						}
733					},
734				});
735			});
736
737			$(".change-uploadProfileImg").unbind('change').change(function () {
738				self.sellerInfoJS.uploadProfileImg('profile');
739			});
740
741			$(".click-screenLink").unbind('click').click(function () {
742				window.clearState = true;
743				mainJS.populatePageData($(this).attr("data-link"));
744			});
745
746			$(".click-changePassword").unbind('click').click(function () {
747				mainJS.populatePageData('/page/user/changePassword');
748			});
749
750			$(".click-allListings").unbind('click').click(function () {
751				utilJS.popupAlert2('<div class="ft-20 text-center">Select the listing you want to view. <div class="col d-flex justify-content-center px-0 pt-5"><input type="radio" name="r1" id="r1" value="animal" class="select-ListingType" checked> &nbsp;<label for="r1"> My Animal Listing</label> &nbsp;&nbsp;&nbsp; <input type="radio" name="r1" id="r2" value="product" class="select-ListingType"> &nbsp;<label for="r2"> My Product Listing</label> </div>', '', "Confirm");
752				$(".click-popupCloseBtn").removeClass("click-allProductListings");
753				$(".click-popupCloseBtn").addClass("click-allAnimalListings");
754				self.setupActionsProfile();
755			});
756
757			$(".select-ListingType").unbind('click').click(function () {
758				if($(this).val()=='product') {
759					$(".click-popupCloseBtn").addClass("click-allProductListings");
760					$(".click-popupCloseBtn").removeClass("click-allAnimalListings");
761				} else {
762					$(".click-popupCloseBtn").removeClass("click-allProductListings");
763					$(".click-popupCloseBtn").addClass("click-allAnimalListings");
764				}
765				self.setupActionsProfile();
766			});
767
768			$(".click-allAnimalListings").unbind('click').click(function () {
769				$("#alertPopup").modal("hide");
770				mainJS.populatePageData('/page/common/searchTable?collection=my_animals');
771			});
772
773			$(".click-viewAniamlInfo").unbind('click').click(function () {
774				mainJS.populatePageData('/page/animal/getAnimalInfo?animalName='+$(this).attr("data-id"));
775			});
776
777			$(".click-allProductListings").unbind('click').click(function () {
778				$("#alertPopup").modal("hide");
779				mainJS.populatePageData('/page/common/searchTable?collection=organisation_products');
780			});
781
782			$(".click-allOrders").unbind('click').click(function () {
783				mainJS.populatePageData('/page/common/searchTable?collection=my_orders');
784			});
785
786			$(".click-viewProductInfo").unbind('click').click(function () {
787				mainJS.populatePageData('/page/products/getProductInfo?productName='+$(this).attr("data-id"));
788			});
789
790			$(".click-upldateAniaml").unbind('click').click(function () {
791				mainJS.populatePageData('/page/common/updateCollection?collection=my_animals&id='+$(this).attr("data-id"));
792			});
793
794			$(".click-verifyAnimal").unbind('click').click(function () {
795				//$("#verify_"+$(this).attr("data-id")).addClass("d-none");
796				pageJS.displayAnimalVerificationForm($(this).attr("data-id"));
797			});
798
799			$(".click-markSold").unbind('click').click(function () {
800				$("#animal_id").val($(this).attr("data-id"));       
801				utilJS.popupConfirm("Are you sure to mark this animal as sold?", self.markSoldFunction);
802			});
803
804			$(".click-allAnimalInquiries").unbind('click').click(function () {
805				mainJS.populatePageData('/page/common/searchTable?collection=my_inquiries');
806			});
807
808			$(".click-viewEnquiry").unbind('click').click(function () {
809				mainJS.populatePageData('/page/common/viewCollection?collection=my_inquiries&id='+$(this).attr("data-id"));
810			});
811
812			$(".click-cancelEnquiry").unbind('click').click(function () {
813				$("#reason_for_cancel").val("");
814				$("#cancel_inquiry_id").val($(this).attr("data-id"));
815				$("#cancelEnquiryDiv").modal("show");
816			});
817
818			$(".click-cancelInquiry").unbind('click').click(function () {
819				commonJS.cancelInquiry();
820			});
821
822			$(".click-cancelOrderCheckbox").unbind('click').click(function () {
823				$("#reason_for_cancel_order").val("");
824				$("#cancel_order_id").val($(this).attr("data-id"));
825				$("#cancelOrderDiv").modal("show");
826			});
827
828			$(".click-cancelOrder").unbind('click').click(function () {
829				commonJS.cancelOrder();
830			});
831
832			$(".click-updateProduct").unbind('click').click(function () {
833				mainJS.populatePageData('/page/common/updateCollection?collection=organisation_products&id='+$(this).attr("data-id"));
834			});
835
836			$(".click-viewOrder").unbind('click').click(function () {
837				mainJS.populatePageData('/page/common/viewCollection?collection=my_orders&id='+$(this).attr("data-id"));
838			});
839
840			$(".click-updateProductOrder").unbind('click').click(function () {
841				mainJS.populatePageData('/page/common/updateCollection?collection=all_org_inquiryProduct&id='+$(this).attr("data-id"));
842			});
843
844			$(".click-editOrganisation").unbind('click').click(function () {
845				mainJS.populatePageData('/page/organisationInfo/editOrganisationInfo');
846			});
847
848			$(".click-editFarmInfo").unbind('click').click(function () {
849				mainJS.populatePageData('/page/farm/farmInfo');
850			});
851
852			$(".click-viewOrganisationPage").unbind('click').click(function (e) {
853				e.preventDefault();
854				mainJS.populatePageData($(this).attr("data-link"));
855			});
856
857			$(".click-editCompanyInfo, .click-editJobInfo").unbind('click').click(function () {
858				mainJS.populatePageData('/page/jobs/editJobProfile');
859			});
860
861			$(".click-btn-profile").unbind('click').click(function (e) {
862				e.preventDefault();
863				e.stopPropagation();
864				mainJS.populatePageData($(this).attr("data-url"));
865			});
866
867			$(".click-share-link").unbind('click').click(function (e) {
868				e.preventDefault();
869				e.stopPropagation();
870				if (navigator.clipboard && window.isSecureContext) {
871				    navigator.clipboard.writeText($(this).attr("data-url"));
872				} else {
873				    const textarea = $("<textarea>");
874				    textarea.val($(this).attr("data-url")).appendTo("body").select();
875				    document.execCommand("copy");
876				    textarea.remove();
877				}
878				$(this).addClass("show-tooltip");
879  				setTimeout(() => $(this).removeClass("show-tooltip"), 1500);
880			});
881
882			chartsJS.setupCharts();
883
884			try {
885				if($(document.querySelector('.lbl_profile').parentNode.parentNode.parentNode).find('.menu_items').text().trim() == "") { 
886					$(document.querySelector('.lbl_profile').parentNode.parentNode.parentNode).addClass("d-none");
887				}
888			} catch(e) {
889			}
890
891		};
892
893		self.setupActionsSaveProfile = function () {
894			pincodeJS.getPinCode('pincode', 'pinCodeLabel');
895			$("#pincode").unbind('blur').blur(function () {
896				pincodeJS.getPinCode('pincode', 'pinCodeLabel');
897			});
898			self.readProfileAddresses();
899			self.writeProfileAddresses();
900			self.renderProfileAddresses();
901
902			$(".click-profile-address-add").unbind('click').click(function () {
903				self.openProfileAddressForm("");
904			});
905
906			$(".click-profile-address-save").unbind('click').click(function () {
907				self.saveProfileAddressFromForm();
908			});
909
910			$(".click-profile-address-cancel").unbind('click').click(function () {
911				$("#profile_address_form").hide();
912			});
913
914			$("#profile_address_pincode").unbind('blur').blur(function () {
915				pincodeJS.getPinCode('profile_address_pincode', 'profileAddressPinLabel');
916			});
917
918			$(document).off('click', '.click-profile-address-edit').on('click', '.click-profile-address-edit', function () {
919				self.openProfileAddressForm(parseInt($(this).attr("data-index")));
920			});
921
922			$(document).off('click', '.click-profile-address-remove').on('click', '.click-profile-address-remove', function () {
923				var index = parseInt($(this).attr("data-index"));
924				if(window.confirm("Remove this address?")) {
925					self.profileDeliveryAddresses.splice(index, 1);
926					self.writeProfileAddresses();
927					self.renderProfileAddresses();
928				}
929			});
930
931			$(".change-uploadProfileImg").unbind('change').change(function () {
932				sellerInfoJS.uploadProfileImg($(this).attr("data-type"));
933			});
934
935			$(".click-submitBtn").unbind('click').click(function () {
936				self.saveUserProfile();
937			}); 
938
939			$(".click-changePassword").unbind('click').click(function () {
940				mainJS.populatePageData('/page/user/changePassword');
941			});
942		};
943
944		self.setupActionsSaveUser = function () {
945			pincodeJS.getPinCode('pincode', 'pinCodeLabel');
946			$("#pincode").unbind('blur').blur(function () {
947				pincodeJS.getPinCode('pincode', 'pinCodeLabel');
948			});
949
950			$(".change-userType").unbind('click').click(function () {
951				self.onChangeUserType();
952			});
953
954			$(".click-screensBtn").unbind('click').click(function () {
955				mainJS.populatePageData("/page/user/manageUserScreens?id="+$(this).attr("data-id")+"&collection="+$('#collection').val());
956			});
957
958			$(".click-privilegesBtn").unbind('click').click(function () {
959				mainJS.populatePageData("/page/user/manageUserPrivileges?id="+$(this).attr("data-id")+"&collection="+$('#collection').val());
960			});
961
962			$(".click-profileBtn").unbind('click').click(function () {
963				mainJS.populatePageData("/page/user/editUserProfile?id="+$(this).attr("data-id")+"&collection="+$('#collection').val());
964			});
965
966			$(".click-saveBtn").unbind('click').click(function () {
967				self.saveUser($('#collection').val());
968			});
969
970			$("#isActive").unbind('change').change(function () {
971				self.onChangeUserIsActive();
972			});
973
974			$(".click-editPasswordBtn").unbind('click').click(function () {
975				$('.passwordDiv').removeClass("d-none");
976				$('.click-editPasswordBtn').addClass("d-none");
977			});
978
979			$(".click-blockUserBtn").unbind('click').click(function () {
980				utilJS.popupConfirm("Are you sure to block this user?", self.blockUser);
981			});
982
983			$(".click-user-order-all").unbind('click').click(function (e) {
984				e.preventDefault();
985				mainJS.populatePageData($(this).attr("data-link"));
986			});
987
988			$(".click-user-order").unbind('click').click(function (e) {
989				e.preventDefault();
990				mainJS.populatePageData($(this).attr("data-link"));
991			});
992
993		};
994
995		self.setupActionsSaveUserScreens = function () {
996			$(".click-saveBtn").unbind('click').click(function () {
997				self.saveUserScreens($('#collection').val(), $('#id').val());
998			});
999
1000			$('.screen-checkbox').unbind('change').change(function () {
1001		        const target = $(this).data('target');
1002		        if (this.checked) {
1003		          $(target).collapse('show');
1004		          $(target).find('.defaultPrivilege').prop('checked', true);
1005		        } else {
1006		          $(target).collapse('hide');
1007		          $(target).find('input[type=checkbox]').prop('checked', false);
1008		        }
1009		    });
1010
1011		     $('.screen-checkbox').each(function () {
1012		        const target = $(this).data('target');
1013		        if (this.checked) {
1014		          $(target).collapse('show');
1015		          $(target).find('.defaultPrivilege').prop('checked', true);
1016		        } else {
1017		          $(target).collapse('hide');
1018		          $(target).find('input[type=checkbox]').prop('checked', false);
1019		        }
1020		    });
1021
1022		};
1023
1024		self.setupActionsSaveUserPrivileges = function () {
1025			$(".click-saveBtn").unbind('click').click(function () {
1026				self.saveUserPrivileges($('#collection').val(), $('#id').val());
1027			});
1028
1029		};
1030	}
1031};
1032
1033userJS.init(); for (key in userJS) { window[key] = userJS[key];}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.