UXを向上
This commit is contained in:
@@ -151,8 +151,8 @@ REST API認証用のAPIキーを管理するモデル。
|
|||||||
|
|
||||||
| 機能 | 説明 |
|
| 機能 | 説明 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| ダッシュボード | 課題の統計情報、本日期限の課題、期限切れ課題、今週期限の課題を表示 |
|
| ダッシュボード | 課題の統計情報、本日期限の課題、期限切れ課題、今週期限の課題を表示。各統計カードをクリックすると対応するフィルタで課題一覧に遷移 |
|
||||||
| 課題一覧 | フィルタ付き(未完了/完了済み/期限切れ)で課題を一覧表示 |
|
| 課題一覧 | フィルタ付き(未完了/今日が期限/今週が期限/完了済み/期限切れ)で課題を一覧表示 |
|
||||||
| 課題登録 | タイトル、説明、教科、重要度、提出期限、通知設定を入力して新規登録 |
|
| 課題登録 | タイトル、説明、教科、重要度、提出期限、通知設定を入力して新規登録 |
|
||||||
| 課題編集 | 既存の課題情報を編集 |
|
| 課題編集 | 既存の課題情報を編集 |
|
||||||
| 課題削除 | 課題を論理削除 |
|
| 課題削除 | 課題を論理削除 |
|
||||||
|
|||||||
@@ -148,11 +148,19 @@ func (r *AssignmentRepository) Search(userID uint, queryStr, priority, filter st
|
|||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
||||||
|
endOfDay := startOfDay.AddDate(0, 0, 1)
|
||||||
|
weekLater := startOfDay.AddDate(0, 0, 7)
|
||||||
|
|
||||||
switch filter {
|
switch filter {
|
||||||
case "completed":
|
case "completed":
|
||||||
dbQuery = dbQuery.Where("is_completed = ?", true)
|
dbQuery = dbQuery.Where("is_completed = ?", true)
|
||||||
case "overdue":
|
case "overdue":
|
||||||
dbQuery = dbQuery.Where("is_completed = ? AND due_date < ?", false, now)
|
dbQuery = dbQuery.Where("is_completed = ? AND due_date < ?", false, now)
|
||||||
|
case "due_today":
|
||||||
|
dbQuery = dbQuery.Where("is_completed = ? AND due_date >= ? AND due_date < ?", false, startOfDay, endOfDay)
|
||||||
|
case "due_this_week":
|
||||||
|
dbQuery = dbQuery.Where("is_completed = ? AND due_date >= ? AND due_date < ?", false, startOfDay, weekLater)
|
||||||
default: // pending
|
default: // pending
|
||||||
dbQuery = dbQuery.Where("is_completed = ?", false)
|
dbQuery = dbQuery.Where("is_completed = ?", false)
|
||||||
}
|
}
|
||||||
@@ -195,12 +203,12 @@ type StatisticsFilter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AssignmentStatistics struct {
|
type AssignmentStatistics struct {
|
||||||
Total int64
|
Total int64
|
||||||
Completed int64
|
Completed int64
|
||||||
Pending int64
|
Pending int64
|
||||||
Overdue int64
|
Overdue int64
|
||||||
CompletedOnTime int64
|
CompletedOnTime int64
|
||||||
OnTimeCompletionRate float64
|
OnTimeCompletionRate float64
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubjectStatistics struct {
|
type SubjectStatistics struct {
|
||||||
@@ -338,4 +346,3 @@ func (r *AssignmentRepository) GetSubjectsByUserIDWithArchived(userID uint, incl
|
|||||||
err := query.Distinct("subject").Pluck("subject", &subjects).Error
|
err := query.Distinct("subject").Pluck("subject", &subjects).Error
|
||||||
return subjects, err
|
return subjects, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,19 +18,43 @@
|
|||||||
<!-- Tabs -->
|
<!-- Tabs -->
|
||||||
<ul class="nav nav-tabs border-0 mb-2" id="assignmentTabs">
|
<ul class="nav nav-tabs border-0 mb-2" id="assignmentTabs">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link py-2 rounded-0 border-0 {{if eq .filter " pending"}}fw-bold border-bottom border-dark
|
<a class="nav-link py-2 rounded-0 {{if eq .filter "pending"}}fw-bold border-bottom border-dark border-3
|
||||||
border-3{{else}}text-muted{{end}}" href="/assignments?filter=pending&q={{.query}}&priority={{.priority}}"
|
text-dark{{else}}border-0 text-muted{{end}}"
|
||||||
style="{{if eq .filter " pending"}}color: black !important;{{end}}">未完了</a>
|
href="/assignments?filter=pending&q={{.query}}&priority={{.priority}}">
|
||||||
|
未完了
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link py-2 rounded-0 border-0 {{if eq .filter " completed"}}fw-bold border-bottom border-dark
|
<a class="nav-link py-2 rounded-0 {{if eq .filter "due_today"}}fw-bold border-bottom border-dark border-3
|
||||||
border-3{{else}}text-muted{{end}}" href="/assignments?filter=completed&q={{.query}}&priority={{.priority}}"
|
text-dark{{else}}border-0 text-muted{{end}}"
|
||||||
style="{{if eq .filter " completed"}}color: black !important;{{end}}">完了済み</a>
|
href="/assignments?filter=due_today&q={{.query}}&priority={{.priority}}">
|
||||||
|
今日が期限
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link py-2 rounded-0 border-0 {{if eq .filter " overdue"}}fw-bold border-bottom border-dark
|
<a class="nav-link py-2 rounded-0 {{if eq .filter "due_this_week"}}fw-bold border-bottom border-dark border-3
|
||||||
border-3{{else}}text-muted{{end}}" href="/assignments?filter=overdue&q={{.query}}&priority={{.priority}}"
|
text-dark{{else}}border-0 text-muted{{end}}"
|
||||||
style="{{if eq .filter " overdue"}}color: black !important;{{end}}">期限切れ</a>
|
href="/assignments?filter=due_this_week&q={{.query}}&priority={{.priority}}">
|
||||||
|
今週が期限
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link py-2 rounded-0 {{if eq .filter "completed"}}fw-bold border-bottom border-dark border-3
|
||||||
|
text-dark{{else}}border-0 text-muted{{end}}"
|
||||||
|
href="/assignments?filter=completed&q={{.query}}&priority={{.priority}}">
|
||||||
|
完了済み
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link py-2 rounded-0 {{if eq .filter "overdue"}}fw-bold border-bottom border-dark border-3
|
||||||
|
text-dark{{else}}border-0 text-muted{{end}}"
|
||||||
|
href="/assignments?filter=overdue&q={{.query}}&priority={{.priority}}">
|
||||||
|
期限切れ
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<hr class="mt-0 mb-3 text-muted" style="opacity: 0.1;">
|
<hr class="mt-0 mb-3 text-muted" style="opacity: 0.1;">
|
||||||
|
|||||||
@@ -30,6 +30,20 @@
|
|||||||
.pagination-info {
|
.pagination-info {
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stats-table {
|
||||||
|
min-width: 700px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-table th,
|
||||||
|
.stats-table td {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-table th:first-child,
|
||||||
|
.stats-table td:first-child {
|
||||||
|
min-width: 120px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
@@ -174,7 +188,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-hover mb-0">
|
<table class="table table-hover mb-0 stats-table">
|
||||||
<thead class="table-light">
|
<thead class="table-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th>科目</th>
|
<th>科目</th>
|
||||||
@@ -206,7 +220,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-hover mb-0">
|
<table class="table table-hover mb-0 stats-table">
|
||||||
<thead class="table-light">
|
<thead class="table-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th>科目</th>
|
<th>科目</th>
|
||||||
|
|||||||
@@ -65,6 +65,16 @@
|
|||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dashboard-stat-card {
|
||||||
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-stat-card:hover {
|
||||||
|
transform: translateY(-4px);
|
||||||
|
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
@@ -83,56 +93,64 @@
|
|||||||
|
|
||||||
<div class="row g-4 mb-4">
|
<div class="row g-4 mb-4">
|
||||||
<div class="col-6 col-md-3">
|
<div class="col-6 col-md-3">
|
||||||
<div class="card bg-primary text-white h-100">
|
<a href="/assignments?filter=pending" class="text-decoration-none">
|
||||||
<div class="card-body">
|
<div class="card bg-primary text-white h-100 dashboard-stat-card">
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
<div class="card-body">
|
||||||
<div>
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
<h6 class="text-white-50">未完了の課題</h6>
|
<div>
|
||||||
<h2 class="mb-0">{{.stats.TotalPending}}</h2>
|
<h6 class="text-white-50">未完了の課題</h6>
|
||||||
|
<h2 class="mb-0">{{.stats.TotalPending}}</h2>
|
||||||
|
</div>
|
||||||
|
<i class="bi bi-list-task display-4 opacity-50"></i>
|
||||||
</div>
|
</div>
|
||||||
<i class="bi bi-list-task display-4 opacity-50"></i>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6 col-md-3">
|
<div class="col-6 col-md-3">
|
||||||
<div class="card bg-warning text-dark h-100">
|
<a href="/assignments?filter=due_today" class="text-decoration-none">
|
||||||
<div class="card-body">
|
<div class="card bg-warning text-dark h-100 dashboard-stat-card">
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
<div class="card-body">
|
||||||
<div>
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
<h6 class="text-dark-50">今日が期限</h6>
|
<div>
|
||||||
<h2 class="mb-0">{{.stats.DueToday}}</h2>
|
<h6 class="text-dark-50">今日が期限</h6>
|
||||||
|
<h2 class="mb-0">{{.stats.DueToday}}</h2>
|
||||||
|
</div>
|
||||||
|
<i class="bi bi-calendar-event display-4 opacity-50"></i>
|
||||||
</div>
|
</div>
|
||||||
<i class="bi bi-calendar-event display-4 opacity-50"></i>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6 col-md-3">
|
<div class="col-6 col-md-3">
|
||||||
<div class="card bg-info text-white h-100">
|
<a href="/assignments?filter=due_this_week" class="text-decoration-none">
|
||||||
<div class="card-body">
|
<div class="card bg-info text-white h-100 dashboard-stat-card">
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
<div class="card-body">
|
||||||
<div>
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
<h6 class="text-white-50">今週が期限</h6>
|
<div>
|
||||||
<h2 class="mb-0">{{.stats.DueThisWeek}}</h2>
|
<h6 class="text-white-50">今週が期限</h6>
|
||||||
|
<h2 class="mb-0">{{.stats.DueThisWeek}}</h2>
|
||||||
|
</div>
|
||||||
|
<i class="bi bi-calendar-week display-4 opacity-50"></i>
|
||||||
</div>
|
</div>
|
||||||
<i class="bi bi-calendar-week display-4 opacity-50"></i>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6 col-md-3">
|
<div class="col-6 col-md-3">
|
||||||
<div class="card bg-danger text-white h-100">
|
<a href="/assignments?filter=overdue" class="text-decoration-none">
|
||||||
<div class="card-body">
|
<div class="card bg-danger text-white h-100 dashboard-stat-card">
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
<div class="card-body">
|
||||||
<div>
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
<h6 class="text-white-50">期限切れ</h6>
|
<div>
|
||||||
<h2 class="mb-0">{{.stats.Overdue}}</h2>
|
<h6 class="text-white-50">期限切れ</h6>
|
||||||
|
<h2 class="mb-0">{{.stats.Overdue}}</h2>
|
||||||
|
</div>
|
||||||
|
<i class="bi bi-exclamation-triangle display-4 opacity-50"></i>
|
||||||
</div>
|
</div>
|
||||||
<i class="bi bi-exclamation-triangle display-4 opacity-50"></i>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user