(login) save login

This commit is contained in:
2021-03-17 23:25:58 +01:00
parent 6f5ea41824
commit 2faabb6c0e
13 changed files with 255 additions and 29 deletions

View File

@@ -1,12 +1,18 @@
<template> <template>
<router-view class="app" /> <router-view v-if="isReady" class="app" />
</template> </template>
<script lang="ts"> <script lang="ts">
import { useGitHubLogin } from '@/hooks/useGitHubLogin.hook'
import { defineComponent } from 'vue' import { defineComponent } from 'vue'
export default defineComponent({ export default defineComponent({
name: 'App' name: 'App',
setup() {
const { isReady, accessToken } = useGitHubLogin()
return { isReady, accessToken }
}
}) })
</script> </script>

View File

@@ -18,6 +18,10 @@
</li> </li>
</ol> </ol>
<router-link :to="{ name: 'RepoList' }" v-if="isLogged"
>go to repos</router-link
>
<form @submit.prevent> <form @submit.prevent>
<div class="columns is-centered is-vcentered to-user-repo"> <div class="columns is-centered is-vcentered to-user-repo">
<div class="column"> <div class="column">
@@ -85,11 +89,14 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import { defineComponent } from 'vue'
import { useForm } from '@/hooks/useForm.hook' import { useForm } from '@/hooks/useForm.hook'
import { useGitHubLogin } from '@/hooks/useGitHubLogin.hook'
export default defineComponent({ export default defineComponent({
name: 'WelcomeWord', name: 'WelcomeWord',
setup() { setup() {
return { ...useForm() } const { isLogged } = useGitHubLogin()
return { ...useForm(), isLogged }
} }
}) })
</script> </script>

View File

@@ -1 +1,3 @@
export enum DataType {} export enum DataType {
GithubAccessToken = 'GithubAccessToken'
}

View File

@@ -1,7 +1,8 @@
import PouchDb from 'pouchdb-browser'
import { Model } from './models/Model'
import indexedDb from 'pouchdb-adapter-indexeddb'
import { DataType } from './DataType.enum' import { DataType } from './DataType.enum'
import { Model } from './models/Model'
import PouchDb from 'pouchdb-browser'
import indexedDb from 'pouchdb-adapter-indexeddb'
import { nanoid } from 'nanoid'
PouchDb.plugin(indexedDb) PouchDb.plugin(indexedDb)
@@ -20,7 +21,9 @@ class Data {
try { try {
const result = await this.locale.put(model) const result = await this.locale.put(model)
return result.ok return result.ok
} catch { } catch (error) {
console.warn(error)
return false return false
} }
} }
@@ -65,6 +68,10 @@ class Data {
return response.rows.map((row) => row.doc) as T[] return response.rows.map((row) => row.doc) as T[]
} }
public generateId(type: DataType, id?: string) {
return `${type}-${id || nanoid()}`
}
} }
export const data = new Data() export const data = new Data()

View File

@@ -0,0 +1,7 @@
import { DataType } from '@/data/DataType.enum'
import { Model } from '@/data/models/Model'
export interface GithubAccessToken extends Model<DataType.GithubAccessToken> {
username: string
personalAccessToken: string
}

View File

@@ -0,0 +1,52 @@
import { computed, ref } from 'vue'
import { DataType } from '@/data/DataType.enum'
import { GithubAccessToken } from '@/data/models/GithubAccessToken'
import { data } from '@/data/data'
const personalAccessTokenId = 'PAT'
const username = ref<string | null>(null)
const accessToken = ref<string | null>(null)
let init = true
export const useGitHubLogin = () => {
const getAccessToken = async () => {
const response = await data.get<
DataType.GithubAccessToken,
GithubAccessToken
>(data.generateId(DataType.GithubAccessToken, personalAccessTokenId))
username.value = response?.username || ''
accessToken.value = response?.personalAccessToken || ''
return response
}
if (init) {
init = false
getAccessToken()
}
const saveCredentials = async (username: string, token: string) => {
const actualPAT = await getAccessToken()
const personalAccessToken: GithubAccessToken = {
...actualPAT,
_id: data.generateId(DataType.GithubAccessToken, personalAccessTokenId),
$type: DataType.GithubAccessToken,
username,
personalAccessToken: token
}
await data.add(personalAccessToken)
getAccessToken()
}
return {
isLogged: !!username.value && !!accessToken.value,
isReady: computed(() => accessToken.value !== null),
username,
accessToken,
saveCredentials
}
}

View File

@@ -10,13 +10,12 @@ export const useQueryStackedNotes = () => {
const { query } = useRoute() const { query } = useRoute()
if (initial) { if (initial) {
initial = false initial = false
stackedNotes.value = Array.isArray(query.stackedNotes) stackedNotes.value = (Array.isArray(query.stackedNotes)
? (query.stackedNotes ? query.stackedNotes
: [query.stackedNotes]
)
.map((n) => n?.toString()) .map((n) => n?.toString())
.filter((n) => !!n) as string[]) .filter((n) => !!n) as string[]
: ([query.stackedNotes]
.map((n) => n?.toString())
.filter((n) => !!n) as string[])
} }
return { return {

View File

@@ -1,6 +1,7 @@
import { Ref, onMounted, ref, watch } from '@vue/runtime-core' import { Ref, onMounted, ref, watch } from '@vue/runtime-core'
import { request } from '@octokit/request' import { Octokit } from '@octokit/rest'
import { useGitHubLogin } from '@/hooks/useGitHubLogin.hook'
import { useMarkdown } from '@/hooks/useMarkdown.hook' import { useMarkdown } from '@/hooks/useMarkdown.hook'
interface Tree { interface Tree {
@@ -13,6 +14,12 @@ interface Tree {
} }
export const useRepo = (owner: Ref<string>, repo: Ref<string>) => { export const useRepo = (owner: Ref<string>, repo: Ref<string>) => {
const { accessToken } = useGitHubLogin()
const octokit = new Octokit({
auth: accessToken.value
})
const { render } = useMarkdown() const { render } = useMarkdown()
const readme = ref<string | null>(null) const readme = ref<string | null>(null)
const notFound = ref(false) const notFound = ref(false)
@@ -24,19 +31,22 @@ export const useRepo = (owner: Ref<string>, repo: Ref<string>) => {
} }
try { try {
const README = await request('GET /repos/{owner}/{repo}/readme', { const README = await octokit.repos.getReadme({
repo: repo.value, owner: owner.value,
owner: owner.value repo: repo.value
}) })
if (README) { if (README) {
readme.value = render(README.data.content) readme.value = render(README.data.content)
} }
const commits = await request('GET /repos/{owner}/{repo}/commits', { const commits = await octokit.request(
'GET /repos/{owner}/{repo}/commits',
{
repo: repo.value, repo: repo.value,
owner: owner.value owner: owner.value
}) }
)
const lastCommit = commits.data.shift() const lastCommit = commits.data.shift()
@@ -44,7 +54,7 @@ export const useRepo = (owner: Ref<string>, repo: Ref<string>) => {
return return
} }
const treeResponse = await request( const treeResponse = await octokit.request(
'GET /repos/{owner}/{repo}/git/trees/{tree_sha}', 'GET /repos/{owner}/{repo}/git/trees/{tree_sha}',
{ {
repo: repo.value, repo: repo.value,

View File

@@ -0,0 +1,28 @@
import { Octokit } from '@octokit/rest'
import { useAsyncState } from '@vueuse/core'
import { useGitHubLogin } from '@/hooks/useGitHubLogin.hook'
export const useRepos = () => {
const { username, accessToken } = useGitHubLogin()
const repos = useAsyncState(async () => {
if (!accessToken.value || !username.value) {
return []
}
const octokit = new Octokit({
auth: accessToken.value
})
const repoList = await octokit.request('GET /search/repositories', {
q: `user:${username.value}`,
per_page: 100
})
return repoList.data.items.map((item) => item.name)
}, [])
return {
repos: repos.state,
isReady: repos.isReady
}
}

View File

@@ -9,6 +9,17 @@ const routes: Array<RouteRecordRaw> = [
component: () => component: () =>
import(/* webpackChunkName: "text-editor" */ '@/views/TextEditor.vue') import(/* webpackChunkName: "text-editor" */ '@/views/TextEditor.vue')
}, },
{
path: '/login',
name: 'Login',
component: () => import(/* webpackChunkName: "login" */ '@/views/Login.vue')
},
{
path: '/repo-list',
name: 'RepoList',
component: () =>
import(/* webpackChunkName: "repo-list" */ '@/views/RepoList.vue')
},
{ {
path: '/:user?/:repo?', path: '/:user?/:repo?',
name: 'Home', name: 'Home',

View File

@@ -3,13 +3,10 @@
<welcome-world /> <welcome-world />
</div> </div>
<div v-else-if="notFound"> <div v-else-if="notFound">
<hr /> <div class="notification is-warning">
<div class="columns is-centered">
<div class="column is-one-third notification is-warning" v-if="notFound">
Not found. Not found.
</div> </div>
</div> </div>
</div>
<div class="home content note-container" v-else> <div class="home content note-container" v-else>
<div class="readme note"> <div class="readme note">
<div class="repo-title"> <div class="repo-title">

60
src/views/Login.vue Normal file
View File

@@ -0,0 +1,60 @@
<template>
<div class="login">
<button class="button is-primary" @click="back">
<img src="@/assets/icons/left-arrow.svg" alt="back" />
</button>
<div class="columns is-centered">
<div class="column is-one-third">
<form @submit.prevent>
<div class="field">
<label class="label">Username</label>
<div class="control">
<input class="input" type="text" v-model="user" />
</div>
</div>
<div class="field">
<label class="label">Token</label>
<div class="control">
<input
class="input"
type="text"
placeholder="Personal Access Token"
v-model="token"
/>
</div>
</div>
<button
class="button is-primary"
type="submit"
@click="saveCredentials(user, token)"
>
register token
</button>
</form>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
import { useGitHubLogin } from '@/hooks/useGitHubLogin.hook'
import { useRouter } from 'vue-router'
export default defineComponent({
name: 'Login',
setup() {
const { go } = useRouter()
const user = ref('')
const token = ref('')
return { ...useGitHubLogin(), user, token, back: () => go(-1) }
}
})
</script>
<style lang="scss" scoped>
.login {
flex: 1;
}
</style>

40
src/views/RepoList.vue Normal file
View File

@@ -0,0 +1,40 @@
<template>
<div class="repo-list">
<h1>Repositories</h1>
<span v-if="!isReady">loading...</span>
<ul>
<li v-for="repo in repos" :key="repo">
<router-link
:to="{ name: 'Home', params: { user: username, repo: repo } }"
>
{{ repo }}
</router-link>
</li>
</ul>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { useRepos } from '@/hooks/useRepos.hook'
import { useGitHubLogin } from '@/hooks/useGitHubLogin.hook'
export default defineComponent({
name: 'RepoList',
setup() {
const { username } = useGitHubLogin()
return {
...useRepos(),
username
}
}
})
</script>
<style lang="scss" scoped>
.repo-list {
flex: 1;
text-align: center;
}
</style>