Compare commits
3 commits
7e2553646c
...
ddfe92fee4
Author | SHA1 | Date | |
---|---|---|---|
ddfe92fee4 | |||
a50b7cd3bc | |||
740df27069 |
21 changed files with 281 additions and 38 deletions
|
@ -219,6 +219,7 @@ input.btn:focus {
|
||||||
.nav-center {
|
.nav-center {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
|
top: 0;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
flex: 1;
|
flex: 1;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -542,6 +543,8 @@ input:not(:placeholder-shown) + label:not(.static) {
|
||||||
|
|
||||||
input[type=radio] {
|
input[type=radio] {
|
||||||
padding: 3rem !important;
|
padding: 3rem !important;
|
||||||
|
width: 1rem !important;
|
||||||
|
outline: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.radio {
|
.radio {
|
||||||
|
|
|
@ -14,19 +14,39 @@
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
padding: 1rem 2rem;
|
padding: 1rem 2rem;
|
||||||
display: grid;
|
padding-bottom: 0;
|
||||||
grid-template-columns: 1fr 1fr 1fr;
|
flex-direction: row;
|
||||||
grid-row-gap: 2rem;
|
|
||||||
grid-auto-rows: 1fr;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
max-width: 90rem;
|
max-width: 90rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.profile {
|
||||||
|
width: 25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(max-width: 1400px) {
|
||||||
|
#people-container {
|
||||||
|
max-width: 70rem;
|
||||||
|
}
|
||||||
|
.profile {
|
||||||
|
width: 25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(max-width: 1000px) {
|
||||||
|
#people-container {
|
||||||
|
max-width: 50rem;
|
||||||
|
}
|
||||||
|
.profile {
|
||||||
|
width: 20rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.profile {
|
.profile {
|
||||||
margin: 1rem;
|
margin: 1rem;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
height: 100%;
|
height: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile:hover {
|
.profile:hover {
|
||||||
|
@ -44,20 +64,6 @@
|
||||||
border-radius: .3rem;
|
border-radius: .3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(max-width: 1400px) {
|
|
||||||
#people-container {
|
|
||||||
max-width: 90rem;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(max-width: 1000px) {
|
|
||||||
#people-container {
|
|
||||||
max-width: 50rem;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
td:nth-child(1) {
|
td:nth-child(1) {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--subtext);
|
color: var(--subtext);
|
||||||
|
|
77
src/public/css/profile.css
Normal file
77
src/public/css/profile.css
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#main-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-header {
|
||||||
|
background-color: var(--surface0);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-header .banner {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 20rem;
|
||||||
|
aspect-ratio: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-header .info .pfp-wrapper .pfp,
|
||||||
|
#profile-header .info .pfp-wrapper .pfp img {
|
||||||
|
height: 12.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-header .info {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-header .info .pfp-wrapper {
|
||||||
|
padding: .5rem;
|
||||||
|
background-color: var(--surface0);
|
||||||
|
height: fit-content;
|
||||||
|
border-radius: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: -2.5rem;
|
||||||
|
left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-header .info .content {
|
||||||
|
margin-left: 17rem;
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-header .info .content .name {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-header > hr {
|
||||||
|
border-bottom: 1px solid var(--surface1);
|
||||||
|
height: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options {
|
||||||
|
width: 100%;
|
||||||
|
height: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options .btn {
|
||||||
|
height: 100%;
|
||||||
|
width: 10rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options .btn span {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tab-posts,
|
||||||
|
#post-container {
|
||||||
|
width: 40rem;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#post-container .post {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
|
@ -61,6 +61,7 @@ class Post_controller extends Controller {
|
||||||
$page = $this->request_model->get_int('page', 0);
|
$page = $this->request_model->get_int('page', 0);
|
||||||
$max = $this->request_model->get_int('max');
|
$max = $this->request_model->get_int('max');
|
||||||
$offset = $page * $this->page_size;
|
$offset = $page * $this->page_size;
|
||||||
|
$filter_uid = $this->request_model->get_int('user_id', FALSE);
|
||||||
|
|
||||||
$user = $this->main->user();
|
$user = $this->main->user();
|
||||||
$uid = isset($user) ? $user['id'] : NULL;
|
$uid = isset($user) ? $user['id'] : NULL;
|
||||||
|
@ -78,6 +79,11 @@ class Post_controller extends Controller {
|
||||||
->where('p.id')->le($max);
|
->where('p.id')->le($max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($uid) {
|
||||||
|
$query = $query
|
||||||
|
->where('p.user_id')->eq($uid);
|
||||||
|
}
|
||||||
|
|
||||||
$posts = $query
|
$posts = $query
|
||||||
->order_by('p.id', 'DESC')
|
->order_by('p.id', 'DESC')
|
||||||
->limit($this->page_size)
|
->limit($this->page_size)
|
||||||
|
@ -96,9 +102,16 @@ class Post_controller extends Controller {
|
||||||
$this->view('template/post', $data);
|
$this->view('template/post', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
$pc = $this->db
|
$query = $this->db
|
||||||
->select('COUNT(p.id) as pc')
|
->select('COUNT(p.id) as pc')
|
||||||
->from('api.post p')
|
->from('api.post p');
|
||||||
|
|
||||||
|
if ($uid) {
|
||||||
|
$query = $query
|
||||||
|
->where('p.user_id')->eq($uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pc = $query
|
||||||
->row()['pc'];
|
->row()['pc'];
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
@ -106,6 +119,7 @@ class Post_controller extends Controller {
|
||||||
'total' => $pc,
|
'total' => $pc,
|
||||||
'page_size' => $this->page_size,
|
'page_size' => $this->page_size,
|
||||||
'max' => $max,
|
'max' => $max,
|
||||||
|
'filter_uid' => $filter_uid
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
35
src/web/_controller/apps/profile.php
Normal file
35
src/web/_controller/apps/profile.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php /* Copyright (c) 2024 Freya Murphy */
|
||||||
|
class Profile_controller extends Controller {
|
||||||
|
|
||||||
|
// the home model
|
||||||
|
private $profile_model;
|
||||||
|
|
||||||
|
// the format model
|
||||||
|
protected $format_model;
|
||||||
|
|
||||||
|
// the post model
|
||||||
|
protected $post_controller;
|
||||||
|
|
||||||
|
function __construct($load) {
|
||||||
|
parent::__construct($load);
|
||||||
|
$this->profile_model = $this->load->model('apps/profile');
|
||||||
|
$this->format_model = $this->load->model('format');
|
||||||
|
$this->post_controller = $this->load->controller('_util/post');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index(): void {
|
||||||
|
parent::index();
|
||||||
|
$data = $this->profile_model->get_data();
|
||||||
|
|
||||||
|
if (!$data) {
|
||||||
|
$this->error(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->view('header', $data);
|
||||||
|
$this->view('apps/profile/main', $data);
|
||||||
|
$this->view('footer', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -5,7 +5,7 @@ class Auth_model extends Model {
|
||||||
parent::__construct($load);
|
parent::__construct($load);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_data(): array {
|
public function get_data(): ?array {
|
||||||
$data = parent::get_data();
|
$data = parent::get_data();
|
||||||
$data['title'] = lang('login');
|
$data['title'] = lang('login');
|
||||||
return $data;
|
return $data;
|
||||||
|
|
|
@ -22,7 +22,7 @@ class Error_model extends Model {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_data(): array {
|
public function get_data(): ?array {
|
||||||
$data = parent::get_data();
|
$data = parent::get_data();
|
||||||
$this->get_msg($data);
|
$this->get_msg($data);
|
||||||
return $data;
|
return $data;
|
||||||
|
|
|
@ -13,7 +13,7 @@ class Home_model extends Model {
|
||||||
->rows();
|
->rows();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_data(): array {
|
public function get_data(): ?array {
|
||||||
$data = parent::get_data();
|
$data = parent::get_data();
|
||||||
$data['title'] = lang('title');
|
$data['title'] = lang('title');
|
||||||
$data['posts'] = $this->get_posts();
|
$data['posts'] = $this->get_posts();
|
||||||
|
|
|
@ -80,7 +80,7 @@ class People_model extends Model {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_data(): array {
|
public function get_data(): ?array {
|
||||||
$data = parent::get_data();
|
$data = parent::get_data();
|
||||||
$data['title'] = lang('title');
|
$data['title'] = lang('title');
|
||||||
return $data;
|
return $data;
|
||||||
|
|
37
src/web/_model/apps/profile.php
Normal file
37
src/web/_model/apps/profile.php
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?php /* Copyright (c) 2024 Freya Murphy */
|
||||||
|
class Profile_model extends Model {
|
||||||
|
|
||||||
|
private $request_model;
|
||||||
|
|
||||||
|
function __construct($load) {
|
||||||
|
parent::__construct($load);
|
||||||
|
$this->request_model = $this->load->model('request');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_data(): ?array {
|
||||||
|
$uid = $this->request_model->get_int('id', FALSE);
|
||||||
|
if ($uid === FALSE) {
|
||||||
|
if ($this->main->session) {
|
||||||
|
$uid = $this->main->user()['id'];
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $this->db
|
||||||
|
->select('*')
|
||||||
|
->from('api.user u')
|
||||||
|
->where('u.id')
|
||||||
|
->eq($uid)
|
||||||
|
->row();
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = parent::get_data();
|
||||||
|
$data['user'] = $user;
|
||||||
|
$data['title'] = lang('title', sub: [$user['first_name']]);
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,7 +48,7 @@
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
var onLogin = function(data) {
|
const onLogin = function(data) {
|
||||||
let jwt = data.token;
|
let jwt = data.token;
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<?php if ($loaded >= $page_size && $page_size < $total): ?>
|
<?php if ($loaded >= $page_size && $page_size < $total): ?>
|
||||||
<?=ilang('action_load_users',
|
<?=ilang('action_load_users',
|
||||||
id: 'action-load-users',
|
id: 'action-load-users',
|
||||||
class: 'btn btn-line btn-wide mt mb',
|
class: 'btn btn-line btn-wide mb',
|
||||||
attrs: array(
|
attrs: array(
|
||||||
'loaded' => $loaded,
|
'loaded' => $loaded,
|
||||||
'pageSize' => $page_size,
|
'pageSize' => $page_size,
|
||||||
|
|
37
src/web/_views/apps/profile/main.php
Normal file
37
src/web/_views/apps/profile/main.php
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<div id="main-content">
|
||||||
|
<div id="profile-header" class="col">
|
||||||
|
<div class="banner image-loading">
|
||||||
|
<img src="/api/rpc/profile_banner?user_id=<?=$user['id']?>">
|
||||||
|
</div>
|
||||||
|
<div class="info row">
|
||||||
|
<div class="pfp-wrapper">
|
||||||
|
<?php $this->view('template/pfp', array('user' => $user)); ?>
|
||||||
|
</div>
|
||||||
|
<div class="col content">
|
||||||
|
<strong class="name"><?=$this->format_model->name($user)?></strong>
|
||||||
|
<span class="dim"><?=lang('joined') . $this->format_model->date($user['created'])?></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="row options">
|
||||||
|
<?=ilang('action_posts',
|
||||||
|
sub: [$user['first_name']],
|
||||||
|
class: 'btn'
|
||||||
|
)?>
|
||||||
|
<?=ilang('action_about',
|
||||||
|
sub: [$user['first_name']],
|
||||||
|
class: 'btn'
|
||||||
|
)?>
|
||||||
|
<?=ilang('action_friends',
|
||||||
|
sub: [$user['first_name']],
|
||||||
|
class: 'btn'
|
||||||
|
)?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="#tab-posts">
|
||||||
|
<?php
|
||||||
|
$_GET['user_id'] = $user['id'];
|
||||||
|
$this->post_controller->index();
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -1,5 +1,5 @@
|
||||||
<?php /* Copyright (c) 2024 Freya Murphy */ ?>
|
<?php /* Copyright (c) 2024 Freya Murphy */ ?>
|
||||||
<?php /* vi: syntax=php */ ?>
|
<?php /* vim: syntax=php */ ?>
|
||||||
<?php
|
<?php
|
||||||
$self = $this->main->user();
|
$self = $this->main->user();
|
||||||
$this->view('header_empty', $data);
|
$this->view('header_empty', $data);
|
||||||
|
|
|
@ -133,8 +133,8 @@
|
||||||
$('#register-form').submit(function(e) {
|
$('#register-form').submit(function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
const form = event.target;
|
let form = event.target;
|
||||||
const formFields = form.elements;
|
let formFields = form.elements;
|
||||||
|
|
||||||
let first_name = formFields.first_name.value.trim();
|
let first_name = formFields.first_name.value.trim();
|
||||||
let last_name = formFields.last_name.value.trim();
|
let last_name = formFields.last_name.value.trim();
|
||||||
|
@ -149,7 +149,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSuccess = () => {
|
const onSuccess = function() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '/api/rpc/login',
|
url: '/api/rpc/login',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -164,8 +164,13 @@
|
||||||
url: '/api/user',
|
url: '/api/user',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
first_name, last_name, username, password,
|
first_name,
|
||||||
email, birth_date, gender
|
last_name,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
email,
|
||||||
|
birth_date,
|
||||||
|
gender,
|
||||||
}),
|
}),
|
||||||
success: onSuccess
|
success: onSuccess
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,16 +6,18 @@
|
||||||
$page_size = $pdata['page_size'];
|
$page_size = $pdata['page_size'];
|
||||||
$total = $pdata['total'];
|
$total = $pdata['total'];
|
||||||
$max = $pdata['max'];
|
$max = $pdata['max'];
|
||||||
|
$filterUid = $pdata['filter_uid'];
|
||||||
|
|
||||||
if ($loaded >= $page_size && $page_size < $total) {
|
if ($loaded >= $page_size && $page_size < $total) {
|
||||||
ilang('action_load_posts',
|
ilang('action_load_posts',
|
||||||
id: 'action-load-posts',
|
id: 'action-load-posts',
|
||||||
class: 'btn btn-line btn-wide mb',
|
class: 'btn btn-line btn-wide mb mt',
|
||||||
attrs: array(
|
attrs: array(
|
||||||
'loaded' => $loaded,
|
'loaded' => $loaded,
|
||||||
'pageSize' => $page_size,
|
'pageSize' => $page_size,
|
||||||
'postCount' => $total,
|
'postCount' => $total,
|
||||||
'postMax' => $max,
|
'postMax' => $max,
|
||||||
|
'userId' => $filterUid
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ class Aesthetic {
|
||||||
),
|
),
|
||||||
'home' => array(
|
'home' => array(
|
||||||
'js' => [
|
'js' => [
|
||||||
'js/routes/home.js',
|
|
||||||
'js/post.js',
|
'js/post.js',
|
||||||
],
|
],
|
||||||
'css' => [
|
'css' => [
|
||||||
|
@ -40,6 +39,15 @@ class Aesthetic {
|
||||||
'css/people.css'
|
'css/people.css'
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
'profile' => array(
|
||||||
|
'js' => [
|
||||||
|
'js/post.js',
|
||||||
|
],
|
||||||
|
'css' => [
|
||||||
|
'css/profile.css',
|
||||||
|
'css/post.css'
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,5 +5,6 @@ $routes['home'] = 'apps/home';
|
||||||
$routes['error'] = 'apps/error';
|
$routes['error'] = 'apps/error';
|
||||||
$routes['auth'] = 'apps/auth';
|
$routes['auth'] = 'apps/auth';
|
||||||
$routes['people'] = 'apps/people';
|
$routes['people'] = 'apps/people';
|
||||||
|
$routes['profile'] = 'apps/profile';
|
||||||
|
|
||||||
$routes[''] = '_index';
|
$routes[''] = '_index';
|
||||||
|
|
|
@ -24,7 +24,7 @@ abstract class Model {
|
||||||
/**
|
/**
|
||||||
* @returns the base model data
|
* @returns the base model data
|
||||||
*/
|
*/
|
||||||
public function get_data(): array {
|
public function get_data(): ?array {
|
||||||
$data = array();
|
$data = array();
|
||||||
$data['self'] = $this->main->user();
|
$data['self'] = $this->main->user();
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ function ilang($key,
|
||||||
$button = FALSE,
|
$button = FALSE,
|
||||||
) {
|
) {
|
||||||
$text = lang($key . "_text", FALSE, sub: $sub);
|
$text = lang($key . "_text", FALSE, sub: $sub);
|
||||||
$tip = lang($key . "_tip", FALSE);
|
$tip = lang($key . "_tip", FALSE, sub: $sub);
|
||||||
$icon = lang($key . "_icon", FALSE);
|
$icon = lang($key . "_icon", FALSE);
|
||||||
$content = lang($key . "_content", FALSE);
|
$content = lang($key . "_content", FALSE);
|
||||||
|
|
||||||
|
|
18
src/web/lang/en_US/apps/profile.php
Normal file
18
src/web/lang/en_US/apps/profile.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$lang['title'] = '%s\'s profile';
|
||||||
|
|
||||||
|
$lang['joined'] = 'Joined: ';
|
||||||
|
$lang['seen'] = 'Seen: ';
|
||||||
|
|
||||||
|
$lang['action_posts_text'] = 'Posts';
|
||||||
|
$lang['action_posts_tip'] = 'View %s\'s posts';
|
||||||
|
$lang['action_about_text'] = 'About';
|
||||||
|
$lang['action_about_tip'] = 'View %s\'s information';
|
||||||
|
$lang['action_friends_text'] = 'Friends';
|
||||||
|
$lang['action_friends_tip'] = 'View %s\'s friends';
|
||||||
|
|
||||||
|
$lang['action_load_posts_text'] = 'Load more posts';
|
||||||
|
$lang['action_load_posts_tip'] = 'Load more posts';
|
||||||
|
|
||||||
|
?>
|
Loading…
Reference in a new issue