medos-sdk 1.1.7 → 1.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/SuccessStep.js +1 -1
- package/dist/vanilla/AppointmentCalendarWidget.d.ts +8 -0
- package/dist/vanilla/AppointmentCalendarWidget.js +463 -158
- package/dist/vanilla/EnquiryFormWidget.d.ts +2 -0
- package/dist/vanilla/EnquiryFormWidget.js +155 -100
- package/dist/vanilla/components/VanillaCalendar.d.ts +32 -0
- package/dist/vanilla/components/VanillaCalendar.js +366 -0
- package/dist/vanilla/components/VanillaIcons.d.ts +17 -0
- package/dist/vanilla/components/VanillaIcons.js +268 -0
- package/dist/vanilla/components/VanillaSelect.d.ts +46 -0
- package/dist/vanilla/components/VanillaSelect.js +523 -0
- package/dist/vanilla/components/index.d.ts +3 -0
- package/dist/vanilla/components/index.js +3 -0
- package/dist/vanilla/components/theme-injector.d.ts +1 -0
- package/dist/vanilla/components/theme-injector.js +447 -0
- package/dist/vanilla/enquiry-widget.js +1366 -100
- package/dist/vanilla/vanilla/AppointmentCalendarWidget.d.ts +8 -0
- package/dist/vanilla/vanilla/EnquiryFormWidget.d.ts +2 -0
- package/dist/vanilla/vanilla/components/VanillaCalendar.d.ts +32 -0
- package/dist/vanilla/vanilla/components/VanillaIcons.d.ts +17 -0
- package/dist/vanilla/vanilla/components/VanillaSelect.d.ts +46 -0
- package/dist/vanilla/vanilla/components/index.d.ts +3 -0
- package/dist/vanilla/vanilla/components/theme-injector.d.ts +1 -0
- package/dist/vanilla/vanilla/widget.d.ts +2 -0
- package/dist/vanilla/widget.d.ts +2 -0
- package/dist/vanilla/widget.js +2213 -257
- package/package.json +1 -1
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import { AppointmentService, } from "../services/AppointmentService";
|
|
2
2
|
import { PatientService } from "../services/PatientService";
|
|
3
3
|
import { MedosClient } from "../client/MedosClient";
|
|
4
|
-
import { INITIAL_STATE, } from "../components/types";
|
|
4
|
+
import { INITIAL_STATE, COUNTRY_CODES, GENDER_OPTIONS, BLOOD_GROUP_OPTIONS, } from "../components/types";
|
|
5
5
|
import { validatePhoneNumber, validateCountryCode, } from "../components/validation";
|
|
6
6
|
import { formatDateToISO, parsePatientName } from "../components/utils";
|
|
7
|
+
import { VanillaIcons } from "./components/VanillaIcons";
|
|
8
|
+
import { VanillaSelect } from "./components/VanillaSelect";
|
|
9
|
+
import { VanillaCalendar } from "./components/VanillaCalendar";
|
|
10
|
+
import { injectThemedStyles } from "./components/theme-injector";
|
|
7
11
|
class AppointmentCalendarWidget {
|
|
8
12
|
constructor(container, options) {
|
|
9
13
|
this.mounted = true;
|
|
10
14
|
this.doctors = [];
|
|
15
|
+
this.addressSelect = null;
|
|
16
|
+
this.doctorSelect = null;
|
|
17
|
+
this.calendar = null;
|
|
18
|
+
this.countryCodeSelect = null;
|
|
19
|
+
this.genderSelect = null;
|
|
20
|
+
this.bloodGroupSelect = null;
|
|
21
|
+
injectThemedStyles();
|
|
11
22
|
if (typeof container === "string") {
|
|
12
23
|
const el = document.getElementById(container);
|
|
13
24
|
if (!el) {
|
|
@@ -195,8 +206,27 @@ class AppointmentCalendarWidget {
|
|
|
195
206
|
return false;
|
|
196
207
|
return true;
|
|
197
208
|
}
|
|
209
|
+
updateSubmitButtonState() {
|
|
210
|
+
const submitBtn = this.container.querySelector("#medos-btn-submit");
|
|
211
|
+
if (submitBtn) {
|
|
212
|
+
const canSubmit = this.state.patientName &&
|
|
213
|
+
this.state.patientAddress &&
|
|
214
|
+
this.state.patientCity &&
|
|
215
|
+
this.state.patientState &&
|
|
216
|
+
this.state.patientCountry &&
|
|
217
|
+
this.state.patientZipcode &&
|
|
218
|
+
this.state.patientEmail &&
|
|
219
|
+
this.state.patientAge &&
|
|
220
|
+
this.state.otpVerified;
|
|
221
|
+
submitBtn.disabled = !(canSubmit && !this.state.loading);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
198
224
|
async sendOtp() {
|
|
199
225
|
this.setState({ error: null });
|
|
226
|
+
console.log("sendOtp called - Current state:", {
|
|
227
|
+
countryCode: this.state.countryCode,
|
|
228
|
+
patientPhone: this.state.patientPhone,
|
|
229
|
+
});
|
|
200
230
|
if (!this.state.countryCode) {
|
|
201
231
|
this.setState({ error: "Please enter country code." });
|
|
202
232
|
return;
|
|
@@ -220,6 +250,10 @@ class AppointmentCalendarWidget {
|
|
|
220
250
|
this.setState({ otpSending: true });
|
|
221
251
|
this.render();
|
|
222
252
|
try {
|
|
253
|
+
console.log("Sending OTP to:", {
|
|
254
|
+
countryCode: this.state.countryCode,
|
|
255
|
+
phoneNumber: this.state.patientPhone,
|
|
256
|
+
});
|
|
223
257
|
await PatientService.sendPhoneVerificationOtp({
|
|
224
258
|
countryCode: this.state.countryCode,
|
|
225
259
|
phoneNumber: this.state.patientPhone,
|
|
@@ -227,7 +261,10 @@ class AppointmentCalendarWidget {
|
|
|
227
261
|
this.setState({ otpSent: true, error: null });
|
|
228
262
|
}
|
|
229
263
|
catch (e) {
|
|
230
|
-
|
|
264
|
+
console.error("Send OTP error:", e);
|
|
265
|
+
const msg = e?.response?.data?.message ||
|
|
266
|
+
e?.message ||
|
|
267
|
+
"Failed to send OTP. Please try again.";
|
|
231
268
|
this.setState({ error: msg });
|
|
232
269
|
this.options.onError?.(e);
|
|
233
270
|
}
|
|
@@ -251,6 +288,11 @@ class AppointmentCalendarWidget {
|
|
|
251
288
|
this.setState({ otpVerifying: true });
|
|
252
289
|
this.render();
|
|
253
290
|
try {
|
|
291
|
+
console.log("Verifying OTP with:", {
|
|
292
|
+
countryCode: this.state.countryCode,
|
|
293
|
+
phoneNumber: this.state.patientPhone,
|
|
294
|
+
otpCode: this.state.otpCode,
|
|
295
|
+
});
|
|
254
296
|
await PatientService.verifyPhoneVerificationOtp({
|
|
255
297
|
countryCode: this.state.countryCode,
|
|
256
298
|
phoneNumber: this.state.patientPhone,
|
|
@@ -259,7 +301,10 @@ class AppointmentCalendarWidget {
|
|
|
259
301
|
this.setState({ otpVerified: true, error: null });
|
|
260
302
|
}
|
|
261
303
|
catch (e) {
|
|
262
|
-
|
|
304
|
+
console.error("OTP verification error:", e);
|
|
305
|
+
const msg = e?.response?.data?.message ||
|
|
306
|
+
e?.message ||
|
|
307
|
+
"Invalid OTP code. Please try again.";
|
|
263
308
|
this.setState({ error: msg });
|
|
264
309
|
this.options.onError?.(e);
|
|
265
310
|
}
|
|
@@ -420,6 +465,112 @@ class AppointmentCalendarWidget {
|
|
|
420
465
|
</div>
|
|
421
466
|
`;
|
|
422
467
|
this.attachEventListeners();
|
|
468
|
+
this.initializeCustomComponents();
|
|
469
|
+
}
|
|
470
|
+
initializeCustomComponents() {
|
|
471
|
+
if (this.state.step === 0) {
|
|
472
|
+
const addressContainer = this.container.querySelector("#medos-address-select-container");
|
|
473
|
+
if (addressContainer && this.state.addresses.length > 0) {
|
|
474
|
+
const addressOptions = this.state.addresses.map((a) => ({
|
|
475
|
+
value: a.id.toString(),
|
|
476
|
+
label: a.label || `Address ${a.id}`,
|
|
477
|
+
}));
|
|
478
|
+
this.addressSelect = new VanillaSelect(addressContainer, addressOptions, {
|
|
479
|
+
placeholder: "Select a location",
|
|
480
|
+
onValueChange: (value) => {
|
|
481
|
+
this.handleAddressChange(Number(value) || null);
|
|
482
|
+
},
|
|
483
|
+
});
|
|
484
|
+
if (this.state.selectedAddress) {
|
|
485
|
+
this.addressSelect.setValue(this.state.selectedAddress.toString());
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
const doctorContainer = this.container.querySelector("#medos-doctor-select-container");
|
|
489
|
+
if (doctorContainer && this.doctors.length > 0) {
|
|
490
|
+
const doctorOptions = this.doctors.map((d) => ({
|
|
491
|
+
value: d.id.toString(),
|
|
492
|
+
label: d.name + (d.specialty ? ` • ${d.specialty}` : ""),
|
|
493
|
+
}));
|
|
494
|
+
this.doctorSelect = new VanillaSelect(doctorContainer, doctorOptions, {
|
|
495
|
+
placeholder: "Select a doctor",
|
|
496
|
+
onValueChange: (value) => {
|
|
497
|
+
this.state.selectedDoctor = Number(value) || null;
|
|
498
|
+
const selectedDoc = this.doctors.find((d) => d.id === this.state.selectedDoctor);
|
|
499
|
+
if (selectedDoc && selectedDoc.consultationCharge) {
|
|
500
|
+
this.state.consultationCharge = selectedDoc.consultationCharge;
|
|
501
|
+
}
|
|
502
|
+
this.render();
|
|
503
|
+
},
|
|
504
|
+
});
|
|
505
|
+
if (this.state.selectedDoctor) {
|
|
506
|
+
this.doctorSelect.setValue(this.state.selectedDoctor.toString());
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
if (this.state.step === 1) {
|
|
511
|
+
const calendarContainer = this.container.querySelector("#medos-calendar-container");
|
|
512
|
+
if (calendarContainer) {
|
|
513
|
+
this.calendar = new VanillaCalendar(calendarContainer, {
|
|
514
|
+
selectedDate: this.state.selectedDate || undefined,
|
|
515
|
+
pastDisabled: true,
|
|
516
|
+
onSelect: (date) => {
|
|
517
|
+
this.state.selectedDate = date;
|
|
518
|
+
this.render();
|
|
519
|
+
},
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
if (this.state.step === 3) {
|
|
524
|
+
const countryCodeContainer = this.container.querySelector("#medos-country-code-container");
|
|
525
|
+
if (countryCodeContainer) {
|
|
526
|
+
const countryOptions = COUNTRY_CODES.map((c) => ({
|
|
527
|
+
value: c.code,
|
|
528
|
+
label: c.label,
|
|
529
|
+
}));
|
|
530
|
+
this.countryCodeSelect = new VanillaSelect(countryCodeContainer, countryOptions, {
|
|
531
|
+
placeholder: "Country",
|
|
532
|
+
onValueChange: (value) => {
|
|
533
|
+
this.state.countryCode = value;
|
|
534
|
+
const sendOtpBtn = this.container.querySelector("#medos-btn-send-otp");
|
|
535
|
+
if (sendOtpBtn) {
|
|
536
|
+
const canSendOtp = this.state.countryCode &&
|
|
537
|
+
this.state.patientPhone.length >= 10;
|
|
538
|
+
sendOtpBtn.disabled = !canSendOtp;
|
|
539
|
+
}
|
|
540
|
+
},
|
|
541
|
+
});
|
|
542
|
+
if (this.state.countryCode) {
|
|
543
|
+
this.countryCodeSelect.setValue(this.state.countryCode);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
if (this.state.step === 4) {
|
|
548
|
+
const genderContainer = this.container.querySelector("#medos-gender-container");
|
|
549
|
+
if (genderContainer) {
|
|
550
|
+
this.genderSelect = new VanillaSelect(genderContainer, GENDER_OPTIONS, {
|
|
551
|
+
placeholder: "Select gender",
|
|
552
|
+
onValueChange: (value) => {
|
|
553
|
+
this.state.patientGender = value;
|
|
554
|
+
this.updateSubmitButtonState();
|
|
555
|
+
},
|
|
556
|
+
});
|
|
557
|
+
if (this.state.patientGender) {
|
|
558
|
+
this.genderSelect.setValue(this.state.patientGender);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
const bloodGroupContainer = this.container.querySelector("#medos-blood-group-container");
|
|
562
|
+
if (bloodGroupContainer) {
|
|
563
|
+
this.bloodGroupSelect = new VanillaSelect(bloodGroupContainer, BLOOD_GROUP_OPTIONS, {
|
|
564
|
+
placeholder: "Select blood group (optional)",
|
|
565
|
+
onValueChange: (value) => {
|
|
566
|
+
this.state.bloodGroup = value;
|
|
567
|
+
},
|
|
568
|
+
});
|
|
569
|
+
if (this.state.bloodGroup) {
|
|
570
|
+
this.bloodGroupSelect.setValue(this.state.bloodGroup);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
423
574
|
}
|
|
424
575
|
renderStep() {
|
|
425
576
|
switch (this.state.step) {
|
|
@@ -442,72 +593,122 @@ class AppointmentCalendarWidget {
|
|
|
442
593
|
renderStep0() {
|
|
443
594
|
const canProceed = this.canProceedFromMergedStep();
|
|
444
595
|
return `
|
|
445
|
-
<div class="medos-
|
|
446
|
-
<div class="medos-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
<select class="medos-appointment-select" id="medos-address-select">
|
|
455
|
-
<option value="">-- choose address --</option>
|
|
456
|
-
${this.state.addresses
|
|
457
|
-
.map((a) => `<option value="${this.escapeHtml(a.id.toString())}" ${this.state.selectedAddress === a.id ? "selected" : ""}>${this.escapeHtml(a.label || "")}</option>`)
|
|
458
|
-
.join("")}
|
|
459
|
-
</select>
|
|
460
|
-
`}
|
|
596
|
+
<div class="medos-section-card">
|
|
597
|
+
<div class="medos-section-header">
|
|
598
|
+
${VanillaIcons.mapPin(14)}
|
|
599
|
+
<span class="medos-section-title">Location & Doctor</span>
|
|
600
|
+
</div>
|
|
601
|
+
<div class="medos-section-body">
|
|
602
|
+
<div class="medos-form-group">
|
|
603
|
+
<label class="medos-label">Preferred Location <span class="medos-required">*</span></label>
|
|
604
|
+
<div id="medos-address-select-container"></div>
|
|
461
605
|
</div>
|
|
462
|
-
<div>
|
|
463
|
-
<label class="medos-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
${this.doctors
|
|
474
|
-
.map((d) => `<option value="${this.escapeHtml(d.id.toString())}" ${this.state.selectedDoctor === d.id ? "selected" : ""}>${this.escapeHtml(d.name)}${d.specialty
|
|
475
|
-
? ` (${this.escapeHtml(d.specialty)})`
|
|
476
|
-
: ""}</option>`)
|
|
477
|
-
.join("")}
|
|
478
|
-
</select>
|
|
479
|
-
`}
|
|
606
|
+
<div class="medos-form-group">
|
|
607
|
+
<label class="medos-label">Preferred Doctor <span class="medos-required">*</span></label>
|
|
608
|
+
<div id="medos-doctor-select-container"></div>
|
|
609
|
+
</div>
|
|
610
|
+
<div class="medos-form-group">
|
|
611
|
+
<label class="medos-label">Chief Complaint <span class="medos-optional">(optional)</span></label>
|
|
612
|
+
<textarea
|
|
613
|
+
class="medos-textarea"
|
|
614
|
+
id="medos-chief-complaint"
|
|
615
|
+
placeholder="Enter Chief Complaint or Appointment Notes"
|
|
616
|
+
></textarea>
|
|
480
617
|
</div>
|
|
481
|
-
</div>
|
|
482
|
-
<div class="medos-appointment-actions">
|
|
483
|
-
<button class="medos-appointment-btn medos-appointment-btn-secondary" id="medos-btn-cancel">Cancel</button>
|
|
484
|
-
<button class="medos-appointment-btn medos-appointment-btn-primary" id="medos-btn-next" ${!canProceed ? "disabled" : ""} style="opacity: ${canProceed ? 1 : 0.6}">Next</button>
|
|
485
618
|
</div>
|
|
486
619
|
</div>
|
|
620
|
+
<div class="medos-actions">
|
|
621
|
+
<button class="medos-btn medos-btn-primary" id="medos-btn-next" ${!canProceed ? "disabled" : ""}>Next</button>
|
|
622
|
+
</div>
|
|
487
623
|
`;
|
|
488
624
|
}
|
|
489
625
|
renderStep1() {
|
|
490
626
|
const dateStr = formatDateToISO(this.state.selectedDate);
|
|
627
|
+
const selectedDoctor = this.doctors.find((d) => d.id === this.state.selectedDoctor);
|
|
628
|
+
const selectedDoctorData = this.doctors.find((d) => d.id === this.state.selectedDoctor);
|
|
629
|
+
const consultationCharge = selectedDoctorData?.consultationCharge ||
|
|
630
|
+
selectedDoctor?.consultationCharge ||
|
|
631
|
+
this.state.consultationCharge ||
|
|
632
|
+
"N/A";
|
|
491
633
|
return `
|
|
492
|
-
<div class="medos-
|
|
493
|
-
<
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
634
|
+
<div class="medos-section-card">
|
|
635
|
+
<div class="medos-section-header">
|
|
636
|
+
${VanillaIcons.consultationType(14)}
|
|
637
|
+
<span class="medos-section-title">Consultation Type</span>
|
|
638
|
+
</div>
|
|
639
|
+
<div class="medos-section-body">
|
|
640
|
+
<div class="medos-consultation-options">
|
|
641
|
+
<label class="medos-radio-option ${this.state.consultationMode === "OFFLINE" ? "selected" : ""}">
|
|
642
|
+
<input
|
|
643
|
+
type="radio"
|
|
644
|
+
name="consultationMode"
|
|
645
|
+
value="OFFLINE"
|
|
646
|
+
${this.state.consultationMode === "OFFLINE" ? "checked" : ""}
|
|
647
|
+
class="medos-radio-input"
|
|
648
|
+
/>
|
|
649
|
+
<span class="medos-radio-label">In-Person Visit</span>
|
|
650
|
+
</label>
|
|
651
|
+
<label class="medos-radio-option ${this.state.consultationMode === "ONLINE" ? "selected" : ""}">
|
|
652
|
+
<input
|
|
653
|
+
type="radio"
|
|
654
|
+
name="consultationMode"
|
|
655
|
+
value="ONLINE"
|
|
656
|
+
${this.state.consultationMode === "ONLINE" ? "checked" : ""}
|
|
657
|
+
class="medos-radio-input"
|
|
658
|
+
/>
|
|
659
|
+
<span class="medos-radio-label">Online Consultation</span>
|
|
660
|
+
</label>
|
|
661
|
+
</div>
|
|
662
|
+
<div class="medos-consultation-charge">
|
|
663
|
+
<span class="medos-charge-label">Consultation Charge:</span>
|
|
664
|
+
<span class="medos-charge-value">${consultationCharge !== "N/A"
|
|
665
|
+
? "₹" + consultationCharge
|
|
666
|
+
: consultationCharge}</span>
|
|
667
|
+
</div>
|
|
668
|
+
</div>
|
|
669
|
+
</div>
|
|
670
|
+
|
|
671
|
+
<div class="medos-section-card">
|
|
672
|
+
<div class="medos-section-header">
|
|
673
|
+
${VanillaIcons.dateTime(14)}
|
|
674
|
+
<span class="medos-section-title">Select Date</span>
|
|
498
675
|
</div>
|
|
676
|
+
<div class="medos-section-body">
|
|
677
|
+
<div id="medos-calendar-container"></div>
|
|
678
|
+
</div>
|
|
679
|
+
</div>
|
|
680
|
+
|
|
681
|
+
<div class="medos-actions">
|
|
682
|
+
<button class="medos-btn medos-btn-secondary" id="medos-btn-back">Back</button>
|
|
683
|
+
<button class="medos-btn medos-btn-primary" id="medos-btn-next" ${dateStr ? "" : "disabled"}>Next</button>
|
|
499
684
|
</div>
|
|
500
685
|
`;
|
|
501
686
|
}
|
|
502
687
|
renderStep2() {
|
|
688
|
+
const dateDisplay = this.state.selectedDate
|
|
689
|
+
? this.state.selectedDate.toLocaleDateString("en-US", {
|
|
690
|
+
weekday: "long",
|
|
691
|
+
year: "numeric",
|
|
692
|
+
month: "long",
|
|
693
|
+
day: "numeric",
|
|
694
|
+
})
|
|
695
|
+
: "";
|
|
503
696
|
return `
|
|
504
|
-
<div class="medos-
|
|
505
|
-
<
|
|
506
|
-
|
|
507
|
-
|
|
697
|
+
<div class="medos-section-card">
|
|
698
|
+
<div class="medos-section-header">
|
|
699
|
+
${VanillaIcons.clock(14)}
|
|
700
|
+
<span class="medos-section-title">Select Time Slot</span>
|
|
701
|
+
</div>
|
|
702
|
+
<div class="medos-section-body">
|
|
703
|
+
<div class="medos-selected-date-display">
|
|
704
|
+
${VanillaIcons.dateTime(16)}
|
|
705
|
+
<span>${dateDisplay}</span>
|
|
706
|
+
</div>
|
|
707
|
+
${this.state.slots.length === 0
|
|
708
|
+
? '<div class="medos-empty-slots">No slots available for selected date</div>'
|
|
508
709
|
: `
|
|
509
|
-
|
|
510
|
-
|
|
710
|
+
<div class="medos-slots-grid">
|
|
711
|
+
${this.state.slots
|
|
511
712
|
.map((s) => {
|
|
512
713
|
const start = new Date(s.start).toLocaleTimeString([], {
|
|
513
714
|
hour: "2-digit",
|
|
@@ -520,19 +721,28 @@ class AppointmentCalendarWidget {
|
|
|
520
721
|
const selected = this.state.selectedSlot?.start === s.start &&
|
|
521
722
|
this.state.selectedSlot?.end === s.end;
|
|
522
723
|
return `
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
724
|
+
<div class="medos-slot-card ${selected ? "selected" : ""}"
|
|
725
|
+
data-slot-id="${this.escapeHtml(s.id || `${s.start}-${s.end}`)}"
|
|
726
|
+
data-slot-start="${this.escapeHtml(s.start)}"
|
|
727
|
+
data-slot-end="${this.escapeHtml(s.end)}">
|
|
728
|
+
<span class="medos-slot-time">${start}</span>
|
|
729
|
+
<span class="medos-slot-separator">-</span>
|
|
730
|
+
<span class="medos-slot-time">${end}</span>
|
|
731
|
+
${selected
|
|
732
|
+
? `<span class="medos-slot-check">${VanillaIcons.check(14)}</span>`
|
|
733
|
+
: ""}
|
|
734
|
+
</div>
|
|
735
|
+
`;
|
|
527
736
|
})
|
|
528
737
|
.join("")}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
<div class="medos-appointment-actions">
|
|
532
|
-
<button class="medos-appointment-btn medos-appointment-btn-secondary" id="medos-btn-back">Back</button>
|
|
533
|
-
<button class="medos-appointment-btn medos-appointment-btn-primary" id="medos-btn-next" ${!this.state.selectedSlot ? "disabled" : ""} style="opacity: ${this.state.selectedSlot ? 1 : 0.6}">Next</button>
|
|
738
|
+
</div>
|
|
739
|
+
`}
|
|
534
740
|
</div>
|
|
535
741
|
</div>
|
|
742
|
+
<div class="medos-actions">
|
|
743
|
+
<button class="medos-btn medos-btn-secondary" id="medos-btn-back">Back</button>
|
|
744
|
+
<button class="medos-btn medos-btn-primary" id="medos-btn-next" ${this.state.selectedSlot ? "" : "disabled"} style="opacity: ${this.state.selectedSlot ? 1 : 0.6}">Next</button>
|
|
745
|
+
</div>
|
|
536
746
|
`;
|
|
537
747
|
}
|
|
538
748
|
renderStep3() {
|
|
@@ -541,46 +751,86 @@ class AppointmentCalendarWidget {
|
|
|
541
751
|
const canSendOtp = countryCodeValid && phoneValid && !this.state.otpSending;
|
|
542
752
|
if (!this.state.otpSent) {
|
|
543
753
|
return `
|
|
544
|
-
<div class="medos-
|
|
545
|
-
<
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
754
|
+
<div class="medos-section-card">
|
|
755
|
+
<div class="medos-section-header">
|
|
756
|
+
${VanillaIcons.phone(14)}
|
|
757
|
+
<span class="medos-section-title">Phone Verification</span>
|
|
758
|
+
</div>
|
|
759
|
+
<div class="medos-section-body">
|
|
760
|
+
<p class="medos-section-description">Please enter your phone number for verification</p>
|
|
761
|
+
<div class="medos-phone-input-row">
|
|
762
|
+
<div class="medos-country-code-wrapper">
|
|
763
|
+
<div id="medos-country-code-container"></div>
|
|
764
|
+
</div>
|
|
765
|
+
<div class="medos-phone-wrapper">
|
|
766
|
+
<input
|
|
767
|
+
type="tel"
|
|
768
|
+
class="medos-input"
|
|
769
|
+
id="medos-phone"
|
|
770
|
+
placeholder="Enter phone number"
|
|
771
|
+
value="${this.escapeHtml(this.state.patientPhone)}"
|
|
772
|
+
maxlength="15"
|
|
773
|
+
/>
|
|
774
|
+
</div>
|
|
775
|
+
</div>
|
|
776
|
+
${this.state.patientPhone && !phoneValid
|
|
777
|
+
? '<div class="medos-validation-error">Phone number should be 7-15 digits</div>'
|
|
554
778
|
: ""}
|
|
555
|
-
<div class="medos-appointment-actions">
|
|
556
|
-
<button class="medos-appointment-btn medos-appointment-btn-secondary" id="medos-btn-back">Back</button>
|
|
557
|
-
<button class="medos-appointment-btn medos-appointment-btn-primary" id="medos-btn-send-otp" ${!canSendOtp ? "disabled" : ""} style="opacity: ${canSendOtp ? 1 : 0.6}">${this.state.otpSending ? "Sending..." : "Send OTP"}</button>
|
|
558
779
|
</div>
|
|
559
780
|
</div>
|
|
781
|
+
<div class="medos-actions">
|
|
782
|
+
<button class="medos-btn medos-btn-secondary" id="medos-btn-back">Back</button>
|
|
783
|
+
<button class="medos-btn medos-btn-primary" id="medos-btn-send-otp" ${canSendOtp ? "" : "disabled"}>${this.state.otpSending ? "Sending..." : "Send OTP"}</button>
|
|
784
|
+
</div>
|
|
560
785
|
`;
|
|
561
786
|
}
|
|
562
787
|
if (this.state.otpVerified) {
|
|
563
788
|
return `
|
|
564
|
-
<div class="medos-
|
|
565
|
-
<div class="medos-
|
|
566
|
-
|
|
567
|
-
<
|
|
568
|
-
|
|
789
|
+
<div class="medos-section-card">
|
|
790
|
+
<div class="medos-section-header">
|
|
791
|
+
${VanillaIcons.phone(14)}
|
|
792
|
+
<span class="medos-section-title">Phone Verification</span>
|
|
793
|
+
</div>
|
|
794
|
+
<div class="medos-section-body">
|
|
795
|
+
<div class="medos-verified-badge">
|
|
796
|
+
${VanillaIcons.successBadge(20)}
|
|
797
|
+
<span>Phone verified successfully</span>
|
|
798
|
+
</div>
|
|
799
|
+
<div class="medos-verified-number">${this.escapeHtml(this.state.countryCode)} ${this.escapeHtml(this.state.patientPhone)}</div>
|
|
569
800
|
</div>
|
|
570
801
|
</div>
|
|
802
|
+
<div class="medos-actions">
|
|
803
|
+
<button class="medos-btn medos-btn-secondary" id="medos-btn-back">Back</button>
|
|
804
|
+
<button class="medos-btn medos-btn-primary" id="medos-btn-next">Continue</button>
|
|
805
|
+
</div>
|
|
571
806
|
`;
|
|
572
807
|
}
|
|
573
808
|
return `
|
|
574
|
-
<div class="medos-
|
|
575
|
-
<
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
<div class="medos-appointment-actions">
|
|
579
|
-
<button class="medos-appointment-btn medos-appointment-btn-secondary" id="medos-btn-change-number">Change Number</button>
|
|
580
|
-
<button class="medos-appointment-btn medos-appointment-btn-primary" id="medos-btn-verify-otp" ${this.state.otpCode.length !== 6 || this.state.otpVerifying
|
|
581
|
-
? "disabled"
|
|
582
|
-
: ""} style="opacity: ${this.state.otpCode.length === 6 && !this.state.otpVerifying ? 1 : 0.6}">${this.state.otpVerifying ? "Verifying..." : "Verify OTP"}</button>
|
|
809
|
+
<div class="medos-section-card">
|
|
810
|
+
<div class="medos-section-header">
|
|
811
|
+
${VanillaIcons.phone(14)}
|
|
812
|
+
<span class="medos-section-title">Enter OTP</span>
|
|
583
813
|
</div>
|
|
814
|
+
<div class="medos-section-body">
|
|
815
|
+
<p class="medos-section-description">Enter the 6-digit code sent to ${this.escapeHtml(this.state.countryCode)} ${this.escapeHtml(this.state.patientPhone)}</p>
|
|
816
|
+
<div class="medos-otp-input-wrapper">
|
|
817
|
+
<input
|
|
818
|
+
type="text"
|
|
819
|
+
class="medos-input medos-otp-input"
|
|
820
|
+
id="medos-otp"
|
|
821
|
+
placeholder="Enter 6-digit OTP"
|
|
822
|
+
value="${this.escapeHtml(this.state.otpCode)}"
|
|
823
|
+
maxlength="6"
|
|
824
|
+
/>
|
|
825
|
+
</div>
|
|
826
|
+
<button class="medos-link-btn" id="medos-btn-change-number">Change phone number</button>
|
|
827
|
+
</div>
|
|
828
|
+
</div>
|
|
829
|
+
<div class="medos-actions">
|
|
830
|
+
<button class="medos-btn medos-btn-secondary" id="medos-btn-resend-otp">Resend OTP</button>
|
|
831
|
+
<button class="medos-btn medos-btn-primary" id="medos-btn-verify-otp" ${this.state.otpCode.length === 6 && !this.state.otpVerifying
|
|
832
|
+
? ""
|
|
833
|
+
: "disabled"}>${this.state.otpVerifying ? "Verifying..." : "Verify OTP"}</button>
|
|
584
834
|
</div>
|
|
585
835
|
`;
|
|
586
836
|
}
|
|
@@ -593,50 +843,79 @@ class AppointmentCalendarWidget {
|
|
|
593
843
|
this.state.patientZipcode &&
|
|
594
844
|
this.state.otpVerified;
|
|
595
845
|
return `
|
|
596
|
-
<div class="medos-
|
|
597
|
-
<
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
<
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
<input type="text" class="medos-appointment-input" id="medos-patient-address" placeholder="Street address, building name, etc." value="${this.escapeHtml(this.state.patientAddress)}" />
|
|
612
|
-
<div class="medos-appointment-form-grid">
|
|
613
|
-
<div>
|
|
614
|
-
<label class="medos-appointment-label">City *</label>
|
|
615
|
-
<input type="text" class="medos-appointment-input" id="medos-patient-city" placeholder="City" value="${this.escapeHtml(this.state.patientCity)}" />
|
|
846
|
+
<div class="medos-section-card">
|
|
847
|
+
<div class="medos-section-header">
|
|
848
|
+
${VanillaIcons.user(14)}
|
|
849
|
+
<span class="medos-section-title">Patient Information</span>
|
|
850
|
+
</div>
|
|
851
|
+
<div class="medos-section-body">
|
|
852
|
+
<div class="medos-form-row">
|
|
853
|
+
<div class="medos-form-group medos-form-group-flex">
|
|
854
|
+
<label class="medos-label">Full Name <span class="medos-required">*</span></label>
|
|
855
|
+
<input type="text" class="medos-input" id="medos-patient-name" placeholder="Enter full name" value="${this.escapeHtml(this.state.patientName)}" />
|
|
856
|
+
</div>
|
|
857
|
+
<div class="medos-form-group medos-form-group-small">
|
|
858
|
+
<label class="medos-label">Age</label>
|
|
859
|
+
<input type="number" class="medos-input" id="medos-patient-age" placeholder="Age" value="${this.escapeHtml(this.state.patientAge)}" />
|
|
860
|
+
</div>
|
|
616
861
|
</div>
|
|
617
|
-
<div>
|
|
618
|
-
<
|
|
619
|
-
|
|
862
|
+
<div class="medos-form-row">
|
|
863
|
+
<div class="medos-form-group medos-form-group-flex">
|
|
864
|
+
<label class="medos-label">Email</label>
|
|
865
|
+
<input type="email" class="medos-input" id="medos-patient-email" placeholder="patient@example.com" value="${this.escapeHtml(this.state.patientEmail)}" />
|
|
866
|
+
</div>
|
|
867
|
+
<div class="medos-form-group medos-form-group-small">
|
|
868
|
+
<label class="medos-label">Gender</label>
|
|
869
|
+
<div id="medos-gender-container"></div>
|
|
870
|
+
</div>
|
|
620
871
|
</div>
|
|
872
|
+
<div class="medos-form-group">
|
|
873
|
+
<label class="medos-label">Blood Group <span class="medos-optional">(optional)</span></label>
|
|
874
|
+
<div id="medos-blood-group-container"></div>
|
|
875
|
+
</div>
|
|
876
|
+
</div>
|
|
877
|
+
</div>
|
|
878
|
+
|
|
879
|
+
<div class="medos-section-card">
|
|
880
|
+
<div class="medos-section-header">
|
|
881
|
+
${VanillaIcons.mapPin(14)}
|
|
882
|
+
<span class="medos-section-title">Address Details</span>
|
|
621
883
|
</div>
|
|
622
|
-
<div class="medos-
|
|
623
|
-
<div>
|
|
624
|
-
<label class="medos-
|
|
625
|
-
<input type="text" class="medos-
|
|
884
|
+
<div class="medos-section-body">
|
|
885
|
+
<div class="medos-form-group">
|
|
886
|
+
<label class="medos-label">Address Line 1 <span class="medos-required">*</span></label>
|
|
887
|
+
<input type="text" class="medos-input" id="medos-patient-address" placeholder="Street address, building name, etc." value="${this.escapeHtml(this.state.patientAddress)}" />
|
|
626
888
|
</div>
|
|
627
|
-
<div>
|
|
628
|
-
<
|
|
629
|
-
|
|
889
|
+
<div class="medos-form-row">
|
|
890
|
+
<div class="medos-form-group">
|
|
891
|
+
<label class="medos-label">City <span class="medos-required">*</span></label>
|
|
892
|
+
<input type="text" class="medos-input" id="medos-patient-city" placeholder="City" value="${this.escapeHtml(this.state.patientCity)}" />
|
|
893
|
+
</div>
|
|
894
|
+
<div class="medos-form-group">
|
|
895
|
+
<label class="medos-label">State <span class="medos-required">*</span></label>
|
|
896
|
+
<input type="text" class="medos-input" id="medos-patient-state" placeholder="State" value="${this.escapeHtml(this.state.patientState)}" />
|
|
897
|
+
</div>
|
|
898
|
+
</div>
|
|
899
|
+
<div class="medos-form-row">
|
|
900
|
+
<div class="medos-form-group">
|
|
901
|
+
<label class="medos-label">Country <span class="medos-required">*</span></label>
|
|
902
|
+
<input type="text" class="medos-input" id="medos-patient-country" placeholder="Country" value="${this.escapeHtml(this.state.patientCountry)}" />
|
|
903
|
+
</div>
|
|
904
|
+
<div class="medos-form-group">
|
|
905
|
+
<label class="medos-label">Zipcode <span class="medos-required">*</span></label>
|
|
906
|
+
<input type="text" class="medos-input" id="medos-patient-zipcode" placeholder="Zipcode" value="${this.escapeHtml(this.state.patientZipcode)}" />
|
|
907
|
+
</div>
|
|
908
|
+
</div>
|
|
909
|
+
<div class="medos-form-group">
|
|
910
|
+
<label class="medos-label">Landmark <span class="medos-optional">(optional)</span></label>
|
|
911
|
+
<input type="text" class="medos-input" id="medos-patient-landmark" placeholder="Nearby landmark" value="${this.escapeHtml(this.state.patientLandmark)}" />
|
|
630
912
|
</div>
|
|
631
913
|
</div>
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
<
|
|
636
|
-
<
|
|
637
|
-
<button class="medos-appointment-btn medos-appointment-btn-secondary" id="medos-btn-back">Back</button>
|
|
638
|
-
<button class="medos-appointment-btn medos-appointment-btn-primary" id="medos-btn-submit" ${!canSubmit || this.state.loading ? "disabled" : ""} style="opacity: ${canSubmit && !this.state.loading ? 1 : 0.6}">${this.state.loading ? "Booking..." : "Book Appointment"}</button>
|
|
639
|
-
</div>
|
|
914
|
+
</div>
|
|
915
|
+
|
|
916
|
+
<div class="medos-actions">
|
|
917
|
+
<button class="medos-btn medos-btn-secondary" id="medos-btn-back">Back</button>
|
|
918
|
+
<button class="medos-btn medos-btn-primary" id="medos-btn-submit" ${canSubmit && !this.state.loading ? "" : "disabled"}>${this.state.loading ? "Booking..." : "Book Appointment"}</button>
|
|
640
919
|
</div>
|
|
641
920
|
`;
|
|
642
921
|
}
|
|
@@ -755,35 +1034,20 @@ class AppointmentCalendarWidget {
|
|
|
755
1034
|
`;
|
|
756
1035
|
}
|
|
757
1036
|
attachEventListeners() {
|
|
758
|
-
const
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
const target = e.target;
|
|
762
|
-
this.handleAddressChange(Number(target.value) || null);
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
|
-
const doctorSelect = this.container.querySelector("#medos-doctor-select");
|
|
766
|
-
if (doctorSelect) {
|
|
767
|
-
doctorSelect.addEventListener("change", (e) => {
|
|
768
|
-
const target = e.target;
|
|
769
|
-
this.state.selectedDoctor = Number(target.value) || null;
|
|
770
|
-
this.render();
|
|
771
|
-
});
|
|
772
|
-
}
|
|
773
|
-
const dateInput = this.container.querySelector("#medos-date-input");
|
|
774
|
-
if (dateInput) {
|
|
775
|
-
dateInput.addEventListener("change", (e) => {
|
|
1037
|
+
const consultationRadios = this.container.querySelectorAll('input[name="consultationMode"]');
|
|
1038
|
+
consultationRadios.forEach((radio) => {
|
|
1039
|
+
radio.addEventListener("change", (e) => {
|
|
776
1040
|
const target = e.target;
|
|
777
|
-
this.state.
|
|
1041
|
+
this.state.consultationMode = target.value;
|
|
778
1042
|
this.render();
|
|
779
1043
|
});
|
|
780
|
-
}
|
|
781
|
-
const slotCards = this.container.querySelectorAll(".medos-
|
|
1044
|
+
});
|
|
1045
|
+
const slotCards = this.container.querySelectorAll(".medos-slot-card");
|
|
782
1046
|
slotCards.forEach((card) => {
|
|
783
1047
|
card.addEventListener("click", () => {
|
|
784
|
-
const slotId = card.
|
|
785
|
-
const slotStart = card.
|
|
786
|
-
const slotEnd = card.
|
|
1048
|
+
const slotId = card.dataset.slotId;
|
|
1049
|
+
const slotStart = card.dataset.slotStart;
|
|
1050
|
+
const slotEnd = card.dataset.slotEnd;
|
|
787
1051
|
if (slotStart && slotEnd) {
|
|
788
1052
|
this.state.selectedSlot = {
|
|
789
1053
|
start: slotStart,
|
|
@@ -805,7 +1069,11 @@ class AppointmentCalendarWidget {
|
|
|
805
1069
|
value = value.replace(/[^\d+]/g, "");
|
|
806
1070
|
this.state.countryCode = value;
|
|
807
1071
|
target.value = value;
|
|
808
|
-
this.
|
|
1072
|
+
const sendOtpBtn = this.container.querySelector("#medos-btn-send-otp");
|
|
1073
|
+
if (sendOtpBtn) {
|
|
1074
|
+
const canSendOtp = this.state.countryCode && this.state.patientPhone.length >= 10;
|
|
1075
|
+
sendOtpBtn.disabled = !canSendOtp;
|
|
1076
|
+
}
|
|
809
1077
|
});
|
|
810
1078
|
}
|
|
811
1079
|
const phoneInput = this.container.querySelector("#medos-phone");
|
|
@@ -814,7 +1082,11 @@ class AppointmentCalendarWidget {
|
|
|
814
1082
|
const target = e.target;
|
|
815
1083
|
this.state.patientPhone = target.value.replace(/\D/g, "");
|
|
816
1084
|
target.value = this.state.patientPhone;
|
|
817
|
-
this.
|
|
1085
|
+
const sendOtpBtn = this.container.querySelector("#medos-btn-send-otp");
|
|
1086
|
+
if (sendOtpBtn) {
|
|
1087
|
+
const canSendOtp = this.state.countryCode && this.state.patientPhone.length >= 10;
|
|
1088
|
+
sendOtpBtn.disabled = !canSendOtp;
|
|
1089
|
+
}
|
|
818
1090
|
});
|
|
819
1091
|
}
|
|
820
1092
|
const otpInput = this.container.querySelector("#medos-otp");
|
|
@@ -822,7 +1094,10 @@ class AppointmentCalendarWidget {
|
|
|
822
1094
|
otpInput.addEventListener("input", (e) => {
|
|
823
1095
|
const target = e.target;
|
|
824
1096
|
this.state.otpCode = target.value;
|
|
825
|
-
this.
|
|
1097
|
+
const verifyBtn = this.container.querySelector("#medos-btn-verify-otp");
|
|
1098
|
+
if (verifyBtn) {
|
|
1099
|
+
verifyBtn.disabled = !(this.state.otpCode.length === 6 && !this.state.otpVerifying);
|
|
1100
|
+
}
|
|
826
1101
|
});
|
|
827
1102
|
}
|
|
828
1103
|
const patientNameInput = this.container.querySelector("#medos-patient-name");
|
|
@@ -830,6 +1105,7 @@ class AppointmentCalendarWidget {
|
|
|
830
1105
|
patientNameInput.addEventListener("input", (e) => {
|
|
831
1106
|
const target = e.target;
|
|
832
1107
|
this.state.patientName = target.value;
|
|
1108
|
+
this.updateSubmitButtonState();
|
|
833
1109
|
});
|
|
834
1110
|
}
|
|
835
1111
|
const patientAgeInput = this.container.querySelector("#medos-patient-age");
|
|
@@ -837,6 +1113,7 @@ class AppointmentCalendarWidget {
|
|
|
837
1113
|
patientAgeInput.addEventListener("input", (e) => {
|
|
838
1114
|
const target = e.target;
|
|
839
1115
|
this.state.patientAge = target.value;
|
|
1116
|
+
this.updateSubmitButtonState();
|
|
840
1117
|
});
|
|
841
1118
|
}
|
|
842
1119
|
const patientEmailInput = this.container.querySelector("#medos-patient-email");
|
|
@@ -844,6 +1121,7 @@ class AppointmentCalendarWidget {
|
|
|
844
1121
|
patientEmailInput.addEventListener("input", (e) => {
|
|
845
1122
|
const target = e.target;
|
|
846
1123
|
this.state.patientEmail = target.value;
|
|
1124
|
+
this.updateSubmitButtonState();
|
|
847
1125
|
});
|
|
848
1126
|
}
|
|
849
1127
|
const patientGenderSelect = this.container.querySelector("#medos-patient-gender");
|
|
@@ -858,6 +1136,7 @@ class AppointmentCalendarWidget {
|
|
|
858
1136
|
patientAddressInput.addEventListener("input", (e) => {
|
|
859
1137
|
const target = e.target;
|
|
860
1138
|
this.state.patientAddress = target.value;
|
|
1139
|
+
this.updateSubmitButtonState();
|
|
861
1140
|
});
|
|
862
1141
|
}
|
|
863
1142
|
const patientCityInput = this.container.querySelector("#medos-patient-city");
|
|
@@ -865,6 +1144,7 @@ class AppointmentCalendarWidget {
|
|
|
865
1144
|
patientCityInput.addEventListener("input", (e) => {
|
|
866
1145
|
const target = e.target;
|
|
867
1146
|
this.state.patientCity = target.value;
|
|
1147
|
+
this.updateSubmitButtonState();
|
|
868
1148
|
});
|
|
869
1149
|
}
|
|
870
1150
|
const patientStateInput = this.container.querySelector("#medos-patient-state");
|
|
@@ -872,6 +1152,7 @@ class AppointmentCalendarWidget {
|
|
|
872
1152
|
patientStateInput.addEventListener("input", (e) => {
|
|
873
1153
|
const target = e.target;
|
|
874
1154
|
this.state.patientState = target.value;
|
|
1155
|
+
this.updateSubmitButtonState();
|
|
875
1156
|
});
|
|
876
1157
|
}
|
|
877
1158
|
const patientCountryInput = this.container.querySelector("#medos-patient-country");
|
|
@@ -879,6 +1160,7 @@ class AppointmentCalendarWidget {
|
|
|
879
1160
|
patientCountryInput.addEventListener("input", (e) => {
|
|
880
1161
|
const target = e.target;
|
|
881
1162
|
this.state.patientCountry = target.value;
|
|
1163
|
+
this.updateSubmitButtonState();
|
|
882
1164
|
});
|
|
883
1165
|
}
|
|
884
1166
|
const patientZipcodeInput = this.container.querySelector("#medos-patient-zipcode");
|
|
@@ -886,6 +1168,7 @@ class AppointmentCalendarWidget {
|
|
|
886
1168
|
patientZipcodeInput.addEventListener("input", (e) => {
|
|
887
1169
|
const target = e.target;
|
|
888
1170
|
this.state.patientZipcode = target.value;
|
|
1171
|
+
this.updateSubmitButtonState();
|
|
889
1172
|
});
|
|
890
1173
|
}
|
|
891
1174
|
const patientLandmarkInput = this.container.querySelector("#medos-patient-landmark");
|
|
@@ -897,7 +1180,11 @@ class AppointmentCalendarWidget {
|
|
|
897
1180
|
}
|
|
898
1181
|
const nextBtn = this.container.querySelector("#medos-btn-next");
|
|
899
1182
|
if (nextBtn) {
|
|
900
|
-
nextBtn.addEventListener("click", () =>
|
|
1183
|
+
nextBtn.addEventListener("click", () => {
|
|
1184
|
+
if (!nextBtn.disabled) {
|
|
1185
|
+
this.goToNext();
|
|
1186
|
+
}
|
|
1187
|
+
});
|
|
901
1188
|
}
|
|
902
1189
|
const backBtn = this.container.querySelector("#medos-btn-back");
|
|
903
1190
|
if (backBtn) {
|
|
@@ -905,11 +1192,19 @@ class AppointmentCalendarWidget {
|
|
|
905
1192
|
}
|
|
906
1193
|
const sendOtpBtn = this.container.querySelector("#medos-btn-send-otp");
|
|
907
1194
|
if (sendOtpBtn) {
|
|
908
|
-
sendOtpBtn.addEventListener("click", () =>
|
|
1195
|
+
sendOtpBtn.addEventListener("click", () => {
|
|
1196
|
+
if (!sendOtpBtn.disabled) {
|
|
1197
|
+
this.sendOtp();
|
|
1198
|
+
}
|
|
1199
|
+
});
|
|
909
1200
|
}
|
|
910
1201
|
const verifyOtpBtn = this.container.querySelector("#medos-btn-verify-otp");
|
|
911
1202
|
if (verifyOtpBtn) {
|
|
912
|
-
verifyOtpBtn.addEventListener("click", () =>
|
|
1203
|
+
verifyOtpBtn.addEventListener("click", () => {
|
|
1204
|
+
if (!verifyOtpBtn.disabled) {
|
|
1205
|
+
this.verifyOtp();
|
|
1206
|
+
}
|
|
1207
|
+
});
|
|
913
1208
|
}
|
|
914
1209
|
const changeNumberBtn = this.container.querySelector("#medos-btn-change-number");
|
|
915
1210
|
if (changeNumberBtn) {
|
|
@@ -918,9 +1213,19 @@ class AppointmentCalendarWidget {
|
|
|
918
1213
|
this.render();
|
|
919
1214
|
});
|
|
920
1215
|
}
|
|
1216
|
+
const resendOtpBtn = this.container.querySelector("#medos-btn-resend-otp");
|
|
1217
|
+
if (resendOtpBtn) {
|
|
1218
|
+
resendOtpBtn.addEventListener("click", () => {
|
|
1219
|
+
this.sendOtp();
|
|
1220
|
+
});
|
|
1221
|
+
}
|
|
921
1222
|
const submitBtn = this.container.querySelector("#medos-btn-submit");
|
|
922
1223
|
if (submitBtn) {
|
|
923
|
-
submitBtn.addEventListener("click", () =>
|
|
1224
|
+
submitBtn.addEventListener("click", () => {
|
|
1225
|
+
if (!submitBtn.disabled) {
|
|
1226
|
+
this.submitAppointment();
|
|
1227
|
+
}
|
|
1228
|
+
});
|
|
924
1229
|
}
|
|
925
1230
|
const bookAnotherBtn = this.container.querySelector("#medos-btn-book-another");
|
|
926
1231
|
if (bookAnotherBtn) {
|