New frontend styling!

This commit is contained in:
gmemstr 2017-11-21 10:38:58 -08:00
parent f3779aa4bd
commit 01465fd4a7
7 changed files with 146 additions and 34 deletions

View file

@ -31,8 +31,12 @@ type User struct {
type UserList struct { type UserList struct {
Users []User Users []User
} }
/*
* The following is a set of admin commands
* that the average user probably shouldn't be
* able to have access to, mostly user management.
*/
// Add user to the SQLite3 database
func AddUser() common.Handler { func AddUser() common.Handler {
return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError { return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError {
@ -265,6 +269,10 @@ func ListUsers() common.Handler {
} }
} }
/*************************************
* End of "sensitive" admin functions
* ***********************************/
// Write custom CSS to disk or send it back to the client if GET // Write custom CSS to disk or send it back to the client if GET
func CustomCss() common.Handler { func CustomCss() common.Handler {
@ -343,7 +351,7 @@ func EditEpisode() common.Handler {
StatusCode: http.StatusBadRequest, StatusCode: http.StatusBadRequest,
} }
} }
w.Write([]byte("<script>window.location = '/admin#published';</script>")) w.Write([]byte("<script>window.location = '/admin#/msg/Episode%20Published!';</script>"))
return nil return nil
} }
} }

View file

@ -3,6 +3,6 @@
"Host": "Gabriel Simmer", "Host": "Gabriel Simmer",
"Email": "admin@localhost", "Email": "admin@localhost",
"Description": "Discussion about open source projects on the internet.", "Description": "Discussion about open source projects on the internet.",
"Image": "localhost:8000/assets/logo-xs.png", "Image": "localhost:3000/assets/logo-xs.png",
"PodcastUrl": "http://localhost:8000" "PodcastUrl": "http://localhost:3000"
} }

View file

@ -9,14 +9,15 @@
<body> <body>
<div class="container"> <div class="container">
<div id="app"> <div id="app">
<router-link to="/publish">Publish</router-link> <router-link to="/theme">Theme</router-link> <router-link to="/manage">Manage</router-link> <router-link to="/users">Users</router-link> <nav>
<router-link to="/publish">Publish</router-link> <router-link to="/manage">Episodes</router-link> <router-link to="/theme">Theme</router-link> <router-link to="/users">Users</router-link></nav>
<h1>{{ header }}</h1> <h1>{{ header }}</h1>
<router-view></router-view> <router-view></router-view>
</div> </div>
</div>
<footer> <footer>
<p>Pogo licensed under the GPLv3</p> <p>Pogo licensed under the GPLv3</p>
</footer> </footer>
</div>
<script src="/assets/vue.js"></script> <script src="/assets/vue.js"></script>
<script src="https://unpkg.com/vue-router@2.7.0/dist/vue-router.js"></script> <script src="https://unpkg.com/vue-router@2.7.0/dist/vue-router.js"></script>
<script src="/assets/app.js"></script> <script src="/assets/app.js"></script>

View file

@ -12,12 +12,14 @@
</head> </head>
<body> <body>
<div class="container"> <div class="container">
<div class="main">
<h1 id="title" class="title">Loading</h1> <h1 id="title" class="title">Loading</h1>
<h3><a href="/admin" class="adminlink">Admin</a></h3> <h3><a href="/admin" class="adminlink">Admin</a></h3>
<div id="podcasts" class="podcastlist"> <div id="podcasts" class="podcastlist">
</div> </div>
</div>
<footer> <footer>
<p>Pogo licensed under the GPLv3 | <a href="/rss">RSS Feed</a> <p>Pogo licensed under the GPLv3 | <a href="/rss">RSS Feed</a>
</footer> </footer>

View file

@ -1,16 +1,16 @@
const episodepublishform = { const episodepublishform = {
template: `<div> template: `<div>
<h3>Publish Episode</h3> <h3>Publish Episode</h3>
<form enctype="multipart/form-data" action="/admin/publish" method="post"> <form enctype="multipart/form-data" action="/admin/publish" method="post" class="publish">
<label for="title">Episode Title</label> <label for="title">Episode Title</label>
<input type="text" id="title" name="title"> <input type="text" id="title" name="title">
<label for="description">Episode Description</label> <label for="description">Episode Description</label>
<textarea name="description" id="description" cols="100" rows="20" style="resize: none;"></textarea> <textarea name="description" id="description" style="resize: none;" class="epdesc"></textarea>
<label for="file">Media File</label> <label for="file">Media File</label>
<input type="file" id="file" name="file"> <input type="file" id="file" name="file">
<label for="date">Publish Date</label> <label for="date">Publish Date</label>
<input type="date" id="date" name="date"> <input type="date" id="date" name="date"><br /><br />
<input type="submit" value="Publish"> <input type="submit" value="Publish" class="button">
</form> </form>
</div>` </div>`
} }
@ -21,18 +21,18 @@ const message = {
const userlist = { const userlist = {
template: `<div> template: `<div>
<router-link :to="\'users/new\'">New</router-link> <router-link :to="\'users/new\'" tag="button">New</router-link>
<table style="width:100%"> <table>
<tr> <tr>
<th>Username</th> <th>Username</th>
<th>Email</th> <th>Email</th>
<th>Edit</th> <th></th>
</tr> </tr>
<tr v-for="item in items"> <tr v-for="item in items">
<td>{{ item.username }}</td> <td>{{ item.username }}</td>
<td>{{ item.email }}</td> <td>{{ item.email }}</td>
<td> <td>
<router-link :to="\'user/\' + item.id">Edit</router-link> <router-link :to="\'user/\' + item.id" class="button">Edit</router-link>
</td> </td>
</tr> </tr>
</table> </table>
@ -91,8 +91,8 @@ const usernew = {
<label for="password">New Password</label> <label for="password">New Password</label>
<input type="password" id="password" name="password"> <input type="password" id="password" name="password">
<br /> <br /><br />
<input type="submit" value="Save"></form> <input type="submit" class="button" value="Save"></form>
</div> </div>
</div>` </div>`
} }
@ -116,9 +116,9 @@ const useredit = {
<label for="oldpw">Old Password</label> <label for="oldpw">Old Password</label>
<input type="password" id="oldpw" name="oldpw"> <input type="password" id="oldpw" name="oldpw">
<input name="id" id="id" :value="user.id" type="hidden"> <input name="id" id="id" :value="user.id" type="hidden">
<br /> <br /><br />
<input type="submit" value="Save"></form> <input type="submit" class="button" value="Save" class="button"></form>
<a v-bind:href="'/admin/deleteuser/'+user.id+''">Delete User</a> <a v-bind:href="'/admin/deleteuser/'+user.id+''" class="button">Delete User</a>
</div> </div>
</div>`, </div>`,
data() { data() {
@ -168,10 +168,12 @@ const episodemanagement = {
template: `<div> template: `<div>
<table style="width:100%"> <table style="width:100%">
<tr> <tr>
<th>Title</th><th>URL</th><th>Actions</th> <th>Title</th>
<th>URL</th>
<th></th>
</tr> </tr>
<tr v-for="item in items"> <tr v-for="item in items">
<td>{{ item.id }}: {{ item.title }}</td><td>{{ item.url }}</td><td><router-link :to="\'edit/\' + item.id">Edit</router-link></td> <td>{{ item.id }}: {{ item.title }}</td><td>{{ item.url }}</td><td><router-link class="button" :to="\'edit/\' + item.id">Edit</router-link></td>
</tr> </tr>
</table> </table>
</div>`, </div>`,
@ -227,7 +229,7 @@ const episodeedit = {
<label for="date">Publish Date</label> <label for="date">Publish Date</label>
<input type="date" id="date" name="date" :value="episode.time"> <input type="date" id="date" name="date" :value="episode.time">
<input name="previousfilename" id="previousfilename" :value="episode.previousfilename" type="hidden"> <input name="previousfilename" id="previousfilename" :value="episode.previousfilename" type="hidden">
<input type="submit" value="Publish"></form> <input type="submit" class="button" value="Publish"></form>
</div> </div>
</div>`, </div>`,
data() { data() {
@ -280,12 +282,11 @@ const episodeedit = {
const customcss = { const customcss = {
template: `<div> template: `<div>
<h3>Edit CSS</h3> <h3>Theme</h3>
<form action="/admin/css" method="post" enctype="multipart/form-data"> <form action="/admin/css" method="post" enctype="multipart/form-data">
<label for="css">Custom CSS</label> <textarea spellcheck="false" name="css" id="css" cols="120" rows="20" class="css">{{ css }}</textarea>
<textarea name="css" id="css" cols="120" rows="20">{{ css }}</textarea> <br /><br />
<br /> <input type="submit" class="button" value="Submit" class="button">
<input type="submit" value="Submit">
</form> </form>
</div>`, </div>`,
data() { data() {
@ -322,6 +323,7 @@ const customcss = {
} }
const routes = [ const routes = [
{path: '/', redirect: '/publish'},
{ path: '/publish', component: episodepublishform }, { path: '/publish', component: episodepublishform },
{ path: '/manage', component: episodemanagement }, { path: '/manage', component: episodemanagement },
{ path: '/theme', component: customcss }, { path: '/theme', component: customcss },

View file

@ -8,7 +8,27 @@
.container {} /* Basic container from styles.css */ .container {} /* Basic container from styles.css */
.title {} /* Page title */ .title {} /* Page title */
.adminlink {} /* Link to admin interface */ .adminlink { /* Link to admin interface */
margin-left:100%;
display:inline-block;
margin-bottom: 10px;
background-color: #397AD6;
border: none;
color: white;
padding: 5px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
-webkit-transition:.52s;
-moz-transition: .5s;
-o-transition: .5s;
-ms-transition: .5s;
transition:.5s;
}
.adminlink:hover {
background-color: #50B7D5;
}
.podcastlist {} /* Chronological podcast list */ .podcastlist {} /* Chronological podcast list */

View file

@ -12,13 +12,68 @@ body {
h1,h2,h3,h4,h5 { h1,h2,h3,h4,h5 {
font-weight: 400; font-weight: 400;
} }
.container { .podcastlist {
margin: 0 auto; padding-bottom: 10%;
padding: 0 2.0rem; }
position: relative; .container {
width: 60vw; margin: 0 auto;
padding: 0 2.0rem;
position: relative;
width: 60vw;
height: 100%;
}
button, .button {
margin-bottom: 10px;
background-color: #397AD6;
border: none;
color: white;
padding: 5px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
-webkit-transition:.52s;
-moz-transition: .5s;
-o-transition: .5s;
-ms-transition: .5s;
transition:.5s;
}
button:hover, .button:hover {
background-color: #50B7D5;
}
footer {
position: absolute;
right: 0;
bottom: 0;
left: 0;
padding: .25rem;
color: #f9f9f9;
background-color: #397AD6;
text-align: center;
}
table {
text-align: left;
width: 100%;
}
nav a {
margin-bottom: 10px;
background-color: #397AD6;
border: none;
color: white;
padding: 5px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
-webkit-transition:.52s;
-moz-transition: .5s;
-o-transition: .5s;
-ms-transition: .5s;
transition:.5s;
}
nav a:hover {
background-color: #50B7D5;
} }
.podcast { .podcast {
width:70%; width:70%;
} }
@ -39,3 +94,27 @@ hr {
text-align: center; text-align: center;
} }
.css {
font-family: Monospace;
}
input[type=text], input[type=date], input[type=file], input[type=password],textarea {
padding:10px;
border-radius: 4px;
box-sizing: border-box;
border: 1px solid #397AD6;
}
.publish [type=text],
.publish input[type=date],
.publish input[type=file],
.publish input[type=password],
.publish textarea {
width: 100%;
}
.publish textarea {
height: 30vh;
}
.epdesc {
font-family: 'Muli', sans-serif;
}