Flask_web-template/app/templates/main/index.html
2024-10-28 23:34:40 +08:00

397 lines
21 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block content %}
<div class="container py-4">
{% if current_user.is_authenticated %}
<!-- 用戶歡迎卡片 -->
<div class="card bg-primary text-white shadow-sm mb-4">
<div class="card-body">
<div class="row align-items-center">
<div class="col-auto">
{% if current_user.avatar_path %}
<img src="{{ url_for('static', filename=current_user.avatar_path) }}"
class="rounded-circle border border-2 border-white"
style="width: 80px; height: 80px; object-fit: cover;">
{% else %}
<div class="avatar-circle bg-white text-primary d-flex align-items-center justify-content-center"
style="width: 80px; height: 80px; border-radius: 50%; font-size: 2rem;">
{{ current_user.username[0].upper() }}
</div>
{% endif %}
</div>
<div class="col">
<h4 class="mb-1">歡迎回來,{{ current_user.username }}</h4>
<div class="small">
<i class="bi bi-clock"></i> 上次登入時間:{{
current_user.last_login.strftime('%Y-%m-%d %H:%M') if current_user.last_login else '首次登入'
}}
</div>
<div class="mt-2">
<a href="{{ url_for('auth.profile') }}" class="btn btn-outline-light btn-sm">
<i class="bi bi-person-gear"></i> 管理個人資料
</a>
<a href="{{ url_for('post.create') }}" class="btn btn-outline-light btn-sm ms-2">
<i class="bi bi-plus-lg"></i> 發布文章
</a>
</div>
</div>
<div class="col-md-3 text-end">
<div class="border-start border-white-50 ps-3">
<div class="mb-2">
<div class="small text-white-50">我的文章</div>
<div class="h4 mb-0">{{ user_stats.posts_count }}</div>
</div>
<div>
<div class="small text-white-50">收到的讚</div>
<div class="h4 mb-0">{{ user_stats.received_likes }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endif %}
<div class="row g-4">
<!-- 左側主要內容區 -->
<div class="col-lg-8">
<!-- 熱門文章輪播 -->
{% if latest_posts %}
<div class="card shadow-sm mb-4">
<div class="card-header bg-white d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">
<i class="bi bi-star-fill text-warning"></i> 精選文章
</h5>
<div>
<button class="btn btn-sm btn-outline-secondary me-1" data-bs-target="#featuredPosts"
data-bs-slide="prev">
<i class="bi bi-chevron-left"></i>
</button>
<button class="btn btn-sm btn-outline-secondary" data-bs-target="#featuredPosts"
data-bs-slide="next">
<i class="bi bi-chevron-right"></i>
</button>
</div>
</div>
<div class="card-body p-0">
<div id="featuredPosts" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
{% for post in latest_posts[:3] %}
<div class="carousel-item {% if loop.first %}active{% endif %}">
<div class="p-4" style="height: 400px; overflow: hidden;">
<div class="d-flex flex-column h-100">
<!-- 作者資訊 -->
<div class="d-flex align-items-center mb-3">
{% if post.author.avatar_path %}
<img src="{{ url_for('static', filename=post.author.avatar_path) }}"
class="rounded-circle me-2"
style="width: 40px; height: 40px; object-fit: cover;">
{% else %}
<div class="avatar-circle bg-primary text-white d-flex align-items-center justify-content-center me-2"
style="width: 40px; height: 40px; border-radius: 50%; font-size: 1.2rem;">
{{ post.author.username[0].upper() }}
</div>
{% endif %}
<div>
<div class="fw-medium">{{ post.author.username }}</div>
<div class="small text-muted">
{{ post.created_at.strftime('%Y-%m-%d %H:%M') }}
</div>
</div>
</div>
<!-- 文章內容 -->
<div class="flex-grow-1 overflow-hidden">
<h4 class="card-title mb-3">
<a href="{{ url_for('post.show', id=post.id) }}"
class="text-decoration-none text-dark">
{{ post.title }}
</a>
</h4>
<p class="card-text text-muted"
style="display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden;">
{{ post.content }}
</p>
</div>
<!-- 文章統計 -->
<div class="d-flex justify-content-between align-items-center mt-3 pt-3 border-top">
<div class="d-flex align-items-center text-muted">
<div class="me-3">
<i class="bi bi-heart-fill text-danger"></i>
<span class="ms-1">{{ post.like_count }}</span>
</div>
<div class="me-3">
<i class="bi bi-chat-fill"></i>
<span class="ms-1">{{ post.comments_count }}</span>
</div>
<div>
<i class="bi bi-eye-fill"></i>
<span class="ms-1">{{
post.view_count if post.view_count else 0
}}</span>
</div>
</div>
<a href="{{ url_for('post.show', id=post.id) }}"
class="btn btn-primary btn-sm">
閱讀更多 <i class="bi bi-arrow-right"></i>
</a>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
<div class="carousel-indicators" style="bottom: 0;">
{% for post in latest_posts[:3] %}
<button type="button"
data-bs-target="#featuredPosts"
data-bs-slide-to="{{ loop.index0 }}"
class="{% if loop.first %}active{% endif %}"
style="background-color: #0d6efd;"></button>
{% endfor %}
</div>
</div>
</div>
</div>
{% endif %}
<!-- 最新文章列表 -->
<div class="card shadow-sm">
<div class="card-header bg-white d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">最新文章</h5>
<a href="{{ url_for('post.index') }}" class="btn btn-outline-primary btn-sm">
查看全部 <i class="bi bi-arrow-right"></i>
</a>
</div>
<div class="card-body">
{% if latest_posts %}
{% for post in latest_posts %}
<div class="card mb-3 border-0">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center mb-2">
<div class="d-flex align-items-center">
{% if post.author.avatar_path %}
<img src="{{ url_for('static', filename=post.author.avatar_path) }}"
class="rounded-circle me-2"
style="width: 32px; height: 32px; object-fit: cover;">
{% else %}
<div class="avatar-circle bg-primary text-white d-flex align-items-center justify-content-center me-2"
style="width: 32px; height: 32px; border-radius: 50%; font-size: 1rem;">
{{ post.author.username[0].upper() }}
</div>
{% endif %}
<div>
<div class="fw-medium">{{ post.author.username }}</div>
<small class="text-muted">{{
post.created_at.strftime('%Y-%m-%d %H:%M')
}}</small>
</div>
</div>
<div class="d-flex align-items-center text-muted small">
<div class="me-3">
<i class="bi bi-heart-fill text-danger"></i>
{{ post.like_count }}
</div>
<div>
<i class="bi bi-chat-fill"></i>
{{ post.comments_count }}
</div>
</div>
</div>
<h6 class="card-title">
<a href="{{ url_for('post.show', id=post.id) }}" class="text-decoration-none text-dark">
{{ post.title }}
</a>
</h6>
<p class="card-text small text-muted">
{{ post.content[:150] }}{% if post.content|length > 150 %}...{% endif %}
</p>
<div class="d-flex justify-content-between align-items-center">
<a href="{{ url_for('post.show', id=post.id) }}" class="btn btn-outline-primary btn-sm">
閱讀更多
</a>
{% if current_user == post.author %}
<div class="btn-group">
<a href="{{ url_for('post.edit', id=post.id) }}"
class="btn btn-outline-secondary btn-sm">
<i class="bi bi-pencil"></i> 編輯
</a>
<button type="button" class="btn btn-outline-danger btn-sm" data-bs-toggle="modal"
data-bs-target="#deleteModal" data-post-id="{{ post.id }}">
<i class="bi bi-trash"></i>
</button>
</div>
{% endif %}
</div>
</div>
</div>
{% if not loop.last %}
{% endif %}
{% endfor %}
{% else %}
<div class="text-center py-5">
<i class="bi bi-journal-text display-4 text-muted"></i>
<p class="mt-3 mb-0">目前還沒有文章</p>
{% if current_user.is_authenticated %}
<a href="{{ url_for('post.create') }}" class="btn btn-primary mt-3">
<i class="bi bi-plus-lg"></i> 發布第一篇文章
</a>
{% endif %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- 右側資訊欄 -->
<div class="col-lg-4">
<!-- 系統資訊卡片 -->
<div class="card shadow-sm mb-4">
<div class="card-header bg-white">
<h5 class="card-title mb-0">
<i class="bi bi-info-circle-fill text-primary"></i> 系統資訊
</h5>
</div>
<div class="card-body">
<div class="list-group list-group-flush">
<div class="list-group-item px-0">
<div class="d-flex justify-content-between align-items-center">
<div>
<i class="bi bi-people"></i> 總會員數
</div>
<span class="badge bg-primary rounded-pill">{{ total_users }}</span>
</div>
</div>
<div class="list-group-item px-0">
<div class="d-flex justify-content-between align-items-center">
<div>
<i class="bi bi-person-plus"></i> 本月新增
</div>
<span class="badge bg-success rounded-pill">{{ new_users_this_month }}</span>
</div>
</div>
<div class="list-group-item px-0">
<div class="d-flex justify-content-between align-items-center">
<div>
<i class="bi bi-file-text"></i> 總文章數
</div>
<span class="badge bg-info rounded-pill">{{ total_posts }}</span>
</div>
</div>
<div class="list-group-item px-0">
<div class="d-flex justify-content-between align-items-center">
<div>
<i class="bi bi-clock-history"></i> 最後更新
</div>
<small class="text-muted">{{ last_update }}</small>
</div>
</div>
</div>
</div>
</div>
<!-- 活躍用戶卡片 -->
<div class="card shadow-sm mb-4">
<div class="card-header bg-white">
<h5 class="card-title mb-0">
<i class="bi bi-star-fill text-warning"></i> 活躍用戶
</h5>
</div>
<div class="card-body">
<div class="d-flex flex-wrap gap-2">
{% for user in active_users[:12] %}
<a href="#" class="text-decoration-none" data-bs-toggle="tooltip" title="{{ user.username }}">
{% if user.avatar_path %}
<img src="{{ url_for('static', filename=user.avatar_path) }}"
class="rounded-circle border"
style="width: 40px; height: 40px; object-fit: cover;">
{% else %}
<div class="avatar-circle bg-primary text-white d-flex align-items-center justify-content-center"
style="width: 40px; height: 40px; border-radius: 50%; font-size: 1.2rem;">
{{ user.username[0].upper() }}
</div>
{% endif %}
</a>
{% endfor %}
</div>
</div>
</div>
<!-- 快速連結卡片 -->
<div class="card shadow-sm">
<div class="card-header bg-white">
<h5 class="card-title mb-0">
<i class="bi bi-link-45deg text-primary"></i> 快速連結
</h5>
</div>
<div class="card-body">
<div class="d-grid gap-2">
{% if current_user.is_authenticated %}
<a href="{{ url_for('post.create') }}" class="btn btn-primary">
<i class="bi bi-plus-lg"></i> 發布文章
</a>
{% endif %}
<a href="{{ url_for('post.index') }}" class="btn btn-outline-primary">
<i class="bi bi-journal-text"></i> 所有文章
</a>
<a href="{{ url_for('main.members') }}" class="btn btn-outline-primary">
<i class="bi bi-people"></i> 會員列表
</a>
{% if not current_user.is_authenticated %}
<a href="{{ url_for('auth.login') }}" class="btn btn-outline-primary">
<i class="bi bi-box-arrow-in-right"></i> 登入系統
</a>
<a href="{{ url_for('auth.register') }}" class="btn btn-outline-primary">
<i class="bi bi-person-plus"></i> 註冊帳號
</a>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 刪除文章確認對話框 -->
<div class="modal fade" id="deleteModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">確認刪除</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p class="mb-0">確定要刪除這篇文章嗎?此操作無法復原。</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<form id="deleteForm" method="post" style="display: inline;">
<button type="submit" class="btn btn-danger">確定刪除</button>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
// 初始化工具提示
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
// 處理刪除文章
document.getElementById('deleteModal').addEventListener('show.bs.modal', function (event) {
const button = event.relatedTarget;
const postId = button.getAttribute('data-post-id');
const form = document.getElementById('deleteForm');
form.action = `/posts/${postId}/delete`;
});
</script>
{% endblock %}