fix reset password
This commit is contained in:
@@ -230,7 +230,7 @@ $routes->get('admin/api/v1/admin/auth/me', 'AuthController::adminAuthMe');
|
|||||||
$routes->get('/welcome_back', 'View\UserController::welcomeBack');
|
$routes->get('/welcome_back', 'View\UserController::welcomeBack');
|
||||||
|
|
||||||
$routes->get('user/forgot_password', 'View\UserController::forgotPassword'); //display forgot password form
|
$routes->get('user/forgot_password', 'View\UserController::forgotPassword'); //display forgot password form
|
||||||
//$routes->post('user/forgot_password', 'View\UserController::processForgotPassword'); //process the password forgot request
|
$routes->post('user/forgot_password', 'View\UserController::processForgotPassword'); //process the password forgot request
|
||||||
|
|
||||||
$routes->get('login', 'AuthController::loginMask');
|
$routes->get('login', 'AuthController::loginMask');
|
||||||
$routes->get(
|
$routes->get(
|
||||||
|
|||||||
@@ -933,8 +933,8 @@ class ParentController extends BaseController
|
|||||||
$errors[] = 'A valid 10-digit home/cell phone number is required.';
|
$errors[] = 'A valid 10-digit home/cell phone number is required.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($street === '' || strlen($street) < 2 || strlen($street) > 50 || ! preg_match('/^[A-Za-z0-9.\s\-]+$/', $street)) {
|
if ($street === '' || strlen($street) < 3 || strlen($street) > 50 || ! preg_match('/^[A-Za-z0-9.\s\-]+$/', $street)) {
|
||||||
$errors[] = 'Home street address must be 2–50 characters and may contain only letters, numbers, spaces, periods, and hyphens.';
|
$errors[] = 'Home street address must be 3–50 characters and may contain only letters, numbers, spaces, periods, and hyphens.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($apt !== '' && (strlen($apt) > 15 || ! preg_match('/^[A-Za-z0-9.\s\-]+$/', $apt))) {
|
if ($apt !== '' && (strlen($apt) > 15 || ! preg_match('/^[A-Za-z0-9.\s\-]+$/', $apt))) {
|
||||||
@@ -2884,7 +2884,6 @@ class ParentController extends BaseController
|
|||||||
'parent_id' => (int) $parentId,
|
'parent_id' => (int) $parentId,
|
||||||
'year_of_registration' => date('Y'),
|
'year_of_registration' => date('Y'),
|
||||||
'school_year' => $schoolYear,
|
'school_year' => $schoolYear,
|
||||||
'semester' => $semester,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if (!is_null($isNew)) {
|
if (!is_null($isNew)) {
|
||||||
|
|||||||
@@ -459,6 +459,8 @@ class UserController extends BaseController
|
|||||||
// --- Handle unknown or unverified email ---
|
// --- Handle unknown or unverified email ---
|
||||||
if (!$user || (int) $user['is_verified'] === 0) {
|
if (!$user || (int) $user['is_verified'] === 0) {
|
||||||
session()->setFlashdata('success', 'If this email is registered, you will receive a reset link.');
|
session()->setFlashdata('success', 'If this email is registered, you will receive a reset link.');
|
||||||
|
session()->setFlashdata('show_modal', true);
|
||||||
|
session()->setFlashdata('email', $email);
|
||||||
log_message('info', "Password reset requested for {$email} (user missing or unverified).");
|
log_message('info', "Password reset requested for {$email} (user missing or unverified).");
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
@@ -478,6 +480,8 @@ class UserController extends BaseController
|
|||||||
$this->sendResetEmail($email, $token);
|
$this->sendResetEmail($email, $token);
|
||||||
|
|
||||||
session()->setFlashdata('success', 'A password reset link has been sent to your email.');
|
session()->setFlashdata('success', 'A password reset link has been sent to your email.');
|
||||||
|
session()->setFlashdata('show_modal', true);
|
||||||
|
session()->setFlashdata('email', $email);
|
||||||
log_message('info', "Password reset email sent to {$email}");
|
log_message('info', "Password reset email sent to {$email}");
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
@@ -633,14 +637,18 @@ class UserController extends BaseController
|
|||||||
$ipAttemptModel->where('ip_address', $ipAddress)->delete();
|
$ipAttemptModel->where('ip_address', $ipAddress)->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->resetRequestModel->where('ip_address', $ipAddress)->delete();
|
||||||
|
|
||||||
// Redirect to a success page with a success message
|
// Redirect to a success page with a success message
|
||||||
return view('user/password_set_success');
|
return redirect()->to('/user/password_set_success');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function passwordSetSuccess()
|
public function passwordSetSuccess()
|
||||||
{
|
{
|
||||||
|
$this->resetRequestModel->where('ip_address', $this->request->getIPAddress())->delete();
|
||||||
|
|
||||||
return view('user/password_set_success');
|
return view('user/password_set_success');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ final class SchoolYearWritableFilter implements FilterInterface
|
|||||||
'user/select_role',
|
'user/select_role',
|
||||||
'set-role',
|
'set-role',
|
||||||
'processForgotPassword',
|
'processForgotPassword',
|
||||||
|
'user/forgot_password',
|
||||||
'user/processResetPassword',
|
'user/processResetPassword',
|
||||||
'user/save_password',
|
'user/save_password',
|
||||||
'set_authorized_user_password',
|
'set_authorized_user_password',
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ class StudentModel extends Model
|
|||||||
'tuition_paid',
|
'tuition_paid',
|
||||||
'year_of_registration',
|
'year_of_registration',
|
||||||
'rfid_tag',
|
'rfid_tag',
|
||||||
'semester',
|
|
||||||
'school_year',
|
'school_year',
|
||||||
'is_active'
|
'is_active'
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ final class EnrollmentRegistrationEmailService
|
|||||||
);
|
);
|
||||||
$studentRows[] = $this->studentRow($student, $evaluation, $opens, $deadline, $schoolYear);
|
$studentRows[] = $this->studentRow($student, $evaluation, $opens, $deadline, $schoolYear);
|
||||||
$studentIds[] = $studentId;
|
$studentIds[] = $studentId;
|
||||||
$hasReEnrollmentEligibleStudent = $hasReEnrollmentEligibleStudent || (bool) ($evaluation['can_enroll'] ?? false);
|
$hasReEnrollmentEligibleStudent = $hasReEnrollmentEligibleStudent || $this->canCompleteParentReEnrollment($evaluation);
|
||||||
}
|
}
|
||||||
|
|
||||||
$financial = $this->financialSection((int) $family['parent_user_id'], $schoolYear, $previousYear);
|
$financial = $this->financialSection((int) $family['parent_user_id'], $schoolYear, $previousYear);
|
||||||
@@ -215,7 +215,7 @@ final class EnrollmentRegistrationEmailService
|
|||||||
|
|
||||||
private function canCompleteParentReEnrollment(array $evaluation): bool
|
private function canCompleteParentReEnrollment(array $evaluation): bool
|
||||||
{
|
{
|
||||||
return (bool) ($evaluation['can_enroll'] ?? false);
|
return (bool) ($evaluation['parent_enrollment_allowed'] ?? $evaluation['can_enroll'] ?? false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function registrationStepsSection(string $opens, string $deadline, bool $include): string
|
private function registrationStepsSection(string $opens, string $deadline, bool $include): string
|
||||||
@@ -306,7 +306,7 @@ final class EnrollmentRegistrationEmailService
|
|||||||
return (string) $evaluation['primary_parent_message'];
|
return (string) $evaluation['primary_parent_message'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($evaluation['blockers'] ?? []) !== []) {
|
if (($evaluation['blockers'] ?? []) !== [] && ! $this->hasOnlyNonBlockingEmailBlockers($evaluation)) {
|
||||||
return implode(' ', array_values(array_unique(array_filter(array_map(
|
return implode(' ', array_values(array_unique(array_filter(array_map(
|
||||||
static fn ($blocker): string => trim((string) $blocker),
|
static fn ($blocker): string => trim((string) $blocker),
|
||||||
$evaluation['blockers']
|
$evaluation['blockers']
|
||||||
@@ -314,6 +314,7 @@ final class EnrollmentRegistrationEmailService
|
|||||||
}
|
}
|
||||||
|
|
||||||
return match ((string) ($evaluation['deliberation_decision'] ?? '')) {
|
return match ((string) ($evaluation['deliberation_decision'] ?? '')) {
|
||||||
|
DeliberationDecision::PASSED => $name . ' has successfully passed ' . $this->currentGradeText($evaluation) . '.',
|
||||||
DeliberationDecision::REPEAT_CLASS => 'The deliberation decision for ' . $name . ' is to repeat the current grade. After re-enrollment is completed, the student will remain in the same grade.',
|
DeliberationDecision::REPEAT_CLASS => 'The deliberation decision for ' . $name . ' is to repeat the current grade. After re-enrollment is completed, the student will remain in the same grade.',
|
||||||
DeliberationDecision::MAKE_UP_EXAM => 'The final academic decision for ' . $name . ' is currently pending the result of a make-up exam. This exam is scheduled for ' . $this->makeupExamDateText($schoolYear) . ' from 9:30 AM to 11:00 AM at ISGL.'
|
DeliberationDecision::MAKE_UP_EXAM => 'The final academic decision for ' . $name . ' is currently pending the result of a make-up exam. This exam is scheduled for ' . $this->makeupExamDateText($schoolYear) . ' from 9:30 AM to 11:00 AM at ISGL.'
|
||||||
. "\n" . 'The exam result will determine whether the student advances to the next grade or repeats the current class. Failure to attend the make-up exam will automatically result in the student repeating the class, as no further retake opportunities will be available.'
|
. "\n" . 'The exam result will determine whether the student advances to the next grade or repeats the current class. Failure to attend the make-up exam will automatically result in the student repeating the class, as no further retake opportunities will be available.'
|
||||||
@@ -355,7 +356,13 @@ final class EnrollmentRegistrationEmailService
|
|||||||
$previousYear ?? '',
|
$previousYear ?? '',
|
||||||
$schoolYearName
|
$schoolYearName
|
||||||
);
|
);
|
||||||
|
$fallbackTotal = (float) ($schoolYear['registration_fee'] ?? 0)
|
||||||
|
+ (float) ($schoolYear['tuition_due_at_registration'] ?? 0)
|
||||||
|
+ (float) ($schoolYear['mandatory_fees'] ?? 0);
|
||||||
$total = (float) ($summary['total_enrollment_due'] ?? $summary['amount_due'] ?? 0);
|
$total = (float) ($summary['total_enrollment_due'] ?? $summary['amount_due'] ?? 0);
|
||||||
|
if ($total <= 0.0 && $fallbackTotal > 0.0) {
|
||||||
|
$total = $fallbackTotal;
|
||||||
|
}
|
||||||
if ($total <= 0.0) {
|
if ($total <= 0.0) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@@ -521,7 +528,7 @@ final class EnrollmentRegistrationEmailService
|
|||||||
|
|
||||||
private function registrationStatus(array $evaluation): string
|
private function registrationStatus(array $evaluation): string
|
||||||
{
|
{
|
||||||
if (($evaluation['can_enroll'] ?? false) === true) {
|
if ($this->canCompleteParentReEnrollment($evaluation)) {
|
||||||
return ($evaluation['deliberation_decision'] ?? '') === DeliberationDecision::MAKE_UP_EXAM
|
return ($evaluation['deliberation_decision'] ?? '') === DeliberationDecision::MAKE_UP_EXAM
|
||||||
? 'Eligible with pending placement'
|
? 'Eligible with pending placement'
|
||||||
: 'Eligible';
|
: 'Eligible';
|
||||||
@@ -543,6 +550,18 @@ final class EnrollmentRegistrationEmailService
|
|||||||
return 'Not Eligible';
|
return 'Not Eligible';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (($evaluation['blockers'] ?? []) !== [] && ! $this->hasOnlyNonBlockingEmailBlockers($evaluation)) {
|
||||||
|
return 'Not Eligible';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($evaluation['deliberation_decision'] ?? '') === DeliberationDecision::PASSED) {
|
||||||
|
return 'Eligible';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($evaluation['deliberation_decision'] ?? '') === DeliberationDecision::MAKE_UP_EXAM) {
|
||||||
|
return 'Eligible with pending placement';
|
||||||
|
}
|
||||||
|
|
||||||
if (($evaluation['blockers'] ?? []) !== []) {
|
if (($evaluation['blockers'] ?? []) !== []) {
|
||||||
return 'Not Eligible';
|
return 'Not Eligible';
|
||||||
}
|
}
|
||||||
@@ -566,6 +585,30 @@ final class EnrollmentRegistrationEmailService
|
|||||||
return array_values(array_diff($codes, $ignoredCodes)) !== [];
|
return array_values(array_diff($codes, $ignoredCodes)) !== [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function hasOnlyNonBlockingEmailBlockers(array $evaluation): bool
|
||||||
|
{
|
||||||
|
$blockers = array_values(array_filter(array_map(
|
||||||
|
static fn ($blocker): string => strtolower(trim((string) $blocker)),
|
||||||
|
$evaluation['blockers'] ?? []
|
||||||
|
)));
|
||||||
|
if ($blockers === []) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($blockers as $blocker) {
|
||||||
|
if (
|
||||||
|
str_contains($blocker, 'registration for the new school year has not opened yet')
|
||||||
|
|| str_contains($blocker, 'passed the highest available grade')
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private function studentIssueCode(array $evaluation): string
|
private function studentIssueCode(array $evaluation): string
|
||||||
{
|
{
|
||||||
if (! empty($evaluation['adult_student'])) {
|
if (! empty($evaluation['adult_student'])) {
|
||||||
@@ -617,12 +660,20 @@ final class EnrollmentRegistrationEmailService
|
|||||||
|
|
||||||
private function requiredAction(array $evaluation, string $deadline, string $name = 'The student'): string
|
private function requiredAction(array $evaluation, string $deadline, string $name = 'The student'): string
|
||||||
{
|
{
|
||||||
if (($evaluation['can_enroll'] ?? false) === true) {
|
if ($this->canCompleteParentReEnrollment($evaluation)) {
|
||||||
return ($evaluation['deliberation_decision'] ?? '') === DeliberationDecision::MAKE_UP_EXAM
|
return ($evaluation['deliberation_decision'] ?? '') === DeliberationDecision::MAKE_UP_EXAM
|
||||||
? ''
|
? ''
|
||||||
: 'Complete re-enrollment before ' . $deadline . '.';
|
: 'Complete re-enrollment before ' . $deadline . '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (($evaluation['deliberation_decision'] ?? '') === DeliberationDecision::MAKE_UP_EXAM && ($evaluation['blockers'] ?? []) === []) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($evaluation['deliberation_decision'] ?? '') === DeliberationDecision::PASSED && $this->hasOnlyNonBlockingEmailBlockers($evaluation)) {
|
||||||
|
return 'Complete re-enrollment before ' . $deadline . '.';
|
||||||
|
}
|
||||||
|
|
||||||
if (! empty($evaluation['primary_parent_message'])) {
|
if (! empty($evaluation['primary_parent_message'])) {
|
||||||
return (string) $evaluation['primary_parent_message'];
|
return (string) $evaluation['primary_parent_message'];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ final class EnrollmentEligibility
|
|||||||
public const DEFERRED_MESSAGE = 'Re-enrollment cannot currently be completed because the final deliberation decision is deferred. Please contact the school administration for the next required step.';
|
public const DEFERRED_MESSAGE = 'Re-enrollment cannot currently be completed because the final deliberation decision is deferred. Please contact the school administration for the next required step.';
|
||||||
public const KG_MISSING_DECISION_ELIGIBLE_MESSAGE = 'KG students may complete registration now. Their new-year grade placement will be based on the school age-placement rule.';
|
public const KG_MISSING_DECISION_ELIGIBLE_MESSAGE = 'KG students may complete registration now. Their new-year grade placement will be based on the school age-placement rule.';
|
||||||
public const MISSING_DECISION_MESSAGE = 'Re-enrollment cannot currently be completed because no final deliberation decision is recorded for the student. Registration will become available after the school records a final decision.';
|
public const MISSING_DECISION_MESSAGE = 'Re-enrollment cannot currently be completed because no final deliberation decision is recorded for the student. Registration will become available after the school records a final decision.';
|
||||||
public const ADULT_STUDENT_MESSAGE = 'This student is over the allowed age for enrollment or re-enrollment at the school. Please contact school administration.';
|
public const ADULT_STUDENT_MESSAGE = 'This student will be 18 years old or older on September 1 of the selected school year. A parent or guardian cannot complete registration for this student. Please contact school administration.';
|
||||||
public const ADULT_STUDENT_PARENT_PORTAL_MESSAGE = self::ADULT_STUDENT_MESSAGE;
|
public const ADULT_STUDENT_PARENT_PORTAL_MESSAGE = self::ADULT_STUDENT_MESSAGE;
|
||||||
public const WITHDRAWN_PORTAL_MESSAGE = 'This student is currently marked as Withdrawn and cannot be enrolled at this time. Please contact school administration.';
|
public const WITHDRAWN_PORTAL_MESSAGE = 'This student is currently marked as Withdrawn and cannot be enrolled at this time. Please contact school administration.';
|
||||||
public const SIBLING_PORTAL_MESSAGE = 'Enrollment cannot continue because the family record requires administrative review. Please contact school administration.';
|
public const SIBLING_PORTAL_MESSAGE = 'Enrollment cannot continue because the family record requires administrative review. Please contact school administration.';
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<!-- app/Views/errors/custom/blocked.php -->
|
<!-- app/Views/errors/custom/blocked.php -->
|
||||||
|
<?php if (session()->getFlashdata('show_block_modal')): ?>
|
||||||
<div class="modal fade" id="blockedModal" tabindex="-1" aria-labelledby="blockedLabel" aria-hidden="true">
|
<div class="modal fade" id="blockedModal" tabindex="-1" aria-labelledby="blockedLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-dialog-centered modal-lg">
|
<div class="modal-dialog modal-dialog-centered modal-lg">
|
||||||
<div class="modal-content rounded-4 shadow border-0" style="max-width: 600px; margin: auto;">
|
<div class="modal-content rounded-4 shadow border-0" style="max-width: 600px; margin: auto;">
|
||||||
@@ -14,7 +15,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if (session()->getFlashdata('show_block_modal')): ?>
|
|
||||||
<script>
|
<script>
|
||||||
window.addEventListener('DOMContentLoaded', function () {
|
window.addEventListener('DOMContentLoaded', function () {
|
||||||
const modal = new bootstrap.Modal(document.getElementById('blockedModal'));
|
const modal = new bootstrap.Modal(document.getElementById('blockedModal'));
|
||||||
|
|||||||
+1
-1
@@ -39,7 +39,7 @@
|
|||||||
<button type="submit">Login</button>
|
<button type="submit">Login</button>
|
||||||
<div class="form-links">
|
<div class="form-links">
|
||||||
<a href="/register">Register</a>
|
<a href="/register">Register</a>
|
||||||
<a href="/forgot_password">Forgot Password</a>
|
<a href="<?= site_url('user/forgot_password') ?>">Forgot Password</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -7,12 +7,17 @@
|
|||||||
<?= esc(session()->getFlashdata('error')) ?>
|
<?= esc(session()->getFlashdata('error')) ?>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
<?php if (session()->getFlashdata('success')): ?>
|
||||||
|
<div class="alert alert-success text-center">
|
||||||
|
<?= esc(session()->getFlashdata('success')) ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<!-- Form -->
|
<!-- Form -->
|
||||||
<form method="post" action="/processForgotPassword" class="text-start" style="max-width: 600px; margin: 0 auto;">
|
<form method="post" action="<?= site_url('user/forgot_password') ?>" class="text-start" style="max-width: 600px; margin: 0 auto;">
|
||||||
<?= csrf_field() ?>
|
<?= csrf_field() ?>
|
||||||
<div class="text-center mb-4">
|
<div class="text-center mb-4">
|
||||||
<a href="<?= base_url('/') ?>">
|
<a href="<?= site_url('user/forgot_password') ?>">
|
||||||
<img src="<?= base_url('assets/images/alrahma_logo.png') ?>" alt=""
|
<img src="<?= base_url('assets/images/alrahma_logo.png') ?>" alt=""
|
||||||
style="width: 120px; height: 120px; border-radius: 50%; object-fit: contain; background-color: #fff;">
|
style="width: 120px; height: 120px; border-radius: 50%; object-fit: contain; background-color: #fff;">
|
||||||
</a>
|
</a>
|
||||||
@@ -43,7 +48,7 @@
|
|||||||
|
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<p class="mb-0">Don't have an account?</p>
|
<p class="mb-0">Don't have an account?</p>
|
||||||
<a href="/register" class="d-inline-block mt-1">Register now</a>
|
<a href="<?= site_url('register') ?>" class="d-inline-block mt-1">Register now</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<!-- app/Views/user/password_reset_confirmation.php -->
|
<!-- app/Views/user/password_reset_confirmation.php -->
|
||||||
|
<?php if (session()->getFlashdata('show_modal')): ?>
|
||||||
<div class="modal fade" id="emailConfirmModal" tabindex="-1" aria-labelledby="emailConfirmLabel" aria-hidden="true">
|
<div class="modal fade" id="emailConfirmModal" tabindex="-1" aria-labelledby="emailConfirmLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-dialog-centered modal-lg">
|
<div class="modal-dialog modal-dialog-centered modal-lg">
|
||||||
<div class="modal-content rounded-4 shadow border-0" style="max-width: 600px; margin: auto;">
|
<div class="modal-content rounded-4 shadow border-0" style="max-width: 600px; margin: auto;">
|
||||||
@@ -17,7 +18,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if (session()->getFlashdata('show_modal')): ?>
|
|
||||||
<script>
|
<script>
|
||||||
window.addEventListener('DOMContentLoaded', function() {
|
window.addEventListener('DOMContentLoaded', function() {
|
||||||
const modal = new bootstrap.Modal(document.getElementById('emailConfirmModal'));
|
const modal = new bootstrap.Modal(document.getElementById('emailConfirmModal'));
|
||||||
|
|||||||
Reference in New Issue
Block a user