add app
This commit is contained in:
1 parent
cbc36d19f5
commit
2093433b96
8 files changed
+450
-211
No files matched your search
File renamed without changes.
@@ -1,12 +0,0 @@
|
|||||||
[[source]]
|
|
||||||
url = "https://pypi.org/simple"
|
|
||||||
verify_ssl = true
|
|
||||||
name = "pypi"
|
|
||||||
|
|
||||||
[packages]
|
|
||||||
gtts = ">=2.2.3"
|
|
||||||
|
|
||||||
[dev-packages]
|
|
||||||
|
|
||||||
[requires]
|
|
||||||
python_version = "3.9"
|
|
||||||
Generated
-84
@@ -1,84 +0,0 @@
|
|||||||
{
|
|
||||||
"_meta": {
|
|
||||||
"hash": {
|
|
||||||
"sha256": "ff889e495c55c0c92b329fe9caf8fad69d314e15db1c62b97c7abbc709a211ab"
|
|
||||||
},
|
|
||||||
"pipfile-spec": 6,
|
|
||||||
"requires": {
|
|
||||||
"python_version": "3.9"
|
|
||||||
},
|
|
||||||
"sources": [
|
|
||||||
{
|
|
||||||
"name": "pypi",
|
|
||||||
"url": "https://pypi.org/simple",
|
|
||||||
"verify_ssl": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"default": {
|
|
||||||
"certifi": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872",
|
|
||||||
"sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"
|
|
||||||
],
|
|
||||||
"version": "==2021.10.8"
|
|
||||||
},
|
|
||||||
"charset-normalizer": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0",
|
|
||||||
"sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '3'",
|
|
||||||
"version": "==2.0.7"
|
|
||||||
},
|
|
||||||
"click": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3",
|
|
||||||
"sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '3.6'",
|
|
||||||
"version": "==8.0.3"
|
|
||||||
},
|
|
||||||
"gtts": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:8376d9bde85ac8cda95ea92dcd12bf31a3efe9e810edcb04437a4151cbec30d6",
|
|
||||||
"sha256:88cfaa112471867009a0450a696e5bc69cf1671fa0fa683fe17d0650023c863c"
|
|
||||||
],
|
|
||||||
"index": "pypi",
|
|
||||||
"version": "==2.2.3"
|
|
||||||
},
|
|
||||||
"idna": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff",
|
|
||||||
"sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '3'",
|
|
||||||
"version": "==3.3"
|
|
||||||
},
|
|
||||||
"requests": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24",
|
|
||||||
"sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
|
|
||||||
"version": "==2.26.0"
|
|
||||||
},
|
|
||||||
"six": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
|
|
||||||
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
|
||||||
"version": "==1.16.0"
|
|
||||||
},
|
|
||||||
"urllib3": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece",
|
|
||||||
"sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'",
|
|
||||||
"version": "==1.26.7"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"develop": {}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
export default {
|
|
||||||
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
|
|
||||||
ssr: false,
|
|
||||||
|
|
||||||
// Target: https://go.nuxtjs.dev/config-target
|
|
||||||
target: 'static',
|
|
||||||
|
|
||||||
// Global page headers: https://go.nuxtjs.dev/config-head
|
|
||||||
head: {
|
|
||||||
title: 'jaquiz',
|
|
||||||
meta: [
|
|
||||||
{ charset: 'utf-8' },
|
|
||||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
|
||||||
{ hid: 'description', name: 'description', content: '' },
|
|
||||||
{ name: 'format-detection', content: 'telephone=no' }
|
|
||||||
],
|
|
||||||
link: [
|
|
||||||
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// Global CSS: https://go.nuxtjs.dev/config-css
|
|
||||||
css: [
|
|
||||||
],
|
|
||||||
|
|
||||||
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
|
|
||||||
plugins: [
|
|
||||||
],
|
|
||||||
|
|
||||||
// Auto import components: https://go.nuxtjs.dev/config-components
|
|
||||||
components: true,
|
|
||||||
|
|
||||||
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
|
|
||||||
buildModules: [
|
|
||||||
// https://go.nuxtjs.dev/typescript
|
|
||||||
'@nuxt/typescript-build',
|
|
||||||
],
|
|
||||||
|
|
||||||
// Modules: https://go.nuxtjs.dev/config-modules
|
|
||||||
modules: [
|
|
||||||
// https://go.nuxtjs.dev/buefy
|
|
||||||
'nuxt-buefy',
|
|
||||||
// https://go.nuxtjs.dev/pwa
|
|
||||||
'@nuxtjs/pwa',
|
|
||||||
],
|
|
||||||
|
|
||||||
// PWA module configuration: https://go.nuxtjs.dev/pwa
|
|
||||||
pwa: {
|
|
||||||
manifest: {
|
|
||||||
lang: 'en'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Build Configuration: https://go.nuxtjs.dev/config-build
|
|
||||||
build: {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import { NuxtConfig } from '@nuxt/types'
|
||||||
|
|
||||||
|
export default async (): Promise<NuxtConfig> => {
|
||||||
|
return {
|
||||||
|
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
|
||||||
|
ssr: false,
|
||||||
|
|
||||||
|
// Target: https://go.nuxtjs.dev/config-target
|
||||||
|
target: 'static',
|
||||||
|
|
||||||
|
// Global page headers: https://go.nuxtjs.dev/config-head
|
||||||
|
head: {
|
||||||
|
title: 'jaquiz',
|
||||||
|
meta: [
|
||||||
|
{ charset: 'utf-8' },
|
||||||
|
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
||||||
|
{ hid: 'description', name: 'description', content: '' },
|
||||||
|
{ name: 'format-detection', content: 'telephone=no' },
|
||||||
|
],
|
||||||
|
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Global CSS: https://go.nuxtjs.dev/config-css
|
||||||
|
css: [],
|
||||||
|
|
||||||
|
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
|
||||||
|
plugins: [],
|
||||||
|
|
||||||
|
// Auto import components: https://go.nuxtjs.dev/config-components
|
||||||
|
components: true,
|
||||||
|
|
||||||
|
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
|
||||||
|
buildModules: [
|
||||||
|
// https://go.nuxtjs.dev/typescript
|
||||||
|
'@nuxt/typescript-build',
|
||||||
|
],
|
||||||
|
|
||||||
|
// Modules: https://go.nuxtjs.dev/config-modules
|
||||||
|
modules: [
|
||||||
|
// https://go.nuxtjs.dev/buefy
|
||||||
|
'nuxt-buefy',
|
||||||
|
// https://go.nuxtjs.dev/pwa
|
||||||
|
'@nuxtjs/pwa',
|
||||||
|
],
|
||||||
|
|
||||||
|
// PWA module configuration: https://go.nuxtjs.dev/pwa
|
||||||
|
pwa: {
|
||||||
|
manifest: {
|
||||||
|
lang: 'en',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Build Configuration: https://go.nuxtjs.dev/config-build
|
||||||
|
build: {},
|
||||||
|
}
|
||||||
|
}
|
||||||
+342
@@ -0,0 +1,342 @@
|
|||||||
|
<template>
|
||||||
|
<section class="AppPage">
|
||||||
|
<b-loading v-if="!isReady" active is-full-page></b-loading>
|
||||||
|
|
||||||
|
<b-sidebar v-if="isReady" v-model="isDrawer" type="is-light" fullheight>
|
||||||
|
<div class="p-2">
|
||||||
|
<aside class="menu">
|
||||||
|
<p class="menu-label">Menu</p>
|
||||||
|
|
||||||
|
<ul class="menu-list">
|
||||||
|
<li v-for="(n, j) in navItems" :key="j">
|
||||||
|
<a
|
||||||
|
role="button"
|
||||||
|
:class="{
|
||||||
|
'is-active': tabs[activeTab].component === n.component,
|
||||||
|
}"
|
||||||
|
@click="setTab(activeTab, n.component)"
|
||||||
|
>
|
||||||
|
<b-icon v-if="n.icon" :icon="n.icon"></b-icon>
|
||||||
|
<span v-if="n.text" :class="'icon ' + n.className">
|
||||||
|
{{ n.text }}
|
||||||
|
</span>
|
||||||
|
{{ n.title || n.component }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="https://github.com/zhquiz/zhquiz/discussions"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<b-icon pack="fab" icon="github"></b-icon>
|
||||||
|
{{ 'Support & Contribute' }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="flex-grow: 1"></div>
|
||||||
|
|
||||||
|
<div class="p-4">
|
||||||
|
<center>
|
||||||
|
<a role="button" title="Click to logout" @click="doLogout">
|
||||||
|
Logged in as {{ $store.state.identifier }}
|
||||||
|
</a>
|
||||||
|
</center>
|
||||||
|
</div>
|
||||||
|
</b-sidebar>
|
||||||
|
|
||||||
|
<nav v-if="isReady" class="tabs is-toggle">
|
||||||
|
<ul>
|
||||||
|
<li @click="isDrawer = true">
|
||||||
|
<b-icon class="clickable" icon="bars" role="button"></b-icon>
|
||||||
|
</li>
|
||||||
|
<li
|
||||||
|
v-for="(t, i) in tabs"
|
||||||
|
:key="i"
|
||||||
|
:class="{ 'is-active': activeTab === i }"
|
||||||
|
>
|
||||||
|
<a role="button">
|
||||||
|
<b-dropdown aria-role="menu" append-to-body :value="t.component">
|
||||||
|
<template #trigger>
|
||||||
|
<a class="no-margin" role="button">
|
||||||
|
<span class="text" @click.stop="setCurrentTab(i)">
|
||||||
|
{{ t.title }}
|
||||||
|
</span>
|
||||||
|
<b-icon icon="caret-down"></b-icon>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<b-dropdown-item
|
||||||
|
v-for="(n, j) in navItems"
|
||||||
|
:key="j"
|
||||||
|
:value="n.component"
|
||||||
|
aria-role="menuitem"
|
||||||
|
@click="setTab(i, n.component)"
|
||||||
|
>
|
||||||
|
<b-icon v-if="n.icon" :icon="n.icon"></b-icon>
|
||||||
|
<span v-if="n.text" :class="'icon ' + n.className">
|
||||||
|
{{ n.text }}
|
||||||
|
</span>
|
||||||
|
{{ n.title || n.component }}
|
||||||
|
</b-dropdown-item>
|
||||||
|
</b-dropdown>
|
||||||
|
|
||||||
|
<button
|
||||||
|
v-if="!t.permanent"
|
||||||
|
class="delete is-small"
|
||||||
|
@click="deleteTab(i)"
|
||||||
|
></button>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a role="button" @click="addTab('Random')">+</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<main v-if="isReady">
|
||||||
|
<component
|
||||||
|
class="container"
|
||||||
|
:is="t.component + 'Tab'"
|
||||||
|
v-for="(t, i) in tabs"
|
||||||
|
v-show="activeTab === i"
|
||||||
|
:key="i"
|
||||||
|
:query="t.query"
|
||||||
|
@title="(t) => setTitle(i, t)"
|
||||||
|
/>
|
||||||
|
</main>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import BrowseTab from '@/components/tabs/BrowseTab.vue'
|
||||||
|
import LookupTab from '@/components/tabs/LookupTab.vue'
|
||||||
|
import LevelTab from '@/components/tabs/LevelTab.vue'
|
||||||
|
import LibraryTab from '@/components/tabs/LibraryTab.vue'
|
||||||
|
import { Component, Vue } from 'nuxt-property-decorator'
|
||||||
|
import { api } from '~/assets/api'
|
||||||
|
|
||||||
|
@Component<AppPage>({
|
||||||
|
components: {
|
||||||
|
BrowseTab,
|
||||||
|
LookupTab,
|
||||||
|
LevelTab,
|
||||||
|
LibraryTab,
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
await this.$accessor.updateSettings()
|
||||||
|
|
||||||
|
if (!this.$accessor.isApp) {
|
||||||
|
this.$router.replace('/')
|
||||||
|
} else {
|
||||||
|
this.$accessor.ADD_TAB({
|
||||||
|
component: 'Lookup',
|
||||||
|
first: true,
|
||||||
|
})
|
||||||
|
this.isReady = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
export default class AppPage extends Vue {
|
||||||
|
isReady = false
|
||||||
|
isDrawer = false
|
||||||
|
|
||||||
|
get navItems(): {
|
||||||
|
title?: string
|
||||||
|
component: string
|
||||||
|
icon?: string | string[]
|
||||||
|
text?: string
|
||||||
|
className?: string
|
||||||
|
}[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: 'Lookup',
|
||||||
|
component: 'Character',
|
||||||
|
text: '字',
|
||||||
|
className: 'font-han',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Level',
|
||||||
|
text: this.level,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'User content',
|
||||||
|
component: 'Browse',
|
||||||
|
icon: 'list-ol',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Library',
|
||||||
|
icon: 'book-reader',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
get level() {
|
||||||
|
const { level } = this.$store.state.settings
|
||||||
|
return level ? level.toString() : ' '
|
||||||
|
}
|
||||||
|
|
||||||
|
get tabs() {
|
||||||
|
return this.$store.state.tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
get activeTab() {
|
||||||
|
return this.$store.state.activeTab
|
||||||
|
}
|
||||||
|
|
||||||
|
setTab(i: number, component: string) {
|
||||||
|
this.$accessor.SET_TAB_COMPONENT({ i, component })
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentTab(i: number) {
|
||||||
|
this.$accessor.SET_TAB_CURRENT({ i })
|
||||||
|
}
|
||||||
|
|
||||||
|
addTab(component: string) {
|
||||||
|
this.$accessor.ADD_TAB({ component })
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteTab(i: number) {
|
||||||
|
this.$accessor.DELETE_TAB({ i })
|
||||||
|
}
|
||||||
|
|
||||||
|
setTitle(i: number, title: string) {
|
||||||
|
this.$accessor.SET_TAB_TITLE({ i, title })
|
||||||
|
}
|
||||||
|
|
||||||
|
doLogout() {
|
||||||
|
this.$buefy.dialog.confirm({
|
||||||
|
message: 'Are you sure you want to logout?',
|
||||||
|
onConfirm: async () => {
|
||||||
|
await api.setWanikaniApiKey()
|
||||||
|
this.$router.push('/')
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
::v-deep .sidebar-content {
|
||||||
|
z-index: 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AppPage {
|
||||||
|
height: 100%;
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: 1fr auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
$nav-height: 45px;
|
||||||
|
|
||||||
|
nav.tabs {
|
||||||
|
z-index: 50;
|
||||||
|
height: $nav-height;
|
||||||
|
padding-top: 0.5em;
|
||||||
|
padding-left: 0.5em;
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
background-color: rgba(230, 230, 230, 0.1);
|
||||||
|
|
||||||
|
li {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
li:not(.is-active) a {
|
||||||
|
background-color: rgba(211, 211, 211, 0.5);
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
li + li {
|
||||||
|
margin-left: 0.5em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
li a {
|
||||||
|
border-bottom-left-radius: 0 !important;
|
||||||
|
border-bottom-right-radius: 0 !important;
|
||||||
|
|
||||||
|
span.text {
|
||||||
|
max-width: 10em;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-margin {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& :hover {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
border: 0;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100vw;
|
||||||
|
overflow-y: scroll;
|
||||||
|
position: absolute;
|
||||||
|
margin-top: $nav-height;
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-bottom: 100px;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(211, 211, 211, 0.2);
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete {
|
||||||
|
border: none !important;
|
||||||
|
transform: translateX(50%);
|
||||||
|
background-color: rgba(143, 183, 221);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: lightgray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
color: lightgray;
|
||||||
|
|
||||||
|
> span {
|
||||||
|
$n: 3;
|
||||||
|
$speed: 0.1s;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
animation: loading (($n + 1) * $speed) infinite;
|
||||||
|
|
||||||
|
@for $i from 1 through $n {
|
||||||
|
&:nth-child(#{$i}) {
|
||||||
|
animation-delay: $i * $speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes loading {
|
||||||
|
0% {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
40% {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
+52
-43
@@ -1,53 +1,62 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="section">
|
<main class="HomePage">
|
||||||
<div class="columns is-mobile">
|
<b-loading v-if="!isReady" active is-full-page></b-loading>
|
||||||
<card
|
<form v-else class="card login-card" @submit.prevent="login">
|
||||||
title="Free"
|
<div class="card-content">
|
||||||
icon="github"
|
<h2 class="title is-4">Login with WaniKani API key</h2>
|
||||||
>
|
|
||||||
Open source on <a href="https://github.com/buefy/buefy">
|
|
||||||
GitHub
|
|
||||||
</a>
|
|
||||||
</card>
|
|
||||||
|
|
||||||
<card
|
<b-field>
|
||||||
title="Responsive"
|
<b-input v-model="apiKey" placeholder="WaniKani API key"></b-input>
|
||||||
icon="cellphone-link"
|
</b-field>
|
||||||
>
|
|
||||||
<b class="has-text-grey">
|
|
||||||
Every
|
|
||||||
</b> component is responsive
|
|
||||||
</card>
|
|
||||||
|
|
||||||
<card
|
<b-button class="is-primary is-fullwidth" @click="login">
|
||||||
title="Modern"
|
Login
|
||||||
icon="alert-decagram"
|
</b-button>
|
||||||
>
|
</div>
|
||||||
Built with <a href="https://vuejs.org/">
|
</form>
|
||||||
Vue.js
|
</main>
|
||||||
</a> and <a href="http://bulma.io/">
|
|
||||||
Bulma
|
|
||||||
</a>
|
|
||||||
</card>
|
|
||||||
|
|
||||||
<card
|
|
||||||
title="Lightweight"
|
|
||||||
icon="arrange-bring-to-front"
|
|
||||||
>
|
|
||||||
No other internal dependency
|
|
||||||
</card>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import Card from '~/components/Card'
|
import { Vue, Component } from 'nuxt-property-decorator'
|
||||||
|
import { api } from '~/assets/api'
|
||||||
|
|
||||||
export default {
|
@Component<HomePage>({
|
||||||
name: 'HomePage',
|
async mounted() {
|
||||||
|
if (await api.isAuthorized()) {
|
||||||
|
this.$router.replace('/app')
|
||||||
|
} else {
|
||||||
|
this.isReady = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
export default class HomePage extends Vue {
|
||||||
|
apiKey = ''
|
||||||
|
|
||||||
components: {
|
isReady = false
|
||||||
Card
|
|
||||||
|
async login() {
|
||||||
|
if (await api.setWanikaniApiKey(this.apiKey)) {
|
||||||
|
this.$router.push('/app')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.HomePage {
|
||||||
|
background-color: rgba(211, 211, 211, 0.3);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-card {
|
||||||
|
position: absolute;
|
||||||
|
max-width: 500px;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="section">
|
|
||||||
<h2 class="title is-3 has-text-grey">
|
|
||||||
"Just start <b-icon
|
|
||||||
icon="rocket"
|
|
||||||
size="is-large"
|
|
||||||
/>"
|
|
||||||
</h2>
|
|
||||||
<h3 class="subtitle is-6 has-text-grey">
|
|
||||||
Author: <a href="https://github.com/anteriovieira">
|
|
||||||
Antério Vieira
|
|
||||||
</a>
|
|
||||||
</h3>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
Reference in new issue
Block a user