- versione: 1.2.77

- aggiustamenti e miglioramenti estetici
This commit is contained in:
Surya Paolo
2025-11-03 14:24:10 +01:00
parent a164db8bf3
commit d812c6c799
34 changed files with 1121 additions and 348 deletions

4
.env
View File

@@ -1,6 +1,6 @@
VITE_APP_VERSION="1.2.76"
VITE_APP_VERSION="1.2.77"
VITE_LANG_DEFAULT="it"
VITE_PAO_APP_ID="KKPPAA5KJK435J3KSS9F9D8S9F8SD98F9SDF"
VITE_SERVICE_WORKER_FILE="sw-1.2.76.js"
VITE_SERVICE_WORKER_FILE="sw-1.2.77.js"
VITE_PROJECT_ID_MAIN="5cc0a13fe5c9d156728f400a"
VITE_VUE_ROUTER_MODE="history"

View File

@@ -10,7 +10,7 @@
<meta name="description" content="<%= productDescription %>">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="version" content="1.2.76">
<meta name="version" content="1.2.77">
<meta name="viewport"
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>">

View File

@@ -1,6 +1,6 @@
{
"name": "riso",
"version": "1.2.76",
"version": "1.2.77",
"productName": "Riso 💚 - Rete Italiana Scambi Orizzontali",
"description": "Progetto RISO (Rete Italiana Scambi Orizzontali) promuove una rete di comunità locali che favoriscono scambi di beni, servizi e ospitalità. Con l'App RISO, sviluppata per facilitare il baratto, il dono e l'uso di monete alternative come i RIS, il progetto crea legami autentici basati sulla fiducia e sostenibilità. Partecipa agli scambi e costruisci una comunità più consapevole e autosufficiente.",
"author": "Surya",
@@ -9,11 +9,11 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "APP_VERSION='1.2.76' PORT=8084 quasar dev",
"dev": "APP_VERSION='1.2.77' PORT=8084 quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.76' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.76' quasar build -m pwa",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.77' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.77' quasar build -m pwa",
"type-check": "vue-tsc --noEmit",
"type-check:watch": "vue-tsc --noEmit --watch",
"buildspa": "quasar build -m spa",
@@ -21,8 +21,8 @@
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.76' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8084 APP_VERSION='1.2.76' quasar dev",
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.77' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8084 APP_VERSION='1.2.77' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",

View File

@@ -1,6 +1,6 @@
{
"name": "cnm",
"version": "1.2.76",
"version": "1.2.77",
"description": "Comunita Nuovo Mondo",
"productName": "ComunitaNuovoMondo",
"author": "Surya",
@@ -9,7 +9,7 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "PORT=8083 APP_VERSION='1.2.76' quasar dev",
"dev": "PORT=8083 APP_VERSION='1.2.77' quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production quasar build -m pwa",
@@ -21,8 +21,8 @@
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.76' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.76' quasar dev",
"pwa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.77' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.77' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",

View File

@@ -1,6 +1,6 @@
{
"name": "freeplanet",
"version": "1.2.76",
"version": "1.2.77",
"description": "freeplanet",
"productName": "freeplanet",
"author": "Surya",
@@ -9,11 +9,11 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "PORT=8087 APP_VERSION='1.2.76' quasar dev",
"dev": "PORT=8087 APP_VERSION='1.2.77' quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.76' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.76' quasar build -m pwa",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.77' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.77' quasar build -m pwa",
"type-check": "vue-tsc --noEmit",
"type-check:watch": "vue-tsc --noEmit --watch",
"buildspa": "quasar build -m spa",
@@ -21,8 +21,8 @@
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8097 APP_VERSION='1.2.76' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8087 APP_VERSION='1.2.76' quasar dev",
"pwa": "NODE_ENV=development PORT=8097 APP_VERSION='1.2.77' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8087 APP_VERSION='1.2.77' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",

View File

@@ -1,6 +1,6 @@
{
"name": "gruppomacro",
"version": "1.2.76",
"version": "1.2.77",
"productName": "Gruppo Macro",
"description": "Il Gruppo Editoriale Macro, attivo dal 1987, è leader europeo nella pubblicazione di libri per il benessere e la consapevolezza. Con oltre 1.500 titoli, promuove una visione armonica del mondo, offrendo opere di autori internazionali e italiani come Gregg Braden, Bruce Lipton, Joe Dispenza, Louise Hay, Eckhart Tolle e molti altri. Scopri un'editoria che abbraccia il corpo, la mente, lo spirito e l'ecologia.",
"author": "Surya",
@@ -9,20 +9,20 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "PORT=8089 APP_VERSION='1.2.76' quasar dev",
"dev": "PORT=8089 APP_VERSION='1.2.77' quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.76' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.76' quasar build -m pwa",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.77' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.77' quasar build -m pwa",
"type-check": "vue-tsc --noEmit",
"type-check:watch": "vue-tsc --noEmit --watch",
"buildspa": "APP_VERSION='1.2.76' quasar build -m spa",
"buildspa": "APP_VERSION='1.2.77' quasar build -m spa",
"lint": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\"",
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.76' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8089 APP_VERSION='1.2.76' quasar dev",
"pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.77' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8089 APP_VERSION='1.2.77' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",

View File

@@ -1,6 +1,6 @@
{
"name": "nuovomondo",
"version": "1.2.76",
"version": "1.2.77",
"description": "Nuovo Mondo",
"productName": "Nuovo Mondo",
"author": "Surya",
@@ -9,11 +9,11 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "APP_VERSION='1.2.76' PORT=8083 quasar dev",
"dev": "APP_VERSION='1.2.77' PORT=8083 quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.76' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.76' quasar build -m pwa",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.77' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.77' quasar build -m pwa",
"type-check": "vue-tsc --noEmit",
"type-check:watch": "vue-tsc --noEmit --watch",
"buildspa": "quasar build -m spa",
@@ -21,8 +21,8 @@
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.76' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.76' quasar dev",
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.77' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.77' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",

View File

@@ -1,6 +1,6 @@
{
"name": "nutriben",
"version": "1.2.76",
"version": "1.2.77",
"description": "Nutriben",
"productName": "Nutriben",
"author": "Surya",
@@ -9,20 +9,20 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "PORT=8093 APP_VERSION='1.2.76' quasar dev",
"dev": "PORT=8093 APP_VERSION='1.2.77' quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.76' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.76' quasar build -m pwa",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.77' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.77' quasar build -m pwa",
"type-check": "vue-tsc --noEmit",
"type-check:watch": "vue-tsc --noEmit --watch",
"buildspa": "APP_VERSION='1.2.76' quasar build -m spa",
"buildspa": "APP_VERSION='1.2.77' quasar build -m spa",
"lint": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\"",
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.76' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.76' quasar dev",
"pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.77' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.77' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",

View File

@@ -1,6 +1,6 @@
{
"name": "piuchebuono",
"version": "1.2.76",
"version": "1.2.77",
"description": "PiuCheBuono",
"productName": "PiuCheBuono",
"author": "Surya",
@@ -9,11 +9,11 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "PORT=8085 APP_VERSION='1.2.76' quasar dev",
"dev": "PORT=8085 APP_VERSION='1.2.77' quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.76' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.76' quasar build -m pwa",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.77' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.77' quasar build -m pwa",
"type-check": "vue-tsc --noEmit",
"type-check:watch": "vue-tsc --noEmit --watch",
"buildspa": "quasar build -m spa",
@@ -21,8 +21,8 @@
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.76' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.76' quasar dev",
"pwa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.77' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.77' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",

View File

@@ -1,6 +1,6 @@
{
"name": "riso",
"version": "1.2.76",
"version": "1.2.77",
"productName": "Riso 💚 - Rete Italiana Scambi Orizzontali",
"description": "Progetto RISO (Rete Italiana Scambi Orizzontali) promuove una rete di comunità locali che favoriscono scambi di beni, servizi e ospitalità. Con l'App RISO, sviluppata per facilitare il baratto, il dono e l'uso di monete alternative come i RIS, il progetto crea legami autentici basati sulla fiducia e sostenibilità. Partecipa agli scambi e costruisci una comunità più consapevole e autosufficiente.",
"author": "Surya",
@@ -9,11 +9,11 @@
"license": "MIT",
"type": "module",
"scripts": {
"dev": "APP_VERSION='1.2.76' PORT=8084 quasar dev",
"dev": "APP_VERSION='1.2.77' PORT=8084 quasar dev",
"dev_noCheck": "SKIP_TSC=true quasar dev",
"build": "quasar build",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.76' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.76' quasar build -m pwa",
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.77' quasar build -m pwa",
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.77' quasar build -m pwa",
"type-check": "vue-tsc --noEmit",
"type-check:watch": "vue-tsc --noEmit --watch",
"buildspa": "quasar build -m spa",
@@ -21,8 +21,8 @@
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.76' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8084 APP_VERSION='1.2.76' quasar dev",
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.77' quasar dev -m pwa",
"spa": "NODE_ENV=development PORT=8084 APP_VERSION='1.2.77' quasar dev",
"debug": "quasar dev --mode debug",
"test": "echo \"No test specified\" && exit 0",
"generate-sw": "workbox generateSW workbox-config.js",

View File

@@ -3,7 +3,7 @@
/* global workbox */
/* global cfgenv */
const VITE_APP_VERSION = '1.2.76';
const VITE_APP_VERSION = '1.2.77';
// Costanti di configurazione
const DYNAMIC_CACHE = 'dynamic-cache-v2';

View File

@@ -0,0 +1,27 @@
.currency-card {
border-radius: 12px;
transition: all 0.2s ease;
&:hover {
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
transform: translateY(-2px);
}
.text-positive {
color: #2e7d32;
}
.text-negative {
color: #c62828;
}
.text-grey {
color: #757575;
}
@media (max-width: 600px) {
.text-body1 {
font-size: 0.9rem;
}
.text-weight-bold {
font-size: 1rem;
}
}
}

View File

@@ -3,4 +3,45 @@
background-color: #fff; /* Colore sfondo per il contenitore (puoi personalizzare) */
border-radius: 10px;
}
}
.option-card {
border-radius: 14px;
background: white;
transition: all 0.25s ease;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
&:hover {
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
}
}
.modern-option-group {
.q-radio {
margin: 6px 0;
border-radius: 10px;
transition: all 0.2s ease;
padding: 6px 10px;
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
&:hover {
background-color: rgba(0, 0, 0, 0.04);
}
&.q-radio--active {
background-color: rgba(var(--q-primary-rgb), 0.08);
border-left: 3px solid var(--q-primary);
}
.q-radio__label {
font-size: 0.95rem;
color: #333;
}
.q-icon {
color: var(--q-primary);
}
}
}

View File

@@ -86,19 +86,19 @@ export default defineComponent({
const contact = computed(() => userStore.my);
const searchType = ref('receivers');
const searchType = ref('username');
const usersList = ref(<any>{ show: false, title: '', list: [], listgroup: [] });
const options = ref([
{
label: 'Lista dei Riceventi di oggi',
value: 'receivers',
},
{
label: 'Cerca per Nome o Username',
value: 'username',
},
{
label: 'Lista dei Riceventi di oggi',
value: 'receivers',
},
{
label: 'Scansiona il QRCode del Destinatario',
value: 'qrcode',

View File

@@ -1,11 +1,18 @@
<template>
<q-option-group
class="q-ma-xs"
style="text-align: left !important"
v-model="searchType"
:options="options"
color="primary"
/>
<div class="q-pa-xs q-gutter-xs">
<q-card flat bordered class="option-card q-pa-xs">
<div class="text-subtitle1 text-weight-medium text-primary q-mb-xs">
Scegli il Destinatario dei RIS
</div>
<q-option-group
v-model="searchType"
:options="options"
color="primary"
type="radio"
class="modern-option-group"
/>
</q-card>
</div>
<q-tab-panels
v-model="searchType"
keep-alive

View File

@@ -1,26 +1,261 @@
// Card totale con gradiente sottile
.total-card {
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
border-radius: 12px;
border: 1px solid rgba(0, 0, 0, 0.08);
transition: all 0.3s ease;
&:hover {
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
transform: translateY(-2px);
}
}
.transaction-icon {
opacity: 0.15;
transition: all 0.3s ease;
}
.total-card:hover .transaction-icon {
opacity: 0.25;
transform: scale(1.1);
}
// Container tabs
.tabs-container {
border-radius: 12px;
overflow: hidden;
border: 1px solid rgba(0, 0, 0, 0.08);
}
.custom-tabs {
background: #ffffff;
:deep(.q-tab) {
padding: 16px 20px;
font-weight: 500;
transition: all 0.3s ease;
&:hover {
background: rgba(0, 0, 0, 0.02);
}
}
:deep(.q-tab__indicator) {
height: 3px;
border-radius: 3px 3px 0 0;
}
}
// Pannelli trasparenti
.transparent-panels {
background: transparent;
:deep(.q-panel) {
background: transparent;
}
}
// Lista movimenti
.movements-list {
display: flex;
flex-direction: column;
gap: 4px;
padding: 8px 0;
}
.movement-item {
transition: all 0.3s ease;
}
// Empty state
.empty-state {
border-radius: 12px;
background: #fafafa;
border: 2px dashed rgba(0, 0, 0, 0.1);
margin: 16px 0;
}
// Animazioni lista
.list-enter-active,
.list-leave-active {
transition: all 0.4s ease;
}
.list-enter-from {
opacity: 0;
transform: translateX(-30px);
}
.list-leave-to {
opacity: 0;
transform: translateX(30px);
}
.list-move {
transition: transform 0.4s ease;
}
// Bottone carica altri
.load-more-btn {
padding: 12px 32px;
font-weight: 500;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
&:hover {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
transform: translateY(-2px);
}
&:active {
transform: translateY(0);
}
}
// Responsive
@media (max-width: 600px) {
.total-card {
:deep(.q-card-section) {
padding: 20px !important;
}
.text-h3 {
font-size: 2rem;
}
.transaction-icon {
display: none;
}
}
.custom-tabs {
:deep(.q-tab) {
padding: 12px 8px;
font-size: 0.875rem;
min-height: 48px;
}
}
.movements-list {
gap: 0px;
padding: 0px 0;
}
.empty-state {
padding: 40px 20px !important;
.q-icon {
font-size: 48px !important;
}
.text-h6 {
font-size: 1rem;
}
}
}
@media (max-width: 400px) {
.custom-tabs {
:deep(.q-tab) {
font-size: 0.75rem;
padding: 12px 4px;
}
}
}
// Bordi arrotondati per lista alternativa
.rounded-borders {
border-radius: 12px;
overflow: hidden;
}
// Spinner loading
#spinner {
:deep(.q-spinner) {
filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.1));
}
}
// Stili per movimenti (integrati dal CSS originale)
.userfrom {
color: red;
font-weight: bold;
color: #e53935;
font-weight: 600;
transition: color 0.2s ease;
&:hover {
color: #c62828;
}
}
.userto {
color: green;
font-weight: bold;
color: #43a047;
font-weight: 600;
transition: color 0.2s ease;
&:hover {
color: #2e7d32;
}
}
.circuit {
color: blue;
color: #1e88e5;
font-weight: 500;
transition: color 0.2s ease;
&:hover {
color: #1565c0;
}
}
.date {
color: gray;
color: #757575;
font-size: 0.875rem;
font-weight: 400;
}
.rigamov {
background-color: lightgray;
background: linear-gradient(to right, #f5f5f5 0%, #fafafa 100%);
border-radius: 8px;
padding: 12px;
margin-bottom: 8px;
border: 1px solid rgba(0, 0, 0, 0.06);
transition: all 0.3s ease;
&:hover {
background: linear-gradient(to right, #eeeeee 0%, #f5f5f5 100%);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
transform: translateX(4px);
}
}
.causale {
font-weight: bold;
margin-bottom: 8px;
font-weight: 600;
margin-bottom: 8px;
color: #424242;
font-size: 0.95rem;
line-height: 1.4;
}
// Responsive per gli stili dei movimenti
@media (max-width: 600px) {
.userfrom,
.userto,
.circuit {
font-size: 0.875rem;
}
.date {
font-size: 0.75rem;
}
.rigamov {
padding: 10px;
margin-bottom: 6px;
}
.causale {
font-size: 0.875rem;
margin-bottom: 6px;
}
}

View File

@@ -46,7 +46,9 @@ export default defineComponent({
const prectransaz = ref(0)
const tab = ref('tutti')
const nummovTodownload = ref(5)
const nummovTodownload = ref(10)
const total_transactions = ref(0)
const mylist = computed(() => {
if (globalStore.datastat || userStore.my.profile) {
@@ -62,6 +64,8 @@ export default defineComponent({
}
}
total_transactions.value = userStore.my.profile.total_transactions
if (transaz >= 0) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
numtransaz.value = transaz
@@ -143,7 +147,7 @@ export default defineComponent({
})
async function addlastmov() {
nummovTodownload.value += 5
nummovTodownload.value += 10
loadingvalues.value = true
await globalStore.loadLastMovements(nummovTodownload.value)
@@ -163,6 +167,7 @@ export default defineComponent({
tab,
loadingvalues,
addlastmov,
total_transactions,
}
}
})

View File

@@ -1,92 +1,223 @@
<template>
<div v-if="username">
<q-tabs
v-model="tab"
dense
inline-label
class="bg-primary text-white shadow-2"
>
<q-tab name="tutti" label="Tutti" />
<q-tab
name="inviati"
:label="t('circuit.inviati') + ' (' + getInviati.length + ')'"
/>
<q-tab
name="ricevuti"
:label="t('circuit.ricevuti') + ' (' + getRicevuti.length + ')'"
/>
</q-tabs>
<!-- Card totale con design più elegante -->
<div class="q-mt-xs q-mb-xs">
<q-card
flat
bordered
class="total-card"
>
<q-card-section class="q-pa-xs">
<div class="row items-center justify-between no-wrap">
<div class="text-body1 text-grey-7">
{{ t('circuit.totale_movimenti_effettuati') }}
</div>
<div class="text-h4 text-weight-bold text-primary text-right">
{{ total_transactions }}
</div>
<q-icon
name="receipt_long"
size="32px"
color="primary"
class="transaction-icon q-ml-sm"
/>
</div>
</q-card-section>
</q-card>
</div>
<q-tab-panels v-model="tab" animated keep-alive>
<q-tab-panel name="tutti">
<div v-if="mylist.length === 0">
{{ t('circuit.nessun_movimento_inviato') }}
</div>
<c-single-movement
v-for="(mov, index) in mylist"
:key="index"
:index="index"
:mov="mov"
:visu="0"
<!-- Tabs ridisegnati -->
<q-card
flat
bordered
class="tabs-container"
>
<q-tabs
v-model="tab"
dense
inline-label
class="custom-tabs"
active-color="primary"
indicator-color="primary"
align="justify"
>
<q-tab
name="tutti"
label="Tutti"
class="custom-tab"
/>
<q-tab
name="inviati"
:label="t('circuit.inviati') + ' (' + getInviati.length + ')'"
class="custom-tab"
/>
<q-tab
name="ricevuti"
:label="t('circuit.ricevuti') + ' (' + getRicevuti.length + ')'"
class="custom-tab"
/>
</q-tabs>
</q-card>
<!-- Tab panels con animazioni fluide -->
<q-tab-panels
v-model="tab"
animated
keep-alive
transition-prev="slide-right"
transition-next="slide-left"
class="q-mt-md transparent-panels"
>
<q-tab-panel
name="tutti"
class="q-pa-none"
>
<div
v-if="mylist.length === 0"
class="empty-state q-pa-xl text-center"
>
</c-single-movement>
<q-icon
name="inbox"
size="64px"
color="grey-5"
class="q-mb-md"
/>
<div class="text-h6 text-grey-7">
{{ t('circuit.nessun_movimento_inviato') }}
</div>
</div>
<transition-group
name="list"
tag="div"
class="movements-list"
>
<c-single-movement
v-for="(mov, index) in mylist"
:key="'tutti-' + index"
:index="index"
:mov="mov"
:visu="0"
class="movement-item"
/>
</transition-group>
</q-tab-panel>
<q-tab-panel name="inviati">
<div v-if="getInviati.length === 0">
{{ t('circuit.nessun_movimento_inviato') }}
</div>
<c-single-movement
v-for="(mov2, index2) in getInviati"
:key="index2"
:index="index2"
:mov="mov2"
:visu="1"
<q-tab-panel
name="inviati"
class="q-pa-none"
>
<div
v-if="getInviati.length === 0"
class="empty-state q-pa-xl text-center"
>
</c-single-movement>
<q-icon
name="send"
size="64px"
color="grey-5"
class="q-mb-md"
/>
<div class="text-h6 text-grey-7">
{{ t('circuit.nessun_movimento_inviato') }}
</div>
</div>
<transition-group
name="list"
tag="div"
class="movements-list"
>
<c-single-movement
v-for="(mov2, index2) in getInviati"
:key="'inviati-' + index2"
:index="index2"
:mov="mov2"
:visu="1"
class="movement-item"
/>
</transition-group>
</q-tab-panel>
<q-tab-panel name="ricevuti">
<div v-if="getRicevuti.length === 0">
{{ t('circuit.nessun_movimento_ricevuto') }}
</div>
<c-single-movement
v-for="(mov3, index3) in getRicevuti"
:key="index3"
:index="index3"
:mov="mov3"
:visu="2"
<q-tab-panel
name="ricevuti"
class="q-pa-none"
>
<div
v-if="getRicevuti.length === 0"
class="empty-state q-pa-xl text-center"
>
</c-single-movement>
<q-icon
name="download"
size="64px"
color="grey-5"
class="q-mb-md"
/>
<div class="text-h6 text-grey-7">
{{ t('circuit.nessun_movimento_ricevuto') }}
</div>
</div>
<transition-group
name="list"
tag="div"
class="movements-list"
>
<c-single-movement
v-for="(mov3, index3) in getRicevuti"
:key="'ricevuti-' + index3"
:index="index3"
:mov="mov3"
:visu="2"
class="movement-item"
/>
</transition-group>
</q-tab-panel>
</q-tab-panels>
<slot></slot>
<div style="margin-bottom: 50px"></div>
</div>
<q-list v-else bordered>
<!-- Vista alternativa senza username -->
<q-list
v-else
bordered
class="rounded-borders"
>
<c-single-movement
v-for="(mov, index) in mylist"
:key="index"
:key="'list-' + index"
:index="index"
:mov="mov"
>
</c-single-movement>
/>
</q-list>
<q-inner-loading id="spinner" :showing="loadingvalues">
<q-spinner-tail size="3em" color="primary" />
<!-- Loading spinner -->
<q-inner-loading
id="spinner"
:showing="loadingvalues"
>
<q-spinner-tail
size="50px"
color="primary"
/>
</q-inner-loading>
<div v-if="showbuttolastmov" class="row justify-center">
<!-- Bottone carica altri -->
<div
v-if="showbuttolastmov"
class="row justify-center q-mt-lg q-mb-lg"
>
<q-btn
rounded
dense
class="text-center"
unelevated
size="md"
color="primary"
:label="t('circuit.show_next_mov')"
icon-right="expand_more"
@click="addlastmov()"
class="load-more-btn"
/>
</div>
</template>
<script lang="ts" src="./CMovements.ts">
</script>
<script lang="ts" src="./CMovements.ts"></script>
<style lang="scss" scoped>
@import './CMovements.scss';

View File

@@ -73,7 +73,7 @@ export default defineComponent({
const filtroutente = ref(<any[]>[])
const nummovTodownload = ref(5)
const nummovTodownload = ref(10)
const listcircuitsfind = computed(() => {
// console.log('list modif')
@@ -195,7 +195,7 @@ export default defineComponent({
}
async function addlastmov() {
nummovTodownload.value += 5
nummovTodownload.value += 10
loadingvalues.value = true
await loadCircuits(nummovTodownload.value)

View File

@@ -134,7 +134,7 @@
<div v-else>
<q-list class="width-container">
<span class="q-my-sm" clickable>
<CMyCircuit :mycircuit="mycircuit" :visu="visu" :username="username">
<CMyCircuit :mycircuit="circuit" :visu="visu" :username="username">
</CMyCircuit>
</span>
</q-list>

View File

@@ -133,7 +133,7 @@ export default defineComponent({
watch(
() => myproduct.value,
(newval, oldval) => {
console.log('myproduct', myproduct.value);
// console.log('myproduct', myproduct.value);
// loadProduct(myproduct.value._id)
updateproductmodif(myproduct.value);
}
@@ -162,7 +162,7 @@ export default defineComponent({
}
saveSearch();
console.log('myproduct.value', myproduct.value);
// console.log('myproduct.value', myproduct.value);
}
watch(
@@ -332,7 +332,7 @@ export default defineComponent({
}
function updateproductmodif(element: IProduct) {
console.log('CSEARCHPRODUCT: updateproductmodif');
// console.log('CSEARCHPRODUCT: updateproductmodif');
emit('updateproductmodif', element);
}

View File

@@ -1,46 +1,53 @@
import { computed, defineComponent, onMounted, PropType, ref, watch } from 'vue'
import { computed, defineComponent, onMounted, PropType, ref, watch } from 'vue';
import { ICalcStat, IOperators } from '../../model'
import { useUserStore } from '../../store/UserStore'
import { useRouter } from 'vue-router'
import { useGlobalStore } from '../../store/globalStore'
import { useCircuitStore } from '../../store/CircuitStore'
import { useI18n } from 'vue-i18n'
import { ICalcStat, IOperators } from '../../model';
import { useUserStore } from '../../store/UserStore';
import { useRouter } from 'vue-router';
import { useGlobalStore } from '../../store/globalStore';
import { useCircuitStore } from '../../store/CircuitStore';
import { useI18n } from 'vue-i18n';
import { shared_consts } from '@src/common/shared_vuejs'
import { costanti, IMainCard } from '@store/Modules/costanti'
import { shared_consts } from '@src/common/shared_vuejs';
import { costanti, IMainCard } from '@store/Modules/costanti';
import { CMyUser } from '../CMyUser'
import { CTitleBanner } from '../CTitleBanner'
import { CMyGroup } from '../CMyGroup'
import { CCopyBtnSmall } from '../CCopyBtnSmall'
import { CContactUser } from '../CContactUser'
import { CQRCode } from '../CQRCode'
import { CFindUsers } from '../CFindUsers'
import { CUserInfoAccount } from '../CUserInfoAccount'
import { tools } from '@tools'
import { useQuasar } from 'quasar'
import { CMyUser } from '../CMyUser';
import { CTitleBanner } from '../CTitleBanner';
import { CMyGroup } from '../CMyGroup';
import { CCopyBtnSmall } from '../CCopyBtnSmall';
import { CContactUser } from '../CContactUser';
import { CQRCode } from '../CQRCode';
import { CFindUsers } from '../CFindUsers';
import { CUserInfoAccount } from '../CUserInfoAccount';
import { tools } from '@tools';
import { useQuasar } from 'quasar';
export default defineComponent({
name: 'CSendRISTo',
props: {},
components: {
CMyUser, CMyGroup, CUserInfoAccount, CCopyBtnSmall,
CTitleBanner, CContactUser, CFindUsers, CQRCode
CMyUser,
CMyGroup,
CUserInfoAccount,
CCopyBtnSmall,
CTitleBanner,
CContactUser,
CFindUsers,
CQRCode,
},
setup(props) {
const userStore = useUserStore();
const globalStore = useGlobalStore();
const circuitStore = useCircuitStore();
const { t } = useI18n();
const $q = useQuasar();
const $router = useRouter();
const userStore = useUserStore()
const globalStore = useGlobalStore()
const circuitStore = useCircuitStore()
const { t } = useI18n()
const $q = useQuasar()
const $router = useRouter()
const showSendCoin = ref(false);
const showReceiveCoin = ref(false);
const receiveType = ref('link');
const riscallrec = ref(<string>'');
const showSendCoin = ref(false)
const showReceiveCoin = ref(false)
const receiveType = ref('link')
const riscallrec = ref(<string>'')
const btnInviaRIS = ref(null);
const optionsReceive = ref([
{
@@ -55,31 +62,39 @@ export default defineComponent({
label: 'Genera il QR Code',
value: 'qrcode',
},
])
]);
const tipoConto = ref(shared_consts.AccountType.USER)
const loading = ref(false)
const miolink = ref('')
const sendRIS = ref('')
const qtyRIS = ref('')
const causal = ref('')
const tipoConto = ref(shared_consts.AccountType.USER);
const loading = ref(false);
const miolink = ref('');
const sendRIS = ref('');
const qtyRIS = ref('');
const causal = ref('');
const circuitpath = computed(() => {
const circ = circuitStore.getCircuitByProvinceAndCard(userStore.my.profile.resid_province, userStore.my.profile.resid_card)
return circ && circ.path ? circ.path : ''
})
const circ = circuitStore.getCircuitByProvinceAndCard(
userStore.my.profile.resid_province,
userStore.my.profile.resid_card
);
return circ && circ.path ? circ.path : '';
});
watch(() => qtyRIS.value, (to: any, from: any) => {
limitQuantity()
miolink.value = userStore.getLinkProfileAndRIS('', qtyRIS.value, causal.value)
})
watch(() => causal.value, (to: any, from: any) => {
miolink.value = userStore.getLinkProfileAndRIS('', qtyRIS.value, causal.value)
})
watch(
() => qtyRIS.value,
(to: any, from: any) => {
limitQuantity();
miolink.value = userStore.getLinkProfileAndRIS('', qtyRIS.value, causal.value);
}
);
watch(
() => causal.value,
(to: any, from: any) => {
miolink.value = userStore.getLinkProfileAndRIS('', qtyRIS.value, causal.value);
}
);
const showonreclist = ref(false)
const showonreclist = ref(false);
const contact = computed(() => userStore.my)
const contact = computed(() => userStore.my);
const arrTypesAccounts = ref(<any>[
{
@@ -89,11 +104,11 @@ export default defineComponent({
{
label: t('circuit.conticollettivi'),
value: shared_consts.AccountType.CONTO_DI_GRUPPO,
}
])
},
]);
function mounted() {
miolink.value = userStore.getLinkProfileAndRIS('', qtyRIS.value)
miolink.value = userStore.getLinkProfileAndRIS('', qtyRIS.value);
}
function limitQuantity() {
@@ -102,35 +117,42 @@ export default defineComponent({
qtyRIS.value = qtyRIS.value.substring(0, 5); // Limita a 5 caratteri
}
qtyRIS.value = qtyRIS.value.replace(',', '.')
qtyRIS.value = qtyRIS.value.replace(',', '.');
}
function clickInviaRIS() {
showSendCoin.value = !showSendCoin.value
if (showSendCoin.value)
showReceiveCoin.value = !showSendCoin.value
}
async function clickriceviRIS() {
showReceiveCoin.value = !showReceiveCoin.value;
if (showReceiveCoin.value)
showSendCoin.value = !showReceiveCoin.value
if (showReceiveCoin.value)
clickAddtoRecList();
}
async function clickAddtoRecList() {
const risultato = await tools.addToTemporaryReceiverRIS(t)
if (risultato) {
riscallrec.value = risultato.msg
showonreclist.value = risultato.ris
function scrollaBottone() {
const btnInviaRIS = document.getElementById('btnInviaRIS');
if (btnInviaRIS) {
const offset = 30; // spazio desiderato in pixel sopra il bottone
const y = btnInviaRIS.getBoundingClientRect().top + window.scrollY - offset;
window.scrollTo({ top: y, behavior: 'smooth' });
}
}
function clickInviaRIS() {
scrollaBottone();
onMounted(mounted)
showSendCoin.value = !showSendCoin.value;
if (showSendCoin.value) showReceiveCoin.value = !showSendCoin.value;
}
async function clickriceviRIS() {
scrollaBottone();
showReceiveCoin.value = !showReceiveCoin.value;
if (showReceiveCoin.value) showSendCoin.value = !showReceiveCoin.value;
if (showReceiveCoin.value) clickAddtoRecList();
}
async function clickAddtoRecList() {
const risultato = await tools.addToTemporaryReceiverRIS(t);
if (risultato) {
riscallrec.value = risultato.msg;
showonreclist.value = risultato.ris;
}
}
onMounted(mounted);
return {
userStore,
@@ -157,6 +179,7 @@ export default defineComponent({
clickAddtoRecList,
clickInviaRIS,
clickriceviRIS,
}
btnInviaRIS,
};
},
})
});

View File

@@ -5,6 +5,7 @@
>
<div class="q-mb-sm">
<q-btn
id="btnInviaRIS"
icon="fas fa-upload"
color="positive"
size="md"

View File

@@ -1,76 +1,330 @@
.userfrom {
color: red;
// Card principale
.movement-card {
margin-bottom: 12px;
border-radius: 16px;
border: 1px solid rgba(0, 0, 0, 0.08);
background: #ffffff;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
overflow: hidden;
position: relative;
&::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 4px;
background: linear-gradient(180deg, #1e88e5 0%, #1565c0 100%);
transform: scaleY(0);
transition: transform 0.3s ease;
}
&:hover {
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
border-color: rgba(30, 136, 229, 0.3);
&::before {
transform: scaleY(1);
}
}
&--even {
background: linear-gradient(135deg, #ffffff 0%, #fafafa 100%);
}
}
.userto {
color: green;
// Container avatar
.avatar-container {
flex-shrink: 0;
transition: transform 0.2s ease;
&:hover {
transform: scale(1.05);
}
}
.circuit {
color: blue;
.avatar-with-value {
flex-shrink: 0;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
transition: transform 0.2s ease;
&:hover {
transform: scale(1.05);
}
}
.date {
color: gray;
// Badge importo
.amount-badge {
padding: 4px 12px;
border-radius: 20px;
font-weight: 600;
font-size: 0.875rem;
white-space: nowrap;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
&--sent {
background: linear-gradient(135deg, #ffebee 0%, #ffcdd2 100%);
color: #c62828;
}
&--received {
background: linear-gradient(135deg, #e8f5e9 0%, #c8e6c9 100%);
color: #2e7d32;
}
}
.rigamov {
background-color: lightgray;
// Contenuto movimento
.movement-content {
min-width: 0;
flex: 1;
}
.causaleDest {
// Causale destinazione
.causale-dest {
display: flex;
align-items: center;
font-style: italic;
color: #5e35b1;
font-weight: 500;
font-size: 0.9rem;
padding: 6px 12px;
background: linear-gradient(135deg, #ede7f6 0%, #f3e5f5 100%);
border-radius: 8px;
border-left: 3px solid #5e35b1;
}
// Info transazione
.transaction-info {
display: flex;
align-items: baseline;
flex-wrap: wrap;
gap: 6px;
font-size: 0.95rem;
line-height: 1.5;
}
.label-text {
color: #757575;
font-weight: 400;
font-size: 0.875rem;
}
.user-name {
font-weight: 600;
word-wrap: break-word;
word-break: break-word;
transition: color 0.2s ease;
&--from {
color: #e53935;
&:hover {
color: #c62828;
}
}
&--to {
color: #43a047;
&:hover {
color: #2e7d32;
}
}
}
// Badge circuito
.circuit-badge {
display: inline-flex;
align-items: center;
padding: 4px 12px;
background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
color: #1565c0;
border-radius: 16px;
font-size: 0.875rem;
font-weight: 500;
border: 1px solid #90caf9;
transition: all 0.2s ease;
&:hover {
background: linear-gradient(135deg, #bbdefb 0%, #90caf9 100%);
}
}
// Box causale
.causale-box {
position: relative;
padding: 10px 12px 10px 36px;
background: linear-gradient(135deg, #fff8e1 0%, #ffecb3 100%);
border-left: 3px solid #ffa726;
border-radius: 8px;
font-style: italic;
color: #e65100;
font-size: 0.9rem;
line-height: 1.5;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.causale-icon {
position: absolute;
left: 10px;
top: 12px;
color: #ff9800;
}
.causale-text {
font-weight: 500;
}
// Data transazione
.transaction-date {
display: flex;
align-items: center;
color: #9e9e9e;
font-size: 0.8rem;
font-weight: 400;
}
// Responsive design
@media (max-width: 768px) {
.movement-card {
margin-bottom: 10px;
border-radius: 12px;
:deep(.q-card-section) {
padding: 12px !important;
}
}
.movement-content {
padding: 0 8px !important;
}
.avatar-with-value {
gap: 6px;
}
.amount-badge {
padding: 3px 10px;
font-size: 0.8rem;
}
.causale-dest {
font-size: 0.85rem;
padding: 5px 10px;
}
.transaction-info {
font-size: 0.875rem;
}
.label-text {
font-size: 0.8rem;
}
.circuit-badge {
font-size: 0.8rem;
padding: 3px 10px;
}
.causale-box {
padding: 8px 10px 8px 32px;
font-size: 0.85rem;
}
.causale-icon {
left: 8px;
top: 10px;
}
.transaction-date {
font-size: 0.75rem;
}
}
@media (max-width: 480px) {
.movement-card {
border-radius: 10px;
:deep(.q-card-section) {
padding: 10px !important;
flex-wrap: wrap;
}
}
.avatar-container,
.avatar-with-value {
margin-bottom: 8px;
font-style: italic;
}
:root {
--causale-text-color: #555;
--causale-bg-color: #f9f9f9;
}
.movement-content {
padding: 0 !important;
width: 100%;
}
.amount-badge {
font-size: 0.75rem;
padding: 2px 8px;
}
.transaction-info {
font-size: 0.85rem;
}
}
// Dark mode support
body.body--dark {
--causale-text-color: #bbb;
--causale-bg-color: #333;
.movement-card {
background: #1e1e1e;
border-color: rgba(255, 255, 255, 0.12);
&--even {
background: linear-gradient(135deg, #1e1e1e 0%, #2a2a2a 100%);
}
&:hover {
border-color: rgba(30, 136, 229, 0.5);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
}
}
.causale-dest {
background: linear-gradient(135deg, #311b92 0%, #4a148c 100%);
color: #b39ddb;
border-left-color: #7c4dff;
}
.label-text {
color: #bdbdbd;
}
.circuit-badge {
background: linear-gradient(135deg, #0d47a1 0%, #1565c0 100%);
color: #90caf9;
border-color: #1976d2;
}
.causale-box {
background: linear-gradient(135deg, #4e342e 0%, #5d4037 100%);
color: #ffb74d;
border-left-color: #ff9800;
}
.causale-icon {
color: #ffa726;
}
.transaction-date {
color: #757575;
}
}
.causale {
position: relative;
/* Necessario per il posizionamento corretto del pseudo-elemento */
font-style: italic;
color: #555;
padding-left: 0px;
margin: 8px 0;
color: var(--causale-text-color);
background-color: var(--causale-bg-color);
}
.userto,
.userfrom {
white-space: pre-wrap;
/* Impedisce il wrapping del testo */
}
.q-item-section.d-flex {
display: flex;
align-items: center;
/* Allinea gli elementi al centro verticalmente */
}
.q-item__section--main~.q-item__section--side {
padding-left: 2px !important;
}
.q-item__section--side {
padding-right: 4px !important;
}
.schede-mov {
margin-top: 2px;
margin-bottom: 2px;
padding-top: 2px;
padding-bottom: 2px;
border: solid 1px blue;
border-radius: 20px;
// Utility
.cursor-pointer {
cursor: pointer;
}

View File

@@ -17,7 +17,7 @@ export default defineComponent({
components: { CMyImgUser, CCurrencyValue },
props: {
mov: {
type: Object as PropType<IMovement>,
type: Object as PropType<IMovVisu>,
required: true,
},
index: {
@@ -47,7 +47,7 @@ export default defineComponent({
return mystr
}
function navigabyMov(mov: IMovQuery, from: boolean) {
function navigabyMov(mov: IMovVisu, from: boolean) {
let link = ''
if (from) {
if (mov.tipocontofrom === shared_consts.AccountType.USER) {

View File

@@ -1,74 +1,114 @@
<template>
<q-item
<q-card
v-if="mov"
:class="[
'm-mb-sm',
'schede-mov',
{
'background-even': index % 2 === 0,
'background-odd': index % 2 !== 0,
},
]"
flat
bordered
class="movement-card"
:class="{ 'movement-card--even': index % 2 === 0 }"
>
<q-item-section v-if="visu !== 1" avatar @click="navigabyMov(mov, true)">
<CMyImgUser :mov="mov" :from="true"> </CMyImgUser>
</q-item-section>
<q-item-section v-else side @click="navigabyMov(mov, false)">
<CMyImgUser :mov="mov" :from="false"> </CMyImgUser>
<CCurrencyValue
:symbol="mov.circuitfrom.symbol"
color="red"
v-model="mov.amount"
:small="true"
label=""
>
</CCurrencyValue>
</q-item-section>
<q-card-section class="row items-center q-pa-sm no-wrap">
<q-item-section>
<q-item-label class="causalDest" v-if="mov.causalDest">{{
mov.causalDest
}}</q-item-label>
<q-item-label v-if="visu !== 1" lines="3">
{{ t('movement.from') }}
<span class="userfrom">{{
tools.getUsernameOrGroupOrContoComByMov(mov, true)
}}</span>
</q-item-label>
<q-item-label v-if="visu !== 2" lines="3">
{{ t('movement.to') }}
<span class="userto">{{
tools.getUsernameOrGroupOrContoComByMov(mov, false)
}}</span></q-item-label
<!-- Avatar FROM (mostrato in 'tutti' e 'ricevuti') -->
<div
v-if="visu !== 1"
class="avatar-with-value cursor-pointer"
@click="navigabyMov(mov, true)"
>
<q-item-label caption lines="1" v-if="mov.circuitfrom" class="circuit">{{
mov.circuitfrom.name
}}</q-item-label>
<q-item-label class="causale" v-if="mov.causal">
<q-icon name="fas fa-star" color="orange"></q-icon>
&quot;{{ mov.causal }}&quot;</q-item-label
>
<q-item-label caption lines="1" v-if="mov.transactionDate" class="date text-right">{{
tools.getstrDateTime(mov.transactionDate)
}}</q-item-label>
</q-item-section>
<CMyImgUser :mov="mov" :from="true" />
<div v-if="visu === 2" class="amount-badge amount-badge--received">
<CCurrencyValue
:symbol="mov.circuitto?.symbol || mov.circuitfrom?.symbol"
:color="tools.getColorByCircuit(mov.circuitto || mov.circuitfrom)"
v-model="mov.amount"
:small="true"
label=""
/>
</div>
</div>
<q-item-section v-if="visu === 0" side @click="navigabyMov(mov, false)">
<CMyImgUser :mov="mov" :from="false"> </CMyImgUser>
<CCurrencyValue
:symbol="mov.circuitfrom.symbol"
color="red"
v-model="mov.amount"
:small="true"
label=""
<!-- Avatar TO (mostrato in 'inviati') -->
<div
v-if="visu === 1"
class="avatar-with-value cursor-pointer"
@click="navigabyMov(mov, false)"
>
</CCurrencyValue>
</q-item-section>
</q-item>
<CMyImgUser :mov="mov" :from="false" />
<div class="amount-badge amount-badge--sent">
<CCurrencyValue
:symbol="mov.circuitfrom?.symbol"
:color="tools.getColorByCircuit(mov.circuitfrom)"
v-model="mov.amount"
:small="true"
label=""
/>
</div>
</div>
<!-- Contenuto principale -->
<div class="col movement-content q-px-md">
<div v-if="mov.causalDest" class="causale-dest q-mb-xs">
<q-icon name="flag" size="16px" class="q-mr-xs" />
{{ mov.causalDest }}
</div>
<!-- Da utente -->
<div v-if="visu !== 1" class="transaction-info q-mb-xs">
<span class="label-text">{{ t('movement.from') }}</span>
<span class="user-name user-name--from">
{{ tools.getUsernameOrGroupOrContoComByMov(mov, true) }}
</span>
</div>
<!-- A utente -->
<div v-if="visu !== 2" class="transaction-info q-mb-xs">
<span class="label-text">{{ t('movement.to') }}</span>
<span class="user-name user-name--to">
{{ tools.getUsernameOrGroupOrContoComByMov(mov, false) }}
</span>
</div>
<!-- Circuito -->
<div v-if="mov.circuitfrom" class="circuit-badge q-mb-xs">
<q-icon name="account_balance" size="14px" class="q-mr-xs" />
{{ mov.circuitfrom.name }}
</div>
<!-- Causale -->
<div v-if="mov.causal" class="causale-box q-mt-sm">
<q-icon name="format_quote" size="16px" class="causale-icon" />
<span class="causale-text">{{ mov.causal }}</span>
</div>
<!-- Data -->
<div v-if="mov.transactionDate" class="transaction-date q-mt-xs">
<q-icon name="schedule" size="14px" class="q-mr-xs" />
{{ tools.getstrDateTime(mov.transactionDate) }}
</div>
</div>
<!-- Avatar TO + valore (solo per 'tutti') -->
<div
v-if="visu === 0"
class="avatar-with-value cursor-pointer"
@click="navigabyMov(mov, false)"
>
<CMyImgUser :mov="mov" :from="false" />
<div class="amount-badge amount-badge--received">
<CCurrencyValue
:symbol="mov.circuitto?.symbol || mov.circuitfrom?.symbol"
:color="tools.getColorByCircuit(mov.circuitto)"
v-model="mov.amount"
:small="true"
label=""
/>
</div>
</div>
</q-card-section>
</q-card>
</template>
<script lang="ts" src="./CSingleMovement.ts">
</script>
<script lang="ts" src="./CSingleMovement.ts"></script>
<style lang="scss" scoped>
@import './CSingleMovement.scss';

View File

@@ -31,7 +31,7 @@ export default defineComponent({
const isLogged = computed(() => userStore.isLogged)
const isEmailVerified = computed(() => userStore.my.verified_email)
const telegVerificato = computed(() => userStore.my.profile.teleg_id > 0 && userStore.my.profile.teleg_id_old > 0)
const telegVerificato = computed(() => tools.TelegVerificato())
function load() {
///

View File

@@ -3,6 +3,7 @@
v-if="!globalStore.serverError"
class="q-ma-sm"
>
<div
v-if="
isLogged &&

View File

@@ -1561,6 +1561,7 @@ export interface IMovement {
accountToId: string
amount: number
causal: string
causalDest: string
residual: number
expiringDate: Date
}
@@ -1575,6 +1576,7 @@ export interface IMovVisu {
circuitto: ICircuit
amount: number
causal: string
causalDest: string
residual: number
expiringDate: Date
}

View File

@@ -189,6 +189,7 @@ export interface IUserProfile {
manage_mycircuits: ICircuit[]
useraccounts: IAccount[]
last_my_transactions: IMovement[]
total_transactions?: number
calc: ICalc
}

View File

@@ -1478,11 +1478,12 @@ const msg_it = {
add_circuit: 'Entra nel Circuito',
select_circuit: 'Scegli il Circuito cui abilitare il conto RIS',
select_circuit_hint: '',
show_next_mov: 'Vedi altri ...',
show_next_mov: 'Mostra precedenti ...',
nessun_movimento_ricevuto: 'Nessun movimento ricevuto. Proponi uno scambio in RIS e conosci altre persone!',
nessun_movimento_inviato: 'Nessun movimento Inviato. Sperimenta l\'utilizzo dei RIS proponendoti in qualcosa!',
nessun_circuito_attivo: 'Attualmente non sei ancora in nessun Circuito Territoriale:',
tuoi_ultimi_movimenti: 'I tuoi ultimi movimenti ({num})',
totale_movimenti_effettuati: 'Totale movimenti effettuati',
circuiti_territoriali: 'Circuiti Territoriali',
find_others_circuit: 'Vedi tutti i Circuiti Territoriali',
hide_others_circuit: 'Nascondi tutti i Circuiti Territoriali',

View File

@@ -8643,6 +8643,8 @@ export const tools = {
userStore.my.profile.last_my_transactions = ris.last_my_transactions
? ris.last_my_transactions
: [];
userStore.my.profile.total_transactions = ris.total_transactions
return [{ userId: userStore.my._id }];
}
});

View File

@@ -123,6 +123,7 @@ export const DefaultUser: IUserFields = {
calc: { numGoodsAndServices: 0 },
resid_province: '',
resid_card: '',
total_transactions: 0,
},
cart: {
userId: '',
@@ -197,6 +198,7 @@ export const DefaultProfile: IUserProfile = {
calc: { numGoodsAndServices: 0 },
resid_province: '',
resid_card: '',
total_transactions: 0,
};
export const useUserStore = defineStore('UserStore', {

View File

@@ -1383,7 +1383,7 @@ export const useGlobalStore = defineStore('GlobalStore', {
},
loadPickup(params: IParamsPickup) {
console.log('loadPickup', params);
// console.log('loadPickup', params);
const userStore = useUserStore();
return Api.SendReq('/pickup', 'POST', params)