mirror of
https://gitlab.com/Alamantus/Readlebee.git
synced 2025-09-03 01:34:26 +02:00
Compare commits
8 commits
596721fb2d
...
8721810bc6
Author | SHA1 | Date | |
---|---|---|---|
8721810bc6 | |||
2ea0015e70 | |||
e991169075 | |||
2b95ab81c1 | |||
6dab28e7a5 | |||
496787263b | |||
ea87184bb3 | |||
71516dd833 |
13 changed files with 219 additions and 92 deletions
|
@ -2,14 +2,25 @@
|
|||
"name": "English",
|
||||
"locale": "en",
|
||||
"home": {
|
||||
"subtitle": "An attempt at a viable alternative to Goodreads",
|
||||
"temp_left": "Still gotta figure out a design.",
|
||||
"temp_right": "It's early days, my friends!"
|
||||
"logged_out_subtitle": "All the Book Buzz in Once Place",
|
||||
"logged_out_track_books": "Keep track of books you've read, want to read, and are currently reading.",
|
||||
"logged_out_share_friends": "Share your thoughts about what you're reading and see what your friends think of their books.",
|
||||
"logged_out_read_rate": "Rate, review, and recommmend books or something. I dunno. It's early days, my friends!",
|
||||
"logged_out_community_header": "A Look Inside the Hive",
|
||||
"logged_out_recent_reviews": "Recent Reviews",
|
||||
"logged_out_recent_updates": "Recent Updates",
|
||||
"logged_out_join_now": "Join Now!"
|
||||
},
|
||||
"login": {
|
||||
"log_in": "Log In",
|
||||
"email": "Email",
|
||||
"password": "Password",
|
||||
"login_button": "Log In!"
|
||||
"login_button": "Log In!",
|
||||
"create_account": "Create a New Account",
|
||||
"confirm_password": "Confirm Password",
|
||||
"username": "Username",
|
||||
"display_name": "Display Name",
|
||||
"create_account_button": "Create Account!"
|
||||
},
|
||||
"search": {
|
||||
"header": "Search",
|
||||
|
@ -22,6 +33,7 @@
|
|||
"see_details_tooltip": "Opens Inventaire in a new tab/window"
|
||||
},
|
||||
"interaction": {
|
||||
"reload": "Reload",
|
||||
"heart": "Like",
|
||||
"add": "Add to Shelf",
|
||||
"average_rating": "Average Rating",
|
||||
|
|
|
@ -59,6 +59,7 @@ app.use((state, emitter) => {
|
|||
state.currentView = 'home';
|
||||
state.language = app.getSettingsItem('lang') ? app.getSettingsItem('lang') : (navigator.language || navigator.userLanguage).split('-')[0];
|
||||
state.viewStates = {};
|
||||
state.isLoggedIn = false;
|
||||
}
|
||||
|
||||
// Listeners
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// Picnic Overrides
|
||||
body {
|
||||
font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
|
||||
}
|
||||
|
@ -18,11 +19,9 @@ nav {
|
|||
position: relative;
|
||||
}
|
||||
|
||||
footer nav {
|
||||
.links {
|
||||
@extend .brand;
|
||||
font-weight: unset;
|
||||
}
|
||||
.pseudo[data-tooltip]::after {
|
||||
background-color: $picnic-black;
|
||||
color: $picnic-white;
|
||||
}
|
||||
|
||||
// External links
|
||||
|
@ -35,11 +34,19 @@ a[href^="https://"]:after{
|
|||
content: "\f08e";
|
||||
}
|
||||
|
||||
// New components
|
||||
.menu ul li {
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
footer nav {
|
||||
.links {
|
||||
@extend .brand;
|
||||
font-weight: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
display: block;
|
||||
width: 75%;
|
||||
|
@ -131,6 +138,7 @@ th {
|
|||
}
|
||||
}
|
||||
|
||||
// Handy Utilities
|
||||
.paddingless {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
@ -140,8 +148,11 @@ th {
|
|||
.italic {
|
||||
font-style: italic !important;
|
||||
}
|
||||
.large {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
.small {
|
||||
font-size: 80%;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
.left-align {
|
||||
text-align: left !important;
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
|
||||
// Colors (from /themes/default/colors)
|
||||
$picnic-white: #fff !default;
|
||||
$picnic-black: #111 !default;
|
||||
$picnic-white: $white !default;
|
||||
$picnic-black: $black !default;
|
||||
$picnic-primary: $teal !default;
|
||||
$picnic-success: $green !default;
|
||||
$picnic-info: $blue !default;
|
||||
|
|
|
@ -12,4 +12,8 @@ export class ViewController {
|
|||
}
|
||||
this.state = this.appState.viewStates[viewName];
|
||||
}
|
||||
|
||||
get isLoggedIn () {
|
||||
return this.appState.isLoggedIn;
|
||||
}
|
||||
}
|
|
@ -5,11 +5,8 @@ export class HomeController extends ViewController {
|
|||
// Super passes state, view name, and default state to ViewController,
|
||||
// which stores state in this.appState and the view controller's state to this.state
|
||||
super(state, 'home', {
|
||||
messages: [
|
||||
'hello',
|
||||
'test',
|
||||
'yay',
|
||||
],
|
||||
recentReviews: [],
|
||||
recentUpdates: [],
|
||||
});
|
||||
|
||||
// If using controller methods in an input's onchange or onclick instance,
|
||||
|
@ -17,7 +14,10 @@ export class HomeController extends ViewController {
|
|||
// or use `onclick=${() => controller.submit()}` to maintain the 'this' of the class instead.
|
||||
}
|
||||
|
||||
get messages() {
|
||||
return [...this.state.messages];
|
||||
get recentReviews() {
|
||||
return [...this.state.recentReviews];
|
||||
}
|
||||
get recentUpdates() {
|
||||
return [...this.state.recentUpdates];
|
||||
}
|
||||
}
|
|
@ -1,42 +1,18 @@
|
|||
import html from 'choo/html';
|
||||
|
||||
import './styles.scss'; // Creates a separate CSS file, but allows better code splitting.
|
||||
// We'll see if code splitting is worth it in the end or if we should combine everything into `src/index.scss`
|
||||
import { HomeController } from './controller'; // The controller for this view, where processing should happen.
|
||||
import { loggedOutView } from './loggedOut';
|
||||
|
||||
// This is the view function that is exported and used in the view manager.
|
||||
export const homeView = (state, emit) => {
|
||||
const controller = new HomeController(state);
|
||||
const { i18n } = controller;
|
||||
|
||||
// Returning an array in a view allows non-shared parent HTML elements.
|
||||
// This one doesn't have the problem right now, but it's good to remember.
|
||||
return [
|
||||
html`<section>
|
||||
<h2 class="subtitle">${i18n.__('home.subtitle')}</h2>
|
||||
|
||||
<article class="flex two">
|
||||
<div class="half">
|
||||
<div class="card">
|
||||
<header>
|
||||
<p>${i18n.__('home.temp_left')}</p>
|
||||
</header>
|
||||
</div>
|
||||
</div>
|
||||
<div class="half">
|
||||
<div class="card">
|
||||
<header>
|
||||
<p>${i18n.__('home.temp_right')}</p>
|
||||
</header>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="test">
|
||||
${controller.messages.map(message => {
|
||||
return html`<p>${message}</p>`;
|
||||
})}
|
||||
</article>
|
||||
</section>`,
|
||||
(!controller.isLoggedIn
|
||||
? loggedOutView(controller, emit)
|
||||
: html`<p>lol wut how are u logged in</p>`
|
||||
),
|
||||
];
|
||||
}
|
83
app/views/home/loggedOut.js
Normal file
83
app/views/home/loggedOut.js
Normal file
|
@ -0,0 +1,83 @@
|
|||
import html from 'choo/html';
|
||||
|
||||
export const loggedOutView = (homeController, emit) => {
|
||||
const { i18n } = homeController;
|
||||
|
||||
return [
|
||||
html`<section>
|
||||
<h2>${i18n.__('home.logged_out_subtitle')}</h2>
|
||||
<article class="flex one three-500">
|
||||
<div>
|
||||
<div class="card">
|
||||
<header class="center-align">
|
||||
<span style="font-size:32pt;color:green;">
|
||||
<i class="icon-check"></i>
|
||||
</span>
|
||||
</header>
|
||||
<footer>
|
||||
${i18n.__('home.logged_out_track_books')}
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="card">
|
||||
<header class="center-align">
|
||||
<span style="font-size:32pt;color:red;">
|
||||
<i class="icon-heart-filled"></i>
|
||||
</span>
|
||||
</header>
|
||||
<footer>
|
||||
${i18n.__('home.logged_out_share_friends')}
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="card">
|
||||
<header class="center-align">
|
||||
<span style="font-size:32pt;color:yellow;">
|
||||
<i class="icon-star"></i>
|
||||
</span>
|
||||
</header>
|
||||
<footer>
|
||||
${i18n.__('home.logged_out_read_rate')}
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</section>`,
|
||||
html`<section>
|
||||
<h2>${i18n.__('home.logged_out_community_header')}</h2>
|
||||
<div class="flex one two-700">
|
||||
<div>
|
||||
<div class="card">
|
||||
<header>
|
||||
<h3>${i18n.__('home.logged_out_recent_reviews')}</h3>
|
||||
<button class="small pseudo pull-right tooltip-left" data-tooltip=${i18n.__('interaction.reload')}>
|
||||
<i class="icon-loading"></i><!--/* This needs to get updated to a reload icon */-->
|
||||
</button>
|
||||
</header>
|
||||
<footer>
|
||||
${homeController.recentReviews.map(review => reviewCard(homeController, review))}
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="card">
|
||||
<header>
|
||||
<h3>${i18n.__('home.logged_out_recent_updates')}</h3>
|
||||
<button class="small pseudo pull-right tooltip-left" data-tooltip=${i18n.__('interaction.reload')}>
|
||||
<i class="icon-loading"></i><!--/* This needs to get updated to a reload icon */-->
|
||||
</button>
|
||||
</header>
|
||||
<footer>
|
||||
${homeController.recentUpdates.map(review => reviewCard(homeController, review))}
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>`,
|
||||
html`<section class="center-align">
|
||||
<a href="/login" class="large success button">${i18n.__('home.logged_out_join_now')}</a>
|
||||
</section>`,
|
||||
];
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
.test {
|
||||
background-color: #dddddd;
|
||||
padding: 10px;
|
||||
|
||||
p {
|
||||
border: 1px solid #444444;
|
||||
}
|
||||
}
|
|
@ -8,19 +8,56 @@ export const loginView = (state, emit) => {
|
|||
|
||||
return html`<section>
|
||||
|
||||
<article class="card">
|
||||
<div class="container wide">
|
||||
<label>
|
||||
<span>${i18n.__('login.email')}</span>
|
||||
<input type="email" name="email">
|
||||
</label>
|
||||
<label>
|
||||
<span>${i18n.__('login.password')}</span>
|
||||
<input type="password" name="password">
|
||||
</label>
|
||||
<input type="submit" value="${i18n.__('login.login_button')}">
|
||||
<div class="flex one two-700">
|
||||
<div>
|
||||
<article class="card">
|
||||
<header>
|
||||
<h3>${i18n.__('login.log_in')}</h3>
|
||||
</header>
|
||||
<footer>
|
||||
<label>
|
||||
<span>${i18n.__('login.email')}</span>
|
||||
<input type="email" name="email">
|
||||
</label>
|
||||
<label>
|
||||
<span>${i18n.__('login.password')}</span>
|
||||
<input type="password" name="password">
|
||||
</label>
|
||||
<input type="submit" value="${i18n.__('login.login_button')}">
|
||||
</footer>
|
||||
</article>
|
||||
</div>
|
||||
<div>
|
||||
<article class="card">
|
||||
<header>
|
||||
<h3>${i18n.__('login.create_account')}</h3>
|
||||
</header>
|
||||
<footer>
|
||||
<label>
|
||||
<span>${i18n.__('login.email')}</span>
|
||||
<input type="email" name="new_email">
|
||||
</label>
|
||||
<label>
|
||||
<span>${i18n.__('login.password')}</span>
|
||||
<input type="password" name="new_password">
|
||||
</label>
|
||||
<label>
|
||||
<span>${i18n.__('login.confirm_password')}</span>
|
||||
<input type="password" name="confirm_password">
|
||||
</label>
|
||||
<label>
|
||||
<span>${i18n.__('login.username')}</span>
|
||||
<input type="text" name="new_username">
|
||||
</label>
|
||||
<label>
|
||||
<span>${i18n.__('login.display_name')}</span>
|
||||
<input type="text" name="new_displayname">
|
||||
</label>
|
||||
<input type="submit" class="success" value="${i18n.__('login.create_account_button')}">
|
||||
</footer>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
</section>`;
|
||||
|
||||
</section>`;
|
||||
}
|
29
app/views/partials/reviewCard.js
Normal file
29
app/views/partials/reviewCard.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
import html from 'choo/html';
|
||||
|
||||
import { starRating } from './starRating';
|
||||
|
||||
export const reviewCard = (controller, review) => {
|
||||
const { i18n } = controller;
|
||||
|
||||
return html`<article class="card">
|
||||
<header style="font-weight:normal;">
|
||||
<strong>${review.reviewer.name}</strong> <em>${review.reviewer.handle}</em><br>
|
||||
${review.date} ${starRating(Math.ceil(review.rating))}
|
||||
</header>
|
||||
<footer>
|
||||
<div class="content">
|
||||
<p>
|
||||
${review.review}
|
||||
</p>
|
||||
</div>
|
||||
<span class="tooltip-top" data-tooltip=${i18n.__('interaction.heart')}>
|
||||
<button class="pseudo">
|
||||
<i class="icon-heart-outline"></i>
|
||||
</button>
|
||||
</span>
|
||||
<span>
|
||||
${review.hearts}
|
||||
</span>
|
||||
</footer>
|
||||
</article>`;
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import html from 'choo/html';
|
||||
|
||||
import { reviewCard } from '../partials/reviewCard';
|
||||
import { starRating } from '../partials/starRating';
|
||||
import { modal } from '../partials/modal';
|
||||
|
||||
|
@ -70,27 +71,7 @@ export const resultDetails = (searchController, result, emit = () => {}) => {
|
|||
</div>
|
||||
</div>
|
||||
${result.reviews.map(review => {
|
||||
return html`<article class="card">
|
||||
<header style="font-weight:normal;">
|
||||
<strong>${review.reviewer.name}</strong> <em>${review.reviewer.handle}</em><br>
|
||||
${review.date} ${starRating(Math.ceil(review.rating))}
|
||||
</header>
|
||||
<footer>
|
||||
<div class="content">
|
||||
<p>
|
||||
${review.review}
|
||||
</p>
|
||||
</div>
|
||||
<span class="tooltip-top" data-tooltip=${i18n.__('interaction.heart')}>
|
||||
<button class="pseudo">
|
||||
<i class="icon-heart-outline"></i>
|
||||
</button>
|
||||
</span>
|
||||
<span>
|
||||
${review.hearts}
|
||||
</span>
|
||||
</footer>
|
||||
</article>`;
|
||||
return reviewCard(searchController, review);
|
||||
})}
|
||||
</div>
|
||||
<div class="sixth-700">
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
"start": "npm run build && cross-env NODE_ENV=production npm run serve",
|
||||
"watch-js": "parcel watch app/index.html --out-dir public --no-hmr --no-cache",
|
||||
"serve": "node server/index.js",
|
||||
"build": "npm run process-images && parcel build app/index.html --out-dir public --no-source-maps --no-cache",
|
||||
"build": "npm run process-images && npm run bundle",
|
||||
"bundle": "parcel build app/index.html --out-dir public --no-source-maps --no-cache",
|
||||
"process-images": "node ./process-images.js",
|
||||
"clear": "rimraf public/{*,.*}"
|
||||
},
|
||||
|
|
Loading…
Add table
Reference in a new issue