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
27 changes: 22 additions & 5 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,36 @@
#############################################################################

import streamlit as st
from modules import display_my_custom_component, display_post, display_genai_advice, display_activity_summary, display_recent_workouts
from modules import display_my_custom_component, study_group_card, navigation_bar, display_explore_page, display_genai_advice, display_activity_summary, display_recent_workouts
from data_fetcher import get_user_posts, get_genai_advice, get_user_profile, get_user_sensor_data, get_user_workouts

userId = 'user1'


def display_app_page():
"""Displays the home page of the app."""
st.title('Welcome to SDS!')
# Navigation sidebar
st.sidebar.title("Navigation")
page = st.sidebar.radio(
"Go to:",
["Explore Groups", "User Profile", "Recent Groups", "AI Recommendations"]
)

mock_study_groups = [
{"group_title": "Calc II Cram Session", "subject": "Math", "description": "Preparing for midterm", "date": "Oct 12", "time": "4PM", "location": "Library Room 3", "members": "4/6"},
{"group_title": "Bio 101 Lab Prep", "subject": "Science", "description": "Reviewing cell structures", "date": "Oct 13", "time": "2PM", "location": "Science Hall", "members": "2/4"},
{"group_title": "Art History Chat", "subject": "Arts", "description": "Renaissance era discussion", "date": "Oct 15", "time": "11AM", "location": "Cafe Blue", "members": "8/10"},
{"group_title": "Python Basics", "subject": "CS", "description": "Looping and logic", "date": "Oct 16", "time": "6PM", "location": "Zoom", "members": "12/20"},
]
if page == "Explore Groups":
# Run the page
filtered_list = navigation_bar(mock_study_groups)
display_explore_page(filtered_list)

else:
st.title("Study Group Finder!")


# An example of displaying a custom component called "my_custom_component"
value = st.text_input('Enter your name')
display_my_custom_component(value)


# This is the starting point for your app. You do not need to change these lines
Expand Down
135 changes: 132 additions & 3 deletions modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,33 @@
#############################################################################

from internals import create_component
import streamlit as st

# CSS style for modules
st.markdown("""
<style>
.study-card {
border-radius: 18px;
padding: 20px;
background-color: #1e1e1e;
border: 1px solid #333;
margin-bottom: 20px;
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}
.subject-tag {
display: inline-block;
padding: 4px 10px;
border-radius: 12px;
background-color: #2d2d2d;
font-size: 0.8rem;
margin-bottom: 8px;
}
.location {
color: #ff4b4b;
font-weight: 500;
}
</style>
""", unsafe_allow_html=True) # Written by Chat GPT


# This one has been written for you as an example. You may change it as wanted.
Expand All @@ -28,10 +55,112 @@ def display_my_custom_component(value):
html_file_name = "my_custom_component"
create_component(data, html_file_name)

def navigation_bar(full_group_list):
"""
Renders a simple search bar and returns a filtered list of groups.
"""
# Simple search input
search_query = st.text_input(
"Search",
placeholder="Search by title or description...",
label_visibility="collapsed"
)

def display_post(username, user_image, timestamp, content, post_image):
"""Write a good docstring here."""
pass
# Filtering Logic
if not search_query:
return full_group_list

filtered_list = [
group for group in full_group_list
if search_query.lower() in group['group_title'].lower() or
search_query.lower() in group['description'].lower()
]

return filtered_list

def study_group_card(group_title, subject, description, date, time, location, members):
"""
Render a styled study group preview card.

Args

group_title : str
The name of the study group.
subject : str
Academic subject or category label displayed at the top.
description : str
Short summary describing the study group.
date : str
Meeting date (formatted string).
time : str
Meeting time (formatted string).
location : str
Physical or virtual meeting location.
members : str
Current and maximum number of members (e.g., "6/12").
"""

with st.container(border=True):

# Title
st.subheader(group_title)

# Description
st.write(description)

# Date & Time
st.write(f"**Date:** {date}")
st.write(f"**Time:** {time}")

# Location
st.markdown(
f'<div class="location">📍 {location}</div>',
unsafe_allow_html=True
)

# Members
st.write(f"👥 {members} members")

# View Details Button
if st.button("View Details", key=f"btn_{group_title}"):
st.session_state.selected_group = group_title
# st.switch_page("pages/group_page.py")

st.markdown('</div>', unsafe_allow_html=True)

def display_explore_page(group_list):
"""
Render the explore page with study group cards arranged in rows.

Args
group_list : list of dict
Each dictionary should have keys:
'group_title', 'subject', 'description', 'date', 'time', 'location', 'members'
"""
if not group_list:
st.info("No groups found")
return


num_columns = 3 # Number of cards per row
for i in range(0, len(group_list), num_columns):
row_groups = group_list[i:i + num_columns]
cols = st.columns(len(row_groups)) # Column for each card in this row
for col, group in zip(cols, row_groups):
with col:
study_group_card(
group_title=group['group_title'],
subject=group['subject'],
description=group['description'],
date=group['date'],
time=group['time'],
location=group['location'],
members=group['members']
)






def display_activity_summary(workouts_list):
Expand Down
51 changes: 45 additions & 6 deletions modules_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,57 @@
#############################################################################

import unittest
from unittest.mock import MagicMock, patch
import streamlit as st
from streamlit.testing.v1 import AppTest
from modules import display_post, display_activity_summary, display_genai_advice, display_recent_workouts
from modules import display_explore_page, navigation_bar, study_group_card # display_activity_summary, display_genai_advice, display_recent_workouts

# Write your tests below
APP_FILE = "app.py"

class TestDisplayPost(unittest.TestCase):
"""Tests the display_post function."""
class TestDisplayExplorePage(unittest.TestCase):
"""Tests the study group app using Streamlit AppTest."""

def test_foo(self):
"""Tests foo."""
pass
def test_app_initial_load(self):
"""Test that the app loads and displays the initial grid of cards."""
at = AppTest.from_file(APP_FILE).run()

assert not at.exception

assert len(at.text_input) == 1
assert at.text_input[0].placeholder == "Search by title or description..."

def test_search_filtering_logic(self):
"""Test that typing 'Python' in the search bar filters the results."""
at = AppTest.from_file(APP_FILE).run()

at.text_input[0].set_value("Python").run()

assert not at.exception

assert len(at.subheader) == 1
assert at.subheader[0].value == "Python Basics"

def test_search_no_results(self):
"""Test the state when a search matches nothing."""
at = AppTest.from_file(APP_FILE).run()

at.text_input[0].set_value("NonExistentSubject123").run()

assert len(at.info) == 1
assert "No groups found" in at.info[0].value

assert len(at.subheader) == 0

def test_view_details_button(self):
"""Test that clicking 'View Details' works (triggers no errors)."""
at = AppTest.from_file(APP_FILE).run()

at.button[0].click().run()

assert not at.exception

assert at.session_state.selected_group == "Calc II Cram Session"

class TestDisplayActivitySummary(unittest.TestCase):
"""Tests the display_activity_summary function."""
Expand Down