PageSourceSearch

https://haroct.com.my/store/signup

html haroct.com.my collected 2026-09-24 14:04:05 UTC 122,369 bytes, 2,646 lines download raw bytes

1<!DOCTYPE html><html lang="en" amp>
2<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# website: http://ogp.me/ns/website# fb: profile: http://ogp.me/ns/profile# fb: article: http://ogp.me/ns/article#">
3    <meta charset="UTF-8" />
4    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5    <title>Haroct</title>    <meta name="viewport" content="width&#x3D;device-width,&#x20;initial-scale&#x3D;1.0,&#x20;maximum-scale&#x3D;2">
6<meta http-equiv="X-UA-Compatible" content="IE&#x3D;edge,chrome&#x3D;1">    <link rel="manifest" href="/themes/store/default/assets/manifest.json" />
7    <link rel="preconnect" href="https://fonts.gstatic.com">
8
9    <meta name="theme-color" content="#f55858"/>
10    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
11    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/build/css/intlTelInput.css">
12    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" integrity="sha512-SnH5WK+bZxgPHs44uWIX+LLJAJ9/2PkPKZ5QiAj6Ta86w+fsb2TkcmfRyVX3pBnMFcV7oQPJkl9QevSCWr3W6A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
13    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet">
14    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/select2-bootstrap-5-theme.min.css" rel="stylesheet">
15    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/driver.js@latest/dist/driver.css">
16
17    <link href="&#x2F;themes&#x2F;store&#x2F;default&#x2F;assets&#x2F;css&#x2F;fonts.css" media="screen" rel="stylesheet" type="text&#x2F;css">
18<link href="&#x2F;themes&#x2F;store&#x2F;default&#x2F;assets&#x2F;css&#x2F;libs.css" media="screen" rel="stylesheet" type="text&#x2F;css">
19<link href="&#x2F;themes&#x2F;store&#x2F;default&#x2F;assets&#x2F;css&#x2F;styles.css" media="screen" rel="stylesheet" type="text&#x2F;css">
20<link href="&#x2F;themes&#x2F;store&#x2F;default&#x2F;assets&#x2F;js&#x2F;notifyjs&#x2F;metro&#x2F;notify-metro.css" media="screen" rel="stylesheet" type="text&#x2F;css">
21<link href="&#x2F;themes&#x2F;store&#x2F;default&#x2F;assets&#x2F;css&#x2F;custom.css&#x3F;v&#x3D;1790258645" media="screen" rel="stylesheet" type="text&#x2F;css">
22<link href="&#x2F;themes&#x2F;store&#x2F;default&#x2F;assets&#x2F;css&#x2F;dashboard.css&#x3F;v&#x3D;1790258645" media="screen" rel="stylesheet" type="text&#x2F;css">
23<link href="&#x2F;themes&#x2F;store&#x2F;default&#x2F;assets&#x2F;favicon&#x2F;favicon.ico" rel="shortcut&#x20;icon" type="image&#x2F;vnd.microsoft.icon">    <link href="/themes/store/default/assets/css/fonts.css" as="style" rel="preload">
24    <!-- icon in the highest resolution we need it for -->
25    <link rel="icon" sizes="192x192" href="/themes/store/default/assets/favicon/android-icon-192x192.png">
26
27    <!-- reuse same icon for Safari -->
28    <link rel="apple-touch-icon" href="/themes/store/default/assets/favicon/apple-icon.png">
29    <!-- meta tags -->
30    <meta itemprop="url" content="https://haroct.com.my" />
31    <meta name="HandheldFriendly" content="true" />
32    <meta name="application-name" content="haroct.com.my" />
33    <meta name="apple-touch-fullscreen" content="yes" />
34            <meta property="article:publisher" content="https://facebook.com"/>
35        <meta property="og:locale" itemprop="inLanguage" content="en_GB"/>
36    <meta property="og:locale:alternate" itemprop="inLanguage" content="en_GB" />
37    <!--<meta property="og:site_name" content=""/>-->
38        <!--<meta property="fb:admins" content="100003215492421">-->
39            <meta name="author" content="Haroct" />
40        <meta name="Robots" content="index, follow" />
41    <meta name="format-detection" content="telephone=no" />
42            <link rel="canonical" href="https://haroct.com.my/store/signup" /> <!-- fixed duplicated meta data -->
43        <meta content='#f55858' name='msapplication-TileColor' />
44
45    <link rel='dns-prefetch' href='//maps.google.com' />
46    <link rel='dns-prefetch' href='//www.gstatic.com' />
47    <link rel='dns-prefetch' href='//fonts.googleapis.com' />
48    
48<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
48
49    
49<script src="/themes/store/default/assets/js/jquery/jquery-3.1.0.min.js"></script>
49
50    
50<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
50
51    
51<script src="/themes/store/default/assets/js/notifyjs/notify.min.js"></script>
51
52    
52<script src="/themes/store/default/assets/js/notifyjs/metro/notify-metro.js"></script>
52
53    
53<script src="https://cdn.jsdelivr.net/npm/driver.js@latest/dist/driver.js.iife.js"></script>
53
54    
54<script src="/themes/store/default/assets/js/custom.js"></script>
vendor: 68 bytes, lines 54-55
54
55    <script async src="https://www.googletagmanager.com/gtag/js?id=
55G-LG2RC922TR
vendor: 16 bytes, lines 55-56
55"></script>
56    
56<script>
57        
vendor: 152 bytes, lines 57-61
57window.dataLayer = window.dataLayer || [];
58        function gtag(){dataLayer.push(arguments);}
59        gtag('js', new Date());
60
61        gtag('config', '
61G-LG2RC922TR
vendor: 8 bytes, lines 61-62
61');
62    
62</script>
62
63</head>
64    <body>
65        <div class="">
66            <div class="container-fluid min-vh-100">
67    <div class="row">
68        <div class="col-md-3 bg-haroct bg-btm text-light d-flex align-items-center justify-content-center p-5 p-md-0">
69            <div class="mb-5 pb-5 text-center">
70                <img src="/themes/store/default/assets/images/logo-haroct.png" class="signup-logo">
71                <h4 class="mt-3">Welcome To Haroct</h4>
72                <div class="mt-2">
73                    <ul class="navbar-nav ms-auto">
74                        <li class="nav-item dropdown">
75                            <a class="nav-link px-3 dropdown-toggle text-light" id="langDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false" href="#">
76                                <img src="/themes/store/default/assets/images/icon-globe.png" class="mr-1 bg-haroct rounded-5" style="width: 18px; height: 18px;"> EN                            </a>
77                            <ul class="dropdown-menu" aria-labelledby="langDropdown">
78                                                                    <li><a class="dropdown-item" href="https://haroct.com.my/store/signup?lang=en">EN</a></li>
79                                                                    <li><a class="dropdown-item" href="https://haroct.com.my/store/signup?lang=my">MY</a></li>
80                                                                    <li><a class="dropdown-item" href="https://haroct.com.my/store/signup?lang=cn">中文</a></li>
81                                                                    <li><a class="dropdown-item" href="https://haroct.com.my/store/signup?lang=th">ไทย</a></li>
82                                                            </ul>
83                        </li>
84                    </ul>
85                </div>
86                <div class="steps">
87                    <div class="step">
88                        <div class="step-number">01</div>
89                        <div class="step-text text-start">
90                            <b>Verify your contact number</b>
91                            <small>Enter the OTP number</small>
92                        </div>
93                    </div>
94                    <div class="connector" id="line-1"></div>
95                    <div class="step">
96                        <div class="step-number">
9602</div>
97                        <div class="step-text text-start">
98                            <b>Your Role</b>
99                            <small>Select your role and field</small>
100                        </div>
101                    </div>
102                    <div class="connector" id="line-2"></div>
103                    <div class="step">
104                        <div class="step-number">03</div>
105                        <div class="step-text text-start">
106                            <b>Your Vertical</b>
107                            <small>Select your business's vertical</small>
108                        </div>
109                    </div>
110                    <div class="connector" id="line-3"></div>
111                    <div class="step">
112                        <div class="step-number">04</div>
113                        <div class="step-text text-start">
114                            <b>Your Business Details</b>
115                            <small>Provide your company details</small>
116                        </div>
117                    </div>
118                </div>
119            </div>
120        </div>
121        <div class="col signup-right-col d-flex align-items-start justify-content-center text-center pt-3 pb-5 px-md-0">
122            <div class="row justify-content-center w-100">
123                <div class="col-md-12 signup-content-col">
124                    <aside class="main-content">
125                    	<section>
126                            <form id="signupForm">
127                                <input type="hidden" name="lang" value="en">
128                                                    
129                        <div id="invitation-banner" class="d-none mb-4">
130                            <div class="alert alert-info text-start mb-0">
131                                <p class="fw-bold mb-1">Welcome to Haroct!</p>
132                                <p class="mb-0"><span id="inviter-name"></span> has invited you to join their company account as a sub-account.</p>
133                            </div>
134                        </div>
135
136                    		<div class="row justify-content-center">
137                    			<div class="col-md-9">
138                    				<div id="progress" class="text-center mb-3">
139                    					<div class="row position-relative">
140                    						<div class="position-absolute text-left mt-2 start-0 w-auto z-1">
141                    							<a id="back-btn" class="btn"><i class="fa fa-arrow-left"></i></a>
142                    						</div>
143                    						<div class="col-12 center-text p-3">
144                    							<span id="step-info">1 of 3</span>
145                    						</div>
146                    					</div>
147                        
148                    					<div class="progress progress-thin">
149                    						<div class="progress-bar bg-warning w-33" role="progressbar" aria-valuenow="33" aria-valuemin="0" aria-valuemax="100"></div>
150                    					</div>
151                    				</div>
152                        
153                    				<div class="row justify-content-center text-center">
154                    					<div class="col-md-8">
155                    						<div id="step1" class="form-step active-step">
156                    							<h4 class="text-center my-5">How can we contact you?</h4>
157                    							<div class="mb-3">
158                    								<div class="row mb-3">
159                    									<div class="col-12">
160                    										<input type="tel" id="phone" name="phone" class="form-control required" placeholder="Phone Number">
161                    										<input type="hidden" class="form-control" name="countryCode" value="">
162                    									</div>
163                    									<div class="col-12 thai-guide text-left mt-2 d-none">
164                    										<span class="default-thai-guide text-muted">
165                    											กรุณาเลือกรหัสประเทศ (+66) <span class="fw-bold">โดยไม่พิมพ์เลข "0"</span> นำหน้า ตามด้วยหมายเลขโทรศัพท์ของท่าน
166                    										</span>
167                    										<span class="error-thai-guide text-danger d-none">
168                    											หมายเลขโทรศัพท์ไม่ถูกต้อง กรุณาเลือกรหัสประเทศ (+66) <span class="fw-bold">โดยไม่พิมพ์เลข "0"</span> นำหน้า ตามด้วยหมายเลขโทรศัพท์ของท่าน
169                    										</span>
170                    									</div>
171                    								</div>
172                        
173                    								                    								<input type="hidden" name="otp" value="">
174                    								<input type="hidden" name="code" value="">
175                    								<input type="hidden" name="version" value="2">
176                        
177                    								<div class="row mb-2 mt-5">
178                    									<div class="col">
179                    										<div class="form-check">
180                    											<input class="form-check-input required" type="checkbox" name="tnc" value="1" id="tnc" required>
181                    											<label class="form-check-label" for="tnc">
182                    												By ticking, you are confirming you have read, understood and agree to HAROCT Terms & Condition and End User License Agreement                    											</label>
183                    										</div>
184                    									</div>
185                    								</div>
186                        
187                    								<div class="row mb-2 mt-4 bg-haroct-2 roun
187ded-1 mx-0 py-2">
188                    									<div class="col align-self-center text-left">
189                    										<i class="fa fa-gift link-haroct fs-6 mr-1"></i> Have a referral code?                    									</div>
190                    									<div class="col-auto text-right">
191                    										<input type="button" class="btn btn-sm bg-light border-haroct btn-claim" value="Claim" data-bs-toggle="modal" data-bs-target="#referralModal">
192                    									</div>
193                    									<div class="col-12 text-left fw-bold referral-block d-none">
194                    										Referral code: <span></span>
195                    										<a href="#" class="btn-remove-referral link-haroct text-decoration-underline ml-2">Remove</a>
196                    									</div>
197                    								</div>
198                        
199                    								                    								<div class="row justify-content-center mb-3 mt-4">
200                    									<button type="button" class="btn btn-haroct btn-request-otp mt-4 w-50" disabled>Request OTP</button>
201                    								</div>
202                        
203                    								<div class="row">
204                    									<div class="col text-center">
205                    										<div>Already have an account?</div>
206                    										<a href="login" class="link-haroct">Login</a>
207                    									</div>
208                    								</div>
209                    							</div>
210                    						</div>
211
212                                            <div id="step2" class="form-step">
213                    							<h4 class="text-center my-5">Set your passcode</h4>
214                    							<div class="mb-3">
215                    								<div class="pin-inputs mb-4">
216                                                        <input type="text" maxlength="1" class="pin" />
217                                                        <input type="text" maxlength="1" class="pin" />
218                                                        <input type="text" maxlength="1" class="pin" />
219                                                        <input type="text" maxlength="1" class="pin" />
220                                                        <input type="text" maxlength="1" class="pin" />
221                                                        <input type="text" maxlength="1" class="pin" />
222                                                    </div>
223                    							</div>
224                        
225                    							<button type="button" class="btn btn-haroct next-btn mt-4 w-50" disabled>Continue</button>
226                    						</div>
227                        
228                    						<div id="step3" class="form-step">
229                    							<h4 class="text-center my-5">What is your role?</h4>
230                    							<div class="mb-3">
231                    								<div class="row">
232                    									<div class="col">
233                    										<div class="radio-box role-box" data-role="seller">
234                    											<input type="radio" class="required" id="role1" name="accountType" value="1">
235                    											<label for="role1" class="p-1 p-md-3">
236                    												<div class="mt-2">I am a seller</div>
237                    											</label>
238                    										</div>
239                    									</div>
240                    									<div class="col">
241                    										<div class="radio-box role-box" data-role="buyer">
242                    											<input type="radio" class="required" id="role2" name="accountType" value="0">
243                    											<label for="role2" class="p-1 p-md-3">
244                    												<div class="mt-2">I am a buyer</div>
245                    											</label>
246                    										</div>
247                    									</div>
248                    								</div>
249                        
250                    								<div class="row mt-2 bg-haroct-2 rounded-1 mx-0 py-2 block-role-info d-none">
251                    									<span></span>
252                    								</div>
253                    							</div>
254                        
255                    							<!-- Buyer Fields -->
256                    							<div id="buyer-fields" class="d-none">
257                                                    <h4 class="text-center my-5">I am a...</h4>
258                                                    <div class="mb-3">
259                                                        <div class="row">
260                                                            <!-- Buyer segments will be dynamically inserted here -->
261                                                        </div>
262                                                    </div>
263                                                </div>
264                                                
265                                                <!-- Seller field -->
266                                                <div id="seller-fields" class="d-none">
267                                                    <h4 class="text-center my-5">I am a...</h4>
268                                                    <div class="mb-3">
269                                                        <div class="row">
270                                                            <!-- Seller segments will be dynamically inserted here -->
271                                                        </div>
272                                                    </div>
273                                                </div>
274                        
275                    							<div class="row mt-2 bg-haroct-2 roun
275ded-1 mx-0 py-2 block-role-info d-none">
276                    								<span></span>
277                    							</div>
278                    							<button type="button" class="btn btn-haroct next-btn mt-4 w-50" disabled>Continue</button>
279                    						</div>
280
281                    						<div id="stepMarket" class="form-step">
282                    							<h4 class="text-center mt-5 mb-1">Where is your business based? <small class="text-muted text-uppercase">Required</small></h4>
283                    							<div class="mb-4">
284                    								<div class="row justify-content-center" id="businessCountryOptions">
285                    									<!-- Business country options rendered dynamically -->
286                    								</div>
287                    							</div>
288
289                    							<h4 class="text-center mt-5 mb-1" id="marketQuestionHeading">Which market do you want to buy from?</h4>
290                    							<p class="text-muted text-center mb-3">Select all that apply</p>
291                    							<div class="mb-3" id="interestedMarketOptions">
292                    								<!-- Interested market checkboxes rendered dynamically -->
293                    							</div>
294
295                    							<button type="button" class="btn btn-haroct next-btn mt-4 w-50" disabled>Continue</button>
296                    						</div>
297
298                    						<div id="step4" class="form-step">
299                    							<h4 class="text-center my-5">What do you sell?</h4>
300                    							<div class="mb-3 non-agri-product">
301                    								<!-- Normal Options -->
302                    								<div class="row">
303                    									<div class="col">
304                    										<div class="radio-box">
305                    											<input type="radio" class="required" id="vertical1" name="verticalType" value="vegetable">
306                    											<label for="vertical1" class="p-1 p-md-3">
307                    												<img src="/themes/store/default/assets/images/vege1.png">
308                    												<div class="mt-2">I am selling vegetables</div>
309                    											</label>
310                    										</div>
311                    									</div>
312                    									<div class="col">
313                    										<div class="radio-box">
314                    											<input type="radio" class="required" id="vertical2" name="verticalType" value="fruit">
315                    											<label for="vertical2" class="p-1 p-md-3">
316                    												<img src="/themes/store/default/assets/images/fruit.png">
317                    												<div class="mt-2">I am selling fruits</div>
318                    											</label>
319                    										</div>
320                    									</div>
321                    								</div>
322                    							</div>
323                                                
324                    								<!-- Agri Input Product Options -->
325                                                <div class="mb-3 agri-input-product d-none">
326                                                    <h6 class="text-center my-5">You can choose more than 1 option</h6>
327                                                    <div class="row agri-product-container" id="agriProductContainer">
328                                                        <!-- Products will be dynamically inserted here -->
329                                                    </div>
330                                                </div>
331                    							<button type="button" class="btn btn-haroct next-btn mt-4 w-50" disabled>Continue</button>
332                    						</div>
333                        
334                    						<div id="step5" class="form-step">
335                    							<!-- Normal Form -->
336                    							<div class="normal-form">
337                    								<h4 class="text-center my-5">Tell us your business</h4>
338                                                    <div class="row text-start mb-3">
339                                                        <div class="col-6">
340                                                            <div class="form-check">
341                                                                <input class="form-check-input" type="radio" name="isBusiness" id="radioBusiness" value="1" checked>
342                                                                <label class="form-check-label" for="radioBusiness">Business</label>
343                                                            </div>
344                                                        </div>
345                                                        <div class="col-6">
346                                                            <div class="form-check">
347                                                                <input class="form-check-input" type="radio" name="isBusiness" id="radioPersonal" value="
3470">
348                                                                <label class="form-check-label" for="radioPersonal">Personal</label>
349                                                            </div>
350                                                        </div>
351                                                    </div>
352                                                    <div class="mb-4">
353                    									<input type="text" class="form-select " name="name" placeholder="Enter Your Business Name" required>
354                    								</div>
355                                                    <div class="mb-4">
356                    									<input type="text" class="form-select " name="email" placeholder="Enter Your Email Address">
357                    								</div>
358                                                    <div class="p-3 border border-dashed rounded upload-container d-flex align-items-center justify-content-between mb-4">
359                                                        <div class="d-flex align-items-center">
360                                                            <div id="logo-placeholder" class="logo-placeholder rounded-circle me-3">
361                                                                <svg class="placeholder-icon" fill="currentColor" viewBox="0 0 16 16">
362                                                                    <path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0"/>
363                                                                    <path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8m8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.758 1.226 5.468 2.37A7 7 0 0 0 8 1"/>
364                                                                </svg>
365                                                            </div>
366                                                            <label for="storeLogoInput" class="mb-0">Tap to upload your store logo</label>
367                                                            <input type="file" class="d-none" id="storeLogoInput" accept="image/*">
368                                                        </div>
369                                                        
370                                                        <button type="button" class="btn btn-sm btn-primary upload-btn">Upload Photo</button>
371                                                    </div>
372                    								<div class="mb-4">
373                    									<select class="form-select " id="stateSelect" name="locationState" required>
374                    										<option value="" selected>Select State</option>
375                    									</select>
376                    								</div>
377                    								<div class="mb-5">
378                    									<select class="form-select" name="locationCity" id="citySelect" required>
379                    										<option value="" selected>Select City</option>
380                    									</select>
381                    								</div>
382                    								<div class="text-center">
383                    									<button type="submit" class="btn btn-haroct mt-4 w-50">Sign Up Now</button>
384                    								</div>
385                    							</div>
386                        
387                    							<!-- Agri Input Form -->
388                    							<div class="agri-input-form d-none">
389                    								<h4 class="text-center my-5">Tell us about your business</h4>
390                    								<div class="mb-3">
391                    									<ul class="nav nav-tabs d-flex justify-content-center w-100">
392                    										<li class="nav-item">
393                    											<a class="nav-link active" data-bs-toggle="tab" href="#business" data-is-business="true">Business</a>
394                    										</li>
395                    										<li class="nav-item">
396                    											<a class="nav-link" data-bs-toggle="tab" href="#personal" data-is-business="false">Personal</a>
397                    										</li>
398                    									</ul>
399                    									<div class="tab-content mt-4">
400                    										<div class="tab-pane fade show active" id="business">
401                    											<form>
402                    												<div class="row">
403                    													<div class="col-md-6 text-left">
404                    														<label for="businessName" class="form-label text-muted label-step-4">Company Name <span class="text-danger">*</span></label>
405                    														<input type="text" class="form-control mb-3" id="businessName" name="store[name]">
406                        
407                    														<label for="personInChargeName" class="form-label text-muted label-step-4">Person In Charge's Name <span class="text-danger">*</span></label>
408                    														<input type="text" class="form-control mb-3" id="personInChargeName" name="name">
409                        
410                    														<div class="row mb-3">
411                    															<div class="col">
412                    																<label for="businessAddress" class="form-label text-muted label-step-4">Company Address (Optional)</label>
413                    																<div class="address-container border rounded p-2 d-flex justify-content-between align-items-center w-100">
414                    																	<div class="text-haroct me-3">
415                    																		<i class="fa fa-map-marker" aria-hidden="true"></i>
416                    																	</div>
417                    																	<span id="businessAddressDisplay" class="text-muted">No address added yet</span>
418                    																	<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#addCompanyAddressModal">
419                    																		Add                    																	</button>
420                    																</div>
421                    																<input type="hidden" id="businessAddress" name="businessAddress">
422                    															</div>
423                    														</div>
424                    													</div>
425                    													<div class="col-md-6 text-left">
426                    														<label for="businessRegNo" class="form-label text-muted label-step-4">Business Registration Number (SSM Registration Number) (Optional)</label>
427                    														<input type="number" class="form-control mb-3" id="businessRegNo" name="store[ssmNumber]">
428                                                                            
429                    														<label for="personInChargeContact" class="form-label text-muted label-step-4">
430                                                                                Person In Charge's Contact Number                                                                                 <sp
430an class="text-danger">*</span>
431                                                                            </label>
432                                                                            <div class="phone-input-container mb-3">
433                                                                                <input type="tel" id="personInChargeContact" name="store[phone]" class="form-control" placeholder="">
434                                                                                <input type="hidden" name="countryCode" value="">
435                                                                            </div>                        
436                    														<label for="businessEmail" class="form-label text-muted label-step-4">Company Email Address (Optional)</label>
437                    														<input type="email" class="form-control mb-3" id="businessEmail" name="store[email]">
438                    													</div>
439                    												</div>
440                    												<!-- <div class="row text-left product-sell">
441                    													<label for="productsSold" class="form-label text-muted label-step-4">What products do you sell on Haroct? <span class="text-danger">*</span></label>
442                    													<a href="" class="btn border w-100 product-name">
443                    														<div class="col text-left">
444                    															<span class="product-name-label">Select</span>
445                    															<i class="ms-1 fa fa-angle-down text-right" aria-hidden="true"></i>
446                    														</div>
447                    													</a>
448                    												</div> -->
449                    											</div>
450                    										</div>
451                        
452                    										<div class="tab-pane fade" id="personal">
453                    											<form>
454                    												<div class="row">
455                    													<div class="col-md-6 text-left">
456                    														<label for="personalName" class="form-label text-muted label-step-4">Name as per NRIC/Passport <span class="text-danger">*</span></label>
457                    														<input type="text" class="form-control mb-3 required" id="personalName" name="name">
458                        
459                    														<label for="personalEmail" class="form-label text-muted label-step-4">Email Address (Optional)</label>
460                    														<input type="email" class="form-control mb-3" id="personalEmail" name="email">
461                        
462                    														<div class="row mb-3">
463                    															<div class="col">
464                    																<label for="personalAddress" class="form-label text-muted label-step-4">Home Address (Optional)</label>
465                    																<div class="address-container border rounded p-2 d-flex justify-content-between align-items-center">
466                    																	<div class="text-haroct me-3">
467                    																		<i class="fa fa-map-marker" aria-hidden="true"></i>
468                    																	</div>
469                    																	<span id="personalAddressDisplay" class="text-muted">No address added yet</span>
470                    																	<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#addAddressModal">
471                    																		Add                    																	</button>
472                    																</div>
473                    																<input type="hidden" id="personalAddress" name="personalAddress">
474                    															</div>
475                    														</div>
476                    													</div>
477                    													<div class="col-md-6 text-left">
478                    														<label for="personalIC" class="form-label text-muted label-step-4">IC/MyKad <span class="text-danger">*</span></label>
479                    														<input type="text" class="form-control mb-3 required" id="personalIC" name="idNo" required>
480                        
481                    														<label for="uploadIC" class="form-label text-muted label-step-4">Upload IC/Passport Copy (Optional)</label>
482                    														<div class="input-group form-control" onclick="document.getElementById('uploadIC').click()">
483                    															<input type="file" class="form-control mb-3 visually-hidden" id="uploadIC" name="idDoc">
484                    															<span class="cursor-pointer text-muted" id="fileNameDisplay"></span>
485                    															<span class="upload-icon-btn">
486                    																<img src="/themes/store/default/assets/images/upload.png" alt="Upload Icon" class="icon-sq-20">
487                    															</span>
488                    														</div>
489                    													</div>
490                    												</div>
491                                                                </form>
492                    										</div>
493                        
494                                                            <div class="form-check mt-3 text-left">
495                    											<input class="form-check-input" type="checkbox" id="agreement" name="agreement" value="1" required>
496                    											<label class="form-check-label label-step-4" for="agreement">
497                    												I have accepted the <a href="#" target="_blank">Agri Input Agreement</a> and <a href="https://haroct.com.my/privacy-policy" target="_blank">Privacy Policy</a>.
498                    											</label>
499                    										</div>
500                        
501                    										<div class="form-check mt-2 text-left">
502                    											<input class="form-check-input" type="checkbox" id="declaration" name="declaration" value="1" required>
503                    											<label class="form-check-label label-step-4" for="declaration">
504                    												I hereby declare that the information and documents provided are true, accurate, and belong to me. I understand that Haroct does not verify the authenticity of the uploaded documents, and I am fully responsible for any claims or liabilities arising from this declaration.
505                    											</label>
506                    										</div>
507                                                            
508                    										<div class="text-center">
509                    											<button type="submit" class="btn btn-haroct mt-4 w-50">Sign Up Now</button>
510                    										</div>
511                    									</div>
512                    								</div>
513                    							</div>
514                    						</div>
515                    					</div>
516                    				</div>
517                    			</div>
518                    		</div>
519                    		</form>
520                        
521                    		<div class="modal fade" id="productNameModal" tabindex="-1" aria-labelledby="productNameModalLabel" aria-hidden="true">
522                    			<div class="modal-dialog modal-dialog-centered">
523                    				<div class="modal-content">
524                    					<div class="modal-header border-bottom">
525                    						<h5 class="modal-title">Select Product Name</h5>
526                    						<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
527                    					</div>
528                    					<div class="modal-body">
529                    						<div class="search-container mb-3">
530                    							<input type="text" class="form-control search-input" placeholder="Search product name">
531                    						</div>
532                    						<div class="product-list mb-3 scrollable-list">
533                    							<div class="product-list-container">
534                    							</div>
535                    						</div>
536                    						<a href="" class="btn btn-haroct rounded-3 w-100 confirm-product-name"> Confirm</a>
537                    					</div>
538                    				</div>
539                    			</div>
540                    		</div>
541                        
542                    		<div class="modal fade" id="addCompanyAddressModal" tabindex="-1" aria-labelledby="addCompanyAddressModalLabel" aria-hidden="true">
543                    			<div class="modal-dialog modal-lg modal-dialog-centered">
544                    				<div class="modal-content">
545                    					<div class="d-flex justify-content-between align-items-center p-4">
546                    						<h5 class="fw-bold">Add Company Address</h5>
547                    						<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
548                    					</div>
549                    					<div class="p-4">
550                    						<form id="companyAddressForm">
551                    							<div class="row">
552                    								<div class="col">
553                    									<div class="mb-3">
554                    										<label for="address1" class="form-label text-muted label-step-4">Address Line 1</label>
555                    										<input type="text" class="form-control" id="companyAddress1" name="store[address1]">
556                    									</div>
557                    									<div class="mb-3">
558                    										<label for="companyAddress2" class="form-label text-muted label-step-4">Address Line 2</label>
559                    										<input type="text" class="form-control" id="companyAddress2" name="store[address2]">
560                    									</div>
561                    									<div class="mb-3">
562                    										<label for="state" class="form-label text-muted label-step-4">State</label>
563                    										<select class="form-select" id="stateSelectBusiness" name="store[state]" required>
564                    											<option value="" selected>Select State</option>
565                    										</select>
566                    									</div>
567                    									<div class="mb-3">
568                    										<label for="city" class="form-label text-muted label-step-4">City</label>
569                    										<select class="form-select" name="store[city]" id="citySelectBusiness" required>
570                    											<option value="" selected>Select City</option>
571                    										</select>
572                    									</div>
573                    									<div class="mb-3">
574                    										<label for="postcode" class="form-label text-muted label-step-4">Postcode</label>
575                    										<input type="text" class="form-control" id="postcode" name="store[postcode]">
576                    									</div>
577                    									<input type="text" class="form-control" id="accessToken" name="accessToken" value="" hidden>
578                    									<input type="text" class="form-control" id="type" name="type" value="store" hidden>
579                    								</div>
580                    								<div class="col">
581                    									<div class="mb-3">
582                    										<label class="form-label text-muted label-step-4">Map</label>
583                    										<p class="map-instruction text-muted label-step-4">Move the pin on the map for accurate location</p>
584                    										<div class="map-container-company"></div>
585                    									</div>
586                    									<div>
587                    										<input type="text" class="form-control" id="latCompany" name="lat" hidden>
588                    										<input type="text" class="form-control" id="lngCompany" name="lng" hidden>
589                    									</div>
590                    								</div>
591                    							</div>
592                    							<div class="d-flex justify-content-center align-items-center mt-4">
593                    								<button type="button" class="btn bg-white border w-25 me-3" data-bs-dismiss="modal" aria-label="Close">Cancel</button>
594                    								<button type="submit" class="btn btn-haroct text-haroct w-25">Save</button>
595                    							</div>
596                    						</form>
597                    					</div>
598                    				</div>
599                    			</div>
600                    		</div>
601                        
602                    		<div class="modal fade" id="addAddressModal" tabindex="-1" aria-labelledby="addAddressModalLabel" aria-hidden="true">
603                    			<div class="modal-dialog modal-lg modal-dialog-centered">
604                    				<div class="modal-content">
605                    					<div class="d-flex justify-content-between align-items-center p-4">
606                    						<h5 class="fw-bold">Add Home Address</h5>
607                    						<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
608                    					</div>
609                    					<div class="p-4">
610                    						<form id="addressForm">
611                    							<div class="row">
612                    								<div class="col">
613                    									<div class="mb-3">
614                    										<label for="addressName" class="form-label text-muted label-step-4">Name</label>
615                    										<input type="text" class="form-control" id="nameAddress" name="delivery[name]">
616                    									</div>
617                    									<div class="mb-3">
618                    										<label for="personalContact" class="form-label text-muted label-step-4">Contact Number </label>
619                    										<div class="phone-input-container">
620                    											<input type="tel" id="contact" name="delivery[phone]" class="form-control required" placeholder=" ">
621                    											<input type="hidden" name="delivery[countryCode]" value="">
622                    										</div>
623                    									</div>
624                    									<div class="mb-3">
625                    										<label for="address1" class="form-label text-muted label-step-4">Address Line 1</label>
626                    										<input type="text" class="form-control" id="address1" name="delivery[address]">
627                    									</div>
628                    									<div class="mb-3">
629                    										<label for="Address2" class="form-label text-muted label-step-4">Address Line 2</label>
630                    										<input type="text" class="form-control" id="address2" name="delivery[addressLine2]]">
631                    									</div>
632                    									<div class="mb-3">
633                    										<label for="state" class="form-label text-muted label-step-4">State</label>
634                    										<select class="form-select" id="stateSelectPersonal" name="delivery[locationState]" required>
635                    											<option value="" selected>Select State</option>
636                    										</select>
637                    									</div>
638                    									<div class="mb-3">
639                    										<label for="city" class="form-label text-muted label-step-4">City</label>
640                    										<select class="form-select" name="delivery[locationCity]" id="citySelectPersonal" required>
641                    											<option value="" selected>Select City</option>
642                    										</select>
643                    									</div>
644                    									<div class="mb-3">
645                    										<label for="postcode" class="form-label text-muted label-step-4">Postcode</label>
646                    										<input type="text" class="form-control" id="personalPostcode" name="delivery[postcode]">
647                    									</div>
648                    									<input type="text" class="form-control" id="accessToken" name="accessToken" value="" hidden>
649                    									<input type="text" class="form-control" id="type" name="type" value="store" hidden>
650                    								</div>
651                    								<div class="col">
652                    									<div class="mb-3">
653                    										<label class="form-label text-muted label-step-4">Map</label>
654                    										<p class="map-instruction text-muted label-step-4">Move the pin on the map for accurate location</p>
655                    										<div class="map-container-personal"></div>
656                    									</div>
657                    									<div>
658                    										<input type="text" class="form-control" id="lat" name="lat" hidden>
659                    										<input type="text" class="form-control" id="lng" name="lng" hidden>
660                    									</div>
661                    								</div>
662                    							</div>
663                    							<div class="d-flex justify-content-center align-items-center mt-4">
664                    								<button type="button" class="btn bg-white border w-25 me-3" data-bs-dismiss="modal" aria-label="Close">Cancel</button>
665                    								<button type="submit" class="btn btn-haroct text-haroct w-25">Save</button>
666                    							</div>
667                    						</form>
668                    					</div>
669                    				</div>
670                    			</div>
671                    		</div>
672                    	</section>
673                    </aside>
674                </div>
675            </div>
676    </div>
677
678<div class="modal fade" id="otpModal" tabindex="-1" aria-labelledby="otpModalLabel" aria-hidden="true" data-bs-backdrop="static">
679    <div class="modal-dialog modal-md modal-dialog-centered">
680        <div class="modal-content rounded-4">
681            <div class="modal-header border-bottom-0">
682                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
683            </div>
684            <div class="modal-body text-center">
685                <div class="text-center mb-3"><img src="/themes/store/default/assets/images/2fa.png"></div>
686                <div class="fs-5 mb-2">Verify Your Phone</div>
687                <p class="text-muted small mb-4">Code has been sent to <span class="fw-bold text-haroct phone-number"></span></p>
688                <div class="otp-inputs mb-4 d-flex justify-content-center gap-2">
689                    <input type="text" maxlength="1" class="otp-pin" />
690                    <input type="text" maxlength="1" class="otp-pin" />
691                    <input type="text" maxlength="1" class="otp-pin" />
692                    <input type="text" maxlength="1" class="otp-pin" />
693                    <input type="text" maxlength="1" class="otp-pin" />
694                    <input type="text" maxlength="1" class="otp-pin" />
695                </div>
696                <div class="row mb-3 otp-countdown d-none">
697                    <div class="col text-center">
698                        <small class="text-warning">Resend OTP in <span>5:00</span></small>
699                    </div>
700                </div>
701                <button type="button" class="btn btn-sm btn-link text-decoration-none d-none btn-resend-otp">Resend OTP</button>
702            </div>
703            <div class="modal-footer justify-content-center border-top-0">
704                <button type="button" class="btn btn-haroct btn-verify-otp w-100" disabled>Verify & Continue</button>
705            </div>
706        </div>
707    </div>
708</div>
709
710<div class="modal fade rounded-5" id="referralModal" tabindex="-1" aria-labelledby="referralModalLabel" aria-hidden="true">
711    <div class="modal-dialog modal-sm modal-dialog-centered modal-dialog-scrollable">
712        <div class="modal-content rounded-4">
713            <div class="modal-body">
714                <form id="referralForm">
715                    <div class="mb-3 link-haroct text-center">
716                        <label for="referral-code" class="col-form-label">
717                            <i class="fa fa-gift fs-1 mt-4 mb-2"></i>
718                            <h6>Enter Referral code<br>to claim your benefits</h6>
719                        </label>
720                        <input type="text" class="form-control" id="referral-code" placeholder="Referral code">
721                    </div>
722                </form>
723            </div>
724            <div class="modal-footer">
725                <button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Close</button>
726                <button type="button" class="btn btn-sm btn-haroct btn-submit-referral">Submit</button>
727            </div>
728        </div>
729    </div>
730</div>
731
732<div class="modal fade rounded-5" id="emailModal" tabindex="-1" aria-labelledby="emailModalLabel" aria-hidden="true">
733    <div class="modal-dialog modal-md">
734        <div class="modal-content rounded-4">
735            <div class="d-flex justify-content-end align-items-center p-2">
736                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
737            </div>
738            <div class="modal-body text-center">
739                <div class="mb-3 link-haroct">
740                    <img src="/themes/store/default/assets/images/icon-coin-signup.svg">
741                    <h4 class="fw-bold">Secure Your Account & Earn 50 Coins!</h4>
742                </div>
743                <div>
744                    <p class="text-muted">Add your email to stay updated on your orders,<br>get special deals, and keep your account secure.</p>
745                </div>
746            </div>
747            <div class="modal-footer">
748                <div class="row w-100 mb-2">
749                    <div class="col-12">
750                        <button type="button" class="btn btn-haroct w-100 py-2">Add Email Now</button>
751                    </div>
752                </div>
753                <div class="row w-100">
754                    <div class="col-12 text-center">
755                        <a href="#" class="link-haroct" data-bs-dismiss="modal"><u>It's okay, I will do it later</u></a>
756                    </div>
757                </div>
758            </div>
759        </div>
760    </div>
761</div>
762
763<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/build/css/intlTelInput.css">
vendor: 70 bytes, lines 763-766
763
764
765
766<script src="https://www.google.com/recaptcha/enterprise.js?render=
7666Lcim1osAAAAANvZ5krlNRs6QP11OT71fvoj2ous
vendor: 12 bytes, line 766
766"></script>
767<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAvvOIrBV014ZdBqnUKpjT82Ae46A90bmA&libraries=places&callback=initAutocomplete" async defer></script>
vendor: 1 bytes, line 767
767
768<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/js/intlTelInput.min.js"></script>
vendor: 1 bytes, line 768
768
769<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/js/utils.js"></script>
vendor: 1 bytes, line 769
769
770<script>
771var avatar = '';
772
773$(document).ready(function() {
774    function getURLParameter(name) {
775        return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
776    }
777
778    // Validate parentId invitation on page load
779    var parentIdParam = null;
780    if (parentIdParam) {
781        ajax_form({ parentId: parentIdParam }, 'https://haroct.com.my/api/v1/u/get-user-info').done(function(response) {
782            if (response.code == 200 && response.item) {
783                $('#inviter-name').text(response.item.name || '');
784                $('#invitation-banner').removeClass('d-none');
785            } else {
786                t('e', 'This invitation link is invalid or has expired.');
787                $('.btn-request-otp, .next-btn').prop('disabled', true);
788            }
789        }).fail(function() {
790            t('e', 'Unable to validate invitation. Please try again.');
791        });
792    }
793
794    $('#seller-fields').addClass('d-none');
795    $('#buyer-fields').addClass('d-none');
796
797    $('[name="accountType"]').change(function() {
798        const selectedRole = $('[name="accountType"]:checked').val();
799
800        if (selectedRole == 1) {
801            // Show seller fields and hide buyer fields
802            $('#seller-fields').removeClass('d-none');
803            $('#buyer-fields').addClass('d-none');
804        } else if (selectedRole == 0) {
805            // Show buyer fields and hide seller fields
806            $('#buyer-fields').removeClass('d-none');
807            $('#seller-fields').addClass('d-none');
808        } else {
809            // Hide both fields if no role is selected
810            $('#seller-fields').addClass('d-none');
811            $('#buyer-fields').addClass('d-none');
812        }
813    });
814
815    $('.role-box').hover(function() {
816        const role = $(this).data('role');
817        let hoverText = '';
818        if (role === 'buyer') {
819            hoverText = 'As a buyer, you can use Haroct to purchase products in bulk with good price';
820        } else if (role === 'seller') {
821            hoverText = 'As a seller, you can use Haroct to sell products with premium prices';
822        }
823        $(this).attr('data-hover-text', hoverText);
824    });
825
826    let currentStep = parseInt(getURLParameter('step')) || 1;
827    const totalSteps = 5;
828    const stepWidth = 100 / totalSteps;
829
830        $('.form-step').hide();
831    $('#step' + currentStep).show();
832    $('#back-btn').hide();
833    updateProgress();
834    
835    window.proceedToStep2 = function() {
836        $('#step1').hide();
837        $('#step2').show();
838        currentStep++;
839        updateProgress();
840    };
841
842    function checkFields(step) {
843        let isValid = true;
844        let failingFields = [];
845
846        const activeForm = step.find('.normal-form:visible, .agri-input-form:visible');
847        const activeTab = step.find('.tab-pane.active');
848        
849        activeTab.find('.required').each(function() {
850            const $field = $(this);
851            const fieldName = $field.attr('name') || $field.attr('id');
852            
853            if ($field.is(':radio')) {
854                if ($('input[name="' + $field.attr('name') + '"]:checked').length === 0) {
855                    isValid = false;
856                    failingFields.push(`Radio: ${fieldName} - not checked`);
857                }
858            } else if ($field.is(':checkbox')) {
859                if (!$field.is(':checked')) {
860                    isValid = false;
861                    failingFields.push(`Checkbox: ${fieldName} - not checked`);
862                }
863            } else {
864                const value = $field.val();
865                if (!value || value.trim() === '') {
866                    isValid = false;
867                    failingFields.push(`Input: ${fieldName} - empty value`);
868                }
869            }
870        });
871
872                // Additional validation for step 1
873                if (step.attr('id') === 'step1') {
874                    const phone = $('[name="phone"]').val();
875                    const isPhoneValid = phone && phone.trim() !== '';
876                    const tncChecked = $('#tnc').is(':checked');
877            
878                    // For Thailand, "Request OTP" acts as a continue button, so change its text
879                    const countryCode = $('[name="countryCode"]').val();
880                    if (countryCode === '+66') {
881                        $('.btn-request-otp').text('Continue');
882                    } else {
883                        $('.btn-request-otp').text('Request OTP');
884                    }
885            
886                    if (!isPhoneValid || !tncChecked) {
887                        isValid = false;
888                    }
889                }
890
891        // console.log('Validation Results:', {
892        //     stepNumber: step.attr('id'),
893        //     isValid: isValid,
894        //     failingFields: failingFields
895        // });
896
897        step.find('.next-btn, .btn-request-otp').prop('disabled', !isValid);
898
899        if (step.attr('id') === 'step4') {
900            const isAgriInput = $('.agri-input-product').is(':visible');
901
902            if (isAgriInput) {
903                // Validate at least one product is selected
904                if ($('.agri-product-checkbox:checked').length === 0) {
905                    isValid = false;
906                    t('e', 'Please select at least one product');
907                }
908            } else {
909                // Normal product selection validation
910                if (!$('[name="verticalType"]:checked').length) {
911                    isValid = false;
912                }
913            }
914        }
915
916        // Check if we're in step 4 and which form is active
917        if (step.attr('id') === 'step5') {
918            const isAgriInputForm = $('#step5 .agri-input-form').is(':visible');
919            
920            if (isAgriInputForm) {
921                // Agri Input form validation
922                const isBusinessTab = $('#business').hasClass('active');
923                const activeContainer = isBusinessTab ? $('#business') : $('#personal');
924                
925                activeContainer.find('.required').each(function() {
926                    if (!validateField($(this))) {
927                        isValid = false;
928                        failingFields.push($(this).attr('name') || $(this).attr('id'));
929                    }
930                });
931            } else {
932                // Normal form validation (only state and city)
933                $('#stateSelect, #citySelect').each(function() {
934                    if (!validateField($(this))) {
935                        isValid = false;
936                        failingFields.push($(this).attr('name'));
937                    }
938                });
939            }
940        } else {
941            // Validation for other steps
942            step.find('.required').each(function() {
943                if (!validateField($(this))) {
944                    isValid = false;
945                    failingFields.push($(this).attr('name') || $(this).attr('id'));
946                }
947            });
948        }
949
950        // console.log('Validation Results:', {
951        //     stepNumber: step.attr('id'),
952        //     isValid: isValid,
953        //     failingFields: failingFields
954        // });
955
956            return isValid;
957        }
958
959        function validateField(field) {
960        if (field.is(':radio')) {
961            return field.is(':checked') || $('input[name="' + field.attr('name') + '"]:checked').length > 0;
962        } else if (field.is(':checkbox')) {
963            return field.is(':checked');
964        } else {
965            const value = field.val();
966            return value && value.trim() !== '';
967        }
968    }
969
970    // Check fields on load in case of any pre-filled values
971    $('.form-step').each(function() {
972        checkFields($(this));
973    });
974
975    $('.required').on('change keyup', function() {
976        let step = $(this).closest('.form-step');
977        checkFields(step);
978    });
979
980    $('.next-btn').click(function() {
981        let current = $(this).closest('.form-step');
982        let next = current.next('.form-step');
983
984        if (!checkFields(current)) {
985            //return;
986        }
987
988        if (current.attr('id') === 'step2') {
989            if( $('.pin').val() === "" ){
990                t('e', 'Please set your passcode');
991                return false;
992            }
993        }
994        
995                // For other steps, proceed normally
996        if (next.length) {
997            current.hide();
998            next.show();
999            currentStep++;
1000            updateProgress();
1001        }
1002    });
1003
1004    $('#back-btn').click(function() {
1005        let current = $('.form-step:visible');
1006        let prev = current.prev('.form-step');
1007        if (prev.length) {
1008            current.hide();
1009            prev.show();
1010            currentStep--;
1011            updateProgress();
1012        }
1013    });
1014
1015    // Function to handle accountSegment change
1016    function handleAccountSegmentChange() {
1017        const selectedSegment = $('[name="accountSegment"]:checked').val();
1018        // console.log('Selected Segment:', selectedSegment); // Debugging: Log the selected segment
1019        
1020        if (selectedSegment == 106 || selectedSegment == 205) {
1021            // console.log('Agri Input Segment Selected');
1022            // Show Agri Input Product options and hide normal options
1023            $('.agri-input-product').removeClass('d-none');
1024            $('.non-agri-product').addClass('d-none');
1025
1026            // Show Agri Input Form and hide Normal Form
1027            $('#step4 .agri-input-form').removeClass('d-none');
1028            $('#step4 .normal-form').addClass('d-none');
1029
1030            // Disable validation for normal form fields
1031            $('.normal-form .required').prop('disabled', true);
1032            // Enable validation for Agri input form fields
1033            $('.agri-input-form .required').prop('disabled', false);
1034
1035            $('#stateSelect, #citySelect').prop('disabled', true);
1036            $('#agreement, #declaration').prop('required', true);
1037
1038            fetchAgriInputProducts();
1039
1040        } else {
1041            // console.log('Normal Segment Selected');
1042            // Show normal options and hide Agri Input Product options
1043            $('.agri-input-product').addClass('d-none');
1044            $('.non-agri-product').removeClass('d-none');
1045
1046            // Show Normal Form and hide Agri Input Form
1047            $('#step4 .normal-form').removeClass('d-none');
1048            $('#step4 .agri-input-form').addClass('d-none');
1049
1050             // Disable validation for Agri input form fields
1051            $('.agri-input-form .required').prop('disabled', true);
1052            // Enable validation for normal form fields
1053            $('.normal-form .required').prop('disabled', false);
1054
1055            $('#stateSelect, #citySelect').prop('disabled', false);
1056            $('#agreement, #declaration').prop('required', false);
1057        }
1058    }
1059
1060    // Trigger the change event initially to set the correct visibility
1061    $('[name="accountSegment"]').trigger('change');
1062    
1063    $('a[data-bs-toggle="tab"]').on('shown.bs.tab', function (e) {
1064        const isBusinessForm = $(e.target).data('is-business');
1065
1066        $('.tab-pane').removeClass('show active');
1067
1068        if (isBusinessForm) {
1069            $('#business').addClass('show active');
1070            $('#personal').removeClass('show active');
1071        } else {
1072            $('#personal').addClass('show active');
1073            $('#business').removeClass('show active');
1074        }
1075    });
1076
1077    // Trigger the tab change event initially to set the correct form visibility
1078    $('a[data-bs-toggle="tab"].active').trigger('shown.bs.tab');
1079
1080    function handleProductSellVisibility() {
1081        const selectedSegment = $('[name="accountSegment"]:checked').val();
1082        
1083        if (selectedSegment == 106) {
1084            // Hide the "What products do you sell on Haroct?" section
1085            $('.product-sell').hide();
1086        } else {
1087            // Show the "What products do you sell on Haroct?" section
1088            $('.product-sell').show();
1089        }
1090    }
1091
1092    // Function to update Step 3 heading based on accountType (buyer/seller)
1093    function updateStep4Heading() {
1094        const selectedRole = $('[name="accountType"]:checked').val();
1095        const step4Heading = $('#step4 h4');
1096
1097        if (selectedRole == 0) {
1098            // Buyer role
1099            step4Heading.text('What do you want to buy?');
1100        } else if (selectedRole == 1) {
1101            // Seller role
1102            step4Heading.text('What do you sell?');
1103        }
1104    }
1105
1106    // Listen for changes in accountType (buyer/seller)
1107    $('[name="accountType"]').change(function() {
1108        updateStep4Heading();
1109    });
1110
1111    // Trigger the change event initially to set the correct heading
1112    $('[name="accountType"]').trigger('change');
1113
1114    // Trigger the change event initially to set the correct visibility
1115    $('[name="accountSegment"]').trigger('change');
1116
1117    $(document).on('change', '#uploadIC', function() {
1118        const file = this.files[0];
1119        if (!file) return;
1120
1121        $('#fileNameDisplay').text(file.name);
1122
1123        const reader = new FileReader();
1124        reader.onload = function(e) {
1125            const base64Data = e.target.result.split(',')[1];
1126            const mimeType = file.type;
1127            const formattedData = `data:${mimeType};base64,${base64Data}`;
1128
1129            $('[name="idDoc[data]"]').remove();
1130            $('<input>').attr({
1131                type: 'hidden',
1132                name: 'idDoc[data]',
1133                value: formattedData
1134            }).appendTo('#signupForm');
1135        };
1136        reader.readAsDataURL(file);
1137    });
1138
1139    function updateProgress() {
1140    // Update step info text
1141    $('#step-info').text(`${currentStep} of ${totalSteps}`);
1142
1143    // Show or hide the back button based on the current step
1144    $('#back-btn').toggle(currentStep !== 1);
1145
1146    // Update the progress bar width
1147    $('.progress-bar')
1148        .css('width', `${stepWidth * currentStep}%`)
1149        .attr('aria-valuenow', stepWidth * currentStep);
1150
1151    // Remove active state from all steps and connectors
1152    $('.step, .connector').removeClass('active');
1153
1154    // Add active state to the current step and all previous steps
1155    $('.step').each(function (index) {
1156        if (index + 1 <= currentStep) {
1157            $(this).addClass('active');
1158        }
1159    });
1160
1161    // Add active state to the connectors for all completed steps
1162    $('.connector').each(function (index) {
1163        if (index + 1 < currentStep) {
1164            $(this).addClass('active');
1165        }
1166    });
1167
1168    $('.pin').each(function (index, element) {
1169        $(element).on('input', function () {
1170            const value = this.value;
1171
1172            // Move forward when filled
1173            if (value.length === 1 && index < $('.pin').length - 1) {
1174                $('.pin').eq(index + 1).focus();
1175            }
1176
1177            // Move backward when cleared
1178            if (value.length === 0 && index > 0) {
1179                $('.pin').eq(index - 1).focus();
1180            }
1181
1182            checkPinComplete();
1183        });
1184
1185        $(element).on('keydown', function (e) {
1186            // Safety fallback for Backspace
1187            if (e.key === 'Backspace' && !this.value && index > 0) {
1188                $('.pin').eq(index - 1).focus();
1189            }
1190        });
1191    });
1192}
1193
1194    $(document).on('change', '[name="lang"]', function(e) {
1195        var val = $(this).val();
1196        if (val) {
1197            var searchParams = new URLSearchParams(window.location.search);
1198            searchParams.set('lang', val);
1199            var newUrl = window.location.protocol + '//' + window.location.host + window.location.pathname + '?' + searchParams.toString();
1200            window.location.href = newUrl;
1201        }
1202    });
1203
1204    
1205    $(document).on('change', '[name="accountType"]', function(e){
1206        val = $('[name="accountType"]:checked').data('info');
1207        if(val){
1208            $('.block-role-info span').text(val).parent().removeClass('d-none').show();
1209        }else{
1210            $('.block-role-info span').text('').parent().addClass('d-none');
1211        }
1212    });
1213
1214    getProductName();
1215
1216    function fetchAccountSegments() {
1217    const requestData = {
1218        'types[]': 'customer-account-segment', // Adding the required parameter
1219        lang: ''
1220    };
1221
1222    ajax_form(requestData, 'https://haroct.com.my/api/v1/g/get-settings').done(function(response) {
1223        if (response.code == 200) {
1224            // console.log('segment', response);
1225            renderAccountSegments(response.settings['customer-account-segment']); // Ensure correct reference
1226        } else {
1227            t('e', response.msg);
1228        }
1229    }).fail(function(jqXHR, textStatus, errorThrown) {
1230        ajax_error(jqXHR);
1231    });
1232}
1233
1234
1235    // Render account segments based on the fetched data
1236    function renderAccountSegments(segments) {
1237        const buyerSegments = segments.buyer;
1238        const sellerSegments = segments.seller;
1239
1240        // Render buyer segments
1241        renderSegments(buyerSegments, 'buyer-fields');
1242        
1243        // Render seller segments
1244        renderSegments(sellerSegments, 'seller-fields');
1245    }
1246
1247    function renderSegments(segments, containerId) {
1248    const container = $(`#${containerId} .row`);
1249    container.empty(); // Clear existing content
1250
1251    // Convert object to an array and split into chunks of 3
1252    const segmentChunks = chunkArray(Object.entries(segments), 3);
1253
1254    segmentChunks.forEach(rowSegments => {
1255        const rowHtml = $('<div class="row mb-3"></div>');
1256
1257        rowSegments.forEach(([key, value]) => {
1258            const segmentHtml = `
1259                <div class="col-md-4">
1260                    <div class="radio-box text-center">
1261                        <input type="radio" class="required" id="${containerId}-${key}" name="accountSegment" value="${key}">
1262                        <label for="${containerId}-${key}" class="p-1 p-md-3 w-100">
1263                            <div class="mt-2 label-field">${value}</div>
1264                        </label>
1265                    </div>
1266                </div>
1267            `;
1268            rowHtml.append(segmentHtml);
1269        });
1270
1271        container.append(rowHtml);
1272    });
1273
1274    // Bind the change event to accountSegment radio buttons after rendering
1275    $('[name="accountSegment"]').change(function() {
1276        // console.log('Account Segment Changed:', $(this).val()); // Debugging: Log the selected segment
1277        handleAccountSegmentChange();
1278        updateStep4Heading();
1279        handleProductSellVisibility();
1280    });
1281}
1282
1283// Helper function to split array into chunks
1284function chunkArray(arr, chunkSize) {
1285    return arr.reduce((acc, _, i) => 
1286        (i % chunkSize ? acc[acc.length - 1].push(arr[i]) : acc.push([arr[i]]), acc), 
1287    []);
1288}
1289
1290
1291    // Fetch account segments on page load
1292    fetchAccountSegments();
1293
1294    setTimeout(function() {
1295        if ($('[name="accountSegment"]').length > 0) {
1296            // console.log('Account Segment radio buttons exist in the DOM.');
1297        } else {
1298            console.log('Account Segment radio buttons do NOT exist in the DOM.');
1299        }
1300    }, 1000); // Delay to allow dynamic rendering
1301
1302    setTimeout(function() {
1303        $('[name="accountSegment"]').first().trigger('click');
1304    }, 1000); 
1305
1306    // Handle role change (buyer/seller)
1307    $('[name="accountType"]').change(function() {
1308        const selectedRole = $('[name="accountType"]:checked').val();
1309        if (selectedRole == 1) {
1310            $('#seller-fields').removeClass('d-none');
1311            $('#buyer-fields').addClass('d-none');
1312        } else if (selectedRole == 0) {
1313            $('#buyer-fields').removeClass('d-none');
1314            $('#seller-fields').addClass('d-none');
1315        }
1316    });
1317
1318    function toggleRequiredFields() {
1319        const activeTab = $('.tab-pane.active'); // Get the active tab
1320        const inactiveTabs = $('.tab-pane').not('.active'); // Get inactive tabs
1321
1322        // Enable required attributes for fields in the active tab
1323        activeTab.find('.required').prop('required', true);
1324
1325        // Disable required attributes for fields in inactive tabs
1326        inactiveTabs.find('.required').prop('required', false);
1327    }
1328
1329    // Trigger the toggle function when switching tabs
1330    $('a[data-bs-toggle="tab"]').on('shown.bs.tab', function () {
1331        toggleRequiredFields();
1332    });
1333
1334    // Call the function on page load to set the correct state
1335    toggleRequiredFields();
1336
1337
1338    // Function to fetch product names using ajax_form
1339    function getProductName(page = 1, keyword = '') {
1340        const requestData = {
1341            page: page,
1342            search: keyword,
1343            parent: 820
1344        };
1345
1346        // Use ajax_form to se\nd the request
1347        ajax_form(requestData, 'https://haroct.com.my/api/v1/products/get-categories').done(function(response) {
1348            if (response.code == 200 && response.items) {
1349                // Clear existing options except the first one
1350                $('#productsSold, #productsSoldPersonal').find('option').not(':first').remove();
1351
1352                // Append new options
1353                response.items.forEach(item => {
1354                    $('#productsSold, #productsSoldPersonal').append(new Option(item.name, item.id));
1355                });
1356            } else {
1357                t('e', response.msg);
1358            }
1359        }).fail(function(jqXHR, textStatus, errorThrown) {
1360            ajax_error(jqXHR);
1361        });
1362    }
1363
1364    $('#productsSold').on('change', function() {
1365        const selectedProductId = $(this).val();
1366        const selectedProductName = $(this).find('option:selected').text();
1367
1368        // You can now use selectedProductId and selectedProductName for further processing
1369        // console.log('Selected Product ID:', selectedProductId);
1370        // console.log('Selected Product Name:', selectedProductName);
1371    });
1372
1373    // Handle product selection
1374    $('#productsSoldPersonal').on('change', function() {
1375        const selectedProductId = $(this).val();
1376        const selectedProductName = $(this).find('option:selected').text();
1377
1378        // You can now use selectedProductId and selectedProductName for further processing
1379        // console.log('Selected Product ID:', selectedProductId);
1380        // console.log('Selected Product Name:', selectedProductName);
1381    });
1382
1383    function fetchAgriInputProducts() {
1384    const requestData = {
1385        parent: 820 // Using the specified verticalId
1386    };
1387
1388    ajax_form(requestData, 'https://haroct.com.my/api/v1/products/get-categories').done(function(response) {
1389        if (response.code == 200 && response.items) {
1390            renderAgriInputProducts(response.items);
1391        } else {
1392            t('e', response.msg || 'Failed to load agricultural input products');
1393        }
1394    }).fail(function(jqXHR, textStatus, errorThrown) {
1395        ajax_error(jqXHR);
1396    });
1397}
1398
1399// Function to render agri input products
1400function renderAgriInputProducts(products) {
1401    const container = $('#agriProductContainer');
1402    container.empty(); // Clear existing content
1403
1404    products.forEach(product => {
1405        const productHtml = `
1406            <div class="col-12 col-md-3 agri-product-item mb-3">
1407                <div class="agri-product-box">
1408                    <input type="checkbox" class="agri-product-checkbox" 
1409                           id="agri-${product.id}" name="verticalType" 
1410                           value="${product.id}" data-product-name="${product.name}">
1411                    <label for="agri-${product.id}">
1412                        <img class="agri-image" src="${product.image || '/themes/store/default/assets/images/default-product.png'}">
1413                        <div class="mt-2">${product.name}</div>
1414                    </label>
1415                </div>
1416            </div>
1417        `;
1418        container.append(productHtml);
1419    });
1420}
1421
1422fetchAgriInputProducts();
1423
1424$(document).on('change', '.agri-product-checkbox', function() {
1425    const $box = $(this).closest('.agri-product-box');
1426    if ($(this).is(':checked')) {
1427        $box.addClass('selected');
1428    } else {
1429        $box.removeClass('selected');
1430    }
1431    
1432    // Update the form validation
1433    checkFields($('#step4'));
1434});
1435
1436// Cross-border interest step: "Where is your business based?" (single choice) +
1437// "Which market do you want to buy/sell from/to?" (multi-select, excludes the chosen home country).
1438var marketCountries = [];
1439
1440function fetchMarketCountries() {
1441    ajax_form({ limit: 100 }, 'https://haroct.com.my/api/v1/g/get-location-countries').done(function(response) {
1442        if (response.code == 200 && response.items) {
1443            marketCountries = response.items;
1444            renderBusinessCountryOptions();
1445        } else {
1446            t('e', response.msg);
1447        }
1448    }).fail(function(jqXHR, textStatus, errorThrown) {
1449        ajax_error(jqXHR);
1450    });
1451}
1452
1453function renderBusinessCountryOptions() {
1454    const container = $('#businessCountryOptions');
1455    const previouslyChecked = $('[name="businessCountryId"]:checked').val();
1456    container.empty();
1457
1458    marketCountries.forEach(function(country) {
1459        const isChecked = previouslyChecked ? (previouslyChecked == country.id) : !!country.isDefault;
1460        const optionHtml = `
1461            <div class="col-auto mb-2">
1462                <div class="radio-box text-center px-3">
1463                    <input type="radio" class="required" id="business-country-${country.id}" name="businessCountryId" value="${country.id}" ${isChecked ? 'checked' : ''}>
1464                    <label for="business-country-${country.id}" class="p-1 p-md-2 px-md-4 w-100">
1465                        <div class="fw-bold">${country.name}</div>
1466                    </label>
1467                </div>
1468            </div>
1469        `;
1470        container.append(optionHtml);
1471    });
1472
1473    renderInterestedMarketOptions();
1474}
1475
1476function renderInterestedMarketOptions() {
1477    const container = $('#interestedMarketOptions');
1478    const businessCountryId = $('[name="businessCountryId"]:checked').val();
1479    const previouslyChecked = $('[name="interestedMarketIds[]"]:checked').map(function() {
1480        return $(this).val();
1481    }).get();
1482    container.empty();
1483
1484    marketCountries.forEach(function(country) {
1485        if (businessCountryId && businessCountryId == country.id) {
1486            return;
1487        }
1488
1489        const isChecked = previouslyChecked.indexOf(String(country.id)) !== -1;
1490        const rowHtml = `
1491            <div class="d-flex align-items-center justify-content-between border rounded-3 p-3 mb-2">
1492                <label class="mb-0" for="market-${country.id}">${country.name}</label>
1493                <input type="checkbox" id="market-${country.id}" name="interestedMarketIds[]" value="${country.id}" style="width:18px;height:18px;flex:none;" ${isChecked ? 'checked' : ''}>
1494            </div>
1495        `;
1496        container.append(rowHtml);
1497    });
1498
1499    updateMarketStepButton();
1500}
1501
1502function updateMarketStepButton() {
1503    $('#stepMarket .next-btn').prop('disabled', !$('[name="businessCountryId"]:checked').length);
1504}
1505
1506function updateMarketQuestionHeading() {
1507    const selectedRole = $('[name="accountType"]:checked').val();
1508    const heading = $('#marketQuestionHeading');
1509
1510    if (selectedRole == 1) {
1511        heading.text('Which market do you want to sell to?');
1512    } else {
1513        heading.text('Which market do you want to buy from?');
1514    }
1515}
1516
1517$(document).on('change', '[name="businessCountryId"]', function() {
1518    renderInterestedMarketOptions();
1519});
1520
1521$(document).on('change', '[name="interestedMarketIds[]"]', function() {
1522    updateMarketStepButton();
1523});
1524
1525$('[name="accountType"]').on('change', updateMarketQuestionHeading);
1526updateMarketQuestionHeading();
1527
1528fetchMarketCountries();
1529
1530    //reside
1531
1532    ajax_form({country:1, limit: 100}, 'https://haroct.com.my/api/v1/g/get-location-states').done(function(response) {
1533        // console.log('state:' ,response);
1534        if (response.code == 200) {
1535            response.items.forEach(function(state) {
1536                $('#stateSelect').append(`<option value="${state.id}">${state.name}</option>`);
1537            });
1538        } else {
1539            t('e', response.msg);
1540        }
1541    }).fail(function(jqXHR, textStatus, errorThrown) {
1542        ajax_error(jqXHR);
1543    });
1544    
1545    $('#stateSelect').change(function() {
1546        var stateId = $(this).val();
1547        $('#citySelect').empty().append('<option value="" selected>Select City</option>');
1548    
1549        ajax_form({state:stateId, limit: 100}, 'https://haroct.com.my/api/v1/g/get-location-cities').done(function(response) {
1550            // console.log('city:' ,response);
1551            if (response.code == 200) {
1552                response.items.forEach(function(city) {
1553                    $('#citySelect').append(`<option value="${city.id}">${city.name}</option>`);
1554                });
1555            } else {
1556                t('e', response.msg);
1557            }
1558        }).fail(function(jqXHR, textStatus, errorThrown) {
1559            ajax_error(jqXHR);
1560        });
1561    });
1562
1563    // Fetch states for both business and personal forms
1564ajax_form({country:1}, 'https://haroct.com.my/api/v1/g/get-location-states').done(function(response) {
1565    if (response.code == 200) {
1566        response.items.forEach(function(state) {
1567            $('#stateSelectBusiness, #stateSelectPersonal').append(`<option value="${state.id}">${state.name}</option>`);
1568        });
1569    } else {
1570        t('e', response.msg);
1571    }
1572}).fail(function(jqXHR, textStatus, errorThrown) {
1573    ajax_error(jqXHR);
1574});
1575
1576// Handle state change for business address
1577$('#stateSelectBusiness').change(function() {
1578    var stateId = $(this).val();
1579    $('#citySelectBusiness').empty().append('<option value="" selected>Select City</option>');
1580
1581    ajax_form({state:stateId}, 'https://haroct.com.my/api/v1/g/get-location-cities').done(function(response) {
1582        if (response.code == 200) {
1583            response.items.forEach(function(city) {
1584                $('#citySelectBusiness').append(`<option value="${city.id}">${city.name}</option>`);
1585            });
1586        } else {
1587            t('e', response.msg);
1588        }
1589    }).fail(function(jqXHR, textStatus, errorThrown) {
1590        ajax_error(jqXHR);
1591    });
1592});
1593
1594// Handle state change for personal address
1595$('#stateSelectPersonal').change(function() {
1596    var stateId = $(this).val();
1597    $('#citySelectPersonal').empty().append('<option value="" selected>Select City</option>');
1598
1599    ajax_form({state:stateId}, 'https://haroct.com.my/api/v1/g/get-location-cities').done(function(response) {
1600        if (response.code == 200) {
1601            response.items.forEach(function(city) {
1602                $('#citySelectPersonal').append(`<option value="${city.id}">${city.name}</option>`);
1603            });
1604        } else {
1605            t('e', response.msg);
1606        }
1607    }).fail(function(jqXHR, textStatus, errorThrown) {
1608        ajax_error(jqXHR);
1609    });
1610});
1611
1612
1613
1614document.querySelectorAll("input[type='checkbox']").forEach(checkbox => {
1615    checkbox.addEventListener("change", function () {
1616        this.style.accentColor = "#5C2D91";
1617    });
1618});
1619
1620document.addEventListener("DOMContentLoaded", function () {
1621    document.querySelectorAll("form").forEach(form => {
1622        form.addEventListener("submit", function (event) {
1623            let isValid = true;
1624            
1625            // Select all required fields excluding optional ones
1626            form.querySelectorAll(".required").forEach(field => {
1627                if (!field.value.trim()) {
1628                    isValid = false;
1629                    field.classList.add("border", "border-danger");
1630                    
1631                    // Add error message if not exists
1632                    if (!field.nextElementSibling || !field.nextElementSibling.classList.contains("error-text")) {
1633                        let errorText = document.createElement("small");
1634                        errorText.classList.add("text-danger", "error-text");
1635                        errorText.innerText = "Please fill this field.";
1636                        field.parentNode.appendChild(errorText);
1637                    }
1638                }
1639            });
1640
1641            // Check required checkboxes
1642            form.querySelectorAll("input[type='checkbox'][required]").forEach(checkbox => {
1643                if (!checkbox.checked) {
1644                    isValid = false;
1645                    
1646                    if (!checkbox.nextElementSibling || !checkbox.nextElementSibling.classList.contains("error-text")) {
1647                        let errorText = document.createElement("small");
1648                        errorText.classList.add("text-danger", "error-text", "d-block");
1649                        errorText.innerText = "Please check this box.";
1650                        checkbox.parentNode.appendChild(errorText);
1651                    }
1652                }
1653            });
1654            
1655            if (!isValid) {
1656                event.preventDefault(); // Prevent form submission if invalid
1657            }
1658        });
1659
1660        // Remove error styling when user types/selects
1661        form.querySelectorAll(".required").forEach(field => {
1662            field.addEventListener("input", function () {
1663                this.classList.remove("border", "border-danger");
1664                if (this.nextElementSibling && this.nextElementSibling.classList.contains("error-text")) {
1665                    this.nextElementSibling.remove();
1666                }
1667            });
1668        });
1669        
1670        form.querySelectorAll("input[type='checkbox'][required]").forEach(checkbox => {
1671            checkbox.addEventListener("change", function () {
1672                if (this.nextElementSibling && this.nextElementSibling.classList.contains("error-text")) {
1673                    this.nextElementSibling.remove();
1674                }
1675            });
1676        });
1677    });
1678});
1679
1680    $(document).on('submit', '#companyAddressForm, #addressForm', function (e) {
1681        e.preventDefault(); // Prevent form submission
1682
1683        // Get the address data
1684        const address1 = $('#address1').val();
1685        const address2 = $('#address2').val();
1686        const stateText = $(this).find('#stateSelectBusiness option:selected, #stateSelectPersonal option:selected').text();
1687        const cityText = $(this).find('#citySelectBusiness option:selected, #citySelectPersonal option:selected').text();
1688        const postcode = $('#postcode').val();
1689
1690        // Construct the full address
1691        const addressParts = [address1, address2, postcode, cityText, stateText ].filter(part => part && part.trim() !== '');
1692        const fullAddress = addressParts.join(', ');
1693
1694        // Update the address display in the container
1695        if ($(this).attr('id') === 'companyAddressForm') {
1696            $('#businessAddressDisplay').text(fullAddress);
1697            $('#businessAddress').val(fullAddress); // Store the full address in a hidden field
1698        } else {
1699            $('#personalAddressDisplay').text(fullAddress);
1700            $('#personalAddress').val(fullAddress); // Store the full address in a hidden field
1701        }
1702
1703        // Close the modal
1704        $(this).closest('.modal').modal('hide');
1705    });
1706    
1707    $(document).on('submit', '#signupForm', function(e) {
1708    e.preventDefault();
1709    $('[type="submit"]').prop('disabled', true);
1710
1711    // Get common form data (from steps 1-3)
1712    const commonData = {
1713        phone: $('[name="phone"]').val(),
1714        countryCode: '+' + iti.getSelectedCountryData().dialCode,
1715        otp: $('[name="otp"]').val(),
1716        code: $('[name="code"]').val(),
1717        accountType: $('[name="accountType"]:checked').val(),
1718        accountSegment: $('[name="accountSegment"]:checked').val(),
1719        verticalType: $('[name="verticalType"]:checked').val(),
1720        businessCountryId: $('[name="businessCountryId"]:checked').val(),
1721        interestedMarketIds: $('[name="interestedMarketIds[]"]:checked').map(function() {
1722            return $(this).val();
1723        }).get(),
1724        version: 1000,
1725        accessToken: '',
1726        userId: '0',
1727        password: getPinValue()
1728    };
1729
1730    // Add referral code if exists
1731    if ($('.referral-block span').text().length) {
1732        commonData.refCode = $('.referral-block span').text();
1733    }
1734
1735    // Include parentId if present
1736    const parentIdVal = $('[name="parentId"]').val();
1737    if (parentIdVal) commonData.parentId = parentIdVal;
1738
1739    const selectedCategoryIds = $('.agri-product-checkbox:checked').map(function() {
1740        return $(this).val();
1741    }).get();
1742    if (selectedCategoryIds.length > 0) {
1743        commonData['categoryIds'] = selectedCategoryIds;
1744    }
1745
1746    // Determine if we're submitting the normal form or agri input form
1747    const isAgriInputForm = $('#step4 .agri-input-form').is(':visible');
1748    
1749    if (isAgriInputForm) {
1750        // Handle Agri Input Form submission (business or personal)
1751        const isBusinessForm = $('#business').hasClass('active');
1752        
1753        if (isBusinessForm) {
1754            // Business form data
1755            const businessData = {
1756                store: {
1757                    name: $('#businessName').val(),
1758                    address1: $('#companyAddress1').val(),
1759                    address2: $('#companyAddress2').val(),
1760                    state: $('#stateSelectBusiness').val(),
1761                    city: $('#citySelectBusiness').val(),
1762                    postcode: $('#postcode').val(),
1763                    phone: $('#personInChargeContact').val(),
1764                    countryCode: '+' + itipersonInChargeContact.getSelectedCountryData().dialCode,
1765                    email: $('#businessEmail').val(),
1766                    ssmNumber: $('#businessRegNo').val()
1767                },
1768                name: $('#personInChargeName').val(),
1769                lat: $('#latCompany').val(),
1770                lng: $('#lngCompany').val(),
1771                verticalType: "agri-input",
1772                isBusiness: 1,
1773                password: getPinValue()
1774            };
1775            
1776            // Merge common data with business data
1777            const formData = {...commonData, ...businessData};
1778            
1779            // Validate required fields
1780            let isValid = true;
1781            $('#business .required').each(function() {
1782                if ($(this).is(':visible') && 
1783                   ((!$(this).val() && !$(this).is(':checkbox')) || 
1784                   ($(this).is(':checkbox') && !$(this).is(':checked')))) {
1785                    isValid = false;
1786                    $(this).addClass('border border-danger');
1787                    // Scroll to first error
1788                    if (isValid) {
1789                        $('html, body').animate({
1790                            scrollTop: $(this).offset().top - 100
1791                        }, 500);
1792                    }
1793                }
1794            });
1795
1796            if (!isValid) {
1797                t('e', 'Please fill in all required fields');
1798                $('[type="submit"]').prop('disabled', false);
1799                return false;
1800            }
1801
1802            // Submit the form
1803            ajax_form(formData, 'https://haroct.com.my/api/v1/u/signup').done(function(response) {
1804                handleSignupResponse(response);
1805            }).fail(function(jqXHR, textStatus, errorThrown) {
1806                ajax_error(jqXHR);
1807                $('[type="submit"]').prop('disabled', false);
1808            });
1809
1810        } else {
1811            // Personal form data
1812            const personalData = {
1813                name: $('#personalName').val(),
1814                email: $('#personalEmail').val(),
1815                idNo: $('#personalIC').val(),
1816                lat: $('#lat').val(),
1817                lng: $('#lng').val(),
1818                delivery: {
1819                    name: $('#nameAddress').val(),
1820                    phone: $('#contact').val(),
1821                    countryCode: '+' + itiContact.getSelectedCountryData().dialCode,
1822                    address: $('#address1').val(),
1823                    addressLine2: $('#address2').val(),
1824                    locationState: $('#stateSelectPersonal').val(),
1825                    locationCity: $('#citySelectPersonal').val(),
1826                    postcode: $('#personalPostcode').val()
1827                },
1828                verticalType: "agri-input",
1829                isBusiness: 0,
1830                password: getPinValue()
1831            };
1832
1833            // Merge common data with personal data
1834            const formData = {...commonData, ...personalData};
1835
1836            const idDocEncoded = $('[name="idDoc[data]"]').val();
1837            if (idDocEncoded) {
1838                formData['idDoc[data]'] = idDocEncoded;
1839            }
1840            
1841            // Validate required fields
1842            let isValid = true;
1843            $('#personal .required').each(function() {
1844                if ($(this).is(':visible') && 
1845                   ((!$(this).val() && !$(this).is(':checkbox')) || 
1846                   ($(this).is(':checkbox') && !$(this).is(':checked')))) {
1847                    isValid = false;
1848                    $(this).addClass('border border-danger');
1849                    // Scroll to first error
1850                    if (isValid) {
1851                        $('html, body').animate({
1852                            scrollTop: $(this).offset().top - 100
1853                        }, 500);
1854                    }
1855                }
1856            });
1857
1858            if (!isValid) {
1859                t('e', 'Please fill in all required fields');
1860                $('[type="submit"]').prop('disabled', false);
1861                return false;
1862            }
1863
1864            ajax_form(formData, 'https://haroct.com.my/api/v1/u/signup').done(function(response) {
1865                handleSignupResponse(response);
1866            }).fail(function(jqXHR, textStatus, errorThrown) {
1867                ajax_error(jqXHR);
1868                $('[type="submit"]').prop('disabled', false);
1869            });
1870        }
1871    } else {
1872        commonData.locationState = $('#stateSelect').val();
1873        commonData.locationCity = $('#citySelect').val();
1874
1875        commonData.name = $('#step5 [name="name"]:visible').val();
1876        commonData.email = $('#step5 [name="email"]:visible').val();
1877        if($('#step5 [name="isBusiness"]').val()){
1878            commonData.isBusiness = 1;
1879            commonData.accountType = 1;
1880        }
1881        commonData.avatar = avatar;
1882
1883        // Validate required fields
1884        let isValid = true;
1885        $('.normal-form .required').each(function() {
1886            if ((!$(this).val() && !$(this).is(':checkbox')) || 
1887                ($(this).is(':checkbox') && !$(this).is(':checked'))) {
1888                isValid = false;
1889                $(this).addClass('border', 'border-danger');
1890                // Scroll to first error
1891                if (isValid) {
1892                    $('html, body').animate({
1893                        scrollTop: $(this).offset().top - 100
1894                    }, 500);
1895                }
1896            }
1897        });
1898
1899        if (!isValid) {
1900            t('e', 'Please fill in all required fields');
1901            $('[type="submit"]').prop('disabled', false);
1902            return false;
1903        }
1904
1905        // Check if email is filled
1906        const email = commonData.email;
1907
1908        if (!email || email.trim() === '') {
1909            // Email is empty, show the modal
1910            emailModal.show();
1911            $('[type="submit"]').prop('disabled', false);
1912
1913            // Store the form data for later use
1914            $('#signupForm').data('pendingSubmission', commonData);
1915        } else {
1916            // Email is filled, proceed with signup
1917            submitNormalForm(commonData);
1918        }
1919    }
1920});
1921
1922function submitNormalForm(formData) {
1923    ajax_form(formData, 'https://haroct.com.my/api/v1/u/signup').done(function(response) {
1924        handleSignupResponse(response);
1925    }).fail(function(jqXHR, textStatus, errorThrown) {
1926        ajax_error(jqXHR);
1927        $('[type="submit"]').prop('disabled', false);
1928    });
1929}
1930
1931// Add this at the end of the document ready function to handle modal button clicks
1932$(document).on('click', '#emailModal .btn-haroct', function(e) {
1933    e.preventDefault();
1934    
1935    // User clicked "Add Email Now" - close modal
1936    emailModal.hide();
1937    $('[type="submit"]').prop('disabled', false);
1938});
1939
1940$(document).on('click', '#emailModal a[data-bs-dismiss="modal"]', function(e) {
1941    e.preventDefault();
1942    
1943    // User clicked "It's okay, I will do it later" - proceed with signup
1944    const pendingData = $('#signupForm').data('pendingSubmission');
1945    if (pendingData) {
1946        emailModal.hide();
1947        submitNormalForm(pendingData);
1948        // Clear the stored data
1949        $('#signupForm').removeData('pendingSubmission');
1950    }
1951});
1952
1953// Initialize the modal
1954var emailModal = new bootstrap.Modal(document.getElementById('emailModal'));
1955
1956function handleSignupResponse(response) {
1957    if (response.code == 200) {
1958        t('s', response.msg);
1959        const accountSegment = $('[name="accountSegment"]:checked').val();
1960        if (accountSegment == 106 || accountSegment == 205) {
1961            location.href = 'https://haroct.com.my/agri-input/auth?accessToken=' + response.accessToken;
1962        } else {
1963            location.href = 'https://haroct.com.my/store/auth?accessToken=' + response.accessToken;
1964        }
1965    } else {
1966        t('e', response.msg);
1967        $('[type="submit"]').prop('disabled', false);
1968    }
1969}
1970    
1971    /*
1972    $(document).on('click', '.btn-submit-referral', function(e){
1973        e.preventDefault();
1974        code = $('#referral-code').val().replace(/[^a-zA-Z0-9]/g, '');
1975        if(code.length){
1976            $('.btn-claim').val('Claimed');
1977            $('.referral-block span').text(code);
1978            $('.referral-block').removeClass('d-none');
1979        }else{
1980            $('.btn-claim').val('Claim');
1981            $('.referral-block span').text('');
1982            $('.referral-block').addClass('d-none');
1983        }
1984    });
1985    */
1986    
1987    $(document).on('click', '.btn-remove-referral', function(e){
1988        e.preventDefault();
1989        $('.btn-claim').val('Claim');
1990        $('#referral-code').val('');
1991        $('.referral-block span').text('');
1992        $('.referral-block').addClass('d-none');
1993    });
1994
1995    $('[name="accountType"]').change();
1996});
1997
1998var iti;
1999var itiContact;
2000var itipersonInChargeContact;
2001var rtoken = '';
2002
2003$(function(){
2004    $(document).on('click', 'body', function(){
2005        grecaptcha.enterprise.ready(async () => {
2006            rtoken = await grecaptcha.enterprise.execute('6Lcim1osAAAAANvZ5krlNRs6QP11OT71fvoj2ous', {action: 'LOGIN'});
2007        });
2008    });
2009
2010    iti = window.intlTelInput(document.querySelector("#phone"), {
2011        initialCountry: "my",
2012        onlyCountries: ["my", "th", "sg"],
2013        showDialCode: true,
2014        separateDialCode: true,
2015    });
2016
2017    document.querySelector("#phone").addEventListener("countrychange", function() {
2018        var selectedCountry = iti.getSelectedCountryData();
2019        var countryCode = '+' + selectedCountry.dialCode;
2020        $('[name="countryCode"]').val(countryCode);
2021        
2022        if (selectedCountry.iso2 === 'th') {
2023            $('.thai-guide').removeClass('d-none');
2024        } else if (selectedCountry.iso2 === 'my') {
2025            $('.thai-guide').addClass('d-none');
2026        }
2027    });
2028
2029    document.querySelector("#phone").addEventListener("input", function() {
2030        var selectedCountry = iti.getSelectedCountryData().iso2;
2031        
2032        if (selectedCountry === 'th') {
2033            var phoneValue = this.value;
2034            
2035            if (phoneValue.startsWith('0')) {
2036                $('.default-thai-guide').addClass('d-none');
2037                $('.error-thai-guide').removeClass('d-none');
2038                $('.signup-btn').addClass('disabled');
2039            } else {
2040                $('.default-thai-guide').removeClass('d-none');
2041                $('.error-thai-guide').addClass('d-none');
2042                $('.signup-btn').removeClass('disabled');
2043            }
2044        }
2045    });
2046});
2047
2048    $(function () {
2049        // Initialize intlTelInput for #contact
2050        itiContact = window.intlTelInput(document.querySelector("#contact"), {
2051            initialCountry: "my",
2052            onlyCountries: ["my", "th", "sg"],
2053            showDialCode: true,
2054            separateDialCode: true
2055        });
2056
2057        // Listen for country change events
2058        document.querySelector("#contact").addEventListener("countrychange", function () {
2059            var selectedCountry = itiContact.getSelectedCountryData();
2060            var countryCode = '+' + selectedCountry.dialCode;
2061            $('#countryCode').val(countryCode);
2062
2063            // Show/hide Thai-specific guidance
2064            if (selectedCountry.iso2 === 'th') {
2065                $('.thai-guide').removeClass('d-none');
2066            } else {
2067                $('.thai-guide').addClass('d-none');
2068            }
2069        });
2070
2071        // Validate Thai phone numbers
2072        document.querySelector("#contact").addEventListener("input", function () {
2073            var selectedCountry = itiContact.getSelectedCountryData().iso2;
2074            var phoneValue = this.value.trim();
2075
2076            if (selectedCountry === 'th') {
2077                if (phoneValue.startsWith('0')) {
2078                    $('.default-thai-guide').addClass('d-none');
2079                    $('.error-thai-guide').removeClass('d-none');
2080                    $('.btn-haroct').addClass('disabled');
2081                } else {
2082                    $('.default-thai-guide').removeClass('d-none');
2083                    $('.error-thai-guide').addClass('d-none');
2084                    $('.btn-haroct').removeClass('disabled');
2085                }
2086            }
2087        });
2088    });
2089
2090
2091    $(function () {
2092        // Initialize intlTelInput for #contact
2093        itipersonInChargeContact = window.intlTelInput(document.querySelector("#personInChargeContact"), {
2094            initialCountry: "my",
2095            onlyCountries: ["my", "th", "sg"],
2096            showDialCode: true,
2097            separateDialCode: true
2098        });
2099
2100        // Listen for country change events
2101        document.querySelector("#personInChargeContact").addEventListener("countrychange", function () {
2102            var selectedCountry = itipersonInChargeContact.getSelectedCountryData();
2103            var countryCode = '+' + selectedCountry.dialCode;
2104            $('#countryCode').val(countryCode);
2105
2106            // Show/hide Thai-specific guidance
2107            if (selectedCountry.iso2 === 'th') {
2108                $('.thai-guide').removeClass('d-none');
2109            } else {
2110                $('.thai-guide').addClass('d-none');
2111            }
2112        });
2113
2114        // Validate Thai phone numbers
2115        document.querySelector("#personInChargeContact").addEventListener("input", function () {
2116            var selectedCountry = itipersonInChargeContact.getSelectedCountryData().iso2;
2117            var phoneValue = this.value.trim();
2118
2119            if (selectedCountry === 'th') {
2120                if (phoneValue.startsWith('0')) {
2121                    $('.default-thai-guide').addClass('d-none');
2122                    $('.error-thai-guide').removeClass('d-none');
2123                    $('.btn-haroct').addClass('disabled');
2124                } else {
2125                    $('.default-thai-guide').removeClass('d-none');
2126                    $('.error-thai-guide').addClass('d-none');
2127                    $('.btn-haroct').removeClass('disabled');
2128                }
2129            }
2130        });
2131    });
2132
2133
2134let otpCountdownInterval;
2135function startOtpCountdown() {
2136    let timeLeft = 5 * 60 - 1;
2137    $('.otp-countdown').removeClass('d-none');
2138    $('.btn-resend-otp').addClass('d-none');
2139    
2140    if (otpCountdownInterval) clearInterval(otpCountdownInterval);
2141    
2142    otpCountdownInterval = setInterval(function() {
2143        const minutes = Math.floor(timeLeft / 60);
2144        const seconds = timeLeft % 60;
2145        $('.otp-countdown span').text(`${minutes}:${seconds.toString().padStart(2, '0')}`);
2146
2147        if (timeLeft <= 0) {
2148            clearInterval(otpCountdownInterval);
2149            $('.otp-countdown span').text('');
2150            $('.otp-countdown').addClass('d-none');
2151            $('.btn-resend-otp').removeClass('d-none');
2152        }
2153        timeLeft--;
2154    }, 1000);
2155}
2156
2157$(document).on('click', '.btn-resend-otp', function(e) {
2158    e.preventDefault();
2159    $('.btn-request-otp').click();
2160});
2161
2162    $(document).on('click', '.btn-request-otp', function(e){
2163        e.preventDefault();
2164        let el = $(this);
2165    
2166        // Check if T&C is checked
2167        if (!$('#tnc').is(':checked')) {
2168            t('e', 'Please accept the Terms & Conditions');
2169            return false;
2170        }
2171    
2172        let originalText = el.text();
2173        let countryCode = '+' + iti.getSelectedCountryData().dialCode;
2174        let phone = $('[name="phone"]').val().replace(/[^a-zA-Z0-9]/g, '');
2175    
2176        $('[name="countryCode"]').val(countryCode);
2177    
2178        if(!phone.length){
2179            t('e', 'Phone number is required');
2180            return false;
2181        }
2182    
2183        // Skip OTP for Thailand (+66)
2184        if (countryCode === '+66') {
2185            if (typeof window.proceedToStep2 === 'function') {
2186                window.proceedToStep2();
2187            }
2188            return false;
2189        }
2190    
2191        $('.otp-pin').val('');
2192        $('[name="otp"]').val('');
2193        $('[name="code"]').val('');
2194        checkOtpComplete();
2195
2196        let data = {phone: phone, countryCode: countryCode, rtoken: rtoken, version: 1000};
2197        el.prop('disabled', true).text('Requesting...');
2198
2199        $('.phone-number').text(countryCode + phone);
2200
2201    ajax_form(data, 'https://haroct.com.my/api/v1/u/check-phone-availability').done(function(response) {
2202        if (response.code == 200) {
2203            ajax_form(data, 'https://haroct.com.my/api/v1/u/request-otp').done(function(response) {
2204                if (response.code == 200) {
2205                    // t('s', response.msg);
2206                    
2207                    var otpModal = new bootstrap.Modal(document.getElementById('otpModal'));
2208                    otpModal.show();
2209                    
2210                    startOtpCountdown();
2211
2212                    setTimeout(function() {
2213                        $('.otp-pin').first().focus();
2214                    }, 500);
2215
2216                } else {
2217                    t('e', response.msg);
2218                }
2219            }).fail(function(jqXHR, textStatus, errorThrown) {
2220                ajax_error(jqXHR);
2221            }).always(function() {
2222                el.prop('disabled', false).text(originalText);
2223            });
2224        }else{
2225            t('e', response.msg);
2226            el.prop('disabled', false).text(originalText);
2227        }
2228    }).fail(function(jqXHR, textStatus, errorThrown) {
2229        ajax_error(jqXHR);
2230        el.prop('disabled', false).text(originalText);
2231    });
2232});
2233
2234$(document).on('click', '.btn-verify-otp', function() {
2235    let otpValue = '';
2236    $('.otp-pin').each(function() {
2237        otpValue += $(this).val();
2238    });
2239    
2240    let phone = $('[name="phone"]').val().replace(/[^a-zA-Z0-9]/g, '');
2241    let countryCode = '+' + iti.getSelectedCountryData().dialCode;
2242    
2243    $('[name="otp"]').val(otpValue);
2244    $('[name="code"]').val(otpValue);
2245
2246    let verifyBtn = $(this);
2247    let originalText = verifyBtn.text();
2248    verifyBtn.prop('disabled', true).text('Verifying...');
2249
2250    ajax_form({
2251        phone: phone,
2252        countryCode: countryCode,
2253        otp: otpValue
2254    }, 'https://haroct.com.my/api/v1/u/validate-otp').done(function(response) {
2255        if (response.code == 200) {
2256            var otpModal = bootstrap.Modal.getInstance(document.getElementById('otpModal'));
2257            if(otpModal) otpModal.hide();
2258            
2259            if (typeof window.proceedToStep2 === 'function') {
2260                window.proceedToStep2();
2261            }
2262        } else {
2263            t('e', response.msg || 'Invalid OTP code');
2264            $('.otp-pin').val('');
2265            $('.otp-pin').first().focus();
2266            verifyBtn.prop('disabled', true);
2267        }
2268    }).fail(function(jqXHR, textStatus, errorThrown) {
2269        ajax_error(jqXHR);
2270    }).always(function() {
2271        verifyBtn.prop('disabled', false).text(originalText);
2272    });
2273});
2274
2275function checkOtpComplete() {
2276    const otpInputs = $('.otp-pin');
2277    const isComplete = otpInputs.toArray().every(input => $(input).val());
2278    $('.btn-verify-otp').prop('disabled', !isComplete);
2279}
2280
2281$(document).on('input', '.otp-pin', function (e) {
2282    let index = $('.otp-pin').index(this);
2283    
2284    if (this.value.length > 1) {
2285        let pastedData = this.value.substring(0, 6);
2286        $('.otp-pin').each(function(i, el) {
2287            if (i < pastedData.length) {
2288                $(el).val(pastedData[i]);
2289            } else {
2290                $(el).val('');
2291            }
2292        });
2293        if (pastedData.length === 6) {
2294            $('.otp-pin').last().focus();
2295        } else {
2296            $('.otp-pin').eq(pastedData.length).focus();
2297        }
2298        checkOtpComplete();
2299        return;
2300    }
2301
2302    const value = this.value;
2303    if (value.length === 1 && index < $('.otp-pin').length - 1) {
2304        $('.otp-pin').eq(index + 1).focus();
2305    }
2306    if (value.length === 0 && index > 0) {
2307        $('.otp-pin').eq(index - 1).focus();
2308    }
2309    checkOtpComplete();
2310});
2311
2312$(document).on('keydown', '.otp-pin', function (e) {
2313    let index = $('.otp-pin').index(this);
2314    if (e.key === 'Backspace' && !this.value && index > 0) {
2315        $('.otp-pin').eq(index - 1).focus();
2316    }
2317});
2318
2319
2320var referralModal = new bootstrap.Modal(document.getElementById('referralModal'));
2321$(document).on('click', '.btn-submit-referral', function(e){
2322    e.preventDefault();
2323    code = $('#referral-code').val().replace(/[^a-zA-Z0-9]/g, '');
2324    if(code.length){
2325        ajax_form({refCode: code, version: 1000}, 'https://haroct.com.my/api/v1/u/check-ref-code').done(function(response) {
2326            if (response.code == 200) {
2327                referralModal.hide();
2328                
2329                $('.btn-claim').val('Claimed');
2330                $('.referral-block span').text(code);
2331                $('.referral-block').removeClass('d-none');
2332            } else {
2333                t('e', response.msg);
2334            }
2335        }).fail(function(jqXHR, textStatus, errorThrown) {
2336            ajax_error(jqXHR);
2337        }).always(function(){
2338            $('[type="submit"]').prop('disabled', false);
2339        });
2340    }else{
2341        $('.btn-claim').val('Claim');
2342        $('.referral-block span').text('');
2343        $('.referral-block').addClass('d-none');
2344    }
2345});
2346
2347$(document).on('click', '.btn-remove-referral', function(e){
2348    e.preventDefault();
2349    $('.btn-claim').val('Claim');
2350    $('#referral-code').val('');
2351    $('.referral-block span').text('');
2352    $('.referral-block').addClass('d-none');
2353});
2354function jsonToUrlParams(json) {
2355    return Object.keys(json)
2356        .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(json[key]))
2357        .join('&');
2358}
2359</script>
2359
2360
2361
2362<script>
2363var mapCompany, mapPersonal, markerCompany, markerPersonal, autocompleteCompany, autocompletePersonal;
2364const defaultLocation = { lat: 3.1390, lng: 101.6869 };
2365
2366function initAutocomplete() {
2367// console.log('Initializing autocomplete...'); 
2368    if ("geolocation" in navigator) {
2369        navigator.geolocation.getCurrentPosition(function(position) {
2370            const userLocation = {
2371                lat: position.coords.latitude,
2372                lng: position.coords.longitude
2373            };
2374            initializeMap(userLocation, 'company');
2375            initializeMap(userLocation, 'personal');
2376        }, function(error) {
2377            console.error("Error getting user location:", error);
2378            initializeMap(defaultLocation, 'company');
2379            initializeMap(defaultLocation, 'personal');
2380        });
2381    } else {
2382        // console.log("Geolocation is not supported by this browser.");
2383        initializeMap(defaultLocation, 'company');
2384        initializeMap(defaultLocation, 'personal');
2385    }
2386
2387    // Initialize autocomplete for company address
2388    autocompleteCompany = new google.maps.places.Autocomplete(
2389        document.getElementById('companyAddress2'),
2390        { types: ['geocode', 'establishment'], componentRestrictions: { country: 'my' } }
2391    );
2392    autocompleteCompany.addListener('place_changed', function () {
2393        handlePlaceChanged(autocompleteCompany, 'company');
2394    });
2395
2396    // Initialize autocomplete for personal address
2397    autocompletePersonal = new google.maps.places.Autocomplete(
2398        document.getElementById('address2'),
2399        { types: ['geocode', 'establishment'], componentRestrictions: { country: 'my' } }
2400    );
2401    autocompletePersonal.addListener('place_changed', function () {
2402        handlePlaceChanged(autocompletePersonal, 'personal');
2403    });
2404}
2405
2406function handlePlaceChanged(autocomplete, type) {
2407    const place = autocomplete.getPlace();
2408    if (place.geometry) {
2409        const map = type === 'company' ? mapCompany : mapPersonal;
2410        const marker = type === 'company' ? markerCompany : markerPersonal;
2411
2412        map.setCenter(place.geometry.location);
2413        map.setZoom(13);
2414
2415        marker.setPosition(place.geometry.location);
2416        let placeName = '';
2417        if (place.name) {
2418            placeName = place.name.split(',')[0].trim();
2419        } else {
2420            place.address_components.some(component => {
2421                if (component.types.includes('premise') || component.types.includes('point_of_interest') || component.types.includes('establishment')) {
2422                    placeName = component.long_name;
2423                    return true;
2424                }
2425            });
2426        }
2427        if (!placeName && place.formatted_address) {
2428            placeName = place.formatted_address.split(',')[0].trim();
2429        }
2430
2431        document.getElementById(type === 'company' ? 'companyAddress2' : 'address2').value = placeName;
2432        document.getElementById(type === 'company' ? 'latCompany' : 'lat').value = place.geometry.location.lat();
2433        document.getElementById(type === 'company' ? 'lngCompany' : 'lng').value = place.geometry.location.lng();
2434    }
2435}
2436
2437function initializeMap(location, type) {
2438    const mapElement = type === 'company' ? document.querySelector(".map-container-company") : document.querySelector(".map-container-personal");
2439    const map = new google.maps.Map(mapElement, {
2440        center: location,
2441        zoom: 13
2442    });
2443
2444    const marker = new google.maps.Marker({
2445        position: location,
2446        map: map,
2447        draggable: true
2448    });
2449
2450    google.maps.event.addListener(marker, 'dragend', function () {
2451        const position = marker.getPosition();
2452        document.getElementById(type === 'company' ? 'latCompany' : 'lat').value = position.lat();
2453        document.getElementById(type === 'company' ? 'lngCompany' : 'lng').value = position.lng();
2454    });
2455
2456    document.getElementById(type === 'company' ? 'latCompany' : 'lat').value = location.lat;
2457    document.getElementById(type === 'company' ? 'lngCompany' : 'lng').value = location.lng;
2458
2459    if (type === 'company') {
2460        mapCompany = map;
2461        markerCompany = marker;
2462    } else {
2463        mapPersonal = map;
2464        markerPersonal = marker;
2465    }
2466}
2467
2468window.onload = initAutocomplete;
2469
2470let currentPage = 1;
2471let isLoading = false;
2472let hasMoreItems = true;
2473let searchTimeout = null;
2474
2475function getProductName(page = 1, keyword = '') {
2476    const requestData = {
2477        page: page,
2478        search: keyword,
2479        parent: 820
2480    };
2481
2482    // Send AJAX request using ajax_form
2483    ajax_form(requestData, 'https://haroct.com.my/api/v1/products/get-categories').done(function(response) {
2484        if (response.code == 200 && response.items) {
2485
2486            if (page === 1) {
2487                document.querySelector('.product-list-container').innerHTML = '';
2488            }
2489
2490            // Append product name options to the container
2491            appendProductNameOptions(response.items, '.product-list-container');
2492
2493            // Update hasMoreItems based on response
2494            hasMoreItems = response.items.length > 0;
2495        }
2496        isLoading = false;
2497    }).fail(function(jqXHR, textStatus, errorThrown) {
2498        // Handle AJAX errors
2499        console.error('AJAX request failed:', textStatus, errorThrown);
2500        isLoading = false;
2501    });
2502}
2503
2504
2505function appendProductNameOptions(items, selector) {
2506    const productListContainer = document.querySelector(selector);
2507    
2508    items.forEach(item => {
2509        const productDiv = document.createElement('div');
2510        productDiv.className = 'product-item';
2511        productDiv.setAttribute('data-product-id', item.id);
2512        productDiv.setAttribute('data-product-name', item.name);
2513
2514        const checkbox = document.createElement('input');
2515        checkbox.type = 'checkbox';
2516        checkbox.className = 'product-checkbox';
2517        checkbox.setAttribute('data-product-id', item.id);
2518        checkbox.setAttribute('data-product-name', item.name);
2519
2520        const label = document.createElement('label');
2521        label.textContent = item.name;
2522        label.className = 'product-label';
2523
2524        productDiv.appendChild(checkbox);
2525        productDiv.appendChild(label);
2526        productListContainer.appendChild(productDiv);
2527    });
2528}
2529
2530$(function() {
2531    productNameModal = new bootstrap.Modal(document.getElementById('productNameModal'));
2532
2533    // Product name click handler
2534    $(document).on('click', '.product-name', function(e) {
2535        e.preventDefault();
2536        currentPage = 1;
2537        hasMoreItems = true;
2538        getProductName(currentPage);
2539        productNameModal.show();
2540    });
2541
2542    // Product item selection handler
2543    $(document).on('change', '.product-checkbox', function() {
2544        const selectedProducts = [];
2545        $('.product-checkbox:checked').each(function() {
2546            selectedProducts.push($(this).attr('data-product-name'));
2547        });
2548        $('.product-name-label').html(selectedProducts.join(', '));
2549    });
2550
2551    // Scroll pagination handler
2552    $('.product-list').on('scroll', function() {
2553        const { scrollTop, scrollHeight, clientHeight } = this;
2554        
2555        // Check if we're near the bottom (within 50px)
2556        if (scrollHeight - scrollTop - clientHeight < 50) {
2557            if (!isLoading && hasMoreItems) {
2558                isLoading = true;
2559                currentPage++;
2560                
2561                // Get current search keyword
2562                const keyword = $('.search-input').val().trim();
2563                getProductName(currentPage, keyword);
2564            }
2565        }
2566    });
2567
2568    // Confirm button handler
2569    $('.confirm-product-name').on('click', function(e) {
2570        e.preventDefault();
2571        productNameModal.hide();
2572    });
2573
2574    $('.search-input').on('input', function() {
2575        const keyword = $(this).val().trim();
2576        
2577        // Clear any existing timeout
2578        if (searchTimeout) {
2579            clearTimeout(searchTimeout);
2580        }
2581        
2582        // Reset pagination variables
2583        currentPage = 1;
2584        hasMoreItems = true;
2585        isLoading = false;
2586        
2587        // Set new timeout for search
2588        searchTimeout = setTimeout(() => {
2589            getProductName(currentPage, keyword);
2590        }, 300);
2591    });
2592
2593    const $fileInput = $('#storeLogoInput');
2594    const $uploadButton = $('.upload-btn');
2595    const $logoPlaceholder = $('#logo-placeholder');
2596
2597    function triggerFileInput() {
2598        $fileInput.trigger('click');
2599    }
2600    
2601    $uploadButton.on('click', triggerFileInput);
2602    $logoPlaceholder.on('click', triggerFileInput);
2603
2604    $fileInput.on('change', function(event) {
2605        const file = event.target.files[0];
2606        
2607        if (file) {
2608            const reader = new FileReader();
2609            
2610            reader.onload = function(e) {
2611                const base64String = e.target.result;
2612                avatar = base64String; 
2613                $logoPlaceholder.empty(); 
2614                
2615                const $img = $('<img>', {
2616                    src: base64String,
2617                    class: 'img-fluid rounded-circle'
2618                });
2619                $logoPlaceholder.append($img);
2620            };
2621            
2622            reader.readAsDataURL(file);
2623        }
2624    });
2625});
2626
2627function getPinValue() {
2628    const pinInputs = $('.pin');
2629    let pinValue = '';
2630
2631    pinInputs.each(function() {
2632        pinValue += $(this).val() || '0';
2633    });
2634
2635    return pinValue.padStart(6, '0');
2636}
2637
2638function checkPinComplete() {
2639    const pinInputs = $('.pin');
2640    const isComplete = pinInputs.toArray().every(input => $(input).val());
2641    pinInputs.closest('.form-step').find('.next-btn').prop('disabled', !isComplete);
2642}
2643</script>
2643
2644        </div>
2645    </body>
2646</html>

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.