rules username perfil
3460
package-lock.json
generated
@@ -26,7 +26,14 @@
|
||||
"eslint-config-prettier": "^8.1.0",
|
||||
"eslint-plugin-vue": "^9.0.0",
|
||||
"postcss": "^8.4.14",
|
||||
"prettier": "^2.5.1"
|
||||
"prettier": "^2.5.1",
|
||||
"workbox-build": "^6.5.4",
|
||||
"workbox-cacheable-response": "^6.5.4",
|
||||
"workbox-core": "^6.5.4",
|
||||
"workbox-expiration": "^6.5.4",
|
||||
"workbox-precaching": "^6.5.4",
|
||||
"workbox-routing": "^6.5.4",
|
||||
"workbox-strategies": "^6.5.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18 || ^16 || ^14.19",
|
||||
|
||||
BIN
public/icons/apple-icon-120x120.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
public/icons/apple-icon-152x152.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/icons/apple-icon-167x167.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
public/icons/apple-icon-180x180.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/icons/icon-128x128.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/icons/icon-192x192.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
public/icons/icon-256x256.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
public/icons/icon-384x384.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
public/icons/icon-512x512.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
public/icons/ms-icon-144x144.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
1
public/icons/safari-pinned-tab.svg
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
30
src-pwa/custom-service-worker.js
Normal file
@@ -0,0 +1,30 @@
|
||||
/* eslint-env serviceworker */
|
||||
|
||||
/*
|
||||
* This file (which will be your service worker)
|
||||
* is picked up by the build system ONLY if
|
||||
* quasar.config.js > pwa > workboxMode is set to "injectManifest"
|
||||
*/
|
||||
|
||||
import { clientsClaim } from 'workbox-core'
|
||||
import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching'
|
||||
import { registerRoute, NavigationRoute } from 'workbox-routing'
|
||||
|
||||
self.skipWaiting()
|
||||
clientsClaim()
|
||||
|
||||
// Use with precache injection
|
||||
precacheAndRoute(self.__WB_MANIFEST)
|
||||
|
||||
cleanupOutdatedCaches()
|
||||
|
||||
// Non-SSR fallback to index.html
|
||||
// Production SSR fallback to offline.html (except for dev)
|
||||
if (process.env.MODE !== 'ssr' || process.env.PROD) {
|
||||
registerRoute(
|
||||
new NavigationRoute(
|
||||
createHandlerBoundToURL(process.env.PWA_FALLBACK_HTML),
|
||||
{ denylist: [/sw\.js$/, /workbox-(.)*\.js$/] }
|
||||
)
|
||||
)
|
||||
}
|
||||
32
src-pwa/manifest.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"orientation": "portrait",
|
||||
"background_color": "#ffffff",
|
||||
"theme_color": "#027be3",
|
||||
"icons": [
|
||||
{
|
||||
"src": "icons/icon-128x128.png",
|
||||
"sizes": "128x128",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "icons/icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "icons/icon-256x256.png",
|
||||
"sizes": "256x256",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "icons/icon-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "icons/icon-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
]
|
||||
}
|
||||
10
src-pwa/pwa-flag.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/* eslint-disable */
|
||||
// THIS FEATURE-FLAG FILE IS AUTOGENERATED,
|
||||
// REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING
|
||||
import "quasar/dist/types/feature-flag";
|
||||
|
||||
declare module "quasar/dist/types/feature-flag" {
|
||||
interface QuasarFeatureFlags {
|
||||
pwa: true;
|
||||
}
|
||||
}
|
||||
41
src-pwa/register-service-worker.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import { register } from 'register-service-worker'
|
||||
|
||||
// The ready(), registered(), cached(), updatefound() and updated()
|
||||
// events passes a ServiceWorkerRegistration instance in their arguments.
|
||||
// ServiceWorkerRegistration: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration
|
||||
|
||||
register(process.env.SERVICE_WORKER_FILE, {
|
||||
// The registrationOptions object will be passed as the second argument
|
||||
// to ServiceWorkerContainer.register()
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register#Parameter
|
||||
|
||||
// registrationOptions: { scope: './' },
|
||||
|
||||
ready (/* registration */) {
|
||||
// console.log('Service worker is active.')
|
||||
},
|
||||
|
||||
registered (/* registration */) {
|
||||
// console.log('Service worker has been registered.')
|
||||
},
|
||||
|
||||
cached (/* registration */) {
|
||||
// console.log('Content has been cached for offline use.')
|
||||
},
|
||||
|
||||
updatefound (/* registration */) {
|
||||
// console.log('New content is downloading.')
|
||||
},
|
||||
|
||||
updated (/* registration */) {
|
||||
// console.log('New content is available; please refresh.')
|
||||
},
|
||||
|
||||
offline () {
|
||||
// console.log('No internet connection found. App is running in offline mode.')
|
||||
},
|
||||
|
||||
error (/* err */) {
|
||||
// console.error('Error during service worker registration:', err)
|
||||
}
|
||||
})
|
||||
@@ -26,23 +26,35 @@
|
||||
/>
|
||||
</q-avatar>
|
||||
</div>
|
||||
<div class="row" style="max-width: 200px">
|
||||
<q-file class="full-width" outlined v-model="imagen" label="Avatar" />
|
||||
</div>
|
||||
<div class="row">
|
||||
<q-input outlined v-model="name" label="Name" />
|
||||
</div>
|
||||
<div class="row">
|
||||
<q-input outlined v-model="username" label="Username" />
|
||||
</div>
|
||||
<div class="row">
|
||||
<q-input
|
||||
outlined
|
||||
v-model="listaStore.pb.authStore.model.email"
|
||||
label="email"
|
||||
disable
|
||||
/>
|
||||
</div>
|
||||
<q-form class="q-gutter-md" @click.once="recibeDatos()">
|
||||
<div class="row" style="max-width: 200px">
|
||||
<q-file class="full-width" outlined v-model="imagen" label="Avatar" />
|
||||
</div>
|
||||
<div class="row">
|
||||
<q-input outlined v-model="name" label="Name" />
|
||||
</div>
|
||||
<div class="row">
|
||||
<q-input
|
||||
outlined
|
||||
v-model="username"
|
||||
label="Username"
|
||||
:rules="[
|
||||
(val) =>
|
||||
(val != null && val.length >= 3) || 'Mínimo 3 caracteres',
|
||||
(val) => comprobarUsername || 'Ya existe en la BD',
|
||||
(val) => /^[A-Z0-9]+$/i.test(val) || 'Sólo letras o números',
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
<div class="row">
|
||||
<q-input
|
||||
outlined
|
||||
v-model="listaStore.pb.authStore.model.email"
|
||||
label="email"
|
||||
disable
|
||||
/>
|
||||
</div>
|
||||
</q-form>
|
||||
<div class="row q-pt-md">
|
||||
<div class="col text-center">
|
||||
<q-btn round color="primary" icon="cancel" @click="cargarDatos()" />
|
||||
@@ -85,7 +97,7 @@
|
||||
</q-page>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ref, computed } from "vue";
|
||||
import { useListaStore } from "../stores/lista.js";
|
||||
|
||||
const listaStore = useListaStore();
|
||||
@@ -94,13 +106,15 @@ const imagen = ref(null);
|
||||
const username = ref(listaStore.pb.authStore.model.username);
|
||||
const name = ref(listaStore.pb.authStore.model.name);
|
||||
const alertSave = ref(false);
|
||||
const usuarios = ref([]);
|
||||
|
||||
const updateUser = async () => {
|
||||
const formData = new FormData();
|
||||
if (username.value.trim().length > 0) {
|
||||
formData.append("username", username.value);
|
||||
formData.append("username", username.value.trim());
|
||||
}
|
||||
if (name.value.trim().length > 0) {
|
||||
formData.append("name", name.value);
|
||||
formData.append("name", name.value.trim());
|
||||
}
|
||||
if (imagen.value != null) {
|
||||
formData.append("avatar", imagen.value);
|
||||
@@ -117,4 +131,25 @@ const cargarDatos = () => {
|
||||
username.value = listaStore.pb.authStore.model.username.trim();
|
||||
name.value = listaStore.pb.authStore.model.name.trim();
|
||||
};
|
||||
|
||||
const recibeDatos = () => {
|
||||
listaStore.getUsers().then(function (item) {
|
||||
usuarios.value = item;
|
||||
});
|
||||
};
|
||||
|
||||
const comprobarUsername = computed(() => {
|
||||
let filtro = usuarios.value?.filter(
|
||||
(user) => user.username.toLowerCase() == username.value.trim().toLowerCase()
|
||||
);
|
||||
if (filtro.length == 0) {
|
||||
return true;
|
||||
} else if (
|
||||
filtro.length == 1 &&
|
||||
filtro[0].username == listaStore.pb.authStore.model.username
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
|
||||