Skip to content

Commit 001bce6

Browse files
committed
Progress
1 parent 5d375dd commit 001bce6

14 files changed

Lines changed: 1507 additions & 43 deletions

File tree

web/components/BackButton.vue

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<template>
2+
<v-btn
3+
color="default"
4+
:small="$vuetify.breakpoint.smAndDown"
5+
:block="block"
6+
@click="goBack"
7+
>
8+
<v-icon>mdi-arrow-left</v-icon>
9+
Go Back
10+
</v-btn>
11+
</template>
12+
13+
<script lang="ts">
14+
import { Vue, Component, Prop } from 'vue-property-decorator'
15+
import { Location } from 'vue-router'
16+
@Component
17+
export default class BackButton extends Vue {
18+
@Prop({ required: false }) route?: Location
19+
@Prop({ required: false, type: Boolean, default: false }) block!: boolean
20+
goBack(): void {
21+
if (this.route) {
22+
this.$router.push(this.route)
23+
return
24+
}
25+
if (window.history.length > 1) {
26+
this.$router.back()
27+
return
28+
}
29+
this.$router.push({ name: 'index' })
30+
}
31+
}
32+
</script>

web/components/FirebaseAuth.vue

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<template>
2+
<div>
3+
<div id="firebaseui-auth-container" ref="authContainer"></div>
4+
<v-progress-circular
5+
v-if="!firebaseUIInitialized"
6+
class="mx-auto d-block my-16"
7+
:size="80"
8+
:width="5"
9+
color="primary"
10+
indeterminate
11+
></v-progress-circular>
12+
</div>
13+
</template>
14+
15+
<script lang="ts">
16+
import { Vue, Component } from 'vue-property-decorator'
17+
import { ProviderId } from 'firebase/auth'
18+
import { auth } from 'firebaseui'
19+
import { NotificationRequest } from '~/store'
20+
21+
@Component
22+
export default class FirebaseAuth extends Vue {
23+
ui: auth.AuthUI | null = null
24+
firebaseUIInitialized = false
25+
26+
beforeDestroy(): void {
27+
if (this.ui) {
28+
this.ui.delete()
29+
}
30+
}
31+
32+
mounted(): void {
33+
if (process.browser) {
34+
const firebaseui = require('firebaseui')
35+
require('firebaseui/dist/firebaseui.css')
36+
this.ui = new firebaseui.auth.AuthUI(this.$fire.auth)
37+
this.ui?.start('#firebaseui-auth-container', this.uiConfig())
38+
}
39+
}
40+
41+
uiConfig(): any {
42+
return {
43+
callbacks: {
44+
signInSuccessWithAuthResult: () => {
45+
this.$store.dispatch('addNotification', {
46+
message: 'Login successfull!',
47+
type: 'success',
48+
} as NotificationRequest)
49+
this.$router.push({ name: 'index' })
50+
return false
51+
},
52+
uiShown: () => {
53+
// The widget is rendered.
54+
// Hide the loader.
55+
this.firebaseUIInitialized = true
56+
const container = this.$refs.authContainer as HTMLElement
57+
Array.from(
58+
container.getElementsByClassName('firebaseui-idp-text-long')
59+
).forEach((item: Element) => {
60+
item.textContent =
61+
item.textContent?.replace('Sign in with', 'Continue with') || null
62+
})
63+
},
64+
},
65+
// Will use popup for IDP Providers sign-in flow instead of the default, redirect.
66+
signInFlow: 'popup',
67+
signInSuccessUrl: this.$store.getters.getAppData.url,
68+
signInOptions: [
69+
// Leave the lines as is for the providers you want to offer your users.
70+
ProviderId.GOOGLE,
71+
ProviderId.GITHUB,
72+
ProviderId.PASSWORD,
73+
],
74+
// Terms of service url.
75+
tosUrl: this.$store.getters.getAppData.url + '/terms-and-conditions',
76+
// Privacy policy url.
77+
privacyPolicyUrl: this.$store.getters.getAppData.url + '/privacy-policy',
78+
}
79+
}
80+
}
81+
</script>

web/components/MessageThreadHeader.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@
4141
</div>
4242
</div>
4343
<v-spacer></v-spacer>
44-
<v-tooltip bottom>
44+
<v-tooltip bottom :open-on-click="true">
4545
<template #activator="{ on, attrs }">
46-
<v-btn icon text v-bind="attrs" v-on="on">
46+
<v-btn icon text v-bind="attrs" v-on="on" @click.prevent>
4747
<v-icon>mdi-dots-vertical</v-icon>
4848
</v-btn>
4949
</template>

web/components/Toast.vue

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<template>
2+
<v-snackbar
3+
v-model="notificationActive"
4+
text
5+
:color="notification.type"
6+
:timeout="notification.timeout"
7+
>
8+
<v-icon v-if="notification.type === 'success'" :color="notification.type"
9+
>mdi-check</v-icon
10+
>
11+
<v-icon v-if="notification.type === 'info'" :color="notification.type"
12+
>mdi-information</v-icon
13+
>
14+
{{ notification.message }}
15+
<template #action="{ attrs }">
16+
<v-btn
17+
v-if="$vuetify.breakpoint.lgAndUp"
18+
:color="notification.type"
19+
text
20+
v-bind="attrs"
21+
@click="disableNotification"
22+
>
23+
<span class="font-weight-bold">Close</span>
24+
</v-btn>
25+
</template>
26+
</v-snackbar>
27+
</template>
28+
29+
<script lang="ts">
30+
import { Vue, Component } from 'vue-property-decorator'
31+
import { Notification } from '~/store'
32+
33+
@Component
34+
export default class Toast extends Vue {
35+
get notification(): Notification {
36+
return this.$store.getters.getNotification
37+
}
38+
39+
get notificationActive(): boolean {
40+
return this.$store.getters.getNotification.active
41+
}
42+
43+
set notificationActive(state: boolean) {
44+
this.disableNotification()
45+
}
46+
47+
disableNotification() {
48+
this.$store.dispatch('disableNotification')
49+
}
50+
}
51+
</script>

web/layouts/default.vue

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<v-app dark>
33
<v-navigation-drawer
4-
v-if="$vuetify.breakpoint.lgAndUp"
4+
v-if="$vuetify.breakpoint.lgAndUp && hasDrawer"
55
:width="400"
66
fixed
77
app
@@ -28,6 +28,12 @@ import { Vue, Component } from 'vue-property-decorator'
2828
2929
@Component
3030
export default class DefaultLayout extends Vue {
31+
poller: number | null = null
32+
33+
get hasDrawer(): boolean {
34+
return !['login'].includes(this.$route.name ?? '')
35+
}
36+
3137
mounted() {
3238
Promise.all([
3339
this.$store.dispatch('loadThreads'),
@@ -36,8 +42,14 @@ export default class DefaultLayout extends Vue {
3642
this.startPoller()
3743
}
3844
45+
beforeDestroy(): void {
46+
if (this.poller) {
47+
clearInterval(this.poller)
48+
}
49+
}
50+
3951
startPoller() {
40-
setInterval(async () => {
52+
this.poller = window.setInterval(async () => {
4153
await this.$store.dispatch('setPolling', true)
4254
4355
const promises = []

web/middleware/user.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Context } from '@nuxt/types'
2+
import { User, Auth } from 'firebase/auth'
3+
import { User as StateUser } from '~/store'
4+
import { setAuthHeader } from '~/plugins/axios'
5+
6+
export default async function (context: Context) {
7+
await context.store.dispatch('setLoadingUser', true)
8+
await setUser(context)
9+
await context.store.dispatch('setLoadingUser', false)
10+
}
11+
12+
const setUser = (context: Context): Promise<User | null> => {
13+
return new Promise((resolve, reject) => {
14+
const unsubscribe = (context.app.$fire.auth as Auth).onAuthStateChanged(
15+
async (user) => {
16+
unsubscribe()
17+
let stateUser: StateUser | null = null
18+
if (user) {
19+
stateUser = {
20+
id: user.uid,
21+
}
22+
setAuthHeader(await user.getIdToken())
23+
}
24+
context.store.dispatch('setUser', stateUser).finally(() => {
25+
resolve(user)
26+
})
27+
},
28+
reject
29+
)
30+
})
31+
}

web/nuxt.config.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,30 @@ export default {
4545
'@nuxtjs/axios',
4646
// Simple usage
4747
'@nuxtjs/dotenv',
48+
[
49+
'@nuxtjs/firebase',
50+
{
51+
config: {
52+
apiKey: 'AIzaSyClL8AX2H_F77_n8yu5FgLzBmJTiSM0NsQ',
53+
authDomain: 'httpsms-86c51.firebaseapp.com',
54+
projectId: 'httpsms-86c51',
55+
storageBucket: 'httpsms-86c51.appspot.com',
56+
messagingSenderId: '877524083399',
57+
appId: '1:877524083399:web:430d6a29a0d808946514e2',
58+
measurementId: 'G-EZ5W9DVK8T',
59+
},
60+
services: {
61+
auth: true,
62+
analytics: true,
63+
},
64+
},
65+
],
4866
],
4967

5068
// Axios module configuration: https://go.nuxtjs.dev/config-axios
5169
axios: {
5270
// Workaround to avoid enforcing hard-coded localhost:3000: https://github.com/nuxt-community/axios-module/issues/308
53-
baseURL: '/',
71+
baseURL: process.env.BASE_URL || 'http://localhost:8000',
5472
},
5573

5674
// Vuetify module configuration: https://go.nuxtjs.dev/config-vuetify
@@ -72,6 +90,10 @@ export default {
7290
},
7391
},
7492

93+
router: {
94+
middleware: ['user'],
95+
},
96+
7597
// Build Configuration: https://go.nuxtjs.dev/config-build
7698
build: {},
7799
}

web/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@
2222
"dependencies": {
2323
"@nuxtjs/axios": "^5.13.6",
2424
"@nuxtjs/dotenv": "^1.4.1",
25+
"@nuxtjs/firebase": "^8.2.2",
2526
"core-js": "^3.19.3",
2627
"dotenv": "^16.0.1",
28+
"firebase": "^9.8.4",
29+
"firebaseui": "^6.0.1",
2730
"libphonenumber-js": "^1.10.6",
2831
"nuxt": "^2.15.8",
2932
"vue": "^2.6.14",

web/pages/inspire.vue

Lines changed: 0 additions & 21 deletions
This file was deleted.

web/pages/login.vue

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<template>
2+
<v-container fill-height fluid>
3+
<v-row align="center" justify="center">
4+
<v-col
5+
cols="12"
6+
md="4"
7+
xl="3"
8+
:class="{ 'mt-n16': $vuetify.breakpoint.lgAndUp }"
9+
>
10+
<h3 class="text-h2 text-center mb-4">Login</h3>
11+
<v-card max-width="360" class="mx-auto">
12+
<v-card-text class="px-0">
13+
<no-ssr>
14+
<firebase-auth></firebase-auth>
15+
</no-ssr>
16+
</v-card-text>
17+
</v-card>
18+
<div class="text-center mt-4">
19+
<back-button></back-button>
20+
</div>
21+
</v-col>
22+
</v-row>
23+
</v-container>
24+
</template>
25+
26+
<script lang="ts">
27+
import Vue from 'vue'
28+
import { Component } from 'vue-property-decorator'
29+
30+
@Component
31+
export default class Login extends Vue {
32+
layout: string = 'auth'
33+
}
34+
</script>

0 commit comments

Comments
 (0)