Add pinia and start working on authentication integration with appwrite

This commit is contained in:
2023-11-05 19:21:03 -05:00
parent e37998f188
commit edde4e79fd
13 changed files with 207 additions and 118 deletions

View File

@@ -1,8 +1,9 @@
# OYS Borrow a Boat (bab-project)
# OYS Borrow a Boat (oys_bab)
Manage a Borrow a Boat program for a Yacht Club
## Install the dependencies
```bash
yarn
# or
@@ -10,32 +11,33 @@ npm install
```
### Start the app in development mode (hot-code reloading, error reporting, etc.)
```bash
quasar dev
```
### Lint the files
```bash
yarn lint
# or
npm run lint
```
### Format the files
```bash
yarn format
# or
npm run format
```
### Build the app for production
```bash
quasar build
```
### Customize the configuration
See [Configuring quasar.config.js](https://v2.quasar.dev/quasar-cli-vite/quasar-config-js).

View File

@@ -1,5 +1,5 @@
{
"name": "bab-project",
"name": "oys_bab",
"version": "0.0.1",
"description": "Manage a Borrow a Boat program for a Yacht Club",
"productName": "OYS Borrow a Boat",
@@ -15,6 +15,7 @@
"dependencies": {
"@quasar/extras": "^1.16.4",
"appwrite": "^13.0.0",
"pinia": "^2.1.7",
"quasar": "^2.6.0",
"vue": "^3.0.0",
"vue-router": "^4.0.0"

View File

@@ -185,7 +185,7 @@ module.exports = configure(function (/* ctx */) {
builder: {
// https://www.electron.build/configuration/configuration
appId: 'bab-project',
appId: 'oys_bab',
},
},

View File

@@ -6,6 +6,6 @@
import { defineComponent } from 'vue';
export default defineComponent({
name: 'App'
name: 'OYS Borrow-a-Boat',
});
</script>

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -1,5 +1,5 @@
import { boot } from 'quasar/wrappers';
import { Client, Account, ID } from 'appwrite';
import { Client, Account } from 'appwrite';
export const client = new Client();
@@ -7,13 +7,17 @@ client
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('653ef6f76baf06d68034');
client.subscribe('account', (response) => {
console.log(response);
});
export const account = new Account(client);
// "async" is optional;
// more info on params: https://v2.quasar.dev/quasar-cli/boot-files
export default boot(async ({ app }) => {
console.log('Appwrite Instantiation');
app.config.globalProperties.$appwrite_client = client;
app.config.globalProperties.$appwrite_account = account;
app.config.globalProperties.$appwrite_ID = ID;
export default boot(({ app, urlPath, redirect }) => {
// Redirect to login page if unauthenticated.
try {
const current = await account.get();
} catch (err) {
redirect('/Login');
}
});

View File

@@ -12,14 +12,14 @@
// to match your app's branding.
// Tip: Use the "Theme Builder" on Quasar's documentation website.
$primary : #1976D2;
$secondary : #26A69A;
$accent : #9C27B0;
$primary: #14539a;
$secondary: #999999;
$accent: #ed323a;
$dark : #1D1D1D;
$dark-page : #121212;
$dark: #1d1d1d;
$dark-page: #121212;
$positive : #21BA45;
$negative : #C10015;
$info : #31CCEC;
$warning : #F2C037;
$positive: #21ba45;
$negative: #c10015;
$info: #31ccec;
$warning: #f2c037;

View File

@@ -11,25 +11,13 @@
@click="toggleLeftDrawer"
/>
<q-toolbar-title>
Quasar App
</q-toolbar-title>
<div>Quasar v{{ $q.version }}</div>
<q-toolbar-title> OYS Borrow a Boat </q-toolbar-title>
</q-toolbar>
</q-header>
<q-drawer
v-model="leftDrawerOpen"
show-if-above
bordered
>
<q-drawer v-model="leftDrawerOpen" show-if-above bordered>
<q-list>
<q-item-label
header
>
Essential Links
</q-item-label>
<q-item-label header> Essential Links </q-item-label>
<EssentialLink
v-for="link in essentialLinks"
@@ -54,63 +42,27 @@ const linksList = [
title: 'Docs',
caption: 'quasar.dev',
icon: 'school',
link: 'https://quasar.dev'
link: 'https://quasar.dev',
},
{
title: 'Github',
caption: 'github.com/quasarframework',
icon: 'code',
link: 'https://github.com/quasarframework'
},
{
title: 'Discord Chat Channel',
caption: 'chat.quasar.dev',
icon: 'chat',
link: 'https://chat.quasar.dev'
},
{
title: 'Forum',
caption: 'forum.quasar.dev',
icon: 'record_voice_over',
link: 'https://forum.quasar.dev'
},
{
title: 'Twitter',
caption: '@quasarframework',
icon: 'rss_feed',
link: 'https://twitter.quasar.dev'
},
{
title: 'Facebook',
caption: '@QuasarFramework',
icon: 'public',
link: 'https://facebook.quasar.dev'
},
{
title: 'Quasar Awesome',
caption: 'Community Quasar projects',
icon: 'favorite',
link: 'https://awesome.quasar.dev'
}
];
export default defineComponent({
name: 'MainLayout',
components: {
EssentialLink
EssentialLink,
},
setup () {
const leftDrawerOpen = ref(false)
setup() {
const leftDrawerOpen = ref(false);
return {
essentialLinks: linksList,
leftDrawerOpen,
toggleLeftDrawer () {
leftDrawerOpen.value = !leftDrawerOpen.value
}
}
}
toggleLeftDrawer() {
leftDrawerOpen.value = !leftDrawerOpen.value;
},
};
},
});
</script>

View File

@@ -1,41 +1,136 @@
<template>
<div>
<p>
{{ loggedInUser ? `Logged in as ${loggedInUser.name}` : 'Not logged in' }}
</p>
<form>
<input type="email" placeholder="Email" v-model="email" />
<input type="password" placeholder="Password" v-model="password" />
<input type="text" placeholder="Name" v-model="name" />
<button type="button" @click="login(email, password)">Login</button>
<button type="button" @click="register">Register</button>
<button type="button" @click="logout">Logout</button>
</form>
</div>
<q-layout>
<q-page-container>
<q-page class="flex bg-image flex-center">
<q-card
v-bind:style="$q.screen.lt.sm ? { width: '80%' } : { width: '30%' }"
>
<q-card-section>
<q-img fit="scale-down" src="~assets/oysqn_logo.png" />
</q-card-section>
<q-card-section>
<div class="text-center q-pt-sm">
<div class="col text-h6">Log in</div>
</div>
<q-card-section>
<div class="alert-box">
<strong>Error!</strong>
<br />
{{ errorMessage }}
</div>
</q-card-section>
<p>
{{
loggedInUser
? `Logged in as ${loggedInUser.name}`
: 'Not logged in'
}}
</p>
</q-card-section>
<q-card-section>
<q-form class="q-gutter-md">
<q-input
v-model="email"
label="E-Mail"
type="email"
color="darkblue"
filled
></q-input>
<q-input
v-model="password"
label="Password"
type="password"
color="darkblue"
filled
></q-input>
<q-btn
type="submit"
@click="login(email, password)"
label="Login"
color="primary"
></q-btn>
<!-- <q-btn
type="button"
@click="register"
color="secondary"
label="Register"
flat
></q-btn> -->
</q-form>
</q-card-section>
</q-card>
</q-page>
</q-page-container>
</q-layout>
</template>
<script setup>
<style>
.bg-image {
background-image: url('/src/assets/oys_lighthouse.jpg');
background-repeat: no-repeat;
background-position-x: center;
background-size: cover;
/* background-image: linear-gradient(
135deg,
#ed232a 0%,
#ffffff 75%,
#14539a 100%
); */
}
</style>
<style scoped>
.alert-box {
color: #666;
border: 1px solid red;
border-radius: 4px;
padding: 20px;
background-color: #f8f8f8;
}
strong {
color: red;
}
</style>
<script lang="ts">
import { account } from 'src/boot/appwrite';
import { defineComponent } from 'vue';
import { ref } from 'vue';
import { account, ID } from './lib/appwrite.js';
const loggedInUser = ref(null);
const email = ref('');
const password = ref('');
const name = ref('');
export default defineComponent({
name: 'LoginPage',
setup() {
const loggedInUser = ref(null);
const email = ref('');
const password = ref('');
const login = async (email, password) => {
await account.createEmailSession(email, password);
loggedInUser.value = await account.get();
};
const current = this.$appwrite_account.get();
const register = async () => {
await account.create(ID.unique(), email.value, password.value, name.value);
login(email.value, password.value);
};
current.then(
function (response) {
console.log(response);
},
function (error) {
console.log(error);
}
);
const logout = async () => {
await account.deleteSession('current');
loggedInUser.value = null;
};
const login = async (email, password) => {
await this.$appwrite_account.createEmailSession(email, password);
loggedInUser.value = await this.$appwrite_account.get();
if (loggedInUser.value.error) {
}
// TODO: Add error handling for failed login.
// TODO: Add forwarding for successful login.
};
return {
email,
password,
login,
};
},
});
</script>

View File

@@ -6,7 +6,10 @@ const routes: RouteRecordRaw[] = [
component: () => import('layouts/MainLayout.vue'),
children: [{ path: '', component: () => import('pages/IndexPage.vue') }],
},
{
path: '/Login',
component: () => import('pages/LoginPage.vue'),
},
// Always leave this as last one,
// but you can also remove it
{

19
src/stores/account.ts Normal file
View File

@@ -0,0 +1,19 @@
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
counter: 0
}),
getters: {
doubleCount (state) {
return state.counter * 2;
}
},
actions: {
increment () {
this.counter++;
}
}
});

View File

@@ -3987,6 +3987,14 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.1:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
pinia@^2.1.7:
version "2.1.7"
resolved "https://registry.yarnpkg.com/pinia/-/pinia-2.1.7.tgz#4cf5420d9324ca00b7b4984d3fbf693222115bbc"
integrity sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==
dependencies:
"@vue/devtools-api" "^6.5.0"
vue-demi ">=0.14.5"
postcss-selector-parser@^6.0.13:
version "6.0.13"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b"
@@ -4899,6 +4907,11 @@ vite@^2.9.13:
optionalDependencies:
fsevents "~2.3.2"
vue-demi@>=0.14.5:
version "0.14.6"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.6.tgz#dc706582851dc1cdc17a0054f4fec2eb6df74c92"
integrity sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==
vue-eslint-parser@^9.3.1:
version "9.3.2"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-9.3.2.tgz#6f9638e55703f1c77875a19026347548d93fd499"