Skip to content

Commit e9bf992

Browse files
authored
Merge branch 'main' into feature/cyber-challenges-quiz-compiler-clean
2 parents 96043b4 + 95243c4 commit e9bf992

3 files changed

Lines changed: 192 additions & 19 deletions

File tree

home/templates/includes/navigation.html

Lines changed: 155 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3011,11 +3011,13 @@
30113011
{% trans "Match" %}
30123012
</li>
30133013
</a>
3014+
{% if user.is_authenticated %}
30143015
<a class="menu-link" href="{% url 'progress' %}">
30153016
<li class="mb-2 menu ps-3 py-1">
30163017
{% trans "Progress" %}
30173018
</li>
30183019
</a>
3020+
{% endif %}
30193021
</ul>
30203022
</div>
30213023
</li>
@@ -3148,7 +3150,60 @@
31483150
</div>
31493151
{% endif %}
31503152

3151-
<span class="hamburger-button-menu ms-2" type="button" data-bs-toggle="collapse" data-bs-target="#navbar_global" aria-controls="navbar_global" aria-expanded="false" aria-label="Toggle navigation">
3153+
3154+
<!-- language switcher (moved into right-side toolbar) -->
3155+
<div class="dropdown ms-2" style="margin-left:10px;margin-right:5px;">
3156+
{% get_current_language as CURRENT_LANG %}
3157+
{% with code=CURRENT_LANG|lower|slice:":2" %}
3158+
<button class="nav-link dropdown-toggle btn btn-link p-0"
3159+
id="langDropdown"
3160+
data-bs-toggle="dropdown"
3161+
aria-expanded="false"
3162+
title="{% trans 'Language' %}"
3163+
type="button">
3164+
{% if code == "en" %}
3165+
🌐
3166+
{% elif code == "es" %}
3167+
<img class="flag-icon" src="{% static 'images/flags/es.png' %}" alt="Español">
3168+
{% elif code == "zh" %}
3169+
<img class="flag-icon" src="{% static 'images/flags/cn.png' %}" alt="简体中文">
3170+
{% elif code == "fr" %}
3171+
<img class="flag-icon" src="{% static 'images/flags/fr.png' %}" alt="Français">
3172+
{% elif code == "ja" %}
3173+
<img class="flag-icon" src="{% static 'images/flags/jp.png' %}" alt="日本語">
3174+
{% elif code == "ko" %}
3175+
<img class="flag-icon" src="{% static 'images/flags/kr.png' %}" alt="한국어">
3176+
{% else %}
3177+
🌐
3178+
{% endif %}
3179+
</button>
3180+
{% endwith %}
3181+
3182+
<ul id="lang_menu" class="dropdown-menu dropdown-menu-end" aria-labelledby="langDropdown">
3183+
<li><a class="dropdown-item d-flex align-items-center lang-choice" href="#" data-lang="en">
3184+
<img class="flag-icon me-2" src="{% static 'images/flags/us.png' %}" alt="English"> English
3185+
</a></li>
3186+
<li><a class="dropdown-item d-flex align-items-center lang-choice" href="#" data-lang="es">
3187+
<img class="flag-icon me-2" src="{% static 'images/flags/es.png' %}" alt="Español"> Español
3188+
</a></li>
3189+
<li><a class="dropdown-item d-flex align-items-center lang-choice" href="#" data-lang="zh-hans">
3190+
<img class="flag-icon me-2" src="{% static 'images/flags/cn.png' %}" alt="简体中文"> 简体中文
3191+
</a></li>
3192+
<li><a class="dropdown-item d-flex align-items-center lang-choice" href="#" data-lang="fr">
3193+
<img class="flag-icon me-2" src="{% static 'images/flags/fr.png' %}" alt="Français"> Français
3194+
</a></li>
3195+
<li><a class="dropdown-item d-flex align-items-center lang-choice" href="#" data-lang="ja">
3196+
<img class="flag-icon me-2" src="{% static 'images/flags/jp.png' %}" alt="日本語"> 日本語
3197+
</a></li>
3198+
<li><a class="dropdown-item d-flex align-items-center lang-choice" href="#" data-lang="ko">
3199+
<img class="flag-icon me-2" src="{% static 'images/flags/kr.png' %}" alt="한국어"> 한국어
3200+
</a></li>
3201+
</ul>
3202+
</div>
3203+
3204+
<span class="hamburger-button-menu ms-2" type="button" data-bs-toggle="collapse"
3205+
data-bs-target="#navbar_global" aria-controls="navbar_global" aria-expanded="false"
3206+
aria-label="Toggle navigation">
31523207
<span class="navbar-toggler-icon"></span>
31533208

31543209
</span>
@@ -3490,11 +3545,83 @@
34903545
});
34913546
</script>
34923547

3493-
3494-
34953548
</div>
34963549
</div>
34973550

3551+
<style>
3552+
.flag-icon{
3553+
width: 30px;
3554+
height: 21px;
3555+
object-fit: cover;
3556+
flex-shrink: 0;
3557+
margin-right: 10px;
3558+
display: inline-block;
3559+
vertical-align: middle;
3560+
border-radius: 2px;
3561+
}
3562+
3563+
.dropdown-menu#lang_menu {
3564+
background-color: #fff !important;
3565+
border: 1px solid #ccc !important;
3566+
border-radius: 4px !important;
3567+
box-shadow: 0 2px 6px rgba(0,0,0,.15) !important;
3568+
padding: 0 !important;
3569+
margin-top: 0.5rem !important;
3570+
min-width: auto !important;
3571+
width: auto !important;
3572+
}
3573+
3574+
.dropdown-menu#lang_menu .dropdown-item {
3575+
color: #4B5868 !important;
3576+
font-weight: 500;
3577+
padding: 0.5rem 0.8rem !important;
3578+
padding-right: 1.2rem !important;
3579+
background-color: transparent !important;
3580+
border-bottom: 1px solid #eee;
3581+
display: flex !important;
3582+
align-items: center;
3583+
justify-content: flex-start;
3584+
}
3585+
3586+
.dropdown-menu#lang_menu .dropdown-item:last-child {
3587+
border-bottom: none;
3588+
}
3589+
3590+
.dropdown-menu#lang_menu .dropdown-item:hover,
3591+
.dropdown-menu#lang_menu .dropdown-item:focus {
3592+
background-color: #1967D2 !important;
3593+
color: #fff !important;
3594+
}
3595+
3596+
.dropdown-menu#lang_menu .dropdown-item.active {
3597+
background-color: #ffcd11 !important;
3598+
color: #fff !important;
3599+
}
3600+
3601+
#langDropdown img.flag-icon {
3602+
filter: none !important;
3603+
opacity: 1 !important;
3604+
}
3605+
</style>
3606+
<script>
3607+
document.addEventListener('DOMContentLoaded', function () {
3608+
const form = document.getElementById('set-lang-form');
3609+
const input = document.getElementById('lang-input');
3610+
document.querySelectorAll('.dropdown-item.lang-choice[data-lang]').forEach(a => {
3611+
a.addEventListener('click', function (e) {
3612+
e.preventDefault();
3613+
input.value = this.dataset.lang;
3614+
form.submit();
3615+
});
3616+
});
3617+
});
3618+
</script>
3619+
3620+
3621+
3622+
</div>
3623+
</div>
3624+
34983625
</nav>
34993626
</header>
35003627
<script src="{% static 'js/toggles.js' %}"></script>
@@ -3675,9 +3802,34 @@
36753802
}
36763803
});
36773804
});
3805+
36783806
</script>
36793807
<script src="{% static 'js/search_suggestions.js' %}"></script>
36803808

3809+
36813810
</script>
36823811
<script src="{% static 'js/search_suggestions.js' %}"></script>
36833812

3813+
3814+
</script>
3815+
<script src="{% static 'js/search_suggestions.js' %}"></script>
3816+
<style>
3817+
/* Keep navbar link text yellow, including when dropdown is expanded */
3818+
.navbar .nav-link,
3819+
.navbar .nav-link:hover,
3820+
.navbar .nav-link:focus,
3821+
.navbar .nav-link:active,
3822+
.navbar .nav-link:visited,
3823+
.navbar .nav-link.active,
3824+
.navbar .dropdown-toggle[aria-expanded="true"],
3825+
.navbar .dropdown-toggle.show {
3826+
color: #FFCD11 !important;
3827+
}
3828+
3829+
/* Ensure icons/arrows inherit the same yellow */
3830+
.navbar .nav-link .fas,
3831+
.navbar .nav-link .nav-link-arrow {
3832+
color: inherit !important;
3833+
}
3834+
</style>
3835+

home/templates/pages/profile.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,23 @@
1313
</div>
1414
{% endif %}
1515

16+
<!-- Banner for users without project preferences -->
17+
{% if not has_preferences %}
18+
<div class="alert alert-warning alert-dismissible fade show mb-4" role="alert">
19+
<div class="d-flex align-items-center">
20+
<i class="fas fa-exclamation-triangle me-3 fs-4"></i>
21+
<div class="flex-grow-1">
22+
<h5 class="alert-heading mb-1">Complete Your Project Preferences</h5>
23+
<p class="mb-2">You haven't filled out your project preferences yet. Complete your preferences to get the most out of your experience!</p>
24+
<a href="/join-us/" class="btn btn-warning btn-sm">
25+
<i class="fas fa-plus me-1"></i>Complete Preferences
26+
</a>
27+
</div>
28+
</div>
29+
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
30+
</div>
31+
{% endif %}
32+
1633
<div class="row justify-content-center">
1734
<!-- Left column for profile picture -->
1835
<div class="col-md-5 mb-4">

home/views.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -190,21 +190,21 @@ def get_login_redirect_url(user):
190190
If user hasn't completed join-us form, redirect to /join-us/
191191
If user has completed it, redirect to profile page
192192
"""
193-
# TEMPORARY FIX: Always redirect to dashboard for OAuth users
194-
# This will be refined later to properly detect OAuth vs regular login
195193
print(f"DEBUG: get_login_redirect_url called for user: {user.email}")
196194

197-
# For now, always redirect to dashboard to fix OAuth redirect issue
198-
print(f"DEBUG: get_login_redirect_url - Redirecting to dashboard")
199-
return '/dashboard/'
200-
201-
# Original logic (commented out for now):
202-
# if Student.objects.filter(user=user).exists():
203-
# # User has completed join-us form, redirect to profile
204-
# return '/profile/'
205-
# else:
206-
# # User hasn't completed join-us form, redirect to join-us page
207-
# return '/join-us/'
195+
try:
196+
student = Student.objects.get(user=user)
197+
# Check if user has filled out project preferences
198+
if student.p1 or student.p2 or student.p3:
199+
print(f"DEBUG: User {user.email} has preferences, redirecting to profile")
200+
return '/profile/'
201+
else:
202+
print(f"DEBUG: User {user.email} has no preferences, redirecting to join-us")
203+
return '/join-us/'
204+
except Student.DoesNotExist:
205+
# User hasn't completed join-us form at all
206+
print(f"DEBUG: User {user.email} has no Student record, redirecting to join-us")
207+
return '/join-us/'
208208

209209

210210

@@ -354,10 +354,13 @@ def profile(request):
354354
except Profile.DoesNotExist:
355355
profile = Profile.objects.create(user=request.user)
356356

357-
# Get student object if exists
357+
# Get student object if exists and check preferences
358+
has_preferences = False
358359
try:
359360
student = Student.objects.get(user=request.user)
360361
skill_count = Progress.objects.filter(student=student, completed=True).count()
362+
# Check if user has filled out project preferences
363+
has_preferences = bool(student.p1 or student.p2 or student.p3)
361364
except Student.DoesNotExist:
362365
skill_count = 0
363366

@@ -409,6 +412,7 @@ def profile(request):
409412
'skill_count': skill_count,
410413
'achievement_count': achievement_count,
411414
'completed_challenges': completed_challenges,
415+
'has_preferences': has_preferences,
412416
}
413417

414418
return render(request, 'pages/profile.html', context)
@@ -698,7 +702,7 @@ def verify_otp(request):
698702
User = get_user_model()
699703
try:
700704
user = User.objects.get(id=user_id)
701-
login(request, user)
705+
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
702706
# Clear session data on success
703707
request.session.pop('otp', None)
704708
request.session.pop('user_id', None)
@@ -1126,7 +1130,7 @@ def login_with_passkey(request):
11261130

11271131
if Passkey.objects.filter(user=user, key=passkey).exists():
11281132
request.session['pending_user_id'] = user.id # Store user ID temporarily
1129-
login(request, user)
1133+
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
11301134

11311135
# Save IP and browser info when logging in with passkey
11321136
user.last_login_ip = get_client_ip(request)

0 commit comments

Comments
 (0)