Added voting. Improved comments.

This commit is contained in:
2023-06-25 19:52:00 +02:00
parent 754a89b913
commit f42daa2f83
29 changed files with 916 additions and 154 deletions

View File

@@ -0,0 +1 @@
export default '/shelf/create';

View File

@@ -0,0 +1,205 @@
<template>
<div class="content">
<h2 class="heading">Create new shelf</h2>
<form
class="form create"
@submit.prevent="create"
>
<div class="form-section">
<div class="form-row name">
<span class="prefix">s/</span>
<input
v-model="slug"
placeholder="home"
class="input"
>
</div>
<div class="form-row">
<input
v-model="title"
placeholder="Tag line"
class="input"
>
</div>
<div class="form-row">
<textarea
v-model="description"
placeholder="Description"
class="input"
/>
</div>
</div>
<div class="form-section">
<div class="form-row">
<div class="form-column">
<h4 class="form-heading">View access</h4>
<label class="access">
<input
v-model="viewAccess"
type="radio"
value="public"
class="radio"
>Public
<div class="access-description">Everyone can browse this shelf</div>
</label>
<label class="access">
<input
v-model="viewAccess"
type="radio"
value="registered"
class="radio"
>Registered
<div class="access-description">Registered shack users can browse</div>
</label>
<label class="access">
<input
v-model="viewAccess"
type="radio"
value="private"
class="radio"
>Private
<div class="access-description">Only invited users can browse</div>
</label>
</div>
<div class="form-column">
<h4 class="form-heading">Post access</h4>
<label class="access">
<input
v-model="postAccess"
type="radio"
value="registered"
class="radio"
>Registered
<div class="access-description">Registered users can post</div>
</label>
<label class="access">
<input
v-model="postAccess"
type="radio"
value="private"
class="radio"
>Private
<div class="access-description">Only invited users can post</div>
</label>
</div>
</div>
</div>
<div class="form-section">
<label class="check-container">
<span>
<span class="nsfw">NSFW 18+</span>
<span class="description">This community allows explicit content</span>
</span>
<Checkbox
:checked="isNsfw"
@change="(checked) => isNsfw = checked"
/>
</label>
</div>
<div class="form-row form-actions">
<button class="button button-submit">Create shelf</button>
</div>
</form>
</div>
</template>
<script setup>
import { ref } from 'vue';
import Checkbox from '../../components/form/checkbox.vue';
import { post } from '../../assets/js/api';
import { navigate } from '../../assets/js/navigate';
const slug = ref();
const title = ref();
const description = ref();
const viewAccess = ref('public');
const postAccess = ref('registered');
const isNsfw = ref(false);
async function create() {
const shelf = await post('/shelves', {
slug: slug.value,
title: title.value,
description: description.value,
settings: {
viewAccess: viewAccess.value,
postAccess: postAccess.value,
isNsfw: isNsfw.value,
},
});
console.log(shelf);
navigate(`/s/${shelf.slug}`);
}
</script>
<style scoped>
.content {
display: flex;
justify-content: center;
align-items: center;
}
.create {
background: var(--background);
padding: 1rem;
border-radius: .5rem;
}
.name {
position: relative;
.input {
padding-left: 1.65rem;
}
.prefix {
color: var(--shadow);
position: absolute;
top: 1px;
left: .25rem;
letter-spacing: .1rem;
padding: .5rem;
}
}
.access {
font-weight: bold;
margin-bottom: .75rem;
cursor: pointer;
}
.access-description {
margin: .25rem 0 0 1.25rem;
color: var(--shadow);
font-size: .9rem;
font-weight: normal;
}
.nsfw {
margin-right: .5rem;
font-weight: bold;
color: var(--error);
}
</style>

View File

@@ -0,0 +1 @@
export default '/s/@id';

View File

@@ -0,0 +1,25 @@
import { RenderErrorPage } from 'vite-plugin-ssr/RenderErrorPage';
import { fetchShelf } from '../../src/shelves';
import { fetchShelfPosts } from '../../src/posts';
async function getPageData(pageContext) {
const shelf = await fetchShelf(pageContext.routeParams.id);
const posts = await fetchShelfPosts(pageContext.routeParams.id, { user: pageContext.session.user, limit: 50 });
if (!shelf) {
throw RenderErrorPage({
pageContext: {
pageProps: {
errorInfo: 'No shelf with this name exists',
},
},
});
}
return {
shelf,
posts,
};
}
export { getPageData };

View File

@@ -0,0 +1,86 @@
<template>
<div class="content">
<h3>{{ shelf.slug }}</h3>
<ul class="posts nolist">
<li
v-for="post in posts"
:key="post.id"
>
<Post
:post="post"
:shelf="shelf"
/>
</li>
</ul>
<form
class="form compose"
@submit.prevent="submitPost"
>
<div class="form-row">
<input
v-model="title"
placeholder="Title"
class="input"
>
</div>
<div class="form-row">
<input
v-model="link"
class="input"
placeholder="Link"
>
</div>
<div class="form-row">
<textarea
v-model="body"
placeholder="Body"
class="input body"
/>
</div>
<div class="form-actions">
<button class="button button-submit">Post</button>
</div>
</form>
</div>
</template>
<script setup>
import { ref } from 'vue';
import Post from '../../components/posts/post.vue';
import * as api from '../../assets/js/api';
import { navigate } from '../../assets/js/navigate';
import { usePageContext } from '../../renderer/usePageContext';
const { pageData, routeParams } = usePageContext();
const {
shelf,
posts,
} = pageData;
const title = ref();
const link = ref();
const body = ref();
async function submitPost() {
const post = await api.post(`/shelves/${routeParams.id}/posts`, {
title: title.value,
link: link.value,
body: body.value,
});
navigate(`/s/${shelf.slug}/post/${post.id}`);
}
</script>
<style scoped>
.posts {
margin-bottom: 1rem;
}
</style>