feat: 初始版本,圆角主题与首次管理员引导
This commit is contained in:
7
app/templates/activities/detail.html
Normal file
7
app/templates/activities/detail.html
Normal file
@@ -0,0 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}活动详情{% endblock %}
|
||||
{% block content %}
|
||||
<h3>{{ activity.title }}</h3>
|
||||
<p>{{ activity.description }}</p>
|
||||
<a class="btn btn-primary" href="{{ url_for('activities.submit', act_id=activity.id) }}">投稿</a>
|
||||
{% endblock %}
|
||||
10
app/templates/activities/list.html
Normal file
10
app/templates/activities/list.html
Normal file
@@ -0,0 +1,10 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}活动{% endblock %}
|
||||
{% block content %}
|
||||
<h3>活动</h3>
|
||||
<ul>
|
||||
{% for a in activities %}
|
||||
<li><a href="{{ url_for('activities.detail', act_id=a.id) }}">{{ a.title }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
10
app/templates/activities/submit.html
Normal file
10
app/templates/activities/submit.html
Normal file
@@ -0,0 +1,10 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}投稿{% endblock %}
|
||||
{% block content %}
|
||||
<h3>向 {{ activity.title }} 投稿</h3>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<div class="mb-3"><label class="form-label">图片</label><input class="form-control" name="images" type="file" accept="image/*" multiple required></div>
|
||||
<button class="btn btn-primary" type="submit">提交</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
31
app/templates/admin/activities.html
Normal file
31
app/templates/admin/activities.html
Normal file
@@ -0,0 +1,31 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}活动管理{% endblock %}
|
||||
{% block content %}
|
||||
<h3>活动管理</h3>
|
||||
<form method="post" class="mb-3">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<div class="mb-2"><input class="form-control" name="title" placeholder="标题" required></div>
|
||||
<div class="mb-2"><input class="form-control" name="theme" placeholder="主题"></div>
|
||||
<div class="mb-2"><textarea class="form-control" name="description" placeholder="描述"></textarea></div>
|
||||
<button class="btn btn-primary" type="submit">创建</button>
|
||||
</form>
|
||||
<table class="table">
|
||||
<tr><th>标题</th><th>状态</th><th>操作</th></tr>
|
||||
{% for a in activities %}
|
||||
<tr>
|
||||
<td>{{ a.title }}</td>
|
||||
<td>{{ a.status.value }}</td>
|
||||
<td>
|
||||
<form method="post" action="{{ url_for('admin.publish_activity', act_id=a.id) }}" style="display:inline">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<button class="btn btn-success">发布</button>
|
||||
</form>
|
||||
<form method="post" action="{{ url_for('admin.close_activity', act_id=a.id) }}" style="display:inline">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<button class="btn btn-warning">关闭</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
15
app/templates/admin/dashboard.html
Normal file
15
app/templates/admin/dashboard.html
Normal file
@@ -0,0 +1,15 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}管理员{% endblock %}
|
||||
{% block content %}
|
||||
<h3>管理员仪表盘</h3>
|
||||
<div class="row">
|
||||
<div class="col">待审核注册:{{ pending_users }}</div>
|
||||
<div class="col">待审核作品:{{ pending_posts }}</div>
|
||||
<div class="col">待审核投稿:{{ pending_subs }}</div>
|
||||
</div>
|
||||
<hr>
|
||||
<a class="btn btn-link" href="{{ url_for('admin.review_users') }}">注册审核</a>
|
||||
<a class="btn btn-link" href="{{ url_for('admin.review_posts') }}">作品审核</a>
|
||||
<a class="btn btn-link" href="{{ url_for('admin.review_submissions') }}">投稿审核</a>
|
||||
<a class="btn btn-link" href="{{ url_for('admin.manage_activities') }}">活动管理</a>
|
||||
{% endblock %}
|
||||
24
app/templates/admin/reviews_posts.html
Normal file
24
app/templates/admin/reviews_posts.html
Normal file
@@ -0,0 +1,24 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}作品审核{% endblock %}
|
||||
{% block content %}
|
||||
<h3>作品审核</h3>
|
||||
<table class="table">
|
||||
<tr><th>标题</th><th>作者</th><th>操作</th></tr>
|
||||
{% for p in posts %}
|
||||
<tr>
|
||||
<td>{{ p.title }}</td>
|
||||
<td>{{ p.user.username }}</td>
|
||||
<td>
|
||||
<form method="post" action="{{ url_for('admin.approve_post', post_id=p.id) }}" style="display:inline">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<button class="btn btn-success">通过</button>
|
||||
</form>
|
||||
<form method="post" action="{{ url_for('admin.reject_post', post_id=p.id) }}" style="display:inline">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<button class="btn btn-danger">拒绝</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
24
app/templates/admin/reviews_submissions.html
Normal file
24
app/templates/admin/reviews_submissions.html
Normal file
@@ -0,0 +1,24 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}投稿审核{% endblock %}
|
||||
{% block content %}
|
||||
<h3>投稿审核</h3>
|
||||
<table class="table">
|
||||
<tr><th>活动</th><th>用户</th><th>操作</th></tr>
|
||||
{% for s in submissions %}
|
||||
<tr>
|
||||
<td>{{ s.activity.title }}</td>
|
||||
<td>{{ s.user_id }}</td>
|
||||
<td>
|
||||
<form method="post" action="{{ url_for('admin.approve_submission', sub_id=s.id) }}" style="display:inline">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<button class="btn btn-success">通过</button>
|
||||
</form>
|
||||
<form method="post" action="{{ url_for('admin.reject_submission', sub_id=s.id) }}" style="display:inline">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<button class="btn btn-danger">拒绝</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
24
app/templates/admin/reviews_users.html
Normal file
24
app/templates/admin/reviews_users.html
Normal file
@@ -0,0 +1,24 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}注册审核{% endblock %}
|
||||
{% block content %}
|
||||
<h3>注册审核</h3>
|
||||
<table class="table">
|
||||
<tr><th>用户名</th><th>邮箱</th><th>操作</th></tr>
|
||||
{% for u in users %}
|
||||
<tr>
|
||||
<td>{{ u.username }}</td>
|
||||
<td>{{ u.email }}</td>
|
||||
<td>
|
||||
<form method="post" action="{{ url_for('admin.approve_user', user_id=u.id) }}" style="display:inline">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<button class="btn btn-success">通过</button>
|
||||
</form>
|
||||
<form method="post" action="{{ url_for('admin.reject_user', user_id=u.id) }}" style="display:inline">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<button class="btn btn-danger">拒绝</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
11
app/templates/auth/login.html
Normal file
11
app/templates/auth/login.html
Normal file
@@ -0,0 +1,11 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}登录{% endblock %}
|
||||
{% block content %}
|
||||
<h3 class="mb-3">登录</h3>
|
||||
<form class="card p-3" method="post">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<div class="mb-3"><label class="form-label">邮箱</label><input class="form-control" name="email" type="email" required></div>
|
||||
<div class="mb-3"><label class="form-label">密码</label><input class="form-control" name="password" type="password" required></div>
|
||||
<button class="btn btn-brand" type="submit">登录</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
13
app/templates/auth/register.html
Normal file
13
app/templates/auth/register.html
Normal file
@@ -0,0 +1,13 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}注册{% endblock %}
|
||||
{% block content %}
|
||||
<h3 class="mb-3">注册</h3>
|
||||
<form class="card p-3" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<div class="mb-3"><label class="form-label">邮箱</label><input class="form-control" name="email" type="email" required></div>
|
||||
<div class="mb-3"><label class="form-label">用户名</label><input class="form-control" name="username" required></div>
|
||||
<div class="mb-3"><label class="form-label">密码</label><input class="form-control" name="password" type="password" required></div>
|
||||
<div class="mb-3"><label class="form-label">学生身份照片</label><input class="form-control" name="identity_photo" type="file" accept="image/*" required></div>
|
||||
<button class="btn btn-brand" type="submit">提交</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
43
app/templates/base.html
Normal file
43
app/templates/base.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}摄影社论坛{% endblock %}</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='theme.css') }}" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-white mb-3 mt-2 px-3">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="{{ url_for('feed.discover') }}">摄影社</a>
|
||||
<div>
|
||||
<a class="btn btn-link" href="{{ url_for('feed.discover') }}">发现</a>
|
||||
{% if current_user.is_authenticated %}
|
||||
<a class="btn btn-link" href="{{ url_for('feed.following') }}">关注</a>
|
||||
<a class="btn btn-link" href="{{ url_for('users.profile', user_id=current_user.id) }}">我的主页</a>
|
||||
<a class="btn btn-link" href="{{ url_for('users.notifications') }}">通知</a>
|
||||
<a class="btn btn-link" href="{{ url_for('posts.create') }}">发布作品</a>
|
||||
<a class="btn btn-link" href="{{ url_for('activities.list_activities') }}">活动</a>
|
||||
{% if current_user.role == 'admin' %}
|
||||
<a class="btn btn-link" href="{{ url_for('admin.dashboard') }}">管理员</a>
|
||||
{% endif %}
|
||||
<a class="btn btn-link" href="{{ url_for('auth.logout') }}">退出</a>
|
||||
{% else %}
|
||||
<a class="btn btn-link" href="{{ url_for('auth.login') }}">登录</a>
|
||||
<a class="btn btn-brand" href="{{ url_for('auth.register') }}">注册</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container">
|
||||
{% with messages = get_flashed_messages() %}
|
||||
{% if messages %}
|
||||
<div class="alert alert-info">{{ messages[0] }}</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
20
app/templates/feed/discover.html
Normal file
20
app/templates/feed/discover.html
Normal file
@@ -0,0 +1,20 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}发现{% endblock %}
|
||||
{% block content %}
|
||||
<h3 class="mb-3">发现</h3>
|
||||
<div class="card-grid">
|
||||
{% for p in posts %}
|
||||
<div class="card">
|
||||
{% set first = p.images[0] if p.images %}
|
||||
{% if first %}
|
||||
<a href="{{ url_for('posts.detail', post_id=p.id) }}">
|
||||
<img class="photo-thumb" src="{{ url_for('main.uploads', filename=first.web_path.split('uploads\\')[-1]) }}" alt="{{ p.title }}" />
|
||||
</a>
|
||||
{% endif %}
|
||||
<div class="p-3">
|
||||
<a class="text-decoration-none" href="{{ url_for('posts.detail', post_id=p.id) }}">{{ p.title }}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
20
app/templates/feed/following.html
Normal file
20
app/templates/feed/following.html
Normal file
@@ -0,0 +1,20 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}关注{% endblock %}
|
||||
{% block content %}
|
||||
<h3 class="mb-3">关注</h3>
|
||||
<div class="card-grid">
|
||||
{% for p in posts %}
|
||||
<div class="card">
|
||||
{% set first = p.images[0] if p.images %}
|
||||
{% if first %}
|
||||
<a href="{{ url_for('posts.detail', post_id=p.id) }}">
|
||||
<img class="photo-thumb" src="{{ url_for('main.uploads', filename=first.web_path.split('uploads\\')[-1]) }}" alt="{{ p.title }}" />
|
||||
</a>
|
||||
{% endif %}
|
||||
<div class="p-3">
|
||||
<a class="text-decoration-none" href="{{ url_for('posts.detail', post_id=p.id) }}">{{ p.title }}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
19
app/templates/posts/create.html
Normal file
19
app/templates/posts/create.html
Normal file
@@ -0,0 +1,19 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}发布作品{% endblock %}
|
||||
{% block content %}
|
||||
<h3 class="mb-3">发布作品</h3>
|
||||
<form class="card p-3" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<div class="mb-3"><label class="form-label">标题</label><input class="form-control" name="title" required></div>
|
||||
<div class="mb-3"><label class="form-label">介绍</label><textarea class="form-control" name="description"></textarea></div>
|
||||
<div class="mb-3"><label class="form-label">可见性</label>
|
||||
<select class="form-select" name="visibility">
|
||||
<option value="public">公开(需审核)</option>
|
||||
<option value="followers">仅关注者</option>
|
||||
<option value="private">仅自己</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3"><label class="form-label">图片</label><input class="form-control" name="images" type="file" accept="image/*" multiple required></div>
|
||||
<button class="btn btn-brand" type="submit">提交</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
26
app/templates/posts/detail.html
Normal file
26
app/templates/posts/detail.html
Normal file
@@ -0,0 +1,26 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}作品详情{% endblock %}
|
||||
{% block content %}
|
||||
<div class="card mb-3">
|
||||
<div class="p-3">
|
||||
<h3 class="mb-2">{{ post.title }}</h3>
|
||||
<p class="text-secondary">{{ post.description }}</p>
|
||||
<span class="badge bg-light text-dark">{{ post.visibility.value }}</span>
|
||||
</div>
|
||||
<div class="p-3">
|
||||
<div class="row">
|
||||
{% for img in post.images %}
|
||||
<div class="col-md-4 mb-2">
|
||||
<img src="{{ url_for('main.uploads', filename=img.web_path.split('uploads\\')[-1]) }}" class="photo-thumb" />
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<form class="card p-3" method="post" action="{{ url_for('comments.create', post_id=post.id) }}">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<div class="mb-3"><textarea class="form-control" name="body" placeholder="发表评论"></textarea></div>
|
||||
<button class="btn btn-brand" type="submit">评论</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
13
app/templates/setup/admin.html
Normal file
13
app/templates/setup/admin.html
Normal file
@@ -0,0 +1,13 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}创建管理员{% endblock %}
|
||||
{% block content %}
|
||||
<h3 class="mb-3">首次使用:创建管理员</h3>
|
||||
<form class="card p-3" method="post">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<div class="mb-3"><label class="form-label">邮箱</label><input class="form-control" name="email" type="email" required></div>
|
||||
<div class="mb-3"><label class="form-label">用户名</label><input class="form-control" name="username" required></div>
|
||||
<div class="mb-3"><label class="form-label">密码</label><input class="form-control" name="password" type="password" required></div>
|
||||
<div class="mb-3"><label class="form-label">确认密码</label><input class="form-control" name="confirm" type="password" required></div>
|
||||
<button class="btn btn-brand" type="submit">创建管理员</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
12
app/templates/users/edit.html
Normal file
12
app/templates/users/edit.html
Normal file
@@ -0,0 +1,12 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}编辑资料{% endblock %}
|
||||
{% block content %}
|
||||
<h3>编辑资料</h3>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<div class="mb-3"><label class="form-label">简介</label><textarea class="form-control" name="bio"></textarea></div>
|
||||
<div class="mb-3"><label class="form-label">年级</label><input class="form-control" name="grade"></div>
|
||||
<div class="mb-3"><label class="form-label">班级</label><input class="form-control" name="class_name"></div>
|
||||
<button class="btn btn-primary" type="submit">保存</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
10
app/templates/users/notifications.html
Normal file
10
app/templates/users/notifications.html
Normal file
@@ -0,0 +1,10 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}通知{% endblock %}
|
||||
{% block content %}
|
||||
<h3>通知</h3>
|
||||
<ul>
|
||||
{% for n in items %}
|
||||
<li>{{ n.type }} {{ n.created_at }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
20
app/templates/users/profile.html
Normal file
20
app/templates/users/profile.html
Normal file
@@ -0,0 +1,20 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}主页{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h3>{{ user.username }}</h3>
|
||||
{% if current_user.is_authenticated and current_user.id != user.id %}
|
||||
<a class="btn btn-outline-primary" href="{{ url_for('follows.follow', user_id=user.id) }}">关注</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p>{{ user.profile.bio }}</p>
|
||||
<hr>
|
||||
<h5>作品</h5>
|
||||
<div class="row">
|
||||
{% for p in user.posts %}
|
||||
<div class="col-md-4">
|
||||
<a href="{{ url_for('posts.detail', post_id=p.id) }}">{{ p.title }}</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user