Skip to content
Snippets Groups Projects
Commit 97881815 authored by b5-mohammed's avatar b5-mohammed
Browse files

Merge remote-tracking branch 'origin/main' into main

parents 2b08c68e d9a87c0f
No related branches found
No related tags found
No related merge requests found
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
<style> <style>
nav { nav {
background-image: linear-gradient(to right, #00bfff, #00ffd5); background-image: linear-gradient(to right, #00bfff, #00ffd5);
/*background-color: #344cff;*/
overflow: hidden; overflow: hidden;
} }
nav ul { nav ul {
......
...@@ -9,6 +9,16 @@ ...@@ -9,6 +9,16 @@
{% else %} {% else %}
<p><strong>Group Name:</strong> {{ group.name }}</p> <p><strong>Group Name:</strong> {{ group.name }}</p>
<p><strong>Group ID:</strong> {{ group.id }}</p> <p><strong>Group ID:</strong> {{ group.id }}</p>
<p><strong>Member Count:</strong> {{ group.member_count }}</p>
{% if request.user in group.members.all %}
<p>You’re already a member of this group.</p>
{% else %}
<form method="post">
{% csrf_token %}
<input type="hidden" name="user_id" value="{{ request.user.id }}">
<button type="submit">Join Group</button>
</form>
{% endif %}
{% endif %} {% endif %}
<p><a href="{% url 'group_list' %}">Back to Groups</a></p> <p><a href="{% url 'group_list' %}">Back to Groups</a></p>
</body> </body>
......
...@@ -4,11 +4,57 @@ ...@@ -4,11 +4,57 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Login</title> <title>Login</title>
<style> <style>
body { font-family: Arial, sans-serif; margin: 2em; } body {
.error { color: red; } font-family: Arial, sans-serif;
margin: 0;
display: flex;
height: 100vh;
}
.container {
display: flex;
width: 100%;
}
.left, .right {
width: 50%;
display: flex;
justify-content: center;
align-items: center;
padding: 2em;
}
.left {
background-color: #f8f9fa;
}
.right {
background-image: linear-gradient(to right, #00bfff, #00ffd5);
text-align: center;
}
.error {
color: red;
}
form {
width: 100%;
max-width: 300px;
}
input, button {
width: 100%;
padding: 0.5em;
margin-top: 0.5em;
}
button {
background-color: #007bff;
color: white;
border: none;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
</style> </style>
</head> </head>
<body> <body>
<div class="container">
<div class="left">
<div>
<h1>Login</h1> <h1>Login</h1>
{% if error %} {% if error %}
<p class="error">{{ error }}</p> <p class="error">{{ error }}</p>
...@@ -16,10 +62,10 @@ ...@@ -16,10 +62,10 @@
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
<label for="id_email">Email:</label> <label for="id_email">Email:</label>
<input type="email" name="email" id="id_email" required><br><br> <input type="email" name="email" id="id_email" required><br>
<label for="id_password">Password:</label> <label for="id_password">Password:</label>
<input type="password" name="password" id="id_password" required><br><br> <input type="password" name="password" id="id_password" required><br>
<button type="submit">Login</button> <button type="submit">Login</button>
</form> </form>
...@@ -27,6 +73,14 @@ ...@@ -27,6 +73,14 @@
Don't have an account? Don't have an account?
<a href="{% url 'register' %}">Register here</a>. <a href="{% url 'register' %}">Register here</a>.
</p> </p>
</div>
</div>
<div class="right">
<h1>UniHub</h1>
<p>Where university happens.</p>
</div>
</div>
</body> </body>
</html> </html>
...@@ -95,32 +95,30 @@ def group_delete_view(request, group_id): ...@@ -95,32 +95,30 @@ def group_delete_view(request, group_id):
return render(request, 'myapp/group_delete.html', context) return render(request, 'myapp/group_delete.html', context)
def group_detail_view(request, group_id): def group_detail_view(request, group_id):
"""
Fetch a single group's details using the Rust extension and display them.
"""
db_url = settings.DATABASE_URL db_url = settings.DATABASE_URL
context = {} context = {}
try: if request.method == 'POST':
# Fetch group details user_id = request.POST.get('user_id') # might be None or 'None'
group = rust_crud_api.get_group(db_url, group_id)
if group is None:
return HttpResponseNotFound("Group not found.")
# Fetch group members and member count
members, member_count = rust_crud_api.get_group_members(db_url, group_id)
# Populate context with group details # Check for None *before* calling Rust
context['group'] = group if not user_id or user_id == 'None':
context['members'] = members context['error'] = "Invalid user_id: None"
context['member_count'] = member_count return render(request, 'myapp/group_detail.html', context)
try:
# Now we safely do int(user_id) because we checked it's not None
result = rust_crud_api.add_user_to_group(db_url, int(group_id), int(user_id))
except Exception as e: except Exception as e:
context['error'] = f"An error occurred: {e}" context['error'] = f"An error occurred: {e}"
return render(request, 'myapp/group_detail.html', context)
# Normal GET behavior...
return render(request, 'myapp/group_detail.html', context) return render(request, 'myapp/group_detail.html', context)
def group_search_view(request): def group_search_view(request):
""" """
Handles searching for groups using Rust. Handles searching for groups using Rust.
...@@ -135,4 +133,3 @@ def group_search_view(request): ...@@ -135,4 +133,3 @@ def group_search_view(request):
return render(request, "group_search.html", {"error": str(e), "query": query}) return render(request, "group_search.html", {"error": str(e), "query": query})
return render(request, "group_search.html", {"groups": groups, "query": query}) return render(request, "group_search.html", {"groups": groups, "query": query})
File moved
...@@ -60,17 +60,19 @@ pub fn get_all_groups(db_url: &str) -> PyResult<Vec<Group>> { ...@@ -60,17 +60,19 @@ pub fn get_all_groups(db_url: &str) -> PyResult<Vec<Group>> {
#[pyfunction] #[pyfunction]
pub fn add_user_to_group(db_url: &str, group_id: i32, user_id: i32) -> PyResult<()> { pub fn add_user_to_group(db_url: &str, group_id: i32, user_id: i32) -> PyResult<()> {
let mut client = Client::connect(db_url, NoTls).map_err(pg_err)?; let mut client = Client::connect(db_url, NoTls).map_err(pg_err)?;
// Insert a row to show membership
client.execute( client.execute(
"INSERT INTO group_members (group_id, user_id) VALUES ($1, $2)", "INSERT INTO group_members (group_id, user_id)
&[&group_id, &user_id] VALUES ($1, $2)
).map_err(pg_err)?; ON CONFLICT DO NOTHING",
client.execute( &[&group_id, &user_id],
"UPDATE groups SET member_count = member_count + 1 WHERE id = $1",
&[&group_id]
).map_err(pg_err)?; ).map_err(pg_err)?;
Ok(()) Ok(())
} }
/// Get all members of a group. /// Get all members of a group.
#[pyfunction] #[pyfunction]
pub fn get_group_members(db_url: &str, group_id: i32) -> PyResult<(Vec<User>, i32)> { pub fn get_group_members(db_url: &str, group_id: i32) -> PyResult<(Vec<User>, i32)> {
...@@ -134,3 +136,13 @@ pub fn search_groups(db_url: &str, query: &str) -> PyResult<Vec<Group>> { ...@@ -134,3 +136,13 @@ pub fn search_groups(db_url: &str, query: &str) -> PyResult<Vec<Group>> {
Ok(groups) Ok(groups)
} }
#[pyfunction]
pub fn get_group_member_count(db_url: &str, group_id: i32) -> PyResult<i64> {
let mut client = Client::connect(db_url, NoTls).map_err(pg_err)?;
let row = client.query_one(
"SELECT COUNT(*) FROM group_members WHERE group_id = $1",
&[&group_id]
).map_err(pg_err)?;
Ok(row.get(0)) // returns i64
}
\ No newline at end of file
...@@ -27,7 +27,7 @@ pub fn init_db(db_url: &str) -> PyResult<()> { ...@@ -27,7 +27,7 @@ pub fn init_db(db_url: &str) -> PyResult<()> {
CREATE TABLE IF NOT EXISTS groups ( CREATE TABLE IF NOT EXISTS groups (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL, name VARCHAR NOT NULL,
member_count INTEGER DEFAULT 0 member_count INTEGER NOT NULL DEFAULT 0
); );
CREATE TABLE IF NOT EXISTS group_members ( CREATE TABLE IF NOT EXISTS group_members (
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment