Chaitanya895 commited on
Commit
7a65254
·
1 Parent(s): 083ba24

Add SkillSync project files to Hugging Face Space

Browse files
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ static/logo.png filter=lfs diff=lfs merge=lfs -text
37
+ static/favicon.ico filter=lfs diff=lfs merge=lfs -text
Dockerfile ADDED
Binary file (320 Bytes). View file
 
app.py ADDED
@@ -0,0 +1,536 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, redirect, url_for, flash, session, send_file
2
+ import pandas as pd
3
+ import nltk
4
+ from nltk.tokenize import word_tokenize
5
+ from nltk.corpus import stopwords
6
+ import string
7
+ from pymongo import MongoClient
8
+ import urllib.parse
9
+ import os
10
+
11
+ # Configuration
12
+ UPLOAD_FOLDER = 'static/uploads'
13
+ ALLOWED_EXTENSIONS = {'pdf'}
14
+ app = Flask(__name__)
15
+ app.secret_key = os.getenv('FLASK_SECRET_KEY', 'default_secret_key')
16
+ app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
17
+
18
+ # Download NLTK dependencies
19
+ nltk.download('punkt')
20
+ nltk.download('stopwords')
21
+
22
+ # MongoDB Connection
23
+ username = "root"
24
+ password = "Chaitu895@" # Replace with your actual password
25
+ host = "cluster0.zklixmv.mongodb.net"
26
+ database = "skillsync"
27
+
28
+ # URL-encode the username and password
29
+ encoded_username = urllib.parse.quote_plus(username)
30
+ encoded_password = urllib.parse.quote_plus(password)
31
+
32
+ # Construct the MongoDB URI
33
+ MONGO_URI = f"mongodb+srv://{encoded_username}:{encoded_password}@{host}/{database}?retryWrites=true&w=majority&appName=Cluster0"
34
+ client = MongoClient(MONGO_URI)
35
+ db = client['skillsync']
36
+
37
+ # Preprocessing function for skills
38
+ def preprocess_skills(skills):
39
+ if not isinstance(skills, str) or skills.strip() == '':
40
+ return []
41
+ tokens = word_tokenize(skills.lower())
42
+ tokens = [word for word in tokens if word not in stopwords.words('english') and word not in string.punctuation]
43
+ return tokens
44
+
45
+ # Fetch data from MongoDB
46
+ def fetch_data():
47
+ # Fetch resumes
48
+ resumes = list(db.resume_info.find())
49
+ resume_df = pd.DataFrame(resumes)
50
+
51
+ # Fetch internships
52
+ internships = list(db.internship_info.find())
53
+ internship_df = pd.DataFrame(internships)
54
+
55
+ # Debug: Check DataFrames
56
+ print("resume_df:", resume_df)
57
+ print("internship_df:", internship_df)
58
+
59
+ # Preprocessing
60
+ resume_df.fillna('', inplace=True)
61
+ internship_df.fillna('', inplace=True)
62
+ resume_df['processed_Skills'] = resume_df['skills'].apply(preprocess_skills)
63
+ internship_df['processed_Required_Skills'] = internship_df['skills_required'].apply(preprocess_skills)
64
+
65
+ # Debug: Check processed skills
66
+ print("resume_df['processed_Skills']:", resume_df['processed_Skills'])
67
+ print("internship_df['processed_Required_Skills']:", internship_df['processed_Required_Skills'])
68
+
69
+ # Create a set of unique skills, handling empty cases
70
+ resume_skills = resume_df['processed_Skills'].explode().dropna().tolist()
71
+ internship_skills = internship_df['processed_Required_Skills'].explode().dropna().tolist()
72
+ all_skills = resume_skills + internship_skills
73
+
74
+ # Debug: Check all_skills
75
+ print("all_skills:", all_skills)
76
+
77
+ global skill_to_index
78
+ skill_to_index = {skill: idx for idx, skill in enumerate(set(all_skills)) if all_skills} # Avoid empty set
79
+
80
+ # Vectorization
81
+ def skills_to_vector(skills):
82
+ vector = [0] * len(skill_to_index)
83
+ for skill in skills:
84
+ if skill in skill_to_index:
85
+ vector[skill_to_index[skill]] += 1
86
+ return vector
87
+
88
+ resume_df['Skill_vector'] = resume_df['processed_Skills'].apply(skills_to_vector)
89
+ internship_df['Required_Skill_vector'] = internship_df['processed_Required_Skills'].apply(skills_to_vector)
90
+
91
+ return resume_df, internship_df
92
+
93
+ # Load data after database initialization
94
+ resume_df, internship_df = fetch_data()
95
+
96
+ # Jaccard Similarity for matching
97
+ def jaccard_similarity(vec1, vec2):
98
+ set1, set2 = set(vec1), set(vec2)
99
+ intersection = len(set1.intersection(set2))
100
+ union = len(set1.union(set2))
101
+ return intersection / union if union != 0 else 0
102
+
103
+ # Routes
104
+ @app.route('/')
105
+ def index():
106
+ return render_template('index.html')
107
+
108
+ @app.route('/signup', methods=['GET', 'POST'])
109
+ def signup():
110
+ if request.method == 'POST':
111
+ name = request.form['name']
112
+ email = request.form['email']
113
+ password = request.form['password']
114
+ role = request.form['role']
115
+ organization_name = request.form.get('organization_name', '')
116
+ contact_details = request.form.get('contact_details', '')
117
+ location = request.form.get('location', '')
118
+ website_link = request.form.get('website_link', '')
119
+
120
+ # Hash the password
121
+ from werkzeug.security import generate_password_hash
122
+ hashed_password = generate_password_hash(password, method='pbkdf2:sha256', salt_length=16)
123
+
124
+ # Check if email already exists
125
+ if db.users.find_one({"email": email}):
126
+ flash('Email already exists!', 'danger')
127
+ return redirect(url_for('signup'))
128
+
129
+ # Get the highest user_id and increment
130
+ max_user = db.users.find_one(sort=[("user_id", -1)])
131
+ new_user_id = (max_user['user_id'] + 1) if max_user and 'user_id' in max_user else 1
132
+
133
+ # Insert new user
134
+ user = {
135
+ "user_id": new_user_id,
136
+ "name": name,
137
+ "email": email,
138
+ "password": hashed_password,
139
+ "role": role,
140
+ "organization_name": organization_name,
141
+ "contact_details": contact_details,
142
+ "location": location,
143
+ "website_link": website_link
144
+ }
145
+ db.users.insert_one(user)
146
+ flash('Signup successful! Please login.', 'success')
147
+ return redirect(url_for('login'))
148
+ return render_template('signup.html')
149
+
150
+ @app.route('/login', methods=['GET', 'POST'])
151
+ def login():
152
+ if request.method == 'POST':
153
+ email = request.form['email']
154
+ password = request.form['password']
155
+
156
+ from werkzeug.security import check_password_hash
157
+ user = db.users.find_one({"email": email})
158
+
159
+ if user and check_password_hash(user['password'], password):
160
+ session['user_id'] = user['user_id']
161
+ session['role'] = user['role']
162
+ flash('Login successful!', 'success')
163
+ if user['role'] == 'intern':
164
+ return redirect(url_for('intern_dashboard'))
165
+ else:
166
+ return redirect(url_for('recruiter_dashboard'))
167
+ else:
168
+ flash('Invalid email or password!', 'danger')
169
+ return render_template('login.html')
170
+
171
+ @app.route('/logout')
172
+ def logout():
173
+ session.pop('user_id', None)
174
+ session.pop('role', None)
175
+ flash('Logged out successfully!', 'success')
176
+ return redirect(url_for('index'))
177
+
178
+ @app.route('/intern_dashboard')
179
+ def intern_dashboard():
180
+ if 'user_id' not in session or session['role'] != 'intern':
181
+ flash('Please login as an intern!', 'danger')
182
+ return redirect(url_for('login'))
183
+
184
+ user_id = session['user_id']
185
+ resume = db.resume_info.find_one({"user_id": user_id})
186
+
187
+ if not resume:
188
+ flash('Please create your resume first!', 'warning')
189
+ return redirect(url_for('create_resume'))
190
+
191
+ user_skills = preprocess_skills(resume['skills'])
192
+ user_vector = [0] * len(skill_to_index)
193
+ for skill in user_skills:
194
+ if skill in skill_to_index:
195
+ user_vector[skill_to_index[skill]] = 1
196
+
197
+ internships = []
198
+ for idx, internship in internship_df.iterrows():
199
+ similarity = jaccard_similarity(user_vector, internship['Required_Skill_vector'])
200
+ if similarity > 0:
201
+ internships.append({
202
+ 'id': internship['id'],
203
+ 'role': internship['role'],
204
+ 'company_name': internship['company_name'],
205
+ 'similarity': similarity
206
+ })
207
+
208
+ internships = sorted(internships, key=lambda x: x['similarity'], reverse=True)
209
+ return render_template('intern_dashboard.html', internships=internships)
210
+
211
+ @app.route('/create_resume', methods=['GET', 'POST'])
212
+ def create_resume():
213
+ if 'user_id' not in session or session['role'] != 'intern':
214
+ flash('Please login as an intern!', 'danger')
215
+ return redirect(url_for('login'))
216
+
217
+ if request.method == 'POST':
218
+ name = request.form['name']
219
+ email = request.form['email']
220
+ phone = request.form['phone']
221
+ skills = request.form['skills']
222
+ experience = request.form['experience']
223
+ education = request.form['education']
224
+ certifications = request.form['certifications']
225
+ achievements = request.form['achievements']
226
+ user_id = session['user_id']
227
+
228
+ resume = {
229
+ "user_id": user_id,
230
+ "name_of_applicant": name,
231
+ "email": email,
232
+ "phone_number": phone,
233
+ "skills": skills,
234
+ "experience": experience,
235
+ "education": education,
236
+ "certifications": certifications,
237
+ "achievements": achievements,
238
+ "downloaded": 0
239
+ }
240
+ db.resume_info.insert_one(resume)
241
+ flash('Resume created successfully!', 'success')
242
+ return redirect(url_for('intern_dashboard'))
243
+ return render_template('create_resume.html')
244
+
245
+ @app.route('/edit_resume', methods=['GET', 'POST'])
246
+ def edit_resume():
247
+ if 'user_id' not in session or session['role'] != 'intern':
248
+ flash('Please login as an intern!', 'danger')
249
+ return redirect(url_for('login'))
250
+
251
+ user_id = session['user_id']
252
+ resume = db.resume_info.find_one({"user_id": user_id})
253
+
254
+ if not resume:
255
+ flash('Please create your resume first!', 'warning')
256
+ return redirect(url_for('create_resume'))
257
+
258
+ if request.method == 'POST':
259
+ name = request.form['name']
260
+ email = request.form['email']
261
+ phone = request.form['phone']
262
+ skills = request.form['skills']
263
+ experience = request.form['experience']
264
+ education = request.form['education']
265
+ certifications = request.form['certifications']
266
+ achievements = request.form['achievements']
267
+
268
+ db.resume_info.update_one(
269
+ {"user_id": user_id},
270
+ {"$set": {
271
+ "name_of_applicant": name,
272
+ "email": email,
273
+ "phone_number": phone,
274
+ "skills": skills,
275
+ "experience": experience,
276
+ "education": education,
277
+ "certifications": certifications,
278
+ "achievements": achievements
279
+ }}
280
+ )
281
+ flash('Resume updated successfully!', 'success')
282
+ return redirect(url_for('intern_dashboard'))
283
+
284
+ return render_template('edit_resume.html', resume=resume)
285
+
286
+ @app.route('/download_resume')
287
+ def download_resume():
288
+ if 'user_id' not in session or session['role'] != 'intern':
289
+ flash('Please login as an intern!', 'danger')
290
+ return redirect(url_for('login'))
291
+
292
+ user_id = session['user_id']
293
+ resume = db.resume_info.find_one({"user_id": user_id})
294
+
295
+ if not resume:
296
+ flash('No resume found!', 'danger')
297
+ return redirect(url_for('create_resume'))
298
+
299
+ db.resume_info.update_one({"user_id": user_id}, {"$set": {"downloaded": 1}})
300
+
301
+ # Render as HTML since pdfkit may not work on Hugging Face Spaces
302
+ return render_template('resume_template.html', resume=resume)
303
+
304
+ @app.route('/apply_internship/<int:internship_id>', methods=['POST'])
305
+ def apply_internship(internship_id):
306
+ if 'user_id' not in session or session['role'] != 'intern':
307
+ flash('Please login as an intern!', 'danger')
308
+ return redirect(url_for('login'))
309
+
310
+ user_id = session['user_id']
311
+ # Check if the user has already applied
312
+ existing_application = db.applications.find_one({"user_id": user_id, "internship_id": internship_id})
313
+ if existing_application:
314
+ flash('You have already applied to this internship!', 'warning')
315
+ return redirect(url_for('intern_dashboard'))
316
+
317
+ application = {
318
+ "user_id": user_id,
319
+ "internship_id": internship_id,
320
+ "applied_at": pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S')
321
+ }
322
+ db.applications.insert_one(application)
323
+ flash('Applied successfully!', 'success')
324
+ return redirect(url_for('intern_dashboard'))
325
+
326
+ @app.route('/applied_internships')
327
+ def applied_internships():
328
+ if 'user_id' not in session or session['role'] != 'intern':
329
+ flash('Please login as an intern!', 'danger')
330
+ return redirect(url_for('login'))
331
+
332
+ user_id = session['user_id']
333
+ applications = list(db.applications.find({"user_id": user_id}))
334
+ internship_ids = [app['internship_id'] for app in applications]
335
+ internships = list(db.internship_info.find({"id": {"$in": internship_ids}}))
336
+ return render_template('applied_internships.html', internships=internships)
337
+
338
+ @app.route('/recruiter_dashboard')
339
+ def recruiter_dashboard():
340
+ if 'user_id' not in session or session['role'] != 'recruiter':
341
+ flash('Please login as a recruiter!', 'danger')
342
+ return redirect(url_for('login'))
343
+
344
+ user_id = session['user_id']
345
+ internships = list(db.internship_info.find({"user_id": user_id}))
346
+ return render_template('recruiter_dashboard.html', internships=internships)
347
+
348
+ @app.route('/register_internship', methods=['GET', 'POST'])
349
+ def register_internship():
350
+ if 'user_id' not in session or session['role'] != 'recruiter':
351
+ flash('Please login as a recruiter!', 'danger')
352
+ return redirect(url_for('login'))
353
+
354
+ user_id = session['user_id']
355
+ # Fetch recruiter details to display in the template
356
+ recruiter = db.users.find_one({"user_id": user_id})
357
+ if not recruiter:
358
+ flash('Recruiter profile not found!', 'danger')
359
+ return redirect(url_for('login'))
360
+
361
+ if request.method == 'POST':
362
+ role = request.form['role']
363
+ description = request.form['description_of_internship']
364
+ start_date = request.form['start_date']
365
+ end_date = request.form['end_date']
366
+ duration = request.form['duration']
367
+ type_of_internship = request.form['type_of_internship']
368
+ skills_required = request.form['skills_required']
369
+ location = request.form['location']
370
+ years_of_experience = int(request.form['years_of_experience'])
371
+ phone_number = request.form['phone_number']
372
+
373
+ # Fetch company details from the recruiter's profile
374
+ company_name = recruiter.get('organization_name', '')
375
+ company_mail = recruiter.get('email', '')
376
+
377
+ # Basic validation
378
+ if not role or not description or not start_date or not end_date or not duration or not type_of_internship or not skills_required or not location or not phone_number:
379
+ flash('All required fields must be filled!', 'danger')
380
+ return render_template('register_internship.html', recruiter=recruiter)
381
+
382
+ # Validate dates
383
+ from datetime import datetime
384
+ try:
385
+ start = datetime.strptime(start_date, '%Y-%m-%d')
386
+ end = datetime.strptime(end_date, '%Y-%m-%d')
387
+ if end <= start:
388
+ flash('End date must be after start date!', 'danger')
389
+ return render_template('register_internship.html', recruiter=recruiter)
390
+ except ValueError:
391
+ flash('Invalid date format!', 'danger')
392
+ return render_template('register_internship.html', recruiter=recruiter)
393
+
394
+ # Validate phone number (basic regex for format like +1-800-555-1234)
395
+ import re
396
+ phone_pattern = r'^\+\d{1,3}-\d{3}-\d{3}-\d{4}$'
397
+ if not re.match(phone_pattern, phone_number):
398
+ flash('Phone number must be in the format +1-800-555-1234!', 'danger')
399
+ return render_template('register_internship.html', recruiter=recruiter)
400
+
401
+ # Get the highest internship_id and increment
402
+ max_internship = db.internship_info.find_one(sort=[("id", -1)])
403
+ new_internship_id = (max_internship['id'] + 1) if max_internship and 'id' in max_internship else 1
404
+
405
+ # Insert internship
406
+ internship = {
407
+ "id": new_internship_id,
408
+ "role": role,
409
+ "description_of_internship": description,
410
+ "start_date": start_date,
411
+ "end_date": end_date,
412
+ "duration": duration,
413
+ "type_of_internship": type_of_internship,
414
+ "skills_required": skills_required,
415
+ "location": location,
416
+ "years_of_experience": years_of_experience,
417
+ "phone_number": phone_number,
418
+ "company_name": company_name,
419
+ "company_mail": company_mail,
420
+ "user_id": user_id,
421
+ "posted_date": pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S'),
422
+ "expected_salary": "" # Not in form, set as empty
423
+ }
424
+ db.internship_info.insert_one(internship)
425
+ flash('Internship registered successfully!', 'success')
426
+ return redirect(url_for('recruiter_dashboard'))
427
+
428
+ return render_template('register_internship.html', recruiter=recruiter)
429
+
430
+ @app.route('/applied_applicants/<int:internship_id>')
431
+ def applied_applicants(internship_id):
432
+ if 'user_id' not in session or session['role'] != 'recruiter':
433
+ flash('Please login as a recruiter!', 'danger')
434
+ return redirect(url_for('login'))
435
+
436
+ applications = list(db.applications.find({"internship_id": internship_id}))
437
+ user_ids = [app['user_id'] for app in applications]
438
+ applicants = []
439
+ for user_id in user_ids:
440
+ resume = db.resume_info.find_one({"user_id": user_id})
441
+ user = db.users.find_one({"user_id": user_id})
442
+ if resume and user:
443
+ applicants.append({
444
+ "name_of_applicant": resume['name_of_applicant'],
445
+ "email": user['email'],
446
+ "skills": resume['skills'],
447
+ "experience": resume['experience'],
448
+ "education": resume['education']
449
+ })
450
+ internship = db.internship_info.find_one({"id": internship_id})
451
+ return render_template('applied_applicants.html', applicants=applicants, internship=internship)
452
+
453
+ @app.route('/top_matched_applicants/<int:internship_id>')
454
+ def top_matched_applicants(internship_id):
455
+ if 'user_id' not in session or session['role'] != 'recruiter':
456
+ flash('Please login as a recruiter!', 'danger')
457
+ return redirect(url_for('login'))
458
+
459
+ internship = internship_df[internship_df['id'] == internship_id].iloc[0]
460
+ internship_vector = internship['Required_Skill_vector']
461
+
462
+ applicants = []
463
+ for idx, resume in resume_df.iterrows():
464
+ similarity = jaccard_similarity(resume['Skill_vector'], internship_vector)
465
+ if similarity > 0:
466
+ user = db.users.find_one({"user_id": resume['user_id']})
467
+ if user:
468
+ applicants.append({
469
+ 'name': resume['name_of_applicant'],
470
+ 'email': user['email'],
471
+ 'similarity': similarity
472
+ })
473
+
474
+ applicants = sorted(applicants, key=lambda x: x['similarity'], reverse=True)[:5]
475
+ return render_template('top_matched_applicants.html', applicants=applicants, internship_id=internship_id)
476
+
477
+ @app.route('/edit_profile', methods=['GET', 'POST'])
478
+ def edit_profile():
479
+ if 'user_id' not in session:
480
+ flash('Please login!', 'danger')
481
+ return redirect(url_for('login'))
482
+
483
+ user_id = session['user_id']
484
+ user = db.users.find_one({"user_id": user_id})
485
+
486
+ if request.method == 'POST':
487
+ name = request.form['name']
488
+ email = request.form['email']
489
+ db.users.update_one(
490
+ {"user_id": user_id},
491
+ {"$set": {"name": name, "email": email}}
492
+ )
493
+ flash('Profile updated successfully!', 'success')
494
+ return redirect(url_for('intern_dashboard' if session['role'] == 'intern' else 'recruiter_dashboard'))
495
+
496
+ return render_template('edit_profile.html', user=user)
497
+
498
+ @app.route('/edit_organization_profile', methods=['GET', 'POST'])
499
+ def edit_organization_profile():
500
+ if 'user_id' not in session or session['role'] != 'recruiter':
501
+ flash('Please login as a recruiter!', 'danger')
502
+ return redirect(url_for('login'))
503
+
504
+ user_id = session['user_id']
505
+ user = db.users.find_one({"user_id": user_id})
506
+
507
+ if request.method == 'POST':
508
+ organization_name = request.form['organization_name']
509
+ contact_details = request.form['contact_details']
510
+ location = request.form['location']
511
+ website_link = request.form['website_link']
512
+ db.users.update_one(
513
+ {"user_id": user_id},
514
+ {"$set": {
515
+ "organization_name": organization_name,
516
+ "contact_details": contact_details,
517
+ "location": location,
518
+ "website_link": website_link
519
+ }}
520
+ )
521
+ flash('Organization profile updated successfully!', 'success')
522
+ return redirect(url_for('recruiter_dashboard'))
523
+
524
+ return render_template('edit_organization_profile.html', user=user)
525
+
526
+ @app.route('/results')
527
+ def results():
528
+ return render_template('results.html')
529
+
530
+ @app.teardown_appcontext
531
+ def close_db(exception):
532
+ client.close()
533
+
534
+ if __name__ == '__main__':
535
+ os.makedirs(UPLOAD_FOLDER, exist_ok=True)
536
+ app.run(debug=True, host='0.0.0.0', port=5000)
applications.csv ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ user_id,internship_id,applied_at
2
+ 4,1,"2025-05-01 06:18:51"
complete_code.py ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Importing necessary libraries
2
+ import mysql.connector
3
+ import pandas as pd
4
+ import nltk
5
+ from nltk.tokenize import word_tokenize
6
+ from nltk.corpus import stopwords
7
+ import string
8
+ import tkinter as tk
9
+ from tkinter import ttk, messagebox
10
+
11
+ # Download NLTK dependencies
12
+ nltk.download('punkt')
13
+ nltk.download('stopwords')
14
+
15
+ # MySQL Database Connection
16
+ def connect_db():
17
+ return mysql.connector.connect(
18
+ host="localhost",
19
+ user="root",
20
+ password="Chaitu895@", # Change to your actual MySQL password
21
+ database="resume_internship_matching"
22
+ )
23
+
24
+ # Fetching data from MySQL
25
+ def fetch_data():
26
+ conn = connect_db()
27
+ cursor = conn.cursor()
28
+
29
+ # Fetch resumes
30
+ cursor.execute("SELECT * FROM resume_info")
31
+ resumes = cursor.fetchall()
32
+
33
+ # Get column names from MySQL tables
34
+ cursor.execute("SHOW COLUMNS FROM resume_info")
35
+ resume_columns = [column[0] for column in cursor.fetchall()]
36
+ # Fetch internships
37
+ cursor.execute("SELECT * FROM internship_info")
38
+ internships = cursor.fetchall()
39
+ cursor.execute("SHOW COLUMNS FROM internship_info")
40
+ internship_columns = [column[0] for column in cursor.fetchall()]
41
+ resume_df = pd.DataFrame(resumes, columns=resume_columns)
42
+ internship_df = pd.DataFrame(internships, columns=internship_columns)
43
+ cursor.close()
44
+ conn.close()
45
+ print(resume_df.head())
46
+ print(internship_df.head())
47
+ return resume_df, internship_df
48
+
49
+ # Preprocessing function for skills
50
+ def preprocess_skills(skills):
51
+ if not isinstance(skills, str) or skills.strip() == '':
52
+ return []
53
+ tokens = word_tokenize(skills.lower())
54
+ tokens = [word for word in tokens if word not in stopwords.words('english') and word not in string.punctuation]
55
+ return tokens
56
+
57
+ # Load data from database
58
+ resume_df, internship_df = fetch_data()
59
+
60
+ # Preprocessing
61
+ resume_df.fillna('', inplace=True)
62
+ internship_df.fillna('', inplace=True)
63
+
64
+ resume_df['processed_Skills'] = resume_df['skills'].apply(preprocess_skills)
65
+ print("Processed Resume Skills:")
66
+ print(resume_df[['processed_Skills']].head())
67
+ internship_df['processed_Required_Skills'] = internship_df['skills_required'].apply(preprocess_skills)
68
+ print("\nProcessed Internship Skills:")
69
+ print(internship_df[['processed_Required_Skills']].head())
70
+ # Creating a set of unique skills
71
+ all_Skills = resume_df['processed_Skills'].sum() + internship_df['processed_Required_Skills'].sum()
72
+ unique_Skills = set(all_Skills)
73
+ Skill_to_index = {skill: idx for idx, skill in enumerate(unique_Skills)}
74
+
75
+ # Converting skills to numerical vectors
76
+ def skills_to_vector(skills):
77
+ vector = [0] * len(Skill_to_index)
78
+ for skill in skills:
79
+ if skill in Skill_to_index:
80
+ vector[Skill_to_index[skill]] += 1
81
+ return vector
82
+
83
+ resume_df['Skill_vector'] = resume_df['processed_Skills'].apply(skills_to_vector)
84
+ internship_df['Required_Skill_vector'] = internship_df['processed_Required_Skills'].apply(skills_to_vector)
85
+
86
+ # Function to calculate Jaccard similarity
87
+ def calculate_similarity(resume_skills, internship_skills):
88
+ set_resume_skills = set(resume_skills)
89
+ set_internship_skills = set(internship_skills)
90
+ intersection = set_resume_skills.intersection(set_internship_skills)
91
+ union = set_resume_skills.union(set_internship_skills)
92
+ return len(intersection) / len(union) if len(union) != 0 else 0
93
+
94
+ # Function to match internships
95
+ def match_internships(resume):
96
+ results = []
97
+ for index, internship in internship_df.iterrows():
98
+ similarity_score = calculate_similarity(resume['processed_Skills'], internship['processed_Required_Skills'])
99
+ if similarity_score > 0: # Include all matches with a similarity score greater than 0
100
+ results.append({
101
+ 'internship_title': internship['role'],
102
+ 'company': internship['company_name'],
103
+ 'type_of_internship': internship['type_of_internship'],
104
+ 'duration': internship['duration'],
105
+ 'location': internship['location'],
106
+ 'description': internship['description_of_internship'],
107
+ 'skills_required': internship['skills_required'],
108
+ 'salary': internship['expected_salary'],
109
+ 'start_date': internship['start_date'],
110
+ 'end_date': internship['end_date'],
111
+ 'posted_date': internship['posted_date'],
112
+ 'similarity_score': similarity_score
113
+ })
114
+
115
+ # Sort by highest similarity score and return the top 5 results
116
+ results = sorted(results, key=lambda x: x['similarity_score'], reverse=True)[:5]
117
+ return results
118
+
119
+ # Function to display matched internships
120
+ def show_results(results, resume_name):
121
+ if not results:
122
+ messagebox.showinfo("No Matches", f"No internships matched for {resume_name}.")
123
+ return
124
+
125
+ results_window = tk.Toplevel(root)
126
+ results_window.title(f"Top 5 Matched Internships for {resume_name}")
127
+ results_window.geometry("800x600")
128
+ results_window.configure(bg='#fafafa')
129
+
130
+ tk.Label(results_window, text=f"Top 5 Matched Internships for {resume_name}", font=('Helvetica', 16, 'bold'), bg='#fafafa').pack(pady=10)
131
+
132
+ for idx, result in enumerate(results, start=1):
133
+ tk.Label(results_window, text=f"#{idx}: {result['internship_title']} at {result['company']}", font=('Helvetica', 14), bg='#fafafa').pack(pady=5)
134
+ tk.Label(results_window, text=f"Location: {result['location']}", font=('Helvetica', 12), bg='#fafafa').pack(pady=2)
135
+ tk.Label(results_window, text=f"Type: {result['type_of_internship']}", font=('Helvetica', 12), bg='#fafafa').pack(pady=2)
136
+ tk.Label(results_window, text=f"Skills Required: {result['skills_required']}", font=('Helvetica', 12), wraplength=700, bg='#fafafa').pack(pady=2)
137
+ tk.Label(results_window, text=f"Duration: {result['duration']}", font=('Helvetica', 12), bg='#fafafa').pack(pady=2)
138
+ tk.Label(results_window, text=f"Salary: {result['salary']}", font=('Helvetica', 12), bg='#fafafa').pack(pady=2)
139
+ tk.Label(results_window, text=f"Start Date: {result['start_date']}", font=('Helvetica', 12), bg='#fafafa').pack(pady=2)
140
+ tk.Label(results_window, text=f"End Date: {result['end_date']}", font=('Helvetica', 12), bg='#fafafa').pack(pady=2)
141
+ tk.Label(results_window, text=f"Posted Date: {result['posted_date']}", font=('Helvetica', 12), bg='#fafafa').pack(pady=2)
142
+ tk.Label(results_window, text=f"Probability of Getting the Job: {result['similarity_score'] * 100:.2f}%", font=('Helvetica', 12, 'bold'), bg='#fafafa').pack(pady=5)
143
+ tk.Label(results_window, text="-" * 80, font=('Helvetica', 12), bg='#fafafa').pack(pady=5)
144
+
145
+ tk.Button(results_window, text="Close", command=results_window.destroy, bg='#00796b', fg='white', font=('Helvetica', 12)).pack(pady=20)
146
+
147
+ # Function to find and match internships
148
+ def find_applicant_and_match_internships():
149
+ applicant_name = entry_name.get().strip()
150
+ if not applicant_name:
151
+ messagebox.showwarning("Input Error", "Please enter a valid applicant name.")
152
+ return
153
+
154
+ matching_resume = resume_df[resume_df['name_of_applicant'].str.contains(applicant_name, case=False)]
155
+ if matching_resume.empty:
156
+ messagebox.showinfo("No Results", f"No resume found for applicant: {applicant_name}")
157
+ else:
158
+ resume = matching_resume.iloc[0]
159
+ matched_internships = match_internships(resume)
160
+ show_results(matched_internships, resume['name_of_applicant'])
161
+
162
+ # Creating the main application window
163
+ root = tk.Tk()
164
+ root.title("SkillSync - Resume Based Internship Matcher")
165
+ root.geometry("800x600")
166
+ root.configure(bg='#e0f7fa')
167
+
168
+ # UI Styling
169
+ style = ttk.Style()
170
+ style.configure('TButton', font=('Helvetica', 12), padding=10)
171
+ style.configure('TLabel', font=('Helvetica', 12), padding=10)
172
+ style.configure('TEntry', font=('Helvetica', 12))
173
+
174
+ # UI Elements
175
+ title_label = ttk.Label(root, text="SkillSync - Resume Based Internship Matcher", font=('Helvetica', 24), background='#e0f7fa')
176
+ title_label.pack(pady=20)
177
+
178
+ name_label = ttk.Label(root, text="Enter Applicant Name:", background='#e0f7fa')
179
+ name_label.pack(pady=10)
180
+
181
+ entry_name = ttk.Entry(root, width=40)
182
+ entry_name.pack(pady=10)
183
+
184
+ search_button = ttk.Button(root, text="Find Matching Internships", command=find_applicant_and_match_internships)
185
+ search_button.pack(pady=20)
186
+
187
+ # Run Tkinter main loop
188
+ root.mainloop()
import_to_mongodb.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import csv
2
+ from pymongo import MongoClient
3
+ import urllib.parse
4
+
5
+ # MongoDB credentials
6
+ username = "root"
7
+ password = "Chaitu895@" # Replace with your actual password
8
+ host = "cluster0.zklixmv.mongodb.net"
9
+ database = "skillsync"
10
+
11
+ # URL-encode the username and password
12
+ encoded_username = urllib.parse.quote_plus(username)
13
+ encoded_password = urllib.parse.quote_plus(password)
14
+
15
+ # Construct the MongoDB URI
16
+ MONGO_URI = f"mongodb+srv://{encoded_username}:{encoded_password}@{host}/{database}?retryWrites=true&w=majority&appName=Cluster0"
17
+ client = MongoClient(MONGO_URI)
18
+ db = client['skillsync']
19
+
20
+ # Function to import CSV into a MongoDB collection
21
+ def import_csv_to_mongo(csv_file, collection_name):
22
+ collection = db[collection_name]
23
+ collection.drop() # Clear the collection before importing
24
+ with open(csv_file, 'r') as f:
25
+ reader = csv.DictReader(f)
26
+ documents = []
27
+ for row in reader:
28
+ # Convert numeric fields to appropriate types
29
+ if 'user_id' in row:
30
+ row['user_id'] = int(row['user_id'])
31
+ if 'internship_id' in row:
32
+ row['internship_id'] = int(row['internship_id'])
33
+ if 'years_of_experience' in row:
34
+ row['years_of_experience'] = int(row['years_of_experience'])
35
+ if 'downloaded' in row:
36
+ row['downloaded'] = int(row['downloaded'])
37
+ documents.append(row)
38
+ collection.insert_many(documents)
39
+ print(f"Imported {csv_file} into {collection_name} collection.")
40
+
41
+ # Import all CSVs
42
+ import_csv_to_mongo('users.csv', 'users')
43
+ import_csv_to_mongo('internship_info.csv', 'internship_info')
44
+ import_csv_to_mongo('applications.csv', 'applications')
45
+ import_csv_to_mongo('resume_info.csv', 'resume_info')
46
+
47
+ client.close()
internship_info.csv ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ role,company_name,company_mail,type_of_internship,skills_required,location,years_of_experience,description_of_internship,phone_number,duration,expected_salary,start_date,end_date,posted_date,user_id
2
+ "Data Science Intern","Tech Innovations","hr@techinnovations.com","Remote","Python, Machine Learning, Data Science","New York, USA",1,"Work on AI models and data analytics projects.","5551234567","6","45000 USD","2025-06-01","2025-12-01","2025-03-13 18:30:00",1
3
+ "Software Engineer Intern","Web Solutions","careers@websolutions.com","Onsite","Java, Spring Boot, SQL","San Francisco, USA",2,"Develop scalable backend services and REST APIs.","5559876543","3","50000 USD","2025-07-01","2025-10-01","2025-03-13 18:30:00",1
4
+ "Frontend Developer Intern","Creative Web","jobs@creativeweb.com","Hybrid","JavaScript, React, Node.js","London, UK",1,"Build dynamic UI components for web applications.","5552233445","4","40000 GBP","2025-06-15","2025-10-15","2025-03-13 18:30:00",1
5
+ "Cybersecurity Intern","SecureNet","security@securenet.com","Remote","Cybersecurity, Ethical Hacking, Python","Berlin, Germany",2,"Conduct security audits and penetration testing.","5553344556","5","42000 EUR","2025-05-10","2025-10-10","2025-03-13 18:30:00",2
6
+ "Robotics Intern","IoT Innovations","iot@iotinnovations.com","Onsite","C++, Embedded Systems, Robotics","Tokyo, Japan",1,"Develop embedded AI for IoT devices.","5554455667","6","48000 JPY","2025-04-20","2025-10-20","2025-03-13 18:30:00",2
7
+ "Software Developer Intern","TechCorp","hr@techcorp.com","Full-Time","Python, Django, SQL","Remote",1,"Develop and maintain web applications.","1234567890","6 months","5000 USD","2025-06-01","2025-12-01","2025-05-01 05:50:51",2
8
+ "Software Developer Intern","TechCorp","john.doe@company.com","Full-Time","Python, Django, REST APIs","Remote",0,"Work on backend development using Python and Django.","+1-800-555-5678","3","","2025-06-01","2025-08-31","2025-05-01 10:43:02",5
9
+ "Frontend Developer Intern","TechCorp","john.doe@company.com","Part-Time","HTML, CSS, JavaScript, React","Remote",0,"Build responsive web applications using React.","+1-800-555-5678","6","","2025-07-01","2025-12-31","2025-05-01 10:44:58",5
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ flask==2.0.1
2
+ pandas==1.5.0
3
+ nltk==3.8.1
4
+ pymongo==4.13.0
5
+ werkzeug==2.0.3
resume_info.csv ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ user_id,name_of_applicant,email,phone_number,skills,experience,education,certifications,achievements,downloaded
2
+ 4,"John Doe","john.doe@email.com","1234567890","Python, Machine Learning, Data Science","2 years at XYZ Corp","B.Sc in Computer Science","AI Chatbot, Web Scraper","Best AI Project Award",0
3
+ 3,"Alice Smith","alice.smith@email.com","9876543210","Java, Spring Boot, SQL","3 years at ABC Tech","M.Sc in Software Engineering","E-commerce Website, Chatbot","Top Developer Award",0
4
+ 6,"Michael Johnson","michael.johnson@email.com","1122334455","JavaScript, React, Node.js","1.5 years at Web Solutions","B.Tech in IT","Portfolio Website, API Development","Employee of the Month",0
5
+ 7,"Emily Davis","emily.davis@email.com","2233445566","C++, Embedded Systems, Robotics","2.5 years at IoT Innovations","B.E in Electronics","Smart Home Automation, AI-driven Drone","Best Robotics Paper",0
6
+ 3,"Robert Brown","robert.brown@email.com","3344556677","Cybersecurity, Ethical Hacking, Python","4 years at SecureNet","M.Sc in Cybersecurity","Network Security Tool, Ethical Hacking Guide","Certified Ethical Hacker",0
static/favicon.ico ADDED

Git LFS Details

  • SHA256: f03771158eb92b66244e8e5984267f49049de8595b760e47fc70349fdf0c9a65
  • Pointer size: 132 Bytes
  • Size of remote file: 1.05 MB
static/logo.png ADDED

Git LFS Details

  • SHA256: f03771158eb92b66244e8e5984267f49049de8595b760e47fc70349fdf0c9a65
  • Pointer size: 132 Bytes
  • Size of remote file: 1.05 MB
static/uploads/resume.pdf ADDED
Binary file (16.3 kB). View file
 
templates/applied_applicants.html ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Applied Applicants</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ margin: 0;
11
+ padding: 0;
12
+ background-color: #f4f4f9;
13
+ }
14
+
15
+ header {
16
+ background-color: #00796b;
17
+ color: white;
18
+ padding: 10px 20px;
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: space-between;
22
+ }
23
+
24
+ header img {
25
+ height: 50px;
26
+ }
27
+
28
+ nav {
29
+ display: flex;
30
+ gap: 20px;
31
+ align-items: center;
32
+ }
33
+
34
+ nav span {
35
+ font-size: 16px;
36
+ }
37
+
38
+ nav a {
39
+ color: white;
40
+ text-decoration: none;
41
+ font-size: 16px;
42
+ padding: 8px 16px;
43
+ border: 1px solid white;
44
+ border-radius: 5px;
45
+ transition: background-color 0.3s ease;
46
+ }
47
+
48
+ nav a:hover {
49
+ background-color: white;
50
+ color: #00796b;
51
+ }
52
+
53
+ .container {
54
+ max-width: 800px;
55
+ margin: 50px auto;
56
+ background: white;
57
+ padding: 20px;
58
+ border-radius: 10px;
59
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
60
+ }
61
+
62
+ h1 {
63
+ text-align: center;
64
+ color: #00796b;
65
+ margin-bottom: 20px;
66
+ }
67
+
68
+ .applicant {
69
+ margin-bottom: 20px;
70
+ padding: 15px;
71
+ border: 1px solid #ccc;
72
+ border-radius: 5px;
73
+ background-color: #f9f9f9;
74
+ }
75
+
76
+ .applicant h2 {
77
+ margin: 0 0 10px;
78
+ color: #00796b;
79
+ font-size: 18px;
80
+ }
81
+
82
+ .applicant p {
83
+ margin: 5px 0;
84
+ color: #333;
85
+ }
86
+
87
+ .applied-date {
88
+ font-size: 14px;
89
+ color: #555;
90
+ }
91
+
92
+ .flash-messages {
93
+ margin: 10px 0;
94
+ }
95
+
96
+ .flash-messages .success {
97
+ color: green;
98
+ background-color: #e0f2e9;
99
+ padding: 10px;
100
+ border-radius: 5px;
101
+ }
102
+
103
+ .flash-messages .error {
104
+ color: red;
105
+ background-color: #ffe6e6;
106
+ padding: 10px;
107
+ border-radius: 5px;
108
+ }
109
+
110
+ .button {
111
+ display: inline-block;
112
+ padding: 10px 20px;
113
+ background-color: #00796b;
114
+ color: white;
115
+ text-decoration: none;
116
+ border-radius: 5px;
117
+ font-size: 16px;
118
+ margin-top: 20px;
119
+ text-align: center;
120
+ transition: background-color 0.3s ease;
121
+ }
122
+
123
+ .button:hover {
124
+ background-color: #005a4f;
125
+ }
126
+ </style>
127
+ </head>
128
+ <body>
129
+ <header>
130
+ <img src="{{ url_for('static', filename='logo.png') }}" alt="SkillSync Logo">
131
+ <nav>
132
+ <span>Welcome, {{ user_name }}</span>
133
+ <a href="{{ url_for('logout') }}">Logout</a>
134
+ </nav>
135
+ </header>
136
+ <div class="container">
137
+ <h1>Applied Applicants</h1>
138
+
139
+ {% with messages = get_flashed_messages(with_categories=true) %}
140
+ {% if messages %}
141
+ <div class="flash-messages">
142
+ {% for category, message in messages %}
143
+ <p class="{{ category }}">{{ message }}</p>
144
+ {% endfor %}
145
+ </div>
146
+ {% endif %}
147
+ {% endwith %}
148
+
149
+ {% if applicants %}
150
+ {% for applicant in applicants %}
151
+ <div class="applicant">
152
+ <h2>{{ applicant.applicant_name }}</h2>
153
+ <p><strong>Email:</strong> {{ applicant.applicant_email }}</p>
154
+ <p><strong>Internship Title:</strong> {{ applicant.internship_title }}</p>
155
+ <p class="applied-date"><strong>Applied On:</strong> {{ applicant.applied_at.strftime('%d %B %Y, %I:%M %p') }}</p>
156
+ </div>
157
+ {% endfor %}
158
+ {% else %}
159
+ <p>No applicants have applied for your internships yet.</p>
160
+ {% endif %}
161
+
162
+ <a href="{{ url_for('recruiter_dashboard') }}" class="button">Back to Dashboard</a>
163
+ </div>
164
+ </body>
165
+ </html>
templates/applied_internships.html ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Applied Internships</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ margin: 0;
11
+ padding: 0;
12
+ background-color: #f4f4f9;
13
+ }
14
+
15
+ .container {
16
+ max-width: 800px;
17
+ margin: 50px auto;
18
+ background: white;
19
+ padding: 20px;
20
+ border-radius: 10px;
21
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
22
+ }
23
+
24
+ h1 {
25
+ text-align: center;
26
+ color: #00796b;
27
+ }
28
+
29
+ .internship {
30
+ margin-bottom: 20px;
31
+ padding: 10px;
32
+ border: 1px solid #ccc;
33
+ border-radius: 5px;
34
+ background-color: #f9f9f9;
35
+ }
36
+
37
+ .internship h2 {
38
+ margin: 0;
39
+ color: #00796b;
40
+ }
41
+
42
+ .internship p {
43
+ margin: 5px 0;
44
+ }
45
+
46
+ .applied-date {
47
+ font-size: 14px;
48
+ color: #555;
49
+ }
50
+ </style>
51
+ </head>
52
+ <body>
53
+ <div class="container">
54
+ <h1>Applied Internships</h1>
55
+ {% if applied_internships %}
56
+ {% for internship in applied_internships %}
57
+ <div class="internship">
58
+ <h2>{{ internship.internship_title }} at {{ internship.company }}</h2>
59
+ <p><strong>Type:</strong> {{ internship.type_of_internship }}</p>
60
+ <p><strong>Location:</strong> {{ internship.location }}</p>
61
+ <p><strong>Description:</strong> {{ internship.description_of_internship }}</p>
62
+ <p class="applied-date"><strong>Applied On:</strong> {{ internship.applied_at.strftime('%d %B %Y, %I:%M %p') }}</p>
63
+ </div>
64
+ {% endfor %}
65
+ {% else %}
66
+ <p>You have not applied for any internships yet.</p>
67
+ {% endif %}
68
+ </div>
69
+ </body>
70
+ </html>
templates/create_resume.html ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Create ATS-Friendly Resume</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ margin: 0;
11
+ padding: 0;
12
+ background-color: #f4f4f9;
13
+ }
14
+
15
+ header {
16
+ background-color: #00796b;
17
+ color: white;
18
+ padding: 10px; 20px;
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: space-between;
22
+ }
23
+
24
+ header img {
25
+ height: 50px;
26
+ }
27
+
28
+ nav {
29
+ display: flex;
30
+ gap: 20px;
31
+ align-items: center;
32
+ }
33
+
34
+ nav a {
35
+ color: white;
36
+ text-decoration: none;
37
+ font-size: 16px;
38
+ padding: 8px 16px;
39
+ border: 1px solid white;
40
+ border-radius: 5px;
41
+ }
42
+
43
+ nav a:hover {
44
+ background-color: white;
45
+ color: #00796b;
46
+ }
47
+
48
+ .container {
49
+ max-width: 600px;
50
+ margin: 50px auto;
51
+ background: white;
52
+ padding: 20px;
53
+ border-radius: 10px;
54
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
55
+ }
56
+
57
+ h1 {
58
+ text-align: center;
59
+ color: #00796b;
60
+ }
61
+
62
+ form {
63
+ display: flex;
64
+ flex-direction: column;
65
+ }
66
+
67
+ label {
68
+ margin-bottom: 5px;
69
+ font-weight: bold;
70
+ color: #555;
71
+ }
72
+
73
+ input, textarea {
74
+ padding: 10px;
75
+ margin-bottom: 15px;
76
+ border: 1px solid #ccc;
77
+ border-radius: 5px;
78
+ font-size: 16px;
79
+ }
80
+
81
+ textarea {
82
+ width: 100%;
83
+ box-sizing: border-box;
84
+ }
85
+
86
+ button {
87
+ padding: 10px;
88
+ background-color: #00796b;
89
+ color: white;
90
+ border: none;
91
+ border-radius: 5px;
92
+ font-size: 16px;
93
+ cursor: pointer;
94
+ transition: background-color 0.3s ease;
95
+ }
96
+
97
+ button:hover {
98
+ background-color: #005a4f;
99
+ }
100
+
101
+ .flash-messages {
102
+ margin: 10px 0;
103
+ }
104
+
105
+ .flash-messages .success {
106
+ color: green;
107
+ background-color: #e0f2e9;
108
+ padding: 10px;
109
+ border-radius: 5px;
110
+ }
111
+
112
+ .flash-messages .error {
113
+ color: red;
114
+ background-color: #ffe6e6;
115
+ padding: 10px;
116
+ border-radius: 5px;
117
+ }
118
+ </style>
119
+ </head>
120
+ <body>
121
+ <header>
122
+ <img src="{{ url_for('static', filename='logo.png') }}" alt="SkillSync Logo">
123
+ <nav>
124
+ <span>Welcome, {{ session.user_name }}</span>
125
+ <a href="{{ url_for('logout') }}">Logout</a>
126
+ </nav>
127
+ </header>
128
+ <div class="container">
129
+ <h1>Create ATS-Friendly Resume</h1>
130
+
131
+ {% with messages = get_flashed_messages(with_categories=true) %}
132
+ {% if messages %}
133
+ <div class="flash-messages">
134
+ {% for category, message in messages %}
135
+ <p class="{{ category }}">{{ message }}</p>
136
+ {% endfor %}
137
+ </div>
138
+ {% endif %}
139
+ {% endwith %}
140
+
141
+ <form action="{{ url_for('create_resume') }}" method="POST">
142
+ <label for="name">Full Name</label>
143
+ <input type="text" id="name" name="name" value="{{ user.user_name if user else '' }}" placeholder="Enter your full name" required>
144
+
145
+ <label for="email">Email</label>
146
+ <input type="email" id="email" name="email" value="{{ user.email if user else '' }}" placeholder="Enter your email" required>
147
+
148
+ <label for="phone">Phone Number</label>
149
+ <input type="text" id="phone" name="phone" placeholder="Enter your phone number">
150
+
151
+ <label for="skills">Skills</label>
152
+ <textarea id="skills" name="skills" placeholder="Enter your skills (e.g., Python, Data Analysis)" rows="4" required></textarea>
153
+
154
+ <label for="experience">Work Experience</label>
155
+ <textarea id="experience" name="experience" placeholder="Enter your work experience (e.g., Job Title, Company, Responsibilities)" rows="6" required></textarea>
156
+
157
+ <label for="education">Education</label>
158
+ <textarea id="education" name="education" placeholder="Enter your educational qualifications (e.g., Degree, Institution, Year)" rows="4" required></textarea>
159
+
160
+ <label for="certifications">Certifications (Optional)</label>
161
+ <textarea id="certifications" name="certifications" placeholder="Enter any certifications (e.g., AWS Certified, PMP)" rows="2"></textarea>
162
+
163
+ <label for="achievements">Achievements (Optional)</label>
164
+ <textarea id="achievements" name="achievements" placeholder="Enter any achievements (e.g., Employee of the Month, Hackathon Winner)" rows="2"></textarea>
165
+
166
+ <button type="submit">Create Resume</button>
167
+ <a href="{{ url_for('intern_dashboard') }}" style="button { display: inline-block; padding: 10px; background-color: #ccc; color: #333; text-decoration: none; border-radius: 5px; margin-top: 10px; }">Cancel</a>
168
+ </form>
169
+ </div>
170
+ </body>
171
+ </html>
templates/edit_organization_profile.html ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Edit Organization Profile</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ margin: 0;
11
+ padding: 0;
12
+ background-color: #f4f4f9;
13
+ }
14
+
15
+ .container {
16
+ max-width: 600px;
17
+ margin: 50px auto;
18
+ background: white;
19
+ padding: 20px;
20
+ border-radius: 10px;
21
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
22
+ }
23
+
24
+ h1 {
25
+ text-align: center;
26
+ color: #00796b;
27
+ }
28
+
29
+ form {
30
+ display: flex;
31
+ flex-direction: column;
32
+ gap: 15px;
33
+ }
34
+
35
+ label {
36
+ font-weight: bold;
37
+ color: #555;
38
+ }
39
+
40
+ input {
41
+ padding: 10px;
42
+ font-size: 16px;
43
+ border: 1px solid #ccc;
44
+ border-radius: 5px;
45
+ width: 100%;
46
+ box-sizing: border-box;
47
+ }
48
+
49
+ button {
50
+ padding: 10px;
51
+ background-color: #00796b;
52
+ color: white;
53
+ border: none;
54
+ border-radius: 5px;
55
+ font-size: 16px;
56
+ cursor: pointer;
57
+ transition: background-color 0.3s ease;
58
+ }
59
+
60
+ button:hover {
61
+ background-color: #005a4f;
62
+ }
63
+ </style>
64
+ </head>
65
+ <body>
66
+ <div class="container">
67
+ <h1>Edit Organization Profile</h1>
68
+ <form action="/edit_organization_profile" method="POST">
69
+ <label for="organization_name">Organization/Company Name:</label>
70
+ <input type="text" id="organization_name" name="organization_name" value="{{ recruiter['organization_name'] }}" required>
71
+
72
+ <label for="contact_details">Contact Details:</label>
73
+ <input type="text" id="contact_details" name="contact_details" value="{{ recruiter['contact_details'] }}" required>
74
+
75
+ <label for="location">Location:</label>
76
+ <input type="text" id="location" name="location" value="{{ recruiter['location'] }}" required>
77
+
78
+ <label for="website_link">Website Link:</label>
79
+ <input type="url" id="website_link" name="website_link" value="{{ recruiter['website_link'] }}" required>
80
+
81
+ <label for="email">Email Address:</label>
82
+ <input type="email" id="email" name="email" value="{{ recruiter['email'] }}" required>
83
+
84
+ <label for="password">New Password (optional):</label>
85
+ <input type="password" id="password" name="password" placeholder="Enter new password">
86
+
87
+ <button type="submit">Save Changes</button>
88
+ </form>
89
+ </div>
90
+ </body>
91
+ </html>
templates/edit_profile.html ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Edit Profile</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ margin: 0;
11
+ padding: 0;
12
+ background-color: #f4f4f9;
13
+ }
14
+
15
+ header {
16
+ background-color: #00796b;
17
+ color: white;
18
+ padding: 10px 20px;
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: space-between;
22
+ }
23
+
24
+ header img {
25
+ height: 50px;
26
+ }
27
+
28
+ nav {
29
+ display: flex;
30
+ gap: 20px;
31
+ align-items: center;
32
+ }
33
+
34
+ nav span {
35
+ font-size: 16px;
36
+ }
37
+
38
+ nav a {
39
+ color: white;
40
+ text-decoration: none;
41
+ font-size: 16px;
42
+ padding: 8px 16px;
43
+ border: 1px solid white;
44
+ border-radius: 5px;
45
+ transition: background-color 0.3s ease;
46
+ }
47
+
48
+ nav a:hover {
49
+ background-color: white;
50
+ color: #00796b;
51
+ }
52
+
53
+ .container {
54
+ max-width: 600px;
55
+ margin: 50px auto;
56
+ background: white;
57
+ padding: 20px;
58
+ border-radius: 10px;
59
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
60
+ }
61
+
62
+ h1 {
63
+ text-align: center;
64
+ color: #00796b;
65
+ margin-bottom: 20px;
66
+ }
67
+
68
+ form {
69
+ display: flex;
70
+ flex-direction: column;
71
+ }
72
+
73
+ p {
74
+ margin: 10px 0;
75
+ }
76
+
77
+ label {
78
+ margin-bottom: 5px;
79
+ font-weight: bold;
80
+ color: #555;
81
+ display: block;
82
+ }
83
+
84
+ input {
85
+ padding: 10px;
86
+ margin-bottom: 15px;
87
+ border: 1px solid #ccc;
88
+ border-radius: 5px;
89
+ font-size: 16px;
90
+ width: 100%;
91
+ box-sizing: border-box;
92
+ }
93
+
94
+ button {
95
+ padding: 10px;
96
+ background-color: #00796b;
97
+ color: white;
98
+ border: none;
99
+ border-radius: 5px;
100
+ font-size: 16px;
101
+ cursor: pointer;
102
+ transition: background-color 0.3s ease;
103
+ }
104
+
105
+ button:hover {
106
+ background-color: #005a4f;
107
+ }
108
+
109
+ .button {
110
+ display: inline-block;
111
+ padding: 10px;
112
+ background-color: #cccccc;
113
+ color: #333;
114
+ text-decoration: none;
115
+ border-radius: 5px;
116
+ font-size: 16px;
117
+ margin-top: 10px;
118
+ text-align: center;
119
+ }
120
+
121
+ .button:hover {
122
+ background-color: #b3b3b3;
123
+ }
124
+
125
+ .flash-messages {
126
+ margin: 10px 0;
127
+ }
128
+
129
+ .flash-messages .success {
130
+ color: green;
131
+ background-color: #e0f2e9;
132
+ padding: 10px;
133
+ border-radius: 5px;
134
+ }
135
+
136
+ .flash-messages .error {
137
+ color: red;
138
+ background-color: #ffe6e6;
139
+ padding: 10px;
140
+ border-radius: 5px;
141
+ }
142
+ </style>
143
+ </head>
144
+ <body>
145
+ <header>
146
+ <img src="{{ url_for('static', filename='logo.png') }}" alt="SkillSync Logo">
147
+ <nav>
148
+ <span>Welcome, {{ session.user_name }}</span>
149
+ <a href="{{ url_for('logout') }}">Logout</a>
150
+ </nav>
151
+ </header>
152
+ <div class="container">
153
+ <h1>Edit Profile</h1>
154
+
155
+ {% with messages = get_flashed_messages(with_categories=true) %}
156
+ {% if messages %}
157
+ <div class="flash-messages">
158
+ {% for category, message in messages %}
159
+ <p class="{{ category }}">{{ message }}</p>
160
+ {% endfor %}
161
+ </div>
162
+ {% endif %}
163
+ {% endwith %}
164
+
165
+ <form action="{{ url_for('edit_profile') }}" method="POST">
166
+ <p>
167
+ <label for="name">Name:</label>
168
+ <input type="text" id="name" name="name" value="{{ user.name if user else '' }}" required>
169
+ </p>
170
+ <p>
171
+ <label for="email">Email:</label>
172
+ <input type="email" id="email" name="email" value="{{ user.email if user else '' }}" required>
173
+ </p>
174
+ <p>
175
+ <label for="password">New Password (Optional):</label>
176
+ <input type="password" id="password" name="password">
177
+ </p>
178
+ <p>
179
+ <button type="submit">Save Changes</button>
180
+ <a href="{{ url_for('intern_dashboard') }}" class="button">Cancel</a>
181
+ </p>
182
+ </form>
183
+ </div>
184
+ </body>
185
+ </html>
templates/edit_resume.html ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Edit ATS-Friendly Resume</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ margin: 0;
11
+ padding: 0;
12
+ background-color: #f4f4f9;
13
+ }
14
+
15
+ header {
16
+ background-color: #00796b;
17
+ color: white;
18
+ padding: 10px 20px;
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: space-between;
22
+ }
23
+
24
+ header img {
25
+ height: 50px;
26
+ }
27
+
28
+ nav {
29
+ display: flex;
30
+ gap: 20px;
31
+ align-items: center;
32
+ }
33
+
34
+ nav a {
35
+ color: white;
36
+ text-decoration: none;
37
+ font-size: 16px;
38
+ padding: 8px 16px;
39
+ border: 1px solid white;
40
+ border-radius: 5px;
41
+ }
42
+
43
+ nav a:hover {
44
+ background-color: white;
45
+ color: #00796b;
46
+ }
47
+
48
+ .container {
49
+ max-width: 600px;
50
+ margin: 50px auto;
51
+ background: white;
52
+ padding: 20px;
53
+ border-radius: 10px;
54
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
55
+ }
56
+
57
+ h1 {
58
+ text-align: center;
59
+ color: #00796b;
60
+ }
61
+
62
+ form {
63
+ display: flex;
64
+ flex-direction: column;
65
+ }
66
+
67
+ label {
68
+ margin-bottom: 5px;
69
+ font-weight: bold;
70
+ color: #555;
71
+ }
72
+
73
+ input, textarea {
74
+ padding: 10px;
75
+ margin-bottom: 15px;
76
+ border: 1px solid #ccc;
77
+ border-radius: 5px;
78
+ font-size: 16px;
79
+ }
80
+
81
+ textarea {
82
+ width: 100%;
83
+ box-sizing: border-box;
84
+ }
85
+
86
+ button {
87
+ padding: 10px;
88
+ background-color: #00796b;
89
+ color: white;
90
+ border: none;
91
+ border-radius: 5px;
92
+ font-size: 16px;
93
+ cursor: pointer;
94
+ transition: background-color 0.3s ease;
95
+ }
96
+
97
+ button:hover {
98
+ background-color: #005a4f;
99
+ }
100
+
101
+ .flash-messages {
102
+ margin: 10px 0;
103
+ }
104
+
105
+ .flash-messages .success {
106
+ color: green;
107
+ background-color: #e0f2e9;
108
+ padding: 10px;
109
+ border-radius: 5px;
110
+ }
111
+
112
+ .flash-messages .error {
113
+ color: red;
114
+ background-color: #ffe6e6;
115
+ padding: 10px;
116
+ border-radius: 5px;
117
+ }
118
+ </style>
119
+ </head>
120
+ <body>
121
+ <header>
122
+ <img src="{{ url_for('static', filename='logo.png') }}" alt="SkillSync Logo">
123
+ <nav>
124
+ <span>Welcome, {{ session.user_name }}</span>
125
+ <a href="{{ url_for('logout') }}">Logout</a>
126
+ </nav>
127
+ </header>
128
+ <div class="container">
129
+ <h1>Edit ATS-Friendly Resume</h1>
130
+
131
+ {% with messages = get_flashed_messages(with_categories=true) %}
132
+ {% if messages %}
133
+ <div class="flash-messages">
134
+ {% for category, message in messages %}
135
+ <p class="{{ category }}">{{ message }}</p>
136
+ {% endfor %}
137
+ </div>
138
+ {% endif %}
139
+ {% endwith %}
140
+
141
+ <form action="{{ url_for('edit_resume') }}" method="POST">
142
+ <label for="name">Full Name</label>
143
+ <input type="text" id="name" name="name" value="{{ resume.name_of_applicant }}" required>
144
+
145
+ <label for="email">Email</label>
146
+ <input type="email" id="email" name="email" value="{{ resume.email }}" required>
147
+
148
+ <label for="phone">Phone Number</label>
149
+ <input type="text" id="phone" name="phone" value="{{ resume.phone_number }}">
150
+
151
+ <label for="skills">Skills</label>
152
+ <textarea id="skills" name="skills" rows="4" required>{{ resume.skills }}</textarea>
153
+
154
+ <label for="experience">Work Experience</label>
155
+ <textarea id="experience" name="experience" rows="6" required>{{ resume.experience }}</textarea>
156
+
157
+ <label for="education">Education</label>
158
+ <textarea id="education" name="education" rows="4" required>{{ resume.education }}</textarea>
159
+
160
+ <label for="certifications">Certifications (Optional)</label>
161
+ <textarea id="certifications" name="certifications" rows="2">{{ resume.certifications }}</textarea>
162
+
163
+ <label for="achievements">Achievements (Optional)</label>
164
+ <textarea id="achievements" name="achievements" rows="2">{{ resume.achievements }}</textarea>
165
+
166
+ <button type="submit">Update Resume</button>
167
+ <a href="{{ url_for('intern_dashboard') }}" style="display: inline-block; padding: 10px; background-color: #ccc; color: #333; text-decoration: none; border-radius: 5px; margin-top: 10px;">Cancel</a>
168
+ </form>
169
+ </div>
170
+ </body>
171
+ </html>
templates/index.html ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
7
+ <title>SkillSync - Internship Matcher</title>
8
+ <style>
9
+ html {
10
+ scroll-behavior: smooth;
11
+ }
12
+
13
+ body {
14
+ font-family: Arial, sans-serif;
15
+ margin: 0;
16
+ padding: 0;
17
+ background-color: #f4f4f9;
18
+ }
19
+
20
+ header {
21
+ background-color: #00796b;
22
+ color: white;
23
+ padding: 10px 20px;
24
+ display: flex;
25
+ align-items: center;
26
+ justify-content: space-between;
27
+ }
28
+
29
+ header img {
30
+ height: 50px;
31
+ }
32
+
33
+ nav {
34
+ display: flex;
35
+ gap: 20px;
36
+ align-items: center;
37
+ }
38
+
39
+ nav span {
40
+ font-size: 16px;
41
+ }
42
+
43
+ nav a {
44
+ color: white;
45
+ text-decoration: none;
46
+ font-size: 16px;
47
+ padding: 8px 16px;
48
+ border: 1px solid white;
49
+ border-radius: 5px;
50
+ transition: background-color 0.3s ease;
51
+ }
52
+
53
+ nav a:hover {
54
+ background-color: white;
55
+ color: #00796b;
56
+ }
57
+
58
+ .hero {
59
+ text-align: center;
60
+ padding: 50px 20px;
61
+ background-color: #e0f7fa;
62
+ }
63
+
64
+ .hero h1 {
65
+ font-size: 36px;
66
+ color: #00796b;
67
+ }
68
+
69
+ .hero p {
70
+ font-size: 18px;
71
+ color: #555;
72
+ margin: 20px 0;
73
+ }
74
+
75
+ .about, .features {
76
+ padding: 50px 20px;
77
+ text-align: center;
78
+ }
79
+
80
+ .about h2, .features h2 {
81
+ font-size: 28px;
82
+ color: #00796b;
83
+ }
84
+
85
+ .about p, .features p {
86
+ font-size: 16px;
87
+ color: #555;
88
+ margin: 20px 0;
89
+ line-height: 1.6;
90
+ }
91
+
92
+ .features ul {
93
+ list-style-type: none;
94
+ padding: 0;
95
+ }
96
+
97
+ .features li {
98
+ font-size: 16px;
99
+ color: #555;
100
+ margin: 10px 0;
101
+ padding: 10px;
102
+ border-radius: 5px;
103
+ transition: background-color 0.3s ease;
104
+ }
105
+
106
+ .features li:hover {
107
+ background-color: #e0f2e9;
108
+ }
109
+
110
+ .contact {
111
+ padding: 50px 20px;
112
+ text-align: center;
113
+ background-color: #e0f7fa;
114
+ }
115
+
116
+ .contact h2 {
117
+ font-size: 28px;
118
+ color: #00796b;
119
+ }
120
+
121
+ .contact p {
122
+ font-size: 16px;
123
+ color: #555;
124
+ margin: 10px 0;
125
+ }
126
+ </style>
127
+ </head>
128
+ <body>
129
+ <header>
130
+ <img src="{{ url_for('static', filename='logo.png') }}" alt="SkillSync Logo">
131
+ <nav>
132
+ <a href="#about">About Us</a>
133
+ <a href="#features">Features Offered</a>
134
+ <a href="#contact">Contact Us</a>
135
+ {% if session['user_name'] %}
136
+ <span>Welcome, {{ session['user_name'] }}</span>
137
+ <a href="/logout">Logout</a>
138
+ {% else %}
139
+ <a href="/signup">Sign Up</a>
140
+ <a href="/login">Login</a>
141
+ {% endif %}
142
+ </nav>
143
+ </header>
144
+
145
+ <div class="hero">
146
+ <h1>Welcome to SkillSync</h1>
147
+ <p>Find the best internships tailored to your skills with just a few clicks!</p>
148
+ </div>
149
+
150
+ <div id="about" class="about">
151
+ <h2>About SkillSync</h2>
152
+ <p>
153
+ SkillSync is an intelligent platform designed to simplify the internship search process.
154
+ By analyzing your skills and matching them with internship requirements, we provide you with
155
+ the top 5 internships that best suit your profile. With our advanced algorithm, we calculate
156
+ the probability of success for each internship, helping you make informed decisions.
157
+ </p>
158
+ <p>
159
+ Whether you're a student looking for your first internship or a professional seeking new opportunities,
160
+ SkillSync makes the process seamless and efficient.
161
+ </p>
162
+ </div>
163
+
164
+ <div id="features" class="features">
165
+ <h2>Features We Offer</h2>
166
+ <ul>
167
+ <li>AI-powered internship matching based on your skills and preferences.</li>
168
+ <li>Top 5 internship recommendations with success probability scores.</li>
169
+ <li>Easy-to-use ATS-friendly resume creation tool.</li>
170
+ <li>Real-time updates on applied internships and recruiter feedback.</li>
171
+ <li>Secure and user-friendly platform for both interns and recruiters.</li>
172
+ </ul>
173
+ </div>
174
+
175
+ <div id="contact" class="contact">
176
+ <h2>Contact Us</h2>
177
+ <p>Email: support@skillsync.com</p>
178
+ <p>Phone: +1-800-555-1234</p>
179
+ <p>Address: 123 Internship Lane, Tech City, USA</p>
180
+ </div>
181
+ </body>
182
+ </html>
templates/intern_dashboard.html ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Intern Dashboard</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ margin: 0;
11
+ padding: 0;
12
+ background-color: #f4f4f9;
13
+ }
14
+
15
+ header {
16
+ background-color: #00796b;
17
+ color: white;
18
+ padding: 10px 20px;
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: space-between;
22
+ }
23
+
24
+ header img {
25
+ height: 50px;
26
+ }
27
+
28
+ nav {
29
+ display: flex;
30
+ gap: 20px;
31
+ align-items: center;
32
+ }
33
+
34
+ nav span {
35
+ font-size: 16px;
36
+ }
37
+
38
+ nav a {
39
+ color: white;
40
+ text-decoration: none;
41
+ font-size: 16px;
42
+ padding: 8px 16px;
43
+ border: 1px solid white;
44
+ border-radius: 5px;
45
+ transition: background-color 0.3s ease;
46
+ }
47
+
48
+ nav a:hover {
49
+ background-color: white;
50
+ color: #00796b;
51
+ }
52
+
53
+ .container {
54
+ padding: 20px;
55
+ max-width: 1200px;
56
+ margin: 0 auto;
57
+ }
58
+
59
+ h1 {
60
+ color: #00796b;
61
+ text-align: center;
62
+ margin-bottom: 20px;
63
+ }
64
+
65
+ .button {
66
+ display: inline-block;
67
+ padding: 15px 30px;
68
+ margin: 10px;
69
+ background-color: #00796b;
70
+ color: white;
71
+ text-decoration: none;
72
+ border-radius: 5px;
73
+ font-size: 18px;
74
+ transition: background-color 0.3s ease;
75
+ }
76
+
77
+ .button:hover {
78
+ background-color: #005a4f;
79
+ }
80
+
81
+ .flash-messages {
82
+ margin: 10px 0;
83
+ }
84
+
85
+ .flash-messages .success {
86
+ color: green;
87
+ background-color: #e0f2e9;
88
+ padding: 10px;
89
+ border-radius: 5px;
90
+ }
91
+
92
+ .flash-messages .error {
93
+ color: red;
94
+ background-color: #ffe6e6;
95
+ padding: 10px;
96
+ border-radius: 5px;
97
+ }
98
+
99
+ .internship {
100
+ background-color: white;
101
+ border: 1px solid #ccc;
102
+ border-radius: 5px;
103
+ padding: 15px;
104
+ margin: 10px 0;
105
+ box-shadow: 0 2px 5px rgba(0,0,0,0.1);
106
+ }
107
+
108
+ .internship h3 {
109
+ color: #00796b;
110
+ margin: 0 0 10px;
111
+ }
112
+
113
+ .internship p {
114
+ margin: 5px 0;
115
+ color: #333;
116
+ }
117
+
118
+ .apply-button {
119
+ display: inline-block;
120
+ padding: 10px 20px;
121
+ background-color: #00796b;
122
+ color: white;
123
+ text-decoration: none;
124
+ border-radius: 5px;
125
+ font-size: 16px;
126
+ transition: background-color 0.3s ease;
127
+ border: none;
128
+ cursor: pointer;
129
+ }
130
+
131
+ .apply-button:hover {
132
+ background-color: #005a4f;
133
+ }
134
+
135
+ .applied-label {
136
+ display: inline-block;
137
+ padding: 10px 20px;
138
+ background-color: #cccccc;
139
+ color: #333;
140
+ border-radius: 5px;
141
+ font-size: 16px;
142
+ text-align: center;
143
+ }
144
+ </style>
145
+ </head>
146
+ <body>
147
+ <header>
148
+ <img src="{{ url_for('static', filename='logo.png') }}" alt="SkillSync Logo">
149
+ <nav>
150
+ <span>Welcome, {{ user_name }}</span>
151
+ <a href="{{ url_for('logout') }}">Logout</a>
152
+ </nav>
153
+ </header>
154
+ <div class="container">
155
+ <h1>Intern Dashboard</h1>
156
+
157
+ {% with messages = get_flashed_messages(with_categories=true) %}
158
+ {% if messages %}
159
+ <div class="flash-messages">
160
+ {% for category, message in messages %}
161
+ <p class="{{ category }}">{{ message }}</p>
162
+ {% endfor %}
163
+ </div>
164
+ {% endif %}
165
+ {% endwith %}
166
+
167
+ <div>
168
+ <a href="{{ url_for('create_resume') }}" class="button">Create ATS-Friendly Resume</a>
169
+ <a href="{{ url_for('edit_resume') }}" class="button">Edit Resume</a>
170
+ <a href="{{ url_for('match') }}" class="button">Matched Internships</a>
171
+ <a href="{{ url_for('applied_internships') }}" class="button">Applied Internships</a>
172
+ <a href="{{ url_for('edit_profile') }}" class="button">Edit Profile</a>
173
+ </div>
174
+
175
+ <h2>Matched Internships</h2>
176
+ {% if matched_internships %}
177
+ {% for internship in matched_internships %}
178
+ <div class="internship">
179
+ <h3>{{ internship.internship_title }} at {{ internship.company }}</h3>
180
+ <p><strong>Type:</strong> {{ internship.type_of_internship }}</p>
181
+ <p><strong>Duration:</strong> {{ internship.duration }}</p>
182
+ <p><strong>Location:</strong> {{ internship.location }}</p>
183
+ <p><strong>Skills Required:</strong> {{ internship.skills_required }}</p>
184
+ <p><strong>Similarity Score:</strong> {{ internship.similarity_score }}%</p>
185
+ {% if internship.similarity_score > 75 %}
186
+ {% if internship.id in applied_internship_ids %}
187
+ <span class="applied-label">Applied</span>
188
+ {% else %}
189
+ <form action="{{ url_for('apply_internship') }}" method="POST">
190
+ <input type="hidden" name="internship_id" value="{{ internship.id }}">
191
+ <button type="submit" class="apply-button">Apply</button>
192
+ </form>
193
+ {% endif %}
194
+ {% endif %}
195
+ </div>
196
+ {% endfor %}
197
+ {% else %}
198
+ <p>No matched internships found. Create or update your resume to find matches.</p>
199
+ {% endif %}
200
+ </div>
201
+ </body>
202
+ </html>
templates/login.html ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Login - SkillSync</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ margin: 0;
11
+ padding: 0;
12
+ background-color: #f4f4f9;
13
+ }
14
+
15
+ .container {
16
+ max-width: 400px;
17
+ margin: 50px auto;
18
+ background: white;
19
+ padding: 20px;
20
+ border-radius: 10px;
21
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
22
+ }
23
+
24
+ h1 {
25
+ text-align: center;
26
+ color: #00796b;
27
+ }
28
+
29
+ form {
30
+ display: flex;
31
+ flex-direction: column;
32
+ }
33
+
34
+ label {
35
+ margin-bottom: 5px;
36
+ font-weight: bold;
37
+ color: #555;
38
+ }
39
+
40
+ input {
41
+ padding: 10px;
42
+ margin-bottom: 15px;
43
+ border: 1px solid #ccc;
44
+ border-radius: 5px;
45
+ font-size: 16px;
46
+ }
47
+
48
+ button {
49
+ padding: 10px;
50
+ background-color: #00796b;
51
+ color: white;
52
+ border: none;
53
+ border-radius: 5px;
54
+ font-size: 16px;
55
+ cursor: pointer;
56
+ transition: background-color 0.3s ease;
57
+ }
58
+
59
+ button:hover {
60
+ background-color: #005a4f;
61
+ }
62
+
63
+ .signup-link {
64
+ text-align: center;
65
+ margin-top: 10px;
66
+ }
67
+
68
+ .signup-link a {
69
+ color: #00796b;
70
+ text-decoration: none;
71
+ font-weight: bold;
72
+ }
73
+
74
+ .signup-link a:hover {
75
+ text-decoration: underline;
76
+ }
77
+ </style>
78
+ </head>
79
+ <body>
80
+ <div class="container">
81
+ <h1>Login</h1>
82
+ <form action="/login" method="POST">
83
+ <label for="email">Email</label>
84
+ <input type="email" id="email" name="email" placeholder="Enter your email" autocomplete="email" required>
85
+
86
+ <label for="password">Password</label>
87
+ <input type="password" id="password" name="password" placeholder="Enter your password" autocomplete="current-password" required>
88
+
89
+ <button type="submit">Login</button>
90
+ </form>
91
+ <div class="signup-link">
92
+ Don't have an account? <a href="/signup">Sign up here</a>
93
+ </div>
94
+ </div>
95
+ </body>
96
+ </html>
templates/recruiter_dashboard.html ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Recruiter Dashboard</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ margin: 0;
11
+ padding: 0;
12
+ background-color: #f4f4f9;
13
+ }
14
+
15
+ header {
16
+ background-color: #00796b;
17
+ color: white;
18
+ padding: 10px 20px;
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: space-between;
22
+ }
23
+
24
+ header img {
25
+ height: 50px;
26
+ }
27
+
28
+ nav {
29
+ display: flex;
30
+ gap: 20px;
31
+ }
32
+
33
+ nav a {
34
+ color: white;
35
+ text-decoration: none;
36
+ font-size: 16px;
37
+ padding: 8px 16px;
38
+ border: 1px solid white;
39
+ border-radius: 5px;
40
+ transition: background-color 0.3s ease;
41
+ }
42
+
43
+ nav a:hover {
44
+ background-color: white;
45
+ color: #00796b;
46
+ }
47
+
48
+ .container {
49
+ padding: 20px;
50
+ }
51
+
52
+ .button {
53
+ display: inline-block;
54
+ padding: 15px 30px;
55
+ margin: 10px;
56
+ background-color: #00796b;
57
+ color: white;
58
+ text-decoration: none;
59
+ border-radius: 5px;
60
+ font-size: 18px;
61
+ transition: background-color 0.3s ease;
62
+ }
63
+
64
+ .button:hover {
65
+ background-color: #005a4f;
66
+ }
67
+
68
+ .success {
69
+ color: green;
70
+ font-weight: bold;
71
+ margin-bottom: 10px;
72
+ }
73
+ .error {
74
+ color: red;
75
+ font-weight: bold;
76
+ margin-bottom: 10px;
77
+ }
78
+ </style>
79
+ </head>
80
+ <body>
81
+ <header>
82
+ <img src="{{ url_for('static', filename='logo.png') }}" alt="SkillSync Logo">
83
+ <nav>
84
+ <span>Welcome, {{ user_name }}</span>
85
+ <a href="/logout">Logout</a>
86
+ </nav>
87
+ </header>
88
+ <div class="container">
89
+ {% with messages = get_flashed_messages(with_categories=true) %}
90
+ {% if messages %}
91
+ <div>
92
+ {% for category, message in messages %}
93
+ <p class="{{ category }}">{{ message }}</p>
94
+ {% endfor %}
95
+ </div>
96
+ {% endif %}
97
+ {% endwith %}
98
+ <h1>Recruiter Dashboard</h1>
99
+ <h1>Welcome, {{ recruiter['name'] }}</h1>
100
+ <p><strong>Organization:</strong> {{ recruiter['organization_name'] }}</p>
101
+ <p><strong>Contact Details:</strong> {{ recruiter['contact_details'] }}</p>
102
+ <p><strong>Location:</strong> {{ recruiter['location'] }}</p>
103
+ <p><strong>Website:</strong> <a href="{{ recruiter['website_link'] }}" target="_blank">{{ recruiter['website_link'] }}</a></p>
104
+ <a href="/register_internship" class="button">Register Internship</a>
105
+ <a href="/applied_applicants" class="button">Display Applied Applicants</a>
106
+ <a href="/top_matched_applicants/1" class="button">Top Matched Applicants</a>
107
+ <a href="/edit_organization_profile" class="button">Edit Organization Profile</a>
108
+ </div>
109
+ </body>
110
+ </html>
templates/register_internship.html ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Register Internship</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ margin: 0;
11
+ padding: 0;
12
+ background-color: #f4f4f9;
13
+ }
14
+
15
+ .container {
16
+ max-width: 600px;
17
+ margin: 50px auto;
18
+ background: white;
19
+ padding: 20px;
20
+ border-radius: 10px;
21
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
22
+ }
23
+
24
+ h1 {
25
+ text-align: center;
26
+ color: #00796b;
27
+ }
28
+
29
+ form {
30
+ display: flex;
31
+ flex-direction: column;
32
+ }
33
+
34
+ label {
35
+ margin-bottom: 5px;
36
+ font-weight: bold;
37
+ color: #555;
38
+ }
39
+
40
+ input, textarea, select {
41
+ padding: 10px;
42
+ margin-bottom: 15px;
43
+ border: 1px solid #ccc;
44
+ border-radius: 5px;
45
+ font-size: 16px;
46
+ }
47
+
48
+ button {
49
+ padding: 10px;
50
+ background-color: #00796b;
51
+ color: white;
52
+ border: none;
53
+ border-radius: 5px;
54
+ font-size: 16px;
55
+ cursor: pointer;
56
+ transition: background-color 0.3s ease;
57
+ }
58
+
59
+ button:hover {
60
+ background-color: #005a4f;
61
+ }
62
+
63
+ .button {
64
+ display: inline-block;
65
+ padding: 10px;
66
+ background-color: #00796b;
67
+ color: white;
68
+ text-decoration: none;
69
+ border-radius: 5px;
70
+ font-size: 16px;
71
+ margin: 5px 0;
72
+ text-align: center;
73
+ transition: background-color 0.3s ease;
74
+ }
75
+
76
+ .button:hover {
77
+ background-color: #005a4f;
78
+ }
79
+
80
+ .success {
81
+ color: green;
82
+ }
83
+
84
+ .error {
85
+ color: red;
86
+ }
87
+ </style>
88
+ </head>
89
+ <body>
90
+ <div class="container">
91
+ <h1>Welcome, {{ recruiter['name'] }}</h1>
92
+ <p><strong>Organization:</strong> {{ recruiter['organization_name'] }}</p>
93
+ <p><strong>Email:</strong> {{ recruiter['email'] }}</p>
94
+
95
+ <form action="/register_internship" method="POST">
96
+ <label for="role">Role:</label>
97
+ <input type="text" id="role" name="role" required><br><br>
98
+
99
+ <label for="description_of_internship">Description:</label>
100
+ <textarea id="description_of_internship" name="description_of_internship" required></textarea><br><br>
101
+
102
+ <label for="start_date">Start Date:</label>
103
+ <input type="date" id="start_date" name="start_date" required><br><br>
104
+
105
+ <label for="end_date">End Date:</label>
106
+ <input type="date" id="end_date" name="end_date" required><br><br>
107
+
108
+ <label for="duration">Duration:</label>
109
+ <input type="text" id="duration" name="duration" required><br><br>
110
+
111
+ <label for="type_of_internship">Type of Internship:</label>
112
+ <input type="text" id="type_of_internship" name="type_of_internship" required><br><br>
113
+
114
+ <label for="skills_required">Skills Required:</label>
115
+ <textarea id="skills_required" name="skills_required" required></textarea><br><br>
116
+
117
+ <label for="location">Location:</label>
118
+ <input type="text" id="location" name="location" required><br><br>
119
+
120
+ <label for="years_of_experience">Years of Experience:</label>
121
+ <input type="number" id="years_of_experience" name="years_of_experience" required><br><br>
122
+
123
+ <label for="phone_number">Phone Number (e.g., +1-800-555-1234):</label>
124
+ <input type="text" id="phone_number" name="phone_number" maxlength="20" required><br><br>
125
+
126
+ <button type="submit">Register Internship</button>
127
+ </form>
128
+ </div>
129
+ </body>
130
+ </html>
templates/results.html ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
7
+ <title>Matched Internships</title>
8
+ <style>
9
+ body {
10
+ font-family: Arial, sans-serif;
11
+ margin: 0;
12
+ padding: 0;
13
+ background-color: #f4f4f9;
14
+ }
15
+
16
+ .container {
17
+ max-width: 800px;
18
+ margin: 50px auto;
19
+ background: white;
20
+ padding: 20px;
21
+ border-radius: 10px;
22
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
23
+ }
24
+
25
+ h1 {
26
+ text-align: center;
27
+ color: #00796b;
28
+ }
29
+
30
+ .internship {
31
+ margin-bottom: 20px;
32
+ padding: 10px;
33
+ border: 1px solid #ccc;
34
+ border-radius: 5px;
35
+ background-color: #f9f9f9;
36
+ }
37
+
38
+ .internship h2 {
39
+ margin: 0;
40
+ color: #00796b;
41
+ }
42
+
43
+ .internship p {
44
+ margin: 5px 0;
45
+ }
46
+
47
+ .apply-button {
48
+ display: inline-block;
49
+ padding: 10px 20px;
50
+ margin-top: 10px;
51
+ background-color: #00796b;
52
+ color: white;
53
+ text-decoration: none;
54
+ border-radius: 5px;
55
+ font-size: 14px;
56
+ transition: background-color 0.3s ease;
57
+ }
58
+
59
+ .apply-button:hover {
60
+ background-color: #005a4f;
61
+ }
62
+
63
+ .success {
64
+ color: green;
65
+ font-weight: bold;
66
+ }
67
+ .error {
68
+ color: red;
69
+ font-weight: bold;
70
+ }
71
+ </style>
72
+ </head>
73
+ <body>
74
+ <div class="container">
75
+ <h1>Matched Internships for {{ applicant_name }}</h1>
76
+ {% with messages = get_flashed_messages(with_categories=true) %}
77
+ {% if messages %}
78
+ <div>
79
+ {% for category, message in messages %}
80
+ <p class="{{ category }}">{{ message }}</p>
81
+ {% endfor %}
82
+ </div>
83
+ {% endif %}
84
+ {% endwith %}
85
+ {% if results %}
86
+ {% for internship in results %}
87
+ <div class="internship">
88
+ <h2>{{ internship.internship_title }} at {{ internship.company }}</h2>
89
+ <p><strong>Type:</strong> {{ internship.type_of_internship }}</p>
90
+ <p><strong>Duration:</strong> {{ internship.duration }}</p>
91
+ <p><strong>Location:</strong> {{ internship.location }}</p>
92
+ <p><strong>Skills Required:</strong> {{ internship.skills_required }}</p>
93
+ <p><strong>Similarity Score:</strong> {{ internship.similarity_score }}%</p>
94
+ {% if internship.similarity_score > 75 %}
95
+ <form action="/apply_internship" method="POST" style="display: inline;">
96
+ <input type="hidden" name="internship_id" value="{{ internship.id }}">
97
+ <button type="submit" class="apply-button">Apply</button>
98
+ </form>
99
+ {% endif %}
100
+ </div>
101
+ {% endfor %}
102
+ {% else %}
103
+ <p>No matched internships found.</p>
104
+ {% endif %}
105
+ </div>
106
+ </body>
107
+ </html>
templates/signup.html ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Sign Up - SkillSync</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ margin: 0;
11
+ padding: 0;
12
+ background-color: #f4f4f9;
13
+ }
14
+
15
+ .container {
16
+ max-width: 600px;
17
+ margin: 50px auto;
18
+ background: white;
19
+ padding: 20px;
20
+ border-radius: 10px;
21
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
22
+ }
23
+
24
+ h1 {
25
+ text-align: center;
26
+ color: #00796b;
27
+ }
28
+
29
+ form {
30
+ display: flex;
31
+ flex-direction: column;
32
+ gap: 15px;
33
+ }
34
+
35
+ label {
36
+ font-weight: bold;
37
+ color: #555;
38
+ }
39
+
40
+ input, select {
41
+ padding: 10px;
42
+ font-size: 16px;
43
+ border: 1px solid #ccc;
44
+ border-radius: 5px;
45
+ width: 100%;
46
+ box-sizing: border-box;
47
+ }
48
+
49
+ .form-group {
50
+ display: flex;
51
+ flex-wrap: wrap;
52
+ gap: 15px;
53
+ }
54
+
55
+ .form-group > div {
56
+ flex: 1;
57
+ min-width: 45%;
58
+ }
59
+
60
+ button {
61
+ padding: 10px;
62
+ background-color: #00796b;
63
+ color: white;
64
+ border: none;
65
+ border-radius: 5px;
66
+ font-size: 16px;
67
+ cursor: pointer;
68
+ transition: background-color 0.3s ease;
69
+ }
70
+
71
+ button:hover {
72
+ background-color: #005a4f;
73
+ }
74
+
75
+ .login-link {
76
+ text-align: center;
77
+ margin-top: 10px;
78
+ }
79
+
80
+ .login-link a {
81
+ color: #00796b;
82
+ text-decoration: none;
83
+ font-weight: bold;
84
+ }
85
+
86
+ .login-link a:hover {
87
+ text-decoration: underline;
88
+ }
89
+
90
+ .error {
91
+ color: red;
92
+ font-weight: bold;
93
+ }
94
+ .success {
95
+ color: green;
96
+ font-weight: bold;
97
+ }
98
+
99
+ .recruiter-fields {
100
+ display: none;
101
+ }
102
+ </style>
103
+ <script>
104
+ function toggleFields() {
105
+ const role = document.getElementById('role').value;
106
+ const recruiterFields = document.getElementById('recruiter-fields');
107
+ if (role === 'recruiter') {
108
+ recruiterFields.style.display = 'block';
109
+ } else {
110
+ recruiterFields.style.display = 'none';
111
+ }
112
+ }
113
+ </script>
114
+ </head>
115
+ <body>
116
+ <header>
117
+ <img src="{{ url_for('static', filename='logo.png') }}" alt="SkillSync Logo" style="height: 50px;">
118
+ </header>
119
+ <div class="container">
120
+ <h1>Sign Up</h1>
121
+ {% with messages = get_flashed_messages(with_categories=true) %}
122
+ {% if messages %}
123
+ <div>
124
+ {% for category, message in messages %}
125
+ <p class="{{ category }}">{{ message }}</p>
126
+ {% endfor %}
127
+ </div>
128
+ {% endif %}
129
+ {% endwith %}
130
+ <form action="/signup" method="POST">
131
+ <label for="name">Name:</label>
132
+ <input type="text" id="name" name="name" required>
133
+
134
+ <label for="email">Email:</label>
135
+ <input type="email" id="email" name="email" required>
136
+
137
+ <label for="password">Password:</label>
138
+ <input type="password" id="password" name="password" required>
139
+
140
+ <label for="confirm_password">Confirm Password:</label>
141
+ <input type="password" id="confirm_password" name="confirm_password" required>
142
+
143
+ <label for="role">Role:</label>
144
+ <select id="role" name="role" onchange="toggleFields()" required>
145
+ <option value="intern">Intern</option>
146
+ <option value="recruiter">Recruiter</option>
147
+ </select>
148
+
149
+ <!-- Recruiter-specific fields -->
150
+ <div id="recruiter-fields" class="recruiter-fields">
151
+ <div class="form-group">
152
+ <div>
153
+ <label for="organization_name">Organization/Company Name:</label>
154
+ <input type="text" id="organization_name" name="organization_name">
155
+ </div>
156
+ <div>
157
+ <label for="contact_details">Contact Details:</label>
158
+ <input type="text" id="contact_details" name="contact_details">
159
+ </div>
160
+ </div>
161
+ <div class="form-group">
162
+ <div>
163
+ <label for="location">Location:</label>
164
+ <input type="text" id="location" name="location">
165
+ </div>
166
+ <div>
167
+ <label for="website_link">Website Link:</label>
168
+ <input type="url" id="website_link" name="website_link">
169
+ </div>
170
+ </div>
171
+ </div>
172
+
173
+ <button type="submit">Sign Up</button>
174
+ </form>
175
+ <div class="login-link">
176
+ Already have an account? <a href="/login">Login here</a>
177
+ </div>
178
+ </div>
179
+ </body>
180
+ </html>
templates/top_matched_applicants.html ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Top Matched Applicants</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ margin: 0;
11
+ padding: 0;
12
+ background-color: #f4f4f9;
13
+ }
14
+
15
+ .container {
16
+ max-width: 800px;
17
+ margin: 50px auto;
18
+ background: white;
19
+ padding: 20px;
20
+ border-radius: 10px;
21
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
22
+ }
23
+
24
+ h1 {
25
+ text-align: center;
26
+ color: #00796b;
27
+ }
28
+
29
+ .applicant {
30
+ margin-bottom: 20px;
31
+ padding: 10px;
32
+ border: 1px solid #ccc;
33
+ border-radius: 5px;
34
+ background-color: #f9f9f9;
35
+ }
36
+
37
+ .applicant h2 {
38
+ margin: 0;
39
+ color: #00796b;
40
+ }
41
+
42
+ .applicant p {
43
+ margin: 5px 0;
44
+ }
45
+
46
+ .similarity-score {
47
+ font-size: 14px;
48
+ color: #555;
49
+ }
50
+ </style>
51
+ </head>
52
+ <body>
53
+ <div class="container">
54
+ <h1>Top Matched Applicants for {{ internship_title }}</h1>
55
+ {% if matched_applicants %}
56
+ {% for applicant in matched_applicants %}
57
+ <div class="applicant">
58
+ <h2>{{ applicant.name }}</h2>
59
+ <p><strong>Email:</strong> {{ applicant.email }}</p>
60
+ <p><strong>Skills:</strong> {{ applicant.skills }}</p>
61
+ <p class="similarity-score"><strong>Similarity Score:</strong> {{ applicant.similarity_score }}%</p>
62
+ </div>
63
+ {% endfor %}
64
+ {% else %}
65
+ <p>No matched applicants found for this role.</p>
66
+ {% endif %}
67
+ </div>
68
+ </body>
69
+ </html>
updated_internship_dataset.xlsx ADDED
Binary file (34.1 kB). View file
 
updated_resume_dataset.xlsx ADDED
Binary file (32 kB). View file
 
users.csv ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ name,email,password,role,organization_name,contact_details,location,website_link
2
+ "B Chaitanya Reddy","bchai@gmail.com","pbkdf2:sha256:1000000$IwoXxqdu1zYIIf4P$70064a2ae7d2103e54d2957aa2d0899d547854e2e6313e5c3b648f52d83435ba","recruiter","","","",""
3
+ "abc","abc@gmail.com","pbkdf2:sha256:1000000$5spHg9C2M6oBOLJ2$05bb400421a6b5688a9281addbcef96479a8ca79bb20ca849de1b472a616bfab","recruiter","","","",""
4
+ "abc","def@gmail.com","pbkdf2:sha256:1000000$eMbeIagjigPKOqAC$b6cbc477d0069b53a09a893c498d5be05e50a18351dd319ebd9f40c55e7ff4f6","intern","","","",""
5
+ "John Doe","john.doe@email.com","pbkdf2:sha256:1000000$sh6a4Yxb4DDUQ9MO$10755d88a3a30ef0d77dcdb53997a73b863c8f76f2133f6a32a359e1ae23457f","intern","","","",""
6
+ "John Doe","john.doe@company.com","pbkdf2:sha256:1000000$uBZdoWuUL8eAnEDr$961b25cf97f37bcd33224a75fd53e3773970ba649e671c22ad1fef2a6e16832f","recruiter","TechCorp","+1-800-555-1234","San Francisco, CA","https://www.techcorp.com"
7
+ "Jane Smith","jane.smith@gmail.com","pbkdf2:sha256:1000000$17VAt8BB2IpEntKf$37fd999fdf86dc8d002725aaed06cead50046f7667cf4d84cee78dbfa7a361d9","intern","","","",""
8
+ "B Chaitanya Reddy","bchaitanyareddy902@gmail.com","pbkdf2:sha256:1000000$qHYm9jyDvaqpc5d6$d40a49464a6366af81b8792c95b01e84fb5b6e5c3579ab2d1c4d068e4148f915","intern","","","",""