Skip to content

Commit

Permalink
Add README info.
Browse files Browse the repository at this point in the history
  • Loading branch information
alessandrojean committed Feb 24, 2021
1 parent f0df764 commit 1a507c2
Show file tree
Hide file tree
Showing 9 changed files with 244 additions and 34 deletions.
3 changes: 3 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
VUE_APP_TITLE=Toshokan
VUE_APP_CLIENT_ID=
VUE_APP_CLIENT_SECRET=
VUE_APP_CBL_QUERY_KEY=
20 changes: 20 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
The MIT License (MIT)

Copyright (c) 2021 Alessandro Jean

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
64 changes: 40 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
# toshokan

## Project setup
```
yarn install
```

### Compiles and hot-reloads for development
```
yarn serve
```

### Compiles and minifies for production
```
yarn build
```

### Lints and fixes files
```
yarn lint
```

### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
# Toshokan

Toshokan is a progressive web app on top of Google Sheets written
in Vue.

It compiles in a static HTML that works great on mobile and can
be deployed anywhere.

It was inspired by the [expenses](https://github.com/jakubgarfield/expenses)
by jakubgarfield, and it uses the Vuetify components and Material Design Icons.

## Features

- Fill required book information by ISBN (only Brazilian editions);
- Automatically get the cover image from Amazon or from the publisher site;
- Generate monthly statistics.

## Get started

You will need the most recent version of Node and a place to deploy
static HTML under a custom domain with support to HTTPS.

1. Copy this [sheet](#) to your Google Drive. After sign in, choose
`File -> Make a copy...`.
2. Don't rename it. It should be named `Toshokan`.
3. Clone this repo, install the dependencies, setup the variables in `.env`
and build the app.

```console
$ yarn install && yarn build
```
4. Copy the content of `build` folder to your server.
5. That's it! You can start adding books now.

## License

> You can check out the full license [here](LICENSE).
This repository is licensed under the terms of the **MIT** license.

14 changes: 12 additions & 2 deletions src/components/VCustomImg.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ export default {
}
},
data: vm => ({
data: () => ({
error: '',
srcToShow: vm.src.length > 0 ? vm.src : placeholder
srcToShow: ''
}),
computed: {
Expand Down Expand Up @@ -80,6 +80,16 @@ export default {
cover.src = this.src
}
},
mounted () {
this.srcToShow = this.src.length > 0 ? this.src : placeholder
},
watch: {
src (newValue) {
this.srcToShow = newValue.length > 0 ? newValue : placeholder
}
}
}
</script>
13 changes: 12 additions & 1 deletion src/router/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
// import goTo from 'vuetify/es5/services/goto'

import store from '../store'

import Home from '@/views/Home.vue'

import DashboardHome from '@/views/DashboardHome'
import DashboardCollection from '@/views/DashboardCollection'
import DashboardList from '@/views/DashboardList'
Expand Down Expand Up @@ -117,6 +117,17 @@ const routes = [
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
// scrollBehavior: (to, from, savedPosition) => {
// let scrollTo = 0

// if (to.hash) {
// scrollTo = to.hash
// } else {
// scrollTo = savedPosition.y
// }

// return goTo(scrollTo)
// },
routes
})

Expand Down
1 change: 1 addition & 0 deletions src/views/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
app
color="primary"
dark
hide-on-scroll
>
<v-app-bar-nav-icon
v-if="!backButton"
Expand Down
153 changes: 149 additions & 4 deletions src/views/DashboardDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,15 @@
{{ book.status === 'Lido' ? 'mdi-book-check' : 'mdi-book-remove-outline' }}
</v-icon>
</v-btn>

<v-btn
icon
color="primary"
title="Editar a imagem de capa"
@click="showCoverDialog"
>
<v-icon>mdi-image-edit-outline</v-icon>
</v-btn>
</v-card-actions>
</v-card>
</v-col>
Expand Down Expand Up @@ -258,10 +267,8 @@
max-width="700px"
>
<v-card>
<v-card-title class="pt-6">
<span class="headline">
Editar o item
</span>
<v-card-title>
Editar o item
</v-card-title>
<v-card-text>
<v-container class="pa-0 pt-6">
Expand Down Expand Up @@ -324,11 +331,88 @@
</v-card-actions>
</v-card>
</v-dialog>

<v-dialog
v-model="coverDialog"
max-width="700px"
>
<v-card>
<v-card-title>
Editar a imagem de capa
</v-card-title>

<v-card-text>
<v-container class="pa-0 pt-6">
<v-text-field
v-model="coverUrl"
:error-messages="coverUrlErrors"
label="Imagem de capa"
outlined
@input="$v.coverUrl.$touch()"
@blur="$v.coverUrl.$touch()"
/>

<v-row
v-if="!$v.coverUrl.$invalid"
class="mt-2 mb-10"
>
<v-col
lg="4"
offset-lg="4"
md="6"
offset-md="3"
>
<v-card>
<v-custom-img
:src="editingBook.coverUrl"
:aspect-ratio="2 / 3"
/>
</v-card>
</v-col>
</v-row>
</v-container>
</v-card-text>

<v-card-actions>
<v-btn
color="primary"
text
:loading="coverLoading"
@click.stop="handleCoverSearchClick"
>
Procurar
</v-btn>

<v-spacer />

<v-btn
color="primary"
text
:disabled="coverLoading"
@click.stop="handleCoverCancelClick"
>
Cancelar
</v-btn>

<v-btn
color="primary"
text
:disabled="$v.invalid || coverLoading"
@click="handleCoverSaveClick"
>
Salvar
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>

<script>
import { mapActions, mapMutations, mapState } from 'vuex'
import { url } from 'vuelidate/lib/validators'
import { findCovers } from '../services/cover'
import BookRecord from '@/components/BookRecord'
import VCustomImg from '@/components/VCustomImg'
Expand All @@ -350,12 +434,18 @@ export default {
exact: true
}
],
coverDialog: false,
coverLoading: false,
deleteDialog: false,
editDialog: false,
favoriteLoading: false,
statusLoading: false
}),
validations: {
coverUrl: { url }
},
computed: {
boughtAt () {
if (this.book.boughtAt.length > 0) {
Expand All @@ -365,6 +455,22 @@ export default {
return 'Desconhecida'
},
coverUrl: {
get () {
return this.editingBook.coverUrl
},
set (coverUrl) {
this.$store.commit('book/updateCoverUrl', coverUrl)
}
},
coverUrlErrors: function () {
const errors = []
if (!this.$v.coverUrl.$dirty) return errors
!this.$v.coverUrl.url && errors.push('Endereço inválido.')
return errors
},
formattedLabelPrice () {
return this.formatPrice(this.book.labelPrice)
},
Expand Down Expand Up @@ -473,6 +579,45 @@ export default {
})
},
async handleCoverSearchClick () {
if (this.editingBook.coverUrl.length > 0) {
return
}
this.coverLoading = true
const results = await findCovers(this.book)
if (results.length > 0) {
this.$store.commit('book/updateCoverUrl', results[0])
}
this.coverLoading = false
},
handleCoverCancelClick () {
this.coverDialog = false
this.clearBook()
},
handleCoverSaveClick () {
this.coverDialog = false
this.saveBook({ book: this.editingBook, oldBook: this.book })
.then(() => {
this.book.coverUrl = this.editingBook.coverUrl
this.clearBook()
})
},
showCoverDialog () {
this.updateBook(this.book)
this.$nextTick(() => {
this.coverDialog = true
})
},
...mapMutations('sheet', ['updateLoading']),
...mapMutations('appbar', ['updateIcons']),
...mapMutations('book', [
Expand Down
8 changes: 6 additions & 2 deletions src/views/DashboardList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ export default {
search: '',
selected: [],
showingCount: 0,
sortBy: 'title',
sortBy: '',
sortByOptions: [
{ key: 'title', title: 'Título' },
{ key: 'imprint', title: 'Editora' },
Expand Down Expand Up @@ -579,7 +579,7 @@ export default {
this.search = this.$route.query.search || ''
this.showingCount = this.itemsToShow.length
const querySort = this.$route.query.sortBy || 'title'
const querySort = this.$route.query.sortBy || ''
const sortIsValid = this.sortByOptions.find(s => s.key === querySort)
if (sortIsValid) {
Expand Down Expand Up @@ -614,6 +614,8 @@ export default {
page: 1
}
})
this.page = 1
}
},
Expand All @@ -634,6 +636,8 @@ export default {
delete query.search
this.$router.push({ query })
}
this.page = 1
}
},
Expand Down
Loading

0 comments on commit 1a507c2

Please sign in to comment.