Skip to content
Open
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
4 changes: 2 additions & 2 deletions backend-api/app/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ class ProfileAutofillAnswer(db.Model):
class Job(db.Model):
__tablename__ = 'Job'
JobID = db.Column(db.Integer, primary_key=True, autoincrement=True)
Salary = db.Column(db.Numeric(10,2))
Salary = db.Column(db.String(50))
Type = db.Column(db.String(50))
Keywords = db.Column(db.Text)
Description = db.Column(db.Text)
Date = db.Column(db.Date, server_default=db.func.current_date())
CompanyName = db.Column(db.String(50))
CompanyName = db.Column(db.String(100))
UserID = db.Column(db.Integer, ForeignKey('Users.UserID', ondelete='SET NULL'))
applications = relationship('AppliedTo', backref='job', cascade="all, delete")
bookmarks = relationship('Bookmark', backref='job', cascade="all, delete")
Expand Down
30 changes: 19 additions & 11 deletions backend-api/app/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ def delete_profile(profile_id):

@bp.route('/jobs', methods=['POST'])
def create_job():
print("Job creation route hit")
data = request.get_json()
user_id = data.get('UserID')
user = User.query.get_or_404(user_id)
Expand Down Expand Up @@ -265,15 +266,18 @@ def create_application():
'FollowUpDeadline': application.FollowUpDeadline
}), 201

@bp.route('/applications/<int:application_id>', methods=['GET'])
def get_application(application_id):
application = AppliedTo.query.get_or_404(application_id)
return jsonify({
'ApplicationID': application.ApplicationID,
'Status': application.Status,
'FollowUpDeadline': application.FollowUpDeadline,
'Note': application.Note
})
@bp.route('/applications/user/<int:user_id>', methods=['GET'])
def get_applications_for_user(user_id):
applications = db.session.query(AppliedTo).filter(AppliedTo.UserID == user_id).all()
return jsonify([
{
'ApplicationID': application.ApplicationID,
'Status': application.Status,
'FollowUpDeadline': application.FollowUpDeadline,
'Note': application.Note
}
for application in applications
])

@bp.route('/applications/<int:application_id>', methods=['PUT'])
def update_application(application_id):
Expand Down Expand Up @@ -344,6 +348,11 @@ def create_bookmark():
user = User.query.get_or_404(user_id)
job = Job.query.get_or_404(job_id)

# Check if the bookmark already exists
existing_bookmark = Bookmark.query.filter_by(UserID=user.UserID, JobID=job.JobID).first()
if existing_bookmark:
return jsonify({"message": "Bookmark already exists"}), 200

bookmark = Bookmark(
UserID=user.UserID,
JobID=job.JobID,
Expand All @@ -365,9 +374,8 @@ def get_bookmarks(user_id):
bookmark_list = []
for bookmark, job in bookmarks:
bookmark_list.append({
'UserID': bookmark.UserID,
'JobID': bookmark.JobID,
'Note': bookmark.Note if bookmark.Note else "No note",
'Note': bookmark.Note or "No note",
'CompanyName': job.CompanyName,
'Type': job.Type
})
Expand Down
Binary file modified backend-api/instance/database.db
Binary file not shown.
23 changes: 18 additions & 5 deletions backend-api/run.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
# Runs instance of app

from app import create_app
from app.database import db
from app.database import db, User
from sqlalchemy import inspect
import os

app = create_app()

def create_test_user():
existing = User.query.filter_by(Email="[email protected]").first()
if not existing:
user = User(
Name="Test User",
Email="[email protected]",
Password="password123"
)
db.session.add(user)
db.session.commit()
print(f"Test user created with UserID {user.UserID}")
else:
print("Test user already exists.")

if __name__ == '__main__':
# Use the PORT environment variable if defined, otherwise default to 5000.
port = int(os.environ.get("PORT", 5000))
# Creates database tables
with app.app_context():
db.create_all()
inspector = inspect(db.engine)
print(inspector.get_table_names())
# Bind to all interfaces to allow external access.
print("Database tables:", inspector.get_table_names())
create_test_user()

app.run(host='0.0.0.0', port=port, debug=True)

8 changes: 5 additions & 3 deletions frontend/app/pages/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@ export default function Dashboard() {
const [error, setError] = useState<string | null>(null);

useEffect(() => {
const fetchNotifications = axios.get(`/api/applied_to/${userId}`);
const fetchBookmarks = axios.get(`/api/bookmarks/${userId}`);

const fetchNotifications = axios.get(`http://localhost:5000/api/applications/user/${userId}`);
const fetchBookmarks = axios.get(`http://localhost:5000/api/bookmarks/${userId}`);
Promise.all([fetchNotifications, fetchBookmarks])
.then(([notificationsRes, bookmarksRes]) => {
console.log("Fetched applications from API:", notificationsRes.data); // Debugging log
console.log("Fetched bookmarks from API:", bookmarksRes.data); // Debugging log
setNotifications(Array.isArray(notificationsRes.data) ? notificationsRes.data : []);
setBookmarks(Array.isArray(bookmarksRes.data) ? bookmarksRes.data : []);
})
Expand Down
51 changes: 50 additions & 1 deletion frontend/app/pages/Postings.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Box, Typography, Card, CardContent, Button, TextField, Grid } from "@mui/material";
import { useState } from "react";
import jobData from "../../dataset_indeed-scraper_2025-04-29_18-38-42-368.json";
import axios from "axios";
import jobData from "../../dataset_indeed-scraper_2025-04-29_18-38-42-368.json"; // Mock job data

export default function Postings() {
const [filters, setFilters] = useState({
Expand Down Expand Up @@ -83,6 +84,44 @@ function JobDetails({ job }: { job: any }) {
setShowFullDescription(!showFullDescription);
};

const handleBookmark = () => {
// Step 1: Create the job
axios
.post("http://localhost:5000/api/jobs", {
Salary: job.salary || "Not specified",
Type: job.positionName,
Keywords: job.keywords || "",
Description: job.description,
CompanyName: job.company,
UserID: 1, // Replace with actual user ID
})
.then((createdJobResponse) => {
console.log("Job created successfully:", createdJobResponse.data);
createBookmark(createdJobResponse.data);
})
.catch((err) => {
console.error("Failed to create job:", err);
alert("Failed to create job and bookmark.");
});

function createBookmark(jobData: any) {
console.log("Creating bookmark for job:", jobData);
axios
.post("http://localhost:5000/api/bookmarks", {
UserID: 1, // Replace with real user ID
JobID: jobData.JobID, // This is the actual JobID from the DB
Note: "Bookmarked from UI",
})
.then(() => {
alert("Job bookmarked!");
})
.catch((err) => {
console.error("Failed to bookmark:", err);
alert("Failed to bookmark job.");
});
}
};

return (
<Card>
<CardContent>
Expand Down Expand Up @@ -135,6 +174,16 @@ function JobDetails({ job }: { job: any }) {
Apply Here
</Button>
</Box>
<Box sx={{ marginTop: 1 }}>
<Button
size="small"
variant="contained"
color="primary"
onClick={handleBookmark}
>
Bookmark Job
</Button>
</Box>
</CardContent>
</Card>
);
Expand Down