Spaces:
Paused
Paused
{% extends "base.html" %} | |
{% block title %}My Applications - Codingo{% endblock %} | |
{% block content %} | |
<section class="content-section"> | |
<div class="section-header"> | |
<h2>My Applications</h2> | |
<p>Track and manage your job applications</p> | |
</div> | |
<ul class="breadcrumbs"> | |
<li><a href="{{ url_for('index') }}">Home</a></li> | |
<li>My Applications</li> | |
</ul> | |
<!-- Interview Guidelines Section --> | |
<div class="interview-guidelines"> | |
<div class="guidelines-header"> | |
<h3><span class="icon">π―</span> Important Interview Guidelines</h3> | |
</div> | |
<div class="guidelines-content"> | |
<div class="guideline-item"> | |
<span class="guideline-icon">β‘</span> | |
<div class="guideline-text"> | |
<strong>One-time opportunity:</strong> The interview can be taken only once, so please be well-prepared. | |
</div> | |
</div> | |
<div class="guideline-item"> | |
<span class="guideline-icon">π§</span> | |
<div class="guideline-text"> | |
<strong>Environment:</strong> Ensure you're in a quiet space with a stable internet connection. | |
</div> | |
</div> | |
<div class="guideline-item"> | |
<span class="guideline-icon">π</span> | |
<div class="guideline-text"> | |
<strong>Purpose:</strong> This helps companies shortlist the most relevant candidates for the role. | |
</div> | |
</div> | |
<div class="guideline-item"> | |
<span class="guideline-icon">π―</span> | |
<div class="guideline-text"> | |
<strong>Customization:</strong> Questions are tailored based on your CV and job requirements. | |
</div> | |
</div> | |
<div class="guideline-item"> | |
<span class="guideline-icon">β±οΈ</span> | |
<div class="guideline-text"> | |
<strong>Duration:</strong> 10-15 minutes including general and skill-based questions. | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Applications Grid --> | |
<div class="applications-container"> | |
{% if applications %} | |
<div class="applications-grid"> | |
{% for application in applications %} | |
<div class="application-card" data-status="{{ application.status }}"> | |
<div class="card-status-badge status-{{ application.status.lower().replace(' ', '-') }}"> | |
{{ application.status }} | |
</div> | |
<div class="application-header"> | |
<h3>{{ application.job.role if application.job else 'Unknown Role' }}</h3> | |
<div class="company-info"> | |
<span class="company-name">{{ application.job.company if application.job else '' }}</span> | |
{% if application.job and application.job.location %} | |
<span class="location">π {{ application.job.location }}</span> | |
{% endif %} | |
</div> | |
</div> | |
<div class="application-body"> | |
<div class="application-meta"> | |
<span class="meta-item"> | |
<i class="icon">π </i> | |
Applied {{ application.date_applied.strftime('%B %d, %Y') }} | |
</span> | |
{% if application.job and application.job.seniority %} | |
<span class="meta-item"> | |
<i class="icon">πΌ</i> | |
{{ application.job.seniority }} | |
</span> | |
{% endif %} | |
</div> | |
{% if application.job %} | |
<p class="job-description"> | |
{{ application.job.description[:150] }}{% if application.job.description|length > 150 %}...{% endif %} | |
</p> | |
{% endif %} | |
</div> | |
<div class="application-footer"> | |
{% if application.job %} | |
<a href="{{ url_for('job_detail', job_id=application.job.id) }}" class="btn btn-outline btn-sm"> | |
<span class="btn-icon">ποΈ</span> View Job | |
</a> | |
{% endif %} | |
{% if application.extracted_features %} | |
<a href="{{ url_for('interview_page', job_id=application.job.id) }}" class="btn btn-primary btn-sm"> | |
<span class="btn-icon">π€</span> Take Interview | |
</a> | |
{% endif %} | |
</div> | |
</div> | |
{% endfor %} | |
</div> | |
{% else %} | |
<div class="empty-state"> | |
<div class="empty-state-icon">π</div> | |
<h3>No Applications Yet</h3> | |
<p>You haven't applied to any jobs yet. Start exploring opportunities!</p> | |
<a href="{{ url_for('jobs') }}" class="btn btn-primary"> | |
<span class="btn-icon">π</span> Browse Jobs | |
</a> | |
</div> | |
{% endif %} | |
</div> | |
<!-- Stats Section --> | |
{% if applications %} | |
<div class="applications-stats"> | |
<div class="stat-card"> | |
<div class="stat-number">{{ applications|length }}</div> | |
<div class="stat-label">Total Applications</div> | |
</div> | |
<div class="stat-card"> | |
<div class="stat-number">{{ applications|selectattr('status', 'equalto', 'pending')|list|length }}</div> | |
<div class="stat-label">Pending Review</div> | |
</div> | |
<div class="stat-card"> | |
<div class="stat-number">{{ applications|selectattr('extracted_features')|list|length }}</div> | |
<div class="stat-label">Ready for Interview</div> | |
</div> | |
</div> | |
{% endif %} | |
</section> | |
<style> | |
/* Section Header */ | |
.section-header { | |
text-align: center; | |
margin-bottom: 3rem; | |
} | |
.section-header h2 { | |
font-size: 2.5rem; | |
color: var(--primary); | |
margin-bottom: 0.5rem; | |
position: relative; | |
display: inline-block; | |
} | |
.section-header h2::after { | |
content: ''; | |
position: absolute; | |
bottom: -10px; | |
left: 50%; | |
transform: translateX(-50%); | |
width: 80px; | |
height: 3px; | |
background: linear-gradient(to right, var(--primary), var(--accent)); | |
} | |
.section-header p { | |
color: #666; | |
font-size: 1.1rem; | |
} | |
/* Interview Guidelines */ | |
.interview-guidelines { | |
background: linear-gradient(135deg, #f5f7ff 0%, #e8ecff 100%); | |
border-radius: 12px; | |
padding: 2rem; | |
margin: 2rem 0; | |
box-shadow: 0 5px 15px rgba(67, 97, 238, 0.1); | |
border: 1px solid rgba(67, 97, 238, 0.1); | |
} | |
.guidelines-header { | |
margin-bottom: 1.5rem; | |
} | |
.guidelines-header h3 { | |
color: var(--primary); | |
font-size: 1.5rem; | |
margin: 0; | |
display: flex; | |
align-items: center; | |
gap: 0.5rem; | |
} | |
.guidelines-header .icon { | |
font-size: 1.75rem; | |
} | |
.guidelines-content { | |
display: grid; | |
gap: 1rem; | |
} | |
.guideline-item { | |
display: flex; | |
align-items: flex-start; | |
gap: 1rem; | |
padding: 0.75rem; | |
background: white; | |
border-radius: 8px; | |
transition: all 0.3s ease; | |
} | |
.guideline-item:hover { | |
transform: translateX(5px); | |
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.05); | |
} | |
.guideline-icon { | |
font-size: 1.5rem; | |
min-width: 2rem; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
} | |
.guideline-text { | |
flex: 1; | |
line-height: 1.6; | |
} | |
.guideline-text strong { | |
color: var(--primary); | |
} | |
/* Applications Container */ | |
.applications-container { | |
margin: 3rem 0; | |
} | |
/* Applications Grid */ | |
.applications-grid { | |
display: grid; | |
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); | |
gap: 1.5rem; | |
} | |
/* Application Card */ | |
.application-card { | |
background: white; | |
border-radius: 12px; | |
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08); | |
position: relative; | |
transition: all 0.3s ease; | |
overflow: hidden; | |
display: flex; | |
flex-direction: column; | |
} | |
.application-card:hover { | |
transform: translateY(-5px); | |
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.12); | |
} | |
/* Status Badge */ | |
.card-status-badge { | |
position: absolute; | |
top: 1rem; | |
right: 1rem; | |
padding: 0.25rem 0.75rem; | |
border-radius: 20px; | |
font-size: 0.875rem; | |
font-weight: 600; | |
text-transform: uppercase; | |
} | |
.status-pending { | |
background-color: #fff3cd; | |
color: #856404; | |
} | |
.status-approved { | |
background-color: #d4edda; | |
color: #155724; | |
} | |
.status-rejected { | |
background-color: #f8d7da; | |
color: #721c24; | |
} | |
.status-interview-scheduled { | |
background-color: #d1ecf1; | |
color: #0c5460; | |
} | |
/* Application Header */ | |
.application-header { | |
padding: 1.5rem 1.5rem 0; | |
} | |
.application-header h3 { | |
color: var(--primary); | |
margin: 0 0 0.5rem 0; | |
font-size: 1.5rem; | |
} | |
.company-info { | |
display: flex; | |
flex-wrap: wrap; | |
gap: 1rem; | |
color: #666; | |
font-size: 0.95rem; | |
} | |
.company-name { | |
font-weight: 600; | |
color: var(--dark); | |
} | |
/* Application Body */ | |
.application-body { | |
padding: 1rem 1.5rem; | |
flex: 1; | |
} | |
.application-meta { | |
display: flex; | |
flex-wrap: wrap; | |
gap: 1rem; | |
margin-bottom: 1rem; | |
font-size: 0.9rem; | |
color: #666; | |
} | |
.meta-item { | |
display: flex; | |
align-items: center; | |
gap: 0.25rem; | |
} | |
.meta-item .icon { | |
font-size: 1rem; | |
} | |
.job-description { | |
color: #495057; | |
line-height: 1.6; | |
margin: 0; | |
} | |
/* Application Footer */ | |
.application-footer { | |
padding: 0 1.5rem 1.5rem; | |
display: flex; | |
gap: 0.75rem; | |
flex-wrap: wrap; | |
} | |
.btn-sm { | |
padding: 0.5rem 1rem; | |
font-size: 0.9rem; | |
} | |
/* Empty State */ | |
.empty-state { | |
text-align: center; | |
padding: 4rem 2rem; | |
background: #f8f9fa; | |
border-radius: 12px; | |
border: 2px dashed #dee2e6; | |
} | |
.empty-state-icon { | |
font-size: 4rem; | |
margin-bottom: 1rem; | |
opacity: 0.5; | |
} | |
.empty-state h3 { | |
color: var(--primary); | |
margin-bottom: 0.5rem; | |
} | |
.empty-state p { | |
color: #666; | |
margin-bottom: 2rem; | |
} | |
/* Stats Section */ | |
.applications-stats { | |
display: grid; | |
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); | |
gap: 1.5rem; | |
margin-top: 3rem; | |
} | |
.stat-card { | |
background: white; | |
padding: 2rem; | |
border-radius: 12px; | |
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08); | |
text-align: center; | |
transition: all 0.3s ease; | |
} | |
.stat-card:hover { | |
transform: translateY(-3px); | |
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12); | |
} | |
.stat-number { | |
font-size: 2.5rem; | |
font-weight: 700; | |
color: var(--primary); | |
margin-bottom: 0.5rem; | |
} | |
.stat-label { | |
color: #666; | |
font-size: 1rem; | |
} | |
/* Responsive Design */ | |
@media (max-width: 768px) { | |
.section-header h2 { | |
font-size: 2rem; | |
} | |
.interview-guidelines { | |
padding: 1.5rem; | |
} | |
.guidelines-header h3 { | |
font-size: 1.25rem; | |
} | |
.guideline-item { | |
padding: 0.5rem; | |
} | |
.guideline-icon { | |
font-size: 1.25rem; | |
} | |
.applications-grid { | |
grid-template-columns: 1fr; | |
} | |
.application-card { | |
margin-bottom: 1rem; | |
} | |
.applications-stats { | |
grid-template-columns: 1fr; | |
} | |
.stat-card { | |
padding: 1.5rem; | |
} | |
} | |
@media (max-width: 480px) { | |
.company-info { | |
flex-direction: column; | |
gap: 0.5rem; | |
} | |
.application-meta { | |
flex-direction: column; | |
gap: 0.5rem; | |
} | |
.application-footer { | |
flex-direction: column; | |
} | |
.application-footer .btn { | |
width: 100%; | |
justify-content: center; | |
} | |
} | |
/* Loading Animation */ | |
@keyframes shimmer { | |
0% { | |
background-position: -1000px 0; | |
} | |
100% { | |
background-position: 1000px 0; | |
} | |
} | |
.loading { | |
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%); | |
background-size: 1000px 100%; | |
animation: shimmer 2s infinite; | |
} | |
</style> | |
<script> | |
document.addEventListener('DOMContentLoaded', function() { | |
// Add animation to cards on page load | |
const cards = document.querySelectorAll('.application-card'); | |
cards.forEach((card, index) => { | |
setTimeout(() => { | |
card.style.opacity = '0'; | |
card.style.transform = 'translateY(20px)'; | |
card.style.animation = 'fadeInUp 0.5s ease forwards'; | |
}, index * 100); | |
}); | |
// Filter functionality (if needed in future) | |
const statusBadges = document.querySelectorAll('.card-status-badge'); | |
statusBadges.forEach(badge => { | |
badge.addEventListener('click', function() { | |
const status = this.textContent.trim(); | |
// Add filter logic here if needed | |
}); | |
}); | |
}); | |
// Animation keyframes | |
const style = document.createElement('style'); | |
style.textContent = ` | |
@keyframes fadeInUp { | |
to { | |
opacity: 1; | |
transform: translateY(0); | |
} | |
} | |
`; | |
document.head.appendChild(style); | |
</script> | |
{% endblock %} |