fixed the login and register page with register preselect country and call code based on gps location

This commit is contained in:
Ghassan Yusuf 2026-01-23 22:24:44 +03:00
parent b0c49bc6e4
commit 6b027b8bc6
5 changed files with 891 additions and 286 deletions

View File

@ -1,27 +1,302 @@
@extends('layouts.app')
@section('hide-navbar')
@endsection
@section('content')
<div class="container">
<div class="row justify-content-center align-items-center" style="min-height: 80vh;">
<div class="col-md-6 col-lg-4">
<div class="card shadow">
<div class="card-body p-4">
<div class="text-center mb-4">
<h3 class="fw-bold">Welcome Back</h3>
<p class="text-muted">Sign in to your account</p>
<style>
.login-page {
background: linear-gradient(135deg, hsl(250 60% 70%) 0%, hsl(140 30% 75%) 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.login-page::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grain" width="100" height="100" patternUnits="userSpaceOnUse"><circle cx="25" cy="25" r="1" fill="rgba(255,255,255,0.1)"/><circle cx="75" cy="75" r="1" fill="rgba(255,255,255,0.1)"/><circle cx="50" cy="10" r="0.5" fill="rgba(255,255,255,0.05)"/></pattern></defs><rect width="100" height="100" fill="url(%23grain)"/></svg>');
opacity: 0.3;
pointer-events: none;
}
.login-box {
width: 420px;
position: relative;
z-index: 1;
animation: slideIn 0.6s ease-out;
}
.login-logo {
text-align: center;
margin-bottom: 1rem;
}
.login-logo a {
color: hsl(250 60% 40%);
font-size: 2rem;
font-weight: bold;
text-decoration: none;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.login-card-body {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1), 0 0 0 1px rgba(255,255,255,0.2);
border: 1px solid rgba(255,255,255,0.3);
padding: 2.5rem;
}
.login-box-msg {
margin: 0 0 2rem 0;
padding: 0;
color: hsl(215 15% 50%);
text-align: center;
font-size: 1.1rem;
font-weight: 400;
letter-spacing: -0.025em;
}
.input-group {
margin-bottom: 1.5rem;
position: relative;
}
.form-control {
border: 2px solid rgba(250, 60, 70, 0.2);
border-radius: 12px;
padding: 0.75rem 1rem;
font-size: 1rem;
background: rgba(255,255,255,0.8);
transition: all 0.3s ease;
box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
}
.form-control:focus {
border-color: hsl(250 60% 70%);
background: #fff;
box-shadow: 0 0 0 3px rgba(250, 60, 70, 0.1), inset 0 1px 3px rgba(0,0,0,0.1);
}
.btn-primary {
background: linear-gradient(135deg, hsl(250 60% 70%), hsl(250 60% 65%));
border: none;
border-radius: 12px;
padding: 0.75rem 2rem;
font-weight: 600;
font-size: 1rem;
color: #fff;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(250, 60, 70, 0.3);
width: 100%;
margin-top: 0.5rem;
}
.btn-primary:hover {
background: linear-gradient(135deg, hsl(250 60% 75%), hsl(250 60% 70%));
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(250, 60, 70, 0.4);
}
.btn-primary:active {
transform: translateY(0);
}
.btn-register {
background: #fff;
border: 2px solid hsl(250 60% 70%);
border-radius: 12px;
padding: 0.75rem 2rem;
font-weight: 600;
font-size: 1rem;
color: hsl(250 60% 70%);
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(250, 60, 70, 0.3);
width: 100%;
margin-top: 0.5rem;
}
.btn-register:hover {
background: hsl(250 60% 70%);
color: #fff;
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(250, 60, 70, 0.4);
}
.btn-register:active {
transform: translateY(0);
}
.form-check-input {
border-color: rgba(250, 60, 70, 0.3);
background-color: rgba(255,255,255,0.8);
}
.form-check-input:checked {
background-color: hsl(250 60% 70%);
border-color: hsl(250 60% 70%);
}
.form-check-input:focus {
border-color: hsl(250 60% 70%);
box-shadow: 0 0 0 0.25rem rgba(250, 60, 70, 0.25);
}
.form-check-label {
color: hsl(215 25% 50%);
font-size: 0.9rem;
}
.text-muted {
color: hsl(215 15% 60%) !important;
font-size: 0.9rem;
}
.text-muted a {
color: hsl(250 60% 60%);
text-decoration: none;
font-weight: 500;
transition: color 0.3s ease;
}
.text-muted a:hover {
color: hsl(250 60% 70%);
text-decoration: underline;
}
.social-auth-links {
margin-top: 1.5rem;
}
.social-auth-links p {
margin: 0.5rem 0;
color: hsl(215 15% 60%);
font-weight: 500;
}
.social-auth-links .btn {
margin-bottom: 0.5rem;
border-radius: 12px;
font-weight: 500;
transition: all 0.3s ease;
}
.social-auth-links .btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0,0,0,0.2);
}
.social-auth-links .btn-primary {
background: linear-gradient(135deg, #1877f2, #42a5f5);
border: none;
}
.social-auth-links .btn-danger {
background: linear-gradient(135deg, #db4437, #ff7043);
border: none;
}
.flatpickr-input {
width: 100%;
padding: 0.75rem 1rem;
font-size: 1rem;
border: 2px solid rgba(250, 60, 70, 0.2);
border-radius: 12px;
background: rgba(255,255,255,0.8);
transition: all 0.3s ease;
box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
}
.flatpickr-input:focus {
border-color: hsl(250 60% 70%);
background: #fff;
box-shadow: 0 0 0 3px rgba(250, 60, 70, 0.1), inset 0 1px 3px rgba(0,0,0,0.1);
}
.form-switch .form-check-input {
width: 3em;
height: 1.5em;
border-radius: 1em;
background-color: rgba(250, 60, 70, 0.2);
border: none;
transition: all 0.3s ease;
}
.form-switch .form-check-input:checked {
background-color: hsl(250 60% 70%);
}
.form-switch .form-check-input:focus {
box-shadow: 0 0 0 3px rgba(250, 60, 70, 0.2);
}
@media (max-width: 480px) {
.login-box {
width: 90%;
margin: 1rem;
}
.login-card-body {
padding: 2rem;
}
.login-box-msg {
font-size: 1.3rem;
}
}
</style>
<!-- Flag Icons CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flag-icons@6.6.6/css/flag-icons.min.css">
<!-- Select2 CSS (for nationality dropdown) -->
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<!-- Flatpickr CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<div class="login-page">
<div class="login-box">
<div class="card">
<div class="card-body login-card-body">
<div class="login-logo">
<a href="{{ url('/') }}">
<img src="{{ asset('images/logo.png') }}" alt="TAKEONE" height="50">
</a>
</div>
<!-- /.login-logo -->
<p class="login-box-msg">Sign in to start your session</p>
<form method="POST" action="{{ route('login') }}">
@csrf
<!-- Email or Phone -->
<div class="mb-3">
<label for="email" class="form-label">Email or Phone</label>
<input id="email" type="text"
class="form-control @error('email') is-invalid @enderror"
name="email"
value="{{ old('email') }}"
placeholder="Enter your email or phone number"
placeholder="Email or Phone"
required autocomplete="username"
autofocus>
@error('email')
@ -31,12 +306,11 @@
@enderror
</div>
<!-- Password -->
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input id="password" type="password"
class="form-control @error('password') is-invalid @enderror"
name="password"
placeholder="Password"
required autocomplete="current-password">
@error('password')
<span class="invalid-feedback" role="alert">
@ -45,33 +319,40 @@
@enderror
</div>
<!-- Remember Me -->
<div class="mb-3 form-check">
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
<div class="form-check mb-3">
<input type="checkbox" class="form-check-input" id="remember" name="remember" {{ old('remember') ? 'checked' : '' }}>
<label class="form-check-label" for="remember">
Remember Me
</label>
</div>
<!-- Login Button -->
<div class="d-grid mb-3">
<button type="submit" class="btn btn-primary">
Login
</button>
<button type="submit" class="btn btn-primary w-100 mb-2">SIGN IN</button>
<a href="{{ route('register') }}" class="btn btn-register w-100 mb-4">REGISTER</a>
</form>
<p class="mb-1 text-center">
@if (Route::has('password.request'))
<a href="{{ route('password.request') }}">I forgot my password</a>
@endif
</p>
</div>
<!-- /.login-card-body -->
</div>
</div>
<!-- /.login-box -->
</div>
<!-- Forgot Password Link -->
<div class="text-center">
@if (Route::has('password.request'))
<a class="text-decoration-none" href="{{ route('password.request') }}">
Forgot Password?
</a>
@endif
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- jQuery (required for Select2) -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- Select2 JS -->
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<!-- Flatpickr JS -->
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
@stack('styles')
@stack('scripts')
@endsection

View File

@ -1,30 +1,287 @@
@extends('layouts.app')
@section('hide-navbar')
@endsection
@section('content')
<style>
.register-container {
min-height: calc(100vh - 72px);
.login-page {
background: linear-gradient(135deg, hsl(250 60% 70%) 0%, hsl(140 30% 75%) 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 2rem 0;
position: relative;
overflow: hidden;
}
.login-page::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grain" width="100" height="100" patternUnits="userSpaceOnUse"><circle cx="25" cy="25" r="1" fill="rgba(255,255,255,0.1)"/><circle cx="75" cy="75" r="1" fill="rgba(255,255,255,0.1)"/><circle cx="50" cy="10" r="0.5" fill="rgba(255,255,255,0.05)"/></pattern></defs><rect width="100" height="100" fill="url(%23grain)"/></svg>');
opacity: 0.3;
pointer-events: none;
}
.login-box {
width: 500px;
position: relative;
z-index: 1;
animation: slideIn 0.6s ease-out;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.login-card-body {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1), 0 0 0 1px rgba(255,255,255,0.2);
border: 1px solid rgba(255,255,255,0.3);
padding: 2.5rem;
}
.login-logo {
text-align: center;
margin-bottom: 1rem;
}
.login-logo a {
color: hsl(250 60% 40%);
font-size: 2rem;
font-weight: bold;
text-decoration: none;
}
.login-box-msg {
margin: 0 0 2rem 0;
padding: 0;
color: hsl(215 15% 50%);
text-align: center;
font-size: 1.1rem;
font-weight: 400;
letter-spacing: -0.025em;
}
.input-group {
margin-bottom: 1.5rem;
position: relative;
}
.form-control {
border: 2px solid rgba(250, 60, 70, 0.2);
border-radius: 12px;
padding: 0.75rem 1rem;
font-size: 1rem;
background: rgba(255,255,255,0.8);
transition: all 0.3s ease;
box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
}
.form-control:focus {
border-color: hsl(250 60% 70%);
background: #fff;
box-shadow: 0 0 0 3px rgba(250, 60, 70, 0.1), inset 0 1px 3px rgba(0,0,0,0.1);
}
.btn-primary {
background: linear-gradient(135deg, hsl(250 60% 70%), hsl(250 60% 65%));
border: none;
border-radius: 12px;
padding: 0.75rem 2rem;
font-weight: 600;
font-size: 1rem;
color: #fff;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(250, 60, 70, 0.3);
width: 100%;
margin-top: 0.5rem;
}
.btn-primary:hover {
background: linear-gradient(135deg, hsl(250 60% 75%), hsl(250 60% 70%));
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(250, 60, 70, 0.4);
}
.btn-primary:active {
transform: translateY(0);
}
.flatpickr-input {
width: 100%;
padding: 0.375rem 0.75rem;
padding: 0.75rem 1rem;
font-size: 1rem;
line-height: 1.5;
color: #212529;
background-color: #fff;
border: 1px solid #ced4da;
border-radius: 0.375rem;
border: 2px solid rgba(250, 60, 70, 0.2);
border-radius: 12px;
background: rgba(255,255,255,0.8);
transition: all 0.3s ease;
box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
}
.flatpickr-input:focus {
border-color: #86b7fe;
outline: 0;
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
border-color: hsl(250 60% 70%);
background: #fff;
box-shadow: 0 0 0 3px rgba(250, 60, 70, 0.1), inset 0 1px 3px rgba(0,0,0,0.1);
}
.form-select {
border: 2px solid rgba(250, 60, 70, 0.2);
border-radius: 12px;
padding: 0.75rem 1rem;
background: rgba(255,255,255,0.8);
transition: all 0.3s ease;
box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
}
.form-select:focus {
border-color: hsl(250 60% 70%);
background: #fff;
box-shadow: 0 0 0 3px rgba(250, 60, 70, 0.1), inset 0 1px 3px rgba(0,0,0,0.1);
}
/* Seamless phone input styling */
.input-group {
border: 2px solid rgba(250, 60, 70, 0.2) !important;
border-radius: 12px !important;
background: rgba(255,255,255,0.8) !important;
transition: all 0.3s ease !important;
box-shadow: inset 0 1px 3px rgba(0,0,0,0.1) !important;
position: relative !important;
}
.input-group:focus-within {
border-color: hsl(250 60% 70%) !important;
background: #fff !important;
box-shadow: 0 0 0 3px rgba(250, 60, 70, 0.1), inset 0 1px 3px rgba(0,0,0,0.1) !important;
}
.country-dropdown-btn {
border: none !important;
border-radius: 0 !important;
border-right: 1px solid rgba(250, 60, 70, 0.2) !important;
padding: 0.75rem 1rem !important;
background: transparent !important;
transition: all 0.3s ease !important;
box-shadow: none !important;
color: hsl(215 25% 35%) !important;
font-size: 1rem !important;
height: auto !important;
min-height: 3rem !important;
width: auto !important;
flex: 0 0 auto !important;
justify-content: flex-start !important;
}
.country-dropdown-btn:hover {
background: rgba(250, 60, 70, 0.05) !important;
}
.country-dropdown-btn:focus {
background: rgba(250, 60, 70, 0.05) !important;
outline: none !important;
}
.input-group .form-control {
border: none !important;
border-radius: 0 !important;
padding: 0.75rem 1rem !important;
background: transparent !important;
box-shadow: none !important;
flex: 1 !important;
}
.input-group .form-control:focus {
background: transparent !important;
box-shadow: none !important;
}
.country-dropdown-btn .dropdown-toggle::after {
margin-left: auto !important;
border-top-color: hsl(215 25% 35%) !important;
}
.form-select {
min-height: 3rem !important;
}
.select2-container--default .select2-selection--single {
border: 2px solid rgba(250, 60, 70, 0.2) !important;
border-radius: 12px !important;
padding: 0.75rem 1rem !important;
background: rgba(255,255,255,0.8) !important;
transition: all 0.3s ease !important;
box-shadow: inset 0 1px 3px rgba(0,0,0,0.1) !important;
height: auto !important;
min-height: 3rem !important;
}
.select2-container--default .select2-selection--single .select2-selection__rendered {
color: hsl(215 25% 35%) !important;
font-size: 1rem !important;
line-height: 1.5 !important;
padding: 0 !important;
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
height: 100% !important;
right: 10px !important;
top: 50% !important;
transform: translateY(-50%) !important;
}
.select2-container--default .select2-selection--single .select2-selection__arrow b {
border-color: hsl(215 25% 35%) transparent transparent transparent !important;
border-width: 5px 5px 0 5px !important;
}
.select2-container--default.select2-container--open .select2-selection--single {
border-color: hsl(250 60% 70%) !important;
background: #fff !important;
box-shadow: 0 0 0 3px rgba(250, 60, 70, 0.1), inset 0 1px 3px rgba(0,0,0,0.1) !important;
}
.select2-dropdown {
border: 2px solid rgba(250, 60, 70, 0.2) !important;
border-radius: 12px !important;
box-shadow: 0 4px 15px rgba(0,0,0,0.1) !important;
}
.select2-container--default .select2-results__option {
padding: 0.5rem 1rem !important;
}
.select2-container--default .select2-results__option--highlighted[aria-selected] {
background-color: hsl(250 60% 95%) !important;
color: hsl(250 60% 30%) !important;
}
@media (max-width: 480px) {
.login-box {
width: 90%;
margin: 1rem;
}
.login-card-body {
padding: 2rem;
}
.login-box-msg {
font-size: 1.3rem;
}
}
</style>
@ -37,27 +294,28 @@
<!-- Flatpickr CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<div class="container register-container">
<div class="row justify-content-center">
<div class="col-lg-10">
<div class="card shadow">
<div class="card-header bg-white py-3">
<h3 class="text-center mb-0 fw-bold">Register</h3>
<div class="login-page">
<div class="login-box">
<div class="card">
<div class="card-body login-card-body">
<div class="login-logo">
<a href="{{ url('/') }}">
<img src="{{ asset('images/logo.png') }}" alt="TAKEONE" height="50">
</a>
</div>
<div class="card-body p-4">
<!-- /.login-logo -->
<p class="login-box-msg">Register a new membership</p>
<form method="POST" action="{{ route('register') }}" id="registrationForm">
@csrf
<div class="row">
<!-- Left Column -->
<div class="col-md-6">
<!-- Full Name -->
<div class="mb-3">
<label for="full_name" class="form-label">Full Name</label>
<input id="full_name" type="text"
class="form-control @error('full_name') is-invalid @enderror"
name="full_name"
value="{{ old('full_name') }}"
placeholder="Full Name"
required autocomplete="name">
@error('full_name')
<span class="invalid-feedback" role="alert">
@ -68,11 +326,11 @@
<!-- Email Address -->
<div class="mb-3">
<label for="email" class="form-label">Email Address</label>
<input id="email" type="email"
class="form-control @error('email') is-invalid @enderror"
name="email"
value="{{ old('email') }}"
placeholder="Email Address"
required autocomplete="email">
@error('email')
<span class="invalid-feedback" role="alert">
@ -83,10 +341,10 @@
<!-- Password -->
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input id="password" type="password"
class="form-control @error('password') is-invalid @enderror"
name="password"
placeholder="Password"
required autocomplete="new-password">
@error('password')
<span class="invalid-feedback" role="alert">
@ -97,19 +355,15 @@
<!-- Confirm Password -->
<div class="mb-3">
<label for="password-confirm" class="form-label">Confirm Password</label>
<input id="password-confirm" type="password"
class="form-control"
name="password_confirmation"
placeholder="Confirm Password"
required autocomplete="new-password">
</div>
</div>
<!-- Right Column -->
<div class="col-md-6">
<!-- Mobile Number with Country Code -->
<div class="mb-3">
<label for="mobile_number" class="form-label">Mobile Number</label>
<x-country-code-dropdown
name="country_code"
id="country_code"
@ -120,8 +374,8 @@
class="form-control @error('mobile_number') is-invalid @enderror"
name="mobile_number"
value="{{ old('mobile_number') }}"
required autocomplete="tel"
placeholder="Phone number">
placeholder="Mobile Number"
required autocomplete="tel">
</x-country-code-dropdown>
@error('mobile_number')
<span class="invalid-feedback d-block" role="alert">
@ -132,7 +386,6 @@
<!-- Gender -->
<div class="mb-3">
<label for="gender" class="form-label">Gender</label>
<select id="gender" class="form-select @error('gender') is-invalid @enderror"
name="gender" required>
<option value="">Select Gender</option>
@ -148,13 +401,12 @@
<!-- Birthdate -->
<div class="mb-3">
<label for="birthdate" class="form-label">Birthdate</label>
<input id="birthdate" type="text"
class="flatpickr-input @error('birthdate') is-invalid @enderror"
name="birthdate"
value="{{ old('birthdate') }}"
placeholder="Birthdate"
required
placeholder="Select birthdate"
readonly>
@error('birthdate')
<span class="invalid-feedback" role="alert">
@ -172,20 +424,14 @@
:required="true"
:error="$errors->first('nationality')" />
</div>
</div>
</div>
<!-- Register Button -->
<div class="d-grid mt-4">
<button type="submit" class="btn btn-primary btn-lg" id="registerButton">
Register
</button>
</div>
<button type="submit" class="btn btn-primary" id="registerButton">Register</button>
</form>
</div>
<!-- /.login-card-body -->
</div>
</div>
</div>
<!-- /.login-box -->
</div>
<!-- jQuery (required for Select2) -->
@ -197,9 +443,6 @@
<!-- Flatpickr JS -->
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
@stack('styles')
@stack('scripts')
<script>
document.addEventListener('DOMContentLoaded', function() {
// Initialize Flatpickr for birthdate
@ -233,4 +476,7 @@
};
});
</script>
@stack('styles')
@stack('scripts')
@endsection

View File

@ -7,7 +7,7 @@
data-bs-toggle="dropdown"
data-bs-auto-close="outside"
aria-expanded="false">
<span class="fi fi-us me-2" id="{{ $id }}SelectedFlag"></span>
<span id="{{ $id }}SelectedFlag">🇺🇸</span>
<span class="country-label" id="{{ $id }}SelectedCountry">{{ $value }}</span>
</button>
@ -68,65 +68,100 @@
document.addEventListener('DOMContentLoaded', function() {
// Country data with flags and codes
const countries = [
{ code: '+1', name: 'United States', flagCode: 'us' },
{ code: '+1', name: 'Canada', flagCode: 'ca' },
{ code: '+44', name: 'United Kingdom', flagCode: 'gb' },
{ code: '+971', name: 'United Arab Emirates', flagCode: 'ae' },
{ code: '+966', name: 'Saudi Arabia', flagCode: 'sa' },
{ code: '+974', name: 'Qatar', flagCode: 'qa' },
{ code: '+965', name: 'Kuwait', flagCode: 'kw' },
{ code: '+973', name: 'Bahrain', flagCode: 'bh' },
{ code: '+968', name: 'Oman', flagCode: 'om' },
{ code: '+20', name: 'Egypt', flagCode: 'eg' },
{ code: '+91', name: 'India', flagCode: 'in' },
{ code: '+92', name: 'Pakistan', flagCode: 'pk' },
{ code: '+880', name: 'Bangladesh', flagCode: 'bd' },
{ code: '+60', name: 'Malaysia', flagCode: 'my' },
{ code: '+65', name: 'Singapore', flagCode: 'sg' },
{ code: '+81', name: 'Japan', flagCode: 'jp' },
{ code: '+86', name: 'China', flagCode: 'cn' },
{ code: '+82', name: 'South Korea', flagCode: 'kr' },
{ code: '+61', name: 'Australia', flagCode: 'au' },
{ code: '+49', name: 'Germany', flagCode: 'de' },
{ code: '+33', name: 'France', flagCode: 'fr' },
{ code: '+39', name: 'Italy', flagCode: 'it' },
{ code: '+34', name: 'Spain', flagCode: 'es' },
{ code: '+31', name: 'Netherlands', flagCode: 'nl' },
{ code: '+46', name: 'Sweden', flagCode: 'se' },
{ code: '+47', name: 'Norway', flagCode: 'no' },
{ code: '+45', name: 'Denmark', flagCode: 'dk' },
{ code: '+358', name: 'Finland', flagCode: 'fi' },
{ code: '+41', name: 'Switzerland', flagCode: 'ch' },
{ code: '+43', name: 'Austria', flagCode: 'at' },
{ code: '+48', name: 'Poland', flagCode: 'pl' },
{ code: '+420', name: 'Czech Republic', flagCode: 'cz' },
{ code: '+36', name: 'Hungary', flagCode: 'hu' },
{ code: '+40', name: 'Romania', flagCode: 'ro' },
{ code: '+30', name: 'Greece', flagCode: 'gr' },
{ code: '+90', name: 'Turkey', flagCode: 'tr' },
{ code: '+7', name: 'Russia', flagCode: 'ru' },
{ code: '+55', name: 'Brazil', flagCode: 'br' },
{ code: '+52', name: 'Mexico', flagCode: 'mx' },
{ code: '+54', name: 'Argentina', flagCode: 'ar' },
{ code: '+56', name: 'Chile', flagCode: 'cl' },
{ code: '+57', name: 'Colombia', flagCode: 'co' },
{ code: '+27', name: 'South Africa', flagCode: 'za' },
{ code: '+234', name: 'Nigeria', flagCode: 'ng' },
{ code: '+254', name: 'Kenya', flagCode: 'ke' },
{ code: '+94', name: 'Sri Lanka', flagCode: 'lk' },
{ code: '+84', name: 'Vietnam', flagCode: 'vn' },
{ code: '+66', name: 'Thailand', flagCode: 'th' },
{ code: '+62', name: 'Indonesia', flagCode: 'id' },
{ code: '+63', name: 'Philippines', flagCode: 'ph' },
{ code: '+64', name: 'New Zealand', flagCode: 'nz' },
{ code: '+351', name: 'Portugal', flagCode: 'pt' },
{ code: '+353', name: 'Ireland', flagCode: 'ie' },
{ code: '+972', name: 'Israel', flagCode: 'il' },
{ code: '+962', name: 'Jordan', flagCode: 'jo' },
{ code: '+961', name: 'Lebanon', flagCode: 'lb' },
{ code: '+964', name: 'Iraq', flagCode: 'iq' },
{ code: '+1', name: 'United States', flag: '🇺🇸' },
{ code: '+1', name: 'Canada', flag: '🇨🇦' },
{ code: '+44', name: 'United Kingdom', flag: '🇬🇧' },
{ code: '+971', name: 'United Arab Emirates', flag: '🇦🇪' },
{ code: '+966', name: 'Saudi Arabia', flag: '🇸🇦' },
{ code: '+974', name: 'Qatar', flag: '🇶🇦' },
{ code: '+965', name: 'Kuwait', flag: '🇰🇼' },
{ code: '+973', name: 'Bahrain', flag: '🇧🇭' },
{ code: '+968', name: 'Oman', flag: '🇴🇲' },
{ code: '+20', name: 'Egypt', flag: '🇪🇬' },
{ code: '+91', name: 'India', flag: '🇮🇳' },
{ code: '+92', name: 'Pakistan', flag: '🇵🇰' },
{ code: '+880', name: 'Bangladesh', flag: '🇧🇩' },
{ code: '+60', name: 'Malaysia', flag: '🇲🇾' },
{ code: '+65', name: 'Singapore', flag: '🇸🇬' },
{ code: '+81', name: 'Japan', flag: '🇯🇵' },
{ code: '+86', name: 'China', flag: '🇨🇳' },
{ code: '+82', name: 'South Korea', flag: '🇰🇷' },
{ code: '+61', name: 'Australia', flag: '🇦🇺' },
{ code: '+49', name: 'Germany', flag: '🇩🇪' },
{ code: '+33', name: 'France', flag: '🇫🇷' },
{ code: '+39', name: 'Italy', flag: '🇮🇹' },
{ code: '+34', name: 'Spain', flag: '🇪🇸' },
{ code: '+31', name: 'Netherlands', flag: '🇳🇱' },
{ code: '+46', name: 'Sweden', flag: '🇸🇪' },
{ code: '+47', name: 'Norway', flag: '🇳🇴' },
{ code: '+45', name: 'Denmark', flag: '🇩🇰' },
{ code: '+358', name: 'Finland', flag: '🇫🇮' },
{ code: '+41', name: 'Switzerland', flag: '🇨🇭' },
{ code: '+43', name: 'Austria', flag: '🇦🇹' },
{ code: '+48', name: 'Poland', flag: '🇵🇱' },
{ code: '+420', name: 'Czech Republic', flag: '🇨🇿' },
{ code: '+36', name: 'Hungary', flag: '🇭🇺' },
{ code: '+40', name: 'Romania', flag: '🇷🇴' },
{ code: '+30', name: 'Greece', flag: '🇬🇷' },
{ code: '+90', name: 'Turkey', flag: '🇹🇷' },
{ code: '+98', name: 'Iran', flag: '🇮🇷' },
{ code: '+7', name: 'Russia', flag: '🇷🇺' },
{ code: '+55', name: 'Brazil', flag: '🇧🇷' },
{ code: '+52', name: 'Mexico', flag: '🇲🇽' },
{ code: '+54', name: 'Argentina', flag: '🇦🇷' },
{ code: '+56', name: 'Chile', flag: '🇨🇱' },
{ code: '+57', name: 'Colombia', flag: '🇨🇴' },
{ code: '+27', name: 'South Africa', flag: '🇿🇦' },
{ code: '+234', name: 'Nigeria', flag: '🇳🇬' },
{ code: '+254', name: 'Kenya', flag: '🇰🇪' },
{ code: '+94', name: 'Sri Lanka', flag: '🇱🇰' },
{ code: '+84', name: 'Vietnam', flag: '🇻🇳' },
{ code: '+66', name: 'Thailand', flag: '🇹🇭' },
{ code: '+62', name: 'Indonesia', flag: '🇮🇩' },
{ code: '+63', name: 'Philippines', flag: '🇵🇭' },
{ code: '+64', name: 'New Zealand', flag: '🇳🇿' },
{ code: '+351', name: 'Portugal', flag: '🇵🇹' },
{ code: '+353', name: 'Ireland', flag: '🇮🇪' },
{ code: '+962', name: 'Jordan', flag: '🇯🇴' },
{ code: '+961', name: 'Lebanon', flag: '🇱🇧' },
{ code: '+964', name: 'Iraq', flag: '🇮🇶' },
{ code: '+970', name: 'Palestine', flag: '🇵🇸' },
{ code: '+972', name: 'Palestine', flag: '🇵🇸' }
];
// Function to get user's country based on GPS
function detectUserCountry(callback) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
// Use a reverse geocoding API
fetch(`https://api.bigdatacloud.net/data/reverse-geocode-client?latitude=${lat}&longitude=${lon}&localityLanguage=en`)
.then(response => response.json())
.then(data => {
const countryName = data.countryName;
const iso2 = data.countryCode;
// Find the country code based on country name or iso2
let defaultCode = '+1'; // Default to US
for (let country of countries) {
if (country.name.toLowerCase().includes(countryName.toLowerCase()) || country.name.toLowerCase().includes(iso2.toLowerCase())) {
defaultCode = country.code;
break;
}
}
callback(defaultCode);
})
.catch(() => {
callback('+1'); // Default if error
});
}, function() {
callback('+1'); // Default if geolocation denied
});
} else {
callback('+1'); // Default if no geolocation
}
}
// Initialize all country code dropdowns on the page
document.querySelectorAll('[id$="List"]').forEach(function(listElement) {
const componentId = listElement.id.replace('List', '');
@ -147,14 +182,14 @@
button.type = 'button';
button.setAttribute('data-country-code', country.code);
button.setAttribute('data-country-name', country.name);
button.setAttribute('data-flag-code', country.flagCode);
button.setAttribute('data-flag', country.flag);
button.setAttribute('data-search', country.name.toLowerCase() + ' ' + country.code.toLowerCase());
button.innerHTML = `
<span class="fi fi-${country.flagCode} me-2"></span>
<span class="me-2">${country.flag}</span>
<span>${country.name} (${country.code})</span>
`;
button.addEventListener('click', function() {
selectCountry(componentId, country.code, country.name, country.flagCode);
selectCountry(componentId, country.code, country.name, country.flag);
});
countryList.appendChild(button);
});
@ -176,23 +211,26 @@
});
}
// Set initial value if provided
// Detect user's country and set as default
detectUserCountry(function(defaultCode) {
const hiddenInput = document.getElementById(componentId);
if (hiddenInput && hiddenInput.value) {
const initialCountry = countries.find(c => c.code === hiddenInput.value);
if (hiddenInput) {
hiddenInput.value = defaultCode;
}
const initialCountry = countries.find(c => c.code === defaultCode);
if (initialCountry) {
selectCountry(componentId, initialCountry.code, initialCountry.name, initialCountry.flagCode);
}
selectCountry(componentId, initialCountry.code, initialCountry.name, initialCountry.flag);
}
});
}
function selectCountry(componentId, code, name, flagCode) {
function selectCountry(componentId, code, name, flag) {
const flagElement = document.getElementById(componentId + 'SelectedFlag');
const countryElement = document.getElementById(componentId + 'SelectedCountry');
const hiddenInput = document.getElementById(componentId);
if (flagElement) flagElement.className = `fi fi-${flagCode} me-2`;
if (countryElement) countryElement.textContent = code;
if (flagElement) flagElement.textContent = flag;
if (countryElement) countryElement.textContent = `${name} (${code})`;
if (hiddenInput) hiddenInput.value = code;
// Close the dropdown after selection

View File

@ -27,6 +27,31 @@
return;
}
// Function to get user's country based on GPS
function detectUserCountry(callback) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
// Use a reverse geocoding API
fetch(`https://api.bigdatacloud.net/data/reverse-geocode-client?latitude=${lat}&longitude=${lon}&localityLanguage=en`)
.then(response => response.json())
.then(data => {
const countryName = data.countryName;
const iso2 = data.countryCode;
callback(countryName, iso2);
})
.catch(() => {
callback('United States', 'US'); // Default if error
});
}, function() {
callback('United States', 'US'); // Default if geolocation denied
});
} else {
callback('United States', 'US'); // Default if no geolocation
}
}
// Load countries from JSON file
fetch('/data/countries.json')
.then(response => response.json())
@ -72,6 +97,19 @@
},
width: '100%'
});
// Detect user's country and set as default
detectUserCountry(function(countryName, iso2) {
// Find the country by name or iso2
let defaultIso3 = 'USA'; // Default to US
for (let country of countries) {
if (country.name.toLowerCase().includes(countryName.toLowerCase()) || country.iso2 === iso2) {
defaultIso3 = country.iso3;
break;
}
}
$(selectElement).val(defaultIso3).trigger('change');
});
}
})
.catch(error => console.error('Error loading countries:', error));

View File

@ -284,6 +284,7 @@
@stack('styles')
</head>
<body>
@if(!View::hasSection('hide-navbar'))
<nav class="navbar navbar-expand-md navbar-light bg-light shadow-sm">
<div class="container">
<a class="navbar-brand" href="{{ Auth::check() ? route('clubs.explore') : url('/') }}">
@ -427,6 +428,7 @@
</div>
</div>
</nav>
@endif
<main>
@yield('content')