Skip to content

Commit

Permalink
Merge pull request #62 from deepraj21/main
Browse files Browse the repository at this point in the history
feat: adding project section
  • Loading branch information
deepraj21 authored Oct 21, 2024
2 parents 5f744b6 + cc05984 commit 28966b9
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 121 deletions.
2 changes: 2 additions & 0 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Profile from './pages/Profile';
import { Toaster } from "@/components/ui/sonner";
import EditProfileForm from './pages/EditProfileForm';
import { MessagePage } from './pages/MessagePage';
import Projects from './components/Projects/Projects';

const App = () => {

Expand All @@ -21,6 +22,7 @@ const App = () => {
<Route path="/home" element={<Home />} />
<Route path="/settings" element={<EditProfileForm />} />
<Route path="/message" element={<MessagePage/>} />
<Route path="/projects" element={<Projects />} />
<Route path="/u/:username" element={<Profile />} />
<Route path="*" element={<div>404</div>} />
</Routes>
Expand Down
34 changes: 34 additions & 0 deletions client/src/components/Projects/Projects.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
SidebarInset,
SidebarProvider,
SidebarTrigger,
} from "@/components/ui/sidebar"
import { SidebarLeft } from '@/components/Sidebar/Sidebar'

const Projects = () => {
return (
<SidebarProvider>
<SidebarLeft />
<SidebarInset>
<header className="sticky top-0 flex h-14 shrink-0 items-center gap-2 bg-background">
<div className="flex flex-1 items-center gap-2 px-3">
<SidebarTrigger />
</div>
</header>
<main className="flex flex-col flex-grow p-4 overflow-hidden">
<Dashboard />
</main>
</SidebarInset>
</SidebarProvider>
)
}

const Dashboard = () => {
return(
<>
project
</>
)
}

export default Projects
9 changes: 7 additions & 2 deletions client/src/components/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
CircleUser,
Trash2,
LogOut,
MessagesSquare,
type LucideIcon,
} from "lucide-react"

Expand Down Expand Up @@ -68,6 +69,11 @@ export function SidebarLeft({ ...props }: React.ComponentProps<typeof Sidebar>)
{
title: "Message",
url: "/message",
icon: MessagesSquare,
},
{
title: "Projects",
url: "/projects",
icon: Inbox,
},
],
Expand Down Expand Up @@ -155,7 +161,7 @@ function NavSecondary({
url: string
icon: LucideIcon
badge?: React.ReactNode
onClick?: React.MouseEventHandler<HTMLAnchorElement> // Add onClick type
onClick?: React.MouseEventHandler<HTMLAnchorElement>
}[]
} & React.ComponentPropsWithoutRef<typeof SidebarGroup>) {
return (
Expand All @@ -165,7 +171,6 @@ function NavSecondary({
{items.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton asChild>
{/* Handle click if provided */}
<a href={item.url} onClick={item.onClick}>
<item.icon />
<span>{item.title}</span>
Expand Down
19 changes: 4 additions & 15 deletions client/src/pages/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,8 @@ const Dashboard = () => {
setProfileData(profileResponse.data);

const friendsResponse = await axios.get(`${backendUrl}/profile/${username}/friends`);
setFriendsList(friendsResponse.data.friends); // Set the visited user's friends list
setFriendsList(friendsResponse.data.friends);

// Check if logged-in user is a friend of the profile user
const loggedInFriendsResponse = await axios.get(`${backendUrl}/profile/${loggedInUsername}/friends`);
const isFriendOfProfileUser = loggedInFriendsResponse.data.friends.includes(username);
setIsFriend(isFriendOfProfileUser);
Expand Down Expand Up @@ -171,22 +170,19 @@ const Dashboard = () => {
const handleFriendRequest = async () => {
try {
if (isFriend) {
// Disconnect if already a friend
await axios.delete(`${backendUrl}/profile/${profileData?.username}/friends`, { data: { friend_username: loggedInUsername } });
setIsFriend(false);
if (username) { // Ensure username is defined
if (username) {
dispatch(setFriendStatus({ username, isFriend: false }));
}
} else {
// Connect if not a friend
await axios.post(`${backendUrl}/profile/${profileData?.username}/friends`, { friend_username: loggedInUsername });
setIsFriend(true);
if (username) { // Ensure username is defined
if (username) {
dispatch(setFriendStatus({ username, isFriend: true }));
}
}

// Fetch the updated friends list for the visited user
const friendsResponse = await axios.get(`${backendUrl}/profile/${username}/friends`);
setFriendsList(friendsResponse.data.friends);
} catch (error) {
Expand All @@ -203,7 +199,6 @@ const Dashboard = () => {
return (
<div className='flex flex-col w-full h-screen bg-neutral-50 p-4 overflow-y-auto bg-white dark:bg-zinc-950'>
<div className='grid gap-6 min-h-screen grid-cols-1 lg:grid-cols-[350px_1fr_300px] lg:px-6 xl:gap-10 w-full'>
{/* Sidebar */}
<div className='space-y-6 py-6 rounded-2xl border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-zinc-900 px-2 '>
<div className='flex flex-col items-center space-y-3'>
{githubData ? (
Expand Down Expand Up @@ -234,7 +229,6 @@ const Dashboard = () => {
</p>
</div>
</div>
{/* Profile Info Section */}
<div className='space-y-4'>
<div className='space-y-2'>
<p className='font-semibold'>Bio</p>
Expand All @@ -258,7 +252,6 @@ const Dashboard = () => {
)}
</div>
</div>
{/* GitHub and LeetCode Links */}
<div className='flex space-x-4'>
{profileData ? (
<>
Expand Down Expand Up @@ -310,14 +303,13 @@ const Dashboard = () => {
</div>
)}
</div>
{/* Friend Button */}

{!isOwnProfile && (
<button onClick={handleFriendRequest} className="bg-blue-500 text-white rounded py-2 px-4">
{isFriend ? 'Disconnect' : 'Connect'}
</button>
)}

{/* Friends List */}
<div>
<h2 className='text-xl font-bold'>Friends</h2>
{friends.length > 0 ? (
Expand All @@ -330,10 +322,7 @@ const Dashboard = () => {
</div>
</div>

{/* Main Content Section */}
<div className='space-y-6 col-span-2 rounded-2xl border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-zinc-900 p-4'>
{/* Friends Section */}

<h2 className='text-xl font-bold'>Projects</h2>
<div className='grid grid-cols-1 md:grid-cols-2 gap-4'>
{profileData ? (
Expand Down
96 changes: 96 additions & 0 deletions server/api/handlers/projects/projects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
from flask import request, jsonify, current_app
from models import Project
from extensions import neo4j_db

def add_project(username):
data = request.get_json()

# Get project details from request
title = data.get('title')
description = data.get('description', '')
repo_link = data.get('repo_link', '')
tags = data.get('tags', '')

# Define a query to create a project without tags initially
create_project_query = """
MATCH (u:User {username: $username})
CREATE (p:Project {title: $title, description: $description, repo_link: $repo_link, tags: $tags})
CREATE (u)-[:OWNS]->(p)
RETURN p
"""

try:
with neo4j_db.driver.session() as session:
# Create the project
result = session.run(create_project_query, username=username, title=title, description=description, repo_link=repo_link, tags=tags)
project_record = result.single()

if project_record:
project = project_record["p"]

domain_tags = [tag for tag in tags.split(',') if tag.strip() in tags]

# Update project with tags
update_project_query = """
MATCH (p:Project {title: $title, description: $description, repo_link: $repo_link})
WITH p, $tags AS tags
UNWIND tags AS tagName
MERGE (t:Tag {name: tagName})
CREATE (p)-[:TAGGED_WITH]->(t)
RETURN p
"""

# Update the project with tags
session.run(update_project_query, title=title, description=description, repo_link=repo_link, tags=domain_tags)

return jsonify({'message': 'Project added and categorized successfully', 'project': {
'title': project["title"],
'description': project.get("description", ""),
'repoLink': project.get("repo_link", ""),
'tags': domain_tags
}}), 201
else:
return jsonify({'message': 'User not found'}), 404
except Exception as e:
current_app.logger.error(f"Error adding project: {e}")
return jsonify({'message': 'An error occurred while adding the project'}), 500



def update_project(username, project_id):
data = request.get_json()
title = data.get('title')
description = data.get('description')
repo_link = data.get('repo_link')
tags = data.get('tags', '')

query = """
MATCH (u:User {username: $username})-[:OWNS]->(p:Project {id: $project_id})
SET p.title = $title, p.description = $description, p.repo_link = $repo_link
WITH p
OPTIONAL MATCH (p)-[r:TAGGED_WITH]->(t:Tag)
DELETE r
WITH p
UNWIND $tags AS tagName
MERGE (t:Tag {name: tagName})
CREATE (p)-[:TAGGED_WITH]->(t)
RETURN p
"""
with neo4j_db.driver.session() as session:
result = session.run(query, username=username, project_id=project_id, title=title, description=description, repo_link=repo_link, tags=tags.split(', ') if tags else [])
if result.single():
return jsonify({'message': 'Project updated successfully'}), 200
return jsonify({'message': 'Project or user not found'}), 404

def delete_project(username, project_title):
query = """
MATCH (u:User {username: $username})-[:OWNS]->(p:Project {title: $project_title})
OPTIONAL MATCH (p)-[r]-()
DELETE r, p
RETURN u
"""
with neo4j_db.driver.session() as session:
result = session.run(query, username=username, project_title=project_title)
if result.single():
return jsonify({'message': 'Project deleted successfully'}), 200
return jsonify({'message': 'Project or user not found'}), 404
98 changes: 1 addition & 97 deletions server/api/handlers/user/profile.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
from flask import request, jsonify, current_app
from flask import request, jsonify
from extensions import neo4j_db
from models import User, Project, Tag
from sqlalchemy.orm import sessionmaker
import os

def get_profile(username):
logged_in_user = request.args.get('logged_in_user')
Expand Down Expand Up @@ -41,7 +38,6 @@ def get_profile(username):
profile_data['projects'] = projects

if logged_in_user:
# Check if the logged-in user is friends with the profile user
friendship_query = """
MATCH (u1:User {username: $logged_in_user})-[:FRIEND]->(u2:User {username: $username})
RETURN COUNT(u1) > 0 AS isFriend
Expand Down Expand Up @@ -71,95 +67,3 @@ def update_profile(username):
return jsonify({'message': 'Profile updated successfully'}), 200
return jsonify({'message': 'User not found'}), 404

def add_project(username):
data = request.get_json()

# Get project details from request
title = data.get('title')
description = data.get('description', '')
repo_link = data.get('repo_link', '')
tags = data.get('tags', '')

# Define a query to create a project without tags initially
create_project_query = """
MATCH (u:User {username: $username})
CREATE (p:Project {title: $title, description: $description, repo_link: $repo_link, tags: $tags})
CREATE (u)-[:OWNS]->(p)
RETURN p
"""

try:
with neo4j_db.driver.session() as session:
# Create the project
result = session.run(create_project_query, username=username, title=title, description=description, repo_link=repo_link, tags=tags)
project_record = result.single()

if project_record:
project = project_record["p"]

domain_tags = [tag for tag in tags.split(',') if tag.strip() in tags]

# Update project with tags
update_project_query = """
MATCH (p:Project {title: $title, description: $description, repo_link: $repo_link})
WITH p, $tags AS tags
UNWIND tags AS tagName
MERGE (t:Tag {name: tagName})
CREATE (p)-[:TAGGED_WITH]->(t)
RETURN p
"""

# Update the project with tags
session.run(update_project_query, title=title, description=description, repo_link=repo_link, tags=domain_tags)

return jsonify({'message': 'Project added and categorized successfully', 'project': {
'title': project["title"],
'description': project.get("description", ""),
'repoLink': project.get("repo_link", ""),
'tags': domain_tags
}}), 201
else:
return jsonify({'message': 'User not found'}), 404
except Exception as e:
current_app.logger.error(f"Error adding project: {e}")
return jsonify({'message': 'An error occurred while adding the project'}), 500



def update_project(username, project_id):
data = request.get_json()
title = data.get('title')
description = data.get('description')
repo_link = data.get('repo_link')
tags = data.get('tags', '')

query = """
MATCH (u:User {username: $username})-[:OWNS]->(p:Project {id: $project_id})
SET p.title = $title, p.description = $description, p.repo_link = $repo_link
WITH p
OPTIONAL MATCH (p)-[r:TAGGED_WITH]->(t:Tag)
DELETE r
WITH p
UNWIND $tags AS tagName
MERGE (t:Tag {name: tagName})
CREATE (p)-[:TAGGED_WITH]->(t)
RETURN p
"""
with neo4j_db.driver.session() as session:
result = session.run(query, username=username, project_id=project_id, title=title, description=description, repo_link=repo_link, tags=tags.split(', ') if tags else [])
if result.single():
return jsonify({'message': 'Project updated successfully'}), 200
return jsonify({'message': 'Project or user not found'}), 404

def delete_project(username, project_title):
query = """
MATCH (u:User {username: $username})-[:OWNS]->(p:Project {title: $project_title})
OPTIONAL MATCH (p)-[r]-()
DELETE r, p
RETURN u
"""
with neo4j_db.driver.session() as session:
result = session.run(query, username=username, project_title=project_title)
if result.single():
return jsonify({'message': 'Project deleted successfully'}), 200
return jsonify({'message': 'Project or user not found'}), 404
3 changes: 2 additions & 1 deletion server/api/urls.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from api.handlers.auth.userauth import signup, login, check_auth, home, logout, index, check_username
from api.handlers.user.profile import get_profile, update_profile, add_project, update_project, delete_project
from api.handlers.user.profile import get_profile, update_profile
from api.handlers.projects.projects import add_project, update_project, delete_project
from api.handlers.analyze.githubdata import github_data, top_languages, streak_stats, pinned_repos, streak_chart
from api.handlers.analyze.leetcodedata import leetcode_data, leetcode_card
from api.handlers.query.querymodel import chat,chat_history
Expand Down
Loading

0 comments on commit 28966b9

Please sign in to comment.