refactor: user_info page with bs5

This commit is contained in:
Baoshuo Ren 2022-09-28 15:39:39 +08:00
parent 492a4fdd83
commit e8125e7e3a
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A
4 changed files with 273 additions and 106 deletions

View File

@ -9,89 +9,239 @@
$username = $_GET['username']; $username = $_GET['username'];
$REQUIRE_LIB['github_contribution_graph'] = ''; if (!validateUsername($username) || !($user = queryUser($username))) {
become404Page();
}
?> ?>
<?php if (validateUsername($username) && ($user = queryUser($username))): ?> <?php
<?php echoUOJPageHeader($user['username'] . ' - ' . UOJLocale::get('user profile')) ?> if (!isset($_COOKIE['bootstrap4'])) {
<?php $REQUIRE_LIB['bootstrap5'] = '';
$esc_email = HTML::escape($user['email']); $REQUIRE_LIB['calendar_heatmap'] = '';
$esc_qq = HTML::escape($user['qq'] != 0 ? $user['qq'] : 'Unfilled'); } else {
$esc_sex = HTML::escape($user['sex']); $REQUIRE_LIB['github_contribution_graph'] = '';
$col_sex="color:blue"; }
if ($esc_sex == "M") {
$esc_sex="";
$col_sex="color:blue";
} elseif ($esc_sex == "F") {
$esc_sex="";
$col_sex="color:red";
} else {
$esc_sex="";
$col_sex="color:black";
}
$motto = addslashes($user['motto']);
?> ?>
<div class="card border-info"> <?php echoUOJPageHeader($user['username'] . ' - ' . UOJLocale::get('user profile')) ?>
<h5 class="card-header bg-info"><?= UOJLocale::get('user profile') ?></h5> <?php if (isset($REQUIRE_LIB['bootstrap5'])): ?>
<div class="card-body"> <div class="row">
<div class="row mb-4"> <div class="col-md-3">
<div class="col-md-4 order-md-9"> <div class="card">
<img class="media-object img-thumbnail d-block mx-auto" alt="<?= $user['username'] ?> Avatar" src="<?= HTML::avatar_addr($user, 256) ?>" /> <img class="card-img-top" alt="Avatar of <?= $user['username'] ?>" src="<?= HTML::avatar_addr($user, 512) ?>" />
<div class="card-body">
<h3>
<?= $user['username'] ?>
<span class="fs-6 align-middle"
<?php if ($user['sex'] == 'M'): ?>
style="color: blue"><i class="bi bi-gender-male"></i>
<?php elseif ($user['sex' == 'F']): ?>
style="color: red"><i class="bi bi-gender-female"></i>
<?php endif ?>
</span>
</h3>
<?php $motto_id = uniqid("motto-{$user['username']}-"); ?>
<div class="card-text" id="<?= $motto_id ?>"></div>
<script type="text/javascript">
$(function() { $('#<?= $motto_id ?>').html(DOMPurify.sanitize(decodeURIComponent("<?= urlencode($user['motto']) ?>"), <?= DOM_SANITIZE_CONFIG ?>)); });
</script>
</div> </div>
<div class="col-md-8 order-md-1"> <ul class="list-group list-group-flush">
<h2><span class="uoj-honor" data-realname="<?= $user['realname'] ?>"><?= $user['username'] ?></span> <span><strong style="<?= $col_sex ?>"><?= $esc_sex ?></strong></span></h2> <?php if ($user['realname']): ?>
<div class="list-group"> <li class="list-group-item">
<div class="list-group-item"> <i class="bi bi-person-fill me-1"></i>
<h4 class="list-group-item-heading"><?= UOJLocale::get('email') ?></h4> <?= $user['realname'] ?>
<p class="list-group-item-text"><?= $esc_email ?></p> </li>
</div> <?php endif ?>
<div class="list-group-item"> <li class="list-group-item">
<h4 class="list-group-item-heading"><?= UOJLocale::get('QQ') ?></h4> <i class="bi bi-envelope-fill me-1"></i>
<p class="list-group-item-text"><?= $esc_qq ?></p> <a class="text-decoration-none text-body" href="mailto:<?= HTML::escape($user['email']) ?>">
</div> <?= HTML::escape($user['email']) ?>
<div class="list-group-item"> </a>
<h4 class="list-group-item-heading"><?= UOJLocale::get('motto') ?></h4><?php </li>
<?php if ($user['qq']): ?>
<li class="list-group-item">
<i class="align-text-bottom me-1"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16"><path d="M433.754 420.445c-11.526 1.393-44.86-52.741-44.86-52.741 0 31.345-16.136 72.247-51.051 101.786 16.842 5.192 54.843 19.167 45.803 34.421-7.316 12.343-125.51 7.881-159.632 4.037-34.122 3.844-152.316 8.306-159.632-4.037-9.045-15.25 28.918-29.214 45.783-34.415-34.92-29.539-51.059-70.445-51.059-101.792 0 0-33.334 54.134-44.859 52.741-5.37-.65-12.424-29.644 9.347-99.704 10.261-33.024 21.995-60.478 40.144-105.779C60.683 98.063 108.982.006 224 0c113.737.006 163.156 96.133 160.264 214.963 18.118 45.223 29.912 72.85 40.144 105.778 21.768 70.06 14.716 99.053 9.346 99.704z" fill="currentColor"/></svg></i>
<?= HTML::escape($user['qq']) ?>
</li>
<?php endif ?>
</ul>
</div>
</div>
<div class="col-md-9 mt-2 mt-md-0">
<nav class="nav mb-2">
<?php if (Auth::check()): ?>
<?php if (Auth::id() != $user['username']): ?>
<a class="nav-link" href="/user/msg?enter=<?= $user['username'] ?>">
<i class="bi bi-chat-left-dots"></i>
<?= UOJLocale::get('send private message') ?>
</a>
<?php else: ?>
<a class="nav-link" href="/user/modify-profile">
<i class="bi bi-pencil"></i>
<?= UOJLocale::get('modify my profile') ?>
</a>
<?php endif ?>
<?php endif ?>
<a class="nav-link" href="<?= HTML::blog_url($user['username'], '/') ?>">
<i class="bi bi-arrow-right-square"></i>
<?= UOJLocale::get('visit his blog', $username) ?>
</a>
<a class="nav-link" href="<?= HTML::blog_url($user['username'], '/self_reviews') ?>">
<i class="bi bi-arrow-right-square"></i>
赛后总结
</a>
</nav>
<div class="card card-default mb-2">
<div class="card-body">
<?php
$_result = DB::query("select date_format(submit_time, '%Y-%m-%d'), problem_id from submissions where submitter = '{$username}' and score = 100 and date(submit_time) between date_sub(curdate(), interval 1 year) and curdate()");
$result = [];
$vis = [];
while ($row = DB::fetch($_result)) {
$id = $row["date_format(submit_time, '%Y-%m-%d')"] . ':' . $row['problem_id'];
if (!$vis[$id]) {
$vis[$id] = 1;
$result[$row["date_format(submit_time, '%Y-%m-%d')"]]++;
}
}
?>
<h4 class="card-title h5">
<?= UOJLocale::get('n accepted in last year', count($result)) ?>
</h4>
<div id="accepted-graph" style="font-size: 14px"></div>
<script>
var accepted_graph_data = [
<?php foreach ($result as $key => $val): ?>
{ date: '<?= $key ?>', count: <?= $val ?> },
<?php endforeach ?>
];
$(document).ready(function () {
$('#accepted-graph').CalendarHeatmap(accepted_graph_data, {});
});
</script>
</div>
</div>
<div class="card card-default mb-2">
<div class="card-body">
<?php $ac_problems = DB::selectAll("select a.problem_id as problem_id, b.title as title from best_ac_submissions a inner join problems b on a.problem_id = b.id where submitter = '{$user['username']}';") ?>
<h4 class="card-title h5">
<?= UOJLocale::get('accepted problems').': '.UOJLocale::get('n problems in total', count($ac_problems))?>
</h4>
<ul class="nav">
<?php foreach ($ac_problems as $problem): ?>
<li class="nav-item">
<a class="nav-link" href="/problem/<?= $problem['problem_id'] ?>" role="button">
#<?= $problem['problem_id'] ?>. <?= $problem['title'] ?>
</a>
</li>
<?php endforeach ?>
<?php if (empty($ac_problems)): ?>
<?= UOJLocale::get('none'); ?>
<?php endif ?>
</ul>
</div>
</div>
<?php if (isSuperUser($myUser)): ?>
<div class="card card-default">
<ul class="list-group list-group-flush">
<li class="list-group-item">
<h5 class="list-group-item-heading">register time</h5>
<p class="list-group-item-text"><?= $user['register_time'] ?></p>
</li>
<li class="list-group-item">
<h5 class="list-group-item-heading">remote_addr</h5>
<p class="list-group-item-text"><?= $user['remote_addr'] ?></p>
</li>
<li class="list-group-item">
<h5 class="list-group-item-heading">http_x_forwarded_for</h5>
<p class="list-group-item-text"><?= $user['http_x_forwarded_for'] ?></p>
</li>
</ul>
</div>
<?php endif ?>
</div>
</div>
<?php else: ?>
<?php
$esc_sex = HTML::escape($user['sex']);
$col_sex="color:blue";
if ($esc_sex == "M") {
$esc_sex="";
$col_sex="color:blue";
} elseif ($esc_sex == "F") {
$esc_sex="";
$col_sex="color:red";
} else {
$esc_sex="";
$col_sex="color:black";
}
?>
<div class="card border-info">
<h5 class="card-header bg-info"><?= UOJLocale::get('user profile') ?></h5>
<div class="card-body">
<div class="row mb-4">
<div class="col-md-4 order-md-9">
<img class="media-object img-thumbnail d-block mx-auto" alt="<?= $user['username'] ?> Avatar" src="<?= HTML::avatar_addr($user, 256) ?>" />
</div>
<div class="col-md-8 order-md-1">
<h2><span class="uoj-honor" data-realname="<?= $user['realname'] ?>"><?= $user['username'] ?></span> <span><strong style="<?= $col_sex ?>"><?= $esc_sex ?></strong></span></h2>
<div class="list-group">
<div class="list-group-item">
<h4 class="list-group-item-heading"><?= UOJLocale::get('email') ?></h4>
<p class="list-group-item-text"><?= HTML::escape($user['email']) ?></p>
</div>
<div class="list-group-item">
<h4 class="list-group-item-heading"><?= UOJLocale::get('QQ') ?></h4>
<p class="list-group-item-text"><?= HTML::escape($user['qq'] != 0 ? $user['qq'] : 'Unfilled') ?></p>
</div>
<div class="list-group-item">
<h4 class="list-group-item-heading"><?= UOJLocale::get('motto') ?></h4>
<?php
$motto_id = uniqid("motto-{$user['username']}-"); $motto_id = uniqid("motto-{$user['username']}-");
$dom_sanitize_config = DOM_SANITIZE_CONFIG; $dom_sanitize_config = DOM_SANITIZE_CONFIG;
?> ?>
<p class="list-group-item-text" id="<?= $motto_id ?>"></p> <p class="list-group-item-text" id="<?= $motto_id ?>"></p>
<script type="text/javascript"> <script type="text/javascript">
$(function() { $('#<?= $motto_id ?>').html(DOMPurify.sanitize('<?= $motto ?>', <?= $dom_sanitize_config ?>)); }); $(function() { $('#<?= $motto_id ?>').html(DOMPurify.sanitize('<?= addslashes($user['motto']) ?>', <?= $dom_sanitize_config ?>)); });
</script> </script>
</div>
<?php if (isSuperUser($myUser)): ?>
<div class="list-group-item">
<h4 class="list-group-item-heading">register time</h4>
<p class="list-group-item-text"><?= $user['register_time'] ?></p>
</div>
<div class="list-group-item">
<h4 class="list-group-item-heading">remote_addr</h4>
<p class="list-group-item-text"><?= $user['remote_addr'] ?></p>
</div>
<div class="list-group-item">
<h4 class="list-group-item-heading">http_x_forwarded_for</h4>
<p class="list-group-item-text"><?= $user['http_x_forwarded_for'] ?></p>
</div>
<?php endif ?>
</div> </div>
<?php if (isSuperUser($myUser)): ?>
<div class="list-group-item">
<h4 class="list-group-item-heading">register time</h4>
<p class="list-group-item-text"><?= $user['register_time'] ?></p>
</div>
<div class="list-group-item">
<h4 class="list-group-item-heading">remote_addr</h4>
<p class="list-group-item-text"><?= $user['remote_addr'] ?></p>
</div>
<div class="list-group-item">
<h4 class="list-group-item-heading">http_x_forwarded_for</h4>
<p class="list-group-item-text"><?= $user['http_x_forwarded_for'] ?></p>
</div>
<?php endif ?>
</div> </div>
</div> </div>
<?php if (Auth::check()): ?> </div>
<?php if (Auth::id() != $user['username']): ?> <?php if (Auth::check()): ?>
<a type="button" class="btn btn-info btn-sm" href="/user/msg?enter=<?= $user['username'] ?>"><span class="glyphicon glyphicon-envelope"></span> <?= UOJLocale::get('send private message') ?></a> <?php if (Auth::id() != $user['username']): ?>
<?php else: ?> <a type="button" class="btn btn-info btn-sm" href="/user/msg?enter=<?= $user['username'] ?>"><span class="glyphicon glyphicon-envelope"></span> <?= UOJLocale::get('send private message') ?></a>
<a type="button" class="btn btn-info btn-sm" href="/user/modify-profile"><span class="glyphicon glyphicon-pencil"></span> <?= UOJLocale::get('modify my profile') ?></a> <?php else: ?>
<?php endif ?> <a type="button" class="btn btn-info btn-sm" href="/user/modify-profile"><span class="glyphicon glyphicon-pencil"></span> <?= UOJLocale::get('modify my profile') ?></a>
<?php endif ?> <?php endif ?>
<?php endif ?>
<a type="button" class="btn btn-success btn-sm" href="<?= HTML::blog_url($user['username'], '/') ?>"><span class="glyphicon glyphicon-arrow-right"></span> <?= UOJLocale::get('visit his blog', $username) ?></a> <a type="button" class="btn btn-success btn-sm" href="<?= HTML::blog_url($user['username'], '/') ?>"><span class="glyphicon glyphicon-arrow-right"></span> <?= UOJLocale::get('visit his blog', $username) ?></a>
<a type="button" class="btn btn-success btn-sm" href="<?= HTML::blog_url($user['username'], '/self_reviews') ?>"><span class="glyphicon glyphicon-arrow-right"></span> 查看 <?= $username ?> 的所有赛后总结</a> <a type="button" class="btn btn-success btn-sm" href="<?= HTML::blog_url($user['username'], '/self_reviews') ?>"><span class="glyphicon glyphicon-arrow-right"></span> 查看 <?= $username ?> 的所有赛后总结</a>
<div class="top-buffer-lg"></div> <div class="top-buffer-lg"></div>
<div class="list-group"> <div class="list-group">
<div class="list-group-item"> <div class="list-group-item">
<?php <?php
$_result = DB::query("select date(submit_time), problem_id from submissions where submitter = '{$username}' and score = 100 and date(submit_time) between date_sub(curdate(), interval 1 year) and curdate()"); $_result = DB::query("select date(submit_time), problem_id from submissions where submitter = '{$username}' and score = 100 and date(submit_time) between date_sub(curdate(), interval 1 year) and curdate()");
$result = []; $result = [];
$vis = []; $vis = [];
while ($row = DB::fetch($_result)) { while ($row = DB::fetch($_result)) {
@ -102,33 +252,33 @@
} }
} }
?> ?>
<h4 class="list-group-item-heading"><?= UOJLocale::get('n accepted in last year', count($result)) ?></h4> <h4 class="list-group-item-heading"><?= UOJLocale::get('n accepted in last year', count($result)) ?></h4>
<div id="accepted-graph"></div> <div id="accepted-graph"></div>
<script> <script>
var accepted_graph_data = [ var accepted_graph_data = [
<?php <?php
foreach ($result as $key => $val) { foreach ($result as $key => $val) {
echo "{ timestamp: {$key}, count: {$val} }, "; echo "{ timestamp: {$key}, count: {$val} }, ";
} }
?> ?>
]; ];
$(document).ready(function () { $(document).ready(function () {
$('#accepted-graph').github_graph({ $('#accepted-graph').github_graph({
data: accepted_graph_data, data: accepted_graph_data,
texts: ['AC', 'AC'], texts: ['AC', 'AC'],
h_days: ['Tue', 'Thu', 'Sat'], h_days: ['Tue', 'Thu', 'Sat'],
});
}); });
</script> });
</div> </script>
<div class="list-group-item"> </div>
<?php <div class="list-group-item">
<?php
$ac_problems = DB::selectAll("select a.problem_id as problem_id, b.title as title from best_ac_submissions a inner join problems b on a.problem_id = b.id where submitter = '{$user['username']}';"); $ac_problems = DB::selectAll("select a.problem_id as problem_id, b.title as title from best_ac_submissions a inner join problems b on a.problem_id = b.id where submitter = '{$user['username']}';");
?> ?>
<h4 class="list-group-item-heading"><?= UOJLocale::get('accepted problems').''.UOJLocale::get('n problems in total', count($ac_problems))?> </h4> <h4 class="list-group-item-heading"><?= UOJLocale::get('accepted problems').''.UOJLocale::get('n problems in total', count($ac_problems))?> </h4>
<ul class="list-group-item-text nav"> <ul class="list-group-item-text nav">
<?php <?php
foreach ($ac_problems as $problem) { foreach ($ac_problems as $problem) {
echo '<li class="mr-1 mb-1"><a href="/problem/', $problem['problem_id'], '" role="button" class="btn btn-light h-100" style="width: 12rem;">#', $problem['problem_id'], '. ', $problem['title'], '</a></li>'; echo '<li class="mr-1 mb-1"><a href="/problem/', $problem['problem_id'], '" role="button" class="btn btn-light h-100" style="width: 12rem;">#', $problem['problem_id'], '. ', $problem['title'], '</a></li>';
} }
@ -137,19 +287,11 @@
echo UOJLocale::get('none'); echo UOJLocale::get('none');
} }
?> ?>
</ul> </ul>
</div>
</div> </div>
</div> </div>
</div> </div>
<?php else: ?> </div>
<?php echoUOJPageHeader('不存在该用户' . ' - 用户信息') ?>
<div class="card border-danger">
<div class="card-header bg-danger">用户信息</div>
<div class="card-body">
<h4>不存在该用户</h4>
</div>
</div>
<?php endif ?> <?php endif ?>
<?php echoUOJPageFooter() ?> <?php echoUOJPageFooter() ?>

View File

@ -228,6 +228,12 @@
<?= HTML::js_src('/js/jquery.github_contribution_graph.js') ?> <?= HTML::js_src('/js/jquery.github_contribution_graph.js') ?>
<?php endif ?> <?php endif ?>
<?php if (isset($REQUIRE_LIB['calendar_heatmap'])): ?>
<!-- jquery-calendar-heatmap -->
<?= HTML::css_link('/css/jquery.calendar_heatmap.min.css') ?>
<?= HTML::js_src('/js/jquery.calendar_heatmap.min.js') ?>
<?php endif ?>
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>

View File

@ -0,0 +1,9 @@
/*
* jquery-calendar-heatmap - v1.3.0
* A simple Calendar Heatmap for jQuery.
* https://github.com/SeBassTian23/CalendarHeatmap
*
* Made by Sebastian Kuhlgert
* Under MIT License
*/
.ch{display:table!important;clear:both}.ch-rounded .ch-day,.ch-rounded .ch-lvl{border-radius:35%}.ch-circle .ch-day,.ch-circle .ch-lvl{border-radius:100%}.ch-month,.ch-week-labels{font-size:0;display:inline-block;white-space:normal;margin:0 4px}.ch-day-labels,.ch-week{display:inline-block;width:11px;box-sizing:content-box}.ch-day-labels{width:inherit}.ch-month-label{text-align:center;font-size:12px;margin-top:10px;margin-bottom:10px}.ch-day-label{text-align:center;font-size:12px;display:block;margin:0;line-height:11px;box-sizing:content-box}.ch-day{display:inline-block;width:9px;height:9px;border:1px solid #fff;background-color:#c8d7e1;margin:0;box-sizing:content-box}.ch-day.is-outside-month,.ch-day.is-outside-month:hover,.ch-lvl.is-outside-month,.ch-lvl.is-outside-month:hover{background-color:transparent;border-color:transparent}.ch-day.lvl-0,.ch-lvl.lvl-0{background-color:#c8d7e1}.ch-day.is-after-today,.ch-lvl.is-after-today{background-color:#e9eff3}.ch-day.lvl-1,.ch-lvl.lvl-1{background-color:#a6c96a}.ch-day.lvl-2,.ch-lvl.lvl-2{background-color:#5cb85c}.ch-day.lvl-3,.ch-lvl.lvl-3{background-color:#009e47}.ch-day.lvl-4,.ch-lvl.lvl-4{background-color:#00753a}.ch-day:hover,.ch-lvl:hover{border-color:#ababab}.ch-legend{padding-top:10px;text-align:right}.ch-legend-left{text-align:left!important}.ch-legend-center{text-align:center!important}.ch-legend:after{content:".";display:block;height:0;width:0;clear:both;visibility:hidden}.ch-lvls{display:inline-block;margin:0;padding:0;list-style-type:none;padding:2px 9px 0 5px}.ch-lvl{width:10px;height:10px;float:left;margin-left:3px}.blue-1{background-color:#ffc!important}.earth-1{background-color:#f4ec15!important}.electric-1{background-color:#f9d824!important}.viridis-1{background-color:#dde218!important}.picknick-1{background-color:#dd2a91!important}.green-1{background-color:#d1be5a!important}.teal-1{background-color:#becfb6!important}.red-1{background-color:#deb7af!important}.blue-2{background-color:#41b6c4!important}.earth-2{background-color:#86bf76!important}.electric-2{background-color:#f38647!important}.viridis-2{background-color:#42bd70!important}.picknick-2{background-color:#b14dec!important}.green-2{background-color:#5f900b!important}.teal-2{background-color:#7db28f!important}.red-2{background-color:#cf8371!important}.blue-3{background-color:#0868ac!important}.earth-3{background-color:#117bd7!important}.electric-3{background-color:#8e0ca3!important}.viridis-3{background-color:#355c8c!important}.picknick-3{background-color:#2e8ebf!important}.green-3{background-color:#39811b!important}.teal-3{background-color:#107d79!important}.red-3{background-color:#b63b25!important}.blue-4{background-color:#253494!important}.earth-4{background-color:#363299!important}.electric-4{background-color:#2e0495!important}.viridis-4{background-color:#471164!important}.picknick-4{background-color:#139863!important}.green-4{background-color:#0d562c!important}.teal-4{background-color:#1c475d!important}.red-4{background-color:#90131c!important}

10
web/js/jquery.calendar_heatmap.min.js vendored Normal file

File diff suppressed because one or more lines are too long