More refactoring!
This commit is contained in:
parent
e368b99775
commit
baa669db8b
11 changed files with 173 additions and 180 deletions
58
src/lib/components/Header.svelte
Normal file
58
src/lib/components/Header.svelte
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
<script>
|
||||||
|
export let data = '';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
|
||||||
|
#logo {
|
||||||
|
|
||||||
|
width: calc(100vw - 20px);
|
||||||
|
|
||||||
|
background: var(--dark-1);
|
||||||
|
|
||||||
|
padding: 5px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#logo a {
|
||||||
|
padding: 10px;
|
||||||
|
color: var(--light-1);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#logo img {
|
||||||
|
height: 30px;
|
||||||
|
width: auto;
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id='logo'>
|
||||||
|
<a href='/'>
|
||||||
|
<img src='/icon_sanifae.svg' alt='Sanifae Logo'>
|
||||||
|
</a>
|
||||||
|
{#if data.username && data.username != 'false'}
|
||||||
|
<a href='/user/{data.username}'>
|
||||||
|
{data.username}
|
||||||
|
</a>
|
||||||
|
<a href='/logout'>
|
||||||
|
Log out
|
||||||
|
</a>
|
||||||
|
<a href='/new_post'>
|
||||||
|
Create
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
|
<a href='/account'>
|
||||||
|
Log in / Register
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
</div>
|
25
src/lib/components/PostList.svelte
Normal file
25
src/lib/components/PostList.svelte
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<script>
|
||||||
|
import Post from '$lib/components/Post.svelte';
|
||||||
|
import Button from '$lib/components/Button.svelte'
|
||||||
|
|
||||||
|
export let data;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if data && data.postJson && data.postJson.data}
|
||||||
|
{#each data.postJson.data as post}
|
||||||
|
<Post
|
||||||
|
success={post.success}
|
||||||
|
username={post.username}
|
||||||
|
content={post.content}
|
||||||
|
upvotes={post.upvotes}
|
||||||
|
downvotes={post.downvotes}
|
||||||
|
id={post.id}
|
||||||
|
isAuthor={post.isAuthor}
|
||||||
|
></Post>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<Button clickFunc={() => { window.location.search = 'page=' + ((data.id)-1) }}>Previous page</Button>
|
||||||
|
<Button clickFunc={() => { window.location.search = 'page=' + ((data.id)+1) }}>Next page</Button>
|
||||||
|
</p>
|
|
@ -1,4 +1,4 @@
|
||||||
const rowCount = 5;
|
const ROW_COUNT = 5;
|
||||||
|
|
||||||
const AUTH_ACTIONS = [
|
const AUTH_ACTIONS = [
|
||||||
'postCreate',
|
'postCreate',
|
||||||
|
@ -7,7 +7,9 @@ const AUTH_ACTIONS = [
|
||||||
'postDelete'
|
'postDelete'
|
||||||
];
|
];
|
||||||
|
|
||||||
const fileSizeLimit = 1024*1024*16;
|
const FILE_SIZE_LIMIT = 1024*1024*16;
|
||||||
|
|
||||||
|
const VALID_EXTENSIONS = ['png','jpg','jpeg','gif','svg']
|
||||||
|
|
||||||
var ridArray = {};
|
var ridArray = {};
|
||||||
|
|
||||||
|
@ -15,8 +17,8 @@ import sqlite3 from 'sqlite3'
|
||||||
import { open } from 'sqlite'
|
import { open } from 'sqlite'
|
||||||
import { hash, compare } from 'bcrypt'
|
import { hash, compare } from 'bcrypt'
|
||||||
import { randomBytes, createHash } from 'node:crypto';
|
import { randomBytes, createHash } from 'node:crypto';
|
||||||
import { readFile, writeFile } from 'node:fs/promises';
|
import { writeFile } from 'node:fs/promises';
|
||||||
import { calcVote, calcVoteUser, checkLength, checkRegex } from '../util.js';
|
import { calcVote, checkLength, checkRegex, safePath } from '../util.js';
|
||||||
|
|
||||||
var db;
|
var db;
|
||||||
async function initDb() {
|
async function initDb() {
|
||||||
|
@ -55,8 +57,6 @@ let updateUser = async ({user}) => {
|
||||||
|
|
||||||
let upvotes = 0;
|
let upvotes = 0;
|
||||||
let downvotes = 0;
|
let downvotes = 0;
|
||||||
let reputation = 0;
|
|
||||||
|
|
||||||
allPosts.forEach(post => {
|
allPosts.forEach(post => {
|
||||||
upvotes += post.upvotes || 0;
|
upvotes += post.upvotes || 0;
|
||||||
downvotes += post.downvotes || 0;
|
downvotes += post.downvotes || 0;
|
||||||
|
@ -72,7 +72,7 @@ let updateUser = async ({user}) => {
|
||||||
0,
|
0,
|
||||||
upvotes,
|
upvotes,
|
||||||
downvotes,
|
downvotes,
|
||||||
calcVoteUser(upvotes,downvotes)
|
calcVote(upvotes,downvotes,'user')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,21 +169,6 @@ backend.postDelete = async ({id, user}) => {
|
||||||
return {'success': 'Your post has been deleted!', 'href': `/post/${id}` };
|
return {'success': 'Your post has been deleted!', 'href': `/post/${id}` };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
backend.postGet = async ({id, cookies }) => {
|
|
||||||
var posts = await db.all('SELECT * from post WHERE id = ?', [
|
|
||||||
id
|
|
||||||
])
|
|
||||||
|
|
||||||
if (!posts || posts.length < 1) {
|
|
||||||
return {'success': 'Post does not exist.'}
|
|
||||||
}
|
|
||||||
|
|
||||||
var user = (await backend.token({cookies})).data;
|
|
||||||
|
|
||||||
return {data: posts[0], isAuthor: posts[0].username == user};
|
|
||||||
}
|
|
||||||
|
|
||||||
backend.userGet = async ({user}) => {
|
backend.userGet = async ({user}) => {
|
||||||
var posts = await db.all('SELECT * from user WHERE username = ?', [
|
var posts = await db.all('SELECT * from user WHERE username = ?', [
|
||||||
user
|
user
|
||||||
|
@ -208,26 +193,36 @@ backend.userBio = async ({user}) => {
|
||||||
return {data: posts[0]};
|
return {data: posts[0]};
|
||||||
}
|
}
|
||||||
|
|
||||||
backend.postBulk = async ({page,user}) => {
|
backend.postBulk = async ({page, id, user, cookies}) => {
|
||||||
var posts;
|
var posts;
|
||||||
|
|
||||||
if (!user) {
|
var userAuth = (await backend.token({cookies})).data;
|
||||||
|
|
||||||
|
if (!user && !id) {
|
||||||
posts = await db.all('SELECT * from post ORDER BY rating DESC LIMIT ?, ?', [
|
posts = await db.all('SELECT * from post ORDER BY rating DESC LIMIT ?, ?', [
|
||||||
page*rowCount,
|
page*ROW_COUNT,
|
||||||
rowCount
|
ROW_COUNT
|
||||||
|
])
|
||||||
|
} else if (id) {
|
||||||
|
posts = await db.all('SELECT * from post WHERE id = ?', [
|
||||||
|
id
|
||||||
])
|
])
|
||||||
} else {
|
} else {
|
||||||
posts = await db.all('SELECT * from post WHERE username = ? ORDER BY rating DESC LIMIT ?, ?', [
|
posts = await db.all('SELECT * from post WHERE username = ? ORDER BY rating DESC LIMIT ?, ?', [
|
||||||
user,
|
user,
|
||||||
page*rowCount,
|
page*ROW_COUNT,
|
||||||
rowCount
|
ROW_COUNT
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
posts = posts.map(post => {
|
||||||
|
return {...post, isAuthor: userAuth == post.username};
|
||||||
|
})
|
||||||
|
|
||||||
return {data: posts};
|
return {data: posts};
|
||||||
}
|
}
|
||||||
|
|
||||||
backend.vote = async ({cookies, id, vote, user}) => {
|
backend.vote = async ({id, vote, user}) => {
|
||||||
if (!id || (vote != 'down' && vote != 'up')) return {success: 'fail' };
|
if (!id || (vote != 'down' && vote != 'up')) return {success: 'fail' };
|
||||||
|
|
||||||
await db.run('DELETE FROM vote WHERE username = ? AND id = ?', [
|
await db.run('DELETE FROM vote WHERE username = ? AND id = ?', [
|
||||||
|
@ -300,12 +295,12 @@ backend.fileCreate = async({img, extension,id, last }) => {
|
||||||
if (!imgHash)
|
if (!imgHash)
|
||||||
return {'success': 'Image not provided.'}
|
return {'success': 'Image not provided.'}
|
||||||
|
|
||||||
if (imgHash.length > fileSizeLimit)
|
if (imgHash.length > FILE_SIZE_LIMIT)
|
||||||
return {'success': 'Image too big.'}
|
return {'success': 'Image too big.'}
|
||||||
|
|
||||||
const extensionSafe = extension.replace(/[^a-zA-Z]+/g, '\\$1');
|
const extensionSafe = safePath(extension);
|
||||||
|
|
||||||
if (extensionSafe != 'png' && extensionSafe != 'jpg' && extensionSafe != 'svg' && extensionSafe != 'gif')
|
if (VALID_EXTENSIONS.indexOf(extensionSafe) == -1)
|
||||||
return { success: 'Illegal file extension.' };
|
return { success: 'Illegal file extension.' };
|
||||||
|
|
||||||
writeFile(`${process.cwd()}/db/post-${imgHash}.${extensionSafe}`,imgData,{encoding: 'base64'});
|
writeFile(`${process.cwd()}/db/post-${imgHash}.${extensionSafe}`,imgData,{encoding: 'base64'});
|
||||||
|
|
|
@ -20,7 +20,7 @@ let checkRegex = function(string, field, regex) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let calcVote = function(up,down) {
|
let calcVote = function(up,down, type) {
|
||||||
var upPadded = up + 3;
|
var upPadded = up + 3;
|
||||||
var downPadded = down + 3;
|
var downPadded = down + 3;
|
||||||
var totalPadded = Math.max(up + down, 3);
|
var totalPadded = Math.max(up + down, 3);
|
||||||
|
@ -28,26 +28,20 @@ let calcVote = function(up,down) {
|
||||||
var rating = -Math.log((1 / ((((upPadded - downPadded) / (upPadded + downPadded)) + 1) / 2)) - 1) / Math.log(Math.E);
|
var rating = -Math.log((1 / ((((upPadded - downPadded) / (upPadded + downPadded)) + 1) / 2)) - 1) / Math.log(Math.E);
|
||||||
|
|
||||||
rating = Math.min(rating,10);
|
rating = Math.min(rating,10);
|
||||||
|
|
||||||
|
if (type != 'user') {
|
||||||
rating = Math.max(rating,-1);
|
rating = Math.max(rating,-1);
|
||||||
|
|
||||||
rating = (rating + 11) / 1.1;
|
rating = (rating + 11) / 1.1;
|
||||||
|
|
||||||
|
rating = rating * Math.log(totalPadded);
|
||||||
|
} else {
|
||||||
|
rating = Math.round(rating * Math.log(totalPadded) * 10);
|
||||||
|
}
|
||||||
|
|
||||||
return rating * Math.log(totalPadded);
|
return rating * Math.log(totalPadded);
|
||||||
}
|
}
|
||||||
|
|
||||||
let calcVoteUser = function(up,down) {
|
|
||||||
var upPadded = up + 3;
|
|
||||||
var downPadded = down + 3;
|
|
||||||
var totalPadded = Math.max(up + down, 3);
|
|
||||||
|
|
||||||
var rating = -Math.log((1 / ((((upPadded - downPadded) / (upPadded + downPadded)) + 1) / 2)) - 1) / Math.log(Math.E);
|
|
||||||
|
|
||||||
rating = Math.min(rating,10);
|
|
||||||
rating = Math.max(rating,-10);
|
|
||||||
|
|
||||||
return Math.round(rating * Math.log(totalPadded) * 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
let handleSubmit = async e => {
|
let handleSubmit = async e => {
|
||||||
const ACTION_URL = e.target.action
|
const ACTION_URL = e.target.action
|
||||||
|
|
||||||
|
@ -59,6 +53,10 @@ let handleSubmit = async e => {
|
||||||
}).then(x => x.text());
|
}).then(x => x.text());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let safeName = function (text) {
|
||||||
|
return text.replaceAll(/[^A-Za-z0-9\-\_]/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
let formatPost = function(post) {
|
let formatPost = function(post) {
|
||||||
post = post.split('\n');
|
post = post.split('\n');
|
||||||
|
|
||||||
|
@ -70,28 +68,25 @@ let formatPost = function(post) {
|
||||||
line = line.map(subPost => {
|
line = line.map(subPost => {
|
||||||
var splitPost = subPost.split('||');
|
var splitPost = subPost.split('||');
|
||||||
|
|
||||||
|
|
||||||
if (splitPost.length > 1) {
|
if (splitPost.length > 1) {
|
||||||
var cap1 = splitPost[0];
|
var cap1 = splitPost[0];
|
||||||
|
|
||||||
if (cap1 == 'img') {
|
if (cap1 == 'img') {
|
||||||
var matchCleaned = splitPost[1].replace(/(\s+)/g, '\\$1');
|
var matchCleaned = safeName(subPost[1]);
|
||||||
splitPost = {'type': 'img', 'url': `/img/${matchCleaned}`};
|
splitPost = {'type': 'img', 'url': `/img/${matchCleaned}`};
|
||||||
|
|
||||||
return splitPost;
|
return splitPost;
|
||||||
}
|
}
|
||||||
} else if (subPost[0] == '@') {
|
} else if (subPost[0] == '@' || subPost[0] == '#') {
|
||||||
var subPostIn = subPost.substring(0).replaceAll(/[^A-Za-z0-9\-\_]/g, '');
|
var subPostIn = safeName(subPost.substring(0));
|
||||||
|
|
||||||
splitPost = {'type': 'link', 'display': subPost, 'url': `/user/${subPostIn}`};
|
var type = (subPost[0] == '@') ? 'user' : 'post';
|
||||||
|
|
||||||
|
splitPost = {'type': 'link', 'display': subPost, 'url': `/${type}/${subPostIn}`};
|
||||||
|
|
||||||
return splitPost;
|
return splitPost;
|
||||||
|
|
||||||
} else if (subPost[0] == '#') {
|
|
||||||
var subPostIn = subPost.substring(0).replaceAll(/[^A-Za-z0-9]/g, '');
|
|
||||||
|
|
||||||
splitPost = {'type': 'link', 'display': subPost, 'url': `/post/${subPostIn}`};
|
|
||||||
|
|
||||||
return splitPost;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return subPost;
|
return subPost;
|
||||||
|
@ -102,16 +97,20 @@ let formatPost = function(post) {
|
||||||
return post;
|
return post;
|
||||||
}
|
}
|
||||||
|
|
||||||
function block(bool) {
|
let block = function(bool) {
|
||||||
return (bool) ? 'block' : 'inline';
|
return (bool) ? 'block' : 'inline';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let safePath = function(path) {
|
||||||
|
return path.replace(/[^a-zA-Z]+/g, '\\$1')
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
checkLength,
|
checkLength,
|
||||||
checkRegex,
|
checkRegex,
|
||||||
calcVote,
|
calcVote,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
calcVoteUser,
|
|
||||||
formatPost,
|
formatPost,
|
||||||
block
|
block,
|
||||||
|
safePath
|
||||||
};
|
};
|
|
@ -1,4 +1,19 @@
|
||||||
<style>
|
<style>
|
||||||
|
#content {
|
||||||
|
background: var(--light-2);
|
||||||
|
|
||||||
|
height: 100vh;
|
||||||
|
width: calc(100vw - 50px);
|
||||||
|
padding: 25px;
|
||||||
|
padding-top: 0px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
:global(:root) {
|
:global(:root) {
|
||||||
--dark-1: #2b2f36;
|
--dark-1: #2b2f36;
|
||||||
--dark-2: #d8d8d8;
|
--dark-2: #d8d8d8;
|
||||||
|
@ -23,78 +38,17 @@
|
||||||
box-shadow: 0px 2px 2.5px 0px var(--dark-2);
|
box-shadow: 0px 2px 2.5px 0px var(--dark-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#content {
|
|
||||||
background: var(--light-2);
|
|
||||||
|
|
||||||
height: 100vh;
|
|
||||||
width: calc(100vw - 50px);
|
|
||||||
padding: 25px;
|
|
||||||
padding-top: 0px;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
#logo {
|
|
||||||
|
|
||||||
width: calc(100vw - 20px);
|
|
||||||
|
|
||||||
background: var(--dark-1);
|
|
||||||
|
|
||||||
padding: 5px;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#logo a {
|
|
||||||
padding: 10px;
|
|
||||||
color: var(--light-1);
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
#logo img {
|
|
||||||
height: 30px;
|
|
||||||
width: auto;
|
|
||||||
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
/** @type {import('./$types').PageData} */
|
/** @type {import('./$types').PageData} */
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
|
import Header from '$lib/components/Header.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div id='content'>
|
<div id='content'>
|
||||||
<div id='logo'>
|
<Header data={data} />
|
||||||
<a href='/'>
|
<slot />
|
||||||
<img src='/icon_sanifae.svg' alt='Sanifae Logo'>
|
|
||||||
</a>
|
|
||||||
{#if data.username && data.username != 'false'}
|
|
||||||
<a href='/user/{data.username}'>
|
|
||||||
{data.username}
|
|
||||||
</a>
|
|
||||||
<a href='/logout'>
|
|
||||||
Log out
|
|
||||||
</a>
|
|
||||||
<a href='/new_post'>
|
|
||||||
Create
|
|
||||||
</a>
|
|
||||||
{:else}
|
|
||||||
<a href='/account'>
|
|
||||||
Log in / Register
|
|
||||||
</a>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
import Post from '$lib/components/Post.svelte';
|
import PostList from '$lib/components/PostList.svelte';
|
||||||
import Button from '$lib/components/Button.svelte'
|
|
||||||
|
|
||||||
/** @type {import('./$types').PageData} */
|
/** @type {import('./$types').PageData} */
|
||||||
export let data;
|
export let data;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#each data.postJson.data as post}
|
<PostList data={data} />
|
||||||
<Post
|
|
||||||
success={post.success}
|
|
||||||
username={post.username}
|
|
||||||
content={post.content}
|
|
||||||
upvotes={post.upvotes}
|
|
||||||
downvotes={post.downvotes}
|
|
||||||
id={post.id}
|
|
||||||
></Post>
|
|
||||||
{/each}
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<Button clickFunc={() => { window.location.search = 'page=' + ((data.id)-1) }}>Previous page</Button>
|
|
||||||
<Button clickFunc={() => { window.location.search = 'page=' + ((data.id)+1) }}>Next page</Button>
|
|
||||||
</p>
|
|
|
@ -7,10 +7,8 @@ export async function load({ fetch, params, url }) {
|
||||||
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 100));
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
|
|
||||||
const res = await fetch(`/api/postGet?id=${id}`);
|
const res = await fetch(`/api/postBulk?id=${id}`);
|
||||||
const postJson = (await res.json());
|
const postJson = (await res.json());
|
||||||
|
|
||||||
console.log(postJson);
|
return {postJson};
|
||||||
|
|
||||||
return postJson;
|
|
||||||
}
|
}
|
|
@ -1,15 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
import Post from '$lib/components/Post.svelte';
|
import PostList from '$lib/components/PostList.svelte';
|
||||||
|
|
||||||
/** @type {import('./$types').PageData} */
|
/** @type {import('./$types').PageData} */
|
||||||
export let data;
|
export let data;
|
||||||
</script>
|
</script>
|
||||||
<Post
|
|
||||||
success={data.data.success}
|
<PostList data={data} />
|
||||||
username={data.data.username}
|
|
||||||
content={data.data.content}
|
|
||||||
upvotes={data.data.upvotes}
|
|
||||||
downvotes={data.data.downvotes}
|
|
||||||
id={data.data.id}
|
|
||||||
isAuthor={data.isAuthor}
|
|
||||||
></Post>
|
|
|
@ -16,5 +16,5 @@ export async function load({ fetch, params, url }) {
|
||||||
const resUser = await fetch(`/api/userGet?user=${user}`);
|
const resUser = await fetch(`/api/userGet?user=${user}`);
|
||||||
const postJsonUser = (await resUser.json()) || {};
|
const postJsonUser = (await resUser.json()) || {};
|
||||||
|
|
||||||
return { postJson, id, postJsonUser };
|
return { postJson, id, postJsonUser, user };
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import Post from '$lib/components/Post.svelte';
|
import Button from '$lib/components/Button.svelte'
|
||||||
import Area from '$lib/components/Area.svelte';
|
import Area from '$lib/components/Area.svelte';
|
||||||
|
import PostList from '$lib/components/PostList.svelte';
|
||||||
|
|
||||||
/** @type {import('./$types').PageData} */
|
/** @type {import('./$types').PageData} */
|
||||||
export let data;
|
export let data;
|
||||||
|
@ -33,33 +34,18 @@
|
||||||
{:else}
|
{:else}
|
||||||
<Area>
|
<Area>
|
||||||
<span slot="header">
|
<span slot="header">
|
||||||
<b>
|
<a href='/users/{data.user}'>
|
||||||
Error
|
{data.user}
|
||||||
</b>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<span slot="main">
|
<span slot="main">
|
||||||
</span>
|
</span>
|
||||||
<span slot="footer">
|
<span slot="footer">
|
||||||
This user does not exist.
|
This user does not have any statistics available.
|
||||||
</span>
|
</span>
|
||||||
</Area>
|
</Area>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<h2>Posts</h2>
|
<h2>Posts</h2>
|
||||||
|
|
||||||
{#each data.postJson as data}
|
<PostList data={data} />
|
||||||
<Post
|
|
||||||
success={data.data.success}
|
|
||||||
username={data.data.username}
|
|
||||||
content={data.data.content}
|
|
||||||
upvotes={data.data.upvotes}
|
|
||||||
downvotes={data.data.downvotes}
|
|
||||||
id={data.data.id}
|
|
||||||
isAuthor={data.isAuthor}
|
|
||||||
></Post>
|
|
||||||
{/each}
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a data-sveltekit-reload href='?page={data.id+1}'>Next page</a>
|
|
||||||
</p>
|
|
||||||
<p></p>
|
|
||||||
|
|
Loading…
Reference in a new issue