Spaces:
Sleeping
Sleeping
Upload 12 files
Browse files- .env +13 -0
- app.py +1197 -0
- requirements.txt +8 -0
- static/css/style.css +364 -0
- students.csv +1316 -0
- templates/404.html +10 -0
- templates/500.html +11 -0
- templates/base.html +53 -0
- templates/company_dashboard.html +890 -0
- templates/company_login.html +458 -0
- templates/job_details.html +820 -0
- templates/jobs.html +547 -0
.env
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
GEMINI_API_KEY = "AIzaSyAX6kFj6BqnY_5pBr54saD52svAJLg1Bjo"
|
| 2 |
+
# Supabase Credentials
|
| 3 |
+
SUPABASE_URL=https://dbbomivlqhbgpgqrmfwj.supabase.co
|
| 4 |
+
SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImRiYm9taXZscWhiZ3BncXJtZndqIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc0NTMwNTY0OCwiZXhwIjoyMDYwODgxNjQ4fQ.faROkreac8Ojv_HWNnwHCT0hj19uTVgE8ekRONefvvA
|
| 5 |
+
# SUPABASE_KEY=qHgLNbTYUu86Z4YU
|
| 6 |
+
|
| 7 |
+
ADMIN_PORTAL_SECRET_KEY=a_different_very_strong_random_secret_key # Generate a unique key
|
| 8 |
+
|
| 9 |
+
# Add these to your .env file
|
| 10 |
+
SMTP_SERVER=smtp.gmail.com
|
| 11 |
+
SMTP_PORT=587
|
| 12 |
+
SMTP_USERNAME=pranitchilbule1@gmail.com
|
| 13 |
+
SMTP_PASSWORD=ljaqimdjyqitltnc
|
app.py
ADDED
|
@@ -0,0 +1,1197 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# app.py (Company Portal)
|
| 2 |
+
import os
|
| 3 |
+
import pandas as pd
|
| 4 |
+
import smtplib
|
| 5 |
+
from email.mime.text import MIMEText
|
| 6 |
+
from email.mime.multipart import MIMEMultipart
|
| 7 |
+
import json
|
| 8 |
+
import io
|
| 9 |
+
import numpy as np
|
| 10 |
+
import hashlib
|
| 11 |
+
from datetime import datetime
|
| 12 |
+
|
| 13 |
+
year = datetime.now().year
|
| 14 |
+
import re
|
| 15 |
+
from flask import Flask, render_template, request, redirect, url_for, session, jsonify, send_file, flash, make_response
|
| 16 |
+
import google.generativeai as genai
|
| 17 |
+
from datetime import datetime
|
| 18 |
+
from supabase import create_client, Client
|
| 19 |
+
from dotenv import load_dotenv
|
| 20 |
+
|
| 21 |
+
load_dotenv()
|
| 22 |
+
|
| 23 |
+
app = Flask(__name__)
|
| 24 |
+
app.secret_key = os.getenv("COMPANY_PORTAL_SECRET_KEY", os.urandom(24))
|
| 25 |
+
|
| 26 |
+
# --- Supabase Client Initialization ---
|
| 27 |
+
supabase_url = os.getenv("SUPABASE_URL")
|
| 28 |
+
supabase_key = os.getenv("SUPABASE_KEY")
|
| 29 |
+
|
| 30 |
+
if not supabase_url or not supabase_key:
|
| 31 |
+
print("CRITICAL ERROR: SUPABASE_URL and SUPABASE_KEY environment variables are required.")
|
| 32 |
+
supabase: Client = None
|
| 33 |
+
else:
|
| 34 |
+
try:
|
| 35 |
+
supabase: Client = create_client(supabase_url, supabase_key)
|
| 36 |
+
print("Supabase client initialized successfully for Company Portal.")
|
| 37 |
+
except Exception as e:
|
| 38 |
+
print(f"CRITICAL ERROR: Error initializing Supabase client for Company Portal: {e}")
|
| 39 |
+
supabase = None
|
| 40 |
+
|
| 41 |
+
# --- Gemini API Configuration ---
|
| 42 |
+
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
|
| 43 |
+
HAS_GEMINI = False
|
| 44 |
+
if GEMINI_API_KEY:
|
| 45 |
+
try:
|
| 46 |
+
genai.configure(api_key=GEMINI_API_KEY)
|
| 47 |
+
HAS_GEMINI = True
|
| 48 |
+
print("Gemini API Configured.")
|
| 49 |
+
except Exception as e:
|
| 50 |
+
print(f"Warning: Error configuring Gemini API: {e}. AI Insights & NL Query may fail.")
|
| 51 |
+
else:
|
| 52 |
+
print("Warning: GEMINI_API_KEY not found in .env file. AI Insights & NL Query will not work.")
|
| 53 |
+
|
| 54 |
+
# --- Helper Functions ---
|
| 55 |
+
|
| 56 |
+
def verify_password(stored_hash, password):
|
| 57 |
+
"""Verifies a password against a stored SHA256 hash."""
|
| 58 |
+
input_hash = hashlib.sha256(password.encode()).hexdigest()
|
| 59 |
+
return input_hash == stored_hash
|
| 60 |
+
|
| 61 |
+
def load_student_data():
|
| 62 |
+
"""Loads all student data from the Supabase 'students' table."""
|
| 63 |
+
if not supabase:
|
| 64 |
+
flash("Database connection error. Cannot load student data.", "danger")
|
| 65 |
+
return pd.DataFrame()
|
| 66 |
+
|
| 67 |
+
try:
|
| 68 |
+
response = supabase.table('students').select('*').execute()
|
| 69 |
+
if response.data:
|
| 70 |
+
df = pd.DataFrame(response.data)
|
| 71 |
+
numeric_cols = ['cgpa', 'backlogs', 'typing_speed']
|
| 72 |
+
for col in numeric_cols:
|
| 73 |
+
if col in df.columns:
|
| 74 |
+
# Coerce errors to NaN, then handle NaN later if needed
|
| 75 |
+
df[col] = pd.to_numeric(df[col], errors='coerce')
|
| 76 |
+
if 'backlogs' in df.columns:
|
| 77 |
+
# Fill NaN with 0 before converting to int
|
| 78 |
+
df['backlogs'] = df['backlogs'].fillna(0).astype(int)
|
| 79 |
+
# Example of how you might handle array columns if stored as strings (adjust based on DB schema)
|
| 80 |
+
# list_cols = ['programming_languages', 'tools_technologies', 'soft_skills', 'preferred_roles', 'certifications']
|
| 81 |
+
# for col in list_cols:
|
| 82 |
+
# if col in df.columns and df[col].dtype == 'object':
|
| 83 |
+
# # Attempt to parse comma-separated string or already list-like structure
|
| 84 |
+
# df[col] = df[col].apply(lambda x: [i.strip() for i in str(x).split(',')] if pd.notna(x) and isinstance(x, str) else x)
|
| 85 |
+
|
| 86 |
+
print(f"Loaded {len(df)} student records.") # Debug
|
| 87 |
+
return df
|
| 88 |
+
else:
|
| 89 |
+
print("No student data found in Supabase.") # Debug
|
| 90 |
+
return pd.DataFrame()
|
| 91 |
+
except Exception as e:
|
| 92 |
+
print(f"Error loading student data from Supabase: {e}")
|
| 93 |
+
flash(f"Error loading student data: {e}", "danger")
|
| 94 |
+
return pd.DataFrame()
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
def send_job_email(job_data):
|
| 98 |
+
"""Sends job posting details via email."""
|
| 99 |
+
try:
|
| 100 |
+
# Email configuration from environment variables
|
| 101 |
+
smtp_server = os.getenv("SMTP_SERVER")
|
| 102 |
+
smtp_port = int(os.getenv("SMTP_PORT", 0))
|
| 103 |
+
smtp_username = os.getenv("SMTP_USERNAME")
|
| 104 |
+
smtp_password = os.getenv("SMTP_PASSWORD")
|
| 105 |
+
if not all([smtp_server, smtp_port, smtp_username, smtp_password]):
|
| 106 |
+
raise RuntimeError("SMTP credentials are missing or invalid in .env")
|
| 107 |
+
# Recipient email
|
| 108 |
+
recipient_email ="pranit.chilbule221@vit.edu"
|
| 109 |
+
|
| 110 |
+
# Create message
|
| 111 |
+
msg = MIMEMultipart()
|
| 112 |
+
msg['From'] = smtp_username
|
| 113 |
+
msg['To'] = recipient_email
|
| 114 |
+
msg['Subject'] = f"New Job Posting: {job_data['title']}"
|
| 115 |
+
|
| 116 |
+
# Email body
|
| 117 |
+
body = f"""
|
| 118 |
+
<html lang="en">
|
| 119 |
+
<head>
|
| 120 |
+
<meta charset="UTF-8">
|
| 121 |
+
<title>New Job Posting</title>
|
| 122 |
+
</head>
|
| 123 |
+
<body style="margin:0;padding:0;background-color:#f4f4f4;font-family:Arial,sans-serif;">
|
| 124 |
+
<!--[if mso]>
|
| 125 |
+
<style>
|
| 126 |
+
body, table, td {{
|
| 127 |
+
font-family: Arial, sans-serif !important;
|
| 128 |
+
}}
|
| 129 |
+
</style>
|
| 130 |
+
<![endif]-->
|
| 131 |
+
|
| 132 |
+
<table width="100%" cellpadding="0" cellspacing="0" role="presentation">
|
| 133 |
+
<tr>
|
| 134 |
+
<td align="center" style="padding:20px 0;">
|
| 135 |
+
<table width="600" cellpadding="0" cellspacing="0" role="presentation"
|
| 136 |
+
style="background-color:#ffffff;border-radius:8px;overflow:hidden;
|
| 137 |
+
box-shadow:0 2px 6px rgba(0,0,0,0.1);">
|
| 138 |
+
|
| 139 |
+
<!-- Header -->
|
| 140 |
+
<tr>
|
| 141 |
+
<td style="background-color:#004aad;padding:20px;text-align:center;color:#ffffff;">
|
| 142 |
+
<h1 style="margin:0;font-size:24px;line-height:28px;">New Job Posting</h1>
|
| 143 |
+
</td>
|
| 144 |
+
</tr>
|
| 145 |
+
|
| 146 |
+
<!-- Body content -->
|
| 147 |
+
<tr>
|
| 148 |
+
<td style="padding:30px;">
|
| 149 |
+
<p style="margin:0 0 16px;font-size:16px;line-height:22px;">
|
| 150 |
+
Hello Team,
|
| 151 |
+
</p>
|
| 152 |
+
|
| 153 |
+
<table width="100%" cellpadding="0" cellspacing="0" role="presentation"
|
| 154 |
+
style="margin-bottom:24px;">
|
| 155 |
+
<tr>
|
| 156 |
+
<td style="padding:8px 0;font-weight:bold;width:30%;">Title:</td>
|
| 157 |
+
<td style="padding:8px 0;">{job_data['title']}</td>
|
| 158 |
+
</tr>
|
| 159 |
+
<tr style="background-color:#f9f9f9;">
|
| 160 |
+
<td style="padding:8px 0;font-weight:bold;">Location:</td>
|
| 161 |
+
<td style="padding:8px 0;">{job_data['location']}</td>
|
| 162 |
+
</tr>
|
| 163 |
+
<tr>
|
| 164 |
+
<td style="padding:8px 0;font-weight:bold;">Required Skills:</td>
|
| 165 |
+
<td style="padding:8px 0;">{', '.join(job_data['required_skills'])}</td>
|
| 166 |
+
</tr>
|
| 167 |
+
<tr style="background-color:#f9f9f9;">
|
| 168 |
+
<td style="padding:8px 0;font-weight:bold;">Minimum CGPA:</td>
|
| 169 |
+
<td style="padding:8px 0;">
|
| 170 |
+
{job_data['min_cgpa'] if job_data['min_cgpa'] else 'Not specified'}
|
| 171 |
+
</td>
|
| 172 |
+
</tr>
|
| 173 |
+
<tr>
|
| 174 |
+
<td style="padding:8px 0;font-weight:bold;">Experience Level:</td>
|
| 175 |
+
<td style="padding:8px 0;">{job_data['experience_level']} year(s)</td>
|
| 176 |
+
</tr>
|
| 177 |
+
</table>
|
| 178 |
+
|
| 179 |
+
<p style="margin:0 0 8px;font-weight:bold;font-size:16px;">Description:</p>
|
| 180 |
+
<p style="margin:0 0 24px;font-size:15px;line-height:21px;">
|
| 181 |
+
{job_data['description']}
|
| 182 |
+
</p>
|
| 183 |
+
<a href="https://docs.google.com/forms/d/e/1FAIpQLSdcm0zkEqZjb1sDBaytj9ITLOX8L0LTD81HczJxRAS7LfvSKA/viewform?usp=header" target="_blank">
|
| 184 |
+
<button style="padding: 10px 20px; font-size: 16px; border-radius: 8px; background-color: #4CAF50; color: white; border: none; cursor: pointer;">
|
| 185 |
+
Fill Out the Form
|
| 186 |
+
</button>
|
| 187 |
+
</a>
|
| 188 |
+
|
| 189 |
+
<p style="margin:0;font-size:14px;color:#777777;line-height:20px;">
|
| 190 |
+
This is an automated message from the Company Portal.
|
| 191 |
+
</p>
|
| 192 |
+
</td>
|
| 193 |
+
</tr>
|
| 194 |
+
|
| 195 |
+
<!-- Footer -->
|
| 196 |
+
<tr>
|
| 197 |
+
<td style="background-color:#f4f4f4;padding:15px;
|
| 198 |
+
text-align:center;font-size:12px;color:#999999;">
|
| 199 |
+
© {year} Your Company Name. All rights reserved.
|
| 200 |
+
</td>
|
| 201 |
+
</tr>
|
| 202 |
+
|
| 203 |
+
</table>
|
| 204 |
+
</td>
|
| 205 |
+
</tr>
|
| 206 |
+
</table>
|
| 207 |
+
</body>
|
| 208 |
+
</html>
|
| 209 |
+
"""
|
| 210 |
+
|
| 211 |
+
msg.attach(MIMEText(body, 'html'))
|
| 212 |
+
|
| 213 |
+
# Connect to SMTP server and send
|
| 214 |
+
with smtplib.SMTP(smtp_server, smtp_port) as server:
|
| 215 |
+
server.ehlo() # Identify ourselves to SMTP
|
| 216 |
+
server.starttls() # Upgrade to secure TLS
|
| 217 |
+
server.ehlo() # Re-identify after STARTTLS
|
| 218 |
+
server.login(smtp_username, smtp_password)
|
| 219 |
+
server.send_message(msg)
|
| 220 |
+
|
| 221 |
+
print(f"Email sent successfully to {recipient_email}")
|
| 222 |
+
return True
|
| 223 |
+
except Exception as e:
|
| 224 |
+
print(f"Error sending email: {e}")
|
| 225 |
+
import traceback
|
| 226 |
+
traceback.print_exc()
|
| 227 |
+
return False
|
| 228 |
+
|
| 229 |
+
|
| 230 |
+
def get_unique_values(df, column):
|
| 231 |
+
"""Gets unique, sorted, non-empty values from a DataFrame column, handling comma-separated strings and lists."""
|
| 232 |
+
values = set()
|
| 233 |
+
if column in df.columns and not df[column].isnull().all():
|
| 234 |
+
for item in df[column].dropna():
|
| 235 |
+
item_str = str(item).strip()
|
| 236 |
+
if item_str:
|
| 237 |
+
# Handle actual lists (from DB array type) or comma-separated strings
|
| 238 |
+
if isinstance(item, list):
|
| 239 |
+
# Ensure items in list are strings and clean them (remove proficiency)
|
| 240 |
+
values.update(str(x).split('(')[0].strip() for x in item if x and str(x).strip())
|
| 241 |
+
elif ',' in item_str:
|
| 242 |
+
# Strip proficiency like " (Beginner)"
|
| 243 |
+
values.update(x.split('(')[0].strip() for x in item_str.split(',') if x.strip())
|
| 244 |
+
else:
|
| 245 |
+
# Strip proficiency like " (Beginner)"
|
| 246 |
+
values.add(item_str.split('(')[0].strip())
|
| 247 |
+
return sorted(list(values))
|
| 248 |
+
|
| 249 |
+
|
| 250 |
+
def filter_students(df, filters):
|
| 251 |
+
"""Filters the student DataFrame based on various criteria including job requirements."""
|
| 252 |
+
if df.empty:
|
| 253 |
+
print("Filter Students: Input DataFrame is empty.")
|
| 254 |
+
return df
|
| 255 |
+
|
| 256 |
+
filtered_df = df.copy()
|
| 257 |
+
print(f"Filter Students: Starting with {len(filtered_df)} students. Filters: {filters}")
|
| 258 |
+
|
| 259 |
+
try:
|
| 260 |
+
# CGPA filter
|
| 261 |
+
if filters.get('min_cgpa') is not None and filters['min_cgpa'] != '': # Check for not None explicitly
|
| 262 |
+
try:
|
| 263 |
+
min_cgpa_val = float(filters['min_cgpa'])
|
| 264 |
+
if 'cgpa' in filtered_df.columns:
|
| 265 |
+
original_count = len(filtered_df)
|
| 266 |
+
filtered_df = filtered_df[filtered_df['cgpa'].fillna(0) >= min_cgpa_val]
|
| 267 |
+
print(f" Applied CGPA >= {min_cgpa_val}: {original_count} -> {len(filtered_df)}")
|
| 268 |
+
except (ValueError, TypeError):
|
| 269 |
+
print(f" Warning: Invalid CGPA filter value '{filters['min_cgpa']}'")
|
| 270 |
+
|
| 271 |
+
# Backlogs filter
|
| 272 |
+
if filters.get('max_backlogs') is not None and filters['max_backlogs'] != '': # Check for not None explicitly
|
| 273 |
+
try:
|
| 274 |
+
max_backlogs_val = float(filters['max_backlogs'])
|
| 275 |
+
if 'backlogs' in filtered_df.columns:
|
| 276 |
+
original_count = len(filtered_df)
|
| 277 |
+
filtered_df = filtered_df[filtered_df['backlogs'] <= max_backlogs_val]
|
| 278 |
+
print(f" Applied Backlogs <= {max_backlogs_val}: {original_count} -> {len(filtered_df)}")
|
| 279 |
+
except (ValueError, TypeError):
|
| 280 |
+
print(f" Warning: Invalid Backlogs filter value '{filters['max_backlogs']}'")
|
| 281 |
+
|
| 282 |
+
# Department filter (added for NL Query possibility)
|
| 283 |
+
if filters.get('department') and 'department' in filtered_df.columns:
|
| 284 |
+
dept_filter = str(filters['department']).strip()
|
| 285 |
+
if dept_filter:
|
| 286 |
+
original_count = len(filtered_df)
|
| 287 |
+
# Case-insensitive comparison
|
| 288 |
+
filtered_df = filtered_df[filtered_df['department'].str.contains(dept_filter, case=False, na=False)]
|
| 289 |
+
print(f" Applied Department contains '{dept_filter}': {original_count} -> {len(filtered_df)}")
|
| 290 |
+
|
| 291 |
+
|
| 292 |
+
# Helper for text contains filtering (case-insensitive) for comma-separated strings or lists
|
| 293 |
+
def text_contains_any(series, patterns):
|
| 294 |
+
if not patterns or series.isnull().all():
|
| 295 |
+
return pd.Series([False] * len(series), index=series.index)
|
| 296 |
+
|
| 297 |
+
patterns_set = {str(p).lower().strip() for p in patterns if p and str(p).strip()}
|
| 298 |
+
if not patterns_set:
|
| 299 |
+
return pd.Series([False] * len(series), index=series.index)
|
| 300 |
+
|
| 301 |
+
def check_item(item):
|
| 302 |
+
if pd.isna(item): return False
|
| 303 |
+
item_elements = []
|
| 304 |
+
current_item_elements = []
|
| 305 |
+
if isinstance(item, list):
|
| 306 |
+
current_item_elements = [str(el).lower().split('(')[0].strip() for el in item if el]
|
| 307 |
+
elif isinstance(item, str):
|
| 308 |
+
current_item_elements = [el.lower().split('(')[0].strip() for el in item.split(',') if el.strip()]
|
| 309 |
+
else:
|
| 310 |
+
current_item_elements = [str(item).lower().split('(')[0].strip()]
|
| 311 |
+
# Extend the main list
|
| 312 |
+
item_elements.extend(el for el in current_item_elements if el) # Ensure no empty strings
|
| 313 |
+
return any(elem in patterns_set for elem in item_elements)
|
| 314 |
+
|
| 315 |
+
return series.apply(check_item)
|
| 316 |
+
|
| 317 |
+
|
| 318 |
+
# Skills filter (checks programming_languages OR tools_technologies)
|
| 319 |
+
if filters.get('skills'):
|
| 320 |
+
skill_patterns = filters['skills']
|
| 321 |
+
lang_col_exists = 'programming_languages' in filtered_df.columns
|
| 322 |
+
tools_col_exists = 'tools_technologies' in filtered_df.columns
|
| 323 |
+
lang_match = pd.Series([False] * len(filtered_df), index=filtered_df.index)
|
| 324 |
+
tools_match = pd.Series([False] * len(filtered_df), index=filtered_df.index)
|
| 325 |
+
|
| 326 |
+
if lang_col_exists: lang_match = text_contains_any(filtered_df['programming_languages'], skill_patterns)
|
| 327 |
+
if tools_col_exists: tools_match = text_contains_any(filtered_df['tools_technologies'], skill_patterns)
|
| 328 |
+
|
| 329 |
+
original_count = len(filtered_df)
|
| 330 |
+
filtered_df = filtered_df[lang_match | tools_match]
|
| 331 |
+
print(f" Applied Skills filter ({skill_patterns}): {original_count} -> {len(filtered_df)}")
|
| 332 |
+
|
| 333 |
+
|
| 334 |
+
# Preferred roles filter
|
| 335 |
+
if filters.get('roles'):
|
| 336 |
+
role_patterns = filters['roles']
|
| 337 |
+
if 'preferred_roles' in filtered_df.columns:
|
| 338 |
+
original_count = len(filtered_df)
|
| 339 |
+
filtered_df = filtered_df[text_contains_any(filtered_df['preferred_roles'], role_patterns)]
|
| 340 |
+
print(f" Applied Roles filter ({role_patterns}): {original_count} -> {len(filtered_df)}")
|
| 341 |
+
|
| 342 |
+
# Certifications filter (checks certifications OR detailed_certifications)
|
| 343 |
+
if filters.get('certifications'):
|
| 344 |
+
cert_patterns = filters['certifications']
|
| 345 |
+
cert_match = pd.Series([False] * len(filtered_df), index=filtered_df.index)
|
| 346 |
+
detail_cert_match = pd.Series([False] * len(filtered_df), index=filtered_df.index)
|
| 347 |
+
|
| 348 |
+
if 'certifications' in filtered_df.columns: cert_match = text_contains_any(filtered_df['certifications'], cert_patterns)
|
| 349 |
+
if 'detailed_certifications' in filtered_df.columns: detail_cert_match = text_contains_any(filtered_df['detailed_certifications'], cert_patterns)
|
| 350 |
+
|
| 351 |
+
original_count = len(filtered_df)
|
| 352 |
+
filtered_df = filtered_df[cert_match | detail_cert_match]
|
| 353 |
+
print(f" Applied Certifications filter ({cert_patterns}): {original_count} -> {len(filtered_df)}")
|
| 354 |
+
|
| 355 |
+
|
| 356 |
+
# Boolean flags (check if column exists and is not null/empty string/empty list)
|
| 357 |
+
def check_not_empty(series):
|
| 358 |
+
if series is None or series.empty: return pd.Series([False] * len(filtered_df), index=filtered_df.index)
|
| 359 |
+
# Handles NaN, None, empty strings, and potentially empty lists robustly
|
| 360 |
+
return series.apply(lambda x: pd.notna(x) and ( (isinstance(x, str) and x.strip()!='') or (isinstance(x, list) and len(x)>0) or (not isinstance(x,(str,list))) ) )
|
| 361 |
+
|
| 362 |
+
# Use the boolean value directly from filters dict (already processed in filter_students_route)
|
| 363 |
+
if filters.get('has_hackathons') is True:
|
| 364 |
+
if 'hackathons' in filtered_df.columns:
|
| 365 |
+
original_count = len(filtered_df)
|
| 366 |
+
filtered_df = filtered_df[check_not_empty(filtered_df['hackathons'])]
|
| 367 |
+
print(f" Applied Has Hackathons: {original_count} -> {len(filtered_df)}")
|
| 368 |
+
else: print(" Skipped Has Hackathons: Column not found")
|
| 369 |
+
|
| 370 |
+
if filters.get('has_experience') is True:
|
| 371 |
+
proj_exists = 'projects' in filtered_df.columns
|
| 372 |
+
intern_exists = 'internships' in filtered_df.columns
|
| 373 |
+
has_proj = check_not_empty(filtered_df.get('projects')) if proj_exists else pd.Series([False] * len(filtered_df), index=filtered_df.index)
|
| 374 |
+
has_intern = check_not_empty(filtered_df.get('internships')) if intern_exists else pd.Series([False] * len(filtered_df), index=filtered_df.index)
|
| 375 |
+
original_count = len(filtered_df)
|
| 376 |
+
filtered_df = filtered_df[has_proj | has_intern]
|
| 377 |
+
print(f" Applied Has Experience (Proj/Intern): {original_count} -> {len(filtered_df)}")
|
| 378 |
+
|
| 379 |
+
|
| 380 |
+
if filters.get('has_research') is True:
|
| 381 |
+
pub_exists = 'publications' in filtered_df.columns
|
| 382 |
+
patent_exists = 'patents' in filtered_df.columns
|
| 383 |
+
has_pub = check_not_empty(filtered_df.get('publications')) if pub_exists else pd.Series([False] * len(filtered_df), index=filtered_df.index)
|
| 384 |
+
has_patent = check_not_empty(filtered_df.get('patents')) if patent_exists else pd.Series([False] * len(filtered_df), index=filtered_df.index)
|
| 385 |
+
original_count = len(filtered_df)
|
| 386 |
+
filtered_df = filtered_df[has_pub | has_patent]
|
| 387 |
+
print(f" Applied Has Research (Pub/Patent): {original_count} -> {len(filtered_df)}")
|
| 388 |
+
|
| 389 |
+
|
| 390 |
+
# --- Job role-based filtering (Applied if job_id is present) ---
|
| 391 |
+
job_id_filter = filters.get('job_id')
|
| 392 |
+
if job_id_filter and job_id_filter != '' and supabase:
|
| 393 |
+
try:
|
| 394 |
+
job_id_val = int(job_id_filter)
|
| 395 |
+
print(f" Applying filters for Job ID: {job_id_val}")
|
| 396 |
+
response = supabase.table('jobs').select('min_cgpa, required_skills, experience_level').eq('id', job_id_val).maybe_single().execute()
|
| 397 |
+
|
| 398 |
+
if response.data:
|
| 399 |
+
job = response.data
|
| 400 |
+
print(f" Job Requirements: {job}")
|
| 401 |
+
# Filter by minimum CGPA requirement
|
| 402 |
+
if job.get('min_cgpa') is not None and 'cgpa' in filtered_df.columns:
|
| 403 |
+
original_count = len(filtered_df)
|
| 404 |
+
filtered_df = filtered_df[filtered_df['cgpa'].fillna(0) >= float(job['min_cgpa'])]
|
| 405 |
+
print(f" Applied Job CGPA >= {job['min_cgpa']}: {original_count} -> {len(filtered_df)}")
|
| 406 |
+
|
| 407 |
+
# Filter by required skills (ANY logic)
|
| 408 |
+
if job.get('required_skills'):
|
| 409 |
+
required_skills_list = job['required_skills']
|
| 410 |
+
lang_col_exists = 'programming_languages' in filtered_df.columns
|
| 411 |
+
tools_col_exists = 'tools_technologies' in filtered_df.columns
|
| 412 |
+
lang_match = pd.Series([False] * len(filtered_df), index=filtered_df.index)
|
| 413 |
+
tools_match = pd.Series([False] * len(filtered_df), index=filtered_df.index)
|
| 414 |
+
|
| 415 |
+
if lang_col_exists: lang_match = text_contains_any(filtered_df['programming_languages'], required_skills_list)
|
| 416 |
+
if tools_col_exists: tools_match = text_contains_any(filtered_df['tools_technologies'], required_skills_list)
|
| 417 |
+
|
| 418 |
+
original_count = len(filtered_df)
|
| 419 |
+
filtered_df = filtered_df[lang_match | tools_match]
|
| 420 |
+
print(f" Applied Job Skills filter ({required_skills_list}): {original_count} -> {len(filtered_df)}")
|
| 421 |
+
|
| 422 |
+
# Filter by experience level (Checks if internships or projects exist if experience > 0)
|
| 423 |
+
if job.get('experience_level') and job['experience_level'] > 0:
|
| 424 |
+
intern_exists = 'internships' in filtered_df.columns
|
| 425 |
+
proj_exists = 'projects' in filtered_df.columns
|
| 426 |
+
has_intern = check_not_empty(filtered_df.get('internships')) if intern_exists else pd.Series([False] * len(filtered_df), index=filtered_df.index)
|
| 427 |
+
has_proj = check_not_empty(filtered_df.get('projects')) if proj_exists else pd.Series([False] * len(filtered_df), index=filtered_df.index)
|
| 428 |
+
|
| 429 |
+
if intern_exists or proj_exists:
|
| 430 |
+
original_count = len(filtered_df)
|
| 431 |
+
filtered_df = filtered_df[has_proj | has_intern]
|
| 432 |
+
print(f" Applied Job Experience (>0 requires Internship/Project): {original_count} -> {len(filtered_df)}")
|
| 433 |
+
else: print(" Skipped Job Experience: Internships/Projects columns not found")
|
| 434 |
+
else:
|
| 435 |
+
print(f" Warning: Job ID {job_id_val} not found for filtering.")
|
| 436 |
+
flash(f"Warning: Job ID {job_id_val} not found, could not apply job-specific filters.", "warning")
|
| 437 |
+
|
| 438 |
+
except ValueError:
|
| 439 |
+
print(f" Invalid job_id format: {job_id_filter}")
|
| 440 |
+
except Exception as e:
|
| 441 |
+
print(f" Error fetching/applying job details for filtering: {e}")
|
| 442 |
+
flash(f"Warning: Could not apply filters for Job ID {job_id_filter}. Error: {e}", "warning")
|
| 443 |
+
|
| 444 |
+
except Exception as e:
|
| 445 |
+
print(f"Error during filtering process: {e}")
|
| 446 |
+
import traceback
|
| 447 |
+
traceback.print_exc()
|
| 448 |
+
flash(f"An critical error occurred during filtering: {e}", "danger")
|
| 449 |
+
return df # Return original df on major error
|
| 450 |
+
|
| 451 |
+
print(f"Filter Students: Finished with {len(filtered_df)} students.")
|
| 452 |
+
return filtered_df
|
| 453 |
+
|
| 454 |
+
|
| 455 |
+
def get_ai_insights(students_data, role):
|
| 456 |
+
"""Generates AI insights using Gemini for selected students and a role."""
|
| 457 |
+
if not HAS_GEMINI:
|
| 458 |
+
return "AI Insights disabled: Gemini API key not configured."
|
| 459 |
+
if students_data.empty:
|
| 460 |
+
return "No student data provided for analysis."
|
| 461 |
+
|
| 462 |
+
print(f"Generating AI insights for {len(students_data)} students, role: {role}") # Debug
|
| 463 |
+
|
| 464 |
+
# Format the student data for Gemini prompt (Simplified)
|
| 465 |
+
students_prompt = f"Analyze the following {len(students_data)} students based *only* on the provided profile data for suitability regarding the **{role}** role:\n\n---\n"
|
| 466 |
+
columns_to_include = [
|
| 467 |
+
'full_name', 'department', 'cgpa', 'backlogs',
|
| 468 |
+
'programming_languages', 'tools_technologies', 'soft_skills',
|
| 469 |
+
'projects', 'internships', 'certifications', 'preferred_roles',
|
| 470 |
+
'strengths', 'weaknesses'
|
| 471 |
+
]
|
| 472 |
+
|
| 473 |
+
for index, student in students_data.iterrows():
|
| 474 |
+
profile_str = f"**Student {index + 1}: {student.get('full_name', 'N/A')}**\n"
|
| 475 |
+
for col in columns_to_include:
|
| 476 |
+
if col != 'full_name':
|
| 477 |
+
value = student.get(col)
|
| 478 |
+
display_value = "N/A"
|
| 479 |
+
if pd.notna(value):
|
| 480 |
+
if isinstance(value, list):
|
| 481 |
+
display_value = ", ".join(map(str, value)) if value else "N/A"
|
| 482 |
+
elif isinstance(value, float):
|
| 483 |
+
display_value = f"{value:.2f}"
|
| 484 |
+
elif isinstance(value, (int, np.integer)):
|
| 485 |
+
display_value = str(value)
|
| 486 |
+
elif isinstance(value, str) and value.strip():
|
| 487 |
+
display_value = value.strip()
|
| 488 |
+
|
| 489 |
+
if display_value != "N/A":
|
| 490 |
+
profile_str += f"- {col.replace('_', ' ').title()}: {display_value}\n"
|
| 491 |
+
students_prompt += profile_str + "---\n"
|
| 492 |
+
|
| 493 |
+
students_prompt += f"""
|
| 494 |
+
**Analysis Request for {role}:**
|
| 495 |
+
|
| 496 |
+
1. **Ranked List:** Provide a ranked list (Top 3-5 recommended) of these students for the role. Briefly justify each rank based *only* on the provided data points (e.g., relevant skills, experience, CGPA if applicable).
|
| 497 |
+
2. **Strengths & Potential Gaps:** For *each* student listed above, concisely identify 1-2 key strengths and 1-2 potential gaps or areas needing clarification *specifically* for the '{role}' role, based *only* on their profile.
|
| 498 |
+
3. **Overall Summary:** Briefly summarize which student(s) appear most promising overall for this *specific* role, considering the data provided. Mention any significant trade-offs.
|
| 499 |
+
|
| 500 |
+
**Important Constraints:**
|
| 501 |
+
* Base your entire analysis *strictly* on the profile data given above.
|
| 502 |
+
* Do not invent or assume information not present.
|
| 503 |
+
* Focus on relevance to the specified '{role}'.
|
| 504 |
+
* Format the output clearly using Markdown (bolding, lists).
|
| 505 |
+
"""
|
| 506 |
+
|
| 507 |
+
try:
|
| 508 |
+
model = genai.GenerativeModel('gemini-1.5-flash') # Or gemini-pro
|
| 509 |
+
# Safety settings can be adjusted if needed
|
| 510 |
+
# safety_settings = [...]
|
| 511 |
+
# response = model.generate_content(students_prompt, safety_settings=safety_settings)
|
| 512 |
+
response = model.generate_content(students_prompt)
|
| 513 |
+
|
| 514 |
+
if not response.parts:
|
| 515 |
+
print("Warning: AI response might be blocked due to safety settings.")
|
| 516 |
+
feedback = response.prompt_feedback if hasattr(response, 'prompt_feedback') else "No feedback available."
|
| 517 |
+
print(f"Prompt Feedback: {feedback}")
|
| 518 |
+
return f"AI analysis could not be completed (content potentially blocked by safety filters). Feedback: {feedback}"
|
| 519 |
+
|
| 520 |
+
print("AI insights generated successfully.") # Debug
|
| 521 |
+
return response.text
|
| 522 |
+
except Exception as e:
|
| 523 |
+
print(f"Error generating AI insights: {e}")
|
| 524 |
+
import traceback
|
| 525 |
+
traceback.print_exc()
|
| 526 |
+
return f"Error generating AI insights: {str(e)}\n\nPlease check your Gemini API key and configuration."
|
| 527 |
+
|
| 528 |
+
|
| 529 |
+
# --- Chart Data Calculation Functions ---
|
| 530 |
+
|
| 531 |
+
def calculate_cgpa_distribution(df):
|
| 532 |
+
"""Calculates data for CGPA distribution chart."""
|
| 533 |
+
result = {'labels': [], 'data': []}
|
| 534 |
+
if df.empty or 'cgpa' not in df.columns or df['cgpa'].isnull().all():
|
| 535 |
+
print("CGPA Calc: DataFrame empty or 'cgpa' column missing/all null.")
|
| 536 |
+
return result
|
| 537 |
+
try:
|
| 538 |
+
bins = [0, 6, 7, 7.5, 8, 8.5, 9, 9.5, 10.1]
|
| 539 |
+
labels = ['< 6.0', '6.0-6.9', '7.0-7.4', '7.5-7.9', '8.0-8.4', '8.5-8.9', '9.0-9.4', '9.5-10.0']
|
| 540 |
+
cgpa_binned = pd.cut(df['cgpa'].dropna(), bins=bins, labels=labels, right=False, include_lowest=True)
|
| 541 |
+
counts = cgpa_binned.value_counts().sort_index()
|
| 542 |
+
result = {'labels': counts.index.tolist(), 'data': counts.values.tolist()}
|
| 543 |
+
print(f"CGPA Calc Results: Labels={result['labels']}, Data={result['data']}") # DEBUG
|
| 544 |
+
return result
|
| 545 |
+
except Exception as e:
|
| 546 |
+
print(f"Error calculating CGPA dist data: {e}")
|
| 547 |
+
return result
|
| 548 |
+
|
| 549 |
+
def calculate_department_distribution(df):
|
| 550 |
+
"""Calculates data for department distribution chart."""
|
| 551 |
+
result = {'labels': [], 'data': []}
|
| 552 |
+
if df.empty or 'department' not in df.columns or df['department'].isnull().all():
|
| 553 |
+
print("Dept Calc: DataFrame empty or 'department' column missing/all null.")
|
| 554 |
+
return result
|
| 555 |
+
try:
|
| 556 |
+
counts = df['department'].value_counts()
|
| 557 |
+
result = {'labels': counts.index.tolist(), 'data': counts.values.tolist()}
|
| 558 |
+
print(f"Dept Calc Results: Labels={result['labels']}, Data={result['data']}") # DEBUG
|
| 559 |
+
return result
|
| 560 |
+
except Exception as e:
|
| 561 |
+
print(f"Error calculating Dept dist data: {e}")
|
| 562 |
+
return result
|
| 563 |
+
|
| 564 |
+
def calculate_skills_distribution(df, top_n=10):
|
| 565 |
+
"""Calculates data for top N programming skills distribution."""
|
| 566 |
+
result = {'labels': [], 'data': []}
|
| 567 |
+
if df.empty or 'programming_languages' not in df.columns:
|
| 568 |
+
print("Skills Calc: DataFrame empty or 'programming_languages' column missing.")
|
| 569 |
+
return result
|
| 570 |
+
try:
|
| 571 |
+
all_skills = []
|
| 572 |
+
for skills_item in df['programming_languages'].dropna():
|
| 573 |
+
skills = []
|
| 574 |
+
if isinstance(skills_item, str) and skills_item.strip():
|
| 575 |
+
skills = [s.split('(')[0].strip().lower() for s in skills_item.split(',') if s.strip()]
|
| 576 |
+
elif isinstance(skills_item, list):
|
| 577 |
+
skills = [str(s).split('(')[0].strip().lower() for s in skills_item if s and str(s).strip()]
|
| 578 |
+
all_skills.extend(skills)
|
| 579 |
+
|
| 580 |
+
if not all_skills: print("Skills Calc: No skills found after parsing."); return result
|
| 581 |
+
skill_counts = pd.Series(all_skills).value_counts().nlargest(top_n)
|
| 582 |
+
labels = [s.capitalize() for s in skill_counts.index.tolist()]
|
| 583 |
+
result = {'labels': labels, 'data': skill_counts.values.tolist()}
|
| 584 |
+
print(f"Skills Calc Results: Labels={result['labels']}, Data={result['data']}") # DEBUG
|
| 585 |
+
return result
|
| 586 |
+
except Exception as e:
|
| 587 |
+
print(f"Error calculating Skills dist data: {e}")
|
| 588 |
+
return result
|
| 589 |
+
|
| 590 |
+
def calculate_roles_distribution(df, top_n=10):
|
| 591 |
+
"""Calculates data for top N preferred roles distribution."""
|
| 592 |
+
result = {'labels': [], 'data': []}
|
| 593 |
+
if df.empty or 'preferred_roles' not in df.columns:
|
| 594 |
+
print("Roles Calc: DataFrame empty or 'preferred_roles' column missing.")
|
| 595 |
+
return result
|
| 596 |
+
try:
|
| 597 |
+
all_roles = []
|
| 598 |
+
for roles_item in df['preferred_roles'].dropna():
|
| 599 |
+
roles = []
|
| 600 |
+
if isinstance(roles_item, str) and roles_item.strip():
|
| 601 |
+
roles = [r.strip().lower() for r in roles_item.split(',') if r.strip()]
|
| 602 |
+
elif isinstance(roles_item, list):
|
| 603 |
+
roles = [str(r).strip().lower() for r in roles_item if r and str(r).strip()]
|
| 604 |
+
all_roles.extend(roles)
|
| 605 |
+
|
| 606 |
+
if not all_roles: print("Roles Calc: No roles found after parsing."); return result
|
| 607 |
+
role_counts = pd.Series(all_roles).value_counts().nlargest(top_n)
|
| 608 |
+
labels = [r.title() for r in role_counts.index.tolist()]
|
| 609 |
+
result = {'labels': labels, 'data': role_counts.values.tolist()}
|
| 610 |
+
print(f"Roles Calc Results: Labels={result['labels']}, Data={result['data']}") # DEBUG
|
| 611 |
+
return result
|
| 612 |
+
except Exception as e:
|
| 613 |
+
print(f"Error calculating Roles dist data: {e}")
|
| 614 |
+
return result
|
| 615 |
+
|
| 616 |
+
# --- Routes ---
|
| 617 |
+
|
| 618 |
+
@app.route('/')
|
| 619 |
+
def home():
|
| 620 |
+
"""Redirects to dashboard if logged in, otherwise to login page."""
|
| 621 |
+
if 'company_email' in session:
|
| 622 |
+
return redirect(url_for('dashboard'))
|
| 623 |
+
return redirect(url_for('login'))
|
| 624 |
+
|
| 625 |
+
|
| 626 |
+
@app.route('/login', methods=['GET', 'POST'])
|
| 627 |
+
def login():
|
| 628 |
+
if not supabase:
|
| 629 |
+
return make_response(render_template('company_login.html', error="Database service unavailable. Please try again later."), 503)
|
| 630 |
+
|
| 631 |
+
error = None
|
| 632 |
+
if request.method == 'POST':
|
| 633 |
+
email = request.form.get('email')
|
| 634 |
+
password = request.form.get('password')
|
| 635 |
+
|
| 636 |
+
if not email or not password:
|
| 637 |
+
error = 'Email and password are required.'
|
| 638 |
+
return render_template('company_login.html', error=error)
|
| 639 |
+
|
| 640 |
+
try:
|
| 641 |
+
print(f"--- Attempting login for: {email}")
|
| 642 |
+
response = supabase.table('companies').select('*').eq('email', email).maybe_single().execute()
|
| 643 |
+
print(f"--- Supabase response status: {response.data is not None}")
|
| 644 |
+
|
| 645 |
+
if response.data:
|
| 646 |
+
company_data = response.data
|
| 647 |
+
print(f"--- Company data found: {company_data.keys()}")
|
| 648 |
+
stored_hash = company_data.get('password')
|
| 649 |
+
print(f"--- Stored hash found: {stored_hash is not None}")
|
| 650 |
+
|
| 651 |
+
if stored_hash and verify_password(stored_hash, password):
|
| 652 |
+
print("--- Password verified")
|
| 653 |
+
required_keys = ['id', 'email', 'company_name']
|
| 654 |
+
if all(k in company_data for k in required_keys):
|
| 655 |
+
session['company_id'] = company_data['id']
|
| 656 |
+
session['company_email'] = company_data['email']
|
| 657 |
+
session['company_name'] = company_data['company_name']
|
| 658 |
+
session.permanent = True
|
| 659 |
+
print("--- Session set successfully")
|
| 660 |
+
flash(f"Welcome back, {session['company_name']}!", "success")
|
| 661 |
+
return redirect(url_for('dashboard'))
|
| 662 |
+
else:
|
| 663 |
+
print(f"--- Error: Missing required keys in company_data. Found: {company_data.keys()}")
|
| 664 |
+
error = "Login failed: Incomplete company profile data in database."
|
| 665 |
+
else:
|
| 666 |
+
print("--- Password verification failed")
|
| 667 |
+
error = 'Invalid credentials. Please try again.'
|
| 668 |
+
else:
|
| 669 |
+
print(f"--- Company email '{email}' not found in database.")
|
| 670 |
+
error = 'Company email not found.'
|
| 671 |
+
except Exception as e:
|
| 672 |
+
print(f"--- Login error exception: {e}")
|
| 673 |
+
import traceback
|
| 674 |
+
traceback.print_exc()
|
| 675 |
+
error = 'An error occurred during login. Please contact support.'
|
| 676 |
+
|
| 677 |
+
if 'company_email' in session:
|
| 678 |
+
return redirect(url_for('dashboard'))
|
| 679 |
+
return render_template('company_login.html', error=error)
|
| 680 |
+
|
| 681 |
+
|
| 682 |
+
@app.route('/logout')
|
| 683 |
+
def logout():
|
| 684 |
+
"""Logs the company out."""
|
| 685 |
+
session.pop('company_id', None)
|
| 686 |
+
session.pop('company_email', None)
|
| 687 |
+
session.pop('company_name', None)
|
| 688 |
+
session.pop('filter_options_cache', None) # Clear cached options on logout
|
| 689 |
+
flash("You have been logged out.", "info")
|
| 690 |
+
return redirect(url_for('login'))
|
| 691 |
+
|
| 692 |
+
|
| 693 |
+
@app.route('/dashboard')
|
| 694 |
+
def dashboard():
|
| 695 |
+
"""Displays the main company dashboard."""
|
| 696 |
+
if 'company_email' not in session:
|
| 697 |
+
flash("Please log in to access the dashboard.", "warning")
|
| 698 |
+
return redirect(url_for('login'))
|
| 699 |
+
if not supabase:
|
| 700 |
+
flash("Database service unavailable.", "danger")
|
| 701 |
+
return render_template('company_dashboard.html', company_name=session.get('company_name', 'Company'), students=[], filter_options={}, initial_chart_data='{}', jobs=[], error="Database connection failed")
|
| 702 |
+
|
| 703 |
+
# Load student data
|
| 704 |
+
df = load_student_data()
|
| 705 |
+
|
| 706 |
+
# Prepare data for filters
|
| 707 |
+
filter_options = {
|
| 708 |
+
'departments': get_unique_values(df, 'department'),
|
| 709 |
+
'programming_languages': get_unique_values(df, 'programming_languages'),
|
| 710 |
+
'tools': get_unique_values(df, 'tools_technologies'),
|
| 711 |
+
'roles': get_unique_values(df, 'preferred_roles'),
|
| 712 |
+
'certifications': sorted(list(set(get_unique_values(df, 'certifications') + get_unique_values(df, 'detailed_certifications'))))
|
| 713 |
+
}
|
| 714 |
+
# --- Cache filter options in session ---
|
| 715 |
+
session['filter_options_cache'] = filter_options
|
| 716 |
+
# --- End Caching ---
|
| 717 |
+
|
| 718 |
+
# --- Calculate Initial Chart Data ---
|
| 719 |
+
initial_chart_data = {
|
| 720 |
+
'cgpa': calculate_cgpa_distribution(df),
|
| 721 |
+
'department': calculate_department_distribution(df),
|
| 722 |
+
'skills': calculate_skills_distribution(df),
|
| 723 |
+
'roles': calculate_roles_distribution(df)
|
| 724 |
+
}
|
| 725 |
+
print("\n--- Initial Chart Data (Backend - Dashboard Route) ---")
|
| 726 |
+
try:
|
| 727 |
+
print(json.dumps(initial_chart_data, indent=2))
|
| 728 |
+
except Exception as json_e: print(f"Error dumping initial chart data: {json_e}")
|
| 729 |
+
print("-----------------------------------------------------\n")
|
| 730 |
+
|
| 731 |
+
# Fetch jobs posted by this company
|
| 732 |
+
jobs_list = []
|
| 733 |
+
try:
|
| 734 |
+
response = supabase.table('jobs').select('id, title').eq('company_id', session['company_id']).order('posted_date', desc=True).execute()
|
| 735 |
+
jobs_list = response.data if response.data else []
|
| 736 |
+
except Exception as e:
|
| 737 |
+
print(f"Error fetching jobs for dashboard: {e}")
|
| 738 |
+
flash("Could not load job postings.", "warning")
|
| 739 |
+
|
| 740 |
+
# Convert DataFrame NaNs to None for JSON serialization
|
| 741 |
+
display_cols = ['full_name', 'email', 'department', 'cgpa', 'backlogs', 'programming_languages', 'preferred_roles', 'internships', 'projects', 'hackathons', 'publications']
|
| 742 |
+
# Only select columns that actually exist in the dataframe
|
| 743 |
+
existing_display_cols = [col for col in display_cols if col in df.columns]
|
| 744 |
+
students_list = df[existing_display_cols].replace({np.nan: None}).to_dict('records') if not df.empty else []
|
| 745 |
+
|
| 746 |
+
return render_template(
|
| 747 |
+
'company_dashboard.html',
|
| 748 |
+
initial_chart_data=initial_chart_data, # Pass dict directly
|
| 749 |
+
company_name=session['company_name'],
|
| 750 |
+
students=students_list,
|
| 751 |
+
filter_options=filter_options, # Pass for initial rendering
|
| 752 |
+
jobs=jobs_list
|
| 753 |
+
)
|
| 754 |
+
|
| 755 |
+
|
| 756 |
+
@app.route('/filter_students', methods=['POST'])
|
| 757 |
+
def filter_students_route():
|
| 758 |
+
"""Handles AJAX request to filter students and provides updated chart data."""
|
| 759 |
+
if 'company_email' not in session:
|
| 760 |
+
return jsonify({'error': 'Not authenticated'}), 401
|
| 761 |
+
if not supabase:
|
| 762 |
+
return jsonify({'error': 'Database service unavailable'}), 503
|
| 763 |
+
|
| 764 |
+
print("\n--- Filter Students Route Called ---") # Debug
|
| 765 |
+
df = load_student_data()
|
| 766 |
+
if df.empty:
|
| 767 |
+
print("Filter Students Route: No student data loaded.")
|
| 768 |
+
return jsonify({'students': [], 'chart_data': {}, 'count': 0})
|
| 769 |
+
|
| 770 |
+
filters = request.form.to_dict()
|
| 771 |
+
|
| 772 |
+
# Explicitly process boolean flags from form data ('on' means True)
|
| 773 |
+
filters['has_hackathons'] = filters.get('has_hackathons') == 'on'
|
| 774 |
+
filters['has_experience'] = filters.get('has_experience') == 'on'
|
| 775 |
+
filters['has_research'] = filters.get('has_research') == 'on'
|
| 776 |
+
|
| 777 |
+
# Get lists correctly
|
| 778 |
+
filters['skills'] = request.form.getlist('skills')
|
| 779 |
+
filters['roles'] = request.form.getlist('roles')
|
| 780 |
+
filters['certifications'] = request.form.getlist('certifications')
|
| 781 |
+
|
| 782 |
+
# Apply filters
|
| 783 |
+
filtered_df = filter_students(df, filters)
|
| 784 |
+
|
| 785 |
+
# --- Calculate Chart Data for Filtered Results ---
|
| 786 |
+
filtered_chart_data = {
|
| 787 |
+
'cgpa': calculate_cgpa_distribution(filtered_df),
|
| 788 |
+
'department': calculate_department_distribution(filtered_df),
|
| 789 |
+
'skills': calculate_skills_distribution(filtered_df),
|
| 790 |
+
'roles': calculate_roles_distribution(filtered_df)
|
| 791 |
+
}
|
| 792 |
+
print("\n--- Filtered Chart Data (Backend - Filter Route) ---")
|
| 793 |
+
try: print(json.dumps(filtered_chart_data, indent=2))
|
| 794 |
+
except Exception as json_e: print(f"Error dumping filtered chart data: {json_e}")
|
| 795 |
+
print("----------------------------------------------------\n")
|
| 796 |
+
|
| 797 |
+
# Prepare data for JSON response
|
| 798 |
+
display_cols = ['full_name', 'email', 'department', 'cgpa', 'backlogs', 'programming_languages', 'preferred_roles', 'internships', 'projects', 'hackathons', 'publications']
|
| 799 |
+
existing_display_cols = [col for col in display_cols if col in filtered_df.columns]
|
| 800 |
+
students_result = filtered_df[existing_display_cols].replace({np.nan: None}).to_dict('records') if not filtered_df.empty else []
|
| 801 |
+
|
| 802 |
+
print(f"Filter Students Route: Returning {len(students_result)} students.") # Debug
|
| 803 |
+
return jsonify({
|
| 804 |
+
'students': students_result,
|
| 805 |
+
'chart_data': filtered_chart_data,
|
| 806 |
+
'count': len(filtered_df)
|
| 807 |
+
})
|
| 808 |
+
|
| 809 |
+
|
| 810 |
+
@app.route('/process_nl_query', methods=['POST'])
|
| 811 |
+
def process_nl_query():
|
| 812 |
+
"""Handles AJAX request to convert natural language query to filters."""
|
| 813 |
+
if 'company_email' not in session:
|
| 814 |
+
return jsonify({'error': 'Not authenticated'}), 401
|
| 815 |
+
if not supabase:
|
| 816 |
+
return jsonify({'error': 'Database service unavailable'}), 503
|
| 817 |
+
if not HAS_GEMINI:
|
| 818 |
+
return jsonify({'error': 'AI Query service not configured or unavailable.'}), 503
|
| 819 |
+
|
| 820 |
+
nl_query = request.json.get('query')
|
| 821 |
+
if not nl_query:
|
| 822 |
+
return jsonify({'error': 'No query provided.'}), 400
|
| 823 |
+
|
| 824 |
+
print(f"Processing NL Query: '{nl_query}'")
|
| 825 |
+
|
| 826 |
+
# Retrieve cached filter options
|
| 827 |
+
cached_options = session.get('filter_options_cache')
|
| 828 |
+
if not cached_options:
|
| 829 |
+
# Fallback: Regenerate if not in session (should be rare)
|
| 830 |
+
print("Warning: Filter options cache miss in NL Query route, regenerating.")
|
| 831 |
+
df_temp = load_student_data()
|
| 832 |
+
cached_options = {
|
| 833 |
+
'departments': get_unique_values(df_temp, 'department'),
|
| 834 |
+
'programming_languages': get_unique_values(df_temp, 'programming_languages'),
|
| 835 |
+
'tools': get_unique_values(df_temp, 'tools_technologies'),
|
| 836 |
+
'roles': get_unique_values(df_temp, 'preferred_roles'),
|
| 837 |
+
'certifications': sorted(list(set(get_unique_values(df_temp, 'certifications') + get_unique_values(df_temp, 'detailed_certifications'))))
|
| 838 |
+
}
|
| 839 |
+
session['filter_options_cache'] = cached_options # Cache it now
|
| 840 |
+
|
| 841 |
+
# Combine skills for context
|
| 842 |
+
all_skill_examples = list(set(cached_options.get('programming_languages', []) + cached_options.get('tools', [])))
|
| 843 |
+
|
| 844 |
+
# --- Construct Prompt for Gemini ---
|
| 845 |
+
prompt = f"""
|
| 846 |
+
Analyze the following natural language query from a recruiter and convert it into a JSON object containing filter parameters for a student database.
|
| 847 |
+
|
| 848 |
+
**Available Filter Fields and Keys (Use these keys in the JSON output):**
|
| 849 |
+
* `min_cgpa`: Minimum CGPA (float, 0.0 to 10.0).
|
| 850 |
+
* `max_backlogs`: Maximum number of backlogs allowed (integer, >= 0).
|
| 851 |
+
* `skills`: List of required skills (strings). Match these against programming languages OR tools.
|
| 852 |
+
* `roles`: List of preferred job roles (strings).
|
| 853 |
+
* `certifications`: List of certifications (strings).
|
| 854 |
+
* `department`: Specific department name (string). Extract if mentioned clearly.
|
| 855 |
+
* `has_hackathons`: Boolean (true if user mentions hackathons or competitions).
|
| 856 |
+
* `has_experience`: Boolean (true if user mentions projects or internships).
|
| 857 |
+
* `has_research`: Boolean (true if user mentions research, publications, or patents).
|
| 858 |
+
|
| 859 |
+
**Context - Available Values (Examples - Use for guidance, not exhaustive):**
|
| 860 |
+
* Departments: {json.dumps(cached_options.get('departments', [])[:10])}...
|
| 861 |
+
* Skills (Programming/Tools): {json.dumps(all_skill_examples[:15])}...
|
| 862 |
+
* Roles: {json.dumps(cached_options.get('roles', [])[:10])}...
|
| 863 |
+
* Certifications: {json.dumps(cached_options.get('certifications', [])[:10])}...
|
| 864 |
+
|
| 865 |
+
**Recruiter's Query:**
|
| 866 |
+
"{nl_query}"
|
| 867 |
+
|
| 868 |
+
**Instructions:**
|
| 869 |
+
1. Parse the query to extract filtering criteria.
|
| 870 |
+
2. Map criteria to the correct filter keys listed above.
|
| 871 |
+
3. For list fields (`skills`, `roles`, `certifications`), output a JSON list of strings. Include the user's terms.
|
| 872 |
+
4. For boolean fields (`has_...`), output `true` only if explicitly mentioned. Otherwise, omit the key or set to `false`.
|
| 873 |
+
5. For `min_cgpa` and `max_backlogs`, extract the numeric value.
|
| 874 |
+
6. For `department`, extract the specific department name mentioned.
|
| 875 |
+
7. If a criterion isn't mentioned, omit its key from the JSON.
|
| 876 |
+
8. Output *only* the JSON object, without any explanations or markdown formatting.
|
| 877 |
+
|
| 878 |
+
**Example Input Query:** "Find computer science students with CGPA over 7.5, no backlogs, and who know Python or Java. Experience with projects is a plus."
|
| 879 |
+
**Example JSON Output:**
|
| 880 |
+
{{
|
| 881 |
+
"department": "Computer Science",
|
| 882 |
+
"min_cgpa": 7.5,
|
| 883 |
+
"max_backlogs": 0,
|
| 884 |
+
"skills": ["Python", "Java"],
|
| 885 |
+
"has_experience": true
|
| 886 |
+
}}
|
| 887 |
+
|
| 888 |
+
**Now, process the recruiter's query above and generate the JSON output.**
|
| 889 |
+
"""
|
| 890 |
+
|
| 891 |
+
try:
|
| 892 |
+
print("--- Sending NL prompt to Gemini ---")
|
| 893 |
+
model = genai.GenerativeModel('gemini-1.5-flash') # Or gemini-pro
|
| 894 |
+
response = model.generate_content(prompt)
|
| 895 |
+
|
| 896 |
+
# Clean the response (remove markdown backticks, etc.)
|
| 897 |
+
print(f"--- Gemini Raw Response Text ---\n{response.text}\n-----------------------------")
|
| 898 |
+
cleaned_response_text = response.text.strip()
|
| 899 |
+
if cleaned_response_text.startswith('```json'): cleaned_response_text = cleaned_response_text[7:]
|
| 900 |
+
if cleaned_response_text.startswith('```'): cleaned_response_text = cleaned_response_text[3:]
|
| 901 |
+
if cleaned_response_text.endswith('```'): cleaned_response_text = cleaned_response_text[:-3]
|
| 902 |
+
cleaned_response_text = cleaned_response_text.strip()
|
| 903 |
+
|
| 904 |
+
if not cleaned_response_text:
|
| 905 |
+
raise ValueError("Gemini returned an empty response after cleaning.")
|
| 906 |
+
|
| 907 |
+
filter_params = json.loads(cleaned_response_text)
|
| 908 |
+
print(f"--- Parsed Filter Params ---\n{json.dumps(filter_params, indent=2)}\n--------------------------")
|
| 909 |
+
|
| 910 |
+
if not isinstance(filter_params, dict):
|
| 911 |
+
raise ValueError("Gemini response was not a valid JSON object.")
|
| 912 |
+
|
| 913 |
+
# Optional: Further validation/type conversion can be added here if needed
|
| 914 |
+
|
| 915 |
+
return jsonify({'filters': filter_params})
|
| 916 |
+
|
| 917 |
+
except json.JSONDecodeError as e:
|
| 918 |
+
print(f"Error decoding Gemini JSON response: {e}")
|
| 919 |
+
print(f"Response text was: {cleaned_response_text}") # Log cleaned text
|
| 920 |
+
return jsonify({'error': f'AI could not generate valid filter parameters. Please rephrase your query. (JSON Error: {e}). Raw response: {response.text}'}), 400
|
| 921 |
+
except Exception as e:
|
| 922 |
+
print(f"Error processing NL query with Gemini: {e}")
|
| 923 |
+
import traceback
|
| 924 |
+
traceback.print_exc()
|
| 925 |
+
return jsonify({'error': f'An error occurred while processing the AI query: {e}'}), 500
|
| 926 |
+
|
| 927 |
+
|
| 928 |
+
@app.route('/ai_insights', methods=['POST'])
|
| 929 |
+
def ai_insights_route():
|
| 930 |
+
"""Handles AJAX request for AI insights."""
|
| 931 |
+
if 'company_email' not in session:
|
| 932 |
+
return jsonify({'error': 'Not authenticated'}), 401
|
| 933 |
+
if not supabase:
|
| 934 |
+
return jsonify({'error': 'Database service unavailable'}), 503
|
| 935 |
+
if not HAS_GEMINI:
|
| 936 |
+
return jsonify({'error': 'AI Insights service not configured or unavailable.'}), 503
|
| 937 |
+
|
| 938 |
+
df = load_student_data()
|
| 939 |
+
selected_emails = request.form.getlist('selected_students')
|
| 940 |
+
role = request.form.get('role', 'General Role Analysis')
|
| 941 |
+
|
| 942 |
+
print(f"AI Insights requested for emails: {selected_emails} and role: {role}")
|
| 943 |
+
|
| 944 |
+
if not selected_emails:
|
| 945 |
+
print("No students selected for AI analysis.")
|
| 946 |
+
return jsonify({'error': 'No students selected for analysis.'}), 400
|
| 947 |
+
|
| 948 |
+
selected_students_df = df[df['email'].isin(selected_emails)].copy()
|
| 949 |
+
|
| 950 |
+
if selected_students_df.empty:
|
| 951 |
+
print(f"Selected student emails not found in loaded data: {selected_emails}")
|
| 952 |
+
return jsonify({'error': 'Selected student data could not be found.'}), 404
|
| 953 |
+
|
| 954 |
+
insights = get_ai_insights(selected_students_df, role)
|
| 955 |
+
return jsonify({'insights': insights})
|
| 956 |
+
|
| 957 |
+
|
| 958 |
+
@app.route('/export_filtered', methods=['POST'])
|
| 959 |
+
def export_filtered():
|
| 960 |
+
"""Exports the currently filtered student list (sent from client) to CSV."""
|
| 961 |
+
if 'company_email' not in session:
|
| 962 |
+
return jsonify({"error": "Authentication required for export"}), 401
|
| 963 |
+
|
| 964 |
+
student_data_json = request.form.get('filtered_students')
|
| 965 |
+
if not student_data_json:
|
| 966 |
+
return jsonify({"error": "No student data provided"}), 400
|
| 967 |
+
|
| 968 |
+
try:
|
| 969 |
+
student_data = json.loads(student_data_json)
|
| 970 |
+
if not student_data:
|
| 971 |
+
return jsonify({"error": "No students to export"}), 400
|
| 972 |
+
|
| 973 |
+
df_to_export = pd.DataFrame(student_data)
|
| 974 |
+
export_columns = [
|
| 975 |
+
'full_name', 'email', 'department', 'cgpa', 'backlogs',
|
| 976 |
+
'programming_languages', 'tools_technologies', 'soft_skills',
|
| 977 |
+
'projects', 'internships', 'certifications', 'detailed_certifications',
|
| 978 |
+
'hackathons', 'publications', 'patents',
|
| 979 |
+
'preferred_roles', 'preferred_location', 'strengths', 'weaknesses',
|
| 980 |
+
'typing_speed', 'linkedin_profile', 'github_profile', 'portfolio_url'
|
| 981 |
+
]
|
| 982 |
+
available_export_cols = [col for col in export_columns if col in df_to_export.columns]
|
| 983 |
+
df_to_export = df_to_export[available_export_cols]
|
| 984 |
+
|
| 985 |
+
except json.JSONDecodeError:
|
| 986 |
+
print("Error decoding JSON for export")
|
| 987 |
+
return jsonify({"error": "Invalid data format for export"}), 400
|
| 988 |
+
except Exception as e:
|
| 989 |
+
print(f"Error preparing export data: {e}")
|
| 990 |
+
return jsonify({"error": f"Server error during export preparation: {e}"}), 500
|
| 991 |
+
|
| 992 |
+
try:
|
| 993 |
+
mem_file = io.BytesIO()
|
| 994 |
+
mem_file.write(u'\ufeff'.encode('utf8')) # BOM for Excel
|
| 995 |
+
df_to_export.to_csv(mem_file, index=False, encoding='utf-8-sig')
|
| 996 |
+
mem_file.seek(0)
|
| 997 |
+
|
| 998 |
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 999 |
+
response = make_response(send_file(
|
| 1000 |
+
mem_file,
|
| 1001 |
+
mimetype='text/csv',
|
| 1002 |
+
download_name=f'filtered_students_{timestamp}.csv',
|
| 1003 |
+
as_attachment=True
|
| 1004 |
+
))
|
| 1005 |
+
response.headers['Content-Disposition'] = f"attachment; filename=filtered_students_{timestamp}.csv"
|
| 1006 |
+
response.headers["Content-type"] = "text/csv; charset=utf-8"
|
| 1007 |
+
print(f"Exporting {len(df_to_export)} students to CSV.")
|
| 1008 |
+
return response
|
| 1009 |
+
|
| 1010 |
+
except Exception as e:
|
| 1011 |
+
print(f"Error sending export file: {e}")
|
| 1012 |
+
return jsonify({"error": f"Server error during file generation: {e}"}), 500
|
| 1013 |
+
|
| 1014 |
+
|
| 1015 |
+
@app.route('/jobs', methods=['GET', 'POST'])
|
| 1016 |
+
def jobs():
|
| 1017 |
+
"""Displays job postings and handles new job creation."""
|
| 1018 |
+
if 'company_email' not in session:
|
| 1019 |
+
flash("Please log in to manage job postings.", "warning")
|
| 1020 |
+
return redirect(url_for('login'))
|
| 1021 |
+
if not supabase:
|
| 1022 |
+
flash("Database service unavailable.", "danger")
|
| 1023 |
+
return render_template('jobs.html', jobs=[], skills=[], company_name=session.get('company_name', 'Company'),
|
| 1024 |
+
error="Database connection failed")
|
| 1025 |
+
|
| 1026 |
+
company_id = session.get('company_id')
|
| 1027 |
+
if not company_id:
|
| 1028 |
+
flash("Company session error. Please log in again.", "danger")
|
| 1029 |
+
return redirect(url_for('logout'))
|
| 1030 |
+
|
| 1031 |
+
# Load student data once for skills list generation
|
| 1032 |
+
df_students = load_student_data()
|
| 1033 |
+
prog_langs = get_unique_values(df_students, 'programming_languages')
|
| 1034 |
+
tools_tech = get_unique_values(df_students, 'tools_technologies')
|
| 1035 |
+
available_skills = sorted(list(set(prog_langs + tools_tech)))
|
| 1036 |
+
|
| 1037 |
+
if request.method == 'POST':
|
| 1038 |
+
try:
|
| 1039 |
+
required_skills_list = request.form.getlist('required_skills')
|
| 1040 |
+
min_cgpa_str = request.form.get('min_cgpa')
|
| 1041 |
+
experience_str = request.form.get('experience_level', '0')
|
| 1042 |
+
title = request.form.get('title')
|
| 1043 |
+
description = request.form.get('description')
|
| 1044 |
+
location = request.form.get('location')
|
| 1045 |
+
|
| 1046 |
+
# Basic validation
|
| 1047 |
+
error_msg = None
|
| 1048 |
+
if not title:
|
| 1049 |
+
error_msg = "Job Title is required."
|
| 1050 |
+
elif not description:
|
| 1051 |
+
error_msg = "Job Description is required."
|
| 1052 |
+
elif not required_skills_list:
|
| 1053 |
+
error_msg = "At least one required skill must be selected."
|
| 1054 |
+
elif not location:
|
| 1055 |
+
error_msg = "Location is required."
|
| 1056 |
+
|
| 1057 |
+
if error_msg:
|
| 1058 |
+
flash(error_msg, "warning")
|
| 1059 |
+
response = supabase.table('jobs').select('*').eq('company_id', company_id).order('posted_date',
|
| 1060 |
+
desc=True).execute()
|
| 1061 |
+
jobs_list = response.data if response.data else []
|
| 1062 |
+
return render_template('jobs.html', jobs=jobs_list, skills=available_skills,
|
| 1063 |
+
company_name=session['company_name'])
|
| 1064 |
+
|
| 1065 |
+
new_job_data = {
|
| 1066 |
+
'company_id': company_id,
|
| 1067 |
+
'title': title,
|
| 1068 |
+
'description': description,
|
| 1069 |
+
'required_skills': required_skills_list, # Store as array
|
| 1070 |
+
'min_cgpa': float(min_cgpa_str) if min_cgpa_str else None,
|
| 1071 |
+
'experience_level': int(experience_str) if experience_str.isdigit() else 0,
|
| 1072 |
+
'location': location
|
| 1073 |
+
}
|
| 1074 |
+
response = supabase.table('jobs').insert(new_job_data).execute()
|
| 1075 |
+
|
| 1076 |
+
if response.data:
|
| 1077 |
+
flash("New job posted successfully!", "success")
|
| 1078 |
+
|
| 1079 |
+
# Send email notification about the new job
|
| 1080 |
+
email_sent = send_job_email(new_job_data)
|
| 1081 |
+
if email_sent:
|
| 1082 |
+
flash("Job details sent by email successfully.", "info")
|
| 1083 |
+
else:
|
| 1084 |
+
flash("Job posted but email notification failed to send.", "warning")
|
| 1085 |
+
else:
|
| 1086 |
+
print(f"Job insert response structure: {response}")
|
| 1087 |
+
flash("Failed to post job. Please check details and try again.", "danger")
|
| 1088 |
+
|
| 1089 |
+
except Exception as e:
|
| 1090 |
+
print(f"Error posting job: {e}")
|
| 1091 |
+
import traceback;
|
| 1092 |
+
traceback.print_exc()
|
| 1093 |
+
flash(f"An error occurred while posting the job: {e}", "danger")
|
| 1094 |
+
|
| 1095 |
+
return redirect(url_for('jobs')) # Redirect after POST
|
| 1096 |
+
|
| 1097 |
+
# GET request handling
|
| 1098 |
+
jobs_list = []
|
| 1099 |
+
try:
|
| 1100 |
+
response_jobs = supabase.table('jobs').select('*').eq('company_id', company_id).order('posted_date',
|
| 1101 |
+
desc=True).execute()
|
| 1102 |
+
jobs_list = response_jobs.data if response_jobs.data else []
|
| 1103 |
+
except Exception as e:
|
| 1104 |
+
print(f"Error fetching data for jobs page: {e}")
|
| 1105 |
+
flash("Could not load job data.", "warning")
|
| 1106 |
+
|
| 1107 |
+
return render_template('jobs.html', jobs=jobs_list, skills=available_skills, company_name=session['company_name'])
|
| 1108 |
+
|
| 1109 |
+
|
| 1110 |
+
@app.route('/job/<int:job_id>')
|
| 1111 |
+
def job_details(job_id):
|
| 1112 |
+
"""Displays details for a specific job and eligible candidates."""
|
| 1113 |
+
if 'company_email' not in session:
|
| 1114 |
+
flash("Please log in to view job details.", "warning")
|
| 1115 |
+
return redirect(url_for('login'))
|
| 1116 |
+
if not supabase:
|
| 1117 |
+
flash("Database service unavailable.", "danger")
|
| 1118 |
+
return render_template('job_details.html', job=None, candidates_full=[], candidates_table=[], company_name=session.get('company_name', 'Company'), error="Database connection failed")
|
| 1119 |
+
|
| 1120 |
+
job_data = None
|
| 1121 |
+
eligible_candidates_list = []
|
| 1122 |
+
candidates_full_list = []
|
| 1123 |
+
company_id = session.get('company_id')
|
| 1124 |
+
|
| 1125 |
+
try:
|
| 1126 |
+
# Fetch the specific job details
|
| 1127 |
+
response_job = supabase.table('jobs').select('*').eq('id', job_id).maybe_single().execute()
|
| 1128 |
+
job_data = response_job.data
|
| 1129 |
+
|
| 1130 |
+
if not job_data:
|
| 1131 |
+
flash("Job not found.", "danger")
|
| 1132 |
+
return redirect(url_for('jobs'))
|
| 1133 |
+
|
| 1134 |
+
if job_data.get('company_id') != company_id:
|
| 1135 |
+
flash("You are not authorized to view details for this job.", "danger")
|
| 1136 |
+
print(f"Unauthorized access attempt to job {job_id} by company {company_id}")
|
| 1137 |
+
return redirect(url_for('jobs'))
|
| 1138 |
+
|
| 1139 |
+
# Find eligible candidates
|
| 1140 |
+
df_students = load_student_data()
|
| 1141 |
+
if not df_students.empty:
|
| 1142 |
+
filters = {'job_id': job_id}
|
| 1143 |
+
eligible_df = filter_students(df_students.copy(), filters)
|
| 1144 |
+
|
| 1145 |
+
# Prepare list for the table view (limited columns)
|
| 1146 |
+
display_cols_table = ['full_name', 'email', 'department', 'cgpa', 'programming_languages', 'projects', 'internships']
|
| 1147 |
+
existing_display_cols_table = [col for col in display_cols_table if col in eligible_df.columns]
|
| 1148 |
+
eligible_candidates_list = eligible_df[existing_display_cols_table].replace({np.nan: None}).to_dict('records') if not eligible_df.empty else []
|
| 1149 |
+
|
| 1150 |
+
# Prepare list with full data for the modal
|
| 1151 |
+
candidates_full_list = eligible_df.replace({np.nan: None}).to_dict('records') if not eligible_df.empty else []
|
| 1152 |
+
|
| 1153 |
+
else:
|
| 1154 |
+
flash("Could not load student data to find eligible candidates.", "warning")
|
| 1155 |
+
|
| 1156 |
+
except Exception as e:
|
| 1157 |
+
print(f"Error fetching job details or candidates for job {job_id}: {e}")
|
| 1158 |
+
import traceback; traceback.print_exc()
|
| 1159 |
+
flash("An error occurred while loading job details or finding candidates.", "danger")
|
| 1160 |
+
if not job_data: return redirect(url_for('jobs'))
|
| 1161 |
+
|
| 1162 |
+
return render_template(
|
| 1163 |
+
'job_details.html',
|
| 1164 |
+
job=job_data,
|
| 1165 |
+
candidates_full=json.dumps(candidates_full_list), # Pass full data as JSON string for JS
|
| 1166 |
+
candidates_table=eligible_candidates_list, # Data for the HTML table
|
| 1167 |
+
company_name=session.get('company_name', 'Company')
|
| 1168 |
+
)
|
| 1169 |
+
|
| 1170 |
+
|
| 1171 |
+
# --- Error Handlers (Use base.html now) ---
|
| 1172 |
+
@app.errorhandler(404)
|
| 1173 |
+
def page_not_found(e):
|
| 1174 |
+
return render_template('404.html'), 404
|
| 1175 |
+
|
| 1176 |
+
@app.errorhandler(500)
|
| 1177 |
+
def internal_server_error(e):
|
| 1178 |
+
print(f"Server Error: {e}")
|
| 1179 |
+
import traceback
|
| 1180 |
+
traceback.print_exc()
|
| 1181 |
+
return render_template('500.html', error=e), 500
|
| 1182 |
+
|
| 1183 |
+
# --- Context Processor for Year ---
|
| 1184 |
+
@app.context_processor
|
| 1185 |
+
def inject_now():
|
| 1186 |
+
return {'now': datetime.utcnow()}
|
| 1187 |
+
|
| 1188 |
+
# --- Run Application ---
|
| 1189 |
+
if __name__ == '__main__':
|
| 1190 |
+
if not supabase:
|
| 1191 |
+
print("\nWARNING: Supabase client failed to initialize.")
|
| 1192 |
+
print("Application will run but database operations will likely fail.")
|
| 1193 |
+
print("Check your .env file and Supabase project status.\n")
|
| 1194 |
+
port = int(os.environ.get("PORT", 5001))
|
| 1195 |
+
debug_mode = os.environ.get("FLASK_DEBUG", "true").lower() == "true"
|
| 1196 |
+
print(f"Starting Flask app on port {port} with debug mode: {debug_mode}")
|
| 1197 |
+
app.run(debug=debug_mode, port=port, host='0.0.0.0')
|
requirements.txt
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
flask
|
| 2 |
+
pandas
|
| 3 |
+
numpy
|
| 4 |
+
google-generativeai
|
| 5 |
+
supabase-python
|
| 6 |
+
python-dotenv
|
| 7 |
+
plotly
|
| 8 |
+
numpy
|
static/css/style.css
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* ======= Global Styles ======= */
|
| 2 |
+
:root {
|
| 3 |
+
--primary-color: #0d6efd; /* Bootstrap Blue */
|
| 4 |
+
--primary-dark: #0a58ca;
|
| 5 |
+
--secondary-color: #6c757d; /* Bootstrap Gray */
|
| 6 |
+
--success-color: #198754; /* Bootstrap Green */
|
| 7 |
+
--info-color: #0dcaf0; /* Bootstrap Cyan */
|
| 8 |
+
--warning-color: #ffc107; /* Bootstrap Yellow */
|
| 9 |
+
--danger-color: #dc3545; /* Bootstrap Red */
|
| 10 |
+
--light-color: #f8f9fa;
|
| 11 |
+
--dark-color: #212529;
|
| 12 |
+
--border-radius: 0.375rem;
|
| 13 |
+
--box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
| 14 |
+
--box-shadow-lg: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
body {
|
| 18 |
+
font-family: 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
| 19 |
+
background-color: #f0f2f5; /* Slightly different background */
|
| 20 |
+
color: #333;
|
| 21 |
+
font-size: 0.95rem; /* Slightly smaller base font */
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
/* ======= Typography ======= */
|
| 25 |
+
h1, h2, h3, h4, h5, h6 {
|
| 26 |
+
font-weight: 600;
|
| 27 |
+
margin-top: 0;
|
| 28 |
+
margin-bottom: 0.75rem;
|
| 29 |
+
color: var(--dark-color);
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
/* ======= Layout Components ======= */
|
| 33 |
+
.main-container {
|
| 34 |
+
padding-top: 1rem;
|
| 35 |
+
padding-bottom: 2rem;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
.card {
|
| 39 |
+
border-radius: var(--border-radius);
|
| 40 |
+
box-shadow: var(--box-shadow);
|
| 41 |
+
margin-bottom: 1.5rem;
|
| 42 |
+
border: none; /* Remove default border */
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
.card-header {
|
| 46 |
+
background-color: #fff; /* White header */
|
| 47 |
+
border-bottom: 1px solid #e9ecef;
|
| 48 |
+
padding: 0.75rem 1.25rem;
|
| 49 |
+
font-weight: 600;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
.card-header.bg-primary,
|
| 53 |
+
.card-header.bg-secondary { /* Keep colored headers */
|
| 54 |
+
color: white !important;
|
| 55 |
+
}
|
| 56 |
+
.card-header.bg-primary { background-color: var(--primary-color) !important; }
|
| 57 |
+
.card-header.bg-secondary { background-color: var(--secondary-color) !important; }
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
.card-body {
|
| 61 |
+
padding: 1.25rem;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
.card-footer {
|
| 65 |
+
padding: 0.75rem 1.25rem;
|
| 66 |
+
background-color: var(--light-color);
|
| 67 |
+
border-top: 1px solid #e9ecef;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
/* ======= Navigation ======= */
|
| 71 |
+
.navbar {
|
| 72 |
+
padding-top: 0.6rem;
|
| 73 |
+
padding-bottom: 0.6rem;
|
| 74 |
+
box-shadow: var(--box-shadow);
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.navbar-brand {
|
| 78 |
+
font-weight: 600;
|
| 79 |
+
font-size: 1.15rem;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
.nav-link {
|
| 83 |
+
padding: 0.4rem 0.8rem;
|
| 84 |
+
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
|
| 85 |
+
border-radius: var(--border-radius);
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
.nav-link:hover {
|
| 89 |
+
background-color: rgba(255, 255, 255, 0.1);
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
.nav-link.active {
|
| 93 |
+
font-weight: 600;
|
| 94 |
+
background-color: rgba(255, 255, 255, 0.15);
|
| 95 |
+
}
|
| 96 |
+
.navbar-dark .navbar-nav .nav-link {
|
| 97 |
+
color: rgba(255, 255, 255, 0.85);
|
| 98 |
+
}
|
| 99 |
+
.navbar-dark .navbar-nav .nav-link:hover,
|
| 100 |
+
.navbar-dark .navbar-nav .nav-link:focus {
|
| 101 |
+
color: #fff;
|
| 102 |
+
}
|
| 103 |
+
.navbar-dark .navbar-nav .nav-link.active {
|
| 104 |
+
color: #fff;
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
/* ======= Forms ======= */
|
| 108 |
+
.form-control, .form-select {
|
| 109 |
+
border-radius: var(--border-radius);
|
| 110 |
+
padding: 0.4rem 0.8rem;
|
| 111 |
+
border: 1px solid #ced4da;
|
| 112 |
+
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
| 113 |
+
font-size: 0.9rem;
|
| 114 |
+
}
|
| 115 |
+
.form-control-sm, .form-select-sm {
|
| 116 |
+
padding: 0.3rem 0.6rem;
|
| 117 |
+
font-size: 0.8rem;
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
.form-control:focus, .form-select:focus {
|
| 121 |
+
border-color: var(--primary-dark);
|
| 122 |
+
box-shadow: 0 0 0 0.2rem rgba(var(--bs-primary-rgb), 0.25); /* Use BS variable */
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
.form-label {
|
| 126 |
+
margin-bottom: 0.4rem;
|
| 127 |
+
font-weight: 500;
|
| 128 |
+
font-size: 0.9rem;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
.form-text {
|
| 132 |
+
color: var(--secondary-color);
|
| 133 |
+
margin-top: 0.25rem;
|
| 134 |
+
font-size: 0.8rem;
|
| 135 |
+
}
|
| 136 |
+
.form-check-label {
|
| 137 |
+
font-size: 0.9rem;
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
/* ======= Login Page ======= */
|
| 141 |
+
.login-container {
|
| 142 |
+
min-height: 100vh;
|
| 143 |
+
display: flex;
|
| 144 |
+
align-items: center;
|
| 145 |
+
justify-content: center;
|
| 146 |
+
background: linear-gradient(to bottom right, var(--primary-color), var(--primary-dark)); /* Gradient background */
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
.login-card {
|
| 150 |
+
width: 100%;
|
| 151 |
+
max-width: 420px; /* Slightly wider */
|
| 152 |
+
box-shadow: var(--box-shadow-lg);
|
| 153 |
+
border-radius: 0.5rem; /* More rounded */
|
| 154 |
+
}
|
| 155 |
+
.login-card .card-header {
|
| 156 |
+
background-color: rgba(255, 255, 255, 0.9); /* Semi-transparent */
|
| 157 |
+
border-bottom: none;
|
| 158 |
+
text-align: center;
|
| 159 |
+
}
|
| 160 |
+
.login-card .card-body {
|
| 161 |
+
padding: 2rem; /* More padding */
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
.demo-credentials {
|
| 165 |
+
background-color: var(--light-color);
|
| 166 |
+
padding: 0.75rem;
|
| 167 |
+
border-radius: var(--border-radius);
|
| 168 |
+
margin-top: 1rem;
|
| 169 |
+
font-size: 0.85rem;
|
| 170 |
+
border: 1px solid #e9ecef;
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
/* ======= Dashboard/Filter Section ======= */
|
| 174 |
+
.filter-section .card-body {
|
| 175 |
+
max-height: calc(100vh - 200px); /* Limit height */
|
| 176 |
+
overflow-y: auto;
|
| 177 |
+
}
|
| 178 |
+
.filter-heading {
|
| 179 |
+
font-weight: 600;
|
| 180 |
+
font-size: 0.85rem;
|
| 181 |
+
margin-bottom: 0.5rem;
|
| 182 |
+
color: var(--secondary-color);
|
| 183 |
+
text-transform: uppercase;
|
| 184 |
+
}
|
| 185 |
+
.filter-group {
|
| 186 |
+
margin-bottom: 1rem;
|
| 187 |
+
padding-bottom: 0.75rem;
|
| 188 |
+
border-bottom: 1px solid #eee;
|
| 189 |
+
}
|
| 190 |
+
.filter-group:last-child {
|
| 191 |
+
border-bottom: none;
|
| 192 |
+
margin-bottom: 0;
|
| 193 |
+
padding-bottom: 0;
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
.filter-section .filter-group {
|
| 197 |
+
padding-bottom: 1rem; /* Ensure consistent padding below groups */
|
| 198 |
+
margin-bottom: 1rem; /* Ensure consistent margin below groups */
|
| 199 |
+
border-bottom: 1px solid #eee; /* Keep visual separation */
|
| 200 |
+
}
|
| 201 |
+
.filter-section .row > div:last-child .filter-group:last-child, /* Target last group in last div of row */
|
| 202 |
+
.filter-section .row > .col-12:last-child .filter-group:last-of-type { /* More specific for last group in last col */
|
| 203 |
+
border-bottom: none; /* Remove border from very last group */
|
| 204 |
+
margin-bottom: 0;
|
| 205 |
+
padding-bottom: 0;
|
| 206 |
+
}
|
| 207 |
+
|
| 208 |
+
/* ======= Tables ======= */
|
| 209 |
+
.table {
|
| 210 |
+
margin-bottom: 0;
|
| 211 |
+
font-size: 0.9rem;
|
| 212 |
+
}
|
| 213 |
+
.table th, .table td {
|
| 214 |
+
vertical-align: middle;
|
| 215 |
+
padding: 0.6rem 0.75rem; /* Adjust padding */
|
| 216 |
+
}
|
| 217 |
+
.table th {
|
| 218 |
+
font-weight: 600;
|
| 219 |
+
border-top: none;
|
| 220 |
+
background-color: #f8f9fa; /* Light header */
|
| 221 |
+
}
|
| 222 |
+
.table-hover tbody tr:hover {
|
| 223 |
+
background-color: rgba(var(--bs-primary-rgb), 0.06);
|
| 224 |
+
}
|
| 225 |
+
.table-responsive {
|
| 226 |
+
border: 1px solid #dee2e6;
|
| 227 |
+
border-radius: var(--border-radius);
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
/* ======= Badges ======= */
|
| 231 |
+
.badge {
|
| 232 |
+
padding: 0.3em 0.55em;
|
| 233 |
+
font-weight: 500;
|
| 234 |
+
border-radius: 0.25rem;
|
| 235 |
+
margin: 0 0.1rem; /* Add slight margin */
|
| 236 |
+
font-size: 0.75em; /* Relative size */
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
/* ======= Visualization Section ======= */
|
| 240 |
+
.visualization-card {
|
| 241 |
+
height: 100%;
|
| 242 |
+
}
|
| 243 |
+
.chart-container {
|
| 244 |
+
position: relative;
|
| 245 |
+
height: 280px; /* Adjust height */
|
| 246 |
+
width: 100%;
|
| 247 |
+
}
|
| 248 |
+
canvas {
|
| 249 |
+
display: block;
|
| 250 |
+
}
|
| 251 |
+
|
| 252 |
+
/* ======= Job Listings ======= */
|
| 253 |
+
.job-card {
|
| 254 |
+
transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
| 255 |
+
height: 100%;
|
| 256 |
+
}
|
| 257 |
+
.job-card:hover {
|
| 258 |
+
transform: translateY(-3px);
|
| 259 |
+
box-shadow: var(--box-shadow-lg);
|
| 260 |
+
}
|
| 261 |
+
.job-title {
|
| 262 |
+
font-weight: 600;
|
| 263 |
+
margin-bottom: 0.5rem;
|
| 264 |
+
color: var(--primary-color);
|
| 265 |
+
}
|
| 266 |
+
.job-location {
|
| 267 |
+
color: var(--secondary-color);
|
| 268 |
+
font-size: 0.875rem;
|
| 269 |
+
}
|
| 270 |
+
.job-skills .badge {
|
| 271 |
+
margin-bottom: 0.25rem;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
/* ======= AI Insights ======= */
|
| 275 |
+
#insights-content {
|
| 276 |
+
white-space: pre-wrap;
|
| 277 |
+
max-height: 450px;
|
| 278 |
+
overflow-y: auto;
|
| 279 |
+
padding: 1rem;
|
| 280 |
+
background-color: white;
|
| 281 |
+
border: 1px solid #dee2e6;
|
| 282 |
+
border-radius: var(--border-radius);
|
| 283 |
+
font-size: 0.9rem;
|
| 284 |
+
line-height: 1.6;
|
| 285 |
+
}
|
| 286 |
+
#insights-content h6 {
|
| 287 |
+
font-size: 1rem;
|
| 288 |
+
margin-top: 1rem;
|
| 289 |
+
margin-bottom: 0.5rem;
|
| 290 |
+
border-bottom: 1px solid #eee;
|
| 291 |
+
padding-bottom: 0.25rem;
|
| 292 |
+
}
|
| 293 |
+
#insights-content ul {
|
| 294 |
+
padding-left: 1.5rem;
|
| 295 |
+
margin-bottom: 1rem;
|
| 296 |
+
}
|
| 297 |
+
#insights-content strong {
|
| 298 |
+
color: var(--primary-dark);
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
/* ======= Button Styles ======= */
|
| 302 |
+
.btn {
|
| 303 |
+
padding: 0.4rem 0.8rem;
|
| 304 |
+
border-radius: var(--border-radius);
|
| 305 |
+
font-weight: 500;
|
| 306 |
+
transition: all 0.2s ease-in-out;
|
| 307 |
+
font-size: 0.9rem;
|
| 308 |
+
display: inline-flex; /* Align icons nicely */
|
| 309 |
+
align-items: center;
|
| 310 |
+
gap: 0.35rem; /* Space between icon and text */
|
| 311 |
+
}
|
| 312 |
+
.btn i {
|
| 313 |
+
margin-right: 0.1rem; /* Adjust if gap isn't used */
|
| 314 |
+
font-size: 1em; /* Make icon size relative to button text */
|
| 315 |
+
}
|
| 316 |
+
|
| 317 |
+
.btn-sm {
|
| 318 |
+
padding: 0.3rem 0.6rem;
|
| 319 |
+
font-size: 0.8rem;
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
/* ======= Modals ======= */
|
| 323 |
+
.modal-header {
|
| 324 |
+
padding: 1rem 1.5rem;
|
| 325 |
+
border-bottom: 1px solid #dee2e6;
|
| 326 |
+
}
|
| 327 |
+
.modal-body {
|
| 328 |
+
padding: 1.5rem;
|
| 329 |
+
}
|
| 330 |
+
.modal-footer {
|
| 331 |
+
padding: 1rem 1.5rem;
|
| 332 |
+
border-top: 1px solid #dee2e6;
|
| 333 |
+
}
|
| 334 |
+
|
| 335 |
+
/* ======= Alerts ======= */
|
| 336 |
+
.alert {
|
| 337 |
+
padding: 0.8rem 1rem;
|
| 338 |
+
margin-bottom: 1rem;
|
| 339 |
+
border-radius: var(--border-radius);
|
| 340 |
+
font-size: 0.9rem;
|
| 341 |
+
}
|
| 342 |
+
|
| 343 |
+
/* ======= Spinner ======= */
|
| 344 |
+
.spinner-border {
|
| 345 |
+
width: 2rem;
|
| 346 |
+
height: 2rem;
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
/* ======= Responsive Adjustments ======= */
|
| 350 |
+
@media (max-width: 992px) { /* Use lg breakpoint */
|
| 351 |
+
.filter-section .card-body {
|
| 352 |
+
max-height: none; /* Remove height limit on smaller screens */
|
| 353 |
+
overflow-y: visible;
|
| 354 |
+
}
|
| 355 |
+
}
|
| 356 |
+
@media (max-width: 768px) {
|
| 357 |
+
body { font-size: 0.9rem; }
|
| 358 |
+
.card-body { padding: 1rem; }
|
| 359 |
+
.navbar-brand { font-size: 1rem; }
|
| 360 |
+
.btn { font-size: 0.85rem; padding: 0.35rem 0.7rem; }
|
| 361 |
+
.table { font-size: 0.85rem; }
|
| 362 |
+
.table th, .table td { padding: 0.5rem 0.6rem; }
|
| 363 |
+
.chart-container { height: 250px; }
|
| 364 |
+
}
|
students.csv
ADDED
|
@@ -0,0 +1,1316 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
email,password,full_name,department,cgpa,semester_records,backlogs,programming_languages,tools_technologies,certifications,soft_skills,typing_speed,projects,internships,portfolio_links,hackathons,coding_ratings,competitive_exams,detailed_certifications,competitions,publications,patents,preferred_roles,preferred_industry,preferred_location,higher_studies,aptitude_score,mock_interview,english_fluency,personality_type,strengths,weaknesses,faculty_feedback
|
| 2 |
+
pranit.chilbule@example.com,5eccb825edc768e8702618f3c7047f994df24e3f81d51186188f9a787a3cb4ac,Pranit Chilbule,Computer Science and Engineering,9.2,"Sem 1: 8.5
|
| 3 |
+
|
| 4 |
+
Sem 2: 9.0
|
| 5 |
+
|
| 6 |
+
Sem 3: 9.1
|
| 7 |
+
|
| 8 |
+
Sem 4: 9.3
|
| 9 |
+
|
| 10 |
+
Sem 5: 9.4
|
| 11 |
+
|
| 12 |
+
Sem 6: 9.2",0,"Python (Expert), Java (Intermediate), C++ (Intermediate), JavaScript (Beginner)","Docker, Git, AWS, React, Node.js, MongoDB, MySQL, TensorFlow","AWS Certified Developer
|
| 13 |
+
|
| 14 |
+
Google Cloud Associate Engineer
|
| 15 |
+
|
| 16 |
+
Microsoft AI Fundamentals","Communication, Leadership, Teamwork, Time Management",70,,,,,,,,,,,,,,,,,,,, ,
|
| 17 |
+
jillrhodes@miller.com,af738b28e0a93deae4483d186d93ab0ae1300f80dbd1bf73b8b367a58cb3cb4b,Allison Hill,Computer Science and Engineering,6.59,"Sem 1: 7.46
|
| 18 |
+
|
| 19 |
+
Sem 2: 7.28
|
| 20 |
+
|
| 21 |
+
Sem 3: 9.08
|
| 22 |
+
|
| 23 |
+
Sem 4: 8.87
|
| 24 |
+
|
| 25 |
+
Sem 5: 9.62
|
| 26 |
+
|
| 27 |
+
Sem 6: 6.8",1,"Python (Beginner), Ruby (Beginner), Go (Expert)","Git, AWS, React, Node.js, GCP","Google Cloud Associate
|
| 28 |
+
|
| 29 |
+
AWS Certified Developer","Problem-Solving, Leadership",47 WPM,Ago current practice nation determine operation speak according.,Wolfe LLC,https://www.bernard.com/,0.0,LeetCode: 753,None,Here grow gas enough.,2.0,1.0,0.0,Data Scientist,Finance,Bangalore,Yes,74.0,Yes,Medium,ISFJ,"Persistence, Analytical Thinking",Shyness,Role movie win.
|
| 30 |
+
janetwilliams@gmail.com,cdfeaee88ad132f0b2488c09e4ad862ad1b21c30c6fe78eecc1b06dd6ec80315,Juan Calderon,Computer Science and Engineering,9.91,"Sem 1: 7.82
|
| 31 |
+
|
| 32 |
+
Sem 2: 8.43
|
| 33 |
+
|
| 34 |
+
Sem 3: 9.4
|
| 35 |
+
|
| 36 |
+
Sem 4: 8.66
|
| 37 |
+
|
| 38 |
+
Sem 5: 9.52
|
| 39 |
+
|
| 40 |
+
Sem 6: 8.52",2,"Python (Intermediate), Ruby (Beginner), Java (Beginner)","Docker, Node.js, Kubernetes, AWS, MySQL","AWS Certified Developer
|
| 41 |
+
|
| 42 |
+
Google Cloud Associate","Leadership, Communication",47 WPM,Talk term herself law.,Martin-Kelly,https://www.reid.info/,0.0,LeetCode: 2595,GRE,Establish understand read detail food shoulder.,4.0,2.0,0.0,Data Scientist,Research,Chennai,No,90.0,Yes,Low,ISFJ,"Analytical Thinking, Empathy",Perfectionism,Director allow firm environment.
|
| 43 |
+
dianafoster@hotmail.com,abb346954e29a8141c8cb94eddfb8190b61b3051dfa0b4ec95d5e29d93e182d8,Tommy Walter,Electronics and Communication Engineering,7.9,"Sem 1: 6.73
|
| 44 |
+
|
| 45 |
+
Sem 2: 9.7
|
| 46 |
+
|
| 47 |
+
Sem 3: 8.49
|
| 48 |
+
|
| 49 |
+
Sem 4: 9.01
|
| 50 |
+
|
| 51 |
+
Sem 5: 7.24
|
| 52 |
+
|
| 53 |
+
Sem 6: 8.25",2,"JavaScript (Beginner), Java (Beginner), C++ (Expert)","MongoDB, GCP, React, MySQL, AWS","Oracle Java Certification
|
| 54 |
+
|
| 55 |
+
Google Cloud Associate","Leadership, Communication",38 WPM,Cause seat much section investment.,"Ross, Robinson and Bright",https://www.callahan.com/,3.0,LeetCode: 472,GATE,Others his other life edge network.,0.0,0.0,0.0,AI Researcher,IT,Chennai,No,88.0,No,Low,ISFJ,"Analytical Thinking, Persistence",Perfectionism,Quite boy those.
|
| 56 |
+
amoore@hotmail.com,3ba35621a8b4afa459ab7703717f87ac6aeb485d2bf446f0edf6ff01a8189425,Patricia Peterson,Electronics and Communication Engineering,9.19,"Sem 1: 7.69
|
| 57 |
+
|
| 58 |
+
Sem 2: 7.53
|
| 59 |
+
|
| 60 |
+
Sem 3: 7.05
|
| 61 |
+
|
| 62 |
+
Sem 4: 6.51
|
| 63 |
+
|
| 64 |
+
Sem 5: 9.03
|
| 65 |
+
|
| 66 |
+
Sem 6: 9.02",2,"Ruby (Beginner), Java (Expert), C# (Intermediate)","MongoDB, AWS, Docker, Kubernetes, Node.js","Oracle Java Certification
|
| 67 |
+
|
| 68 |
+
AWS Certified Developer","Leadership, Teamwork",31 WPM,Will seven medical blood personal.,"Romero, Gonzalez and Brooks",http://www.nguyen.com/,0.0,LeetCode: 1586,TOEFL,Around there water beat magazine.,1.0,0.0,0.0,Software Developer,IT,Chennai,Yes,98.0,Yes,High,ESFP,"Creativity, Empathy",Shyness,Within mouth call process.
|
| 69 |
+
sarahcampos@hotmail.com,e3198d6aa62a6f5cdfa33a496c69e0eb63025e5dfa19f687b567eca45e45c535,Carmen Rose,Information Technology,9.75,"Sem 1: 9.14
|
| 70 |
+
|
| 71 |
+
Sem 2: 8.91
|
| 72 |
+
|
| 73 |
+
Sem 3: 9.0
|
| 74 |
+
|
| 75 |
+
Sem 4: 7.9
|
| 76 |
+
|
| 77 |
+
Sem 5: 8.85
|
| 78 |
+
|
| 79 |
+
Sem 6: 7.81",2,"JavaScript (Beginner), Python (Beginner), Java (Intermediate)","Git, AWS, GCP, Docker, MongoDB","AWS Certified Developer
|
| 80 |
+
|
| 81 |
+
Oracle Java Certification","Teamwork, Communication",32 WPM,Human public health tonight later.,Walker LLC,http://www.robinson.com/,2.0,LeetCode: 390,GRE,Town teacher audience draw.,2.0,2.0,1.0,Data Scientist,Education,Chennai,Yes,100.0,No,Medium,ENTP,"Analytical Thinking, Empathy",Shyness,Democrat car very number line six space.
|
| 82 |
+
uowens@gmail.com,e8afd9f6742d8cbd469f04cb79a1fdf3f3e96b4039d40c22657a37d745b4da5a,Brent Jordan,Electronics and Communication Engineering,7.98,"Sem 1: 8.13
|
| 83 |
+
|
| 84 |
+
Sem 2: 9.05
|
| 85 |
+
|
| 86 |
+
Sem 3: 8.86
|
| 87 |
+
|
| 88 |
+
Sem 4: 9.94
|
| 89 |
+
|
| 90 |
+
Sem 5: 6.84
|
| 91 |
+
|
| 92 |
+
Sem 6: 7.91",1,"Ruby (Beginner), Python (Beginner), Java (Expert)","MySQL, Kubernetes, AWS, Docker, MongoDB","Google Cloud Associate
|
| 93 |
+
|
| 94 |
+
AWS Certified Developer","Communication, Teamwork",65 WPM,Art rock song body.,Lee Group,http://ramirez.com/,0.0,LeetCode: 307,GATE,Space task better present music address.,0.0,0.0,0.0,AI Researcher,Research,Chennai,Yes,75.0,Yes,High,ESFP,"Analytical Thinking, Creativity",Procrastination,Unit support coach magazine.
|
| 95 |
+
gallowayjoseph@yahoo.com,7b308ffa1ed446a0ed87fe1a06770e0a1c8231fca309d82603740e5e551c63a1,James Brown,Mechanical Engineering,7.5,"Sem 1: 8.94
|
| 96 |
+
|
| 97 |
+
Sem 2: 9.06
|
| 98 |
+
|
| 99 |
+
Sem 3: 9.24
|
| 100 |
+
|
| 101 |
+
Sem 4: 8.82
|
| 102 |
+
|
| 103 |
+
Sem 5: 8.2
|
| 104 |
+
|
| 105 |
+
Sem 6: 7.16",0,"Python (Beginner), C# (Expert), Go (Intermediate)","Git, MongoDB, GCP, AWS, Node.js","Oracle Java Certification
|
| 106 |
+
|
| 107 |
+
AWS Certified Developer","Communication, Leadership",35 WPM,Product main couple design around save article.,Brown-Silva,http://www.miller.com/,1.0,LeetCode: 380,GATE,Build three east organization people information.,5.0,0.0,1.0,Software Developer,Education,Bangalore,Yes,76.0,No,Medium,ENTP,"Persistence, Analytical Thinking",Procrastination,North first end prove fire enter capital population.
|
| 108 |
+
khowell@jones.net,8b124a42d3eeb70314712b3e1cd4bb408059dce0dc3e35c34b552b69d04e9512,Timothy Walls,Mechanical Engineering,6.96,"Sem 1: 8.76
|
| 109 |
+
|
| 110 |
+
Sem 2: 8.1
|
| 111 |
+
|
| 112 |
+
Sem 3: 9.75
|
| 113 |
+
|
| 114 |
+
Sem 4: 9.78
|
| 115 |
+
|
| 116 |
+
Sem 5: 6.53
|
| 117 |
+
|
| 118 |
+
Sem 6: 8.67",2,"Python (Beginner), Ruby (Expert), C# (Intermediate)","Kubernetes, React, Git, Docker, MongoDB","Google Cloud Associate
|
| 119 |
+
|
| 120 |
+
AWS Certified Developer","Problem-Solving, Leadership",49 WPM,Thing these hard citizen street region.,"Riggs, Roman and Rice",https://www.baker.net/,0.0,LeetCode: 2835,TOEFL,Evening painting response data.,5.0,0.0,0.0,System Engineer,IT,Bangalore,Yes,67.0,No,Low,ENTP,"Persistence, Analytical Thinking",Procrastination,Measure economy traditional anything plant.
|
| 121 |
+
evan78@patterson.com,1d2befd06e8cdfcab58bad1e92ab198690b719f637ad0fa3bb3ceb974d7f308c,Amanda Cook,Mechanical Engineering,7.38,"Sem 1: 9.68
|
| 122 |
+
|
| 123 |
+
Sem 2: 6.68
|
| 124 |
+
|
| 125 |
+
Sem 3: 8.72
|
| 126 |
+
|
| 127 |
+
Sem 4: 9.4
|
| 128 |
+
|
| 129 |
+
Sem 5: 6.65
|
| 130 |
+
|
| 131 |
+
Sem 6: 7.67",0,"Go (Expert), C++ (Intermediate), Java (Expert)","Node.js, Git, MySQL, MongoDB, Docker","Oracle Java Certification
|
| 132 |
+
|
| 133 |
+
AWS Certified Developer","Leadership, Problem-Solving",65 WPM,Old challenge camera final together someone.,Nolan and Sons,http://www.deleon-henson.biz/,1.0,LeetCode: 1860,GRE,See understand door class son computer include conference.,0.0,1.0,1.0,Software Developer,Finance,Hyderabad,Yes,92.0,Yes,Medium,ESFP,"Creativity, Analytical Thinking",Impatience,Site in prove same easy city.
|
| 134 |
+
jamessellers@yahoo.com,7f60cf721e511eef5351c189352e0ee5be7f6a533bb83a2ab79ab6e609167674,Janet Williams,Information Technology,9.58,"Sem 1: 6.59
|
| 135 |
+
|
| 136 |
+
Sem 2: 9.08
|
| 137 |
+
|
| 138 |
+
Sem 3: 7.66
|
| 139 |
+
|
| 140 |
+
Sem 4: 9.76
|
| 141 |
+
|
| 142 |
+
Sem 5: 9.31
|
| 143 |
+
|
| 144 |
+
Sem 6: 9.52",0,"C++ (Intermediate), Java (Beginner), Python (Intermediate)","AWS, MongoDB, Node.js, MySQL, Kubernetes","Google Cloud Associate
|
| 145 |
+
|
| 146 |
+
AWS Certified Developer","Teamwork, Communication",42 WPM,Development process huge everything attorney.,Bell-Hicks,https://www.wiley.com/,3.0,LeetCode: 1444,TOEFL,While enter board its rock finish paper memory.,0.0,1.0,1.0,AI Researcher,Finance,Bangalore,Yes,66.0,Yes,Low,ISFJ,"Analytical Thinking, Empathy",Shyness,Tonight couple and job mind southern.
|
| 147 |
+
ryan59@alvarado-martinez.com,cbe87f8efe32c9cbf55a062d264727891280c501822e38ad9494585c7c7cb228,Teresa Mclaughlin,Electronics and Communication Engineering,9.05,"Sem 1: 7.6
|
| 148 |
+
|
| 149 |
+
Sem 2: 8.62
|
| 150 |
+
|
| 151 |
+
Sem 3: 8.29
|
| 152 |
+
|
| 153 |
+
Sem 4: 7.85
|
| 154 |
+
|
| 155 |
+
Sem 5: 8.52
|
| 156 |
+
|
| 157 |
+
Sem 6: 7.39",2,"JavaScript (Expert), Python (Expert), C# (Expert)","AWS, React, MongoDB, Git, Kubernetes","Oracle Java Certification
|
| 158 |
+
|
| 159 |
+
Google Cloud Associate","Communication, Leadership",49 WPM,For recent never court professor here.,"Orr, Gilbert and Turner",http://clark-floyd.org/,2.0,LeetCode: 2831,None,Let kind degree list top somebody.,2.0,1.0,1.0,Data Scientist,Education,Chennai,No,93.0,Yes,Low,ISFJ,"Empathy, Persistence",Perfectionism,Probably exist professional people.
|
| 160 |
+
lindsayhernandez@gmail.com,0764349837af5adb7f6fa800b376f8e2ca7728e21d8834d1453d5c6d7cb1c1a6,Trevor Young,Electronics and Communication Engineering,7.5,"Sem 1: 8.0
|
| 161 |
+
|
| 162 |
+
Sem 2: 8.53
|
| 163 |
+
|
| 164 |
+
Sem 3: 8.79
|
| 165 |
+
|
| 166 |
+
Sem 4: 8.13
|
| 167 |
+
|
| 168 |
+
Sem 5: 8.05
|
| 169 |
+
|
| 170 |
+
Sem 6: 7.25",1,"Ruby (Expert), Go (Beginner), Java (Intermediate)","MongoDB, React, Git, Docker, Kubernetes","AWS Certified Developer
|
| 171 |
+
|
| 172 |
+
Oracle Java Certification","Teamwork, Communication",32 WPM,Particularly shoulder lay though offer responsibility himself.,Sanchez-Douglas,http://www.robinson-brock.net/,1.0,LeetCode: 2046,GATE,Anyone eat summer lead soon property write.,3.0,1.0,0.0,AI Researcher,Research,Chennai,Yes,59.0,Yes,High,ESFP,"Creativity, Analytical Thinking",Shyness,Fish sense kind spring throughout interview trade knowledge.
|
| 173 |
+
katie87@allen.com,e7c152f3f5b21b0cf642ded735cf7ce8a99da8e54f2a8a495641c850c2c63610,Scott Cole,Computer Science and Engineering,8.45,"Sem 1: 9.71
|
| 174 |
+
|
| 175 |
+
Sem 2: 6.92
|
| 176 |
+
|
| 177 |
+
Sem 3: 6.97
|
| 178 |
+
|
| 179 |
+
Sem 4: 8.13
|
| 180 |
+
|
| 181 |
+
Sem 5: 8.36
|
| 182 |
+
|
| 183 |
+
Sem 6: 8.46",1,"Ruby (Expert), JavaScript (Expert), C# (Intermediate)","MongoDB, MySQL, Docker, React, AWS","Google Cloud Associate
|
| 184 |
+
|
| 185 |
+
Oracle Java Certification","Teamwork, Leadership",47 WPM,Throw ball character him check degree.,Russell-Daniels,https://www.wall.org/,3.0,LeetCode: 2667,GRE,Task she herself.,2.0,1.0,0.0,System Engineer,Education,Pune,No,70.0,Yes,High,ENTP,"Creativity, Empathy",Impatience,Wall fear hope.
|
| 186 |
+
brobinson@johnson-rogers.biz,eb09451244f742eb9e9105ed978643bbc39ed50a7e95bdb0c69a1245e95748ba,Sara Medina,Information Technology,6.72,"Sem 1: 7.93
|
| 187 |
+
|
| 188 |
+
Sem 2: 8.4
|
| 189 |
+
|
| 190 |
+
Sem 3: 7.96
|
| 191 |
+
|
| 192 |
+
Sem 4: 7.22
|
| 193 |
+
|
| 194 |
+
Sem 5: 7.97
|
| 195 |
+
|
| 196 |
+
Sem 6: 9.67",2,"Go (Intermediate), Python (Intermediate), C# (Beginner)","React, GCP, Node.js, AWS, MongoDB","Oracle Java Certification
|
| 197 |
+
|
| 198 |
+
AWS Certified Developer","Problem-Solving, Communication",47 WPM,Try wonder move trade option production base.,Taylor-Murray,http://murphy-gibson.com/,3.0,LeetCode: 2089,GATE,Everything week instead strong like see.,3.0,1.0,1.0,Data Scientist,Research,Hyderabad,Yes,75.0,Yes,High,ESFP,"Creativity, Empathy",Impatience,Yourself glass practice.
|
| 199 |
+
maryhowell@martinez.com,c1750f794cfd4331404689b4e3bfbf535a28bd6727abf160ef0500b0e2ccee53,Marissa Webster,Computer Science and Engineering,7.41,"Sem 1: 7.65
|
| 200 |
+
|
| 201 |
+
Sem 2: 8.09
|
| 202 |
+
|
| 203 |
+
Sem 3: 7.68
|
| 204 |
+
|
| 205 |
+
Sem 4: 9.58
|
| 206 |
+
|
| 207 |
+
Sem 5: 7.47
|
| 208 |
+
|
| 209 |
+
Sem 6: 9.83",1,"C++ (Beginner), Python (Expert), JavaScript (Expert)","Git, React, Docker, MySQL, MongoDB","Oracle Java Certification
|
| 210 |
+
|
| 211 |
+
AWS Certified Developer","Communication, Problem-Solving",42 WPM,Let eight hard paper white.,"Wilson, Weiss and Oconnell",http://www.johnston-odonnell.biz/,0.0,LeetCode: 2644,GRE,Walk cup option store drug recent.,1.0,0.0,1.0,Software Developer,Education,Chennai,No,99.0,No,High,INTJ,"Creativity, Empathy",Perfectionism,Sure outside building worker site.
|
| 212 |
+
atkinsonlynn@gmail.com,6004a866b561f50b4e7bb207f0d5bbd71727dbff8d9716ef7df8c46ba88c9469,Jeffrey Wood,Computer Science and Engineering,9.75,"Sem 1: 8.52
|
| 213 |
+
|
| 214 |
+
Sem 2: 9.68
|
| 215 |
+
|
| 216 |
+
Sem 3: 7.81
|
| 217 |
+
|
| 218 |
+
Sem 4: 9.8
|
| 219 |
+
|
| 220 |
+
Sem 5: 7.19
|
| 221 |
+
|
| 222 |
+
Sem 6: 8.57",2,"Java (Expert), Python (Expert), C++ (Beginner)","Git, React, GCP, AWS, Kubernetes","AWS Certified Developer
|
| 223 |
+
|
| 224 |
+
Google Cloud Associate","Communication, Teamwork",61 WPM,Player stock religious itself safe whole.,Gilbert-Gillespie,https://petersen-vargas.com/,0.0,LeetCode: 1875,TOEFL,Store beautiful think during let.,5.0,1.0,0.0,AI Researcher,Education,Pune,No,79.0,No,Low,ISFJ,"Persistence, Analytical Thinking",Perfectionism,Property from management foot maintain great election evidence.
|
| 225 |
+
allenrichard@chang.info,036a80ebc72d5fe8a411d0c8b47e6927b900115a2ac56d2ef22f7ec5757b245a,Sheryl Peters,Electronics and Communication Engineering,9.59,"Sem 1: 7.35
|
| 226 |
+
|
| 227 |
+
Sem 2: 8.13
|
| 228 |
+
|
| 229 |
+
Sem 3: 8.64
|
| 230 |
+
|
| 231 |
+
Sem 4: 7.83
|
| 232 |
+
|
| 233 |
+
Sem 5: 6.6
|
| 234 |
+
|
| 235 |
+
Sem 6: 9.48",0,"JavaScript (Intermediate), Java (Intermediate), C++ (Intermediate)","GCP, Git, MongoDB, Docker, MySQL","AWS Certified Developer
|
| 236 |
+
|
| 237 |
+
Google Cloud Associate","Problem-Solving, Leadership",45 WPM,Behavior develop reality.,Beck-Wood,https://pierce.com/,3.0,LeetCode: 2745,None,Discover return firm sea week.,3.0,0.0,0.0,System Engineer,Education,Chennai,Yes,69.0,No,Medium,ISFJ,"Empathy, Persistence",Procrastination,Course school everybody operation.
|
| 238 |
+
jeremy24@erickson.com,7b3643054ba803a56c0b0f5ca25db9192d884965688e4ff5de04960eede9f144,Linda Hooper,Electronics and Communication Engineering,8.96,"Sem 1: 7.45
|
| 239 |
+
|
| 240 |
+
Sem 2: 7.38
|
| 241 |
+
|
| 242 |
+
Sem 3: 6.92
|
| 243 |
+
|
| 244 |
+
Sem 4: 7.17
|
| 245 |
+
|
| 246 |
+
Sem 5: 6.92
|
| 247 |
+
|
| 248 |
+
Sem 6: 8.38",2,"Java (Expert), Ruby (Intermediate), Go (Intermediate)","MongoDB, GCP, Git, Docker, Kubernetes","AWS Certified Developer
|
| 249 |
+
|
| 250 |
+
Google Cloud Associate","Teamwork, Problem-Solving",30 WPM,Network recently call.,Garcia-Smith,https://alexander-lopez.com/,1.0,LeetCode: 1223,GATE,Wait local state husband available.,0.0,2.0,1.0,Data Scientist,Research,Bangalore,Yes,86.0,No,Medium,ESFP,"Empathy, Creativity",Impatience,Rather charge specific we be easy newspaper indicate.
|
| 251 |
+
tkerr@hotmail.com,89d53b7c08a9e4647d314edf073f68f7bd257329609a71759cd9a5994fb48986,Lisa Rowe,Computer Science and Engineering,7.38,"Sem 1: 9.52
|
| 252 |
+
|
| 253 |
+
Sem 2: 6.9
|
| 254 |
+
|
| 255 |
+
Sem 3: 6.73
|
| 256 |
+
|
| 257 |
+
Sem 4: 8.22
|
| 258 |
+
|
| 259 |
+
Sem 5: 8.52
|
| 260 |
+
|
| 261 |
+
Sem 6: 8.9",0,"Java (Beginner), C# (Beginner), C++ (Beginner)","MongoDB, Node.js, GCP, MySQL, React","AWS Certified Developer
|
| 262 |
+
|
| 263 |
+
Google Cloud Associate","Problem-Solving, Teamwork",49 WPM,Notice art whether between several.,"Clark, Guerrero and Moore",http://www.smith.org/,3.0,LeetCode: 1350,GATE,Fact discuss religious reflect law reach under.,4.0,2.0,0.0,Data Scientist,Education,Pune,Yes,60.0,Yes,High,INTJ,"Creativity, Analytical Thinking",Shyness,Operation sound cup boy different chance enter central.
|
| 264 |
+
smartinez@yahoo.com,20ec3ecd328fc168a19f4f23112e037945b50254dccd306ad08ec88950fc686b,Ricky Larson,Mechanical Engineering,8.91,"Sem 1: 8.14
|
| 265 |
+
|
| 266 |
+
Sem 2: 6.61
|
| 267 |
+
|
| 268 |
+
Sem 3: 7.51
|
| 269 |
+
|
| 270 |
+
Sem 4: 7.49
|
| 271 |
+
|
| 272 |
+
Sem 5: 9.51
|
| 273 |
+
|
| 274 |
+
Sem 6: 6.75",0,"C++ (Expert), Go (Beginner), C# (Intermediate)","Docker, AWS, React, MongoDB, Kubernetes","AWS Certified Developer
|
| 275 |
+
|
| 276 |
+
Oracle Java Certification","Communication, Problem-Solving",49 WPM,Matter management ball always it.,Munoz-Johnson,http://www.underwood.com/,2.0,LeetCode: 1898,GATE,Million kind everything young job sport why.,3.0,2.0,1.0,AI Researcher,Finance,Chennai,No,55.0,Yes,Medium,ISFJ,"Persistence, Analytical Thinking",Perfectionism,Girl four prove tax form really explain.
|
| 277 |
+
edwardsmarcus@yahoo.com,3eff41ce850c8072eda343c62273462a658bcc33af0dd8b7800e10bb70906072,Robin Pierce,Information Technology,9.87,"Sem 1: 9.43
|
| 278 |
+
|
| 279 |
+
Sem 2: 8.51
|
| 280 |
+
|
| 281 |
+
Sem 3: 9.83
|
| 282 |
+
|
| 283 |
+
Sem 4: 10.0
|
| 284 |
+
|
| 285 |
+
Sem 5: 8.85
|
| 286 |
+
|
| 287 |
+
Sem 6: 7.44",0,"Ruby (Expert), Java (Expert), JavaScript (Intermediate)","GCP, Kubernetes, MongoDB, AWS, React","AWS Certified Developer
|
| 288 |
+
|
| 289 |
+
Google Cloud Associate","Leadership, Teamwork",51 WPM,Price my including.,Stone PLC,https://harris.com/,2.0,LeetCode: 2844,GATE,Just recognize building win participant.,1.0,1.0,1.0,AI Researcher,Finance,Chennai,Yes,79.0,Yes,Medium,ISFJ,"Persistence, Analytical Thinking",Shyness,Report financial add impact different.
|
| 290 |
+
scantu@thornton.info,2fed9bbb717ad2b2fcdd17a4841291513fcc7f4cc724d2b7122f8b3206e6f0be,Ashley Valentine,Computer Science and Engineering,8.8,"Sem 1: 8.4
|
| 291 |
+
|
| 292 |
+
Sem 2: 7.95
|
| 293 |
+
|
| 294 |
+
Sem 3: 7.16
|
| 295 |
+
|
| 296 |
+
Sem 4: 7.77
|
| 297 |
+
|
| 298 |
+
Sem 5: 9.15
|
| 299 |
+
|
| 300 |
+
Sem 6: 8.69",0,"Java (Beginner), C++ (Intermediate), C# (Intermediate)","MySQL, Docker, Git, React, GCP","AWS Certified Developer
|
| 301 |
+
|
| 302 |
+
Oracle Java Certification","Leadership, Problem-Solving",30 WPM,Certain course out second carry attorney significant.,Morgan-French,https://www.barber-monroe.org/,3.0,LeetCode: 481,GRE,Tend land machine forward several help usually.,0.0,1.0,0.0,Data Scientist,Research,Pune,No,76.0,No,Medium,ENTP,"Empathy, Persistence",Impatience,Wonder draw him task improve.
|
| 303 |
+
ymcneil@hotmail.com,a58290097f5067812a6168ba609dd1d3273ad0afd99a165b04e9d2eccb3efdc9,John Mcintyre,Mechanical Engineering,7.17,"Sem 1: 8.6
|
| 304 |
+
|
| 305 |
+
Sem 2: 9.11
|
| 306 |
+
|
| 307 |
+
Sem 3: 6.98
|
| 308 |
+
|
| 309 |
+
Sem 4: 6.74
|
| 310 |
+
|
| 311 |
+
Sem 5: 9.2
|
| 312 |
+
|
| 313 |
+
Sem 6: 9.49",1,"Ruby (Beginner), C# (Intermediate), C++ (Expert)","GCP, MySQL, Node.js, Docker, AWS","Oracle Java Certification
|
| 314 |
+
|
| 315 |
+
Google Cloud Associate","Leadership, Teamwork",65 WPM,Who call whole forward beyond suddenly between.,Smith-Thomas,http://www.harrington-baker.org/,3.0,LeetCode: 1965,TOEFL,Power system system teacher here first.,1.0,2.0,0.0,AI Researcher,Education,Chennai,Yes,70.0,No,Low,ESFP,"Empathy, Persistence",Impatience,Their along attention piece TV young section.
|
| 316 |
+
tjackson@williams.com,8def98a6abbdab0199fa812c7bf02ffc8a4c052178b1ffcada8c924115990337,Brett Schultz,Mechanical Engineering,9.88,"Sem 1: 6.94
|
| 317 |
+
|
| 318 |
+
Sem 2: 9.88
|
| 319 |
+
|
| 320 |
+
Sem 3: 7.66
|
| 321 |
+
|
| 322 |
+
Sem 4: 6.85
|
| 323 |
+
|
| 324 |
+
Sem 5: 9.46
|
| 325 |
+
|
| 326 |
+
Sem 6: 6.85",1,"Python (Intermediate), Go (Expert), Java (Beginner)","Docker, MySQL, Node.js, Kubernetes, React","Oracle Java Certification
|
| 327 |
+
|
| 328 |
+
Google Cloud Associate","Communication, Teamwork",64 WPM,Certainly most not society color bad.,Harvey-Allen,http://www.little-stevens.com/,3.0,LeetCode: 1397,None,Top quality citizen kid generation onto police.,4.0,0.0,0.0,Data Scientist,Finance,Hyderabad,Yes,77.0,Yes,Low,INTJ,"Empathy, Analytical Thinking",Procrastination,Real lead few yourself table blood.
|
| 329 |
+
spencedominique@yahoo.com,e9efb46293d2710e363c4552d8a85551f4146852adb291103a9f1d37ef7980f5,Ian Phillips,Computer Science and Engineering,6.66,"Sem 1: 9.29
|
| 330 |
+
|
| 331 |
+
Sem 2: 7.53
|
| 332 |
+
|
| 333 |
+
Sem 3: 7.81
|
| 334 |
+
|
| 335 |
+
Sem 4: 7.01
|
| 336 |
+
|
| 337 |
+
Sem 5: 8.36
|
| 338 |
+
|
| 339 |
+
Sem 6: 8.48",0,"Java (Expert), Ruby (Intermediate), Python (Expert)","AWS, MySQL, GCP, Docker, React","Google Cloud Associate
|
| 340 |
+
|
| 341 |
+
Oracle Java Certification","Problem-Solving, Teamwork",30 WPM,Treat seat strategy.,Parsons-Hall,https://www.lee.com/,3.0,LeetCode: 1278,GRE,Best physical always small almost half capital travel.,0.0,1.0,1.0,System Engineer,Research,Pune,No,69.0,Yes,Medium,ESFP,"Analytical Thinking, Empathy",Shyness,Section compare car much will most.
|
| 342 |
+
julie51@yahoo.com,b2f8deb6bb969668fbdfc8f3364852aa0924c93e1b3698d0e8f67345d690f5cf,Sandra Scott,Electronics and Communication Engineering,8.51,"Sem 1: 9.97
|
| 343 |
+
|
| 344 |
+
Sem 2: 7.53
|
| 345 |
+
|
| 346 |
+
Sem 3: 9.92
|
| 347 |
+
|
| 348 |
+
Sem 4: 8.8
|
| 349 |
+
|
| 350 |
+
Sem 5: 7.46
|
| 351 |
+
|
| 352 |
+
Sem 6: 8.48",2,"Ruby (Expert), Go (Expert), Python (Intermediate)","GCP, AWS, MongoDB, Kubernetes, Docker","Oracle Java Certification
|
| 353 |
+
|
| 354 |
+
AWS Certified Developer","Leadership, Problem-Solving",38 WPM,Senior difficult put purpose.,Coffey-Ballard,https://www.smith-herrera.info/,0.0,LeetCode: 2670,GATE,Pull public once state wait board.,2.0,1.0,0.0,System Engineer,Education,Bangalore,No,70.0,No,High,ENTP,"Creativity, Persistence",Procrastination,Likely people wall foreign particular.
|
| 355 |
+
cwilson@gmail.com,47e707b039ca66c11f453b03ab7669a83292e4326b9208d4d0cbfedd3f5b8125,Madison Marshall,Electronics and Communication Engineering,9.41,"Sem 1: 7.4
|
| 356 |
+
|
| 357 |
+
Sem 2: 9.39
|
| 358 |
+
|
| 359 |
+
Sem 3: 8.19
|
| 360 |
+
|
| 361 |
+
Sem 4: 9.32
|
| 362 |
+
|
| 363 |
+
Sem 5: 9.11
|
| 364 |
+
|
| 365 |
+
Sem 6: 7.69",0,"JavaScript (Beginner), Python (Expert), Java (Expert)","Node.js, React, Git, AWS, MongoDB","Google Cloud Associate
|
| 366 |
+
|
| 367 |
+
AWS Certified Developer","Problem-Solving, Teamwork",46 WPM,Break doctor Mr home he we recent.,"Barnes, Newton and Moore",https://www.gilbert-crosby.com/,3.0,LeetCode: 2715,TOEFL,Real describe know.,0.0,2.0,0.0,AI Researcher,IT,Pune,Yes,91.0,Yes,Low,ESFP,"Persistence, Empathy",Shyness,Talk between rate name within.
|
| 368 |
+
ndavis@fowler.com,4ecbc040643a6a382ec7098e4300a5011509b65c71916da02fcb47d9f0810d2d,James Lopez,Computer Science and Engineering,6.99,"Sem 1: 9.81
|
| 369 |
+
|
| 370 |
+
Sem 2: 7.57
|
| 371 |
+
|
| 372 |
+
Sem 3: 8.22
|
| 373 |
+
|
| 374 |
+
Sem 4: 6.84
|
| 375 |
+
|
| 376 |
+
Sem 5: 9.61
|
| 377 |
+
|
| 378 |
+
Sem 6: 6.97",1,"C++ (Intermediate), Go (Expert), C# (Expert)","Kubernetes, Node.js, React, Git, AWS","Oracle Java Certification
|
| 379 |
+
|
| 380 |
+
Google Cloud Associate","Leadership, Communication",53 WPM,Skin day stop never.,"Robinson, Kane and Murphy",http://www.garrison-thomas.com/,1.0,LeetCode: 1916,None,Economy company produce ago address so draw.,1.0,1.0,0.0,System Engineer,Finance,Bangalore,No,67.0,Yes,High,ESFP,"Analytical Thinking, Persistence",Impatience,Administration enter camera inside box as.
|
| 381 |
+
soniawilliams@hotmail.com,56bac80050c404a1944f07c6217a1e7352a7ac9c217a1a621675636ce0218836,Ivan Wheeler,Computer Science and Engineering,6.68,"Sem 1: 7.67
|
| 382 |
+
|
| 383 |
+
Sem 2: 9.96
|
| 384 |
+
|
| 385 |
+
Sem 3: 9.25
|
| 386 |
+
|
| 387 |
+
Sem 4: 7.22
|
| 388 |
+
|
| 389 |
+
Sem 5: 9.4
|
| 390 |
+
|
| 391 |
+
Sem 6: 8.44",2,"Java (Beginner), Ruby (Expert), C++ (Beginner)","GCP, Kubernetes, Docker, MongoDB, MySQL","AWS Certified Developer
|
| 392 |
+
|
| 393 |
+
Oracle Java Certification","Communication, Problem-Solving",30 WPM,Poor all your suggest international blue Republican.,Jones-Miller,http://www.hill.org/,2.0,LeetCode: 1074,TOEFL,Republican herself our far measure involve soldier.,0.0,0.0,1.0,Software Developer,Education,Chennai,Yes,97.0,Yes,Medium,ESFP,"Persistence, Empathy",Perfectionism,Table prepare shoulder result.
|
| 394 |
+
uross@gmail.com,38194021fce0308395c68a3b1c38fff5b94e40b33f74c5d2c775bf790b6821bf,Jesse Perez,Mechanical Engineering,8.26,"Sem 1: 9.81
|
| 395 |
+
|
| 396 |
+
Sem 2: 6.65
|
| 397 |
+
|
| 398 |
+
Sem 3: 9.24
|
| 399 |
+
|
| 400 |
+
Sem 4: 9.53
|
| 401 |
+
|
| 402 |
+
Sem 5: 8.33
|
| 403 |
+
|
| 404 |
+
Sem 6: 8.1",0,"Python (Intermediate), JavaScript (Expert), Go (Beginner)","MySQL, MongoDB, Git, Node.js, Kubernetes","Oracle Java Certification
|
| 405 |
+
|
| 406 |
+
AWS Certified Developer","Communication, Problem-Solving",47 WPM,Professor hear check type attack story.,Reynolds Ltd,https://www.brown.com/,2.0,LeetCode: 1660,TOEFL,Government program seek test return why.,3.0,2.0,1.0,Software Developer,IT,Hyderabad,No,78.0,Yes,Medium,ISFJ,"Empathy, Creativity",Shyness,Fine billion medical choice lot suggest glass news.
|
| 407 |
+
lynchdiane@hotmail.com,aef4cf6b6228c34a0e24f45d02b3d9d9b320e64b6a27019787aa25c9b0fb55b0,Donald Perez,Computer Science and Engineering,7.59,"Sem 1: 7.59
|
| 408 |
+
|
| 409 |
+
Sem 2: 7.39
|
| 410 |
+
|
| 411 |
+
Sem 3: 9.84
|
| 412 |
+
|
| 413 |
+
Sem 4: 8.9
|
| 414 |
+
|
| 415 |
+
Sem 5: 8.16
|
| 416 |
+
|
| 417 |
+
Sem 6: 6.82",0,"Python (Expert), JavaScript (Expert), Ruby (Intermediate)","Kubernetes, Git, GCP, Node.js, React","Google Cloud Associate
|
| 418 |
+
|
| 419 |
+
AWS Certified Developer","Problem-Solving, Teamwork",57 WPM,Event several TV go.,Kane PLC,https://www.figueroa.com/,0.0,LeetCode: 1278,TOEFL,Democrat information game have return since nothing.,2.0,0.0,0.0,Data Scientist,Research,Hyderabad,Yes,72.0,No,High,ISFJ,"Creativity, Empathy",Perfectionism,Third choose senior anyone.
|
| 420 |
+
wnelson@hotmail.com,70544bee5e638d035f39d0d0eb7bf96367b57f5e24261b8092c8bc4517999118,Jeremy Coleman,Electronics and Communication Engineering,6.6,"Sem 1: 7.46
|
| 421 |
+
|
| 422 |
+
Sem 2: 9.17
|
| 423 |
+
|
| 424 |
+
Sem 3: 9.73
|
| 425 |
+
|
| 426 |
+
Sem 4: 7.73
|
| 427 |
+
|
| 428 |
+
Sem 5: 7.13
|
| 429 |
+
|
| 430 |
+
Sem 6: 7.0",2,"JavaScript (Expert), Python (Expert), Java (Beginner)","Docker, AWS, MySQL, Node.js, React","Google Cloud Associate
|
| 431 |
+
|
| 432 |
+
AWS Certified Developer","Leadership, Teamwork",50 WPM,Book question or money final determine.,"Brown, Harris and Dougherty",http://murphy-smith.biz/,0.0,LeetCode: 315,GRE,Can mouth discover next.,1.0,2.0,0.0,Software Developer,Finance,Chennai,No,81.0,No,Medium,ISFJ,"Creativity, Persistence",Perfectionism,Author technology amount affect TV television.
|
| 433 |
+
darius05@gmail.com,d3bf3444caea8d869fcfdf779d2d4ce0aff0e73d7a25b58bf3909d52f822852e,Laura Mckinney,Electronics and Communication Engineering,8.0,"Sem 1: 7.49
|
| 434 |
+
|
| 435 |
+
Sem 2: 8.87
|
| 436 |
+
|
| 437 |
+
Sem 3: 8.2
|
| 438 |
+
|
| 439 |
+
Sem 4: 8.83
|
| 440 |
+
|
| 441 |
+
Sem 5: 6.66
|
| 442 |
+
|
| 443 |
+
Sem 6: 7.88",2,"Python (Intermediate), Ruby (Beginner), Java (Beginner)","GCP, MongoDB, Kubernetes, Git, React","Google Cloud Associate
|
| 444 |
+
|
| 445 |
+
Oracle Java Certification","Teamwork, Communication",54 WPM,Least ready gun join black job hundred bad.,Reese-Walker,http://www.schultz.com/,1.0,LeetCode: 2149,TOEFL,Road standard spring door chair culture.,0.0,1.0,0.0,AI Researcher,IT,Chennai,Yes,70.0,No,Low,ESFP,"Empathy, Creativity",Perfectionism,Check service away week physical less nor often.
|
| 446 |
+
edward17@yahoo.com,f7db3801e31dc141e04bd6d3b7b79ab5e3b653a1b653b6e4178b4cf3aa1679b4,Sonia Day,Mechanical Engineering,6.57,"Sem 1: 7.64
|
| 447 |
+
|
| 448 |
+
Sem 2: 9.3
|
| 449 |
+
|
| 450 |
+
Sem 3: 8.66
|
| 451 |
+
|
| 452 |
+
Sem 4: 9.41
|
| 453 |
+
|
| 454 |
+
Sem 5: 9.72
|
| 455 |
+
|
| 456 |
+
Sem 6: 6.81",0,"Java (Intermediate), JavaScript (Expert), C# (Beginner)","Node.js, GCP, React, Kubernetes, Docker","Google Cloud Associate
|
| 457 |
+
|
| 458 |
+
AWS Certified Developer","Communication, Leadership",70 WPM,Option goal avoid left also.,Decker-Jones,http://carpenter-best.com/,0.0,LeetCode: 2273,GRE,Training occur could painting may whatever late.,2.0,1.0,0.0,Data Scientist,IT,Hyderabad,No,62.0,Yes,Low,ENTP,"Analytical Thinking, Empathy",Shyness,Word base position always remain yard.
|
| 459 |
+
vortiz@hotmail.com,aa7c17f25d23948083b96211859e6dd044f884139df13c23dfe28fbedc92828e,Lisa Cox,Mechanical Engineering,9.14,"Sem 1: 9.16
|
| 460 |
+
|
| 461 |
+
Sem 2: 8.07
|
| 462 |
+
|
| 463 |
+
Sem 3: 9.73
|
| 464 |
+
|
| 465 |
+
Sem 4: 8.48
|
| 466 |
+
|
| 467 |
+
Sem 5: 8.72
|
| 468 |
+
|
| 469 |
+
Sem 6: 8.69",2,"C++ (Beginner), Java (Intermediate), JavaScript (Intermediate)","GCP, MongoDB, MySQL, Git, Kubernetes","Oracle Java Certification
|
| 470 |
+
|
| 471 |
+
AWS Certified Developer","Leadership, Teamwork",58 WPM,Positive at behind question exist rich prevent trade.,Cook PLC,http://ponce-hale.biz/,0.0,LeetCode: 333,TOEFL,Organization visit finally heavy.,2.0,0.0,0.0,AI Researcher,Research,Bangalore,No,86.0,Yes,Medium,ESFP,"Creativity, Analytical Thinking",Shyness,Spend prove stock school rate money.
|
| 472 |
+
henry35@yahoo.com,56e72a8119a84d8ee703f3e014af3e2d5cab70a46dd1059332176b3fb6d15c59,Jessica Cox,Computer Science and Engineering,9.34,"Sem 1: 9.43
|
| 473 |
+
|
| 474 |
+
Sem 2: 9.94
|
| 475 |
+
|
| 476 |
+
Sem 3: 6.8
|
| 477 |
+
|
| 478 |
+
Sem 4: 8.76
|
| 479 |
+
|
| 480 |
+
Sem 5: 6.64
|
| 481 |
+
|
| 482 |
+
Sem 6: 8.98",1,"C# (Beginner), Ruby (Intermediate), Go (Intermediate)","GCP, Node.js, AWS, Kubernetes, MongoDB","AWS Certified Developer
|
| 483 |
+
|
| 484 |
+
Google Cloud Associate","Communication, Teamwork",36 WPM,Choice fast small medical.,"Conley, Stephenson and Johnson",https://www.bennett.org/,3.0,LeetCode: 1263,TOEFL,Return analysis hair rest.,5.0,2.0,0.0,System Engineer,IT,Hyderabad,No,69.0,No,High,INTJ,"Persistence, Empathy",Shyness,Particular sell six doctor dream whole.
|
| 485 |
+
xhammond@yahoo.com,221356491746203cb305d390ea47dccaab3b304f1a76b9d860655b3ba1a94def,Stephanie Lee,Electronics and Communication Engineering,9.35,"Sem 1: 8.85
|
| 486 |
+
|
| 487 |
+
Sem 2: 9.4
|
| 488 |
+
|
| 489 |
+
Sem 3: 9.09
|
| 490 |
+
|
| 491 |
+
Sem 4: 8.9
|
| 492 |
+
|
| 493 |
+
Sem 5: 8.34
|
| 494 |
+
|
| 495 |
+
Sem 6: 8.76",1,"C# (Intermediate), C++ (Intermediate), Python (Beginner)","AWS, React, Node.js, MongoDB, Docker","AWS Certified Developer
|
| 496 |
+
|
| 497 |
+
Oracle Java Certification","Teamwork, Communication",48 WPM,Whom stage soon catch economic political.,Spencer-Garcia,http://hines.info/,0.0,LeetCode: 2179,GATE,Challenge join watch develop later glass ago.,5.0,1.0,0.0,AI Researcher,Education,Hyderabad,Yes,94.0,Yes,Low,ESFP,"Analytical Thinking, Creativity",Procrastination,How hear history.
|
| 498 |
+
lacey20@lowery-kennedy.com,bf1be9868e36ca698f76c50aaebfddb51e5148d7efcd3b75a71c568ebae1d54e,Danny Flores,Information Technology,9.89,"Sem 1: 8.64
|
| 499 |
+
|
| 500 |
+
Sem 2: 9.13
|
| 501 |
+
|
| 502 |
+
Sem 3: 9.24
|
| 503 |
+
|
| 504 |
+
Sem 4: 7.32
|
| 505 |
+
|
| 506 |
+
Sem 5: 7.34
|
| 507 |
+
|
| 508 |
+
Sem 6: 9.88",1,"Ruby (Expert), Java (Expert), C++ (Intermediate)","MySQL, GCP, Node.js, AWS, MongoDB","Oracle Java Certification
|
| 509 |
+
|
| 510 |
+
Google Cloud Associate","Teamwork, Communication",68 WPM,Large accept bad eight strong nature road.,"Henderson, Parsons and Young",http://www.barnes.info/,1.0,LeetCode: 1124,GATE,Book toward others administration.,5.0,1.0,1.0,Software Developer,IT,Pune,Yes,98.0,Yes,Medium,ESFP,"Creativity, Empathy",Perfectionism,Offer responsibility fact ability good number cost.
|
| 511 |
+
cmarks@hughes.com,69e02d5b6ffd5af1e251574d723596bf1921b95e6e0f5ab247d473a8f8f3af19,Kelly Ward,Information Technology,9.36,"Sem 1: 9.6
|
| 512 |
+
|
| 513 |
+
Sem 2: 9.76
|
| 514 |
+
|
| 515 |
+
Sem 3: 7.95
|
| 516 |
+
|
| 517 |
+
Sem 4: 7.89
|
| 518 |
+
|
| 519 |
+
Sem 5: 7.81
|
| 520 |
+
|
| 521 |
+
Sem 6: 7.85",0,"C++ (Intermediate), Java (Beginner), Python (Expert)","React, Kubernetes, Docker, Git, MySQL","Google Cloud Associate
|
| 522 |
+
|
| 523 |
+
AWS Certified Developer","Problem-Solving, Teamwork",69 WPM,Drop price billion old series card.,Payne-Li,http://mendoza.info/,0.0,LeetCode: 424,GATE,Fall analysis current.,2.0,0.0,0.0,AI Researcher,IT,Pune,Yes,69.0,Yes,High,ENTP,"Empathy, Persistence",Shyness,Firm financial huge.
|
| 524 |
+
michael05@martinez-richardson.biz,372711d6646e3cedd5706b39c52780c499a37abb65e9e322f6158e54fd3efea4,Kara Johnson,Computer Science and Engineering,6.89,"Sem 1: 9.67
|
| 525 |
+
|
| 526 |
+
Sem 2: 8.59
|
| 527 |
+
|
| 528 |
+
Sem 3: 6.56
|
| 529 |
+
|
| 530 |
+
Sem 4: 8.3
|
| 531 |
+
|
| 532 |
+
Sem 5: 7.35
|
| 533 |
+
|
| 534 |
+
Sem 6: 7.0",1,"Python (Beginner), C# (Expert), C++ (Intermediate)","Kubernetes, Docker, GCP, MongoDB, Git","Oracle Java Certification
|
| 535 |
+
|
| 536 |
+
AWS Certified Developer","Problem-Solving, Teamwork",32 WPM,Fund cost reality happen something entire.,Acosta Inc,https://www.carter.com/,3.0,LeetCode: 1629,TOEFL,Knowledge response coach know language.,5.0,0.0,1.0,Software Developer,Finance,Hyderabad,Yes,99.0,No,High,INTJ,"Persistence, Empathy",Procrastination,Past itself police social arm provide.
|
| 537 |
+
thomascathy@johnson-jones.com,18091453e151613cb3736a7aa601b5e805479a48b1bd910b92bd7c2501963db1,Jose Brady,Information Technology,9.41,"Sem 1: 8.9
|
| 538 |
+
|
| 539 |
+
Sem 2: 9.93
|
| 540 |
+
|
| 541 |
+
Sem 3: 8.17
|
| 542 |
+
|
| 543 |
+
Sem 4: 7.14
|
| 544 |
+
|
| 545 |
+
Sem 5: 6.97
|
| 546 |
+
|
| 547 |
+
Sem 6: 9.01",1,"Python (Beginner), C++ (Beginner), Java (Beginner)","React, GCP, MySQL, AWS, Node.js","Google Cloud Associate
|
| 548 |
+
|
| 549 |
+
Oracle Java Certification","Communication, Leadership",42 WPM,Allow check last he know baby case.,Sanders-Banks,http://www.fitzgerald.net/,2.0,LeetCode: 1562,GATE,Trial brother simple region Democrat partner.,5.0,1.0,1.0,Software Developer,Finance,Chennai,No,97.0,No,Medium,ISFJ,"Creativity, Empathy",Shyness,Customer career available common require young specific.
|
| 550 |
+
patricia22@hicks-martinez.com,002d519f44238c5132b4012b02b65cb0c00b4beb5fa4b2b6632a96b4626521e4,Victoria Contreras,Electronics and Communication Engineering,9.74,"Sem 1: 8.32
|
| 551 |
+
|
| 552 |
+
Sem 2: 9.3
|
| 553 |
+
|
| 554 |
+
Sem 3: 9.04
|
| 555 |
+
|
| 556 |
+
Sem 4: 6.78
|
| 557 |
+
|
| 558 |
+
Sem 5: 8.61
|
| 559 |
+
|
| 560 |
+
Sem 6: 9.38",2,"C++ (Beginner), Ruby (Intermediate), Python (Expert)","GCP, MongoDB, AWS, MySQL, Node.js","AWS Certified Developer
|
| 561 |
+
|
| 562 |
+
Google Cloud Associate","Leadership, Teamwork",32 WPM,So ago network hard sound.,"Anderson, Henson and Jones",https://jenkins.com/,2.0,LeetCode: 2618,None,Politics last quite general there sister.,2.0,2.0,0.0,Software Developer,Research,Pune,Yes,51.0,Yes,Low,ESFP,"Analytical Thinking, Empathy",Perfectionism,Consider whom item treat area buy check clearly.
|
| 563 |
+
kingcynthia@hotmail.com,cbc76f1468ed01edd05bdc3e6453ffd28acb1c481e23c660602f85c490cab343,Michael Reed,Information Technology,9.22,"Sem 1: 7.78
|
| 564 |
+
|
| 565 |
+
Sem 2: 7.84
|
| 566 |
+
|
| 567 |
+
Sem 3: 8.49
|
| 568 |
+
|
| 569 |
+
Sem 4: 8.62
|
| 570 |
+
|
| 571 |
+
Sem 5: 8.88
|
| 572 |
+
|
| 573 |
+
Sem 6: 9.82",1,"JavaScript (Beginner), Python (Expert), C# (Intermediate)","Node.js, React, MySQL, Kubernetes, Docker","AWS Certified Developer
|
| 574 |
+
|
| 575 |
+
Oracle Java Certification","Teamwork, Problem-Solving",63 WPM,Field move maybe collection walk child probably result.,"Morgan, Bradshaw and Williams",http://www.fry.com/,3.0,LeetCode: 2400,GATE,Short indicate police marriage phone.,2.0,1.0,1.0,Data Scientist,Finance,Chennai,Yes,57.0,Yes,High,ESFP,"Creativity, Persistence",Shyness,Politics few each southern image.
|
| 576 |
+
vmarshall@hotmail.com,ae637135d5c320d9b916c10b7252f9eba017b3c7c4d2ce15b667a30a906fabae,Michael Moore,Computer Science and Engineering,9.34,"Sem 1: 9.89
|
| 577 |
+
|
| 578 |
+
Sem 2: 9.95
|
| 579 |
+
|
| 580 |
+
Sem 3: 8.84
|
| 581 |
+
|
| 582 |
+
Sem 4: 8.98
|
| 583 |
+
|
| 584 |
+
Sem 5: 8.42
|
| 585 |
+
|
| 586 |
+
Sem 6: 7.52",1,"Ruby (Intermediate), Java (Expert), Go (Beginner)","Docker, AWS, Node.js, MongoDB, React","Google Cloud Associate
|
| 587 |
+
|
| 588 |
+
AWS Certified Developer","Leadership, Problem-Solving",66 WPM,Safe team wish candidate have no.,Allen-Martinez,https://www.davis.biz/,2.0,LeetCode: 2014,GRE,Industry while total spend value return couple city.,4.0,0.0,0.0,System Engineer,Research,Chennai,No,99.0,No,Low,INTJ,"Creativity, Empathy",Perfectionism,Level these market bed hotel lead drive.
|
| 589 |
+
amanda16@gmail.com,9b23be4dcfb3a5a1b7a4c4ba8ff4f17c30c047b627cb3e84a6aa504202588316,Amber Campbell,Mechanical Engineering,8.13,"Sem 1: 8.31
|
| 590 |
+
|
| 591 |
+
Sem 2: 6.95
|
| 592 |
+
|
| 593 |
+
Sem 3: 9.4
|
| 594 |
+
|
| 595 |
+
Sem 4: 8.43
|
| 596 |
+
|
| 597 |
+
Sem 5: 8.56
|
| 598 |
+
|
| 599 |
+
Sem 6: 9.19",0,"JavaScript (Beginner), C# (Expert), Python (Beginner)","GCP, Kubernetes, Docker, MySQL, Node.js","Google Cloud Associate
|
| 600 |
+
|
| 601 |
+
Oracle Java Certification","Communication, Teamwork",42 WPM,Shake hand hundred now crime network.,Hughes Group,https://www.hester.com/,2.0,LeetCode: 612,TOEFL,Newspaper hand certain own husband American.,4.0,2.0,0.0,Data Scientist,Education,Hyderabad,No,86.0,Yes,High,INTJ,"Analytical Thinking, Persistence",Procrastination,Case four listen.
|
| 602 |
+
francisco94@hotmail.com,b79acdf5afca82a5ac6c77181214ab05681c5255aa9e566b02aac0b44adb995b,Larry Robertson,Information Technology,9.18,"Sem 1: 7.96
|
| 603 |
+
|
| 604 |
+
Sem 2: 8.74
|
| 605 |
+
|
| 606 |
+
Sem 3: 8.24
|
| 607 |
+
|
| 608 |
+
Sem 4: 8.7
|
| 609 |
+
|
| 610 |
+
Sem 5: 7.51
|
| 611 |
+
|
| 612 |
+
Sem 6: 9.85",1,"Java (Intermediate), Go (Intermediate), JavaScript (Beginner)","Git, Kubernetes, AWS, Node.js, React","Google Cloud Associate
|
| 613 |
+
|
| 614 |
+
AWS Certified Developer","Leadership, Problem-Solving",39 WPM,Mother remember feel staff happy purpose woman.,"Parker, Roach and Wiggins",http://coffey-patton.org/,2.0,LeetCode: 1407,TOEFL,Dinner anything lose modern return simple herself.,3.0,0.0,1.0,Software Developer,Finance,Hyderabad,No,57.0,No,Medium,ENTP,"Creativity, Analytical Thinking",Perfectionism,All way body affect finish.
|
| 615 |
+
thorntonapril@hotmail.com,965ba874764988a2d924436c4bb5230eee9995bbb17b0abb6a61a92812472843,Michael Jenkins,Electronics and Communication Engineering,9.81,"Sem 1: 9.52
|
| 616 |
+
|
| 617 |
+
Sem 2: 7.96
|
| 618 |
+
|
| 619 |
+
Sem 3: 9.87
|
| 620 |
+
|
| 621 |
+
Sem 4: 9.66
|
| 622 |
+
|
| 623 |
+
Sem 5: 9.35
|
| 624 |
+
|
| 625 |
+
Sem 6: 9.77",2,"C++ (Intermediate), Java (Expert), Go (Intermediate)","MySQL, GCP, AWS, Git, React","Google Cloud Associate
|
| 626 |
+
|
| 627 |
+
Oracle Java Certification","Teamwork, Communication",67 WPM,Moment finish community treatment garden great sign.,"Becker, Lara and Baker",https://www.ramirez.com/,2.0,LeetCode: 299,GATE,Side relate real major look.,2.0,1.0,1.0,System Engineer,IT,Bangalore,No,58.0,No,Low,ISFJ,"Empathy, Creativity",Perfectionism,Value somebody event business quality here woman.
|
| 628 |
+
robertsjennifer@yahoo.com,88610e29d42c5e88dd640075251cd071d675b12ecf4d06539937d8c5bc6e9413,Tina Ballard,Mechanical Engineering,6.68,"Sem 1: 8.47
|
| 629 |
+
|
| 630 |
+
Sem 2: 7.77
|
| 631 |
+
|
| 632 |
+
Sem 3: 7.51
|
| 633 |
+
|
| 634 |
+
Sem 4: 7.85
|
| 635 |
+
|
| 636 |
+
Sem 5: 8.08
|
| 637 |
+
|
| 638 |
+
Sem 6: 8.42",2,"Go (Beginner), C# (Beginner), Python (Intermediate)","React, MongoDB, GCP, Kubernetes, Docker","AWS Certified Developer
|
| 639 |
+
|
| 640 |
+
Google Cloud Associate","Communication, Problem-Solving",32 WPM,Section degree still even no.,Taylor-Gilbert,http://www.santiago.com/,1.0,LeetCode: 1464,None,Appear including response beyond side.,4.0,1.0,0.0,Data Scientist,Finance,Pune,Yes,75.0,No,Low,ISFJ,"Empathy, Persistence",Procrastination,Who within citizen.
|
| 641 |
+
manuel01@andrews.com,28db82072eb8f01aadde28cd56b3ea4559588547eab5ea4adb3125da332ad540,Shirley Alvarez,Mechanical Engineering,9.36,"Sem 1: 7.79
|
| 642 |
+
|
| 643 |
+
Sem 2: 8.86
|
| 644 |
+
|
| 645 |
+
Sem 3: 9.93
|
| 646 |
+
|
| 647 |
+
Sem 4: 8.54
|
| 648 |
+
|
| 649 |
+
Sem 5: 9.29
|
| 650 |
+
|
| 651 |
+
Sem 6: 9.04",2,"Go (Intermediate), Python (Intermediate), C# (Expert)","AWS, Git, GCP, MongoDB, Docker","Oracle Java Certification
|
| 652 |
+
|
| 653 |
+
Google Cloud Associate","Teamwork, Leadership",45 WPM,Individual study value already.,French-Lopez,https://www.evans.com/,0.0,LeetCode: 2445,GATE,Expect writer myself management voice surface.,1.0,0.0,1.0,System Engineer,Research,Hyderabad,No,94.0,Yes,Medium,ESFP,"Analytical Thinking, Persistence",Impatience,Evening speak former room possible responsibility add.
|
| 654 |
+
cherylfowler@wilcox-robertson.com,d881043311ef3b6db037d6656cd033f7e89d49a69a9c5663744e49e02970fdb8,Edward Craig,Information Technology,8.46,"Sem 1: 9.99
|
| 655 |
+
|
| 656 |
+
Sem 2: 8.17
|
| 657 |
+
|
| 658 |
+
Sem 3: 7.82
|
| 659 |
+
|
| 660 |
+
Sem 4: 9.85
|
| 661 |
+
|
| 662 |
+
Sem 5: 8.11
|
| 663 |
+
|
| 664 |
+
Sem 6: 8.37",2,"C++ (Expert), Go (Intermediate), Ruby (Beginner)","AWS, GCP, MySQL, Kubernetes, Docker","Google Cloud Associate
|
| 665 |
+
|
| 666 |
+
Oracle Java Certification","Teamwork, Leadership",61 WPM,Continue cell food easy.,Reyes-Griffin,https://aguilar-berry.com/,2.0,LeetCode: 2065,TOEFL,Realize artist brother fill if maybe.,4.0,2.0,1.0,System Engineer,IT,Chennai,No,72.0,Yes,Medium,INTJ,"Persistence, Empathy",Perfectionism,Real police wait happen determine.
|
| 667 |
+
emiles@hotmail.com,f7a6b6df3b8c2e3cb4e77cea718b44a48b04b586023019c57744f537b3177d03,Karen Gibson,Electronics and Communication Engineering,9.73,"Sem 1: 8.8
|
| 668 |
+
|
| 669 |
+
Sem 2: 9.12
|
| 670 |
+
|
| 671 |
+
Sem 3: 7.25
|
| 672 |
+
|
| 673 |
+
Sem 4: 9.4
|
| 674 |
+
|
| 675 |
+
Sem 5: 7.45
|
| 676 |
+
|
| 677 |
+
Sem 6: 8.47",1,"Java (Expert), Python (Expert), C# (Beginner)","AWS, Git, React, GCP, Docker","Oracle Java Certification
|
| 678 |
+
|
| 679 |
+
AWS Certified Developer","Communication, Problem-Solving",56 WPM,Seven quite other skin moment.,"Padilla, Miller and Elliott",http://www.herrera.info/,2.0,LeetCode: 2034,GATE,Quite response major together.,5.0,0.0,0.0,Data Scientist,Research,Chennai,No,91.0,Yes,Medium,ISFJ,"Persistence, Empathy",Perfectionism,Speak law message lead around left southern.
|
| 680 |
+
williamsmelvin@weaver.com,ec3152388fdb28c35d993726866f7724654551d2323f6ca0872ccbdb125a1318,Jennifer Velasquez,Computer Science and Engineering,8.78,"Sem 1: 7.31
|
| 681 |
+
|
| 682 |
+
Sem 2: 9.09
|
| 683 |
+
|
| 684 |
+
Sem 3: 9.48
|
| 685 |
+
|
| 686 |
+
Sem 4: 6.63
|
| 687 |
+
|
| 688 |
+
Sem 5: 9.73
|
| 689 |
+
|
| 690 |
+
Sem 6: 7.96",0,"Python (Beginner), JavaScript (Expert), Go (Intermediate)","Git, MongoDB, Kubernetes, GCP, React","AWS Certified Developer
|
| 691 |
+
|
| 692 |
+
Google Cloud Associate","Leadership, Teamwork",64 WPM,All important shoulder she within position inside.,West-Stark,https://vega.net/,3.0,LeetCode: 649,None,President girl condition Mr.,2.0,0.0,0.0,System Engineer,Education,Chennai,No,95.0,Yes,High,ISFJ,"Persistence, Empathy",Impatience,Camera without strong series without leg rest.
|
| 693 |
+
eric31@gmail.com,1b6c70ffcdff997148095b8d12d36741df350b7ed8276a18116df126cc30e888,James Hall,Information Technology,8.64,"Sem 1: 8.74
|
| 694 |
+
|
| 695 |
+
Sem 2: 7.92
|
| 696 |
+
|
| 697 |
+
Sem 3: 8.0
|
| 698 |
+
|
| 699 |
+
Sem 4: 7.65
|
| 700 |
+
|
| 701 |
+
Sem 5: 7.9
|
| 702 |
+
|
| 703 |
+
Sem 6: 6.83",0,"JavaScript (Beginner), C++ (Intermediate), Java (Intermediate)","AWS, MySQL, Node.js, Kubernetes, React","Google Cloud Associate
|
| 704 |
+
|
| 705 |
+
AWS Certified Developer","Leadership, Problem-Solving",53 WPM,Past view threat drive attack order.,Harper-Warner,http://www.williams.com/,1.0,LeetCode: 354,GATE,Mean eye staff rule.,3.0,1.0,0.0,AI Researcher,Finance,Bangalore,No,73.0,Yes,High,ENTP,"Empathy, Analytical Thinking",Shyness,Officer significant stand down then worry.
|
| 706 |
+
dpeters@david-powers.net,0d2f8a1ea0b456331f211200548edfdb61e7f89ecc1ed0c30ece12e4e5cecf52,Jennifer Hill,Electronics and Communication Engineering,7.96,"Sem 1: 8.42
|
| 707 |
+
|
| 708 |
+
Sem 2: 8.15
|
| 709 |
+
|
| 710 |
+
Sem 3: 8.38
|
| 711 |
+
|
| 712 |
+
Sem 4: 8.82
|
| 713 |
+
|
| 714 |
+
Sem 5: 7.26
|
| 715 |
+
|
| 716 |
+
Sem 6: 7.37",2,"Ruby (Intermediate), Python (Expert), C# (Expert)","React, Docker, GCP, Git, MongoDB","Oracle Java Certification
|
| 717 |
+
|
| 718 |
+
AWS Certified Developer","Teamwork, Communication",50 WPM,Impact feel contain Mrs drive different.,"Thomas, Ford and Brown",https://moreno.com/,3.0,LeetCode: 576,GRE,Two suggest begin right.,5.0,2.0,1.0,Software Developer,Research,Bangalore,No,58.0,No,Medium,INTJ,"Empathy, Persistence",Procrastination,Appear help painting always authority.
|
| 719 |
+
vclark@krueger-smith.com,00c8c6b46635800246724d11c19c7c44fd29582bb8adb24ec65e402efc6bbc8c,Laurie Powers,Computer Science and Engineering,7.89,"Sem 1: 9.36
|
| 720 |
+
|
| 721 |
+
Sem 2: 9.11
|
| 722 |
+
|
| 723 |
+
Sem 3: 8.52
|
| 724 |
+
|
| 725 |
+
Sem 4: 6.66
|
| 726 |
+
|
| 727 |
+
Sem 5: 7.71
|
| 728 |
+
|
| 729 |
+
Sem 6: 6.72",0,"Python (Intermediate), JavaScript (Intermediate), Ruby (Beginner)","Kubernetes, Node.js, MongoDB, AWS, React","Google Cloud Associate
|
| 730 |
+
|
| 731 |
+
Oracle Java Certification","Communication, Leadership",64 WPM,Section senior trial receive.,"Harris, Herman and Arnold",https://ferguson-howard.com/,1.0,LeetCode: 2776,TOEFL,Mention market better wonder light style.,0.0,0.0,1.0,Data Scientist,Education,Bangalore,Yes,69.0,No,Low,ESFP,"Empathy, Analytical Thinking",Impatience,Have including none determine certainly.
|
| 732 |
+
elijah53@yahoo.com,4c961514a4537b09daf6057cc17b2c3fd9ae30f95d777ae4f9e965d2364c47a8,Timothy Riley,Mechanical Engineering,7.71,"Sem 1: 7.46
|
| 733 |
+
|
| 734 |
+
Sem 2: 9.78
|
| 735 |
+
|
| 736 |
+
Sem 3: 9.04
|
| 737 |
+
|
| 738 |
+
Sem 4: 6.89
|
| 739 |
+
|
| 740 |
+
Sem 5: 9.33
|
| 741 |
+
|
| 742 |
+
Sem 6: 7.97",0,"Java (Beginner), Ruby (Expert), Python (Beginner)","MySQL, Git, Docker, React, MongoDB","Google Cloud Associate
|
| 743 |
+
|
| 744 |
+
Oracle Java Certification","Teamwork, Leadership",43 WPM,Material pressure range either start.,"May, Henry and Jackson",https://www.cortez.com/,0.0,LeetCode: 673,TOEFL,Wrong whatever model stuff avoid stand any.,1.0,2.0,1.0,System Engineer,Education,Pune,Yes,92.0,Yes,Medium,ISFJ,"Persistence, Analytical Thinking",Impatience,Include successful discuss.
|
| 745 |
+
williamsonelizabeth@hotmail.com,52260b17e66fb24a1d9453a9c0ba52d9de0f9fb38faeee3f972ad45b687788cb,Alexa Wagner,Mechanical Engineering,8.45,"Sem 1: 6.66
|
| 746 |
+
|
| 747 |
+
Sem 2: 7.71
|
| 748 |
+
|
| 749 |
+
Sem 3: 8.75
|
| 750 |
+
|
| 751 |
+
Sem 4: 7.83
|
| 752 |
+
|
| 753 |
+
Sem 5: 8.34
|
| 754 |
+
|
| 755 |
+
Sem 6: 8.94",1,"Java (Beginner), C++ (Expert), JavaScript (Intermediate)","AWS, MongoDB, Kubernetes, React, Docker","Google Cloud Associate
|
| 756 |
+
|
| 757 |
+
AWS Certified Developer","Problem-Solving, Teamwork",65 WPM,Administration mother in admit reveal movie expert.,"Li, Craig and Drake",http://www.warren.com/,1.0,LeetCode: 1690,GRE,Money spring environment however health image north wrong.,2.0,0.0,1.0,Software Developer,Research,Pune,Yes,84.0,Yes,High,ISFJ,"Empathy, Persistence",Perfectionism,Feel stock ball yard practice.
|
| 758 |
+
walshjacqueline@gmail.com,4dc29081a8ff8675c0dca05b29cbe37fa6464455891f18b5c723689967a58011,Jared Bennett,Computer Science and Engineering,7.16,"Sem 1: 9.17
|
| 759 |
+
|
| 760 |
+
Sem 2: 9.04
|
| 761 |
+
|
| 762 |
+
Sem 3: 8.46
|
| 763 |
+
|
| 764 |
+
Sem 4: 8.18
|
| 765 |
+
|
| 766 |
+
Sem 5: 9.54
|
| 767 |
+
|
| 768 |
+
Sem 6: 7.67",0,"Java (Expert), Ruby (Intermediate), Python (Beginner)","AWS, Node.js, Docker, GCP, Kubernetes","Google Cloud Associate
|
| 769 |
+
|
| 770 |
+
Oracle Java Certification","Problem-Solving, Leadership",52 WPM,Population former with wind thus try.,Lewis Ltd,https://glass.com/,2.0,LeetCode: 1171,TOEFL,Nor allow up fire which onto sell.,4.0,1.0,1.0,Software Developer,Research,Pune,Yes,73.0,No,Medium,INTJ,"Creativity, Persistence",Impatience,Up federal nor note support quality.
|
| 771 |
+
brian63@peterson.org,1aa4774c7cec3624b5bfac5f15a9cc73ea335186fb77f35fe1c9744eb81ad523,Janet Singh,Computer Science and Engineering,7.41,"Sem 1: 9.77
|
| 772 |
+
|
| 773 |
+
Sem 2: 8.53
|
| 774 |
+
|
| 775 |
+
Sem 3: 7.96
|
| 776 |
+
|
| 777 |
+
Sem 4: 7.03
|
| 778 |
+
|
| 779 |
+
Sem 5: 7.65
|
| 780 |
+
|
| 781 |
+
Sem 6: 7.83",0,"JavaScript (Intermediate), C# (Intermediate), C++ (Expert)","MySQL, MongoDB, Docker, React, Kubernetes","AWS Certified Developer
|
| 782 |
+
|
| 783 |
+
Oracle Java Certification","Problem-Solving, Communication",64 WPM,Ahead event yeah make green wait.,Lopez-Willis,https://www.phillips.com/,0.0,LeetCode: 2246,GATE,Here six child hope.,0.0,2.0,0.0,Software Developer,Research,Hyderabad,Yes,54.0,Yes,High,ENTP,"Empathy, Creativity",Perfectionism,Blood accept final growth especially car.
|
| 784 |
+
johnsonmichael@gmail.com,71f86bd9964867fae2402e9de0e041461b0cd177e674bd11e2f8764098788839,Jerry Peters,Mechanical Engineering,8.81,"Sem 1: 6.56
|
| 785 |
+
|
| 786 |
+
Sem 2: 8.36
|
| 787 |
+
|
| 788 |
+
Sem 3: 7.94
|
| 789 |
+
|
| 790 |
+
Sem 4: 6.56
|
| 791 |
+
|
| 792 |
+
Sem 5: 9.03
|
| 793 |
+
|
| 794 |
+
Sem 6: 8.38",1,"Python (Beginner), C# (Beginner), JavaScript (Beginner)","MongoDB, Kubernetes, Docker, Node.js, GCP","Oracle Java Certification
|
| 795 |
+
|
| 796 |
+
Google Cloud Associate","Leadership, Teamwork",55 WPM,Tell activity including single right nice.,Armstrong and Sons,https://www.adams.info/,0.0,LeetCode: 1628,None,As itself inside machine.,3.0,2.0,0.0,Data Scientist,Finance,Bangalore,Yes,55.0,No,Medium,ESFP,"Empathy, Analytical Thinking",Perfectionism,Guess want result many.
|
| 797 |
+
ncook@brock-rivera.com,e8fb86e82425719a03be05dacbd54e031c9beeee4af7e75780ded5c99dc5376c,Judith Taylor,Information Technology,6.79,"Sem 1: 9.46
|
| 798 |
+
|
| 799 |
+
Sem 2: 8.76
|
| 800 |
+
|
| 801 |
+
Sem 3: 7.66
|
| 802 |
+
|
| 803 |
+
Sem 4: 9.92
|
| 804 |
+
|
| 805 |
+
Sem 5: 9.91
|
| 806 |
+
|
| 807 |
+
Sem 6: 9.63",0,"Java (Intermediate), Ruby (Intermediate), C# (Beginner)","Docker, GCP, MySQL, Node.js, Git","AWS Certified Developer
|
| 808 |
+
|
| 809 |
+
Google Cloud Associate","Communication, Problem-Solving",67 WPM,Carry fly water cut fire who why fact.,"Chen, Faulkner and Casey",https://velasquez-long.com/,1.0,LeetCode: 1731,GATE,Customer young conference should agree road wall.,2.0,0.0,0.0,AI Researcher,Finance,Chennai,Yes,100.0,Yes,Low,ISFJ,"Analytical Thinking, Empathy",Shyness,Just fact realize standard somebody.
|
| 810 |
+
donna66@cole.info,e3922a22ab2eb77a4f77feffde7cee4ac4f73a8dc39d522794bbda148630cfc1,Jonathan Schultz,Information Technology,9.44,"Sem 1: 7.69
|
| 811 |
+
|
| 812 |
+
Sem 2: 9.19
|
| 813 |
+
|
| 814 |
+
Sem 3: 9.84
|
| 815 |
+
|
| 816 |
+
Sem 4: 7.89
|
| 817 |
+
|
| 818 |
+
Sem 5: 9.21
|
| 819 |
+
|
| 820 |
+
Sem 6: 6.6",1,"Ruby (Beginner), JavaScript (Intermediate), Go (Expert)","Node.js, MongoDB, Docker, React, GCP","Oracle Java Certification
|
| 821 |
+
|
| 822 |
+
Google Cloud Associate","Communication, Leadership",48 WPM,Media turn reality myself so growth time.,"Wheeler, Rocha and Rodriguez",http://holland.org/,1.0,LeetCode: 401,GATE,Whom former someone black better develop.,2.0,0.0,1.0,Data Scientist,Research,Pune,No,56.0,Yes,High,ISFJ,"Empathy, Creativity",Procrastination,Newspaper reach determine hear leg quickly real.
|
| 823 |
+
fknapp@gmail.com,4f9c13c9b0e39defddd0f1ab86f4aee8c6145c6be2fe006bad830eab93dcfb73,Zachary Webb,Computer Science and Engineering,6.96,"Sem 1: 7.16
|
| 824 |
+
|
| 825 |
+
Sem 2: 8.07
|
| 826 |
+
|
| 827 |
+
Sem 3: 8.44
|
| 828 |
+
|
| 829 |
+
Sem 4: 7.93
|
| 830 |
+
|
| 831 |
+
Sem 5: 6.59
|
| 832 |
+
|
| 833 |
+
Sem 6: 7.74",0,"C# (Intermediate), Ruby (Beginner), C++ (Intermediate)","Node.js, MongoDB, MySQL, Git, GCP","AWS Certified Developer
|
| 834 |
+
|
| 835 |
+
Oracle Java Certification","Problem-Solving, Communication",38 WPM,Give gas six miss.,Alvarez-Kim,https://evans.com/,2.0,LeetCode: 1333,TOEFL,Support possible quality.,3.0,0.0,0.0,Data Scientist,Research,Pune,No,69.0,No,High,ISFJ,"Persistence, Analytical Thinking",Shyness,Upon scientist might necessary.
|
| 836 |
+
jacobsandoval@yahoo.com,605bd6c2f9b01bc5bdbc83ffdfb7bd9ef8d523c5c3f006b659155e2d250c8f0b,Jeffery Murray,Information Technology,8.1,"Sem 1: 6.97
|
| 837 |
+
|
| 838 |
+
Sem 2: 6.52
|
| 839 |
+
|
| 840 |
+
Sem 3: 7.88
|
| 841 |
+
|
| 842 |
+
Sem 4: 9.45
|
| 843 |
+
|
| 844 |
+
Sem 5: 7.83
|
| 845 |
+
|
| 846 |
+
Sem 6: 9.52",1,"C++ (Beginner), JavaScript (Intermediate), C# (Intermediate)","AWS, MySQL, Kubernetes, Docker, MongoDB","Google Cloud Associate
|
| 847 |
+
|
| 848 |
+
Oracle Java Certification","Problem-Solving, Leadership",45 WPM,Third last involve above Democrat everything region somebody.,"Garcia, Wiggins and Lopez",https://www.wilson-lambert.info/,2.0,LeetCode: 1640,TOEFL,Whole finish home hotel box goal leader.,3.0,1.0,0.0,Data Scientist,Education,Bangalore,No,95.0,Yes,Medium,ISFJ,"Analytical Thinking, Creativity",Shyness,Sport relationship father pass.
|
| 849 |
+
whiteheather@hotmail.com,2930a09094a8d42998fdd105f021898c09b8dcb2ee65dffb76299e5f29144def,Cesar Wilson,Information Technology,8.72,"Sem 1: 7.35
|
| 850 |
+
|
| 851 |
+
Sem 2: 8.81
|
| 852 |
+
|
| 853 |
+
Sem 3: 9.0
|
| 854 |
+
|
| 855 |
+
Sem 4: 9.26
|
| 856 |
+
|
| 857 |
+
Sem 5: 6.76
|
| 858 |
+
|
| 859 |
+
Sem 6: 9.97",1,"C# (Expert), JavaScript (Expert), Ruby (Intermediate)","MongoDB, Git, Node.js, Kubernetes, GCP","Oracle Java Certification
|
| 860 |
+
|
| 861 |
+
AWS Certified Developer","Communication, Problem-Solving",52 WPM,Case himself control player really population yourself never.,Roberts-Lopez,https://www.crane-washington.com/,1.0,LeetCode: 2750,GATE,White measure manager range indeed style.,4.0,2.0,1.0,System Engineer,Research,Bangalore,Yes,56.0,No,High,ENTP,"Empathy, Creativity",Shyness,Cold not somebody determine allow different eye.
|
| 862 |
+
armstrongjoseph@hotmail.com,e49ce57cabf898d62d9a320ade7516a5027af4506df7b5c609fbbcc3b10e3cb2,Krystal Barton,Mechanical Engineering,9.2,"Sem 1: 8.56
|
| 863 |
+
|
| 864 |
+
Sem 2: 8.25
|
| 865 |
+
|
| 866 |
+
Sem 3: 7.71
|
| 867 |
+
|
| 868 |
+
Sem 4: 6.59
|
| 869 |
+
|
| 870 |
+
Sem 5: 6.87
|
| 871 |
+
|
| 872 |
+
Sem 6: 7.96",0,"Python (Intermediate), Go (Intermediate), Java (Intermediate)","MySQL, AWS, GCP, MongoDB, Kubernetes","Google Cloud Associate
|
| 873 |
+
|
| 874 |
+
AWS Certified Developer","Problem-Solving, Leadership",58 WPM,My series service kid despite interesting.,"Greer, Potter and Evans",http://bailey-montoya.info/,2.0,LeetCode: 375,TOEFL,Simply down specific onto.,0.0,2.0,0.0,Software Developer,Finance,Bangalore,Yes,97.0,Yes,Low,ENTP,"Creativity, Empathy",Shyness,Technology particular into pattern size spend.
|
| 875 |
+
tiffany44@adams.com,902527015e941225dba2d5a2a0d41f8b1dc2188493b585967cf153ebc754d320,Laura Patel,Mechanical Engineering,7.31,"Sem 1: 7.92
|
| 876 |
+
|
| 877 |
+
Sem 2: 7.15
|
| 878 |
+
|
| 879 |
+
Sem 3: 8.74
|
| 880 |
+
|
| 881 |
+
Sem 4: 8.01
|
| 882 |
+
|
| 883 |
+
Sem 5: 6.6
|
| 884 |
+
|
| 885 |
+
Sem 6: 8.65",0,"JavaScript (Intermediate), C# (Beginner), Ruby (Expert)","AWS, MongoDB, Kubernetes, React, Git","Oracle Java Certification
|
| 886 |
+
|
| 887 |
+
AWS Certified Developer","Teamwork, Problem-Solving",50 WPM,Try yeah term camera tend economic.,"Morris, Wright and Bridges",https://ray.biz/,1.0,LeetCode: 1974,GATE,Later plant they behavior middle everything.,2.0,2.0,1.0,System Engineer,Research,Chennai,Yes,72.0,No,Medium,ENTP,"Persistence, Empathy",Perfectionism,Lawyer maintain old than suggest behavior.
|
| 888 |
+
brobinson@simpson.com,83593749421757f1edcbc9d70d631978874f8d1955bf5e9435f281d654714909,Madison Terry,Information Technology,7.6,"Sem 1: 7.34
|
| 889 |
+
|
| 890 |
+
Sem 2: 6.91
|
| 891 |
+
|
| 892 |
+
Sem 3: 7.81
|
| 893 |
+
|
| 894 |
+
Sem 4: 6.99
|
| 895 |
+
|
| 896 |
+
Sem 5: 7.86
|
| 897 |
+
|
| 898 |
+
Sem 6: 8.59",2,"JavaScript (Intermediate), Ruby (Expert), Java (Expert)","Kubernetes, MongoDB, AWS, MySQL, Docker","AWS Certified Developer
|
| 899 |
+
|
| 900 |
+
Google Cloud Associate","Problem-Solving, Leadership",33 WPM,Candidate system small thus several animal phone.,Smith-Noble,http://smith-rubio.com/,2.0,LeetCode: 139,None,Think few themselves theory.,1.0,0.0,1.0,AI Researcher,Research,Chennai,No,95.0,No,Medium,ENTP,"Analytical Thinking, Persistence",Perfectionism,Pressure economy head tough.
|
| 901 |
+
trios@smith.com,000c88700161f93a05d033e9f6e09eb0b3e8b1504a3fa4b1024fc9aa58aee2fc,James Torres,Information Technology,7.52,"Sem 1: 7.46
|
| 902 |
+
|
| 903 |
+
Sem 2: 8.38
|
| 904 |
+
|
| 905 |
+
Sem 3: 7.09
|
| 906 |
+
|
| 907 |
+
Sem 4: 8.1
|
| 908 |
+
|
| 909 |
+
Sem 5: 9.1
|
| 910 |
+
|
| 911 |
+
Sem 6: 9.18",2,"C# (Beginner), Python (Intermediate), Ruby (Expert)","React, Git, Node.js, MongoDB, AWS","Oracle Java Certification
|
| 912 |
+
|
| 913 |
+
AWS Certified Developer","Problem-Solving, Communication",45 WPM,Mind knowledge account gas building.,Benson-Woods,http://cross.com/,2.0,LeetCode: 232,None,Happen federal him spend themselves political.,2.0,1.0,0.0,AI Researcher,IT,Hyderabad,Yes,97.0,No,Low,ESFP,"Creativity, Persistence",Impatience,Attention none particular clearly.
|
| 914 |
+
fheath@gmail.com,1c8a5a6effdff58b2b24536346821df5aade1ed4e7303edd88bbdb2971c6e618,Daniel Goodman,Information Technology,9.35,"Sem 1: 9.32
|
| 915 |
+
|
| 916 |
+
Sem 2: 8.5
|
| 917 |
+
|
| 918 |
+
Sem 3: 8.36
|
| 919 |
+
|
| 920 |
+
Sem 4: 8.59
|
| 921 |
+
|
| 922 |
+
Sem 5: 7.09
|
| 923 |
+
|
| 924 |
+
Sem 6: 9.93",1,"C++ (Expert), C# (Expert), Ruby (Beginner)","Kubernetes, Node.js, Git, MongoDB, Docker","Oracle Java Certification
|
| 925 |
+
|
| 926 |
+
AWS Certified Developer","Teamwork, Communication",50 WPM,Operation himself white fire.,Wright Ltd,http://www.burke.com/,1.0,LeetCode: 2869,None,Day parent country hot position.,3.0,0.0,1.0,AI Researcher,Research,Chennai,Yes,90.0,Yes,Medium,ISFJ,"Persistence, Creativity",Shyness,Manager both matter order month.
|
| 927 |
+
kvalencia@diaz-vega.info,ebd26a86db2ec2b6e74de5e8878acd4b8b1ddfa2e8178dd93618f1f48d536be4,Victoria Peck,Electronics and Communication Engineering,8.54,"Sem 1: 9.54
|
| 928 |
+
|
| 929 |
+
Sem 2: 9.47
|
| 930 |
+
|
| 931 |
+
Sem 3: 6.83
|
| 932 |
+
|
| 933 |
+
Sem 4: 9.9
|
| 934 |
+
|
| 935 |
+
Sem 5: 8.72
|
| 936 |
+
|
| 937 |
+
Sem 6: 8.94",0,"Ruby (Beginner), C# (Intermediate), JavaScript (Beginner)","MySQL, GCP, Kubernetes, Node.js, React","Oracle Java Certification
|
| 938 |
+
|
| 939 |
+
AWS Certified Developer","Problem-Solving, Teamwork",33 WPM,Admit attack energy always.,Fry Group,https://miles-miller.net/,0.0,LeetCode: 507,None,Pattern everyone finally memory data space movie.,0.0,0.0,0.0,AI Researcher,Research,Bangalore,No,62.0,Yes,Low,ISFJ,"Creativity, Empathy",Perfectionism,Only shake power poor financial join.
|
| 940 |
+
chavezchelsea@yahoo.com,39d5e5988d8aef599d3d3d5053adbfe3505af0862915a8c8137b44a5691c98df,Cynthia Sanchez,Electronics and Communication Engineering,7.38,"Sem 1: 7.8
|
| 941 |
+
|
| 942 |
+
Sem 2: 9.66
|
| 943 |
+
|
| 944 |
+
Sem 3: 7.08
|
| 945 |
+
|
| 946 |
+
Sem 4: 7.89
|
| 947 |
+
|
| 948 |
+
Sem 5: 7.57
|
| 949 |
+
|
| 950 |
+
Sem 6: 8.95",0,"JavaScript (Expert), Go (Beginner), Python (Beginner)","AWS, MySQL, Git, Docker, GCP","AWS Certified Developer
|
| 951 |
+
|
| 952 |
+
Google Cloud Associate","Communication, Problem-Solving",51 WPM,Budget remain reduce clearly.,Mills-Logan,https://www.martinez-norman.com/,0.0,LeetCode: 1829,GRE,Sign ahead southern evening.,3.0,0.0,0.0,AI Researcher,IT,Bangalore,Yes,70.0,No,Medium,ENTP,"Empathy, Analytical Thinking",Impatience,Enjoy window physical many.
|
| 953 |
+
eric19@sharp.com,c79140f46dd31ef71f0b3fbf2c29fe0357597ac2a632e3c080a3b93d1464e58e,Amy Villarreal,Computer Science and Engineering,8.36,"Sem 1: 6.53
|
| 954 |
+
|
| 955 |
+
Sem 2: 8.78
|
| 956 |
+
|
| 957 |
+
Sem 3: 8.04
|
| 958 |
+
|
| 959 |
+
Sem 4: 9.03
|
| 960 |
+
|
| 961 |
+
Sem 5: 8.7
|
| 962 |
+
|
| 963 |
+
Sem 6: 7.03",1,"C# (Beginner), Go (Beginner), JavaScript (Beginner)","Kubernetes, Docker, GCP, React, AWS","Google Cloud Associate
|
| 964 |
+
|
| 965 |
+
Oracle Java Certification","Leadership, Communication",45 WPM,Each line him.,White Inc,https://www.wright-moon.com/,2.0,LeetCode: 2740,GATE,Step number budget pull apply.,1.0,2.0,1.0,Software Developer,Finance,Hyderabad,Yes,97.0,No,Medium,INTJ,"Creativity, Empathy",Shyness,Source wonder west attention let.
|
| 966 |
+
woodkelly@yahoo.com,5cadfebe02ef8ac4870eb822786c818d2a0cef52166231bd62027405f8edf96b,Ryan Murphy,Computer Science and Engineering,7.34,"Sem 1: 8.73
|
| 967 |
+
|
| 968 |
+
Sem 2: 6.75
|
| 969 |
+
|
| 970 |
+
Sem 3: 9.61
|
| 971 |
+
|
| 972 |
+
Sem 4: 6.54
|
| 973 |
+
|
| 974 |
+
Sem 5: 7.76
|
| 975 |
+
|
| 976 |
+
Sem 6: 7.61",1,"Ruby (Intermediate), C# (Expert), JavaScript (Expert)","Kubernetes, MySQL, Node.js, Git, React","Oracle Java Certification
|
| 977 |
+
|
| 978 |
+
AWS Certified Developer","Communication, Teamwork",43 WPM,Less option management significant crime.,"Hodges, Sanchez and Smith",https://www.weaver.com/,0.0,LeetCode: 347,None,Ability price support road billion morning.,4.0,1.0,1.0,AI Researcher,Research,Bangalore,Yes,67.0,Yes,Medium,INTJ,"Creativity, Analytical Thinking",Procrastination,Information which win central evidence.
|
| 979 |
+
stephen19@gmail.com,dc5d81ee36d5ba800430055df19c1f1a3c57763040afdf0fd3011a221ffc09eb,David Bruce,Mechanical Engineering,8.55,"Sem 1: 9.17
|
| 980 |
+
|
| 981 |
+
Sem 2: 8.77
|
| 982 |
+
|
| 983 |
+
Sem 3: 8.75
|
| 984 |
+
|
| 985 |
+
Sem 4: 7.59
|
| 986 |
+
|
| 987 |
+
Sem 5: 8.03
|
| 988 |
+
|
| 989 |
+
Sem 6: 9.84",0,"Python (Intermediate), Java (Beginner), Ruby (Intermediate)","Git, GCP, React, Node.js, Docker","AWS Certified Developer
|
| 990 |
+
|
| 991 |
+
Oracle Java Certification","Teamwork, Leadership",30 WPM,Avoid nothing itself who door end.,Howe-Long,https://nelson-jones.com/,1.0,LeetCode: 2133,TOEFL,Sister once choice clearly.,4.0,2.0,1.0,Data Scientist,Finance,Hyderabad,No,96.0,Yes,High,ISFJ,"Empathy, Creativity",Perfectionism,Finish building group show later leg system.
|
| 992 |
+
marymurphy@dawson.biz,60acc8de30cbbcbad2ef448782735cd8da0ad3b396d3dc397125615eb48f3823,Robert Torres,Electronics and Communication Engineering,8.99,"Sem 1: 8.52
|
| 993 |
+
|
| 994 |
+
Sem 2: 6.77
|
| 995 |
+
|
| 996 |
+
Sem 3: 8.09
|
| 997 |
+
|
| 998 |
+
Sem 4: 7.76
|
| 999 |
+
|
| 1000 |
+
Sem 5: 8.25
|
| 1001 |
+
|
| 1002 |
+
Sem 6: 8.48",1,"Java (Expert), C++ (Expert), Python (Expert)","Docker, AWS, React, GCP, Git","AWS Certified Developer
|
| 1003 |
+
|
| 1004 |
+
Oracle Java Certification","Teamwork, Communication",60 WPM,Employee wrong all identify laugh.,"Pierce, Davis and Garcia",http://www.brown.com/,2.0,LeetCode: 1668,GRE,Statement head piece popular old.,1.0,0.0,1.0,Data Scientist,Finance,Hyderabad,No,96.0,No,Medium,INTJ,"Persistence, Analytical Thinking",Perfectionism,True avoid young cup position.
|
| 1005 |
+
williamssteven@gmail.com,ab278fb4a0a0853d2e14efe9c6e23ab895f2ca23b90b7000fbfb716ebb3e1fca,Anna Boone,Information Technology,7.28,"Sem 1: 8.31
|
| 1006 |
+
|
| 1007 |
+
Sem 2: 6.66
|
| 1008 |
+
|
| 1009 |
+
Sem 3: 7.9
|
| 1010 |
+
|
| 1011 |
+
Sem 4: 9.57
|
| 1012 |
+
|
| 1013 |
+
Sem 5: 9.53
|
| 1014 |
+
|
| 1015 |
+
Sem 6: 9.21",1,"C++ (Intermediate), Python (Beginner), C# (Intermediate)","AWS, GCP, MySQL, Kubernetes, Node.js","AWS Certified Developer
|
| 1016 |
+
|
| 1017 |
+
Google Cloud Associate","Leadership, Problem-Solving",61 WPM,Start house ahead raise common Democrat.,Hill Group,http://www.harvey.biz/,1.0,LeetCode: 2338,GRE,Look because him information poor something eat.,1.0,0.0,1.0,Software Developer,Education,Pune,Yes,71.0,Yes,Low,ESFP,"Persistence, Analytical Thinking",Impatience,Some writer site grow name machine tree.
|
| 1018 |
+
anthonycochran@yahoo.com,64a02493d7c80999620a4f3b1a27892b1c1ad1d17b1586135c47b9132ca0dde5,Jasmine White,Information Technology,7.97,"Sem 1: 9.86
|
| 1019 |
+
|
| 1020 |
+
Sem 2: 9.9
|
| 1021 |
+
|
| 1022 |
+
Sem 3: 7.0
|
| 1023 |
+
|
| 1024 |
+
Sem 4: 7.48
|
| 1025 |
+
|
| 1026 |
+
Sem 5: 6.65
|
| 1027 |
+
|
| 1028 |
+
Sem 6: 7.31",2,"JavaScript (Intermediate), Go (Expert), C++ (Beginner)","Docker, Kubernetes, React, AWS, Git","Oracle Java Certification
|
| 1029 |
+
|
| 1030 |
+
AWS Certified Developer","Problem-Solving, Leadership",38 WPM,Morning short yourself wind beyond prevent entire.,"Brown, Davies and Robinson",https://thompson.com/,1.0,LeetCode: 1294,TOEFL,Trial agreement red way nor none.,2.0,1.0,1.0,System Engineer,Research,Pune,Yes,54.0,Yes,High,INTJ,"Creativity, Analytical Thinking",Impatience,Student special wife my compare.
|
| 1031 |
+
nsmith@drake.com,4059d2dac86be43ca3a9bc71f84b1fb6577f9541be1d0fd18323ff1dc47156a5,Anthony Guzman,Mechanical Engineering,8.13,"Sem 1: 7.92
|
| 1032 |
+
|
| 1033 |
+
Sem 2: 8.38
|
| 1034 |
+
|
| 1035 |
+
Sem 3: 9.88
|
| 1036 |
+
|
| 1037 |
+
Sem 4: 7.23
|
| 1038 |
+
|
| 1039 |
+
Sem 5: 7.58
|
| 1040 |
+
|
| 1041 |
+
Sem 6: 7.43",0,"Python (Expert), Java (Expert), C++ (Expert)","Git, AWS, Node.js, Kubernetes, Docker","AWS Certified Developer
|
| 1042 |
+
|
| 1043 |
+
Oracle Java Certification","Leadership, Teamwork",62 WPM,Arrive challenge relate center book money.,Yu-Brooks,https://www.turner-taylor.com/,0.0,LeetCode: 2873,TOEFL,Social whether power company why really.,2.0,0.0,0.0,AI Researcher,Research,Hyderabad,Yes,79.0,Yes,High,INTJ,"Analytical Thinking, Empathy",Impatience,Skin development open compare fill read camera rock.
|
| 1044 |
+
carriemccall@walker.com,53a6b5dce6247ac7e8dc091e485dfcdd135d9db46e182ee610e87dc59526612c,Tiffany Myers,Information Technology,7.19,"Sem 1: 7.9
|
| 1045 |
+
|
| 1046 |
+
Sem 2: 8.9
|
| 1047 |
+
|
| 1048 |
+
Sem 3: 9.78
|
| 1049 |
+
|
| 1050 |
+
Sem 4: 6.79
|
| 1051 |
+
|
| 1052 |
+
Sem 5: 8.55
|
| 1053 |
+
|
| 1054 |
+
Sem 6: 9.71",0,"Python (Expert), Ruby (Intermediate), Java (Beginner)","Docker, React, Git, Node.js, AWS","AWS Certified Developer
|
| 1055 |
+
|
| 1056 |
+
Oracle Java Certification","Problem-Solving, Leadership",55 WPM,Draw word collection those.,Underwood Ltd,https://baker.com/,3.0,LeetCode: 220,None,Either blue ability history run why.,5.0,1.0,0.0,System Engineer,Education,Hyderabad,No,67.0,No,High,INTJ,"Creativity, Persistence",Procrastination,Manage her national big look tell.
|
| 1057 |
+
phillipslucas@jones.biz,d9a8fab9822778e7e9128cd29f57a542058c3ad03eb4b6171df31a9e47b240d1,Melissa Martin,Mechanical Engineering,7.94,"Sem 1: 8.43
|
| 1058 |
+
|
| 1059 |
+
Sem 2: 6.71
|
| 1060 |
+
|
| 1061 |
+
Sem 3: 7.48
|
| 1062 |
+
|
| 1063 |
+
Sem 4: 6.98
|
| 1064 |
+
|
| 1065 |
+
Sem 5: 7.2
|
| 1066 |
+
|
| 1067 |
+
Sem 6: 9.6",2,"Java (Beginner), Go (Intermediate), C# (Expert)","React, MySQL, GCP, AWS, Kubernetes","Oracle Java Certification
|
| 1068 |
+
|
| 1069 |
+
Google Cloud Associate","Problem-Solving, Teamwork",41 WPM,Natural together behavior order.,"Barry, Bush and Reynolds",http://brown.com/,0.0,LeetCode: 1406,GRE,Important never understand music produce.,0.0,1.0,0.0,AI Researcher,Finance,Hyderabad,Yes,56.0,Yes,Low,ENTP,"Persistence, Empathy",Perfectionism,Down anyone occur style child.
|
| 1070 |
+
collinclark@hotmail.com,c7cc40bf3a068ea35e444d7b3551933adecbf5574cb96eb8f50616c3b3e223a4,Jeffrey Phillips,Information Technology,8.51,"Sem 1: 9.94
|
| 1071 |
+
|
| 1072 |
+
Sem 2: 7.86
|
| 1073 |
+
|
| 1074 |
+
Sem 3: 9.77
|
| 1075 |
+
|
| 1076 |
+
Sem 4: 9.97
|
| 1077 |
+
|
| 1078 |
+
Sem 5: 7.11
|
| 1079 |
+
|
| 1080 |
+
Sem 6: 7.33",1,"Ruby (Expert), Go (Beginner), C++ (Expert)","React, Kubernetes, GCP, Docker, AWS","Oracle Java Certification
|
| 1081 |
+
|
| 1082 |
+
Google Cloud Associate","Teamwork, Problem-Solving",32 WPM,List break size likely.,"Baker, May and Hughes",https://lopez-williams.info/,0.0,LeetCode: 330,GRE,Enjoy student nor character recent benefit property.,4.0,0.0,0.0,AI Researcher,IT,Pune,Yes,58.0,No,Low,ENTP,"Persistence, Analytical Thinking",Perfectionism,Including series dinner article hit mission whole.
|
| 1083 |
+
zevans@johnson.org,23b71cc7fffeb885380cd88d745c32a0a47ba694eba5589323b1134aa1ef3b57,Taylor Armstrong,Information Technology,8.55,"Sem 1: 9.71
|
| 1084 |
+
|
| 1085 |
+
Sem 2: 9.21
|
| 1086 |
+
|
| 1087 |
+
Sem 3: 9.46
|
| 1088 |
+
|
| 1089 |
+
Sem 4: 9.51
|
| 1090 |
+
|
| 1091 |
+
Sem 5: 9.86
|
| 1092 |
+
|
| 1093 |
+
Sem 6: 7.81",2,"JavaScript (Intermediate), C# (Intermediate), Python (Intermediate)","Kubernetes, MongoDB, React, AWS, Node.js","Oracle Java Certification
|
| 1094 |
+
|
| 1095 |
+
Google Cloud Associate","Teamwork, Leadership",65 WPM,Challenge we last we cold deep cover amount.,Mcneil Group,http://www.scott.com/,2.0,LeetCode: 1014,GRE,Hold however for everybody.,3.0,1.0,1.0,Data Scientist,Education,Bangalore,No,99.0,Yes,High,ISFJ,"Creativity, Persistence",Perfectionism,True actually red onto site both change.
|
| 1096 |
+
hartcraig@dillon-beard.biz,79fe922a61ae5676677183d18b75af542ee1728513cf590add84bc9a6a1281a7,Lauren Hanna,Mechanical Engineering,6.99,"Sem 1: 9.11
|
| 1097 |
+
|
| 1098 |
+
Sem 2: 7.33
|
| 1099 |
+
|
| 1100 |
+
Sem 3: 9.94
|
| 1101 |
+
|
| 1102 |
+
Sem 4: 7.09
|
| 1103 |
+
|
| 1104 |
+
Sem 5: 9.6
|
| 1105 |
+
|
| 1106 |
+
Sem 6: 6.81",2,"Go (Intermediate), Ruby (Beginner), C++ (Intermediate)","AWS, MongoDB, React, Git, Kubernetes","Google Cloud Associate
|
| 1107 |
+
|
| 1108 |
+
AWS Certified Developer","Communication, Problem-Solving",54 WPM,Occur list common idea peace race I.,Preston-Rivera,http://www.alvarez.com/,3.0,LeetCode: 1818,GRE,Financial successful teach range win.,3.0,1.0,1.0,System Engineer,Research,Bangalore,No,100.0,Yes,High,ESFP,"Analytical Thinking, Empathy",Procrastination,Care wind kitchen stay especially.
|
| 1109 |
+
wfigueroa@camacho.com,d7ae3dd31bfab08eb337576504fae74a6876c617a90ef9a3b517428b17a35e2c,Matthew Lopez,Computer Science and Engineering,7.62,"Sem 1: 9.83
|
| 1110 |
+
|
| 1111 |
+
Sem 2: 6.76
|
| 1112 |
+
|
| 1113 |
+
Sem 3: 7.1
|
| 1114 |
+
|
| 1115 |
+
Sem 4: 7.81
|
| 1116 |
+
|
| 1117 |
+
Sem 5: 9.06
|
| 1118 |
+
|
| 1119 |
+
Sem 6: 8.41",0,"C++ (Intermediate), C# (Expert), Go (Beginner)","Node.js, Kubernetes, GCP, AWS, Docker","AWS Certified Developer
|
| 1120 |
+
|
| 1121 |
+
Oracle Java Certification","Leadership, Communication",42 WPM,Idea sister modern notice community themselves customer.,Wright Group,http://gonzalez.biz/,3.0,LeetCode: 2955,TOEFL,Race drop major land.,5.0,1.0,1.0,Data Scientist,IT,Bangalore,No,86.0,No,High,INTJ,"Persistence, Analytical Thinking",Shyness,Only glass clear thus see read expect.
|
| 1122 |
+
deborahbyrd@pearson-palmer.com,d2f654b695aab3ab9ec3cf3ba8acc88b060650d7bc1bf0ef82cff99422c6d0d3,Christopher Armstrong,Computer Science and Engineering,7.53,"Sem 1: 8.82
|
| 1123 |
+
|
| 1124 |
+
Sem 2: 8.6
|
| 1125 |
+
|
| 1126 |
+
Sem 3: 7.2
|
| 1127 |
+
|
| 1128 |
+
Sem 4: 6.59
|
| 1129 |
+
|
| 1130 |
+
Sem 5: 7.1
|
| 1131 |
+
|
| 1132 |
+
Sem 6: 7.52",0,"JavaScript (Intermediate), Python (Intermediate), C++ (Intermediate)","GCP, Docker, React, MongoDB, AWS","AWS Certified Developer
|
| 1133 |
+
|
| 1134 |
+
Google Cloud Associate","Problem-Solving, Teamwork",41 WPM,Positive over across education.,Marquez-Fletcher,https://york-stevens.com/,3.0,LeetCode: 282,TOEFL,Few minute perhaps once account yourself whom.,3.0,1.0,1.0,Data Scientist,Finance,Bangalore,Yes,98.0,Yes,High,ISFJ,"Empathy, Persistence",Impatience,No order executive range loss from.
|
| 1135 |
+
edwardcannon@gmail.com,88ea674d7d303515fb1f89d5ff713abb801c9f43a4fbee2cc8fc1d216e0ecf09,Frederick Hill,Computer Science and Engineering,9.44,"Sem 1: 9.36
|
| 1136 |
+
|
| 1137 |
+
Sem 2: 7.97
|
| 1138 |
+
|
| 1139 |
+
Sem 3: 8.37
|
| 1140 |
+
|
| 1141 |
+
Sem 4: 9.53
|
| 1142 |
+
|
| 1143 |
+
Sem 5: 8.16
|
| 1144 |
+
|
| 1145 |
+
Sem 6: 9.59",1,"C++ (Expert), Python (Beginner), JavaScript (Expert)","MongoDB, Kubernetes, Git, AWS, Docker","AWS Certified Developer
|
| 1146 |
+
|
| 1147 |
+
Oracle Java Certification","Teamwork, Communication",32 WPM,Identify floor cause agent market fast trade identify.,"Johnson, Erickson and Armstrong",http://reeves.info/,3.0,LeetCode: 420,None,Medical suddenly subject theory Congress best.,1.0,2.0,0.0,System Engineer,Finance,Bangalore,Yes,74.0,No,Low,ISFJ,"Persistence, Empathy",Shyness,Scientist rise next tree.
|
| 1148 |
+
jeffrey46@watson-richards.info,c3630d11312e4e55782f86a8e74613da1235c1b729c63cf9a1f727e52cde4864,Stephanie Pena,Computer Science and Engineering,9.25,"Sem 1: 8.68
|
| 1149 |
+
|
| 1150 |
+
Sem 2: 8.33
|
| 1151 |
+
|
| 1152 |
+
Sem 3: 7.97
|
| 1153 |
+
|
| 1154 |
+
Sem 4: 7.95
|
| 1155 |
+
|
| 1156 |
+
Sem 5: 7.02
|
| 1157 |
+
|
| 1158 |
+
Sem 6: 8.56",0,"Python (Intermediate), C# (Expert), Ruby (Intermediate)","Node.js, GCP, AWS, React, MongoDB","Oracle Java Certification
|
| 1159 |
+
|
| 1160 |
+
Google Cloud Associate","Communication, Problem-Solving",47 WPM,Approach plant oil per line create build.,"James, Evans and Brown",http://www.cooper.info/,3.0,LeetCode: 689,None,First resource single maintain.,0.0,1.0,1.0,Data Scientist,IT,Chennai,No,73.0,Yes,Medium,ISFJ,"Persistence, Creativity",Shyness,Would finish around later decide similar office citizen.
|
| 1161 |
+
epowell@yahoo.com,8bb7848e064edaf597e41472685eaa33519405c98ed035c83a32774e389e7b1b,Penny Anderson,Computer Science and Engineering,9.9,"Sem 1: 7.3
|
| 1162 |
+
|
| 1163 |
+
Sem 2: 7.55
|
| 1164 |
+
|
| 1165 |
+
Sem 3: 9.1
|
| 1166 |
+
|
| 1167 |
+
Sem 4: 9.21
|
| 1168 |
+
|
| 1169 |
+
Sem 5: 7.62
|
| 1170 |
+
|
| 1171 |
+
Sem 6: 9.05",2,"Go (Intermediate), Python (Beginner), Java (Intermediate)","MySQL, React, Node.js, Git, GCP","AWS Certified Developer
|
| 1172 |
+
|
| 1173 |
+
Oracle Java Certification","Leadership, Problem-Solving",62 WPM,Current health add focus street course quality.,"Gross, Perez and Wiley",https://www.reyes.com/,3.0,LeetCode: 655,GATE,Assume animal way lay.,1.0,0.0,0.0,Software Developer,Education,Bangalore,No,53.0,No,Low,ENTP,"Persistence, Creativity",Shyness,Others full thousand yet garden top grow.
|
| 1174 |
+
perezjessica@gmail.com,aa82c819efd169455fb83f79e28ac2b4d90543a87fec8c92af8a4cf104ee0255,Travis Hull,Mechanical Engineering,8.72,"Sem 1: 6.93
|
| 1175 |
+
|
| 1176 |
+
Sem 2: 6.61
|
| 1177 |
+
|
| 1178 |
+
Sem 3: 7.8
|
| 1179 |
+
|
| 1180 |
+
Sem 4: 8.58
|
| 1181 |
+
|
| 1182 |
+
Sem 5: 7.12
|
| 1183 |
+
|
| 1184 |
+
Sem 6: 9.55",2,"C# (Beginner), C++ (Intermediate), Go (Expert)","Docker, GCP, Git, AWS, Node.js","AWS Certified Developer
|
| 1185 |
+
|
| 1186 |
+
Oracle Java Certification","Teamwork, Leadership",44 WPM,Operation college hand.,"Conner, Brooks and Bowman",http://www.rodriguez.com/,1.0,LeetCode: 1202,None,Know buy education reduce day rate.,4.0,0.0,0.0,AI Researcher,Education,Hyderabad,Yes,64.0,No,Low,ISFJ,"Persistence, Creativity",Shyness,Feeling product production.
|
| 1187 |
+
campbellkristen@gonzalez-gonzalez.com,3214164a5565be0f0cfc20a18f772e4f07aa0870a47bc569a6719b2f30a29cdd,Larry Taylor,Electronics and Communication Engineering,8.11,"Sem 1: 7.26
|
| 1188 |
+
|
| 1189 |
+
Sem 2: 7.56
|
| 1190 |
+
|
| 1191 |
+
Sem 3: 8.32
|
| 1192 |
+
|
| 1193 |
+
Sem 4: 8.68
|
| 1194 |
+
|
| 1195 |
+
Sem 5: 8.55
|
| 1196 |
+
|
| 1197 |
+
Sem 6: 6.53",2,"Ruby (Expert), C++ (Expert), C# (Expert)","GCP, MongoDB, React, Git, AWS","AWS Certified Developer
|
| 1198 |
+
|
| 1199 |
+
Google Cloud Associate","Leadership, Problem-Solving",50 WPM,Group important civil nature travel.,"Fitzpatrick, Rivera and Smith",http://www.caldwell.net/,2.0,LeetCode: 1169,TOEFL,Rich big eight discuss.,1.0,0.0,0.0,Software Developer,Research,Pune,Yes,96.0,Yes,Low,ESFP,"Persistence, Creativity",Shyness,Enough anyone spend them system.
|
| 1200 |
+
yorkpamela@christian.com,679d861c03118ebcd369bde72c391780474b4014cbcbd56e61ea936e19ff65b5,Michael Simmons,Mechanical Engineering,7.86,"Sem 1: 6.62
|
| 1201 |
+
|
| 1202 |
+
Sem 2: 8.98
|
| 1203 |
+
|
| 1204 |
+
Sem 3: 8.5
|
| 1205 |
+
|
| 1206 |
+
Sem 4: 7.16
|
| 1207 |
+
|
| 1208 |
+
Sem 5: 9.04
|
| 1209 |
+
|
| 1210 |
+
Sem 6: 7.28",2,"Go (Expert), JavaScript (Intermediate), C++ (Beginner)","MongoDB, Kubernetes, MySQL, Git, AWS","AWS Certified Developer
|
| 1211 |
+
|
| 1212 |
+
Google Cloud Associate","Teamwork, Leadership",51 WPM,Western environmental run head garden box.,Rivers-Nelson,https://banks-robles.com/,0.0,LeetCode: 1010,TOEFL,Receive around wall city.,1.0,2.0,1.0,AI Researcher,Finance,Pune,No,87.0,No,Medium,INTJ,"Empathy, Analytical Thinking",Perfectionism,Treat lot notice just particularly single.
|
| 1213 |
+
hknapp@alexander-brown.com,4018e725c3f0d9aaace06e5adc293f3c4f9dbed236de31acd0b26646463deabb,Shari Hobbs,Mechanical Engineering,9.61,"Sem 1: 8.25
|
| 1214 |
+
|
| 1215 |
+
Sem 2: 9.54
|
| 1216 |
+
|
| 1217 |
+
Sem 3: 7.84
|
| 1218 |
+
|
| 1219 |
+
Sem 4: 7.54
|
| 1220 |
+
|
| 1221 |
+
Sem 5: 6.69
|
| 1222 |
+
|
| 1223 |
+
Sem 6: 9.49",0,"Java (Expert), C++ (Intermediate), JavaScript (Beginner)","React, Kubernetes, Node.js, Git, AWS","Google Cloud Associate
|
| 1224 |
+
|
| 1225 |
+
AWS Certified Developer","Leadership, Problem-Solving",33 WPM,Should office north within prove full mission.,"Montgomery, Reynolds and Barber",https://rhodes.net/,0.0,LeetCode: 1951,TOEFL,Approach poor church support system thank avoid man.,1.0,0.0,0.0,AI Researcher,IT,Hyderabad,No,90.0,No,Medium,ESFP,"Empathy, Creativity",Perfectionism,Former everything medical nearly her.
|
| 1226 |
+
gatessergio@gmail.com,8328ae6c441bdbe8d0edd6a7d1b5008db4310232326abac9b3d84d1a0b165d7f,Angela Wallace,Computer Science and Engineering,8.37,"Sem 1: 9.06
|
| 1227 |
+
|
| 1228 |
+
Sem 2: 9.83
|
| 1229 |
+
|
| 1230 |
+
Sem 3: 9.62
|
| 1231 |
+
|
| 1232 |
+
Sem 4: 9.15
|
| 1233 |
+
|
| 1234 |
+
Sem 5: 8.36
|
| 1235 |
+
|
| 1236 |
+
Sem 6: 6.56",0,"Go (Beginner), Ruby (Expert), Java (Intermediate)","GCP, Kubernetes, Git, AWS, MongoDB","Oracle Java Certification
|
| 1237 |
+
|
| 1238 |
+
Google Cloud Associate","Teamwork, Communication",32 WPM,Bill include news.,Petersen PLC,https://www.powers.com/,2.0,LeetCode: 1291,None,Such forward should outside respond.,5.0,2.0,1.0,AI Researcher,Education,Pune,No,72.0,Yes,High,ESFP,"Analytical Thinking, Empathy",Impatience,Respond box service develop game stop.
|
| 1239 |
+
princetravis@newton.com,a5746e580089498d437ddd5440ecf7d0bb60c20d26f37c6c8d1559624d73c834,Dorothy Boyd,Information Technology,7.24,"Sem 1: 6.58
|
| 1240 |
+
|
| 1241 |
+
Sem 2: 8.27
|
| 1242 |
+
|
| 1243 |
+
Sem 3: 6.93
|
| 1244 |
+
|
| 1245 |
+
Sem 4: 8.99
|
| 1246 |
+
|
| 1247 |
+
Sem 5: 9.27
|
| 1248 |
+
|
| 1249 |
+
Sem 6: 7.81",2,"C++ (Beginner), C# (Expert), Go (Beginner)","Docker, Git, MySQL, React, Node.js","Google Cloud Associate
|
| 1250 |
+
|
| 1251 |
+
Oracle Java Certification","Problem-Solving, Communication",65 WPM,Democratic station course full serious another.,"Monroe, Chapman and Barton",https://lawrence.com/,2.0,LeetCode: 2043,GRE,Save network item one under sit travel.,1.0,2.0,0.0,System Engineer,Research,Bangalore,No,89.0,Yes,Medium,INTJ,"Analytical Thinking, Creativity",Perfectionism,Community spring billion price paper focus thing industry.
|
| 1252 |
+
tara72@gmail.com,de945b3a4aaefc980d57b8e56357298a876a5459761a9863828c302b83b8bcec,Melissa Wright,Computer Science and Engineering,8.24,"Sem 1: 8.63
|
| 1253 |
+
|
| 1254 |
+
Sem 2: 9.22
|
| 1255 |
+
|
| 1256 |
+
Sem 3: 9.41
|
| 1257 |
+
|
| 1258 |
+
Sem 4: 9.91
|
| 1259 |
+
|
| 1260 |
+
Sem 5: 7.75
|
| 1261 |
+
|
| 1262 |
+
Sem 6: 7.93",0,"Python (Beginner), C# (Expert), JavaScript (Intermediate)","React, AWS, Git, Node.js, MongoDB","AWS Certified Developer
|
| 1263 |
+
|
| 1264 |
+
Google Cloud Associate","Teamwork, Communication",62 WPM,Federal reduce team Republican very plan cut.,"Klein, Parks and Morse",http://www.daniels.com/,0.0,LeetCode: 514,TOEFL,Lose number project individual security subject experience.,5.0,0.0,1.0,System Engineer,Finance,Chennai,Yes,56.0,Yes,High,ISFJ,"Persistence, Empathy",Procrastination,Space mission agent certainly prove customer.
|
| 1265 |
+
maryvaughn@yahoo.com,5ff723c079d46f152c53166182c66780d9cdd4d596e7e2dad50494b27f40dc7f,Candace Mitchell,Mechanical Engineering,9.08,"Sem 1: 6.83
|
| 1266 |
+
|
| 1267 |
+
Sem 2: 9.15
|
| 1268 |
+
|
| 1269 |
+
Sem 3: 6.66
|
| 1270 |
+
|
| 1271 |
+
Sem 4: 9.48
|
| 1272 |
+
|
| 1273 |
+
Sem 5: 8.82
|
| 1274 |
+
|
| 1275 |
+
Sem 6: 7.1",1,"JavaScript (Expert), C# (Beginner), C++ (Intermediate)","React, Kubernetes, Git, AWS, MongoDB","Google Cloud Associate
|
| 1276 |
+
|
| 1277 |
+
Oracle Java Certification","Problem-Solving, Leadership",60 WPM,Allow sport bill test science ten score.,"Price, Dixon and Robles",https://www.hughes-frye.com/,3.0,LeetCode: 2757,GRE,Approach season data than team kitchen difficult.,0.0,0.0,0.0,Data Scientist,IT,Chennai,No,86.0,No,High,ESFP,"Persistence, Empathy",Perfectionism,Sense national owner simply who family.
|
| 1278 |
+
bennettroy@baker.com,f9a7350c76a8890ab21f06bf272f809c1b1260cd0fc2ee252b2209928e881636,Michael Lopez,Information Technology,8.19,"Sem 1: 8.21
|
| 1279 |
+
|
| 1280 |
+
Sem 2: 9.61
|
| 1281 |
+
|
| 1282 |
+
Sem 3: 8.04
|
| 1283 |
+
|
| 1284 |
+
Sem 4: 6.72
|
| 1285 |
+
|
| 1286 |
+
Sem 5: 8.79
|
| 1287 |
+
|
| 1288 |
+
Sem 6: 6.54",2,"C# (Expert), Go (Expert), Ruby (Beginner)","React, Docker, AWS, MongoDB, MySQL","Google Cloud Associate
|
| 1289 |
+
|
| 1290 |
+
Oracle Java Certification","Problem-Solving, Communication",65 WPM,Always up others similar.,"Gilbert, Stanley and Henry",https://www.stewart.com/,0.0,LeetCode: 147,GRE,City myself idea glass third professional former.,4.0,1.0,1.0,Data Scientist,IT,Chennai,No,65.0,No,Medium,INTJ,"Creativity, Persistence",Shyness,Despite sell most you statement.
|
| 1291 |
+
flemingmanuel@cruz.com,0c09ad671a072cd77977e3209e13793af17e61007c4d5883c6df914c4a7c7697,Mrs. Maureen Griffin,Mechanical Engineering,9.36,"Sem 1: 6.78
|
| 1292 |
+
|
| 1293 |
+
Sem 2: 8.05
|
| 1294 |
+
|
| 1295 |
+
Sem 3: 8.51
|
| 1296 |
+
|
| 1297 |
+
Sem 4: 6.81
|
| 1298 |
+
|
| 1299 |
+
Sem 5: 8.24
|
| 1300 |
+
|
| 1301 |
+
Sem 6: 7.61",1,"Go (Beginner), Ruby (Intermediate), Python (Intermediate)","Git, MongoDB, Node.js, MySQL, GCP","Oracle Java Certification
|
| 1302 |
+
|
| 1303 |
+
Google Cloud Associate","Teamwork, Leadership",59 WPM,State heart sort knowledge analysis together court.,"Miller, Davis and Bonilla",http://www.santiago.biz/,2.0,LeetCode: 1588,GATE,Day stock these scientist.,1.0,1.0,1.0,AI Researcher,Finance,Chennai,Yes,56.0,Yes,High,ISFJ,"Persistence, Empathy",Procrastination,Position vote section child learn forward.
|
| 1304 |
+
rhondarussell@mccoy-hamilton.com,e8530cb052dc75c5eec77e96deb16c5b0648cf2a6556ba13c80b367cbeb26aa0,Anthony Bauer,Electronics and Communication Engineering,8.96,"Sem 1: 6.66
|
| 1305 |
+
|
| 1306 |
+
Sem 2: 7.07
|
| 1307 |
+
|
| 1308 |
+
Sem 3: 6.99
|
| 1309 |
+
|
| 1310 |
+
Sem 4: 9.01
|
| 1311 |
+
|
| 1312 |
+
Sem 5: 9.03
|
| 1313 |
+
|
| 1314 |
+
Sem 6: 6.87",2,"Java (Intermediate), Ruby (Beginner), Python (Intermediate)","AWS, React, Git, MongoDB, Node.js","Oracle Java Certification
|
| 1315 |
+
|
| 1316 |
+
AWS Certified Developer","Problem-Solving, Teamwork",67 WPM,Movement political peace series.,"Williams, Charles and Howard",http://turner.info/,1.0,LeetCode: 2143,GATE,House produce listen mouth carry hospital.,4.0,2.0,0.0,AI Researcher,Research,Hyderabad,Yes,96.0,Yes,High,ESFP,"Persistence, Empathy",Shyness,Far plant fear thought whole term possible.
|
templates/404.html
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends 'base.html' %}
|
| 2 |
+
{% block title %}Page Not Found{% endblock %}
|
| 3 |
+
{% block content %}
|
| 4 |
+
<div class="text-center py-5">
|
| 5 |
+
<h1 class="display-1">404</h1>
|
| 6 |
+
<h2>Oops! Page Not Found</h2>
|
| 7 |
+
<p class="lead">The page you are looking for does not exist or has been moved.</p>
|
| 8 |
+
<a href="{{ url_for('home') }}" class="btn btn-primary mt-3">Go to Homepage</a>
|
| 9 |
+
</div>
|
| 10 |
+
{% endblock %}
|
templates/500.html
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends 'base.html' %}
|
| 2 |
+
{% block title %}Server Error{% endblock %}
|
| 3 |
+
{% block content %}
|
| 4 |
+
<div class="text-center py-5">
|
| 5 |
+
<h1 class="display-1">500</h1>
|
| 6 |
+
<h2>Oops! Internal Server Error</h2>
|
| 7 |
+
<p class="lead">Something went wrong on our end. We are working to fix it.</p>
|
| 8 |
+
<p>Please try again later or contact support if the problem persists.</p>
|
| 9 |
+
<a href="{{ url_for('home') }}" class="btn btn-primary mt-3">Go to Homepage</a>
|
| 10 |
+
</div>
|
| 11 |
+
{% endblock %}
|
templates/base.html
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<!-- Block for title -->
|
| 7 |
+
<title>{% block title %}Campus Recruitment Portal{% endblock %}</title>
|
| 8 |
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
|
| 9 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
|
| 10 |
+
<!-- Link to your static CSS file -->
|
| 11 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
| 12 |
+
<!-- Block for additional head elements -->
|
| 13 |
+
{% block head %}{% endblock %}
|
| 14 |
+
</head>
|
| 15 |
+
<body>
|
| 16 |
+
<!-- Optional: Add a common navbar or header here if needed for error pages -->
|
| 17 |
+
<!--
|
| 18 |
+
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
| 19 |
+
<div class="container-fluid">
|
| 20 |
+
<a class="navbar-brand" href="/">Recruitment Portal</a>
|
| 21 |
+
</div>
|
| 22 |
+
</nav>
|
| 23 |
+
-->
|
| 24 |
+
|
| 25 |
+
<div class="container mt-4">
|
| 26 |
+
<!-- Display Flash Messages -->
|
| 27 |
+
{% with messages = get_flashed_messages(with_categories=true) %}
|
| 28 |
+
{% if messages %}
|
| 29 |
+
{% for category, message in messages %}
|
| 30 |
+
<div class="alert alert-{{ category if category in ['danger', 'warning', 'info', 'success'] else 'secondary' }} alert-dismissible fade show" role="alert">
|
| 31 |
+
{{ message }}
|
| 32 |
+
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
| 33 |
+
</div>
|
| 34 |
+
{% endfor %}
|
| 35 |
+
{% endif %}
|
| 36 |
+
{% endwith %}
|
| 37 |
+
|
| 38 |
+
<!-- Block for main content -->
|
| 39 |
+
{% block content %}{% endblock %}
|
| 40 |
+
</div>
|
| 41 |
+
|
| 42 |
+
<!-- Optional: Add a common footer here -->
|
| 43 |
+
<!--
|
| 44 |
+
<footer class="text-center mt-5 py-3 bg-light">
|
| 45 |
+
<small>© {{ now.year }} Campus Recruitment Portal</small>
|
| 46 |
+
</footer>
|
| 47 |
+
-->
|
| 48 |
+
|
| 49 |
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
|
| 50 |
+
<!-- Block for additional scripts -->
|
| 51 |
+
{% block scripts %}{% endblock %}
|
| 52 |
+
</body>
|
| 53 |
+
</html>
|
templates/company_dashboard.html
ADDED
|
@@ -0,0 +1,890 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Company Dashboard | Campus Recruitment Portal</title>
|
| 7 |
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
| 8 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
| 9 |
+
<!-- Link to your EXTERNAL static CSS file -->
|
| 10 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
| 11 |
+
<style>
|
| 12 |
+
/* Minimal page-specific overrides */
|
| 13 |
+
.chart-container {
|
| 14 |
+
position: relative;
|
| 15 |
+
height: 280px; /* Default height */
|
| 16 |
+
width: 100%;
|
| 17 |
+
min-height: 200px; /* Ensure minimum height */
|
| 18 |
+
}
|
| 19 |
+
canvas {
|
| 20 |
+
display: block; /* Prevents extra space below canvas */
|
| 21 |
+
max-width: 100%; /* Ensure canvas doesn't overflow container */
|
| 22 |
+
}
|
| 23 |
+
/* Make table header sticky */
|
| 24 |
+
.table-responsive thead {
|
| 25 |
+
position: sticky;
|
| 26 |
+
top: 0;
|
| 27 |
+
z-index: 1;
|
| 28 |
+
/* Background applied by .table-light in the thead tag */
|
| 29 |
+
}
|
| 30 |
+
.filter-section .card-body {
|
| 31 |
+
max-height: calc(100vh - 150px); /* Adjust based on nav height etc. */
|
| 32 |
+
overflow-y: auto;
|
| 33 |
+
}
|
| 34 |
+
@media (max-width: 992px) {
|
| 35 |
+
.filter-section .card-body {
|
| 36 |
+
max-height: none;
|
| 37 |
+
overflow-y: visible;
|
| 38 |
+
}
|
| 39 |
+
}
|
| 40 |
+
/* Style for AI Query section */
|
| 41 |
+
#nl-query-error {
|
| 42 |
+
font-size: 0.85rem;
|
| 43 |
+
}
|
| 44 |
+
</style>
|
| 45 |
+
</head>
|
| 46 |
+
<body>
|
| 47 |
+
<!-- Navigation -->
|
| 48 |
+
<nav class="navbar navbar-expand-lg navbar-dark bg-primary sticky-top shadow-sm">
|
| 49 |
+
<div class="container-fluid">
|
| 50 |
+
<a class="navbar-brand" href="{{ url_for('dashboard') }}">
|
| 51 |
+
<i class="bi bi-building"></i> {{ company_name }} - Portal
|
| 52 |
+
</a>
|
| 53 |
+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
| 54 |
+
<span class="navbar-toggler-icon"></span>
|
| 55 |
+
</button>
|
| 56 |
+
<div class="collapse navbar-collapse" id="navbarNav">
|
| 57 |
+
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
| 58 |
+
<li class="nav-item">
|
| 59 |
+
<a class="nav-link active" aria-current="page" href="{{ url_for('dashboard') }}"><i class="bi bi-speedometer2"></i> Dashboard</a>
|
| 60 |
+
</li>
|
| 61 |
+
<li class="nav-item">
|
| 62 |
+
<a class="nav-link" href="{{ url_for('jobs') }}"><i class="bi bi-briefcase-fill"></i> Job Postings</a>
|
| 63 |
+
</li>
|
| 64 |
+
</ul>
|
| 65 |
+
<ul class="navbar-nav">
|
| 66 |
+
<!-- Display Flash Messages Dropdown -->
|
| 67 |
+
{% with messages = get_flashed_messages(with_categories=true) %}
|
| 68 |
+
{% if messages %}
|
| 69 |
+
<li class="nav-item dropdown">
|
| 70 |
+
<a class="nav-link dropdown-toggle text-warning position-relative" href="#" id="messagesDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
| 71 |
+
<i class="bi bi-bell-fill"></i>
|
| 72 |
+
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger" style="font-size: 0.6em;">
|
| 73 |
+
{{ messages|length }}
|
| 74 |
+
<span class="visually-hidden">notifications</span>
|
| 75 |
+
</span>
|
| 76 |
+
</a>
|
| 77 |
+
<ul class="dropdown-menu dropdown-menu-end shadow border-0 mt-2" aria-labelledby="messagesDropdown" style="min-width: 250px;">
|
| 78 |
+
<li><h6 class="dropdown-header small text-muted">Notifications</h6></li>
|
| 79 |
+
{% for category, message in messages %}
|
| 80 |
+
<li>
|
| 81 |
+
<div class="dropdown-item small py-2">
|
| 82 |
+
<span class="badge bg-{{ category if category in ['danger', 'warning', 'info', 'success'] else 'secondary' }} me-1"> </span>
|
| 83 |
+
{{ message }}
|
| 84 |
+
</div>
|
| 85 |
+
</li>
|
| 86 |
+
{% endfor %}
|
| 87 |
+
<li><hr class="dropdown-divider my-1"></li>
|
| 88 |
+
<li><a class="dropdown-item small text-muted text-center" href="#">View All (Not implemented)</a></li>
|
| 89 |
+
</ul>
|
| 90 |
+
</li>
|
| 91 |
+
{% endif %}
|
| 92 |
+
{% endwith %}
|
| 93 |
+
<li class="nav-item">
|
| 94 |
+
<a class="nav-link" href="{{ url_for('logout') }}" title="Logout">
|
| 95 |
+
<i class="bi bi-box-arrow-right"></i> Logout
|
| 96 |
+
</a>
|
| 97 |
+
</li>
|
| 98 |
+
</ul>
|
| 99 |
+
</div>
|
| 100 |
+
</div>
|
| 101 |
+
</nav>
|
| 102 |
+
|
| 103 |
+
<!-- Main Content -->
|
| 104 |
+
<div class="container-fluid mt-3 main-container">
|
| 105 |
+
<!-- Display top-level error if passed -->
|
| 106 |
+
{% if error %}
|
| 107 |
+
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
| 108 |
+
{{ error }}
|
| 109 |
+
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
| 110 |
+
</div>
|
| 111 |
+
{% endif %}
|
| 112 |
+
|
| 113 |
+
<div class="row">
|
| 114 |
+
<!-- Filters Column -->
|
| 115 |
+
<div class="col-lg-3">
|
| 116 |
+
<!-- Filters Card -->
|
| 117 |
+
<div class="card mb-3 filter-section shadow-sm">
|
| 118 |
+
<div class="card-header bg-secondary text-white">
|
| 119 |
+
<h5 class="card-title mb-0"><i class="bi bi-filter"></i> Filter Candidates</h5>
|
| 120 |
+
</div>
|
| 121 |
+
<div class="card-body">
|
| 122 |
+
<form id="filter-form">
|
| 123 |
+
<!-- Row for Job Filter (Spans full width initially for emphasis) -->
|
| 124 |
+
<div class="row mb-3">
|
| 125 |
+
<div class="col-12 filter-group border-bottom pb-3">
|
| 126 |
+
<label for="job_id_filter" class="form-label filter-heading">Filter by Job</label>
|
| 127 |
+
<select class="form-select form-select-sm" name="job_id" id="job_id_filter">
|
| 128 |
+
<option value="">(All Candidates / Use Manual Filters)</option>
|
| 129 |
+
{% for job in jobs %}
|
| 130 |
+
<option value="{{ job.id }}">{{ job.title }}</option>
|
| 131 |
+
{% endfor %}
|
| 132 |
+
</select>
|
| 133 |
+
<small class="form-text text-muted">Applies job's requirements & overrides manual filters below if selected.</small>
|
| 134 |
+
</div>
|
| 135 |
+
</div>
|
| 136 |
+
|
| 137 |
+
<!-- Row for the rest of the filters (2 columns on large screens) -->
|
| 138 |
+
<div class="row">
|
| 139 |
+
<!-- Column 1: Basic Criteria & Experience -->
|
| 140 |
+
<div class="col-12 col-lg-6">
|
| 141 |
+
<div class="mb-3 filter-group">
|
| 142 |
+
<label for="min_cgpa_filter" class="form-label filter-heading">Min CGPA</label>
|
| 143 |
+
<input type="number" class="form-control form-control-sm" name="min_cgpa" id="min_cgpa_filter" min="0" max="10" step="0.1" placeholder="e.g., 7.5">
|
| 144 |
+
</div>
|
| 145 |
+
|
| 146 |
+
<div class="mb-3 filter-group">
|
| 147 |
+
<label for="max_backlogs_filter" class="form-label filter-heading">Max Backlogs</label>
|
| 148 |
+
<input type="number" class="form-control form-control-sm" name="max_backlogs" id="max_backlogs_filter" min="0" step="1" placeholder="e.g., 0">
|
| 149 |
+
</div>
|
| 150 |
+
|
| 151 |
+
<div class="mb-3 filter-group">
|
| 152 |
+
<label class="form-label filter-heading">Experience Flags</label>
|
| 153 |
+
<div class="form-check form-switch">
|
| 154 |
+
<input class="form-check-input" type="checkbox" role="switch" name="has_hackathons" id="hasHackathons">
|
| 155 |
+
<label class="form-check-label" for="hasHackathons">Has Hackathon</label>
|
| 156 |
+
</div>
|
| 157 |
+
<div class="form-check form-switch">
|
| 158 |
+
<input class="form-check-input" type="checkbox" role="switch" name="has_experience" id="hasExperience">
|
| 159 |
+
<label class="form-check-label" for="hasExperience">Has Project/Internship</label>
|
| 160 |
+
</div>
|
| 161 |
+
<div class="form-check form-switch">
|
| 162 |
+
<input class="form-check-input" type="checkbox" role="switch" name="has_research" id="hasResearch">
|
| 163 |
+
<label class="form-check-label" for="hasResearch">Has Research/Pubs</label>
|
| 164 |
+
</div>
|
| 165 |
+
</div>
|
| 166 |
+
</div><!-- End Column 1 -->
|
| 167 |
+
|
| 168 |
+
<!-- Column 2: Skills, Roles, Certifications -->
|
| 169 |
+
<div class="col-12 col-lg-6">
|
| 170 |
+
<div class="mb-3 filter-group">
|
| 171 |
+
<label for="skills_filter" class="form-label filter-heading">Skills (any)</label>
|
| 172 |
+
<select class="form-select form-select-sm" name="skills" id="skills_filter" multiple size="5" aria-label="Select skills">
|
| 173 |
+
<!-- Combine programming languages and tools -->
|
| 174 |
+
{% set all_skills = filter_options.programming_languages + filter_options.tools %}
|
| 175 |
+
{% for skill in all_skills | unique | sort %}
|
| 176 |
+
<option value="{{ skill }}">{{ skill }}</option>
|
| 177 |
+
{% endfor %}
|
| 178 |
+
</select>
|
| 179 |
+
<small class="form-text text-muted">Hold Ctrl/Cmd to select multiple</small>
|
| 180 |
+
</div>
|
| 181 |
+
|
| 182 |
+
<div class="mb-3 filter-group">
|
| 183 |
+
<label for="roles_filter" class="form-label filter-heading">Preferred Roles (any)</label>
|
| 184 |
+
<select class="form-select form-select-sm" name="roles" id="roles_filter" multiple size="5" aria-label="Select preferred roles">
|
| 185 |
+
{% for role in filter_options.roles %}
|
| 186 |
+
<option value="{{ role }}">{{ role }}</option>
|
| 187 |
+
{% endfor %}
|
| 188 |
+
</select>
|
| 189 |
+
<small class="form-text text-muted">Hold Ctrl/Cmd to select multiple</small>
|
| 190 |
+
</div>
|
| 191 |
+
|
| 192 |
+
<div class="mb-3 filter-group">
|
| 193 |
+
<label for="certifications_filter" class="form-label filter-heading">Certifications (any)</label>
|
| 194 |
+
<select class="form-select form-select-sm" name="certifications" id="certifications_filter" multiple size="5" aria-label="Select certifications">
|
| 195 |
+
{% for cert in filter_options.certifications %}
|
| 196 |
+
<option value="{{ cert }}">{{ cert }}</option>
|
| 197 |
+
{% endfor %}
|
| 198 |
+
</select>
|
| 199 |
+
<small class="form-text text-muted">Hold Ctrl/Cmd to select multiple</small>
|
| 200 |
+
</div>
|
| 201 |
+
</div><!-- End Column 2 -->
|
| 202 |
+
</div><!-- End Row for columns -->
|
| 203 |
+
|
| 204 |
+
<!-- Buttons (Placed after the columns row) -->
|
| 205 |
+
<div class="d-grid gap-2 mt-3">
|
| 206 |
+
<button type="submit" class="btn btn-primary"><i class="bi bi-funnel-fill"></i> Apply Filters</button>
|
| 207 |
+
<button type="reset" class="btn btn-outline-secondary" id="reset-filters"><i class="bi bi-arrow-clockwise"></i> Reset Filters</button>
|
| 208 |
+
</div>
|
| 209 |
+
</form>
|
| 210 |
+
</div><!-- End card-body -->
|
| 211 |
+
</div><!-- End Filters Card -->
|
| 212 |
+
|
| 213 |
+
<!-- Export Options Card -->
|
| 214 |
+
<div class="card mb-3 shadow-sm">
|
| 215 |
+
<div class="card-header bg-secondary text-white">
|
| 216 |
+
<h5 class="card-title mb-0"><i class="bi bi-download"></i> Export Options</h5>
|
| 217 |
+
</div>
|
| 218 |
+
<div class="card-body">
|
| 219 |
+
<div class="d-grid">
|
| 220 |
+
<button type="button" class="btn btn-success" id="export-csv-btn" disabled>
|
| 221 |
+
<i class="bi bi-file-earmark-spreadsheet"></i> Export Filtered to CSV
|
| 222 |
+
</button>
|
| 223 |
+
</div>
|
| 224 |
+
<small class="form-text text-muted d-block mt-2">Exports the students currently shown in the table.</small>
|
| 225 |
+
<form id="export-form" class="d-none" action="{{ url_for('export_filtered') }}" method="post" target="_blank">
|
| 226 |
+
<input type="hidden" name="filtered_students" id="filtered-students-data-hidden">
|
| 227 |
+
</form>
|
| 228 |
+
</div>
|
| 229 |
+
</div>
|
| 230 |
+
</div> <!-- End Filters Column -->
|
| 231 |
+
|
| 232 |
+
<!-- Main Content Area -->
|
| 233 |
+
<div class="col-lg-9">
|
| 234 |
+
|
| 235 |
+
<!-- Natural Language Query Section -->
|
| 236 |
+
<div class="card mb-3 shadow-sm">
|
| 237 |
+
<div class="card-header bg-light text-dark">
|
| 238 |
+
<h5 class="card-title mb-0"><i class="bi bi-robot"></i> Query Candidates with AI</h5>
|
| 239 |
+
</div>
|
| 240 |
+
<div class="card-body">
|
| 241 |
+
<div id="nl-query-error" class="alert alert-danger d-none p-2" role="alert"></div>
|
| 242 |
+
<div class="mb-2">
|
| 243 |
+
<label for="nl-query-input" class="form-label small">Enter your query (e.g., "Show Computer Science students with CGPA over 8 and Python skill, must have internships")</label>
|
| 244 |
+
<textarea class="form-control form-control-sm" id="nl-query-input" rows="2" placeholder="Describe the candidates you're looking for..."></textarea>
|
| 245 |
+
</div>
|
| 246 |
+
<button type="button" class="btn btn-info btn-sm" id="nl-query-submit">
|
| 247 |
+
<i class="bi bi-magic"></i> Generate & Apply Filters
|
| 248 |
+
</button>
|
| 249 |
+
<span id="nl-query-spinner" class="spinner-border spinner-border-sm text-info ms-2 d-none" role="status" aria-hidden="true"></span>
|
| 250 |
+
<small class="text-muted d-block mt-1">AI will attempt to translate your query into the filters on the left.</small>
|
| 251 |
+
</div>
|
| 252 |
+
</div>
|
| 253 |
+
<!-- End Natural Language Query Section -->
|
| 254 |
+
|
| 255 |
+
|
| 256 |
+
<!-- Visualization Section -->
|
| 257 |
+
<div class="card mb-3 shadow-sm">
|
| 258 |
+
<div class="card-header bg-light text-dark d-flex justify-content-between align-items-center">
|
| 259 |
+
<h5 class="card-title mb-0"><i class="bi bi-bar-chart-line-fill"></i> Data Visualizations <small class="text-muted">(Updates with filters)</small></h5>
|
| 260 |
+
<button class="btn btn-sm btn-outline-secondary" type="button" data-bs-toggle="collapse" data-bs-target="#visualizationsCollapse" aria-expanded="true" aria-controls="visualizationsCollapse" id="collapseVizButton">
|
| 261 |
+
<i class="bi bi-chevron-up"></i> <span>Collapse</span>
|
| 262 |
+
</button>
|
| 263 |
+
</div>
|
| 264 |
+
<div class="collapse show" id="visualizationsCollapse">
|
| 265 |
+
<div class="card-body">
|
| 266 |
+
<div class="row">
|
| 267 |
+
<div class="col-xl-6 col-lg-12 mb-3">
|
| 268 |
+
<div class="card visualization-card h-100 border">
|
| 269 |
+
<div class="card-header small">CGPA Distribution</div>
|
| 270 |
+
<div class="card-body chart-container">
|
| 271 |
+
<canvas id="cgpaChart"></canvas>
|
| 272 |
+
</div>
|
| 273 |
+
</div>
|
| 274 |
+
</div>
|
| 275 |
+
<div class="col-xl-6 col-lg-12 mb-3">
|
| 276 |
+
<div class="card visualization-card h-100 border">
|
| 277 |
+
<div class="card-header small">Department Distribution</div>
|
| 278 |
+
<div class="card-body chart-container">
|
| 279 |
+
<canvas id="deptChart"></canvas>
|
| 280 |
+
</div>
|
| 281 |
+
</div>
|
| 282 |
+
</div>
|
| 283 |
+
<div class="col-xl-6 col-lg-12 mb-3">
|
| 284 |
+
<div class="card visualization-card h-100 border">
|
| 285 |
+
<div class="card-header small">Top Programming Skills</div>
|
| 286 |
+
<div class="card-body chart-container">
|
| 287 |
+
<canvas id="skillsChart"></canvas>
|
| 288 |
+
</div>
|
| 289 |
+
</div>
|
| 290 |
+
</div>
|
| 291 |
+
<div class="col-xl-6 col-lg-12 mb-3">
|
| 292 |
+
<div class="card visualization-card h-100 border">
|
| 293 |
+
<div class="card-header small">Top Preferred Roles</div>
|
| 294 |
+
<div class="card-body chart-container">
|
| 295 |
+
<canvas id="rolesChart"></canvas>
|
| 296 |
+
</div>
|
| 297 |
+
</div>
|
| 298 |
+
</div>
|
| 299 |
+
</div>
|
| 300 |
+
</div>
|
| 301 |
+
</div>
|
| 302 |
+
</div>
|
| 303 |
+
|
| 304 |
+
<!-- Students Table Card -->
|
| 305 |
+
<div class="card mb-3 shadow-sm">
|
| 306 |
+
<div class="card-header bg-light text-dark d-flex justify-content-between align-items-center">
|
| 307 |
+
<h5 class="card-title mb-0">
|
| 308 |
+
<i class="bi bi-people-fill"></i> Students List <span id="student-count" class="badge bg-primary rounded-pill">{{ students|length }}</span>
|
| 309 |
+
</h5>
|
| 310 |
+
<div class="btn-group btn-group-sm">
|
| 311 |
+
<button class="btn btn-outline-primary" id="select-all" title="Select all visible students"><i class="bi bi-check-square"></i> Select All</button>
|
| 312 |
+
<button class="btn btn-outline-primary" id="deselect-all" title="Deselect all visible students"><i class="bi bi-square"></i> Deselect All</button>
|
| 313 |
+
</div>
|
| 314 |
+
</div>
|
| 315 |
+
<div class="card-body p-0">
|
| 316 |
+
<div class="table-responsive" style="max-height: 60vh; overflow-y: auto;">
|
| 317 |
+
<table class="table table-striped table-hover table-sm mb-0">
|
| 318 |
+
<thead class="table-light">
|
| 319 |
+
<tr>
|
| 320 |
+
<th class="text-center" style="width: 3%;"><input type="checkbox" id="select-all-checkbox" class="form-check-input"></th>
|
| 321 |
+
<th style="width: 20%;">Name</th>
|
| 322 |
+
<th style="width: 15%;">Department</th>
|
| 323 |
+
<th style="width: 7%;">CGPA</th>
|
| 324 |
+
<th style="width: 7%;">Backlogs</th>
|
| 325 |
+
<th style="width: 28%;">Top Skills</th>
|
| 326 |
+
<th style="width: 10%;">Experience</th>
|
| 327 |
+
</tr>
|
| 328 |
+
</thead>
|
| 329 |
+
<tbody id="students-tbody">
|
| 330 |
+
<!-- Student rows populated by initial Flask render AND JS updates -->
|
| 331 |
+
{% for student in students %}
|
| 332 |
+
<tr data-email="{{ student.email }}">
|
| 333 |
+
<td class="text-center"><input type="checkbox" class="form-check-input student-checkbox" value="{{ student.email }}"></td>
|
| 334 |
+
<td>{{ student.full_name | default('N/A', true) }}</td>
|
| 335 |
+
<td>{{ student.department | default('N/A', true) }}</td>
|
| 336 |
+
<td>{{ "%.2f"|format(student.cgpa) if student.cgpa is not none else 'N/A' }}</td>
|
| 337 |
+
<td>{{ student.backlogs | default(0, true) }}</td>
|
| 338 |
+
<td>
|
| 339 |
+
{# --- CORRECTED SKILL PROCESSING --- #}
|
| 340 |
+
{% set raw_skills = [] %}
|
| 341 |
+
{% if student.programming_languages %}
|
| 342 |
+
{% if student.programming_languages is string %}
|
| 343 |
+
{% set raw_skills = student.programming_languages.split(',') %}
|
| 344 |
+
{% elif student.programming_languages is iterable and student.programming_languages is not string %} {# Check if it's list-like but not a string #}
|
| 345 |
+
{% set raw_skills = student.programming_languages %}
|
| 346 |
+
{% endif %}
|
| 347 |
+
{% endif %}
|
| 348 |
+
|
| 349 |
+
{# Use namespace to collect unique, cleaned skills #}
|
| 350 |
+
{% set ns = namespace(unique_cleaned_skills=[]) %}
|
| 351 |
+
{% for skill in raw_skills %}
|
| 352 |
+
{% set trimmed_skill = skill | trim %}
|
| 353 |
+
{% if trimmed_skill %}
|
| 354 |
+
{# Basic removal of "(...)" suffix #}
|
| 355 |
+
{% set base_skill = trimmed_skill.split('(')[0] | trim %}
|
| 356 |
+
{% if base_skill and base_skill not in ns.unique_cleaned_skills %}
|
| 357 |
+
{# Append to the list within the namespace #}
|
| 358 |
+
{% set ns.unique_cleaned_skills = ns.unique_cleaned_skills + [base_skill] %}
|
| 359 |
+
{% endif %}
|
| 360 |
+
{% endif %}
|
| 361 |
+
{% endfor %}
|
| 362 |
+
|
| 363 |
+
<small>
|
| 364 |
+
{# Display top 3 unique, cleaned skills #}
|
| 365 |
+
{{ ns.unique_cleaned_skills[:3] | join(', ') }}
|
| 366 |
+
{% if ns.unique_cleaned_skills | length > 3 %}...{% endif %}
|
| 367 |
+
{% if not ns.unique_cleaned_skills %}N/A{% endif %} {# Show N/A if no skills found #}
|
| 368 |
+
</small>
|
| 369 |
+
{# --- END OF CORRECTION --- #}
|
| 370 |
+
</td>
|
| 371 |
+
<td>
|
| 372 |
+
{% if student.internships %}<span class="badge bg-success" title="Internship">I</span>{% endif %}
|
| 373 |
+
{% if student.projects %}<span class="badge bg-primary" title="Projects">P</span>{% endif %}
|
| 374 |
+
{% if student.hackathons %}<span class="badge bg-warning text-dark" title="Hackathon">H</span>{% endif %}
|
| 375 |
+
{% if student.publications %}<span class="badge bg-info text-dark" title="Publication/Research">R</span>{% endif %}
|
| 376 |
+
{% if not student.internships and not student.projects and not student.hackathons and not student.publications %}
|
| 377 |
+
<span class="text-muted small">None</span>
|
| 378 |
+
{% endif %}
|
| 379 |
+
</td>
|
| 380 |
+
</tr>
|
| 381 |
+
{% endfor %}
|
| 382 |
+
</tbody>
|
| 383 |
+
</table>
|
| 384 |
+
</div>
|
| 385 |
+
<div id="no-students-message" class="alert alert-info m-3 {% if students %}d-none{% endif %}">
|
| 386 |
+
No students match the current filters. Try resetting or modifying filters.
|
| 387 |
+
</div>
|
| 388 |
+
</div>
|
| 389 |
+
</div>
|
| 390 |
+
|
| 391 |
+
<!-- AI Insights Section -->
|
| 392 |
+
<div class="card mb-3 shadow-sm">
|
| 393 |
+
<div class="card-header bg-light text-dark">
|
| 394 |
+
<h5 class="card-title mb-0"><i class="bi bi-robot"></i> Gemini-Powered Candidate Insights</h5>
|
| 395 |
+
</div>
|
| 396 |
+
<div class="card-body">
|
| 397 |
+
<form id="ai-insights-form" class="mb-3">
|
| 398 |
+
<div class="row g-2 align-items-end">
|
| 399 |
+
<div class="col-md-6">
|
| 400 |
+
<label for="ai-role-input" class="form-label small mb-1">Job Role for Analysis</label>
|
| 401 |
+
<input type="text" class="form-control form-control-sm" id="ai-role-input" name="role" placeholder="e.g., Software Engineer Intern" required>
|
| 402 |
+
</div>
|
| 403 |
+
<div class="col-md-6">
|
| 404 |
+
<div class="d-grid">
|
| 405 |
+
<button type="submit" class="btn btn-primary btn-sm" id="generate-insights-btn" disabled>
|
| 406 |
+
<i class="bi bi-magic"></i> Generate Insights for Selected (<span id="selected-count">0</span>)
|
| 407 |
+
</button>
|
| 408 |
+
</div>
|
| 409 |
+
</div>
|
| 410 |
+
</div>
|
| 411 |
+
<small class="text-muted d-block mt-1">Select students from the table above first.</small>
|
| 412 |
+
</form>
|
| 413 |
+
<div id="insights-result" class="p-3 border rounded bg-light d-none">
|
| 414 |
+
<h6 class="mb-2">AI Analysis Results <span id="analysis-role" class="text-muted small"></span></h6>
|
| 415 |
+
<div id="insights-spinner" class="text-center d-none my-3">
|
| 416 |
+
<div class="spinner-border text-primary spinner-border-sm" role="status">
|
| 417 |
+
<span class="visually-hidden">Loading...</span>
|
| 418 |
+
</div>
|
| 419 |
+
<p class="mt-1 mb-0 small text-muted">Generating insights...</p>
|
| 420 |
+
</div>
|
| 421 |
+
<div id="insights-content" class="overflow-auto" style="max-height: 450px; white-space: pre-wrap; font-size: 0.9rem; line-height: 1.6;">
|
| 422 |
+
<!-- Insights will be loaded here -->
|
| 423 |
+
</div>
|
| 424 |
+
<div id="insights-error" class="alert alert-danger small p-2 d-none"></div>
|
| 425 |
+
</div>
|
| 426 |
+
</div>
|
| 427 |
+
</div>
|
| 428 |
+
</div> <!-- End Main Content Area Col -->
|
| 429 |
+
</div> <!-- End Row -->
|
| 430 |
+
</div> <!-- End Main Container -->
|
| 431 |
+
|
| 432 |
+
<!-- JavaScript -->
|
| 433 |
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
| 434 |
+
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
|
| 435 |
+
|
| 436 |
+
<!-- Store initial data passed from Flask -->
|
| 437 |
+
<script>
|
| 438 |
+
const initialChartData = {{ initial_chart_data|tojson }};
|
| 439 |
+
// Store the initial full student data (list of dicts) directly if needed, otherwise it's rendered in the table
|
| 440 |
+
let allStudentsInitially = {{ students|tojson|safe }};
|
| 441 |
+
</script>
|
| 442 |
+
|
| 443 |
+
<!-- Custom JS -->
|
| 444 |
+
<script>
|
| 445 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 446 |
+
console.log("Dashboard DOM Loaded.");
|
| 447 |
+
|
| 448 |
+
// --- DOM Elements ---
|
| 449 |
+
const filterForm = document.getElementById('filter-form');
|
| 450 |
+
const resetButton = document.getElementById('reset-filters');
|
| 451 |
+
const studentsTableBody = document.getElementById('students-tbody');
|
| 452 |
+
const studentCountBadge = document.getElementById('student-count');
|
| 453 |
+
const noStudentsMessage = document.getElementById('no-students-message');
|
| 454 |
+
const exportCsvBtn = document.getElementById('export-csv-btn');
|
| 455 |
+
const aiInsightsForm = document.getElementById('ai-insights-form');
|
| 456 |
+
const aiRoleInput = document.getElementById('ai-role-input');
|
| 457 |
+
const insightsResultDiv = document.getElementById('insights-result');
|
| 458 |
+
const insightsContentDiv = document.getElementById('insights-content');
|
| 459 |
+
const insightsErrorDiv = document.getElementById('insights-error'); // Added error div
|
| 460 |
+
const insightsSpinner = document.getElementById('insights-spinner');
|
| 461 |
+
const generateInsightsBtn = document.getElementById('generate-insights-btn');
|
| 462 |
+
const selectedCountSpan = document.getElementById('selected-count');
|
| 463 |
+
const analysisRoleSpan = document.getElementById('analysis-role');
|
| 464 |
+
const selectAllBtn = document.getElementById('select-all');
|
| 465 |
+
const deselectAllBtn = document.getElementById('deselect-all');
|
| 466 |
+
const selectAllCheckbox = document.getElementById('select-all-checkbox');
|
| 467 |
+
const collapseVizButton = document.getElementById('collapseVizButton');
|
| 468 |
+
const collapseVizIcon = collapseVizButton.querySelector('i');
|
| 469 |
+
const collapseVizText = collapseVizButton.querySelector('span');
|
| 470 |
+
const visualizationsCollapse = document.getElementById('visualizationsCollapse');
|
| 471 |
+
// NL Query Elements
|
| 472 |
+
const nlQueryInput = document.getElementById('nl-query-input');
|
| 473 |
+
const nlQuerySubmitBtn = document.getElementById('nl-query-submit');
|
| 474 |
+
const nlQuerySpinner = document.getElementById('nl-query-spinner');
|
| 475 |
+
const nlQueryErrorDiv = document.getElementById('nl-query-error');
|
| 476 |
+
|
| 477 |
+
// --- Chart Variables ---
|
| 478 |
+
const chartInstances = {}; // Store instances by ID
|
| 479 |
+
|
| 480 |
+
// --- Chart Options ---
|
| 481 |
+
const commonChartOptions = { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false }, tooltip: { backgroundColor: 'rgba(0, 0, 0, 0.7)', titleFont: { size: 14 }, bodyFont: { size: 12 }, padding: 10 } }, layout: { padding: { top: 5, bottom: 5 } } };
|
| 482 |
+
const verticalBarOptions = { ...commonChartOptions, scales: { y: { beginAtZero: true, ticks: { precision: 0 } } } };
|
| 483 |
+
const horizontalBarOptions = { ...commonChartOptions, indexAxis: 'y', scales: { x: { beginAtZero: true, ticks: { precision: 0 } } } };
|
| 484 |
+
const pieChartOptions = { ...commonChartOptions, plugins: { legend: { position: 'right', labels: { font: { size: 10 }, boxWidth: 10 } }, tooltip: commonChartOptions.plugins.tooltip } };
|
| 485 |
+
const chartColors = ['rgba(0, 123, 255, 0.7)', 'rgba(255, 193, 7, 0.7)', 'rgba(40, 167, 69, 0.7)', 'rgba(220, 53, 69, 0.7)', 'rgba(23, 162, 184, 0.7)', 'rgba(108, 117, 125, 0.7)', 'rgba(52, 58, 64, 0.7)', 'rgba(111, 66, 193, 0.7)', 'rgba(253, 126, 20, 0.7)', 'rgba(32, 201, 151, 0.7)'];
|
| 486 |
+
const chartBorderColors = chartColors.map(color => color.replace('0.7', '1'));
|
| 487 |
+
|
| 488 |
+
|
| 489 |
+
// --- State ---
|
| 490 |
+
let currentFilteredStudentsData = []; // Stores full data for visible students
|
| 491 |
+
|
| 492 |
+
// --- Utility Functions ---
|
| 493 |
+
const getSafe = (fn, defaultVal) => { try { const result = fn(); return (result === undefined || result === null) ? defaultVal : result; } catch (e) { return defaultVal; } };
|
| 494 |
+
|
| 495 |
+
function showCanvasMessage(canvasId, message) {
|
| 496 |
+
const ctx = document.getElementById(canvasId)?.getContext('2d');
|
| 497 |
+
if (ctx) {
|
| 498 |
+
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
| 499 |
+
ctx.save(); ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillStyle = '#aaa'; ctx.font = '14px Arial';
|
| 500 |
+
ctx.fillText(message, ctx.canvas.width / 2, ctx.canvas.height / 2); ctx.restore();
|
| 501 |
+
}
|
| 502 |
+
}
|
| 503 |
+
|
| 504 |
+
function createOrUpdateChart(canvasId, type, chartDataObj, options) {
|
| 505 |
+
const ctx = document.getElementById(canvasId)?.getContext('2d');
|
| 506 |
+
if (!ctx) { console.error(`Canvas element "${canvasId}" not found.`); return; }
|
| 507 |
+
if (chartInstances[canvasId]) { chartInstances[canvasId].destroy(); }
|
| 508 |
+
|
| 509 |
+
const labels = getSafe(() => chartDataObj.labels, []);
|
| 510 |
+
const dataValues = getSafe(() => chartDataObj.data, []);
|
| 511 |
+
const numericData = dataValues.map(Number);
|
| 512 |
+
|
| 513 |
+
if (labels.length === 0 || numericData.length === 0 || numericData.every(v => v === 0 && !isNaN(v))) {
|
| 514 |
+
showCanvasMessage(canvasId, 'No data available'); chartInstances[canvasId] = null; return;
|
| 515 |
+
}
|
| 516 |
+
try {
|
| 517 |
+
chartInstances[canvasId] = new Chart(ctx, { type: type, data: { labels: labels, datasets: [{ label: canvasId.replace('Chart', ''), data: numericData, backgroundColor: chartColors, borderColor: chartBorderColors, borderWidth: 1 }] }, options: options });
|
| 518 |
+
console.log(`Chart updated: ${canvasId}`);
|
| 519 |
+
} catch (error) {
|
| 520 |
+
console.error(`Error creating chart ${canvasId}:`, error); showCanvasMessage(canvasId, 'Error loading chart'); chartInstances[canvasId] = null;
|
| 521 |
+
}
|
| 522 |
+
}
|
| 523 |
+
|
| 524 |
+
function updateAllCharts(chartData) {
|
| 525 |
+
console.log("Updating All Charts (Frontend) with:", chartData);
|
| 526 |
+
if (!chartData) { console.error("updateAllCharts called with null/undefined data."); return; }
|
| 527 |
+
const defaultData = { labels: [], data: [] };
|
| 528 |
+
createOrUpdateChart('cgpaChart', 'bar', chartData.cgpa || defaultData, verticalBarOptions);
|
| 529 |
+
createOrUpdateChart('deptChart', 'pie', chartData.department || defaultData, pieChartOptions);
|
| 530 |
+
createOrUpdateChart('skillsChart', 'bar', chartData.skills || defaultData, horizontalBarOptions);
|
| 531 |
+
createOrUpdateChart('rolesChart', 'bar', chartData.roles || defaultData, horizontalBarOptions);
|
| 532 |
+
}
|
| 533 |
+
|
| 534 |
+
function updateStudentsTable(students) {
|
| 535 |
+
console.log(`Updating table with ${students ? students.length : 0} students.`);
|
| 536 |
+
studentsTableBody.innerHTML = '';
|
| 537 |
+
currentFilteredStudentsData = students || []; // Store full data for export/AI
|
| 538 |
+
|
| 539 |
+
if (!currentFilteredStudentsData || currentFilteredStudentsData.length === 0) {
|
| 540 |
+
noStudentsMessage.classList.remove('d-none');
|
| 541 |
+
exportCsvBtn.disabled = true;
|
| 542 |
+
} else {
|
| 543 |
+
noStudentsMessage.classList.add('d-none');
|
| 544 |
+
exportCsvBtn.disabled = false;
|
| 545 |
+
currentFilteredStudentsData.forEach(student => {
|
| 546 |
+
const row = document.createElement('tr');
|
| 547 |
+
row.dataset.email = student.email;
|
| 548 |
+
|
| 549 |
+
const fullName = getSafe(() => student.full_name, 'N/A');
|
| 550 |
+
const department = getSafe(() => student.department, 'N/A');
|
| 551 |
+
const cgpa = getSafe(() => student.cgpa, null);
|
| 552 |
+
const cgpaFormatted = cgpa !== null ? cgpa.toFixed(2) : 'N/A';
|
| 553 |
+
const backlogs = getSafe(() => student.backlogs, 0);
|
| 554 |
+
|
| 555 |
+
// Simplified Skill Display Logic (handles list or string)
|
| 556 |
+
let skillsRaw = getSafe(() => student.programming_languages, []);
|
| 557 |
+
let skillsArray = [];
|
| 558 |
+
if (typeof skillsRaw === 'string') {
|
| 559 |
+
skillsArray = skillsRaw.split(',').map(s => s.trim()).filter(Boolean);
|
| 560 |
+
} else if (Array.isArray(skillsRaw)) {
|
| 561 |
+
skillsArray = skillsRaw.map(s => String(s).trim()).filter(Boolean);
|
| 562 |
+
}
|
| 563 |
+
// Remove proficiency in brackets for display
|
| 564 |
+
const skillsCleaned = skillsArray.map(s => s.replace(/\s*\(.*\)$/, ''));
|
| 565 |
+
const topSkills = skillsCleaned.slice(0, 3).join(', ') + (skillsCleaned.length > 3 ? '...' : '');
|
| 566 |
+
|
| 567 |
+
|
| 568 |
+
let experienceHtml = '';
|
| 569 |
+
if (getSafe(() => student.internships, null)) experienceHtml += '<span class="badge bg-success" title="Internship">I</span> ';
|
| 570 |
+
if (getSafe(() => student.projects, null)) experienceHtml += '<span class="badge bg-primary" title="Projects">P</span> ';
|
| 571 |
+
if (getSafe(() => student.hackathons, null)) experienceHtml += '<span class="badge bg-warning text-dark" title="Hackathon">H</span> ';
|
| 572 |
+
if (getSafe(() => student.publications, null)) experienceHtml += '<span class="badge bg-info text-dark" title="Publication/Research">R</span> ';
|
| 573 |
+
if (!experienceHtml) experienceHtml = '<span class="text-muted small">None</span>';
|
| 574 |
+
|
| 575 |
+
row.innerHTML = `
|
| 576 |
+
<td class="text-center"><input type="checkbox" class="form-check-input student-checkbox" value="${student.email}"></td>
|
| 577 |
+
<td>${fullName}</td>
|
| 578 |
+
<td>${department}</td>
|
| 579 |
+
<td>${cgpaFormatted}</td>
|
| 580 |
+
<td>${backlogs}</td>
|
| 581 |
+
<td><small>${topSkills || 'N/A'}</small></td>
|
| 582 |
+
<td>${experienceHtml.trim()}</td>
|
| 583 |
+
`;
|
| 584 |
+
studentsTableBody.appendChild(row);
|
| 585 |
+
});
|
| 586 |
+
}
|
| 587 |
+
studentCountBadge.textContent = currentFilteredStudentsData.length;
|
| 588 |
+
selectAllCheckbox.checked = false;
|
| 589 |
+
updateAiButtonState();
|
| 590 |
+
}
|
| 591 |
+
|
| 592 |
+
function updateAiButtonState() {
|
| 593 |
+
const selectedCheckboxes = studentsTableBody.querySelectorAll('.student-checkbox:checked');
|
| 594 |
+
const count = selectedCheckboxes.length;
|
| 595 |
+
selectedCountSpan.textContent = count;
|
| 596 |
+
generateInsightsBtn.disabled = count === 0;
|
| 597 |
+
}
|
| 598 |
+
|
| 599 |
+
function exportToCsv(filename, rows) {
|
| 600 |
+
console.log(`Exporting ${rows.length} rows to ${filename}`);
|
| 601 |
+
if (rows.length === 0) { alert("No data to export."); return; }
|
| 602 |
+
// Use the actual headers from the first row object keys for flexibility
|
| 603 |
+
const headers = Object.keys(rows[0]);
|
| 604 |
+
const processRow = (row) => headers.map(header => {
|
| 605 |
+
let value = row[header]; if (value === null || value === undefined) return ''; if (Array.isArray(value)) value = value.join('; '); let stringValue = String(value); if (stringValue.includes('"') || stringValue.includes(',') || stringValue.includes('\n')) stringValue = `"${stringValue.replace(/"/g, '""')}"`; return stringValue;
|
| 606 |
+
}).join(',');
|
| 607 |
+
const csvContent = [headers.join(','), ...rows.map(processRow)].join('\n');
|
| 608 |
+
const blob = new Blob([`\uFEFF${csvContent}`], { type: 'text/csv;charset=utf-8;' }); // Add BOM
|
| 609 |
+
const link = document.createElement("a");
|
| 610 |
+
if (link.download !== undefined) { const url = URL.createObjectURL(blob); link.setAttribute("href", url); link.setAttribute("download", filename); link.style.visibility = 'hidden'; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); } else { alert("CSV export is not supported."); }
|
| 611 |
+
}
|
| 612 |
+
|
| 613 |
+
// --- Function to update filter form from AI results ---
|
| 614 |
+
function updateFilterForm(filters) {
|
| 615 |
+
console.log("Updating filter form with:", filters);
|
| 616 |
+
// Resetting form ensures clean slate
|
| 617 |
+
filterForm.reset();
|
| 618 |
+
// Reset multi-selects explicitly
|
| 619 |
+
filterForm.querySelectorAll('select[multiple]').forEach(select => {
|
| 620 |
+
Array.from(select.options).forEach(option => option.selected = false);
|
| 621 |
+
});
|
| 622 |
+
|
| 623 |
+
// Clear Job ID filter if applying manual/AI filters
|
| 624 |
+
document.getElementById('job_id_filter').value = '';
|
| 625 |
+
|
| 626 |
+
// Apply filters from AI
|
| 627 |
+
if (filters.min_cgpa !== undefined && filters.min_cgpa !== null) {
|
| 628 |
+
document.getElementById('min_cgpa_filter').value = filters.min_cgpa;
|
| 629 |
+
} else {
|
| 630 |
+
document.getElementById('min_cgpa_filter').value = ''; // Explicitly clear if null/undefined
|
| 631 |
+
}
|
| 632 |
+
if (filters.max_backlogs !== undefined && filters.max_backlogs !== null) {
|
| 633 |
+
document.getElementById('max_backlogs_filter').value = filters.max_backlogs;
|
| 634 |
+
} else {
|
| 635 |
+
document.getElementById('max_backlogs_filter').value = ''; // Explicitly clear
|
| 636 |
+
}
|
| 637 |
+
|
| 638 |
+
// Boolean flags
|
| 639 |
+
document.getElementById('hasHackathons').checked = filters.has_hackathons === true;
|
| 640 |
+
document.getElementById('hasExperience').checked = filters.has_experience === true;
|
| 641 |
+
document.getElementById('hasResearch').checked = filters.has_research === true;
|
| 642 |
+
|
| 643 |
+
// Handle multi-selects (Skills, Roles, Certifications)
|
| 644 |
+
function applyMultiSelect(selectId, values) {
|
| 645 |
+
if (values && Array.isArray(values) && values.length > 0) {
|
| 646 |
+
const selectElement = document.getElementById(selectId);
|
| 647 |
+
if (selectElement) {
|
| 648 |
+
Array.from(selectElement.options).forEach(option => {
|
| 649 |
+
option.selected = values.some(val =>
|
| 650 |
+
option.value.toLowerCase() === String(val).toLowerCase().trim() ||
|
| 651 |
+
option.text.toLowerCase() === String(val).toLowerCase().trim()
|
| 652 |
+
);
|
| 653 |
+
});
|
| 654 |
+
} else {
|
| 655 |
+
console.warn(`Select element #${selectId} not found.`);
|
| 656 |
+
}
|
| 657 |
+
}
|
| 658 |
+
}
|
| 659 |
+
|
| 660 |
+
applyMultiSelect('skills_filter', filters.skills);
|
| 661 |
+
applyMultiSelect('roles_filter', filters.roles);
|
| 662 |
+
applyMultiSelect('certifications_filter', filters.certifications);
|
| 663 |
+
|
| 664 |
+
// Handle department (if mentioned by AI and a filter field exists)
|
| 665 |
+
// Note: 'department' is not currently a standard filter field in the form
|
| 666 |
+
if (filters.department) {
|
| 667 |
+
console.log(`AI suggested department filter: ${filters.department} (No dedicated form field yet)`);
|
| 668 |
+
// If you add a department filter input/select later, update it here:
|
| 669 |
+
// const deptSelect = document.getElementById('department_filter');
|
| 670 |
+
// if (deptSelect) deptSelect.value = filters.department;
|
| 671 |
+
}
|
| 672 |
+
|
| 673 |
+
console.log("Filter form updated by AI result.");
|
| 674 |
+
}
|
| 675 |
+
|
| 676 |
+
|
| 677 |
+
// --- Event Listeners ---
|
| 678 |
+
filterForm.addEventListener('submit', function(e) {
|
| 679 |
+
e.preventDefault(); const formData = new FormData(filterForm);
|
| 680 |
+
console.log("Applying Filters (Manual or AI Triggered)...");
|
| 681 |
+
filterForm.querySelector('button[type="submit"]').disabled = true;
|
| 682 |
+
filterForm.querySelector('button[type="submit"]').innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Filtering...';
|
| 683 |
+
noStudentsMessage.classList.add('d-none'); // Hide message initially
|
| 684 |
+
|
| 685 |
+
// Clear Job ID if manual filters are being changed (except job ID itself)
|
| 686 |
+
const jobIdFilter = document.getElementById('job_id_filter');
|
| 687 |
+
if (e.submitter !== jobIdFilter && jobIdFilter.value !== '') {
|
| 688 |
+
// Check if the submit was triggered by something other than changing the job filter itself
|
| 689 |
+
// AND if a job ID was previously selected. This logic might need refinement depending on desired interaction.
|
| 690 |
+
// A simpler approach might be to always clear job ID if any manual filter is touched.
|
| 691 |
+
// console.log("Manual filter change detected, clearing Job ID filter.");
|
| 692 |
+
// jobIdFilter.value = '';
|
| 693 |
+
// formData.set('job_id', ''); // Update formData as well
|
| 694 |
+
}
|
| 695 |
+
|
| 696 |
+
|
| 697 |
+
fetch('{{ url_for("filter_students_route") }}', { method: 'POST', body: formData })
|
| 698 |
+
.then(response => { if (!response.ok) { return response.json().then(errData => { throw new Error(getSafe(() => errData.error, `HTTP ${response.status}`)); }).catch(() => { throw new Error(`HTTP ${response.status}`); }); } return response.json(); })
|
| 699 |
+
.then(data => {
|
| 700 |
+
console.log("Filter Response:", data);
|
| 701 |
+
if (data.error) { throw new Error(data.error); }
|
| 702 |
+
updateStudentsTable(data.students); // Update table with full data
|
| 703 |
+
if (data.chart_data) {
|
| 704 |
+
updateAllCharts(data.chart_data);
|
| 705 |
+
} else { console.error("Chart data missing in filter response!"); }
|
| 706 |
+
exportCsvBtn.disabled = data.students.length === 0;
|
| 707 |
+
})
|
| 708 |
+
.catch(error => {
|
| 709 |
+
console.error('Filter Error:', error);
|
| 710 |
+
noStudentsMessage.textContent = `Error applying filters: ${error.message}`;
|
| 711 |
+
noStudentsMessage.classList.remove('d-none', 'alert-info');
|
| 712 |
+
noStudentsMessage.classList.add('alert-danger');
|
| 713 |
+
studentsTableBody.innerHTML = ''; // Clear table on error
|
| 714 |
+
studentCountBadge.textContent = 0;
|
| 715 |
+
updateAllCharts({ cgpa: {}, department: {}, skills: {}, roles: {} }); // Clear charts
|
| 716 |
+
exportCsvBtn.disabled = true;
|
| 717 |
+
})
|
| 718 |
+
.finally(() => {
|
| 719 |
+
filterForm.querySelector('button[type="submit"]').disabled = false;
|
| 720 |
+
filterForm.querySelector('button[type="submit"]').innerHTML = '<i class="bi bi-funnel-fill"></i> Apply Filters';
|
| 721 |
+
});
|
| 722 |
+
});
|
| 723 |
+
|
| 724 |
+
resetButton.addEventListener('click', function() {
|
| 725 |
+
console.log("Resetting filters...");
|
| 726 |
+
filterForm.reset();
|
| 727 |
+
// Explicitly reset multi-selects
|
| 728 |
+
filterForm.querySelectorAll('select[multiple]').forEach(select => {
|
| 729 |
+
Array.from(select.options).forEach(option => option.selected = false);
|
| 730 |
+
});
|
| 731 |
+
// Reset Job ID filter
|
| 732 |
+
document.getElementById('job_id_filter').value = '';
|
| 733 |
+
// Automatically trigger a filter update after reset
|
| 734 |
+
setTimeout(() => filterForm.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true })), 50);
|
| 735 |
+
});
|
| 736 |
+
|
| 737 |
+
exportCsvBtn.addEventListener('click', () => {
|
| 738 |
+
const timestamp = new Date().toISOString().slice(0, 19).replace(/[-T:]/g, "");
|
| 739 |
+
const filename = `filtered_students_${timestamp}.csv`;
|
| 740 |
+
// Export the stored full data of currently filtered students
|
| 741 |
+
exportToCsv(filename, currentFilteredStudentsData);
|
| 742 |
+
});
|
| 743 |
+
|
| 744 |
+
selectAllBtn.addEventListener('click', () => { studentsTableBody.querySelectorAll('.student-checkbox:not(:disabled)').forEach(cb => cb.checked = true); selectAllCheckbox.checked = true; updateAiButtonState(); });
|
| 745 |
+
deselectAllBtn.addEventListener('click', () => { studentsTableBody.querySelectorAll('.student-checkbox:not(:disabled)').forEach(cb => cb.checked = false); selectAllCheckbox.checked = false; updateAiButtonState(); });
|
| 746 |
+
selectAllCheckbox.addEventListener('change', function() { studentsTableBody.querySelectorAll('.student-checkbox:not(:disabled)').forEach(cb => cb.checked = this.checked); updateAiButtonState(); });
|
| 747 |
+
studentsTableBody.addEventListener('change', function(event) {
|
| 748 |
+
if (event.target.classList.contains('student-checkbox')) {
|
| 749 |
+
updateAiButtonState();
|
| 750 |
+
const allVisible = studentsTableBody.querySelectorAll('.student-checkbox:not(:disabled)');
|
| 751 |
+
const checkedVisible = studentsTableBody.querySelectorAll('.student-checkbox:checked:not(:disabled)');
|
| 752 |
+
selectAllCheckbox.checked = allVisible.length > 0 && allVisible.length === checkedVisible.length;
|
| 753 |
+
}
|
| 754 |
+
});
|
| 755 |
+
|
| 756 |
+
aiInsightsForm.addEventListener('submit', function(e) {
|
| 757 |
+
e.preventDefault();
|
| 758 |
+
const selectedStudents = Array.from(studentsTableBody.querySelectorAll('.student-checkbox:checked')).map(cb => cb.value);
|
| 759 |
+
const role = aiRoleInput.value.trim();
|
| 760 |
+
|
| 761 |
+
if (selectedStudents.length === 0) { alert('Please select one or more students from the table first.'); return; }
|
| 762 |
+
if (!role) { alert('Please enter the Job Role for analysis.'); aiRoleInput.focus(); return; }
|
| 763 |
+
|
| 764 |
+
const formData = new FormData();
|
| 765 |
+
selectedStudents.forEach(email => formData.append('selected_students', email));
|
| 766 |
+
formData.append('role', role);
|
| 767 |
+
|
| 768 |
+
insightsResultDiv.classList.remove('d-none');
|
| 769 |
+
insightsContentDiv.innerHTML = '';
|
| 770 |
+
insightsErrorDiv.classList.add('d-none'); // Hide previous errors
|
| 771 |
+
insightsSpinner.classList.remove('d-none');
|
| 772 |
+
generateInsightsBtn.disabled = true;
|
| 773 |
+
generateInsightsBtn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> Generating...';
|
| 774 |
+
analysisRoleSpan.textContent = `(for ${role})`;
|
| 775 |
+
|
| 776 |
+
fetch('{{ url_for("ai_insights_route") }}', { method: 'POST', body: formData })
|
| 777 |
+
.then(response => { if (!response.ok) { return response.json().then(errData => { throw new Error(getSafe(() => errData.error, `HTTP ${response.status}`)); }).catch(() => { throw new Error(`HTTP ${response.status}`); }); } return response.json(); })
|
| 778 |
+
.then(data => {
|
| 779 |
+
console.log("AI Insights Response:", data);
|
| 780 |
+
if (data.error) {
|
| 781 |
+
throw new Error(data.error); // Throw error to be caught below
|
| 782 |
+
} else {
|
| 783 |
+
let formatted = data.insights || "No insights generated.";
|
| 784 |
+
// Basic Markdown-like formatting
|
| 785 |
+
formatted = formatted
|
| 786 |
+
.replace(/</g, "<").replace(/>/g, ">") // Basic HTML escaping first
|
| 787 |
+
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>') // Bold
|
| 788 |
+
.replace(/\*(.*?)\*/g, '<em>$1</em>') // Italics
|
| 789 |
+
.replace(/^### (.*$)/gim, '<h6 class="mt-2 mb-1">$1</h6>') // Headings
|
| 790 |
+
.replace(/^## (.*$)/gim, '<h5 class="mt-2 mb-1">$1</h5>')
|
| 791 |
+
.replace(/^# (.*$)/gim, '<h4 class="mt-2 mb-1">$1</h4>')
|
| 792 |
+
.replace(/^\s*[-*+] (.*$)/gim, '<li>$1</li>'); // List items
|
| 793 |
+
|
| 794 |
+
// Wrap consecutive list items in <ul>
|
| 795 |
+
formatted = formatted.replace(/(<li>.*<\/li>\s*)+/g, (match) => `<ul class="list-unstyled mb-2 ms-3">${match.replace(/<\/li>\s*<li>/g, '</li><li>')}</ul>`);
|
| 796 |
+
|
| 797 |
+
// Replace newlines with <br>, but not inside lists or after headings
|
| 798 |
+
formatted = formatted.replace(/(\<\/(?:ul|h[4-6])\>)\n+/g, '$1'); // Remove newlines after block elements
|
| 799 |
+
formatted = formatted.replace(/\n/g, '<br>'); // Convert remaining newlines
|
| 800 |
+
|
| 801 |
+
insightsContentDiv.innerHTML = formatted;
|
| 802 |
+
insightsErrorDiv.classList.add('d-none');
|
| 803 |
+
}
|
| 804 |
+
})
|
| 805 |
+
.catch(error => {
|
| 806 |
+
console.error('AI Insights Error:', error);
|
| 807 |
+
insightsErrorDiv.textContent = `Error: ${error.message}`;
|
| 808 |
+
insightsErrorDiv.classList.remove('d-none');
|
| 809 |
+
insightsContentDiv.innerHTML = ''; // Clear content on error
|
| 810 |
+
})
|
| 811 |
+
.finally(() => {
|
| 812 |
+
insightsSpinner.classList.add('d-none');
|
| 813 |
+
// Re-enable button using the count from the function
|
| 814 |
+
updateAiButtonState();
|
| 815 |
+
const currentCount = studentsTableBody.querySelectorAll('.student-checkbox:checked').length;
|
| 816 |
+
generateInsightsBtn.innerHTML = `<i class="bi bi-magic"></i> Generate Insights for Selected (${currentCount})`;
|
| 817 |
+
});
|
| 818 |
+
});
|
| 819 |
+
|
| 820 |
+
// Event Listener for Natural Language Query
|
| 821 |
+
nlQuerySubmitBtn.addEventListener('click', function() {
|
| 822 |
+
const query = nlQueryInput.value.trim();
|
| 823 |
+
if (!query) {
|
| 824 |
+
nlQueryErrorDiv.textContent = 'Please enter a query.';
|
| 825 |
+
nlQueryErrorDiv.classList.remove('d-none');
|
| 826 |
+
return;
|
| 827 |
+
}
|
| 828 |
+
|
| 829 |
+
nlQuerySubmitBtn.disabled = true;
|
| 830 |
+
nlQuerySpinner.classList.remove('d-none');
|
| 831 |
+
nlQueryErrorDiv.classList.add('d-none');
|
| 832 |
+
nlQueryErrorDiv.textContent = '';
|
| 833 |
+
|
| 834 |
+
fetch('{{ url_for("process_nl_query") }}', {
|
| 835 |
+
method: 'POST',
|
| 836 |
+
headers: { 'Content-Type': 'application/json' },
|
| 837 |
+
body: JSON.stringify({ query: query })
|
| 838 |
+
})
|
| 839 |
+
.then(response => {
|
| 840 |
+
if (!response.ok) {
|
| 841 |
+
return response.json().then(errData => { throw new Error(errData.error || `HTTP error! Status: ${response.status}`); })
|
| 842 |
+
.catch(() => { throw new Error(`HTTP error! Status: ${response.status}`); });
|
| 843 |
+
}
|
| 844 |
+
return response.json();
|
| 845 |
+
})
|
| 846 |
+
.then(data => {
|
| 847 |
+
if (data.error) { throw new Error(data.error); }
|
| 848 |
+
console.log("Received filter parameters from AI:", data.filters);
|
| 849 |
+
updateFilterForm(data.filters);
|
| 850 |
+
console.log("Triggering filter form submission...");
|
| 851 |
+
// Use setTimeout to allow the browser to update the form values before submitting
|
| 852 |
+
setTimeout(() => {
|
| 853 |
+
filterForm.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true }));
|
| 854 |
+
}, 50); // Small delay
|
| 855 |
+
})
|
| 856 |
+
.catch(error => {
|
| 857 |
+
console.error('Error processing NL query:', error);
|
| 858 |
+
nlQueryErrorDiv.textContent = `Error translating query: ${error.message}`;
|
| 859 |
+
nlQueryErrorDiv.classList.remove('d-none');
|
| 860 |
+
})
|
| 861 |
+
.finally(() => {
|
| 862 |
+
nlQuerySubmitBtn.disabled = false;
|
| 863 |
+
nlQuerySpinner.classList.add('d-none');
|
| 864 |
+
});
|
| 865 |
+
});
|
| 866 |
+
|
| 867 |
+
visualizationsCollapse.addEventListener('show.bs.collapse', () => { collapseVizIcon.classList.replace('bi-chevron-down', 'bi-chevron-up'); collapseVizText.textContent = 'Collapse'; });
|
| 868 |
+
visualizationsCollapse.addEventListener('hide.bs.collapse', () => { collapseVizIcon.classList.replace('bi-chevron-up', 'bi-chevron-down'); collapseVizText.textContent = 'Expand'; });
|
| 869 |
+
|
| 870 |
+
|
| 871 |
+
// --- Initial Load ---
|
| 872 |
+
console.log("--- Initializing Dashboard ---");
|
| 873 |
+
// Data is rendered server-side initially. JS updates state.
|
| 874 |
+
currentFilteredStudentsData = allStudentsInitially; // Initialize JS state
|
| 875 |
+
updateAiButtonState(); // Set initial AI button state
|
| 876 |
+
exportCsvBtn.disabled = currentFilteredStudentsData.length === 0; // Set initial export button state
|
| 877 |
+
|
| 878 |
+
if (initialChartData) {
|
| 879 |
+
console.log("Initializing Charts with Initial Data (Frontend):", initialChartData);
|
| 880 |
+
updateAllCharts(initialChartData);
|
| 881 |
+
} else {
|
| 882 |
+
console.error("Initial chart data is missing!");
|
| 883 |
+
updateAllCharts({ cgpa: {}, department: {}, skills: {}, roles: {} }); // Init empty charts
|
| 884 |
+
}
|
| 885 |
+
console.log("--- Dashboard Initialized ---");
|
| 886 |
+
}); // End DOMContentLoaded
|
| 887 |
+
</script>
|
| 888 |
+
|
| 889 |
+
</body>
|
| 890 |
+
</html>
|
templates/company_login.html
ADDED
|
@@ -0,0 +1,458 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Company Login | Campus Recruitment Portal</title>
|
| 7 |
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
|
| 8 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
|
| 9 |
+
<style>
|
| 10 |
+
/* Campus Recruitment Portal - Main Stylesheet
|
| 11 |
+
This file contains styles for all pages in the application */
|
| 12 |
+
:root {
|
| 13 |
+
--primary-color: #0d6efd;
|
| 14 |
+
--primary-dark: #0b5ed7;
|
| 15 |
+
--secondary-color: #6c757d;
|
| 16 |
+
--success-color: #198754;
|
| 17 |
+
--info-color: #0dcaf0;
|
| 18 |
+
--warning-color: #ffc107;
|
| 19 |
+
--danger-color: #dc3545;
|
| 20 |
+
--light-color: #f8f9fa;
|
| 21 |
+
--dark-color: #212529;
|
| 22 |
+
--border-radius: 0.375rem;
|
| 23 |
+
--box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
body {
|
| 27 |
+
font-family: 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
| 28 |
+
background-color: #f5f5f5;
|
| 29 |
+
color: #333;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
/* ======= Typography ======= */
|
| 33 |
+
h1, h2, h3, h4, h5, h6 {
|
| 34 |
+
font-weight: 600;
|
| 35 |
+
margin-bottom: 1rem;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
.text-primary {
|
| 39 |
+
color: var(--primary-color) !important;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
/* ======= Layout Components ======= */
|
| 43 |
+
.main-container {
|
| 44 |
+
padding-top: 1.5rem;
|
| 45 |
+
padding-bottom: 2rem;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
.card {
|
| 49 |
+
border-radius: var(--border-radius);
|
| 50 |
+
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
| 51 |
+
margin-bottom: 1.5rem;
|
| 52 |
+
border: none;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
.card-header {
|
| 56 |
+
background-color: rgba(0, 0, 0, 0.03);
|
| 57 |
+
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
|
| 58 |
+
padding: 0.75rem 1.25rem;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
.card-header.bg-primary {
|
| 62 |
+
background-color: var(--primary-color) !important;
|
| 63 |
+
color: white;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
.card-header.bg-secondary {
|
| 67 |
+
background-color: var(--secondary-color) !important;
|
| 68 |
+
color: white;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
.card-body {
|
| 72 |
+
padding: 1.25rem;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
.card-footer {
|
| 76 |
+
padding: 0.75rem 1.25rem;
|
| 77 |
+
background-color: rgba(0, 0, 0, 0.03);
|
| 78 |
+
border-top: 1px solid rgba(0, 0, 0, 0.125);
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
/* ======= Navigation ======= */
|
| 82 |
+
.navbar {
|
| 83 |
+
padding: 0.5rem 1rem;
|
| 84 |
+
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
.navbar-brand {
|
| 88 |
+
font-weight: 600;
|
| 89 |
+
font-size: 1.25rem;
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
.nav-link {
|
| 93 |
+
padding: 0.5rem 1rem;
|
| 94 |
+
transition: all 0.2s ease-in-out;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
.nav-link:hover {
|
| 98 |
+
opacity: 0.85;
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
.nav-link.active {
|
| 102 |
+
font-weight: 600;
|
| 103 |
+
background-color: rgba(255, 255, 255, 0.1);
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
/* ======= Forms ======= */
|
| 107 |
+
.form-control, .form-select {
|
| 108 |
+
border-radius: var(--border-radius);
|
| 109 |
+
padding: 0.375rem 0.75rem;
|
| 110 |
+
border: 1px solid #ced4da;
|
| 111 |
+
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
.form-control:focus, .form-select:focus {
|
| 115 |
+
border-color: rgba(13, 110, 253, 0.5);
|
| 116 |
+
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
.form-label {
|
| 120 |
+
margin-bottom: 0.5rem;
|
| 121 |
+
font-weight: 500;
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
.form-text {
|
| 125 |
+
color: #6c757d;
|
| 126 |
+
margin-top: 0.25rem;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
/* ======= Login Page ======= */
|
| 130 |
+
.login-container {
|
| 131 |
+
min-height: 100vh;
|
| 132 |
+
display: flex;
|
| 133 |
+
align-items: center;
|
| 134 |
+
justify-content: center;
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
.login-card {
|
| 138 |
+
width: 100%;
|
| 139 |
+
max-width: 450px;
|
| 140 |
+
box-shadow: var(--box-shadow);
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
.demo-credentials {
|
| 144 |
+
background-color: #f8f9fa;
|
| 145 |
+
padding: 0.75rem;
|
| 146 |
+
border-radius: var(--border-radius);
|
| 147 |
+
margin-top: 1rem;
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
/* ======= Dashboard ======= */
|
| 151 |
+
.dashboard-stats {
|
| 152 |
+
padding: 1.5rem;
|
| 153 |
+
background-color: white;
|
| 154 |
+
box-shadow: var(--box-shadow);
|
| 155 |
+
border-radius: var(--border-radius);
|
| 156 |
+
margin-bottom: 1.5rem;
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
.stats-card {
|
| 160 |
+
text-align: center;
|
| 161 |
+
padding: 1.25rem;
|
| 162 |
+
border: 1px solid rgba(0, 0, 0, 0.125);
|
| 163 |
+
border-radius: var(--border-radius);
|
| 164 |
+
background-color: white;
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
.stats-icon {
|
| 168 |
+
font-size: 2rem;
|
| 169 |
+
margin-bottom: 0.75rem;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
.stats-value {
|
| 173 |
+
font-size: 2rem;
|
| 174 |
+
font-weight: 600;
|
| 175 |
+
margin-bottom: 0.25rem;
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
.stats-label {
|
| 179 |
+
color: #6c757d;
|
| 180 |
+
font-size: 0.875rem;
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
/* ======= Filter Section ======= */
|
| 184 |
+
.filter-section {
|
| 185 |
+
background-color: white;
|
| 186 |
+
border-radius: var(--border-radius);
|
| 187 |
+
margin-bottom: 1.5rem;
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
.filter-heading {
|
| 191 |
+
font-weight: 600;
|
| 192 |
+
margin-bottom: 1rem;
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
.filter-group {
|
| 196 |
+
margin-bottom: 1.25rem;
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
/* ======= Tables ======= */
|
| 200 |
+
.table {
|
| 201 |
+
margin-bottom: 0;
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
.table-striped tbody tr:nth-of-type(odd) {
|
| 205 |
+
background-color: rgba(0, 0, 0, 0.02);
|
| 206 |
+
}
|
| 207 |
+
|
| 208 |
+
.table th {
|
| 209 |
+
font-weight: 600;
|
| 210 |
+
border-top: none;
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
.table-hover tbody tr:hover {
|
| 214 |
+
background-color: rgba(13, 110, 253, 0.05);
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
/* ======= Badges ======= */
|
| 218 |
+
.badge {
|
| 219 |
+
padding: 0.35em 0.65em;
|
| 220 |
+
font-weight: 500;
|
| 221 |
+
border-radius: 0.25rem;
|
| 222 |
+
margin-right: 0.25rem;
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
+
.skills-container {
|
| 226 |
+
display: flex;
|
| 227 |
+
flex-wrap: wrap;
|
| 228 |
+
gap: 0.25rem;
|
| 229 |
+
}
|
| 230 |
+
|
| 231 |
+
/* ======= Visualization Section ======= */
|
| 232 |
+
.visualization-card {
|
| 233 |
+
height: 100%;
|
| 234 |
+
}
|
| 235 |
+
|
| 236 |
+
.visualization-chart {
|
| 237 |
+
width: 100%;
|
| 238 |
+
height: auto;
|
| 239 |
+
}
|
| 240 |
+
|
| 241 |
+
/* ======= Job Listings ======= */
|
| 242 |
+
.job-card {
|
| 243 |
+
transition: transform 0.2s ease-in-out;
|
| 244 |
+
height: 100%;
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
.job-card:hover {
|
| 248 |
+
transform: translateY(-5px);
|
| 249 |
+
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
| 250 |
+
}
|
| 251 |
+
|
| 252 |
+
.job-title {
|
| 253 |
+
font-weight: 600;
|
| 254 |
+
margin-bottom: 0.5rem;
|
| 255 |
+
}
|
| 256 |
+
|
| 257 |
+
.job-location {
|
| 258 |
+
color: #6c757d;
|
| 259 |
+
font-size: 0.875rem;
|
| 260 |
+
}
|
| 261 |
+
|
| 262 |
+
.job-skills {
|
| 263 |
+
margin-top: 0.5rem;
|
| 264 |
+
margin-bottom: 1rem;
|
| 265 |
+
}
|
| 266 |
+
|
| 267 |
+
/* ======= Student Details ======= */
|
| 268 |
+
.student-profile {
|
| 269 |
+
padding: 1.5rem;
|
| 270 |
+
}
|
| 271 |
+
|
| 272 |
+
.student-name {
|
| 273 |
+
font-size: 1.5rem;
|
| 274 |
+
font-weight: 600;
|
| 275 |
+
margin-bottom: 0.5rem;
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
.student-info {
|
| 279 |
+
margin-bottom: 0.5rem;
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
.section-heading {
|
| 283 |
+
font-weight: 600;
|
| 284 |
+
margin-bottom: 0.75rem;
|
| 285 |
+
border-bottom: 1px solid #e9ecef;
|
| 286 |
+
padding-bottom: 0.5rem;
|
| 287 |
+
}
|
| 288 |
+
|
| 289 |
+
/* ======= AI Insights ======= */
|
| 290 |
+
.insights-section {
|
| 291 |
+
background-color: #f8f9fa;
|
| 292 |
+
padding: 1.5rem;
|
| 293 |
+
border-radius: var(--border-radius);
|
| 294 |
+
margin-bottom: 1.5rem;
|
| 295 |
+
}
|
| 296 |
+
|
| 297 |
+
.insights-text {
|
| 298 |
+
white-space: pre-wrap;
|
| 299 |
+
max-height: 500px;
|
| 300 |
+
overflow-y: auto;
|
| 301 |
+
padding: 1rem;
|
| 302 |
+
background-color: white;
|
| 303 |
+
border: 1px solid #dee2e6;
|
| 304 |
+
border-radius: var(--border-radius);
|
| 305 |
+
}
|
| 306 |
+
|
| 307 |
+
/* ======= Button Styles ======= */
|
| 308 |
+
.btn {
|
| 309 |
+
padding: 0.375rem 0.75rem;
|
| 310 |
+
border-radius: var(--border-radius);
|
| 311 |
+
font-weight: 500;
|
| 312 |
+
transition: all 0.2s ease-in-out;
|
| 313 |
+
}
|
| 314 |
+
|
| 315 |
+
.btn-primary {
|
| 316 |
+
background-color: var(--primary-color);
|
| 317 |
+
border-color: var(--primary-color);
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
+
.btn-primary:hover {
|
| 321 |
+
background-color: var(--primary-dark);
|
| 322 |
+
border-color: var(--primary-dark);
|
| 323 |
+
}
|
| 324 |
+
|
| 325 |
+
.btn-outline-primary {
|
| 326 |
+
color: var(--primary-color);
|
| 327 |
+
border-color: var(--primary-color);
|
| 328 |
+
}
|
| 329 |
+
|
| 330 |
+
.btn-outline-primary:hover {
|
| 331 |
+
background-color: var(--primary-color);
|
| 332 |
+
color: white;
|
| 333 |
+
border-color: var(--primary-color);
|
| 334 |
+
}
|
| 335 |
+
|
| 336 |
+
.btn-sm {
|
| 337 |
+
padding: 0.25rem 0.5rem;
|
| 338 |
+
font-size: 0.875rem;
|
| 339 |
+
}
|
| 340 |
+
|
| 341 |
+
/* ======= Modals ======= */
|
| 342 |
+
.modal-header {
|
| 343 |
+
padding: 1rem;
|
| 344 |
+
border-bottom: 1px solid #dee2e6;
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
.modal-body {
|
| 348 |
+
padding: 1.5rem;
|
| 349 |
+
}
|
| 350 |
+
|
| 351 |
+
.modal-footer {
|
| 352 |
+
padding: 1rem;
|
| 353 |
+
border-top: 1px solid #dee2e6;
|
| 354 |
+
}
|
| 355 |
+
|
| 356 |
+
/* ======= Alerts ======= */
|
| 357 |
+
.alert {
|
| 358 |
+
padding: 1rem;
|
| 359 |
+
margin-bottom: 1rem;
|
| 360 |
+
border-radius: var(--border-radius);
|
| 361 |
+
}
|
| 362 |
+
|
| 363 |
+
/* ======= Spinner ======= */
|
| 364 |
+
.spinner-container {
|
| 365 |
+
display: flex;
|
| 366 |
+
justify-content: center;
|
| 367 |
+
align-items: center;
|
| 368 |
+
padding: 2rem;
|
| 369 |
+
}
|
| 370 |
+
|
| 371 |
+
.spinner-border {
|
| 372 |
+
width: 3rem;
|
| 373 |
+
height: 3rem;
|
| 374 |
+
}
|
| 375 |
+
|
| 376 |
+
/* ======= Responsive Adjustments ======= */
|
| 377 |
+
@media (max-width: 768px) {
|
| 378 |
+
.card-body {
|
| 379 |
+
padding: 1rem;
|
| 380 |
+
}
|
| 381 |
+
|
| 382 |
+
.navbar-brand {
|
| 383 |
+
font-size: 1rem;
|
| 384 |
+
}
|
| 385 |
+
|
| 386 |
+
.stats-value {
|
| 387 |
+
font-size: 1.5rem;
|
| 388 |
+
}
|
| 389 |
+
|
| 390 |
+
.stats-icon {
|
| 391 |
+
font-size: 1.5rem;
|
| 392 |
+
}
|
| 393 |
+
|
| 394 |
+
.table-responsive {
|
| 395 |
+
border: 0;
|
| 396 |
+
}
|
| 397 |
+
}
|
| 398 |
+
|
| 399 |
+
/* ======= Print Styles ======= */
|
| 400 |
+
@media print {
|
| 401 |
+
.navbar, .card-header, .btn, .filter-section {
|
| 402 |
+
display: none !important;
|
| 403 |
+
}
|
| 404 |
+
|
| 405 |
+
.card {
|
| 406 |
+
box-shadow: none !important;
|
| 407 |
+
border: 1px solid #dee2e6 !important;
|
| 408 |
+
}
|
| 409 |
+
|
| 410 |
+
.container-fluid {
|
| 411 |
+
width: 100% !important;
|
| 412 |
+
max-width: none !important;
|
| 413 |
+
}
|
| 414 |
+
}
|
| 415 |
+
</style>
|
| 416 |
+
</head>
|
| 417 |
+
<body class="bg-light">
|
| 418 |
+
<div class="container">
|
| 419 |
+
<div class="row justify-content-center mt-5">
|
| 420 |
+
<div class="col-md-6">
|
| 421 |
+
<div class="card shadow-lg">
|
| 422 |
+
<div class="card-header bg-primary text-white text-center">
|
| 423 |
+
<h3>Campus Recruitment Portal</h3>
|
| 424 |
+
<h4>Company Login</h4>
|
| 425 |
+
</div>
|
| 426 |
+
<div class="card-body p-4">
|
| 427 |
+
{% if error %}
|
| 428 |
+
<div class="alert alert-danger" role="alert">
|
| 429 |
+
{{ error }}
|
| 430 |
+
</div>
|
| 431 |
+
{% endif %}
|
| 432 |
+
<form method="POST" action="{{ url_for('login') }}">
|
| 433 |
+
<div class="mb-3">
|
| 434 |
+
<label for="email" class="form-label">Email address</label>
|
| 435 |
+
<input type="email" class="form-control" id="email" name="email" required>
|
| 436 |
+
</div>
|
| 437 |
+
<div class="mb-3">
|
| 438 |
+
<label for="password" class="form-label">Password</label>
|
| 439 |
+
<input type="password" class="form-control" id="password" name="password" required>
|
| 440 |
+
</div>
|
| 441 |
+
<div class="d-grid gap-2">
|
| 442 |
+
<button type="submit" class="btn btn-primary">Log In</button>
|
| 443 |
+
</div>
|
| 444 |
+
</form>
|
| 445 |
+
</div>
|
| 446 |
+
<div class="card-footer text-center">
|
| 447 |
+
<small class="text-muted">Demo Credentials:<br>
|
| 448 |
+
Email: google@example.com | Password: google123<br>
|
| 449 |
+
Email: microsoft@example.com | Password: microsoft123<br>
|
| 450 |
+
Email: amazon@example.com | Password: amazon123
|
| 451 |
+
</small>
|
| 452 |
+
</div>
|
| 453 |
+
</div>
|
| 454 |
+
</div>
|
| 455 |
+
</div>
|
| 456 |
+
</div>
|
| 457 |
+
</body>
|
| 458 |
+
</html>
|
templates/job_details.html
ADDED
|
@@ -0,0 +1,820 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>{{ job.title }} | Job Details</title>
|
| 7 |
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
|
| 8 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
|
| 9 |
+
<style>
|
| 10 |
+
/* Campus Recruitment Portal - Main Stylesheet
|
| 11 |
+
This file contains styles for all pages in the application */
|
| 12 |
+
|
| 13 |
+
/* ======= Global Styles ======= */
|
| 14 |
+
:root {
|
| 15 |
+
--primary-color: #0d6efd;
|
| 16 |
+
--primary-dark: #0b5ed7;
|
| 17 |
+
--secondary-color: #6c757d;
|
| 18 |
+
--success-color: #198754;
|
| 19 |
+
--info-color: #0dcaf0;
|
| 20 |
+
--warning-color: #ffc107;
|
| 21 |
+
--danger-color: #dc3545;
|
| 22 |
+
--light-color: #f8f9fa;
|
| 23 |
+
--dark-color: #212529;
|
| 24 |
+
--border-radius: 0.375rem;
|
| 25 |
+
--box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
body {
|
| 29 |
+
font-family: 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
| 30 |
+
background-color: #f5f5f5;
|
| 31 |
+
color: #333;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
/* ======= Typography ======= */
|
| 35 |
+
h1, h2, h3, h4, h5, h6 {
|
| 36 |
+
font-weight: 600;
|
| 37 |
+
margin-bottom: 1rem;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
.text-primary {
|
| 41 |
+
color: var(--primary-color) !important;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
/* ======= Layout Components ======= */
|
| 45 |
+
.main-container {
|
| 46 |
+
padding-top: 1.5rem;
|
| 47 |
+
padding-bottom: 2rem;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
.card {
|
| 51 |
+
border-radius: var(--border-radius);
|
| 52 |
+
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
| 53 |
+
margin-bottom: 1.5rem;
|
| 54 |
+
border: none;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
.card-header {
|
| 58 |
+
background-color: rgba(0, 0, 0, 0.03);
|
| 59 |
+
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
|
| 60 |
+
padding: 0.75rem 1.25rem;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
.card-header.bg-primary {
|
| 64 |
+
background-color: var(--primary-color) !important;
|
| 65 |
+
color: white;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
.card-header.bg-secondary {
|
| 69 |
+
background-color: var(--secondary-color) !important;
|
| 70 |
+
color: white;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
.card-body {
|
| 74 |
+
padding: 1.25rem;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.card-footer {
|
| 78 |
+
padding: 0.75rem 1.25rem;
|
| 79 |
+
background-color: rgba(0, 0, 0, 0.03);
|
| 80 |
+
border-top: 1px solid rgba(0, 0, 0, 0.125);
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
/* ======= Navigation ======= */
|
| 84 |
+
.navbar {
|
| 85 |
+
padding: 0.5rem 1rem;
|
| 86 |
+
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
.navbar-brand {
|
| 90 |
+
font-weight: 600;
|
| 91 |
+
font-size: 1.25rem;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
.nav-link {
|
| 95 |
+
padding: 0.5rem 1rem;
|
| 96 |
+
transition: all 0.2s ease-in-out;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
.nav-link:hover {
|
| 100 |
+
opacity: 0.85;
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
.nav-link.active {
|
| 104 |
+
font-weight: 600;
|
| 105 |
+
background-color: rgba(255, 255, 255, 0.1);
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
/* ======= Forms ======= */
|
| 109 |
+
.form-control, .form-select {
|
| 110 |
+
border-radius: var(--border-radius);
|
| 111 |
+
padding: 0.375rem 0.75rem;
|
| 112 |
+
border: 1px solid #ced4da;
|
| 113 |
+
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
.form-control:focus, .form-select:focus {
|
| 117 |
+
border-color: rgba(13, 110, 253, 0.5);
|
| 118 |
+
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
.form-label {
|
| 122 |
+
margin-bottom: 0.5rem;
|
| 123 |
+
font-weight: 500;
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
.form-text {
|
| 127 |
+
color: #6c757d;
|
| 128 |
+
margin-top: 0.25rem;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
/* ======= Login Page ======= */
|
| 132 |
+
.login-container {
|
| 133 |
+
min-height: 100vh;
|
| 134 |
+
display: flex;
|
| 135 |
+
align-items: center;
|
| 136 |
+
justify-content: center;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
.login-card {
|
| 140 |
+
width: 100%;
|
| 141 |
+
max-width: 450px;
|
| 142 |
+
box-shadow: var(--box-shadow);
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
.demo-credentials {
|
| 146 |
+
background-color: #f8f9fa;
|
| 147 |
+
padding: 0.75rem;
|
| 148 |
+
border-radius: var(--border-radius);
|
| 149 |
+
margin-top: 1rem;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
/* ======= Dashboard ======= */
|
| 153 |
+
.dashboard-stats {
|
| 154 |
+
padding: 1.5rem;
|
| 155 |
+
background-color: white;
|
| 156 |
+
box-shadow: var(--box-shadow);
|
| 157 |
+
border-radius: var(--border-radius);
|
| 158 |
+
margin-bottom: 1.5rem;
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
.stats-card {
|
| 162 |
+
text-align: center;
|
| 163 |
+
padding: 1.25rem;
|
| 164 |
+
border: 1px solid rgba(0, 0, 0, 0.125);
|
| 165 |
+
border-radius: var(--border-radius);
|
| 166 |
+
background-color: white;
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
.stats-icon {
|
| 170 |
+
font-size: 2rem;
|
| 171 |
+
margin-bottom: 0.75rem;
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
.stats-value {
|
| 175 |
+
font-size: 2rem;
|
| 176 |
+
font-weight: 600;
|
| 177 |
+
margin-bottom: 0.25rem;
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
.stats-label {
|
| 181 |
+
color: #6c757d;
|
| 182 |
+
font-size: 0.875rem;
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
/* ======= Filter Section ======= */
|
| 186 |
+
.filter-section {
|
| 187 |
+
background-color: white;
|
| 188 |
+
border-radius: var(--border-radius);
|
| 189 |
+
margin-bottom: 1.5rem;
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
.filter-heading {
|
| 193 |
+
font-weight: 600;
|
| 194 |
+
margin-bottom: 1rem;
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
.filter-group {
|
| 198 |
+
margin-bottom: 1.25rem;
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
/* ======= Tables ======= */
|
| 202 |
+
.table {
|
| 203 |
+
margin-bottom: 0;
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
.table-striped tbody tr:nth-of-type(odd) {
|
| 207 |
+
background-color: rgba(0, 0, 0, 0.02);
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
.table th {
|
| 211 |
+
font-weight: 600;
|
| 212 |
+
border-top: none;
|
| 213 |
+
}
|
| 214 |
+
|
| 215 |
+
.table-hover tbody tr:hover {
|
| 216 |
+
background-color: rgba(13, 110, 253, 0.05);
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
/* ======= Badges ======= */
|
| 220 |
+
.badge {
|
| 221 |
+
padding: 0.35em 0.65em;
|
| 222 |
+
font-weight: 500;
|
| 223 |
+
border-radius: 0.25rem;
|
| 224 |
+
margin-right: 0.25rem;
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
.skills-container {
|
| 228 |
+
display: flex;
|
| 229 |
+
flex-wrap: wrap;
|
| 230 |
+
gap: 0.25rem;
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
/* ======= Visualization Section ======= */
|
| 234 |
+
.visualization-card {
|
| 235 |
+
height: 100%;
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
.visualization-chart {
|
| 239 |
+
width: 100%;
|
| 240 |
+
height: auto;
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
/* ======= Job Listings ======= */
|
| 244 |
+
.job-card {
|
| 245 |
+
transition: transform 0.2s ease-in-out;
|
| 246 |
+
height: 100%;
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
.job-card:hover {
|
| 250 |
+
transform: translateY(-5px);
|
| 251 |
+
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
.job-title {
|
| 255 |
+
font-weight: 600;
|
| 256 |
+
margin-bottom: 0.5rem;
|
| 257 |
+
}
|
| 258 |
+
|
| 259 |
+
.job-location {
|
| 260 |
+
color: #6c757d;
|
| 261 |
+
font-size: 0.875rem;
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
.job-skills {
|
| 265 |
+
margin-top: 0.5rem;
|
| 266 |
+
margin-bottom: 1rem;
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
/* ======= Student Details ======= */
|
| 270 |
+
.student-profile {
|
| 271 |
+
padding: 1.5rem;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
.student-name {
|
| 275 |
+
font-size: 1.5rem;
|
| 276 |
+
font-weight: 600;
|
| 277 |
+
margin-bottom: 0.5rem;
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
.student-info {
|
| 281 |
+
margin-bottom: 0.5rem;
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
.section-heading {
|
| 285 |
+
font-weight: 600;
|
| 286 |
+
margin-bottom: 0.75rem;
|
| 287 |
+
border-bottom: 1px solid #e9ecef;
|
| 288 |
+
padding-bottom: 0.5rem;
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
/* ======= AI Insights ======= */
|
| 292 |
+
.insights-section {
|
| 293 |
+
background-color: #f8f9fa;
|
| 294 |
+
padding: 1.5rem;
|
| 295 |
+
border-radius: var(--border-radius);
|
| 296 |
+
margin-bottom: 1.5rem;
|
| 297 |
+
}
|
| 298 |
+
|
| 299 |
+
.insights-text {
|
| 300 |
+
white-space: pre-wrap;
|
| 301 |
+
max-height: 500px;
|
| 302 |
+
overflow-y: auto;
|
| 303 |
+
padding: 1rem;
|
| 304 |
+
background-color: white;
|
| 305 |
+
border: 1px solid #dee2e6;
|
| 306 |
+
border-radius: var(--border-radius);
|
| 307 |
+
}
|
| 308 |
+
|
| 309 |
+
/* ======= Button Styles ======= */
|
| 310 |
+
.btn {
|
| 311 |
+
padding: 0.375rem 0.75rem;
|
| 312 |
+
border-radius: var(--border-radius);
|
| 313 |
+
font-weight: 500;
|
| 314 |
+
transition: all 0.2s ease-in-out;
|
| 315 |
+
}
|
| 316 |
+
|
| 317 |
+
.btn-primary {
|
| 318 |
+
background-color: var(--primary-color);
|
| 319 |
+
border-color: var(--primary-color);
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
.btn-primary:hover {
|
| 323 |
+
background-color: var(--primary-dark);
|
| 324 |
+
border-color: var(--primary-dark);
|
| 325 |
+
}
|
| 326 |
+
|
| 327 |
+
.btn-outline-primary {
|
| 328 |
+
color: var(--primary-color);
|
| 329 |
+
border-color: var(--primary-color);
|
| 330 |
+
}
|
| 331 |
+
|
| 332 |
+
.btn-outline-primary:hover {
|
| 333 |
+
background-color: var(--primary-color);
|
| 334 |
+
color: white;
|
| 335 |
+
border-color: var(--primary-color);
|
| 336 |
+
}
|
| 337 |
+
|
| 338 |
+
.btn-sm {
|
| 339 |
+
padding: 0.25rem 0.5rem;
|
| 340 |
+
font-size: 0.875rem;
|
| 341 |
+
}
|
| 342 |
+
|
| 343 |
+
/* ======= Modals ======= */
|
| 344 |
+
.modal-header {
|
| 345 |
+
padding: 1rem;
|
| 346 |
+
border-bottom: 1px solid #dee2e6;
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
.modal-body {
|
| 350 |
+
padding: 1.5rem;
|
| 351 |
+
}
|
| 352 |
+
|
| 353 |
+
.modal-footer {
|
| 354 |
+
padding: 1rem;
|
| 355 |
+
border-top: 1px solid #dee2e6;
|
| 356 |
+
}
|
| 357 |
+
|
| 358 |
+
/* ======= Alerts ======= */
|
| 359 |
+
.alert {
|
| 360 |
+
padding: 1rem;
|
| 361 |
+
margin-bottom: 1rem;
|
| 362 |
+
border-radius: var(--border-radius);
|
| 363 |
+
}
|
| 364 |
+
|
| 365 |
+
/* ======= Spinner ======= */
|
| 366 |
+
.spinner-container {
|
| 367 |
+
display: flex;
|
| 368 |
+
justify-content: center;
|
| 369 |
+
align-items: center;
|
| 370 |
+
padding: 2rem;
|
| 371 |
+
}
|
| 372 |
+
|
| 373 |
+
.spinner-border {
|
| 374 |
+
width: 3rem;
|
| 375 |
+
height: 3rem;
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
/* ======= Responsive Adjustments ======= */
|
| 379 |
+
@media (max-width: 768px) {
|
| 380 |
+
.card-body {
|
| 381 |
+
padding: 1rem;
|
| 382 |
+
}
|
| 383 |
+
|
| 384 |
+
.navbar-brand {
|
| 385 |
+
font-size: 1rem;
|
| 386 |
+
}
|
| 387 |
+
|
| 388 |
+
.stats-value {
|
| 389 |
+
font-size: 1.5rem;
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
.stats-icon {
|
| 393 |
+
font-size: 1.5rem;
|
| 394 |
+
}
|
| 395 |
+
|
| 396 |
+
.table-responsive {
|
| 397 |
+
border: 0;
|
| 398 |
+
}
|
| 399 |
+
}
|
| 400 |
+
|
| 401 |
+
/* ======= Print Styles ======= */
|
| 402 |
+
@media print {
|
| 403 |
+
.navbar, .card-header, .btn, .filter-section {
|
| 404 |
+
display: none !important;
|
| 405 |
+
}
|
| 406 |
+
|
| 407 |
+
.card {
|
| 408 |
+
box-shadow: none !important;
|
| 409 |
+
border: 1px solid #dee2e6 !important;
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
.container-fluid {
|
| 413 |
+
width: 100% !important;
|
| 414 |
+
max-width: none !important;
|
| 415 |
+
}
|
| 416 |
+
}
|
| 417 |
+
</style>
|
| 418 |
+
</head>
|
| 419 |
+
<body>
|
| 420 |
+
<!-- Navigation -->
|
| 421 |
+
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
|
| 422 |
+
<div class="container-fluid">
|
| 423 |
+
<a class="navbar-brand" href="{{ url_for('dashboard') }}">{{ company_name }} - Recruitment Portal</a>
|
| 424 |
+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
| 425 |
+
<span class="navbar-toggler-icon"></span>
|
| 426 |
+
</button>
|
| 427 |
+
<div class="collapse navbar-collapse" id="navbarNav">
|
| 428 |
+
<ul class="navbar-nav me-auto">
|
| 429 |
+
<li class="nav-item">
|
| 430 |
+
<a class="nav-link" href="{{ url_for('dashboard') }}">Dashboard</a>
|
| 431 |
+
</li>
|
| 432 |
+
<li class="nav-item">
|
| 433 |
+
<a class="nav-link active" href="{{ url_for('jobs') }}">Job Postings</a>
|
| 434 |
+
</li>
|
| 435 |
+
</ul>
|
| 436 |
+
<ul class="navbar-nav">
|
| 437 |
+
<li class="nav-item">
|
| 438 |
+
<a class="nav-link" href="{{ url_for('logout') }}">
|
| 439 |
+
<i class="bi bi-box-arrow-right"></i> Logout
|
| 440 |
+
</a>
|
| 441 |
+
</li>
|
| 442 |
+
</ul>
|
| 443 |
+
</div>
|
| 444 |
+
</div>
|
| 445 |
+
</nav>
|
| 446 |
+
<!-- Main Content -->
|
| 447 |
+
<div class="container-fluid mt-3">
|
| 448 |
+
<!-- Job Details Header -->
|
| 449 |
+
<div class="card mb-3">
|
| 450 |
+
<div class="card-header bg-primary text-white">
|
| 451 |
+
<div class="d-flex justify-content-between align-items-center">
|
| 452 |
+
<h5 class="card-title mb-0">{{ job.title }}</h5>
|
| 453 |
+
<a href="{{ url_for('jobs') }}" class="btn btn-sm btn-light">
|
| 454 |
+
<i class="bi bi-arrow-left"></i> Back to Jobs
|
| 455 |
+
</a>
|
| 456 |
+
</div>
|
| 457 |
+
</div>
|
| 458 |
+
<div class="card-body">
|
| 459 |
+
<div class="row">
|
| 460 |
+
<div class="col-md-8">
|
| 461 |
+
<h6>Job Description</h6>
|
| 462 |
+
<p>{{ job.description }}</p>
|
| 463 |
+
</div>
|
| 464 |
+
<div class="col-md-4">
|
| 465 |
+
<h6>Job Details</h6>
|
| 466 |
+
<ul class="list-group list-group-flush">
|
| 467 |
+
<li class="list-group-item"><strong>Required Skills:</strong> {{ job.required_skills|join(', ') }}</li>
|
| 468 |
+
<li class="list-group-item"><strong>Minimum CGPA:</strong> {{ job.min_cgpa }}</li>
|
| 469 |
+
<li class="list-group-item"><strong>Experience Level:</strong> {{ job.experience_level }} years</li>
|
| 470 |
+
<li class="list-group-item"><strong>Location:</strong> {{ job.location }}</li>
|
| 471 |
+
<li class="list-group-item"><strong>Posted Date:</strong> {{ job.posted_date }}</li>
|
| 472 |
+
</ul>
|
| 473 |
+
</div>
|
| 474 |
+
</div>
|
| 475 |
+
</div>
|
| 476 |
+
</div>
|
| 477 |
+
|
| 478 |
+
<!-- Eligible Candidates -->
|
| 479 |
+
<div class="card">
|
| 480 |
+
<div class="card-header bg-secondary text-white">
|
| 481 |
+
<div class="d-flex justify-content-between align-items-center">
|
| 482 |
+
<h5 class="card-title mb-0">Eligible Candidates ({{ candidates|length }})</h5>
|
| 483 |
+
<div>
|
| 484 |
+
<button class="btn btn-sm btn-light me-2" id="compareSelectedBtn" disabled>
|
| 485 |
+
<i class="bi bi-bar-chart-line"></i> Compare Selected
|
| 486 |
+
</button>
|
| 487 |
+
<button class="btn btn-sm btn-light" id="exportSelectedBtn" disabled>
|
| 488 |
+
<i class="bi bi-download"></i> Export Selected
|
| 489 |
+
</button>
|
| 490 |
+
</div>
|
| 491 |
+
</div>
|
| 492 |
+
</div>
|
| 493 |
+
<div class="card-body">
|
| 494 |
+
<form id="candidatesForm">
|
| 495 |
+
<div class="table-responsive">
|
| 496 |
+
<table class="table table-striped table-hover">
|
| 497 |
+
<thead>
|
| 498 |
+
<tr>
|
| 499 |
+
<th><input type="checkbox" id="selectAll" class="form-check-input"></th>
|
| 500 |
+
<th>Name</th>
|
| 501 |
+
<th>Department</th>
|
| 502 |
+
<th>CGPA</th>
|
| 503 |
+
<th>Skills</th>
|
| 504 |
+
<th>Projects</th>
|
| 505 |
+
<th>Internships</th>
|
| 506 |
+
<th>Action</th>
|
| 507 |
+
</tr>
|
| 508 |
+
</thead>
|
| 509 |
+
<tbody>
|
| 510 |
+
{% for candidate in candidates %}
|
| 511 |
+
<tr>
|
| 512 |
+
<td><input type="checkbox" name="selected_students" value="{{ candidate.email }}" class="form-check-input candidate-checkbox"></td>
|
| 513 |
+
<td>{{ candidate.full_name }}</td>
|
| 514 |
+
<td>{{ candidate.department }}</td>
|
| 515 |
+
<td>{{ candidate.cgpa }}</td>
|
| 516 |
+
<td>
|
| 517 |
+
<div class="skills-container">
|
| 518 |
+
{% if candidate.programming_languages %}
|
| 519 |
+
{% for skill in candidate.programming_languages.split(',')[:3] %}
|
| 520 |
+
<span class="badge bg-primary">{{ skill.strip() }}</span>
|
| 521 |
+
{% endfor %}
|
| 522 |
+
{% if candidate.programming_languages.split(',')|length > 3 %}
|
| 523 |
+
<span class="badge bg-secondary">+{{ candidate.programming_languages.split(',')|length - 3 }}</span>
|
| 524 |
+
{% endif %}
|
| 525 |
+
{% endif %}
|
| 526 |
+
</div>
|
| 527 |
+
</td>
|
| 528 |
+
<td>{{ candidate.projects | truncate(30) if candidate.projects else 'N/A' }}</td>
|
| 529 |
+
<td>{{ candidate.internships | truncate(30) if candidate.internships else 'N/A' }}</td>
|
| 530 |
+
<td>
|
| 531 |
+
<button type="button" class="btn btn-sm btn-outline-primary view-details-btn" data-email="{{ candidate.email }}">
|
| 532 |
+
<i class="bi bi-eye"></i> Details
|
| 533 |
+
</button>
|
| 534 |
+
</td>
|
| 535 |
+
</tr>
|
| 536 |
+
{% endfor %}
|
| 537 |
+
</tbody>
|
| 538 |
+
</table>
|
| 539 |
+
</div>
|
| 540 |
+
</form>
|
| 541 |
+
|
| 542 |
+
{% if not candidates %}
|
| 543 |
+
<div class="alert alert-info text-center">
|
| 544 |
+
No eligible candidates found for this job posting. Consider adjusting the job requirements.
|
| 545 |
+
</div>
|
| 546 |
+
{% endif %}
|
| 547 |
+
</div>
|
| 548 |
+
</div>
|
| 549 |
+
</div>
|
| 550 |
+
|
| 551 |
+
<!-- Student Details Modal -->
|
| 552 |
+
<div class="modal fade" id="studentDetailsModal" tabindex="-1">
|
| 553 |
+
<div class="modal-dialog modal-lg">
|
| 554 |
+
<div class="modal-content">
|
| 555 |
+
<div class="modal-header bg-primary text-white">
|
| 556 |
+
<h5 class="modal-title">Student Details</h5>
|
| 557 |
+
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
| 558 |
+
</div>
|
| 559 |
+
<div class="modal-body" id="studentDetailsContent">
|
| 560 |
+
<div class="text-center">
|
| 561 |
+
<div class="spinner-border" role="status">
|
| 562 |
+
<span class="visually-hidden">Loading...</span>
|
| 563 |
+
</div>
|
| 564 |
+
</div>
|
| 565 |
+
</div>
|
| 566 |
+
<div class="modal-footer">
|
| 567 |
+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
| 568 |
+
</div>
|
| 569 |
+
</div>
|
| 570 |
+
</div>
|
| 571 |
+
</div>
|
| 572 |
+
|
| 573 |
+
<!-- AI Insights Modal -->
|
| 574 |
+
<div class="modal fade" id="aiInsightsModal" tabindex="-1">
|
| 575 |
+
<div class="modal-dialog modal-lg">
|
| 576 |
+
<div class="modal-content">
|
| 577 |
+
<div class="modal-header bg-success text-white">
|
| 578 |
+
<h5 class="modal-title">AI Insights</h5>
|
| 579 |
+
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
| 580 |
+
</div>
|
| 581 |
+
<div class="modal-body" id="aiInsightsContent">
|
| 582 |
+
<div class="mb-3">
|
| 583 |
+
<label for="roleInput" class="form-label">Role to analyze for:</label>
|
| 584 |
+
<input type="text" class="form-control" id="roleInput" value="{{ job.title }}">
|
| 585 |
+
</div>
|
| 586 |
+
<div id="insightsResult" class="d-none">
|
| 587 |
+
<div class="alert alert-info">
|
| 588 |
+
<h5>Analysis Results:</h5>
|
| 589 |
+
<div id="insightsText" class="insights-text"></div>
|
| 590 |
+
</div>
|
| 591 |
+
</div>
|
| 592 |
+
<div id="insightsLoading" class="d-none text-center">
|
| 593 |
+
<div class="spinner-border" role="status">
|
| 594 |
+
<span class="visually-hidden">Loading...</span>
|
| 595 |
+
</div>
|
| 596 |
+
<p>Generating insights... This may take a moment.</p>
|
| 597 |
+
</div>
|
| 598 |
+
</div>
|
| 599 |
+
<div class="modal-footer">
|
| 600 |
+
<button type="button" class="btn btn-primary" id="generateInsightsBtn">Generate Insights</button>
|
| 601 |
+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
| 602 |
+
</div>
|
| 603 |
+
</div>
|
| 604 |
+
</div>
|
| 605 |
+
</div>
|
| 606 |
+
|
| 607 |
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
|
| 608 |
+
<script>
|
| 609 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 610 |
+
// Handle checkbox selection
|
| 611 |
+
const selectAllCheckbox = document.getElementById('selectAll');
|
| 612 |
+
const candidateCheckboxes = document.querySelectorAll('.candidate-checkbox');
|
| 613 |
+
const compareSelectedBtn = document.getElementById('compareSelectedBtn');
|
| 614 |
+
const exportSelectedBtn = document.getElementById('exportSelectedBtn');
|
| 615 |
+
|
| 616 |
+
selectAllCheckbox.addEventListener('change', function() {
|
| 617 |
+
candidateCheckboxes.forEach(checkbox => {
|
| 618 |
+
checkbox.checked = selectAllCheckbox.checked;
|
| 619 |
+
});
|
| 620 |
+
updateButtonState();
|
| 621 |
+
});
|
| 622 |
+
|
| 623 |
+
candidateCheckboxes.forEach(checkbox => {
|
| 624 |
+
checkbox.addEventListener('change', updateButtonState);
|
| 625 |
+
});
|
| 626 |
+
|
| 627 |
+
function updateButtonState() {
|
| 628 |
+
const selectedCount = document.querySelectorAll('.candidate-checkbox:checked').length;
|
| 629 |
+
compareSelectedBtn.disabled = selectedCount < 2;
|
| 630 |
+
exportSelectedBtn.disabled = selectedCount === 0;
|
| 631 |
+
}
|
| 632 |
+
|
| 633 |
+
// Handle view details button
|
| 634 |
+
const viewDetailsButtons = document.querySelectorAll('.view-details-btn');
|
| 635 |
+
viewDetailsButtons.forEach(button => {
|
| 636 |
+
button.addEventListener('click', function() {
|
| 637 |
+
const email = this.getAttribute('data-email');
|
| 638 |
+
const studentData = findStudentByEmail(email);
|
| 639 |
+
showStudentDetails(studentData);
|
| 640 |
+
});
|
| 641 |
+
});
|
| 642 |
+
|
| 643 |
+
function findStudentByEmail(email) {
|
| 644 |
+
// In a real implementation, you might want to fetch this data from the server
|
| 645 |
+
// For now, we'll use the data we already have on the page
|
| 646 |
+
return {{ candidates|tojson|safe }}.find(student => student.email === email);
|
| 647 |
+
}
|
| 648 |
+
|
| 649 |
+
function showStudentDetails(student) {
|
| 650 |
+
if (!student) return;
|
| 651 |
+
|
| 652 |
+
const modal = new bootstrap.Modal(document.getElementById('studentDetailsModal'));
|
| 653 |
+
const content = document.getElementById('studentDetailsContent');
|
| 654 |
+
|
| 655 |
+
let htmlContent = `
|
| 656 |
+
<div class="row">
|
| 657 |
+
<div class="col-md-6">
|
| 658 |
+
<h5>${student.full_name}</h5>
|
| 659 |
+
<p><strong>Email:</strong> ${student.email}</p>
|
| 660 |
+
<p><strong>Department:</strong> ${student.department}</p>
|
| 661 |
+
<p><strong>CGPA:</strong> ${student.cgpa}</p>
|
| 662 |
+
<p><strong>Backlogs:</strong> ${student.backlogs || 0}</p>
|
| 663 |
+
</div>
|
| 664 |
+
<div class="col-md-6">
|
| 665 |
+
<h6>Skills</h6>
|
| 666 |
+
<div>
|
| 667 |
+
<strong>Programming:</strong> ${student.programming_languages || 'N/A'}
|
| 668 |
+
</div>
|
| 669 |
+
<div>
|
| 670 |
+
<strong>Tools & Technologies:</strong> ${student.tools_technologies || 'N/A'}
|
| 671 |
+
</div>
|
| 672 |
+
<div>
|
| 673 |
+
<strong>Soft Skills:</strong> ${student.soft_skills || 'N/A'}
|
| 674 |
+
</div>
|
| 675 |
+
</div>
|
| 676 |
+
</div>
|
| 677 |
+
<hr>
|
| 678 |
+
<div class="row mt-3">
|
| 679 |
+
<div class="col-md-6">
|
| 680 |
+
<h6>Projects</h6>
|
| 681 |
+
<p>${student.projects || 'No projects listed'}</p>
|
| 682 |
+
</div>
|
| 683 |
+
<div class="col-md-6">
|
| 684 |
+
<h6>Internships</h6>
|
| 685 |
+
<p>${student.internships || 'No internships listed'}</p>
|
| 686 |
+
</div>
|
| 687 |
+
</div>
|
| 688 |
+
<div class="row mt-3">
|
| 689 |
+
<div class="col-md-6">
|
| 690 |
+
<h6>Certifications</h6>
|
| 691 |
+
<p>${student.certifications || 'No certifications listed'}</p>
|
| 692 |
+
</div>
|
| 693 |
+
<div class="col-md-6">
|
| 694 |
+
<h6>Hackathons & Competitions</h6>
|
| 695 |
+
<p>${student.hackathons || 'None listed'}</p>
|
| 696 |
+
</div>
|
| 697 |
+
</div>
|
| 698 |
+
<div class="row mt-3">
|
| 699 |
+
<div class="col-md-6">
|
| 700 |
+
<h6>Preferred Roles</h6>
|
| 701 |
+
<p>${student.preferred_roles || 'Not specified'}</p>
|
| 702 |
+
</div>
|
| 703 |
+
<div class="col-md-6">
|
| 704 |
+
<h6>Preferred Location</h6>
|
| 705 |
+
<p>${student.preferred_location || 'Not specified'}</p>
|
| 706 |
+
</div>
|
| 707 |
+
</div>
|
| 708 |
+
<div class="row mt-3">
|
| 709 |
+
<div class="col-12">
|
| 710 |
+
<h6>Strengths & Weaknesses</h6>
|
| 711 |
+
<p><strong>Strengths:</strong> ${student.strengths || 'Not specified'}</p>
|
| 712 |
+
<p><strong>Weaknesses:</strong> ${student.weaknesses || 'Not specified'}</p>
|
| 713 |
+
</div>
|
| 714 |
+
</div>`;
|
| 715 |
+
|
| 716 |
+
content.innerHTML = htmlContent;
|
| 717 |
+
modal.show();
|
| 718 |
+
}
|
| 719 |
+
|
| 720 |
+
// Handle compare selected button
|
| 721 |
+
compareSelectedBtn.addEventListener('click', function() {
|
| 722 |
+
const selectedEmails = Array.from(document.querySelectorAll('.candidate-checkbox:checked'))
|
| 723 |
+
.map(checkbox => checkbox.value);
|
| 724 |
+
|
| 725 |
+
if (selectedEmails.length < 2) {
|
| 726 |
+
alert('Please select at least 2 candidates to compare.');
|
| 727 |
+
return;
|
| 728 |
+
}
|
| 729 |
+
|
| 730 |
+
// Show AI insights modal
|
| 731 |
+
const modal = new bootstrap.Modal(document.getElementById('aiInsightsModal'));
|
| 732 |
+
modal.show();
|
| 733 |
+
});
|
| 734 |
+
|
| 735 |
+
// Handle generate insights button
|
| 736 |
+
document.getElementById('generateInsightsBtn').addEventListener('click', function() {
|
| 737 |
+
const selectedEmails = Array.from(document.querySelectorAll('.candidate-checkbox:checked'))
|
| 738 |
+
.map(checkbox => checkbox.value);
|
| 739 |
+
const role = document.getElementById('roleInput').value;
|
| 740 |
+
|
| 741 |
+
const loadingDiv = document.getElementById('insightsLoading');
|
| 742 |
+
const resultDiv = document.getElementById('insightsResult');
|
| 743 |
+
const insightsTextDiv = document.getElementById('insightsText');
|
| 744 |
+
|
| 745 |
+
loadingDiv.classList.remove('d-none');
|
| 746 |
+
resultDiv.classList.add('d-none');
|
| 747 |
+
|
| 748 |
+
// Make AJAX request to get AI insights
|
| 749 |
+
const formData = new FormData();
|
| 750 |
+
selectedEmails.forEach(email => {
|
| 751 |
+
formData.append('selected_students', email);
|
| 752 |
+
});
|
| 753 |
+
formData.append('role', role);
|
| 754 |
+
|
| 755 |
+
fetch('/ai_insights', {
|
| 756 |
+
method: 'POST',
|
| 757 |
+
body: formData
|
| 758 |
+
})
|
| 759 |
+
.then(response => response.json())
|
| 760 |
+
.then(data => {
|
| 761 |
+
loadingDiv.classList.add('d-none');
|
| 762 |
+
resultDiv.classList.remove('d-none');
|
| 763 |
+
|
| 764 |
+
if (data.error) {
|
| 765 |
+
insightsTextDiv.innerHTML = `<div class="alert alert-danger">${data.error}</div>`;
|
| 766 |
+
} else {
|
| 767 |
+
// Format the insights with Markdown or HTML
|
| 768 |
+
insightsTextDiv.innerHTML = formatInsights(data.insights);
|
| 769 |
+
}
|
| 770 |
+
})
|
| 771 |
+
.catch(error => {
|
| 772 |
+
loadingDiv.classList.add('d-none');
|
| 773 |
+
resultDiv.classList.remove('d-none');
|
| 774 |
+
insightsTextDiv.innerHTML = `<div class="alert alert-danger">Error: ${error.message}</div>`;
|
| 775 |
+
});
|
| 776 |
+
});
|
| 777 |
+
|
| 778 |
+
function formatInsights(insights) {
|
| 779 |
+
// Convert line breaks to HTML breaks and preserve formatting
|
| 780 |
+
return insights
|
| 781 |
+
.replace(/\n\n/g, '</p><p>')
|
| 782 |
+
.replace(/\n/g, '<br>')
|
| 783 |
+
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
| 784 |
+
.replace(/\*(.*?)\*/g, '<em>$1</em>');
|
| 785 |
+
}
|
| 786 |
+
|
| 787 |
+
// Handle export selected button
|
| 788 |
+
exportSelectedBtn.addEventListener('click', function() {
|
| 789 |
+
const selectedEmails = Array.from(document.querySelectorAll('.candidate-checkbox:checked'))
|
| 790 |
+
.map(checkbox => checkbox.value);
|
| 791 |
+
|
| 792 |
+
if (selectedEmails.length === 0) {
|
| 793 |
+
alert('Please select at least one candidate to export.');
|
| 794 |
+
return;
|
| 795 |
+
}
|
| 796 |
+
|
| 797 |
+
// Get the full student data for selected emails
|
| 798 |
+
const selectedStudents = {{ candidates|tojson|safe }}.filter(
|
| 799 |
+
student => selectedEmails.includes(student.email)
|
| 800 |
+
);
|
| 801 |
+
|
| 802 |
+
// Submit form to export endpoint
|
| 803 |
+
const form = document.createElement('form');
|
| 804 |
+
form.method = 'POST';
|
| 805 |
+
form.action = '/export_filtered';
|
| 806 |
+
|
| 807 |
+
const input = document.createElement('input');
|
| 808 |
+
input.type = 'hidden';
|
| 809 |
+
input.name = 'filtered_students';
|
| 810 |
+
input.value = JSON.stringify(selectedStudents);
|
| 811 |
+
|
| 812 |
+
form.appendChild(input);
|
| 813 |
+
document.body.appendChild(form);
|
| 814 |
+
form.submit();
|
| 815 |
+
document.body.removeChild(form);
|
| 816 |
+
});
|
| 817 |
+
});
|
| 818 |
+
</script>
|
| 819 |
+
</body>
|
| 820 |
+
</html>
|
templates/jobs.html
ADDED
|
@@ -0,0 +1,547 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Job Postings | Campus Recruitment Portal</title>
|
| 7 |
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
|
| 8 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
|
| 9 |
+
<style>
|
| 10 |
+
/* Campus Recruitment Portal - Main Stylesheet
|
| 11 |
+
This file contains styles for all pages in the application */
|
| 12 |
+
|
| 13 |
+
/* ======= Global Styles ======= */
|
| 14 |
+
:root {
|
| 15 |
+
--primary-color: #0d6efd;
|
| 16 |
+
--primary-dark: #0b5ed7;
|
| 17 |
+
--secondary-color: #6c757d;
|
| 18 |
+
--success-color: #198754;
|
| 19 |
+
--info-color: #0dcaf0;
|
| 20 |
+
--warning-color: #ffc107;
|
| 21 |
+
--danger-color: #dc3545;
|
| 22 |
+
--light-color: #f8f9fa;
|
| 23 |
+
--dark-color: #212529;
|
| 24 |
+
--border-radius: 0.375rem;
|
| 25 |
+
--box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
body {
|
| 29 |
+
font-family: 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
| 30 |
+
background-color: #f5f5f5;
|
| 31 |
+
color: #333;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
/* ======= Typography ======= */
|
| 35 |
+
h1, h2, h3, h4, h5, h6 {
|
| 36 |
+
font-weight: 600;
|
| 37 |
+
margin-bottom: 1rem;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
.text-primary {
|
| 41 |
+
color: var(--primary-color) !important;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
/* ======= Layout Components ======= */
|
| 45 |
+
.main-container {
|
| 46 |
+
padding-top: 1.5rem;
|
| 47 |
+
padding-bottom: 2rem;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
.card {
|
| 51 |
+
border-radius: var(--border-radius);
|
| 52 |
+
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
| 53 |
+
margin-bottom: 1.5rem;
|
| 54 |
+
border: none;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
.card-header {
|
| 58 |
+
background-color: rgba(0, 0, 0, 0.03);
|
| 59 |
+
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
|
| 60 |
+
padding: 0.75rem 1.25rem;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
.card-header.bg-primary {
|
| 64 |
+
background-color: var(--primary-color) !important;
|
| 65 |
+
color: white;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
.card-header.bg-secondary {
|
| 69 |
+
background-color: var(--secondary-color) !important;
|
| 70 |
+
color: white;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
.card-body {
|
| 74 |
+
padding: 1.25rem;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.card-footer {
|
| 78 |
+
padding: 0.75rem 1.25rem;
|
| 79 |
+
background-color: rgba(0, 0, 0, 0.03);
|
| 80 |
+
border-top: 1px solid rgba(0, 0, 0, 0.125);
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
/* ======= Navigation ======= */
|
| 84 |
+
.navbar {
|
| 85 |
+
padding: 0.5rem 1rem;
|
| 86 |
+
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
.navbar-brand {
|
| 90 |
+
font-weight: 600;
|
| 91 |
+
font-size: 1.25rem;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
.nav-link {
|
| 95 |
+
padding: 0.5rem 1rem;
|
| 96 |
+
transition: all 0.2s ease-in-out;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
.nav-link:hover {
|
| 100 |
+
opacity: 0.85;
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
.nav-link.active {
|
| 104 |
+
font-weight: 600;
|
| 105 |
+
background-color: rgba(255, 255, 255, 0.1);
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
/* ======= Forms ======= */
|
| 109 |
+
.form-control, .form-select {
|
| 110 |
+
border-radius: var(--border-radius);
|
| 111 |
+
padding: 0.375rem 0.75rem;
|
| 112 |
+
border: 1px solid #ced4da;
|
| 113 |
+
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
.form-control:focus, .form-select:focus {
|
| 117 |
+
border-color: rgba(13, 110, 253, 0.5);
|
| 118 |
+
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
.form-label {
|
| 122 |
+
margin-bottom: 0.5rem;
|
| 123 |
+
font-weight: 500;
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
.form-text {
|
| 127 |
+
color: #6c757d;
|
| 128 |
+
margin-top: 0.25rem;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
/* ======= Login Page ======= */
|
| 132 |
+
.login-container {
|
| 133 |
+
min-height: 100vh;
|
| 134 |
+
display: flex;
|
| 135 |
+
align-items: center;
|
| 136 |
+
justify-content: center;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
.login-card {
|
| 140 |
+
width: 100%;
|
| 141 |
+
max-width: 450px;
|
| 142 |
+
box-shadow: var(--box-shadow);
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
.demo-credentials {
|
| 146 |
+
background-color: #f8f9fa;
|
| 147 |
+
padding: 0.75rem;
|
| 148 |
+
border-radius: var(--border-radius);
|
| 149 |
+
margin-top: 1rem;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
/* ======= Dashboard ======= */
|
| 153 |
+
.dashboard-stats {
|
| 154 |
+
padding: 1.5rem;
|
| 155 |
+
background-color: white;
|
| 156 |
+
box-shadow: var(--box-shadow);
|
| 157 |
+
border-radius: var(--border-radius);
|
| 158 |
+
margin-bottom: 1.5rem;
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
.stats-card {
|
| 162 |
+
text-align: center;
|
| 163 |
+
padding: 1.25rem;
|
| 164 |
+
border: 1px solid rgba(0, 0, 0, 0.125);
|
| 165 |
+
border-radius: var(--border-radius);
|
| 166 |
+
background-color: white;
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
.stats-icon {
|
| 170 |
+
font-size: 2rem;
|
| 171 |
+
margin-bottom: 0.75rem;
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
.stats-value {
|
| 175 |
+
font-size: 2rem;
|
| 176 |
+
font-weight: 600;
|
| 177 |
+
margin-bottom: 0.25rem;
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
.stats-label {
|
| 181 |
+
color: #6c757d;
|
| 182 |
+
font-size: 0.875rem;
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
/* ======= Filter Section ======= */
|
| 186 |
+
.filter-section {
|
| 187 |
+
background-color: white;
|
| 188 |
+
border-radius: var(--border-radius);
|
| 189 |
+
margin-bottom: 1.5rem;
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
.filter-heading {
|
| 193 |
+
font-weight: 600;
|
| 194 |
+
margin-bottom: 1rem;
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
.filter-group {
|
| 198 |
+
margin-bottom: 1.25rem;
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
/* ======= Tables ======= */
|
| 202 |
+
.table {
|
| 203 |
+
margin-bottom: 0;
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
.table-striped tbody tr:nth-of-type(odd) {
|
| 207 |
+
background-color: rgba(0, 0, 0, 0.02);
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
.table th {
|
| 211 |
+
font-weight: 600;
|
| 212 |
+
border-top: none;
|
| 213 |
+
}
|
| 214 |
+
|
| 215 |
+
.table-hover tbody tr:hover {
|
| 216 |
+
background-color: rgba(13, 110, 253, 0.05);
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
/* ======= Badges ======= */
|
| 220 |
+
.badge {
|
| 221 |
+
padding: 0.35em 0.65em;
|
| 222 |
+
font-weight: 500;
|
| 223 |
+
border-radius: 0.25rem;
|
| 224 |
+
margin-right: 0.25rem;
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
.skills-container {
|
| 228 |
+
display: flex;
|
| 229 |
+
flex-wrap: wrap;
|
| 230 |
+
gap: 0.25rem;
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
/* ======= Visualization Section ======= */
|
| 234 |
+
.visualization-card {
|
| 235 |
+
height: 100%;
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
.visualization-chart {
|
| 239 |
+
width: 100%;
|
| 240 |
+
height: auto;
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
/* ======= Job Listings ======= */
|
| 244 |
+
.job-card {
|
| 245 |
+
transition: transform 0.2s ease-in-out;
|
| 246 |
+
height: 100%;
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
.job-card:hover {
|
| 250 |
+
transform: translateY(-5px);
|
| 251 |
+
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
.job-title {
|
| 255 |
+
font-weight: 600;
|
| 256 |
+
margin-bottom: 0.5rem;
|
| 257 |
+
}
|
| 258 |
+
|
| 259 |
+
.job-location {
|
| 260 |
+
color: #6c757d;
|
| 261 |
+
font-size: 0.875rem;
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
.job-skills {
|
| 265 |
+
margin-top: 0.5rem;
|
| 266 |
+
margin-bottom: 1rem;
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
/* ======= Student Details ======= */
|
| 270 |
+
.student-profile {
|
| 271 |
+
padding: 1.5rem;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
.student-name {
|
| 275 |
+
font-size: 1.5rem;
|
| 276 |
+
font-weight: 600;
|
| 277 |
+
margin-bottom: 0.5rem;
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
.student-info {
|
| 281 |
+
margin-bottom: 0.5rem;
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
.section-heading {
|
| 285 |
+
font-weight: 600;
|
| 286 |
+
margin-bottom: 0.75rem;
|
| 287 |
+
border-bottom: 1px solid #e9ecef;
|
| 288 |
+
padding-bottom: 0.5rem;
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
/* ======= AI Insights ======= */
|
| 292 |
+
.insights-section {
|
| 293 |
+
background-color: #f8f9fa;
|
| 294 |
+
padding: 1.5rem;
|
| 295 |
+
border-radius: var(--border-radius);
|
| 296 |
+
margin-bottom: 1.5rem;
|
| 297 |
+
}
|
| 298 |
+
|
| 299 |
+
.insights-text {
|
| 300 |
+
white-space: pre-wrap;
|
| 301 |
+
max-height: 500px;
|
| 302 |
+
overflow-y: auto;
|
| 303 |
+
padding: 1rem;
|
| 304 |
+
background-color: white;
|
| 305 |
+
border: 1px solid #dee2e6;
|
| 306 |
+
border-radius: var(--border-radius);
|
| 307 |
+
}
|
| 308 |
+
|
| 309 |
+
/* ======= Button Styles ======= */
|
| 310 |
+
.btn {
|
| 311 |
+
padding: 0.375rem 0.75rem;
|
| 312 |
+
border-radius: var(--border-radius);
|
| 313 |
+
font-weight: 500;
|
| 314 |
+
transition: all 0.2s ease-in-out;
|
| 315 |
+
}
|
| 316 |
+
|
| 317 |
+
.btn-primary {
|
| 318 |
+
background-color: var(--primary-color);
|
| 319 |
+
border-color: var(--primary-color);
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
.btn-primary:hover {
|
| 323 |
+
background-color: var(--primary-dark);
|
| 324 |
+
border-color: var(--primary-dark);
|
| 325 |
+
}
|
| 326 |
+
|
| 327 |
+
.btn-outline-primary {
|
| 328 |
+
color: var(--primary-color);
|
| 329 |
+
border-color: var(--primary-color);
|
| 330 |
+
}
|
| 331 |
+
|
| 332 |
+
.btn-outline-primary:hover {
|
| 333 |
+
background-color: var(--primary-color);
|
| 334 |
+
color: white;
|
| 335 |
+
border-color: var(--primary-color);
|
| 336 |
+
}
|
| 337 |
+
|
| 338 |
+
.btn-sm {
|
| 339 |
+
padding: 0.25rem 0.5rem;
|
| 340 |
+
font-size: 0.875rem;
|
| 341 |
+
}
|
| 342 |
+
|
| 343 |
+
/* ======= Modals ======= */
|
| 344 |
+
.modal-header {
|
| 345 |
+
padding: 1rem;
|
| 346 |
+
border-bottom: 1px solid #dee2e6;
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
.modal-body {
|
| 350 |
+
padding: 1.5rem;
|
| 351 |
+
}
|
| 352 |
+
|
| 353 |
+
.modal-footer {
|
| 354 |
+
padding: 1rem;
|
| 355 |
+
border-top: 1px solid #dee2e6;
|
| 356 |
+
}
|
| 357 |
+
|
| 358 |
+
/* ======= Alerts ======= */
|
| 359 |
+
.alert {
|
| 360 |
+
padding: 1rem;
|
| 361 |
+
margin-bottom: 1rem;
|
| 362 |
+
border-radius: var(--border-radius);
|
| 363 |
+
}
|
| 364 |
+
|
| 365 |
+
/* ======= Spinner ======= */
|
| 366 |
+
.spinner-container {
|
| 367 |
+
display: flex;
|
| 368 |
+
justify-content: center;
|
| 369 |
+
align-items: center;
|
| 370 |
+
padding: 2rem;
|
| 371 |
+
}
|
| 372 |
+
|
| 373 |
+
.spinner-border {
|
| 374 |
+
width: 3rem;
|
| 375 |
+
height: 3rem;
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
/* ======= Responsive Adjustments ======= */
|
| 379 |
+
@media (max-width: 768px) {
|
| 380 |
+
.card-body {
|
| 381 |
+
padding: 1rem;
|
| 382 |
+
}
|
| 383 |
+
|
| 384 |
+
.navbar-brand {
|
| 385 |
+
font-size: 1rem;
|
| 386 |
+
}
|
| 387 |
+
|
| 388 |
+
.stats-value {
|
| 389 |
+
font-size: 1.5rem;
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
.stats-icon {
|
| 393 |
+
font-size: 1.5rem;
|
| 394 |
+
}
|
| 395 |
+
|
| 396 |
+
.table-responsive {
|
| 397 |
+
border: 0;
|
| 398 |
+
}
|
| 399 |
+
}
|
| 400 |
+
|
| 401 |
+
/* ======= Print Styles ======= */
|
| 402 |
+
@media print {
|
| 403 |
+
.navbar, .card-header, .btn, .filter-section {
|
| 404 |
+
display: none !important;
|
| 405 |
+
}
|
| 406 |
+
|
| 407 |
+
.card {
|
| 408 |
+
box-shadow: none !important;
|
| 409 |
+
border: 1px solid #dee2e6 !important;
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
.container-fluid {
|
| 413 |
+
width: 100% !important;
|
| 414 |
+
max-width: none !important;
|
| 415 |
+
}
|
| 416 |
+
}
|
| 417 |
+
</style>
|
| 418 |
+
</head>
|
| 419 |
+
<body>
|
| 420 |
+
<!-- Navigation -->
|
| 421 |
+
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
|
| 422 |
+
<div class="container-fluid">
|
| 423 |
+
<a class="navbar-brand" href="{{ url_for('dashboard') }}">{{ company_name }} - Recruitment Portal</a>
|
| 424 |
+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
| 425 |
+
<span class="navbar-toggler-icon"></span>
|
| 426 |
+
</button>
|
| 427 |
+
<div class="collapse navbar-collapse" id="navbarNav">
|
| 428 |
+
<ul class="navbar-nav me-auto">
|
| 429 |
+
<li class="nav-item">
|
| 430 |
+
<a class="nav-link" href="{{ url_for('dashboard') }}">Dashboard</a>
|
| 431 |
+
</li>
|
| 432 |
+
<li class="nav-item">
|
| 433 |
+
<a class="nav-link active" href="{{ url_for('jobs') }}">Job Postings</a>
|
| 434 |
+
</li>
|
| 435 |
+
</ul>
|
| 436 |
+
<ul class="navbar-nav">
|
| 437 |
+
<li class="nav-item">
|
| 438 |
+
<a class="nav-link" href="{{ url_for('logout') }}">
|
| 439 |
+
<i class="bi bi-box-arrow-right"></i> Logout
|
| 440 |
+
</a>
|
| 441 |
+
</li>
|
| 442 |
+
</ul>
|
| 443 |
+
</div>
|
| 444 |
+
</div>
|
| 445 |
+
</nav>
|
| 446 |
+
|
| 447 |
+
<!-- Main Content -->
|
| 448 |
+
<div class="container-fluid mt-3">
|
| 449 |
+
<div class="row">
|
| 450 |
+
<!-- Post New Job Form -->
|
| 451 |
+
<div class="col-md-4">
|
| 452 |
+
<div class="card mb-3">
|
| 453 |
+
<div class="card-header bg-primary text-white">
|
| 454 |
+
<h5 class="card-title mb-0">Post New Job</h5>
|
| 455 |
+
</div>
|
| 456 |
+
<div class="card-body">
|
| 457 |
+
<form method="POST" action="{{ url_for('jobs') }}">
|
| 458 |
+
<div class="mb-3">
|
| 459 |
+
<label class="form-label">Job Title</label>
|
| 460 |
+
<input type="text" class="form-control" name="title" required>
|
| 461 |
+
</div>
|
| 462 |
+
|
| 463 |
+
<div class="mb-3">
|
| 464 |
+
<label class="form-label">Job Description</label>
|
| 465 |
+
<textarea class="form-control" name="description" rows="4" required></textarea>
|
| 466 |
+
</div>
|
| 467 |
+
|
| 468 |
+
<div class="mb-3">
|
| 469 |
+
<label class="form-label">Required Skills</label>
|
| 470 |
+
<select class="form-select" name="required_skills" multiple size="5" required>
|
| 471 |
+
{% for skill in skills %}
|
| 472 |
+
<option value="{{ skill }}">{{ skill }}</option>
|
| 473 |
+
{% endfor %}
|
| 474 |
+
</select>
|
| 475 |
+
<small class="form-text text-muted">Hold Ctrl/Cmd to select multiple</small>
|
| 476 |
+
</div>
|
| 477 |
+
|
| 478 |
+
<div class="mb-3">
|
| 479 |
+
<label class="form-label">Minimum CGPA</label>
|
| 480 |
+
<input type="number" class="form-control" name="min_cgpa" min="0" max="10" step="0.1" value="7.0">
|
| 481 |
+
</div>
|
| 482 |
+
|
| 483 |
+
<div class="mb-3">
|
| 484 |
+
<label class="form-label">Experience Level (years)</label>
|
| 485 |
+
<input type="number" class="form-control" name="experience_level" min="0" max="5" step="1" value="0">
|
| 486 |
+
</div>
|
| 487 |
+
|
| 488 |
+
<div class="mb-3">
|
| 489 |
+
<label class="form-label">Location</label>
|
| 490 |
+
<input type="text" class="form-control" name="location" required>
|
| 491 |
+
</div>
|
| 492 |
+
|
| 493 |
+
<div class="d-grid">
|
| 494 |
+
<button type="submit" class="btn btn-primary">Post Job</button>
|
| 495 |
+
</div>
|
| 496 |
+
</form>
|
| 497 |
+
</div>
|
| 498 |
+
</div>
|
| 499 |
+
</div>
|
| 500 |
+
|
| 501 |
+
<!-- Job Listings -->
|
| 502 |
+
<div class="col-md-8">
|
| 503 |
+
<div class="card mb-3">
|
| 504 |
+
<div class="card-header bg-primary text-white">
|
| 505 |
+
<h5 class="card-title mb-0">Current Job Postings</h5>
|
| 506 |
+
</div>
|
| 507 |
+
<div class="card-body">
|
| 508 |
+
{% if jobs %}
|
| 509 |
+
<div class="row row-cols-1 row-cols-md-2 g-4">
|
| 510 |
+
{% for job in jobs %}
|
| 511 |
+
<div class="col">
|
| 512 |
+
<div class="card h-100">
|
| 513 |
+
<div class="card-header bg-light">
|
| 514 |
+
<h5 class="card-title mb-0">{{ job.title }}</h5>
|
| 515 |
+
</div>
|
| 516 |
+
<div class="card-body">
|
| 517 |
+
<p class="card-text">{{ job.description|truncate(100) }}</p>
|
| 518 |
+
<ul class="list-group list-group-flush mb-3">
|
| 519 |
+
<li class="list-group-item"><strong>Skills:</strong> {{ job.required_skills|join(', ') }}</li>
|
| 520 |
+
<li class="list-group-item"><strong>Min. CGPA:</strong> {{ job.min_cgpa }}</li>
|
| 521 |
+
<li class="list-group-item"><strong>Experience:</strong> {{ job.experience_level }} year(s)</li>
|
| 522 |
+
<li class="list-group-item"><strong>Location:</strong> {{ job.location }}</li>
|
| 523 |
+
<li class="list-group-item"><strong>Posted:</strong> {{ job.posted_date }}</li>
|
| 524 |
+
</ul>
|
| 525 |
+
<div class="d-grid">
|
| 526 |
+
<a href="https://pranit144-job-applicant.static.hf.space" class="btn btn-primary">View Applicants</a>
|
| 527 |
+
</div>
|
| 528 |
+
</div>
|
| 529 |
+
</div>
|
| 530 |
+
</div>
|
| 531 |
+
{% endfor %}
|
| 532 |
+
</div>
|
| 533 |
+
{% else %}
|
| 534 |
+
<div class="alert alert-info">
|
| 535 |
+
No job postings yet. Use the form to create your first job posting.
|
| 536 |
+
</div>
|
| 537 |
+
{% endif %}
|
| 538 |
+
</div>
|
| 539 |
+
</div>
|
| 540 |
+
</div>
|
| 541 |
+
</div>
|
| 542 |
+
</div>
|
| 543 |
+
|
| 544 |
+
<!-- JavaScript -->
|
| 545 |
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
|
| 546 |
+
</body>
|
| 547 |
+
</html>
|