Added voting. Improved comments.
This commit is contained in:
1
pages/shelves/create.page.route.js
Normal file
1
pages/shelves/create.page.route.js
Normal file
@@ -0,0 +1 @@
|
||||
export default '/shelf/create';
|
||||
205
pages/shelves/create.page.vue
Normal file
205
pages/shelves/create.page.vue
Normal 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>
|
||||
1
pages/shelves/shelf.page.route.js
Normal file
1
pages/shelves/shelf.page.route.js
Normal file
@@ -0,0 +1 @@
|
||||
export default '/s/@id';
|
||||
25
pages/shelves/shelf.page.server.js
Normal file
25
pages/shelves/shelf.page.server.js
Normal 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 };
|
||||
86
pages/shelves/shelf.page.vue
Normal file
86
pages/shelves/shelf.page.vue
Normal 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>
|
||||
Reference in New Issue
Block a user