@metano/quasar_rest_auth 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/.gitattributes +17 -0
  2. package/LICENSE +21 -0
  3. package/Makefile +18 -0
  4. package/README.md +6 -0
  5. package/boot/alerts.js +152 -0
  6. package/boot/api.js +155 -0
  7. package/boot/app.js +111 -0
  8. package/boot/base.js +242 -0
  9. package/boot/config.js +117 -0
  10. package/boot/cripto.js +35 -0
  11. package/boot/data.js +28 -0
  12. package/boot/storage.js +74 -0
  13. package/components/DefinicoesLayout.vue +34 -0
  14. package/components/FormLogin.vue +217 -0
  15. package/components/LeftMenu.vue +93 -0
  16. package/components/LeftMenuSegundo.vue +96 -0
  17. package/components/MyTest.vue +41 -0
  18. package/components/RightMenu.vue +36 -0
  19. package/components/SearchMenu.vue +88 -0
  20. package/components/SettingsLayout.vue +34 -0
  21. package/components/TopMenu.vue +68 -0
  22. package/components/TopMenuSegundo.vue +85 -0
  23. package/components/footer/Comments.vue +77 -0
  24. package/components/footer/MainFooter.vue +71 -0
  25. package/components/header/HeaderBrand.vue +64 -0
  26. package/components/header/HeaderDarkModeToggle.vue +40 -0
  27. package/components/header/HeaderFullScreen.vue +55 -0
  28. package/components/header/HeaderLanguage.vue +56 -0
  29. package/components/header/HeaderNotifications.vue +53 -0
  30. package/components/header/HeaderServices.vue +118 -0
  31. package/components/header/HeaderUser.vue +210 -0
  32. package/components/header/HeaderUserMenu.vue +0 -0
  33. package/components/header/RegistarEntidade.vue +309 -0
  34. package/gitignore +3 -0
  35. package/help +9 -0
  36. package/index.js +9 -0
  37. package/layouts/AuthLayout.vue +74 -0
  38. package/layouts/MainLayout.vue +190 -0
  39. package/package.json +31 -0
  40. package/pages/auth/LoginPage.vue +32 -0
  41. package/pages/routes.js +33 -0
  42. package/stores/AuthStore.js +587 -0
  43. package/stores/example-store.js +21 -0
  44. package/stores/index.js +20 -0
  45. package/stores/settings.js +12 -0
@@ -0,0 +1,217 @@
1
+
2
+ <template>
3
+ <q-page-container>
4
+ <q-page class=" row items-center justify-evenly">
5
+ <div class="row">
6
+ <q-card square flat class="text-center">
7
+ <q-card-section class="text-left justify-evenly">
8
+ <q-card v-if="incorrectAuth" class="my-card bg-red text-white">
9
+ <q-card-section>
10
+ <div class="text-subtitle2">{{ tdc('Incorrect username or password entered') }} <br> {{ tdc('please try again') }}</div>
11
+ </q-card-section>
12
+
13
+ </q-card>
14
+ <q-card v-if="correctAuth" class="my-card bg-green text-white">
15
+ <q-card-section>
16
+ <div class="text-subtitle2"> {{ tdc('Login successfuly') }} <br>
17
+ {{ tdc('Redirect to home page') }} ...</div>
18
+ </q-card-section>
19
+
20
+ </q-card>
21
+ <br>
22
+ <q-form class="">
23
+
24
+ <q-input outlined dense clearable v-model="email" type="email" :label="tdc('Usuario ou Celular ou Email')">
25
+ <template v-slot:prepend>
26
+ <q-icon name="email" />
27
+ </template>
28
+ <template v-slot:append>
29
+ <q-icon name="phone" />
30
+ </template>
31
+ </q-input>
32
+ <br/>
33
+ <q-input outlined dense :readonly="readonly" clearable v-model="password" :type="isPwd ? 'password': 'text'" :label="tdc('Senha')">
34
+
35
+ <template v-slot:prepend>
36
+ <q-icon
37
+ name="lock"
38
+ class="cursor-pointer"
39
+ @click="isPwd = !isPwd"
40
+ />
41
+ </template>
42
+ <template v-slot:append>
43
+ <q-icon
44
+ :name="isPwd ? 'visibility_off' : 'visibility'"
45
+ class="cursor-pointer"
46
+ @click="isPwd = !isPwd"
47
+ />
48
+ </template>
49
+ </q-input>
50
+
51
+ <br/>
52
+ <q-checkbox class="text-grey-7" dense clearable v-model="User.manterLogado" @click="check" :label="tdc('Manter-me logado')">
53
+ </q-checkbox>
54
+ </q-form>
55
+ </q-card-section>
56
+
57
+ <q-card-actions class="q-px-md" >
58
+ <q-btn :readonly="readonly" size="md" @click="login()" color="positive" dense class="full-width " :label="tdc('Entrar')" />
59
+ <p></p>
60
+ </q-card-actions>
61
+ <q-card-actions align="around" >
62
+ <q-btn flat :to="{name:'esquecerpassword'}" size="md" color="purple" :label="tdc('Esqueci minha') + ' ' + tdc('Senha')" />
63
+ <q-btn flat :to="{name:'registarUser'}" size="md" color="primary" class="" :label="tdc('Registar')" />
64
+ </q-card-actions>
65
+ </q-card>
66
+ </div>
67
+ </q-page>
68
+ </q-page-container>
69
+ </template>
70
+ <style scoped>
71
+
72
+ </style>
73
+ <script >
74
+
75
+ import { defineComponent } from 'vue'
76
+ import { tdc } from '../boot/app'
77
+ import { AuthStore, UserStore } from '../stores/AuthStore'
78
+ import { setStorage, getStorage } from '../boot/storage';
79
+ import { useQuasar } from 'quasar'
80
+
81
+
82
+ export default defineComponent({
83
+ name: 'FormLogin',
84
+
85
+ props: {
86
+
87
+ },
88
+
89
+ components: {
90
+
91
+ },
92
+ setup () {
93
+ const Auth = AuthStore()
94
+ const User = UserStore()
95
+ const $q = useQuasar()
96
+ return {
97
+ Auth,
98
+ tdc,
99
+ User,
100
+ $q
101
+ }
102
+ },
103
+ data () {
104
+ return {
105
+ user_id: null,
106
+ entidade_id: null,
107
+ isPwd: true,
108
+ readonly: false,
109
+ email: '',
110
+ password: '',
111
+ incorrectAuth: false,
112
+ correctAuth: false,
113
+ latitude: '',
114
+ longitude: '',
115
+ local: '',
116
+ ipAddress: '0.0.0.0'
117
+ }
118
+ },
119
+ computed: {
120
+
121
+ },
122
+ watch: {
123
+ 'User.Grupo' (val) {
124
+ if (!val) return
125
+ this.$router.push({ name: 'wellcome' })
126
+ },
127
+ },
128
+ mounted () {
129
+
130
+ if (getStorage('c', 'manterlogado') === 'true') {
131
+ this.User.manterLogado = true
132
+ } else {
133
+ this.User.manterLogado = false
134
+ }
135
+ this.getGeolocation()
136
+ fetch('https://api.ipify.org?format=json')
137
+ .then(response => response.json())
138
+ .then(data => {
139
+ this.ipAddress = data.ip
140
+ })
141
+ .catch(error => {
142
+ console.error('Error fetching IP address:', error)
143
+ })
144
+ },
145
+ methods: {
146
+ check () {
147
+ setStorage('c', 'manterlogado', this.User.manterLogado, 365)
148
+ },
149
+ getGeolocation () {
150
+ if (navigator.geolocation) {
151
+ navigator.geolocation.getCurrentPosition(this.setPosition, this.errorPosition)
152
+ } else {
153
+ this.errorPosition()
154
+ }
155
+ },
156
+ async getLocalFromCoords(lat, lon) {
157
+ const url = `https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}&accept-language=pt`
158
+
159
+ const res = await fetch(url, {
160
+ headers: {
161
+ // 'User-Agent': 'SeuApp/1.0'
162
+ }
163
+ })
164
+
165
+ const data = await res.json()
166
+
167
+ return {
168
+ cidade: data.address.city
169
+ || data.address.town
170
+ || data.address.village
171
+ || '',
172
+ bairro: data.address.suburb || '',
173
+ pais: data.address.country || '',
174
+ nomeCompleto: data.display_name || '.'
175
+ }
176
+ },
177
+ setPosition (position) {
178
+ const coords = position.coords
179
+ this.latitude = coords.latitude
180
+ this.longitude = coords.longitude
181
+
182
+ this.local = this.getLocalFromCoords(this.latitude, this.longitude)
183
+ console.log(this.local)
184
+
185
+ },
186
+ errorPosition () {
187
+ this.$q.notify({
188
+ position: 'bottom',
189
+ timeout: 3000,
190
+ color: 'negative',
191
+ textColor: 'white',
192
+ actions: [{ icon: 'close', color: 'white' }],
193
+ message: 'Não foi possível recupera sua posição!'
194
+ })
195
+ },
196
+
197
+ async login () {
198
+ const availScreenWidth = window.screen.availWidth
199
+ const availScreenHeight = window.screen.availHeight
200
+
201
+ setStorage('c', 'manterlogado', this.User.manterLogado, 365)
202
+
203
+ this.correctAuth = false
204
+
205
+ await this.User.login({
206
+ email: this.email,
207
+ password: this.password,
208
+ info: navigator.platform + ' ' + this.ipAddress,
209
+ dispositivo: navigator.userAgent,
210
+ local_lat: this.latitude || '-26.372109',
211
+ local_lon: this.longitude || '28.233608',
212
+ local: JSON.stringify(this.local)
213
+ }, this.$q)
214
+ }
215
+ }
216
+ })
217
+ </script>
@@ -0,0 +1,93 @@
1
+
2
+ <template>
3
+ <q-layout >
4
+ <q-card square
5
+ :class="$q.dark.isActive ? 'bg-dark text-white fixed-top q-pa-sm ' : 'bg-primary text-white q-pa-sm fixed-top'"
6
+ flat
7
+ >
8
+ <div class="text-center text-h6">{{ User?.username }}</div>
9
+ <q-btn
10
+ flat dense
11
+ :label="User.Grupo?.name"
12
+ class="full-width"
13
+ >
14
+ <q-menu fit>
15
+ <q-list dense>
16
+ <q-item clickable v-close-popup @click="User.selectGrupo({id:'1', name:'Hóspede'})" >
17
+ <q-item-section>
18
+ <q-item-label overline> {{tdc('Hóspede')}}</q-item-label>
19
+ </q-item-section>
20
+ </q-item>
21
+ <q-item v-for="grupo in User.Grupos" :key="grupo.id" clickable @click="User.selectGroup(grupo)">
22
+ <q-item-section>{{ grupo.name }}</q-item-section>
23
+ </q-item>
24
+ </q-list>
25
+ </q-menu>
26
+ </q-btn>
27
+ <q-list >
28
+ <q-item clickable replace v-ripple exact
29
+ :class="$q.dark.isActive ? 'bg-dark text-white' : 'bg-primary text-white'"
30
+ exact-active-class="" >
31
+ <q-item-section avatar @click="$router.push({ name: 'home'})">
32
+ <q-icon name="home" />
33
+ </q-item-section>
34
+ <q-item-section class="text-h6" @click="$router.push({ name: 'home'})">{{ tdc('Casa') }}</q-item-section>
35
+ <q-item-section side >
36
+ <q-btn
37
+ round dense flat
38
+ :icon="'settings'" :class="$q.dark.isActive ? 'text-white' : 'text-white'"
39
+ @click="User.toggleSettings()"
40
+ >
41
+ <q-tooltip :class="$q.dark.isActive ? 'bg-dark text-white' : 'bg-primary text-white'">{{ tdc('Configurações') }}</q-tooltip>
42
+ </q-btn>
43
+ </q-item-section>
44
+ </q-item>
45
+ </q-list>
46
+ </q-card>
47
+
48
+ <LeftMenuSegundo :class="$q.dark.isActive ? 'bg-dark text-white fixed-top' : 'bg-primary text-white fixed-top'" style="margin-top:127px" ></LeftMenuSegundo>
49
+
50
+ </q-layout>
51
+ </template>
52
+ <script >
53
+
54
+ import LeftMenuSegundo from './LeftMenuSegundo.vue'
55
+
56
+
57
+ import { defineComponent } from 'vue'
58
+ import { HTTPClient, url } from '../boot/api'
59
+ import { tdc } from '../boot/app'
60
+ import { UserStore } from '../stores/AuthStore'
61
+
62
+ export default defineComponent({
63
+ components: {
64
+ LeftMenuSegundo
65
+ },
66
+ setup () {
67
+ const User = UserStore()
68
+ return {
69
+ User,
70
+ }
71
+ },
72
+
73
+ data () {
74
+ return {
75
+ tdc: tdc,
76
+
77
+ }
78
+ },
79
+
80
+ created () {
81
+ },
82
+ computed: {
83
+ },
84
+
85
+ mounted () {
86
+
87
+ },
88
+
89
+ methods: {
90
+
91
+ }
92
+ })
93
+ </script>
@@ -0,0 +1,96 @@
1
+ <template>
2
+ <div class="col-12" style="margin-top: 2px;">
3
+ <search-menu />
4
+ <q-card square flat class=" col-xs-12 col-md-12 col-lg-12 q-bt-md"
5
+ v-for="App in Auth.TipoEntidadeMenus" :key="App"
6
+ style="padding: 0px;"
7
+ v-show="User.EntidadeModulos.includes(App.app) && User.isAuthorized(App.app.toLowerCase())"
8
+ >
9
+ <q-expansion-item default-opened
10
+ :class="$q.dark.isActive ? 'bg-dark-custom text-subtitle1' : 'bg-white text-subtitle1 text-primary'"
11
+ :icon="App.icon"
12
+ dense
13
+ :label="tdc(App.menu)"
14
+ :header-class="$q.dark.isActive ? 'bg-dark text-white' : 'bg-primary text-white'"
15
+ :expand-icon-class="$q.dark.isActive ? 'text-white' : 'text-white'"
16
+ >
17
+ <q-separator />
18
+
19
+ <q-item v-for="sm in App.submenu " :key="sm"
20
+ dense
21
+ clickable v-ripple
22
+ :to="{name: sm?.rota}"
23
+ v-show="User.isAuthorized(sm.role.toLowerCase())"
24
+ >
25
+ <q-item-section avatar>
26
+ <q-icon :name="sm.icon" />
27
+ </q-item-section>
28
+ <q-item-section>{{tdc(sm.menu)}}</q-item-section>
29
+ <q-item-section side >
30
+ <q-item dense style="margin-right: -20px;"
31
+ v-show="User.isAuthorized('add_' + sm.menu.toLowerCase())"
32
+ clickable v-ripple
33
+ :to="{name: 'add_' + sm.menu.toLowerCase()}"
34
+ >
35
+ <q-icon name="add" size="sm" :color="$q.dark.isActive ? '' : 'primary'">
36
+ <q-tooltip :class="$q.dark.isActive ? 'bg-dark' : 'bg-primary'">
37
+ {{ tdc('Adicionar ') }} {{ tdc(sm.menu) }}
38
+ </q-tooltip>
39
+ </q-icon>
40
+ </q-item>
41
+ </q-item-section>
42
+ </q-item>
43
+ <q-separator />
44
+ </q-expansion-item>
45
+ </q-card>
46
+ </div>
47
+ </template>
48
+
49
+ <style scoped>
50
+ .bg-dark-custom {
51
+ background-color: #121212 !important;
52
+ }
53
+ </style>
54
+ <script >
55
+
56
+
57
+ import { defineComponent } from 'vue'
58
+ import { tdc } from '../boot/app'
59
+ import { AuthStore, UserStore } from '../stores/AuthStore'
60
+ import SearchMenu from './SearchMenu.vue';
61
+
62
+
63
+ export default defineComponent({
64
+ name: 'LeftMenuSegundo',
65
+
66
+ components: {
67
+ SearchMenu
68
+ },
69
+ setup () {
70
+ const Auth = AuthStore()
71
+ const User = UserStore()
72
+ return {
73
+ Auth,
74
+ User,
75
+ tdc
76
+ }
77
+ },
78
+ data () {
79
+ return {
80
+
81
+ }
82
+ },
83
+ computed: {
84
+
85
+ },
86
+ watch: {
87
+
88
+ },
89
+ mounted () {
90
+
91
+ },
92
+ methods: {
93
+
94
+ }
95
+ })
96
+ </script>
@@ -0,0 +1,41 @@
1
+ <template>
2
+ <div class="q-pa-md">
3
+ <h1> {{ Teste }}</h1>
4
+ </div>
5
+ </template>
6
+
7
+
8
+
9
+ <script>
10
+ import { defineComponent } from 'vue'
11
+
12
+
13
+ export default defineComponent({
14
+ components: {
15
+
16
+ },
17
+ setup () {
18
+
19
+ return {
20
+
21
+ }
22
+ },
23
+ data () {
24
+ return {
25
+ Teste: "Teste",
26
+
27
+ }
28
+ },
29
+ computed: {
30
+
31
+ },
32
+
33
+ mounted(){
34
+
35
+ },
36
+
37
+ methods: {
38
+
39
+ }
40
+ })
41
+ </script>
@@ -0,0 +1,36 @@
1
+ <template>
2
+ <div class="q-pa-md">
3
+ <h1>{{Teste}}</h1>
4
+ </div>
5
+ </template>
6
+
7
+
8
+ <script>
9
+ import { defineComponent } from 'vue'
10
+
11
+ export default defineComponent({
12
+ components: {
13
+
14
+ },
15
+ setup () {
16
+ return {
17
+ }
18
+ },
19
+ data () {
20
+ return {
21
+ Teste: "Teste",
22
+ }
23
+ },
24
+ computed: {
25
+
26
+ },
27
+
28
+ mounted(){
29
+
30
+ },
31
+
32
+ methods: {
33
+
34
+ }
35
+ })
36
+ </script>
@@ -0,0 +1,88 @@
1
+ <template>
2
+ <div >
3
+ <q-input standout v-model="Auth.search" square :class="[$q.dark.isActive ? 'bg-transparent ' : 'bg-transparent', 'input-28', 'q-pa-0']" dense @update:model-value="filterMenus"
4
+ :label=" ' ' + tdc(' Procurar') + ' '">
5
+ <template v-slot:append>
6
+ <q-icon name="search" />
7
+ </template>
8
+ </q-input>
9
+ </div>
10
+ </template>
11
+
12
+ <style scoped>
13
+ .input-28 .q-field__control {
14
+ height: 28px;
15
+ min-height: 28px;
16
+ }
17
+ </style>
18
+
19
+ <script >
20
+
21
+ import { defineComponent } from 'vue'
22
+ import { tdc } from '../boot/app'
23
+ import { UserStore, AuthStore } from '../stores/AuthStore'
24
+
25
+
26
+
27
+ export default defineComponent({
28
+ name: 'SearchMenu',
29
+
30
+ components: {
31
+
32
+ },
33
+ setup () {
34
+
35
+ const User = UserStore()
36
+ const Auth = AuthStore()
37
+
38
+ return {
39
+ User,
40
+ Auth,
41
+ tdc
42
+ }
43
+ },
44
+ data () {
45
+ return {
46
+ search: ''
47
+ }
48
+ },
49
+ computed: {
50
+
51
+ },
52
+ watch: {
53
+ 'User.Permicoes' () {
54
+ this.filterMenus(this.Auth.search)
55
+ },
56
+
57
+ 'User.Entidade'() {
58
+ this.Auth.setTipoEntidadeMenus()
59
+ this.User.setEntidadeModelos()
60
+ this.User.setEntidadeModulos()
61
+ },
62
+
63
+ },
64
+ mounted () {
65
+ this.filterMenus(this.Auth.search)
66
+ this.Auth.setTipoEntidadeMenus()
67
+ this.User.setEntidadeModelos()
68
+ this.User.setEntidadeModulos()
69
+ },
70
+ methods: {
71
+
72
+ filterMenus (val) {
73
+ console.log(val)
74
+ if (val === '') {
75
+ this.Auth.TipoEntidadeMenus = this.Auth.TipoEntidadeAllMenus
76
+ } else {
77
+ const needle = val.toLowerCase()
78
+ this.Auth.TipoEntidadeMenus = this.Auth.TipoEntidadeAllMenus.map(v => ({
79
+ ...v,
80
+ submenu: v.submenu.filter(sub =>
81
+ sub.menu && sub.menu.toLowerCase().includes(needle.toLowerCase())
82
+ )
83
+ })).filter(v => v.submenu.length > 0)
84
+ }
85
+ }
86
+ }
87
+ })
88
+ </script>
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <div class="q-pa-md q-gutter-sm">
3
+ <q-btn label="Fixed size" color="primary" @click="''" />
4
+ </div>
5
+ </template>
6
+ <script >
7
+
8
+ import { defineComponent } from 'vue'
9
+
10
+ // import { st } from 'src/js/appMytech'
11
+
12
+ export default defineComponent({
13
+ components: {
14
+
15
+ },
16
+ setup () {
17
+ },
18
+ data () {
19
+ return {
20
+
21
+ }
22
+ },
23
+ methods: {
24
+
25
+ },
26
+ created () {
27
+ },
28
+ computed: {
29
+ },
30
+ mounted () {
31
+
32
+ }
33
+ })
34
+ </script>
@@ -0,0 +1,68 @@
1
+ <template>
2
+ <q-bar >
3
+ <div class="q-pa-sm q-pl-md items-center text-body1">
4
+ <div class="q-ml-md cursor-pointer non-selectable">
5
+ <q-item clickable dense replace v-ripple
6
+ :class="$q.dark.isActive ? 'bg-dark text-white' : 'bg-primary text-white'" >
7
+ <q-item-section avatar @click="$router.push({ name: 'home'})" >
8
+ <q-icon name="home" />
9
+ </q-item-section>
10
+ <q-item-section class="text-body1" @click="$router.push({ name: 'home'})" >{{ tdc('Casa') }}</q-item-section>
11
+ <q-item-section side>
12
+ <q-btn
13
+ round dense flat
14
+ :icon="'settings'" :class="$q.dark.isActive ? 'text-white' : 'text-white'"
15
+ @click="User.toggleSettings()"
16
+ >
17
+ <q-tooltip :class="$q.dark.isActive ? 'bg-dark text-white' : 'bg-primary text-white'">{{ tdc('Configurações') }}</q-tooltip>
18
+ </q-btn>
19
+ </q-item-section>
20
+ </q-item>
21
+ </div>
22
+ </div>
23
+
24
+ <SearchMenu style="height: 28px; margin-top:-4px;"/>
25
+ <q-space />
26
+ <TopMenuSegundo ></TopMenuSegundo>
27
+ </q-bar>
28
+ </template>
29
+ <script >
30
+
31
+ import TopMenuSegundo from './TopMenuSegundo.vue'
32
+ import { defineComponent } from 'vue'
33
+ import { tdc } from '../boot/app'
34
+ import { UserStore } from '../stores/AuthStore'
35
+ import SearchMenu from './SearchMenu.vue';
36
+
37
+ export default defineComponent({
38
+ components: {
39
+ TopMenuSegundo,
40
+ SearchMenu
41
+ },
42
+ setup () {
43
+ const User = UserStore()
44
+ return {
45
+ User
46
+ }
47
+ },
48
+
49
+ data () {
50
+ return {
51
+ tdc: tdc,
52
+ }
53
+ },
54
+
55
+ created () {
56
+ },
57
+ computed: {
58
+ },
59
+
60
+ mounted () {
61
+
62
+ },
63
+
64
+ methods: {
65
+
66
+ }
67
+ })
68
+ </script>