Ptul2x5's picture
Update database restore
80eb435 verified
{% extends "base.html" %}
{% block title %}Student Feedback Sentiment Analysis{% endblock %}
{% block page_title %}Student Feedback Analysis{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-8">
<!-- Analysis Mode Toggle -->
<div class="card shadow-sm mb-4">
<div class="card-body py-3">
<div class="d-flex justify-content-center">
<div class="btn-group" role="group" aria-label="Analysis mode">
<input type="radio" class="btn-check" name="analysisMode" id="singleMode" value="single" checked>
<label class="btn btn-outline-secondary" for="singleMode">
<i class="fas fa-keyboard me-1"></i>Nhập đơn lẻ
</label>
<input type="radio" class="btn-check" name="analysisMode" id="csvMode" value="csv">
<label class="btn btn-outline-secondary" for="csvMode">
<i class="fas fa-file-csv me-1"></i>Upload CSV
</label>
</div>
</div>
</div>
</div>
<!-- Single Input Form -->
<div id="singleFeedbackForm" class="card shadow-lg">
<div class="card-header bg-primary text-white">
<h3 class="card-title mb-0">
<i class="fas fa-comment-dots me-2"></i>
Nhập Feedback
</h3>
</div>
<div class="card-body">
<form id="feedbackForm">
<div class="mb-3">
<label for="feedbackText" class="form-label fw-bold">
<i class="fas fa-edit me-2"></i>
Feedback của bạn:
</label>
<textarea
class="form-control"
id="feedbackText"
rows="5"
placeholder="Nhập feedback về giảng viên, chương trình đào tạo, cơ sở vật chất..."
required
></textarea>
<div class="form-text">
<i class="fas fa-info-circle me-1"></i>
Nhập feedback bằng tiếng Việt để có kết quả chính xác nhất
</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary btn-lg" id="analyzeBtn">
<i class="fas fa-search me-2"></i>
Phân Tích Feedback
</button>
</div>
</form>
</div>
</div>
<!-- CSV Upload Form -->
<div id="csvUploadForm" class="card shadow-lg" style="display: none;">
<div class="card-header bg-primary text-white">
<h3 class="card-title mb-0">
<i class="fas fa-file-csv me-2"></i>
Upload File CSV
</h3>
</div>
<div class="card-body">
<form id="csvForm" enctype="multipart/form-data">
<div class="mb-3">
<label for="csvFile" class="form-label fw-bold">
<i class="fas fa-upload me-1"></i>
Chọn file CSV:
</label>
<input type="file" id="csvFile" class="form-control" accept=".csv" required>
<div class="form-text">
<i class="fas fa-info-circle me-1"></i>
File CSV phải có cột chứa feedback (tên cột: 'feedback', 'text', 'content' hoặc 'comment')
</div>
<div class="form-text">
<i class="fas fa-exclamation-triangle me-1 text-warning"></i>
<small>File phải được mã hóa UTF-8 và có header (tên cột)</small>
</div>
<div class="form-text">
<i class="fas fa-download me-1 text-success"></i>
<a href="#" id="downloadTemplate" class="text-decoration-none">
<small>Tải file CSV mẫu</small>
</a>
</div>
</div>
<div class="mb-3">
<div class="d-flex align-items-center">
<i class="fas fa-exclamation-triangle me-2 text-warning"></i>
<small class="text-muted">Quá trình phân tích có thể mất vài phút tùy thuộc vào số lượng feedback</small>
</div>
</div>
<div class="d-grid">
<button type="submit" id="analyzeCsvBtn" class="btn btn-primary btn-lg">
<i class="fas fa-chart-bar me-2"></i>
Phân Tích File CSV
</button>
</div>
</form>
</div>
</div>
<!-- Loading Spinner -->
<div id="loadingSpinner" class="text-center mb-4" style="display: none;">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="mt-2 text-muted">Đang phân tích feedback...</p>
</div>
<!-- Results -->
<div id="results" style="display: none;">
<!-- Sentiment Result -->
<div class="card shadow-lg mb-3">
<div class="card-header bg-primary text-white">
<h4 class="card-title mb-0">
<i class="fas fa-heart me-2"></i>
Phân loại cảm xúc của feedback
</h4>
</div>
<div class="card-body">
<div class="row align-items-center">
<div class="col-md-3">
<div id="sentimentIcon" class="text-center">
<i class="fas fa-smile fa-3x"></i>
</div>
</div>
<div class="col-md-9">
<h3 id="sentimentResult" class="mb-2"></h3>
<p id="sentimentDescription" class="text-muted mb-0"></p>
</div>
</div>
</div>
</div>
<!-- Topic Result -->
<div class="card shadow-lg mb-4">
<div class="card-header bg-primary text-white">
<h4 class="card-title mb-0">
<i class="fas fa-tags me-2"></i>
Chủ đề liên quan đến nội dung feedback
</h4>
</div>
<div class="card-body">
<div class="row align-items-center">
<div class="col-md-3">
<div id="topicIcon" class="text-center">
<i class="fas fa-user-tie fa-3x"></i>
</div>
</div>
<div class="col-md-9">
<h3 id="topicResult" class="mb-2"></h3>
<p id="topicDescription" class="text-muted mb-0"></p>
</div>
</div>
</div>
</div>
<!-- Original Text -->
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h5 class="card-title mb-0">
<i class="fas fa-quote-left me-2"></i>
Feedback Gốc
</h5>
</div>
<div class="card-body">
<blockquote class="blockquote mb-0">
<p id="originalText" class="mb-0"></p>
</blockquote>
</div>
</div>
</div>
<!-- Error Message -->
<div id="errorMessage" class="alert alert-danger" style="display: none;">
<i class="fas fa-exclamation-triangle me-2"></i>
<span id="errorText"></span>
</div>
<!-- Time Filter -->
<div id="timeFilter" class="card shadow-lg mt-4">
<div class="card-header">
<h5 class="card-title mb-0">
<i class="fas fa-filter me-2"></i>
Lọc theo thời gian
</h5>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label fw-bold">
<i class="fas fa-clock me-1"></i>
Khoảng thời gian:
</label>
</div>
<div class="row mb-3 g-2">
<div class="col">
<input type="radio" class="btn-check" name="timeFilter" id="allTime" value="all" checked>
<label class="btn btn-outline-secondary w-100 text-center d-flex flex-column align-items-center justify-content-center" for="allTime" style="height: 60px;">
<i class="fas fa-globe mb-1"></i>
<small>Tất cả</small>
</label>
</div>
<div class="col">
<input type="radio" class="btn-check" name="timeFilter" id="today" value="today">
<label class="btn btn-outline-secondary w-100 text-center d-flex flex-column align-items-center justify-content-center" for="today" style="height: 60px;">
<i class="fas fa-calendar-day mb-1"></i>
<small>Hôm nay</small>
</label>
</div>
<div class="col">
<input type="radio" class="btn-check" name="timeFilter" id="lastWeek" value="week">
<label class="btn btn-outline-secondary w-100 text-center d-flex flex-column align-items-center justify-content-center" for="lastWeek" style="height: 60px;">
<i class="fas fa-calendar-week mb-1"></i>
<small>7 ngày trước</small>
</label>
</div>
<div class="col">
<input type="radio" class="btn-check" name="timeFilter" id="lastMonth" value="month">
<label class="btn btn-outline-secondary w-100 text-center d-flex flex-column align-items-center justify-content-center" for="lastMonth" style="height: 60px;">
<i class="fas fa-calendar-alt mb-1"></i>
<small>30 ngày trước</small>
</label>
</div>
<div class="col">
<input type="radio" class="btn-check" name="timeFilter" id="custom" value="custom">
<label class="btn btn-outline-secondary w-100 text-center d-flex flex-column align-items-center justify-content-center" for="custom" style="height: 60px;">
<i class="fas fa-calendar-check mb-1"></i>
<small>Tùy chọn</small>
</label>
</div>
</div>
<div id="customDateRange" class="d-flex gap-2 mb-3" style="display: none !important;">
<input type="date" id="startDate" class="form-control form-control-sm flex-fill" placeholder="Từ ngày">
<input type="date" id="endDate" class="form-control form-control-sm flex-fill" placeholder="Đến ngày">
</div>
<div class="mt-3">
<div class="d-flex align-items-center">
<i class="fas fa-info-circle me-2"></i>
<span id="filterInfo" class="small">Hiển thị tất cả feedback</span>
</div>
</div>
</div>
</div>
<!-- Feedback History -->
<div id="feedbackHistory" class="card shadow-lg mt-4">
<div class="card-header">
<h4 class="card-title mb-0 d-flex align-items-center">
<i class="fas fa-history me-2"></i>
Lịch sử Feedback
<span id="feedbackCount" class="badge bg-light text-dark ms-2">0</span>
</h4>
</div>
<div class="card-body">
<div id="historyLoading" class="text-center py-3" style="display: none;">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="mt-2 text-muted">Đang tải lịch sử...</p>
</div>
<div id="historyContent">
<!-- History items will be loaded here -->
</div>
<div id="historyPagination" class="d-flex justify-content-center mt-3">
<!-- Pagination will be loaded here -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_scripts %}
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
<style>
/* Custom styles for time filter */
#timeFilter .btn {
transition: all 0.3s ease;
font-weight: 500;
min-height: 60px;
border-radius: 8px;
white-space: normal;
line-height: 1.2;
}
#timeFilter .btn:hover {
background-color: var(--gray-100);
}
#timeFilter .btn-check:checked + .btn {
background-color: var(--gray-400);
border-color: var(--gray-400);
color: #F3F4F6;
}
#timeFilter .btn i {
font-size: 1.1rem;
}
#timeFilter .btn small {
font-size: 0.75rem;
font-weight: 500;
}
#timeFilter .form-control {
transition: all 0.3s ease;
}
#timeFilter .form-control:focus {
border-color: var(--gray-400);
box-shadow: 0 0 0 0.2rem rgba(107, 114, 128, 0.25);
}
#customDateRange {
display: none;
}
#customDateRange.show {
display: flex;
}
#feedbackHistory .card-body {
padding: 1.5rem;
}
/* Smooth transitions for filter info */
#filterInfo {
transition: all 0.3s ease;
}
/* Enhanced card shadows */
.card {
transition: all 0.3s ease;
}
.card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0,0,0,0.1) !important;
}
</style>
{% endblock %}