Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion public/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,10 @@ <h1 id="header-welcome" class="text-3xl md:text-4xl lg:text-5xl font-extrabold t
}

// Type icons and colors
const typeIcon = { course: '📚', meetup: '🤝', workshop: '🔧', seminar: '🎤', other: '✨' };
const typeIcon = { course: '📚', study_group: '👥', meetup: '🤝', workshop: '🔧', seminar: '🎤', other: '✨' };
const typeColor = {
course: 'bg-indigo-100 dark:bg-indigo-900/30 text-indigo-700 dark:text-indigo-300',
study_group: 'bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300',
meetup: 'bg-pink-100 dark:bg-pink-900/30 text-pink-700 dark:text-pink-300',
workshop: 'bg-orange-100 dark:bg-orange-900/30 text-orange-700 dark:text-orange-300',
seminar: 'bg-teal-100 dark:bg-teal-900/30 text-teal-700 dark:text-teal-300',
Expand Down
6 changes: 4 additions & 2 deletions public/teach.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ <h1 class="text-4xl md:text-5xl lg:text-6xl font-extrabold text-white leading-ti
Create & Manage Your Activities
</h1>
<p class="text-lg md:text-xl text-orange-50 max-w-2xl mx-auto mb-8">
Host courses, workshops, meetups, clubs, events, videos, and seminars. Reach learners worldwide and build your teaching community.
Host courses, study groups, workshops, meetups, clubs, events, videos, and seminars. Reach learners worldwide and build your teaching community.
</p>
<a href="#host-content" class="inline-flex items-center gap-2 bg-white text-orange-600 font-bold px-8 py-3 rounded-xl shadow-lg hover:shadow-xl hover:-translate-y-1 transition-all duration-300">
<i class="fas fa-arrow-down"></i>
Expand Down Expand Up @@ -128,6 +128,7 @@ <h2 class="font-bold text-lg text-gray-800 dark:text-gray-200 flex items-center
<label class="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">Type</label>
<select id="a-type" class="w-full px-3 py-2.5 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-orange-500 dark:bg-gray-700 dark:text-white text-sm">
<option value="course">📚 Course</option>
<option value="study_group">👥 Study Group</option>
<option value="workshop">🔧 Workshop</option>
<option value="meetup">🤝 Meetup</option>
<option value="seminar">🎤 Seminar</option>
Expand Down Expand Up @@ -278,9 +279,10 @@ <h2 class="font-bold text-lg text-gray-800 dark:text-gray-200 flex items-center
}

// Type icons and colors
const typeIcon = { course: '📚', meetup: '🤝', workshop: '🔧', seminar: '🎤', club: '🏛', event: '📅', video: '🎬', other: '✨' };
const typeIcon = { course: '📚', study_group: '👥', meetup: '🤝', workshop: '🔧', seminar: '🎤', club: '🏛', event: '📅', video: '🎬', other: '✨' };
const typeColor = {
course: 'bg-indigo-100 dark:bg-indigo-900/30 text-indigo-700 dark:text-indigo-300',
study_group: 'bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300',
meetup: 'bg-pink-100 dark:bg-pink-900/30 text-pink-700 dark:text-pink-300',
workshop: 'bg-orange-100 dark:bg-orange-900/30 text-orange-700 dark:text-orange-300',
seminar: 'bg-teal-100 dark:bg-teal-900/30 text-teal-700 dark:text-teal-300',
Expand Down
14 changes: 4 additions & 10 deletions src/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2910,15 +2910,6 @@ async def api_list_subjects(_req, env):
"noun": "posts",
"private": False,
},
"/study-groups": {
"title": "Study Groups",
"kicker": "Learn together",
"description": "Browse study groups and group invitations from the learning community.",
"group": "community",
"models": ["web.StudyGroup", "web.StudyGroupInvite"],
"noun": "groups",
"private": False,
},
"/quizzes": {
"title": "Quizzes",
"kicker": "Assessments",
Expand Down Expand Up @@ -3130,7 +3121,7 @@ def _language_prefixed_target(path: str) -> Optional[str]:

if route in LEGACY_LANGUAGE_ROUTE_ALIASES:
return LEGACY_LANGUAGE_ROUTE_ALIASES[route]
for old_prefix, new_prefix in (("/courses/", "/activity/"), ("/course/", "/activity/"), ("/classes/", "/activity/")):
for old_prefix, new_prefix in (("/courses/", "/activity/"), ("/course/", "/activity/"), ("/classes/", "/activity/"), ("/study-groups/", "/activity/"), ("/study-group/", "/activity/")):
if route.startswith(old_prefix):
return new_prefix + route[len(old_prefix):]

Expand Down Expand Up @@ -6093,6 +6084,9 @@ async def _dispatch(request, env):
route_path = path[:-5] if path.endswith(".html") else path
if len(route_path) > 1 and route_path.endswith("/"):
route_path = route_path.rstrip("/")
m_study_group = re.fullmatch(r"/study-groups?/([^/]+)", route_path)
if method == "GET" and m_study_group:
return _redirect_to_current_route(request, f"/activity/{m_study_group.group(1)}")
if method == "GET" and route_path in ("/activity", "/activity.html"):
Comment thread
Ananya44444 marked this conversation as resolved.
activity_query = parse_qs(urlparse(request.url).query)
if activity_query.get("slug") or activity_query.get("id"):
Expand Down
30 changes: 30 additions & 0 deletions tests/test_dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,33 @@ async def test_post_init_wrong_method_returns_404(self):
req = MockRequest(method="GET", url="http://localhost/api/init")
r = await worker._dispatch(req, env)
assert r.status == 404

# Study groups redirection
class TestStudyGroupRedirection:
async def test_study_groups_serves_static_page(self):
env = make_env()
set_static_content(env, "<html>study groups</html>")
req = MockRequest(method="GET", url="http://localhost/study-groups")
r = await worker._dispatch(req, env)
assert r.status == 200

async def test_study_groups_html_serves_static_page(self):
env = make_env()
set_static_content(env, "<html>study groups</html>")
req = MockRequest(method="GET", url="http://localhost/study-groups.html")
r = await worker._dispatch(req, env)
assert r.status == 200

async def test_study_group_slug_redirects_to_activity_slug(self):
env = make_env()
req = MockRequest(method="GET", url="http://localhost/study-groups/my-awesome-group")
r = await worker._dispatch(req, env)
assert r.status == 302
assert r.headers.get("Location") == "http://localhost/activity/my-awesome-group"
Comment thread
coderabbitai[bot] marked this conversation as resolved.

async def test_study_group_singular_slug_redirects_to_activity_slug(self):
env = make_env()
req = MockRequest(method="GET", url="http://localhost/study-group/my-awesome-group")
r = await worker._dispatch(req, env)
assert r.status == 302
assert r.headers.get("Location") == "http://localhost/activity/my-awesome-group"
Loading