- Corretto campo "Comune di Residenza".

- Aggiornato Completamento Profilo: Comune di Residenza.
- Registrazione
This commit is contained in:
Surya Paolo
2025-11-26 18:32:05 +01:00
parent b37204f543
commit 145327a6ca
53 changed files with 4122 additions and 1203 deletions

View File

@@ -220,6 +220,8 @@ export default defineComponent({
'profile.qualifica': 1,
'profile.note': 1,
'profile.da_contattare': 1,
'profile.resid_str_comune': 1,
'profile.resid_comune': 1,
'profile.resid_province': 1,
'mycities.reg': 1,
perm: 1,

View File

@@ -1,5 +1,5 @@
// ========================================
// VARIABILI MODERNE (compatibili con Quasar)
// VARIABILI MODERNE CON GRADIENTI
// ========================================
$primary-color: #1976d2;
$primary-light: #42a5f5;
@@ -27,13 +27,26 @@ $mobile-breakpoint: 768px;
$small-breakpoint: 600px;
// ========================================
// PROFILE (già esistente - solo ottimizzato)
// GRADIENTI MODERNI
// ========================================
$gradient-primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
$gradient-secondary: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
$gradient-info: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
$gradient-positive: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
$gradient-card-light: linear-gradient(135deg, #fdfbfb 0%, #ebedee 100%);
$gradient-card-white: linear-gradient(to bottom, #ffffff 0%, #f8f9fa 100%);
$gradient-hover: linear-gradient(135deg, rgba(102, 126, 234, 0.05) 0%, rgba(118, 75, 162, 0.05) 100%);
// ========================================
// PROFILE (con gradiente)
// ========================================
.profile {
width: 100%;
margin: 0 auto;
max-width: 450px;
padding: 6px;
background: $gradient-card-white;
border-radius: $border-radius-sm;
@media (max-width: $mobile-breakpoint) {
padding: 4px;
@@ -41,7 +54,7 @@ $small-breakpoint: 600px;
}
// ========================================
// MY ROW (già esistente - ottimizzato)
// MY ROW
// ========================================
.myrow {
display: flex;
@@ -54,20 +67,38 @@ $small-breakpoint: 600px;
}
// ========================================
// QUALIFICA (già esistente - modernizzato)
// QUALIFICA (con gradiente)
// ========================================
.qualifica {
border: 2px solid $primary-light;
background: linear-gradient(135deg, rgba(38, 166, 154, 0.1) 0%, rgba(38, 166, 154, 0.05) 100%);
border: 2px solid rgba(38, 166, 154, 0.3);
border-radius: $border-radius-sm;
padding: 6px 10px;
background: rgba(65, 152, 239, 0.05);
transition: all $transition-speed ease;
font-weight: 500;
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
transition: left 0.5s ease;
}
&:hover {
background: rgba(65, 152, 239, 0.1);
border-color: $primary-color;
transform: translateX(2px);
background: linear-gradient(135deg, rgba(38, 166, 154, 0.15) 0%, rgba(38, 166, 154, 0.08) 100%);
border-color: $secondary-color;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(38, 166, 154, 0.2);
&::before {
left: 100%;
}
}
@media (max-width: $mobile-breakpoint) {
@@ -76,15 +107,33 @@ $small-breakpoint: 600px;
}
// ========================================
// TEXT BACHECA (già esistente - modernizzato)
// TEXT BACHECA (con gradiente)
// ========================================
.text-bacheca {
margin: 8px 0;
border: 2px solid $primary-light;
background: linear-gradient(135deg, rgba(79, 172, 254, 0.08) 0%, rgba(0, 242, 254, 0.08) 100%);
border: 2px solid rgba(79, 172, 254, 0.3);
border-radius: $border-radius-sm;
padding: 10px 12px;
background: rgba(65, 152, 239, 0.03);
line-height: 1.6;
position: relative;
overflow: hidden;
&::after {
content: '';
position: absolute;
top: -50%;
right: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%);
opacity: 0;
transition: opacity 0.3s ease;
}
&:hover::after {
opacity: 1;
}
@media (max-width: $mobile-breakpoint) {
margin: 6px 0;
@@ -93,16 +142,17 @@ $small-breakpoint: 600px;
}
// ========================================
// NOTE BACHECA (già esistente - modernizzato)
// NOTE BACHECA (con gradiente warning)
// ========================================
.note-bacheca {
border: 2px solid $warning-color;
background: linear-gradient(135deg, rgba(242, 192, 55, 0.12) 0%, rgba(242, 192, 55, 0.06) 100%);
border: 2px solid rgba(242, 192, 55, 0.4);
border-left: 4px solid $warning-color;
border-radius: $border-radius-sm;
padding: 10px 12px;
background: rgba(242, 192, 55, 0.08);
border-left: 4px solid $warning-color;
line-height: 1.6;
margin: 8px 0;
box-shadow: 0 2px 8px rgba(242, 192, 55, 0.15);
@media (max-width: $mobile-breakpoint) {
padding: 8px 10px;
@@ -111,7 +161,7 @@ $small-breakpoint: 600px;
}
// ========================================
// IMG (già esistente - ottimizzato)
// IMG
// ========================================
.img {
margin: 0 auto;
@@ -128,7 +178,7 @@ $small-breakpoint: 600px;
}
// ========================================
// CALENDAR STYLES (già esistente - compatto)
// CALENDAR STYLES
// ========================================
.cal {
color: #1a1a1a;
@@ -210,13 +260,15 @@ $small-breakpoint: 600px;
}
// ========================================
// BADGE FAV/BOOK (già esistente - ottimizzato)
// BADGE FAV/BOOK (con gradiente)
// ========================================
.badge-favbook {
font-weight: 600;
padding: 3px 8px;
border-radius: 6px;
font-size: 0.8125rem;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0.7) 100%);
backdrop-filter: blur(4px);
@media (max-width: $mobile-breakpoint) {
padding: 2px 6px;
@@ -225,7 +277,7 @@ $small-breakpoint: 600px;
}
// ========================================
// BUTTONS FAV (già esistente - compatto)
// BUTTONS FAV
// ========================================
.buttonsfav {
display: flex;
@@ -251,7 +303,7 @@ $small-breakpoint: 600px;
}
// ========================================
// CONTAINER BUTTON (già esistente - ottimizzato)
// CONTAINER BUTTON
// ========================================
.container_butt {
display: flex;
@@ -267,7 +319,7 @@ $small-breakpoint: 600px;
}
// ========================================
// ANIMATIONS (già esistente)
// ANIMATIONS
// ========================================
.expand-fade-enter-active,
.expand-fade-leave-active {
@@ -286,7 +338,7 @@ $small-breakpoint: 600px;
}
// ========================================
// DIALOG POSITIONING (già esistente - ottimizzato)
// DIALOG POSITIONING
// ========================================
.well-positioned-dialog {
width: 50vw;
@@ -312,37 +364,75 @@ $small-breakpoint: 600px;
}
// ========================================
// MODERN CARD (nuovo - sostituisce my-card)
// MODERN CARD (con gradienti bellissimi!)
// ========================================
.modern-card {
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 50%, #ffffff 100%);
border: 1px solid rgba(0, 0, 0, 0.06);
border-radius: $border-radius;
box-shadow: $shadow-md;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
margin: 8px 0;
transition: all $transition-speed ease;
position: relative;
overflow: hidden;
// Effetto luce che scorre
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
transition: left 0.6s ease;
}
@media (max-width: $mobile-breakpoint) {
margin: 6px 0;
}
&:hover {
box-shadow: $shadow-lg;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
transform: translateY(-4px);
background: linear-gradient(135deg, #ffffff 0%, #f0f4f8 50%, #ffffff 100%);
border-color: rgba(25, 118, 210, 0.2);
&::before {
left: 100%;
}
}
// Variante con bordo colorato a sinistra - User
&.clBorderUser {
border-left: 4px solid $primary-color;
background: linear-gradient(to right, rgba(25, 118, 210, 0.03), #ffffff 10%, #f8f9fa 50%, #ffffff 100%);
&:hover {
background: linear-gradient(to right, rgba(25, 118, 210, 0.06), #ffffff 10%, #f0f4f8 50%, #ffffff 100%);
box-shadow: 0 8px 24px rgba(25, 118, 210, 0.15);
}
}
// Variante con bordo colorato a sinistra - Service
&.clBorderService {
border-left: 4px solid $secondary-color;
background: linear-gradient(to right, rgba(38, 166, 154, 0.03), #ffffff 10%, #f8f9fa 50%, #ffffff 100%);
&:hover {
background: linear-gradient(to right, rgba(38, 166, 154, 0.06), #ffffff 10%, #f0f4f8 50%, #ffffff 100%);
box-shadow: 0 8px 24px rgba(38, 166, 154, 0.15);
}
}
}
// ========================================
// MODERN DIALOG (nuovo - sostituisce visudialog)
// MODERN DIALOG (con gradiente)
// ========================================
.modern-dialog {
max-height: 80vh;
overflow-y: auto;
background: linear-gradient(to bottom, #ffffff 0%, #f8f9fa 100%);
@media (max-width: $mobile-breakpoint) {
max-height: 90vh;
@@ -351,6 +441,7 @@ $small-breakpoint: 600px;
&.no-padding {
:deep(.q-card-section) {
padding: 12px;
background: transparent;
@media (max-width: $mobile-breakpoint) {
padding: 10px;
@@ -358,32 +449,35 @@ $small-breakpoint: 600px;
}
}
// Scrollbar styling
// Scrollbar styling con gradiente
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
background: linear-gradient(to bottom, #f1f1f1, #e0e0e0);
border-radius: 10px;
}
&::-webkit-scrollbar-thumb {
background: $primary-light;
background: linear-gradient(135deg, $primary-light, $primary-color);
border-radius: 10px;
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.1);
&:hover {
background: $primary-color;
background: linear-gradient(135deg, $primary-color, $primary-dark);
}
}
}
// ========================================
// TOOLBAR (già esistente - compatto)
// TOOLBAR (con gradiente)
// ========================================
.q-toolbar {
min-height: 48px;
padding: 8px 12px;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95), rgba(248, 249, 250, 0.95));
backdrop-filter: blur(10px);
@media (max-width: $mobile-breakpoint) {
min-height: 44px;
@@ -398,14 +492,28 @@ $small-breakpoint: 600px;
font-size: 1rem;
}
}
&.bg-primary {
background: $gradient-primary !important;
}
&.bg-white {
background: linear-gradient(135deg, #ffffff, #f8f9fa) !important;
}
}
// ========================================
// MENU STYLES (già esistente - modernizzato)
// MENU STYLES (con gradienti)
// ========================================
.q-menu {
background: linear-gradient(to bottom, #ffffff, #f8f9fa);
backdrop-filter: blur(10px);
border: 1px solid rgba(0, 0, 0, 0.08);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
.q-list {
padding: 6px;
background: transparent;
@media (max-width: $mobile-breakpoint) {
padding: 4px;
@@ -417,10 +525,12 @@ $small-breakpoint: 600px;
min-height: 40px;
border-radius: $border-radius-sm;
transition: all $transition-speed ease;
background: transparent;
&:hover {
background: rgba(25, 118, 210, 0.08);
transform: translateX(2px);
background: linear-gradient(135deg, rgba(25, 118, 210, 0.08), rgba(25, 118, 210, 0.04));
transform: translateX(4px);
box-shadow: 0 2px 8px rgba(25, 118, 210, 0.1);
}
@media (max-width: $mobile-breakpoint) {
@@ -439,7 +549,7 @@ $small-breakpoint: 600px;
}
// ========================================
// ABSOLUTE POSITIONING (già esistente - ottimizzato)
// ABSOLUTE POSITIONING
// ========================================
.absolute-top-right {
position: absolute;
@@ -451,14 +561,27 @@ $small-breakpoint: 600px;
top: 8px;
right: 8px;
}
.q-btn {
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(8px);
transition: all $transition-speed ease;
&:hover {
background: rgba(0, 0, 0, 0.7);
transform: scale(1.1) rotate(90deg);
}
}
}
// ========================================
// INSET SHADOW (già esistente - ottimizzato)
// INSET SHADOW (con gradiente)
// ========================================
.inset-shadow {
background: linear-gradient(to bottom, #fafafa, #f5f5f5);
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.06);
padding: 10px;
border-radius: $border-radius-sm;
@media (max-width: $mobile-breakpoint) {
padding: 8px;
@@ -466,12 +589,14 @@ $small-breakpoint: 600px;
}
// ========================================
// DIALOG CARD (già esistente - ottimizzato)
// DIALOG CARD (con gradiente)
// ========================================
.dialog_card {
max-width: 500px;
width: 100%;
border-radius: $border-radius;
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
@media (max-width: $mobile-breakpoint) {
max-width: 100%;
@@ -480,10 +605,22 @@ $small-breakpoint: 600px;
}
// ========================================
// CLASSI ESISTENTI MANTENUTE
// CLASSI ESISTENTI CON GRADIENTI
// ========================================
.clBorderService {
border: 1px solid rgba($secondary-color, 0.3);
position: relative;
overflow: hidden;
&::after {
content: '';
position: absolute;
left: 0;
top: 0;
width: 4px;
height: 100%;
background: linear-gradient(to bottom, $secondary-color, rgba($secondary-color, 0.9));
}
&:hover {
border-color: $secondary-color;
@@ -492,6 +629,18 @@ $small-breakpoint: 600px;
.clBorderUser {
border: 1px solid rgba($primary-color, 0.3);
position: relative;
overflow: hidden;
&::after {
content: '';
position: absolute;
left: 0;
top: 0;
width: 4px;
height: 100%;
background: linear-gradient(to bottom, $primary-color, color-contrast($primary-color, -10%));
}
&:hover {
border-color: $primary-color;
@@ -501,6 +650,8 @@ $small-breakpoint: 600px;
.clDescrEstesa {
padding: 10px;
line-height: 1.6;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.5), rgba(248, 249, 250, 0.5));
border-radius: $border-radius-sm;
@media (max-width: $mobile-breakpoint) {
padding: 8px;
@@ -509,7 +660,10 @@ $small-breakpoint: 600px;
.accom_maxosp {
font-weight: 600;
color: $primary-color;
background: linear-gradient(135deg, $primary-color, color-lighten($primary-color, 15%));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-right: 4px;
}
@@ -518,6 +672,7 @@ $small-breakpoint: 600px;
// ========================================
.q-item {
padding: 10px 12px;
transition: all $transition-speed ease;
@media (max-width: $mobile-breakpoint) {
padding: 8px 10px;
@@ -530,27 +685,59 @@ $small-breakpoint: 600px;
.q-item__label {
line-height: 1.5;
}
}
// ========================================
// Q-CHIP OTTIMIZZAZIONI
// ========================================
.q-chip {
margin: 2px 4px 2px 0;
&.glossy {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0) 100%);
&:hover {
background: linear-gradient(90deg, rgba(25, 118, 210, 0.03), transparent);
}
}
// ========================================
// Q-BTN OTTIMIZZAZIONI
// Q-CHIP OTTIMIZZAZIONI (con gradienti)
// ========================================
.q-chip {
margin: 2px 4px 2px 0;
transition: all $transition-speed ease;
&.glossy {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.05) 100%);
backdrop-filter: blur(4px);
}
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
}
// ========================================
// Q-BTN OTTIMIZZAZIONI (con effetti)
// ========================================
.q-btn {
transition: all $transition-speed ease;
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.3);
transform: translate(-50%, -50%);
transition: width 0.6s ease, height 0.6s ease;
}
&:hover:not(.q-btn--disable) {
transform: scale(1.02);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
&::before {
width: 300px;
height: 300px;
}
}
&.q-btn--round {
@@ -558,10 +745,21 @@ $small-breakpoint: 600px;
transform: scale(1.1);
}
}
&.q-btn--unelevated {
background: linear-gradient(135deg, currentColor, color-darken($primary-color, 5%));
}
}
// ========================================
// RESPONSIVE UTILITIES (già esistente - ottimizzato)
// Q-CARD SECTION (con gradiente sottile)
// ========================================
.q-card-section {
background: linear-gradient(to bottom, transparent 0%, rgba(0, 0, 0, 0.01) 100%);
}
// ========================================
// RESPONSIVE UTILITIES
// ========================================
@media (max-width: $mobile-breakpoint) {
.q-pa-xs {
@@ -611,8 +809,17 @@ $small-breakpoint: 600px;
}
}
@keyframes shimmer {
0% {
background-position: -1000px 0;
}
100% {
background-position: 1000px 0;
}
}
.modern-card {
animation: fadeIn 0.3s ease-out;
animation: fadeIn 0.4s ease-out;
}
// ========================================
@@ -620,8 +827,27 @@ $small-breakpoint: 600px;
// ========================================
.q-separator {
margin: 8px 0;
background: linear-gradient(to right, transparent, rgba(0, 0, 0, 0.1), transparent);
@media (max-width: $mobile-breakpoint) {
margin: 6px 0;
}
}
// ========================================
// EXTRA: Effetti particolari
// ========================================
// Effetto glassmorphism
.glass-effect {
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
// Card evento "attending"
.is-attending {
border-left: 4px solid $positive-color;
background: linear-gradient(to right, rgba(33, 186, 69, 0.08), transparent 20%);
box-shadow: 0 2px 12px rgba(33, 186, 69, 0.1);
}

View File

@@ -565,6 +565,8 @@ export default defineComponent({
'profile.img': 1,
'profile.mygroups': 1,
'profile.qualifica': 1,
'profile.resid_str_comune': 1,
'profile.resid_comune': 1,
'profile.resid_province': 1,
'profile.resid_card': 1,
'mycities.reg': 1,

View File

@@ -1,6 +1,282 @@
.clchip{
display: flex;
justify-content: left;
//flex: 1;
//flex-direction: column;
// ========================================
// CMyChipList - SCSS Moderno con Gradienti
// ========================================
$primary-color: #1976d2;
$primary-light: #42a5f5;
$secondary-color: #26a69a;
$positive-color: #21ba45;
$negative-color: #c10015;
$info-color: #31ccec;
$warning-color: #f2c037;
@use 'sass:color';
$border-radius-sm: 8px;
$border-radius: 10px;
$transition-speed: 0.3s;
$shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);
$shadow-md: 0 2px 8px rgba(0, 0, 0, 0.1);
$mobile-breakpoint: 768px;
// ========================================
// CONTAINER
// ========================================
.q-mb-sm {
// Padding e margini ottimizzati
@media (max-width: $mobile-breakpoint) {
margin-bottom: 10px !important;
}
}
// ========================================
// LABEL/TITLE (con gradiente sottile)
// ========================================
.text-subtitle2 {
&.text-primary {
background: linear-gradient(135deg, $primary-color, lighten($primary-color, 15%));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-weight: 600;
letter-spacing: 0.02em;
margin-bottom: 8px;
@media (max-width: $mobile-breakpoint) {
font-size: 0.875rem;
margin-bottom: 6px;
}
}
}
// ========================================
// CHIPS CONTAINER
// ========================================
.q-gutter-sm {
&.row.wrap {
gap: 8px;
@media (max-width: $mobile-breakpoint) {
gap: 6px;
}
}
}
// ========================================
// SINGLE CHIP (con gradienti bellissimi!)
// ========================================
.q-chip {
position: relative;
overflow: hidden;
transition: all $transition-speed cubic-bezier(0.4, 0, 0.2, 1);
border-radius: $border-radius !important;
font-weight: 500;
letter-spacing: 0.01em;
// Effetto luce scorrevole
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
transition: left 0.5s ease;
}
// Shadow con gradiente
&.shadow-1 {
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
}
// Padding compatto
&.q-px-sm {
padding-left: 10px !important;
padding-right: 10px !important;
@media (max-width: $mobile-breakpoint) {
padding-left: 8px !important;
padding-right: 8px !important;
font-size: 0.8125rem !important;
}
}
// Hover effect
&:hover {
transform: translateY(-2px) scale(1.02);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
&::before {
left: 100%;
}
}
// Colori con gradienti
&[class*='bg-primary'],
&[class*='bg-blue'] {
background: linear-gradient(135deg, $primary-color, lighten($primary-color, 10%)) !important;
box-shadow: 0 2px 8px rgba($primary-color, 0.3);
&:hover {
background: linear-gradient(135deg, color.adjust($primary-color, $lightness: -5%), $primary-color) !important;
box-shadow: 0 4px 12px rgba($primary-color, 0.4);
}
}
&[class*='bg-secondary'],
&[class*='bg-teal'] {
background: linear-gradient(135deg, $secondary-color, lighten($secondary-color, 10%)) !important;
box-shadow: 0 2px 8px rgba($secondary-color, 0.3);
&:hover {
background: linear-gradient(135deg, color.adjust($secondary-color, $lightness: -5%), $secondary-color) !important;
box-shadow: 0 4px 12px rgba($secondary-color, 0.4);
}
}
&[class*='bg-positive'],
&[class*='bg-green'] {
background: linear-gradient(135deg, $positive-color, lighten($positive-color, 10%)) !important;
box-shadow: 0 2px 8px rgba($positive-color, 0.3);
&:hover {
background: linear-gradient(135deg, color.adjust($positive-color, $lightness: -5%), $positive-color) !important;
box-shadow: 0 4px 12px rgba($positive-color, 0.4);
}
}
&[class*='bg-negative'],
&[class*='bg-red'] {
background: linear-gradient(135deg, $negative-color, color.adjust($negative-color, $lightness: 10%)) !important;
box-shadow: 0 2px 8px rgba($negative-color, 0.3);
&:hover {
background: linear-gradient(135deg, color.adjust($negative-color, $lightness: -5%), $negative-color) !important;
box-shadow: 0 4px 12px rgba($negative-color, 0.4);
}
}
&[class*='bg-warning'],
&[class*='bg-orange'],
&[class*='bg-amber'] {
background: linear-gradient(135deg, $warning-color, lighten($warning-color, 10%)) !important;
box-shadow: 0 2px 8px rgba($warning-color, 0.3);
&:hover {
background: linear-gradient(135deg, color.adjust($warning-color, $lightness: -5%), $warning-color) !important;
box-shadow: 0 4px 12px rgba($warning-color, 0.4);
}
}
&[class*='bg-info'],
&[class*='bg-cyan'] {
background: linear-gradient(135deg, $info-color, color.adjust($info-color, $lightness: 10%)) !important;
box-shadow: 0 2px 8px rgba($info-color, 0.3);
&:hover {
background: linear-gradient(135deg, color.adjust($info-color, $lightness: -5%), $info-color) !important;
box-shadow: 0 4px 12px rgba($info-color, 0.4);
}
}
&[class*='bg-purple'] {
background: linear-gradient(135deg, #9c27b0, lighten(#9c27b0, 10%)) !important;
box-shadow: 0 2px 8px rgba(#9c27b0, 0.3);
&:hover {
background: linear-gradient(135deg, color.adjust(#9c27b0, $lightness: -5%), #9c27b0) !important;
box-shadow: 0 4px 12px rgba(#9c27b0, 0.4);
}
}
&[class*='bg-pink'] {
background: linear-gradient(135deg, #e91e63, lighten(#e91e63, 10%)) !important;
box-shadow: 0 2px 8px rgba(#e91e63, 0.3);
&:hover {
background: linear-gradient(135deg, color.adjust(#e91e63, $lightness: -5%), #e91e63) !important;
box-shadow: 0 4px 12px rgba(#e91e63, 0.4);
}
}
&[class*='bg-grey'],
&[class*='bg-gray'] {
background: linear-gradient(135deg, #757575, lighten(#757575, 10%)) !important;
box-shadow: 0 2px 8px rgba(#757575, 0.3);
&:hover {
background: linear-gradient(135deg, color.adjust(#757575, $lightness: -5%), #757575) !important;
box-shadow: 0 4px 12px rgba(#757575, 0.4);
}
}
// Icon dentro il chip
.q-icon {
transition: transform $transition-speed ease;
}
&:hover .q-icon {
transform: scale(1.1) rotate(5deg);
}
// Text color bianco con ombra sottile per leggibilità
&[class*='text-white'] {
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
}
}
// ========================================
// DENSE VARIANT
// ========================================
.q-chip--dense {
padding: 3px 8px !important;
font-size: 0.8125rem;
@media (max-width: $mobile-breakpoint) {
padding: 2px 6px !important;
font-size: 0.75rem;
}
}
// ========================================
// ANIMATION
// ========================================
@keyframes chipAppear {
from {
opacity: 0;
transform: scale(0.8) translateY(10px);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
}
.q-chip {
animation: chipAppear 0.3s ease-out;
animation-fill-mode: both;
// Stagger animation per chip multipli
@for $i from 1 through 20 {
&:nth-child(#{$i}) {
animation-delay: #{$i * 0.05}s;
}
}
}
// ========================================
// GLASSMORPHISM VARIANT (opzionale)
// ========================================
.q-chip.glass-effect {
background: rgba(255, 255, 255, 0.2) !important;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
&:hover {
background: rgba(255, 255, 255, 0.3) !important;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
}
}

View File

@@ -0,0 +1,283 @@
// ========================================
// MODERN FIELD DB - COMPACT & PROFESSIONAL
// ========================================
// Container principale
.modern-field-container {
display: flex;
align-items: stretch;
gap: 12px;
padding: 8px 12px;
margin: 6px 0;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(250, 250, 252, 0.95) 100%);
border-radius: 12px;
border: 1px solid rgba(66, 165, 245, 0.15);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(66, 165, 245, 0.08), transparent);
transition: left 0.6s ease;
}
&:hover {
border-color: rgba(66, 165, 245, 0.3);
box-shadow: 0 4px 12px rgba(25, 118, 210, 0.12);
transform: translateY(-1px);
&::before {
left: 100%;
}
}
@media (max-width: 599px) {
gap: 6px;
padding: 3px 5px;
margin: 4px 0;
border-radius: 10px;
}
}
// Label/Titolo campo
.modern-field-label {
display: flex;
align-items: center;
justify-content: center;
min-width: 120px;
max-width: 140px;
padding: 10px 14px;
background: linear-gradient(135deg, #42a5f5 0%, #1976d2 100%);
border-radius: 8px;
box-shadow: 0 2px 6px rgba(25, 118, 210, 0.25);
position: relative;
overflow: hidden;
&::after {
content: '';
position: absolute;
top: -50%;
right: -50%;
width: 100%;
height: 200%;
background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.1), transparent);
transform: rotate(45deg);
animation: shimmer 3s infinite;
}
.label-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
z-index: 1;
}
.label-icon {
width: 32px;
height: 32px;
object-fit: contain;
}
.label-text {
color: white;
font-weight: 600;
font-size: 0.9rem;
text-align: center;
line-height: 1.3;
letter-spacing: 0.3px;
}
@media (max-width: 599px) {
min-width: 80px;
max-width: 100px;
padding: 8px 8px;
border-radius: 6px;
.label-icon {
width: 24px;
height: 24px;
}
.label-text {
font-size: 0.8rem;
}
}
}
// Valore campo (chip/display)
.modern-field-value {
flex: 1;
display: flex;
align-items: center;
padding: 8px 12px;
min-height: 48px;
cursor: pointer;
border-radius: 8px;
transition: all 0.3s ease;
position: relative;
&:hover {
background: rgba(66, 165, 245, 0.05);
.value-chip {
transform: scale(1.02);
box-shadow: 0 3px 10px rgba(102, 126, 234, 0.35);
}
}
@media (max-width: 599px) {
padding: 6px 8px;
min-height: 40px;
}
}
// Chip valore
.value-chip {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
font-weight: 500;
font-size: 0.95rem;
padding: 10px 16px;
border-radius: 20px;
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
max-width: 100%;
word-break: break-word;
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.25), transparent);
transition: left 0.5s ease;
}
&:hover::before {
left: 100%;
}
@media (max-width: 599px) {
font-size: 0.85rem;
padding: 8px 12px;
border-radius: 16px;
}
}
// Stato vuoto
.value-empty {
color: #999;
font-style: italic;
font-size: 0.9rem;
padding: 10px 16px;
@media (max-width: 599px) {
font-size: 0.85rem;
padding: 8px 12px;
}
}
// Wrapper per popup edit
.modern-popup-wrapper {
width: 100%;
:deep(.q-field) {
margin-bottom: 0;
}
:deep(.q-field__control) {
border-radius: 8px;
min-height: 44px;
@media (max-width: 599px) {
min-height: 40px;
border-radius: 6px;
}
}
:deep(.q-field__label) {
font-size: 0.9rem;
font-weight: 500;
@media (max-width: 599px) {
font-size: 0.85rem;
}
}
}
// Animazione shimmer
@keyframes shimmer {
0% {
transform: translateX(-100%) rotate(45deg);
}
100% {
transform: translateX(100%) rotate(45deg);
}
}
// Stati disabilitati
.modern-field-container.disabled {
opacity: 0.6;
cursor: not-allowed;
pointer-events: none;
.modern-field-label {
background: linear-gradient(135deg, #90a4ae 0%, #607d8b 100%);
}
.value-chip {
background: linear-gradient(135deg, #b0bec5 0%, #90a4ae 100%);
}
}
// Variante readonly (non clickable ma visibile)
.modern-field-container.readonly {
.modern-field-value {
cursor: default;
&:hover {
background: transparent;
.value-chip {
transform: none;
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
}
}
}
}
// LEGACY SUPPORT - mantiene classi esistenti
.colmodif {
cursor: pointer;
&:hover {
background-color: rgba(168, 240, 255, 0.3);
}
}
.colsel {
background-color: rgba(129, 184, 255, 0.3);
}
.cldisable {
color: #999 !important;
opacity: 0.6;
}
.clinput {
@media (max-width: 500px) {
display: flex;
flex-grow: 1;
}
}

View File

@@ -14,7 +14,7 @@ import MixinBase from '@src/mixins/mixin-base'
export default defineComponent({
name: 'CMyFieldDb',
emits: ['save'],
emits: ['save', 'savedInDb'],
props: {
title: {
type: String,
@@ -34,6 +34,16 @@ export default defineComponent({
required: false,
default: '',
},
mysubkey_tosee: {
type: String,
required: false,
default: '',
},
fieldsel_tosee: {
type: String,
required: false,
default: '',
},
specialField: {
type: Object as PropType<ISpecialField>,
required: false,
@@ -149,12 +159,13 @@ export default defineComponent({
const { setValDb, getValDb } = MixinBase()
function showandsave(row: any, col: any, newval: any, valinitial: any) {
async function showandsave(row: any, col: any, newval: any, valinitial: any) {
console.log('showandsave CMyFieldDb:', newval)
console.log('subkey', props.mysubkey, 'sskey', props.mysubsubkey)
tools.saveInDBForTypes($q, props.mykey, newval, props.type, props.serv, props.table, props.mysubkey, props.id, props.indrec, props.mysubsubkey, props.specialField);
await tools.saveInDBForTypes($q, props.mykey, newval, props.type, props.serv, props.table, props.mysubkey, props.id, props.indrec, props.mysubsubkey, props.specialField);
emit('savedInDb')
}
function save(newval: any) {

View File

@@ -1,75 +1,51 @@
<template>
<div class="text-center">
<div class="row items-center justify-center q-gutter-md q-ma-xs">
<div v-if="title" class="q-ma-xs">
<q-field
rounded
outlined
:bg-color="$q.dark.isActive ? '' : 'blue-4'"
dense
style="min-width: 110px"
>
<template v-slot:control>
<div class="centermydiv">
<div v-if="myimg" class="text-center">
<q-img
:src="myimg"
class="text-center"
style="height: 50px; width: 50px"
:alt="title"
>
</q-img>
</div>
<div
class="self-center full-width no-outline text-center"
tabindex="0"
>
{{ title }}
</div>
</div>
</template>
</q-field>
<div class="modern-field-container" :class="{ disabled: disable, readonly: !canModify && !canEdit }">
<!-- Label/Titolo -->
<div v-if="title" class="modern-field-label">
<div class="label-content">
<img v-if="myimg" :src="myimg" :alt="title" class="label-icon" />
<span class="label-text">{{ title }}</span>
</div>
</div>
<div
:class="` q-ma-sm q-pa-sm col-grow popupedit `"
:style="withBorder() ? `` : ``"
<!-- Valore/Edit -->
<div class="modern-field-value modern-popup-wrapper">
<CMyPopupEdit
debounce="1000"
:fielddb="true"
v-bind="$attrs"
:rec="rec"
:isrec="!!rec"
:table="table"
:hint="hint"
:title="title"
:field="mykey"
:filter="filter"
:subfield="mysubkey"
:subfield_to_see="mysubkey_tosee"
:fieldsel_tosee="fieldsel_tosee"
:specialField="specialField"
:mysubsubkey="mysubsubkey"
:indrec="indrec"
:type="type"
:serv="serv"
:disable="disable"
:jointable="jointable"
:myimg="myimg"
:canModify="canModify"
:canEdit="true"
:id="id"
:idmain="idmain"
:mycol="col ? col : {}"
:tablesel="tablesel"
:pickup="pickup"
v-model:row="row"
minuteinterval="1"
@showandsave="showandsave"
@save="save"
:notAllowAtChar="notAllowAtChar"
>
<CMyPopupEdit
debounce="1000"
:fielddb="true"
v-bind="$attrs"
:rec="rec"
:isrec="!!rec"
:table="table"
:hint="hint"
:title="title"
:field="mykey"
:filter="filter"
:subfield="mysubkey"
:specialField="specialField"
:mysubsubkey="mysubsubkey"
:indrec="indrec"
:type="type"
:serv="serv"
:disable="disable"
:jointable="jointable"
:myimg="myimg"
:canModify="canModify"
:canEdit="true"
:id="id"
:idmain="idmain"
:mycol="col ? col : {}"
:tablesel="tablesel"
:pickup="pickup"
v-model:row="row"
minuteinterval="1"
@showandsave="showandsave"
@save="save"
:notAllowAtChar="notAllowAtChar"
>
</CMyPopupEdit>
</div>
</CMyPopupEdit>
</div>
</div>
</template>
@@ -78,5 +54,5 @@
</script>
<style lang="scss" scoped>
@import './CMyFieldDb.scss';
@import './CMyFieldDb-modern.scss';
</style>

View File

@@ -1,25 +1,524 @@
.myflex{
display: flex;
flex: 1;
// ========================================
// CMyGroup - SCSS Moderno con Gradienti
// ========================================
$primary-color: #1976d2;
$primary-light: #42a5f5;
$primary-dark: #1565c0;
$secondary-color: #26a69a;
$positive-color: #21ba45;
$negative-color: #c10015;
$info-color: #31ccec;
$warning-color: #f2c037;
$grey-text: #555;
$grey-light: #999;
$border-radius-sm: 8px;
$border-radius: 12px;
$transition-speed: 0.3s;
$shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);
$shadow-md: 0 2px 8px rgba(0, 0, 0, 0.1);
$shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.15);
$mobile-breakpoint: 768px;
// Gradiente speciale per gruppi
$gradient-group-primary: linear-gradient(135deg, $secondary-color 0%, lighten($secondary-color, 15%) 100%);
$gradient-group-hover: linear-gradient(135deg, darken($secondary-color, 5%) 0%, $secondary-color 100%);
// ========================================
// Q-ITEM CONTAINER (con gradiente group-style)
// ========================================
.q-item {
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 50%, #ffffff 100%);
border-radius: $border-radius;
padding: 10px 12px;
margin: 8px 0;
transition: all $transition-speed cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: $shadow-sm;
position: relative;
overflow: hidden;
border: 1px solid rgba(0, 0, 0, 0.06);
border-left: 4px solid transparent;
// Effetto luce scorrevole
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
transition: left 0.6s ease;
z-index: 0;
}
// Gradiente sottile group-themed
&::after {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: linear-gradient(to right, rgba($secondary-color, 0.02), transparent 15%);
opacity: 0;
transition: opacity $transition-speed ease;
z-index: 0;
}
@media (max-width: $mobile-breakpoint) {
padding: 8px 10px;
margin: 6px 0;
}
// Hover effect
&.clickable:hover,
&[clickable]:hover {
background: linear-gradient(135deg, #ffffff 0%, #f0f4f8 50%, #ffffff 100%);
box-shadow: 0 4px 16px rgba($secondary-color, 0.15);
transform: translateY(-2px);
border-left-color: $secondary-color;
border-color: rgba($secondary-color, 0.15);
&::before {
left: 100%;
}
&::after {
opacity: 1;
}
}
// Assicura che i contenuti siano sopra gli effetti
> * {
position: relative;
z-index: 1;
}
}
.container{
vertical-align: center;
padding: 5px;
font-size: 1.15rem;
// ========================================
// AVATAR (con effetto glow group-themed)
// ========================================
.q-avatar {
transition: all $transition-speed ease;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
border: 2px solid rgba(255, 255, 255, 0.8);
position: relative;
&::after {
content: '';
position: absolute;
inset: -2px;
border-radius: 50%;
background: $gradient-group-primary;
opacity: 0;
transition: opacity $transition-speed ease;
z-index: -1;
}
.q-item:hover & {
transform: scale(1.05);
box-shadow: 0 4px 16px rgba($secondary-color, 0.3);
&::after {
opacity: 0.3;
}
}
@media (max-width: $mobile-breakpoint) {
width: 50px !important;
height: 50px !important;
}
}
.element{
font-weight: bold;
vertical-align: center;
padding: 5px;
font-size: 1.15rem;
// ========================================
// PROFILE IMAGE
// ========================================
.imgprofile {
border-radius: 50%;
object-fit: cover;
}
// ========================================
// GROUP TITLE (con gradiente)
// ========================================
.q-item__label {
line-height: 1.5;
margin-bottom: 3px;
.title_param{
font-size: 1.25rem;
&:last-child {
margin-bottom: 0;
}
strong {
font-weight: 600;
background: $gradient-group-primary;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-size: 1rem;
transition: all $transition-speed ease;
@media (max-width: $mobile-breakpoint) {
font-size: 0.9375rem;
}
.q-item:hover & {
background: $gradient-group-hover;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
}
em {
font-style: italic;
color: $grey-text;
font-size: 0.875rem;
@media (max-width: $mobile-breakpoint) {
font-size: 0.8125rem;
}
}
// Caption style
&[caption] {
color: $grey-light;
font-size: 0.8125rem;
margin-top: 2px;
@media (max-width: $mobile-breakpoint) {
font-size: 0.75rem;
}
}
}
.iconcirc {
margin-right: 4px;
// ========================================
// GROUPNAME BADGE
// ========================================
.q-item__label {
// Stile per (groupname)
&:has(strong) {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
// Parentesi con groupname
> :not(strong) {
font-size: 0.875rem;
color: $grey-text;
padding: 2px 8px;
border-radius: 6px;
background: linear-gradient(135deg, rgba($secondary-color, 0.08), rgba($secondary-color, 0.04));
border: 1px solid rgba($secondary-color, 0.2);
@media (max-width: $mobile-breakpoint) {
font-size: 0.8125rem;
padding: 2px 6px;
}
}
}
}
// ========================================
// ACTION BUTTONS (con gradienti)
// ========================================
.q-btn {
transition: all $transition-speed ease;
position: relative;
overflow: hidden;
// Rounded menu button
&[rounded] {
&.q-btn--round {
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(8px);
box-shadow: $shadow-sm;
border: 1px solid rgba(0, 0, 0, 0.06);
&:hover {
background: rgba(255, 255, 255, 0.95);
box-shadow: $shadow-md;
transform: scale(1.1) rotate(90deg);
}
}
}
// Send coins button (special gradient)
&[color='green'] {
background: linear-gradient(135deg, $positive-color, lighten($positive-color, 10%)) !important;
box-shadow: 0 2px 8px rgba($positive-color, 0.3);
&:hover {
background: linear-gradient(135deg, darken($positive-color, 5%), $positive-color) !important;
box-shadow: 0 4px 12px rgba($positive-color, 0.4);
transform: translateY(-2px);
}
&::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.4);
transform: translate(-50%, -50%);
transition: width 0.6s ease, height 0.6s ease;
}
&:hover::before {
width: 300px;
height: 300px;
}
}
}
// ========================================
// MENU DROPDOWN (con gradienti)
// ========================================
.q-menu {
background: linear-gradient(to bottom, #ffffff, #f8f9fa);
backdrop-filter: blur(10px);
border: 1px solid rgba(0, 0, 0, 0.08);
box-shadow: $shadow-lg;
border-radius: $border-radius-sm;
.q-list {
padding: 6px;
background: transparent;
@media (max-width: $mobile-breakpoint) {
padding: 4px;
}
}
.q-item {
border-radius: $border-radius-sm;
margin: 2px 0;
background: transparent;
border: none;
box-shadow: none;
border-left: none;
padding: 10px 12px;
&::before {
display: none;
}
&::after {
display: none;
}
&:hover {
background: linear-gradient(135deg, rgba($secondary-color, 0.08), rgba($secondary-color, 0.04));
transform: translateX(4px) translateY(0);
box-shadow: 0 2px 8px rgba($secondary-color, 0.1);
}
@media (max-width: $mobile-breakpoint) {
padding: 8px 10px;
}
}
.q-item__section--avatar {
min-width: 36px;
@media (max-width: $mobile-breakpoint) {
min-width: 32px;
}
.q-icon {
transition: all $transition-speed ease;
}
.q-item:hover & .q-icon {
transform: scale(1.1);
}
}
}
// ========================================
// COIN ICON (special styling)
// ========================================
.q-btn {
[class*='img:'] {
transition: transform $transition-speed ease;
}
&:hover [class*='img:'] {
transform: scale(1.1) rotate(10deg);
}
}
// ========================================
// DIALOG (con gradiente)
// ========================================
.q-dialog {
.q-card {
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
border-radius: $border-radius;
@media (max-width: $mobile-breakpoint) {
border-radius: 0;
}
}
.q-toolbar {
background: linear-gradient(135deg, $primary-color, $primary-dark) !important;
border-radius: $border-radius $border-radius 0 0;
padding: 12px 16px;
@media (max-width: $mobile-breakpoint) {
padding: 10px 12px;
border-radius: 0;
}
.q-toolbar-title {
font-weight: 600;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
}
}
// ========================================
// ANIMATIONS
// ========================================
@keyframes groupItemAppear {
from {
opacity: 0;
transform: translateY(10px) scale(0.98);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.q-item {
animation: groupItemAppear 0.35s ease-out;
}
// Coin icon rotation on hover
@keyframes coinRotate {
0% { transform: rotateY(0deg); }
100% { transform: rotateY(360deg); }
}
.q-btn:hover [class*='img:'] {
animation: coinRotate 0.8s ease-in-out;
}
// ========================================
// RESPONSIVE ADJUSTMENTS
// ========================================
@media (max-width: $mobile-breakpoint) {
.q-item-section {
padding: 0 4px;
}
.q-item__label {
line-height: 1.4;
}
.q-btn {
&[rounded] {
padding: 6px;
}
&[dense] {
padding: 4px 8px;
font-size: 0.875rem;
}
}
}
// ========================================
// UTILITY CLASSES
// ========================================
// Glass effect variant
.glass-group-item {
.q-item {
background: rgba(255, 255, 255, 0.7) !important;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
&:hover {
background: rgba(255, 255, 255, 0.85) !important;
}
}
}
// Highlighted group (admin)
.admin-group {
.q-item {
border-left: 4px solid $warning-color;
background: linear-gradient(to right, rgba($warning-color, 0.05), transparent 20%);
&:hover {
background: linear-gradient(to right, rgba($warning-color, 0.08), transparent 20%);
box-shadow: 0 4px 16px rgba($warning-color, 0.15);
}
}
}
// Featured group
.featured-group {
.q-item {
border: 2px solid transparent;
background: linear-gradient(white, white) padding-box,
$gradient-group-primary border-box;
&:hover {
box-shadow: 0 6px 20px rgba($secondary-color, 0.25);
}
}
}
// Active group indicator
.active-group-indicator {
position: absolute;
top: 8px;
right: 8px;
width: 10px;
height: 10px;
border-radius: 50%;
background: $gradient-group-primary;
box-shadow: 0 0 8px rgba($secondary-color, 0.6);
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% {
box-shadow: 0 0 8px rgba($secondary-color, 0.6);
}
50% {
box-shadow: 0 0 16px rgba($secondary-color, 0.9);
}
}
// Member count badge (opzionale)
.member-count-badge {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 8px;
border-radius: 12px;
background: linear-gradient(135deg, rgba($info-color, 0.1), rgba($info-color, 0.05));
border: 1px solid rgba($info-color, 0.3);
color: darken($info-color, 15%);
font-size: 0.75rem;
font-weight: 600;
margin-left: 8px;
.q-icon {
font-size: 0.875rem;
}
}

View File

@@ -0,0 +1,437 @@
// ========================================
// MODERN POPUP EDIT - ENHANCED DISPLAY
// ========================================
// Sovrascrive e aggiunge agli stili esistenti
// Display del valore quando non in modifica
.modern-value-display {
width: 100%;
// Chip per valori stringa/generici
.value-chip-display {
display: inline-flex;
align-items: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
font-weight: 500;
font-size: 0.95rem;
padding: 10px 18px;
border-radius: 20px;
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
max-width: 100%;
word-break: break-word;
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.25), transparent);
transition: left 0.5s ease;
}
&:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
&::before {
left: 100%;
}
}
@media (max-width: 599px) {
font-size: 0.85rem;
padding: 8px 14px;
border-radius: 16px;
}
}
// Link button
.value-link-btn {
background: linear-gradient(135deg, #42a5f5 0%, #1976d2 100%);
color: white;
padding: 10px 18px;
border-radius: 20px;
box-shadow: 0 2px 8px rgba(25, 118, 210, 0.3);
transition: all 0.3s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 8px;
font-weight: 500;
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s ease;
}
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(25, 118, 210, 0.4);
&::before {
left: 100%;
}
}
@media (max-width: 599px) {
padding: 8px 14px;
border-radius: 16px;
font-size: 0.85rem;
gap: 6px;
}
}
// Toggle migliorato
.value-toggle {
:deep(.q-toggle) {
padding: 4px 0;
.q-toggle__track {
width: 48px;
height: 24px;
border-radius: 12px;
transition: all 0.3s ease;
}
.q-toggle__thumb {
width: 20px;
height: 20px;
transition: all 0.3s ease;
}
&.q-toggle--truthy {
.q-toggle__track {
background: linear-gradient(135deg, #4caf50 0%, #2e7d32 100%);
box-shadow: 0 2px 6px rgba(76, 175, 80, 0.3);
}
}
&.q-toggle--falsy {
.q-toggle__track {
background: linear-gradient(135deg, #e0e0e0 0%, #bdbdbd 100%);
}
}
@media (max-width: 599px) {
.q-toggle__track {
width: 42px;
height: 22px;
}
.q-toggle__thumb {
width: 18px;
height: 18px;
}
}
}
}
}
// Enhanced chip_shadow per user items
.chip_shadow {
:deep(.q-chip) {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
transition: all 0.3s ease;
border: none;
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s ease;
}
&:hover {
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
transform: translateY(-1px);
&::before {
left: 100%;
}
}
@media (max-width: 599px) {
font-size: 0.85rem;
}
}
}
// User card migliorata
.user-item-card {
padding: 10px 12px;
margin: 6px 0;
border-radius: 12px;
transition: all 0.3s ease;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(250, 250, 252, 0.95) 100%);
border: 1px solid rgba(66, 165, 245, 0.15);
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(66, 165, 245, 0.08), transparent);
transition: left 0.6s ease;
}
&:hover {
background: linear-gradient(135deg, rgba(255, 255, 255, 1) 0%, rgba(245, 248, 252, 1) 100%);
border-color: rgba(66, 165, 245, 0.3);
box-shadow: 0 4px 12px rgba(25, 118, 210, 0.15);
transform: translateY(-1px);
&::before {
left: 100%;
}
}
@media (max-width: 599px) {
padding: 8px 10px;
margin: 4px 0;
border-radius: 10px;
}
.q-item-section {
&.avatar {
padding-right: 12px;
@media (max-width: 599px) {
padding-right: 8px;
}
}
}
.q-avatar {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border: 2px solid rgba(255, 255, 255, 0.8);
transition: all 0.3s ease;
}
&:hover .q-avatar {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
transform: scale(1.05);
}
.q-badge {
font-size: 0.7rem;
padding: 3px 8px;
font-weight: 600;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
@media (max-width: 599px) {
font-size: 0.65rem;
padding: 2px 6px;
}
}
.q-item-label {
font-weight: 500;
color: #2c3e50;
&.caption {
color: #7f8c8d;
font-size: 0.85rem;
@media (max-width: 599px) {
font-size: 0.8rem;
}
}
}
}
// Input states durante editing
.popup-edit-wrapper {
:deep(.q-field) {
padding-bottom: 6px;
@media (max-width: 599px) {
padding-bottom: 4px;
}
}
:deep(.q-field__control) {
min-height: 44px;
border-radius: 8px;
transition: all 0.3s ease;
&:hover {
background: rgba(66, 165, 245, 0.03);
}
&:focus-within {
background: rgba(66, 165, 245, 0.05);
box-shadow: 0 0 0 2px rgba(66, 165, 245, 0.2);
}
@media (max-width: 599px) {
min-height: 40px;
border-radius: 6px;
}
}
:deep(.q-field__label) {
font-size: 0.9rem;
font-weight: 500;
color: #1976d2;
@media (max-width: 599px) {
font-size: 0.85rem;
}
}
:deep(.q-field__native) {
font-size: 0.95rem;
color: #2c3e50;
padding: 8px 12px;
@media (max-width: 599px) {
font-size: 0.85rem;
padding: 6px 10px;
}
}
:deep(.q-input),
:deep(.q-select) {
margin: 2px 0;
@media (max-width: 599px) {
margin: 1px 0;
}
}
}
// Stato focus su editor
.editor {
border: 1px solid rgba(66, 165, 245, 0.3);
border-radius: 8px;
padding: 8px;
min-height: 60px;
transition: all 0.3s ease;
background: white;
&:hover {
border-color: rgba(66, 165, 245, 0.5);
background: rgba(66, 165, 245, 0.02);
}
&:focus-within {
border-color: #42a5f5;
box-shadow: 0 0 0 2px rgba(66, 165, 245, 0.15);
background: white;
}
@media (max-width: 599px) {
padding: 6px;
min-height: 50px;
border-radius: 6px;
}
}
// Textarea compatta
:deep(textarea.myinput-area) {
padding: 10px;
border-radius: 8px;
min-height: 60px;
line-height: 1.5;
font-size: 0.95rem;
color: #2c3e50;
transition: all 0.3s ease;
&:focus {
background: rgba(66, 165, 245, 0.02);
}
@media (max-width: 599px) {
padding: 8px;
min-height: 50px;
font-size: 0.85rem;
}
}
// Bottoni migliorati
.popup-button {
padding: 8px 16px;
margin: 4px 8px;
border-radius: 20px;
transition: all 0.3s ease;
background: linear-gradient(135deg, #42a5f5 0%, #1976d2 100%);
color: white;
font-weight: 500;
box-shadow: 0 2px 6px rgba(25, 118, 210, 0.3);
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s ease;
}
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(25, 118, 210, 0.4);
&::before {
left: 100%;
}
}
@media (max-width: 599px) {
padding: 6px 12px;
margin: 3px 6px;
border-radius: 16px;
}
}
// Extra field modernizzato
.extrafield {
font-size: 0.9rem;
padding: 6px 12px;
color: #5e6e7f;
font-weight: 500;
margin-bottom: 6px;
display: inline-block;
background: linear-gradient(135deg, rgba(66, 165, 245, 0.08) 0%, rgba(66, 165, 245, 0.05) 100%);
border-radius: 8px;
border: 1px solid rgba(66, 165, 245, 0.15);
@media (max-width: 599px) {
font-size: 0.85rem;
padding: 4px 10px;
margin-bottom: 4px;
border-radius: 6px;
}
}

View File

@@ -1,362 +1,449 @@
// ========================================
// VARIABILI
// MODERN POPUP EDIT - ENHANCED DISPLAY
// ========================================
$primary-color: #1976d2;
$primary-light: #42a5f5;
$grey-color: #666;
$border-radius: 8px;
$border-radius-sm: 6px;
$transition-speed: 0.3s;
// Sovrascrive e aggiunge agli stili esistenti
$shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);
$shadow-md: 0 2px 8px rgba(0, 0, 0, 0.1);
// Display del valore quando non in modifica
.modern-value-display {
width: 100%;
$mobile-breakpoint: 768px;
// Chip per valori stringa/generici
.value-chip-display {
display: inline-flex;
align-items: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
font-weight: 500;
font-size: 0.95rem;
padding: 10px 18px;
border-radius: 20px;
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
max-width: 100%;
word-break: break-word;
// ========================================
// EDITOR
// ========================================
.editor {
border: 1px solid rgba(25, 118, 210, 0.3);
border-radius: $border-radius-sm;
padding: 6px;
min-height: 60px;
transition: all $transition-speed ease;
background: white;
&:hover {
border-color: $primary-light;
}
&:focus-within {
border-color: $primary-color;
box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.1);
}
@media (max-width: $mobile-breakpoint) {
padding: 4px;
min-height: 50px;
}
}
// ========================================
// POPUP EDIT CONTAINER
// ========================================
.popup-edit-wrapper {
:deep(.q-popup-edit) {
padding: 8px;
border-radius: $border-radius;
box-shadow: $shadow-md;
@media (max-width: $mobile-breakpoint) {
padding: 6px;
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.25), transparent);
transition: left 0.5s ease;
}
}
}
// ========================================
// FIELD WRAPPERS
// ========================================
.field-wrapper {
padding: 4px 0;
margin: 3px 0;
@media (max-width: $mobile-breakpoint) {
padding: 3px 0;
margin: 2px 0;
}
}
// ========================================
// EXTRA FIELD
// ========================================
.extrafield {
font-size: 0.9375rem;
padding: 4px 6px;
color: $grey-color;
font-weight: 500;
margin-bottom: 4px;
display: inline-block;
background: rgba(0, 0, 0, 0.03);
border-radius: $border-radius-sm;
@media (max-width: $mobile-breakpoint) {
font-size: 0.875rem;
padding: 3px 4px;
margin-bottom: 3px;
}
}
// ========================================
// TOGGLE ENHANCED
// ========================================
.toggle-enhanced {
padding: 4px 0;
:deep(.q-toggle__label) {
font-size: 0.9375rem;
margin-left: 6px;
@media (max-width: $mobile-breakpoint) {
font-size: 0.875rem;
margin-left: 4px;
}
}
:deep(.q-toggle__inner) {
transition: all $transition-speed ease;
}
}
// ========================================
// CHIP SHADOW
// ========================================
.chip_shadow {
:deep(.q-chip) {
box-shadow: $shadow-sm;
transition: all $transition-speed ease;
&:hover {
box-shadow: $shadow-md;
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
&::before {
left: 100%;
}
}
@media (max-width: 599px) {
font-size: 0.85rem;
padding: 8px 14px;
border-radius: 16px;
}
}
// Link button
.value-link-btn {
background: linear-gradient(135deg, #42a5f5 0%, #1976d2 100%);
color: white;
padding: 10px 18px;
border-radius: 20px;
box-shadow: 0 2px 8px rgba(25, 118, 210, 0.3);
transition: all 0.3s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 8px;
font-weight: 500;
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s ease;
}
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(25, 118, 210, 0.4);
&::before {
left: 100%;
}
}
@media (max-width: 599px) {
padding: 8px 14px;
border-radius: 16px;
font-size: 0.85rem;
gap: 6px;
}
}
// Toggle migliorato
.value-toggle {
:deep(.q-toggle) {
padding: 4px 0;
.q-toggle__track {
width: 48px;
height: 24px;
border-radius: 12px;
transition: all 0.3s ease;
}
.q-toggle__thumb {
width: 20px;
height: 20px;
transition: all 0.3s ease;
}
&.q-toggle--truthy {
.q-toggle__track {
background: linear-gradient(135deg, #4caf50 0%, #2e7d32 100%);
box-shadow: 0 2px 6px rgba(76, 175, 80, 0.3);
}
}
&.q-toggle--falsy {
.q-toggle__track {
background: linear-gradient(135deg, #e0e0e0 0%, #bdbdbd 100%);
}
}
@media (max-width: 599px) {
.q-toggle__track {
width: 42px;
height: 22px;
}
.q-toggle__thumb {
width: 18px;
height: 18px;
}
}
}
}
}
// ========================================
// USER CARD IN POPUP
// ========================================
.user-item-card {
padding: 6px 8px;
margin: 4px 0;
border-radius: $border-radius;
transition: all $transition-speed ease;
background: white;
border: 1px solid rgba(0, 0, 0, 0.08);
// Enhanced chip_shadow per user items
.chip_shadow {
:deep(.q-chip) {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
transition: all 0.3s ease;
border: none;
position: relative;
overflow: hidden;
&:hover {
background: rgba(25, 118, 210, 0.05);
border-color: rgba(25, 118, 210, 0.2);
box-shadow: $shadow-sm;
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s ease;
}
&:hover {
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
transform: translateY(-1px);
&::before {
left: 100%;
}
}
@media (max-width: 599px) {
font-size: 0.85rem;
}
}
}
// User card migliorata
.user-item-card {
padding: 10px 12px;
margin: 6px 0;
border-radius: 12px;
transition: all 0.3s ease;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(250, 250, 252, 0.95) 100%);
border: 1px solid rgba(66, 165, 245, 0.15);
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(66, 165, 245, 0.08), transparent);
transition: left 0.6s ease;
}
@media (max-width: $mobile-breakpoint) {
padding: 4px 6px;
margin: 3px 0;
&:hover {
background: linear-gradient(135deg, rgba(255, 255, 255, 1) 0%, rgba(245, 248, 252, 1) 100%);
border-color: rgba(66, 165, 245, 0.3);
box-shadow: 0 4px 12px rgba(25, 118, 210, 0.15);
transform: translateY(-1px);
&::before {
left: 100%;
}
}
@media (max-width: 599px) {
padding: 8px 10px;
margin: 4px 0;
border-radius: 10px;
}
.q-item-section {
&.avatar {
padding-right: 8px;
padding-right: 12px;
@media (max-width: $mobile-breakpoint) {
padding-right: 6px;
@media (max-width: 599px) {
padding-right: 8px;
}
}
}
.q-avatar {
box-shadow: $shadow-sm;
border: 2px solid rgba(0, 0, 0, 0.05);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border: 2px solid rgba(255, 255, 255, 0.8);
transition: all 0.3s ease;
}
&:hover .q-avatar {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
transform: scale(1.05);
}
.q-badge {
font-size: 0.6875rem;
padding: 2px 6px;
font-size: 0.7rem;
padding: 3px 8px;
font-weight: 600;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
@media (max-width: $mobile-breakpoint) {
font-size: 0.625rem;
padding: 1px 4px;
@media (max-width: 599px) {
font-size: 0.65rem;
padding: 2px 6px;
}
}
.q-item-label {
font-weight: 500;
color: #2c3e50;
&.caption {
color: #7f8c8d;
font-size: 0.85rem;
@media (max-width: 599px) {
font-size: 0.8rem;
}
}
}
}
// ========================================
// INPUT OVERRIDES (Compact)
// ========================================
// Input states durante editing
.popup-edit-wrapper {
:deep(.q-field) {
padding-bottom: 8px;
padding-bottom: 6px;
@media (max-width: $mobile-breakpoint) {
padding-bottom: 6px;
@media (max-width: 599px) {
padding-bottom: 4px;
}
}
:deep(.q-field__control) {
min-height: 44px;
border-radius: 8px;
transition: all 0.3s ease;
@media (max-width: $mobile-breakpoint) {
&:hover {
background: rgba(66, 165, 245, 0.03);
}
&:focus-within {
background: rgba(66, 165, 245, 0.05);
box-shadow: 0 0 0 2px rgba(66, 165, 245, 0.2);
}
@media (max-width: 599px) {
min-height: 40px;
border-radius: 6px;
}
}
:deep(.q-field__label) {
font-size: 0.9375rem;
font-size: 0.9rem;
font-weight: 500;
color: #1976d2;
@media (max-width: $mobile-breakpoint) {
font-size: 0.875rem;
@media (max-width: 599px) {
font-size: 0.85rem;
}
}
:deep(.q-input) {
margin: 3px 0;
:deep(.q-field__native) {
font-size: 0.95rem;
color: #2c3e50;
padding: 8px 12px;
@media (max-width: $mobile-breakpoint) {
margin: 2px 0;
@media (max-width: 599px) {
font-size: 0.85rem;
padding: 6px 10px;
}
}
:deep(.q-input),
:deep(.q-select) {
margin: 3px 0;
@media (max-width: $mobile-breakpoint) {
margin: 2px 0;
}
}
}
// ========================================
// TEXTAREA COMPACT
// ========================================
:deep(textarea) {
&.myinput-area {
padding: 8px;
border-radius: $border-radius-sm;
min-height: 60px;
line-height: 1.4;
@media (max-width: $mobile-breakpoint) {
padding: 6px;
min-height: 50px;
}
}
}
// ========================================
// BUTTON IN POPUP
// ========================================
.popup-button {
padding: 6px 12px;
margin: 3px 6px;
border-radius: $border-radius-sm;
transition: all $transition-speed ease;
&:hover {
transform: translateY(-1px);
box-shadow: $shadow-sm;
}
@media (max-width: $mobile-breakpoint) {
padding: 4px 8px;
margin: 2px 4px;
}
}
// ========================================
// DATE PICKER COMPACT
// ========================================
.date-picker-compact {
:deep(.q-date) {
padding: 4px;
@media (max-width: $mobile-breakpoint) {
padding: 3px;
}
}
:deep(.q-date__header) {
padding: 6px;
@media (max-width: $mobile-breakpoint) {
padding: 4px;
}
}
:deep(.q-date__calendar-item) {
padding: 3px;
@media (max-width: $mobile-breakpoint) {
padding: 2px;
}
}
}
// ========================================
// COLOR PICKER
// ========================================
.color-select-wrapper {
:deep(.q-select) {
min-width: 150px;
@media (max-width: $mobile-breakpoint) {
min-width: 120px;
}
}
}
// ========================================
// LEGACY SUPPORT
// ========================================
.clpopupVisuCard {
border-radius: $border-radius;
padding: 4px;
margin: 3px 0;
@media (max-width: $mobile-breakpoint) {
padding: 3px;
margin: 2px 0;
@media (max-width: 599px) {
margin: 1px 0;
}
}
}
// ========================================
// DISABLED STATE
// ========================================
.disabled {
opacity: 0.5;
cursor: not-allowed;
pointer-events: none;
}
// ========================================
// CURSOR POINTER
// ========================================
.cursor-pointer {
cursor: pointer;
transition: opacity $transition-speed ease;
// Stato focus su editor
.editor {
border: 1px solid rgba(66, 165, 245, 0.3);
border-radius: 8px;
padding: 8px;
min-height: 60px;
transition: all 0.3s ease;
background: white;
&:hover {
opacity: 0.8;
border-color: rgba(66, 165, 245, 0.5);
background: rgba(66, 165, 245, 0.02);
}
&:focus-within {
border-color: #42a5f5;
box-shadow: 0 0 0 2px rgba(66, 165, 245, 0.15);
background: white;
}
@media (max-width: 599px) {
padding: 6px;
min-height: 50px;
border-radius: 6px;
}
}
// ========================================
// FLEX HELPERS (Compact)
// ========================================
.flex {
display: flex;
gap: 6px;
// Textarea compatta
:deep(textarea.myinput-area) {
padding: 10px;
border-radius: 8px;
min-height: 60px;
line-height: 1.5;
font-size: 0.95rem;
color: #2c3e50;
transition: all 0.3s ease;
@media (max-width: $mobile-breakpoint) {
gap: 4px;
&:focus {
background: rgba(66, 165, 245, 0.02);
}
@media (max-width: 599px) {
padding: 8px;
min-height: 50px;
font-size: 0.85rem;
}
}
.justify-center {
justify-content: center;
// Bottoni migliorati
.popup-button {
padding: 8px 16px;
margin: 4px 8px;
border-radius: 20px;
transition: all 0.3s ease;
background: linear-gradient(135deg, #42a5f5 0%, #1976d2 100%);
color: white;
font-weight: 500;
box-shadow: 0 2px 6px rgba(25, 118, 210, 0.3);
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s ease;
}
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(25, 118, 210, 0.4);
&::before {
left: 100%;
}
}
@media (max-width: 599px) {
padding: 6px 12px;
margin: 3px 6px;
border-radius: 16px;
}
}
.items-center {
align-items: center;
}
// Extra field modernizzato
.extrafield {
font-size: 0.9rem;
padding: 6px 12px;
color: #5e6e7f;
font-weight: 500;
margin-bottom: 6px;
display: inline-block;
background: linear-gradient(135deg, rgba(66, 165, 245, 0.08) 0%, rgba(66, 165, 245, 0.05) 100%);
border-radius: 8px;
border: 1px solid rgba(66, 165, 245, 0.15);
// ========================================
// REQUIRED INDICATOR
// ========================================
.required-indicator {
color: #c10015;
font-weight: 600;
margin-left: 2px;
@media (max-width: 599px) {
font-size: 0.85rem;
padding: 4px 10px;
margin-bottom: 4px;
border-radius: 6px;
}
}
.modern-chip-container {
min-width: 350px;
@media (max-width: 599px) {
width: 100%;
min-width: unset;
}
.modern-chip {
width: 100%;
}
}

View File

@@ -121,6 +121,21 @@ export default defineComponent({
required: false,
default: '',
},
label_trans: {
type: String,
required: false,
default: '',
},
subfield_to_see: {
type: String,
required: false,
default: '',
},
fieldsel_tosee: {
type: String,
required: false,
default: '',
},
subfield2: {
type: String,
required: false,
@@ -261,6 +276,7 @@ export default defineComponent({
const userStore = useUserStore();
const globalStore = useGlobalStore();
const myvaltosee = ref(null as any);
const myvalue = ref(null as any);
const myvalue2 = ref(null as any);
const myvalueprec = ref('false');
@@ -276,6 +292,7 @@ export default defineComponent({
const $router = useRouter();
const loaded = ref(false);
const modeEdit = ref(false);
const myColor = ref('#FF00AA55'); // Colore con trasparenza iniziale
@@ -357,6 +374,7 @@ export default defineComponent({
}
}
col.value.jointable = props.jointable;
col.value.label_trans = props.label_trans;
if (props.filter) col.value.filter = props.filter;
col.value.fieldtype = props.type;
@@ -519,7 +537,7 @@ export default defineComponent({
}
function changevalRecOrig(newval: any, subcol: string = '') {
console.log('changevalRec', newval)
console.log('changevalRec', newval);
// if (!props.insertMode || (props.insertMode && col.value.fieldtype !== costanti.FieldType.multioption)) {
if (col.value && col.value.allowchar === costanti.ALLOWCHAR_CODE) {
newval = tools.removespaces_slash(newval);
@@ -537,7 +555,7 @@ export default defineComponent({
}
if (props.type === costanti.FieldType.imgfile_sfuso) {
newval = newval?.imagefile
newval = newval?.imagefile;
}
if (props.notAllowAtChar) {
@@ -635,8 +653,11 @@ export default defineComponent({
note: '',
};
}
} catch (e) { }
} catch (e) {}
if (props.subfield_to_see) {
myvaltosee.value = myrow.value[props.field][props.subfield_to_see];
}
// console.log('popupedit: myvalue.value', myvalue.value)
@@ -740,7 +761,6 @@ export default defineComponent({
}
}
if (col.value.fieldtype === costanti.FieldType.verifica) {
newVal.username = userStore.my.username;
newVal.data = tools.getDateNow();
@@ -793,6 +813,11 @@ export default defineComponent({
}
}
if (props.fieldsel_tosee) {
const mystrcol = props.fieldsel_tosee;
myvaltosee.value = copynewval[mystrcol];
}
console.log('SaveValueInt', newVal, valinitial);
emit('save', newVal, valinitial, copynewval.which!);
@@ -836,6 +861,25 @@ export default defineComponent({
);
}
}
async function savefieldtosee(value: any, initialval: any, myq: any) {
if (!props.insertMode) {
let ret = null;
myvalue2.value = value;
return tools.saveInDBForTypes(
myq,
props.field2,
myvalue2.value,
props.type,
props.serv,
props.table,
props.fieldsel_tosee,
props.id,
props.indrec,
props.mysubsubkey,
props.specialField
);
}
}
function annulla(val: any) {
emit('annulla', true);
@@ -889,7 +933,7 @@ export default defineComponent({
myvalue.value = '';
} else {
myvalue.value = newVal.imagefile;
newVal = tools.getDirUpload() + mypath.value + myvalue.value
newVal = tools.getDirUpload() + mypath.value + myvalue.value;
}
} else if (col.value.fieldtype === costanti.FieldType.imgcard) {
console.log('newVal.imagefile', newVal);
@@ -1204,6 +1248,8 @@ export default defineComponent({
colorPicker,
myColor,
hoverPreview,
myvaltosee,
modeEdit,
};
},
});

View File

@@ -1282,15 +1282,19 @@
</CMySelect>
</div>
<div v-else>
<!--
rec: {{rec}}<br><br>
row: {{row}}<br><br>
col.jointable {{col.jointable}}<br><br>
myvalue {{myvalue}}<br><br>
opt: {{globalStore.getTableJoinByName(col.jointable, col.addall, col.addnone, col.filter)}}<br><br>
val: {{fieldsTable.getKeyByTable(col.jointable)}}<br><br>
lab: {{fieldsTable.getLabelByTable(col.jointable)}}<br><br>-->
<div
v-if="!modeEdit && myvaltosee"
class="modern-chip-container"
>
<q-chip
:label="myvaltosee"
class="modern-chip"
size="md"
@click="modeEdit = true"
></q-chip>
</div>
<CMyChipList
v-else
:rec="row"
myclass="text-center"
:type="col.fieldtype"
@@ -1776,10 +1780,12 @@
"
:filter_table="col.filter_table"
:filter_field="col.filter_field"
:sola_lettura="col.disable || disable"
:value_extra="value_extra"
:newvaluefunc="addNewValue"
:optval="fieldsTable.getKeyByTable(col.jointable)"
:optlab="fieldsTable.getLabelByTable(col.jointable)"
:myvaltosee="myvaltosee"
:options="
globalStore.getTableJoinByName(
col.jointable,
@@ -2167,5 +2173,5 @@
<script lang="ts" src="./CMyPopupEdit.ts"></script>
<style lang="scss" scoped>
@import './CMyPopupEdit.scss';
@import './CMyPopupEdit-modern.scss';
</style>

View File

@@ -130,7 +130,7 @@ export default defineComponent({
const arrStep = ref([
{
/*{
indstep: 0,
step: STEP_CITY,
title: t('tutorial.step_residence_title'),
@@ -140,6 +140,17 @@ export default defineComponent({
checkOkReal: function (): boolean { return this.checkOk() },
icon: 'house',
required: true,
},*/
{
indstep: 0,
step: STEP_CITY,
title: t('tutorial.step_residence_comune_title'),
extratitle: function () { return ': ' + (contact.value!.profile.resid_str_comune ? contact.value!.profile.resid_str_comune : '') },
label: t('tutorial.step_residence_comune'),
checkOk: function (): boolean { return contact.value ? !!contact.value.profile.resid_str_comune && contact.value.profile.resid_str_comune !== '' && contact.value.profile.resid_str_comune !== '0' : false },
checkOkReal: function (): boolean { return this.checkOk() },
icon: 'house',
required: true,
},
/*{
step: STEP_NAME_SURNAME, // 2
@@ -343,8 +354,8 @@ export default defineComponent({
username.value = props.mycontact.username
}
}
if (contact.value && contact.value.profile && contact.value.profile.resid_province === '0') {
contact.value.profile.resid_province = ''
if (contact.value && contact.value.profile && contact.value.profile.resid_str_comune === '0') {
contact.value.profile.resid_str_comune = ''
}
mylistcircuits.value = circuitStore.getCircuitsNameByProvince(strProv.value)

File diff suppressed because it is too large Load Diff

View File

@@ -39,7 +39,7 @@
<q-item v-if="mystr">
<q-item-section class="text-grey">
<span
v-if="Number.isInteger(parseInt(mystr))"
v-if="Number.isInteger(parseInt(mystr)) && tools.isGruppoMacro()"
@click="searchOnGM(mystr)"
class="clickable-text"
>
@@ -108,7 +108,7 @@
:input-class="myclass"
:options="valori"
:option-value="optval"
:option-label="getOptionLabel"
:option-label="(opt) => getOptionLabel(opt)"
:use-chips="tools.isValueNotEmpty(myvalue)"
stack-label
clearable
@@ -130,7 +130,7 @@
<q-item v-if="mystr">
<q-item-section class="text-grey">
<span
v-if="Number.isInteger(parseInt(mystr))"
v-if="Number.isInteger(parseInt(mystr)) && tools.isGruppoMacro()"
@click="searchOnGM(mystr)"
class="clickable-text text-blue"
>

View File

@@ -1,4 +1,439 @@
.myflex{
display: flex;
flex: 1;
// ========================================
// CMyUser - SCSS Moderno con Gradienti
// ========================================
$primary-color: #1976d2;
$primary-light: #42a5f5;
$primary-dark: #1565c0;
$secondary-color: #26a69a;
$positive-color: #21ba45;
$negative-color: #c10015;
$info-color: #31ccec;
$warning-color: #f2c037;
$grey-text: #555;
$grey-light: #999;
$border-radius-sm: 8px;
$border-radius: 12px;
$transition-speed: 0.3s;
$shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);
$shadow-md: 0 2px 8px rgba(0, 0, 0, 0.1);
$shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.15);
$mobile-breakpoint: 768px;
// ========================================
// Q-ITEM CONTAINER (con gradiente)
// ========================================
.q-item {
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 50%, #ffffff 100%);
border-radius: $border-radius;
padding: 10px 12px;
margin: 8px 0;
transition: all $transition-speed cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: $shadow-sm;
position: relative;
overflow: hidden;
border: 1px solid rgba(0, 0, 0, 0.06);
// Effetto luce scorrevole
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
transition: left 0.6s ease;
z-index: 0;
}
@media (max-width: $mobile-breakpoint) {
padding: 8px 10px;
margin: 6px 0;
}
// Hover effect
&.clickable:hover,
&[clickable]:hover {
background: linear-gradient(135deg, #ffffff 0%, #f0f4f8 50%, #ffffff 100%);
box-shadow: $shadow-md;
transform: translateY(-2px);
border-color: rgba($primary-color, 0.15);
&::before {
left: 100%;
}
}
// Assicura che i contenuti siano sopra l'effetto luce
>* {
position: relative;
z-index: 1;
}
}
// ========================================
// AVATAR (con effetto glow)
// ========================================
.q-avatar {
transition: all $transition-speed ease;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
border: 2px solid rgba(255, 255, 255, 0.8);
position: relative;
&::after {
content: '';
position: absolute;
inset: -2px;
border-radius: 50%;
background: linear-gradient(135deg, $primary-light, $secondary-color);
opacity: 0;
transition: opacity $transition-speed ease;
z-index: -1;
}
.q-item:hover & {
transform: scale(1.05);
box-shadow: 0 4px 16px rgba($primary-color, 0.3);
&::after {
opacity: 0.3;
}
}
@media (max-width: $mobile-breakpoint) {
width: 50px !important;
height: 50px !important;
}
}
// ========================================
// PROFILE IMAGE
// ========================================
.imgprofile {
border-radius: 50%;
object-fit: cover;
}
// ========================================
// USERNAME (con gradiente)
// ========================================
.username {
font-weight: 600;
background: linear-gradient(135deg, $primary-color, rgba($primary-color, 0.85));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-size: 1rem;
transition: all $transition-speed ease;
@media (max-width: $mobile-breakpoint) {
font-size: 0.9375rem;
}
.q-item:hover & {
background: linear-gradient(135deg, color-darken($primary-color, 5%), $primary-color);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
}
// ========================================
// PROVINCE DISPLAY (con gradiente)
// ========================================
.show_province_title,
.show_comune_title {
font-style: italic;
text-align: right;
font-size: 0.8125rem;
color: $grey-text;
margin-top: 4px;
@media (max-width: $mobile-breakpoint) {
font-size: 0.75rem;
}
}
.show_province,
.show_comune {
font-weight: 600;
padding: 2px 8px;
border-radius: 6px;
background: linear-gradient(135deg, rgba($info-color, 0.1), rgba($info-color, 0.05));
border: 1px solid rgba($info-color, 0.3);
color: color-darken($info-color, 15%);
transition: all $transition-speed ease;
&:hover {
background: linear-gradient(135deg, rgba($info-color, 0.15), rgba($info-color, 0.08));
border-color: $info-color;
}
}
// ========================================
// Q-ITEM LABEL
// ========================================
.q-item__label {
line-height: 1.5;
margin-bottom: 3px;
&:last-child {
margin-bottom: 0;
}
strong {
font-weight: 600;
color: color-darken($grey-text, 10%);
}
em {
font-style: italic;
color: $grey-text;
font-size: 0.875rem;
@media (max-width: $mobile-breakpoint) {
font-size: 0.8125rem;
}
}
// Caption style
&[caption] {
color: $grey-light;
font-size: 0.8125rem;
margin-top: 2px;
@media (max-width: $mobile-breakpoint) {
font-size: 0.75rem;
}
}
}
// ========================================
// MENU BUTTON (con glassmorphism)
// ========================================
.q-btn {
transition: all $transition-speed ease;
&[rounded] {
&.q-btn--round {
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(8px);
box-shadow: $shadow-sm;
border: 1px solid rgba(0, 0, 0, 0.06);
&:hover {
background: rgba(255, 255, 255, 0.95);
box-shadow: $shadow-md;
transform: scale(1.1) rotate(90deg);
}
}
}
}
// ========================================
// MENU DROPDOWN (con gradienti)
// ========================================
.q-menu {
background: linear-gradient(to bottom, #ffffff, #f8f9fa);
backdrop-filter: blur(10px);
border: 1px solid rgba(0, 0, 0, 0.08);
box-shadow: $shadow-lg;
border-radius: $border-radius-sm;
.q-list {
padding: 6px;
background: transparent;
@media (max-width: $mobile-breakpoint) {
padding: 4px;
}
}
.q-item {
border-radius: $border-radius-sm;
margin: 2px 0;
background: transparent;
border: none;
box-shadow: none;
&::before {
display: none;
}
&:hover {
background: linear-gradient(135deg, rgba($primary-color, 0.08), rgba($primary-color, 0.04));
transform: translateX(4px) translateY(0);
box-shadow: 0 2px 8px rgba($primary-color, 0.1);
}
@media (max-width: $mobile-breakpoint) {
padding: 8px 10px;
}
}
.q-item__section--avatar {
min-width: 36px;
@media (max-width: $mobile-breakpoint) {
min-width: 32px;
}
.q-icon {
transition: all $transition-speed ease;
}
.q-item:hover & .q-icon {
transform: scale(1.1);
}
}
}
// ========================================
// STATUS INDICATORS
// ========================================
// Reported user
[style*='color: red'] {
&[style*='font-weight: bold'] {
background: linear-gradient(135deg, rgba($negative-color, 0.12), rgba($negative-color, 0.06));
padding: 4px 8px;
border-radius: 6px;
border-left: 3px solid $negative-color;
display: inline-block;
margin: 4px 0;
}
}
// Facilitator note
[style*='color: blue'] {
em {
background: linear-gradient(135deg, rgba($primary-color, 0.08), rgba($primary-color, 0.04));
padding: 3px 6px;
border-radius: 6px;
border-left: 2px solid $primary-color;
}
}
// ========================================
// DIALOG (con gradiente)
// ========================================
.q-dialog {
.q-card {
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
border-radius: $border-radius;
@media (max-width: $mobile-breakpoint) {
border-radius: 0;
}
}
.q-toolbar {
background: linear-gradient(135deg, $primary-color, $primary-dark) !important;
border-radius: $border-radius $border-radius 0 0;
padding: 12px 16px;
@media (max-width: $mobile-breakpoint) {
padding: 10px 12px;
border-radius: 0;
}
.q-toolbar-title {
font-weight: 600;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
}
}
// ========================================
// ANIMATIONS
// ========================================
@keyframes userItemAppear {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.q-item {
animation: userItemAppear 0.3s ease-out;
}
// ========================================
// RESPONSIVE ADJUSTMENTS
// ========================================
@media (max-width: $mobile-breakpoint) {
.q-item-section {
padding: 0 4px;
}
.q-item__label {
line-height: 1.4;
}
.q-btn {
&[rounded] {
padding: 6px;
}
}
}
// ========================================
// UTILITY CLASSES
// ========================================
// Glass effect variant
.glass-user-item {
.q-item {
background: rgba(255, 255, 255, 0.7) !important;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
&:hover {
background: rgba(255, 255, 255, 0.85) !important;
}
}
}
// Highlighted user
.highlighted-user {
.q-item {
border-left: 4px solid $primary-color;
background: linear-gradient(to right, rgba($primary-color, 0.05), transparent 20%);
}
}
// Online indicator (opzionale)
.online-indicator {
position: absolute;
bottom: 2px;
right: 2px;
width: 12px;
height: 12px;
border-radius: 50%;
background: linear-gradient(135deg, $positive-color, rgba($positive-color, 0.9));
border: 2px solid white;
box-shadow: 0 0 8px rgba($positive-color, 0.6);
animation: pulse 2s infinite;
}
@keyframes pulse {
0%,
100% {
box-shadow: 0 0 8px rgba($positive-color, 0.6);
}
50% {
box-shadow: 0 0 16px rgba($positive-color, 0.9);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -251,7 +251,6 @@ $transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.step-completed & {
text-decoration: line-through;
opacity: 0.8;
}
}

View File

@@ -15,6 +15,7 @@ import type { ICircuit, IUserFields } from 'model';
import { costanti } from '@costanti';
import { shared_consts } from '@src/common/shared_vuejs';
import { CMyFieldDb } from '@src/components/CMyFieldDb';
import { CMySelectCity } from '@src/components/CMySelectCity';
import { CMyCircuit } from '@src/components/CMyCircuit';
import { CMyUser } from '@src/components/CMyUser';
@@ -29,6 +30,7 @@ export default defineComponent({
CMySelectCity,
CMyCircuit,
CMyUser,
CMyFieldDb,
},
props: {
showAlsoIfSkipped: {
@@ -68,7 +70,6 @@ export default defineComponent({
// ========================================
// TUTORIAL STATE
// ========================================
const contact = ref(<IUserFields | null>null);
const activeStep = ref<string | null>('telegram');
const currentStepIndex = ref(0); // Indice step corrente per navigazione
const nascondiavviso = ref(false);
@@ -89,6 +90,14 @@ export default defineComponent({
return userStore.my?.profile?.telegram_verification_skipped;
});
const contact = computed(() => {
if (!props.mycontact) {
return userStore.my;
} else {
return props.mycontact;
}
});
const isTelegramVerified = computed(() => {
return (
!!(userStore.my?.profile?.username_telegram && userStore.my?.profile?.teleg_id) ||
@@ -121,6 +130,13 @@ export default defineComponent({
return '';
});
const strComune = computed(() => {
if (contact.value && contact.value.profile.resid_str_comune) {
return contact.value.profile.resid_str_comune;
}
return '';
});
const card = computed(() => {
if (contact.value && contact.value.profile.resid_card) {
return contact.value.profile.resid_card;
@@ -135,24 +151,24 @@ export default defineComponent({
// Step definitions
const stepResidence = computed(() => ({
step: STEP_CITY,
title: t('tutorial.step_residence_title'),
title: t('tutorial.step_residence_comune_title'),
extratitle: function () {
return contact.value?.profile.resid_province
? ': ' + contact.value.profile.resid_province
return contact.value?.profile.resid_str_comune
? ': ' + contact.value.profile.resid_str_comune
: '';
},
label: t('tutorial.step_residence'),
checkOk: function (): boolean {
return contact.value
? !!contact.value.profile.resid_province &&
contact.value.profile.resid_province !== '' &&
contact.value.profile.resid_province !== '0'
? !!contact.value.profile.resid_str_comune &&
contact.value.profile.resid_str_comune !== '' &&
contact.value.profile.resid_str_comune !== '0'
: false;
},
checkOkReal: function (): boolean {
return this.checkOk();
},
icon: 'house',
icon: 'fas fa-map-marker-alt',
required: true,
}));
@@ -215,7 +231,7 @@ export default defineComponent({
}
return false;
},
icon: 'img: /images/1ris_rosso_100.png',
icon: 'flag-icon flag-icon-it',
required: false,
}));
@@ -233,6 +249,14 @@ export default defineComponent({
step: 0,
});
// Step 2: Comune
steps.push({
key: 'comune',
name: 'Comune di Residenza',
completed: stepResidence.value.checkOk(),
step: STEP_CITY,
});
// Step 3: Circuito Locale (solo se disponibile)
steps.push({
key: 'circuit',
@@ -271,14 +295,43 @@ export default defineComponent({
badge: {
color: isTelegramVerified.value
? 'positive'
: (isTelegramSkipped.value
: isTelegramSkipped.value
? 'red'
: 'orange'),
: 'orange',
label: isTelegramVerified.value
? 'Fatto'
: (isTelegramSkipped.value
: isTelegramSkipped.value
? 'Saltato'
: 'Da fare'),
: 'Da fare',
},
},
{
key: 'comune',
visible: true,
disabled: false,
title: 'Comune Residenza',
description:
'Seleziona il tuo comune di residenza, o dove vivi abitualmente, per connetterti con la Community Locale.',
completed: stepResidence.value.checkOk(),
avatar: {
color: stepResidence.value.checkOk() ? 'positive' : 'primary',
icon: stepResidence.value.checkOk() ? 'check' : stepResidence.value.icon,
isImage: false,
},
caption: stepResidence.value.checkOk()
? 'Completato: ' + stepResidence.value.extratitle() + ' (' + strProv.value + ')'
: stepResidence.value.extratitle(),
badge: {
color: stepResidence.value.checkOkReal()
? 'positive'
: isSalta(STEP_CITY)
? 'red'
: 'orange',
label: stepResidence.value.checkOkReal()
? 'Fatto'
: isSalta(STEP_CITY)
? 'Saltato'
: 'Da fare',
},
},
{
@@ -286,12 +339,11 @@ export default defineComponent({
visible: true,
disabled: false,
title: 'Circuito RIS Locale',
description:
'Seleziona la tua provincia di residenza per connetterti con la community locale.',
description: 'Unisciti al circuito della tua zona',
completed: stepCircuit.value.checkOk(),
avatar: {
color: stepCircuit.value.checkOk() ? 'positive' : 'orange',
icon: stepCircuit.value.checkOk() ? 'check' : '',
color: stepCircuit.value.checkOk() ? 'positive' : 'primary',
icon: stepCircuit.value.checkOk() ? 'check' : stepCircuit.value.icon,
isImage: !stepCircuit.value.checkOk(),
imageSrc: '/images/1ris_rosso_100.png',
},
@@ -301,14 +353,14 @@ export default defineComponent({
badge: {
color: stepCircuit.value.checkOkReal()
? 'positive'
: (isSalta(STEP_CIRCUIT)
: isSalta(STEP_CIRCUIT)
? 'red'
: 'orange'),
: 'orange',
label: stepCircuit.value.checkOkReal()
? 'Fatto'
: (isSalta(STEP_CIRCUIT)
: isSalta(STEP_CIRCUIT)
? 'Saltato'
: 'Da fare'),
: 'Da fare',
},
},
{
@@ -321,7 +373,9 @@ export default defineComponent({
completed: stepCircuitItalia.value.checkOk(),
avatar: {
color: stepCircuitItalia.value.checkOk() ? 'positive' : 'grey-6',
icon: stepCircuitItalia.value.checkOk() ? 'check' : '',
icon: stepCircuitItalia.value.checkOk()
? 'check'
: stepCircuitItalia.value.icon,
isImage: !stepCircuitItalia.value.checkOk(),
imageSrc: '/images/1ris_rosso_100.png',
},
@@ -383,6 +437,7 @@ export default defineComponent({
const totalSteps = computed(() => {
let count = 0;
count++; // Telegram
count++; // Comune
count++; // Circuito Locale
// if (mycircuit.value)
if (circuititalia.value) count++; // Circuito Italia
@@ -392,6 +447,7 @@ export default defineComponent({
const completedSteps = computed(() => {
let count = 0;
if (isTelegramVerified.value) count++;
if (stepResidence.value.checkOk()) count++;
if (stepCircuit.value.checkOk()) count++;
if (stepCircuitItalia.value.checkOk()) count++;
return count;
@@ -712,18 +768,14 @@ export default defineComponent({
// TUTORIAL METHODS
// ========================================
const updateContact = () => {
if (!props.mycontact) {
contact.value = userStore.my;
} else {
contact.value = props.mycontact;
}
console.log('updateContact');
if (
contact.value &&
contact.value.profile &&
contact.value.profile.resid_province === '0'
contact.value.profile.resid_str_comune === '0'
) {
contact.value.profile.resid_province = '';
contact.value.profile.resid_str_comune = '';
}
// Trova il primo step non completato e aprilo
@@ -899,7 +951,10 @@ export default defineComponent({
userStore,
globalStore,
costanti,
strComune,
t,
updateContact,
strProv,
};
},
});

View File

@@ -1,6 +1,6 @@
<template>
<div
v-if="contact && !isProfileComplete && tools.isLogged()"
v-if="contact && (!isProfileComplete || showAlsoIfSkipped) && tools.isLogged()"
class="profile-completion-container"
>
<div class="completion-card">
@@ -176,21 +176,27 @@
/>
</div>
<template v-if="stepConfig.key === 'comune'">
<CMyFieldDb
:title="$t('reg.residency_city')"
table="users"
tablesel="cities"
mykey="profile"
mysubkey="resid_comune"
mysubkey_tosee="resid_str_comune"
fieldsel_tosee="comune"
label_trans="reg.resid_str_comune"
:useinput="false"
jointable="cities"
:pickup="true"
:type="costanti.FieldType.select_by_server"
:rec="contact"
@savedInDb="updateContact"
/>
</template>
<!-- Contenuto Circuito Locale -->
<template v-if="stepConfig.key === 'circuit'">
<CMySelectCity
:label="$t('reg.resid_province')"
table="users"
jointable="provinces"
v-model="contact.profile.resid_province"
myclass="modern-select"
:db_type="costanti.FieldType.string"
db_field="profile"
db_subfield="resid_province"
:db_id="contact._id"
:db_rec="contact"
/>
<div v-if="stepResidence.checkOk()">
<CMySelectCity
v-if="
@@ -323,7 +329,8 @@
</div>
</div>
</div>
</div>
<div v-if="tools.isLogged()">
<!-- Banners Extra -->
<q-banner
v-if="userstoverify?.length > 0 && showBanner_utenti_verif"

View File

@@ -119,9 +119,9 @@ $mobile-footer-height: 80px;
box-shadow: $shadow-sm;
@media (max-width: $mobile-breakpoint) {
padding: 6px 8px;
padding: 12px 8px;
border-radius: 0;
margin: 8px;
margin: 4px;
background: white;
}
}
@@ -840,4 +840,229 @@ $mobile-footer-height: 80px;
font-size: 1.25rem;
}
}
}
// ========================================
// DIALOG NOINVITO (Stile Moderno)
// ========================================
.noinvito-card {
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
border-radius: $border-radius;
box-shadow: $shadow-lg;
@media (max-width: $mobile-breakpoint) {
border-radius: 0;
}
}
.noinvito-header {
background: linear-gradient(135deg, $primary-color, $primary-dark);
color: white;
padding: 16px 20px;
@media (max-width: $mobile-breakpoint) {
padding: 14px 16px;
}
.text-h6 {
font-weight: 600;
font-size: 1.125rem;
@media (max-width: $mobile-breakpoint) {
font-size: 1rem;
}
}
.q-btn {
color: white;
&:hover {
background: rgba(255, 255, 255, 0.15);
}
}
}
.noinvito-content {
padding: 24px;
@media (max-width: $mobile-breakpoint) {
padding: 16px;
}
}
.info-box {
display: flex;
gap: 16px;
padding: 20px;
border-radius: $border-radius-sm;
margin-bottom: 20px;
transition: all $transition-speed ease;
position: relative;
overflow: hidden;
@media (max-width: $mobile-breakpoint) {
padding: 16px;
gap: 12px;
margin-bottom: 16px;
}
// Effetto luce scorrevole
&::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
transition: left 0.6s ease;
}
&:hover::before {
left: 100%;
}
.q-icon {
flex-shrink: 0;
margin-top: 2px;
}
p {
margin: 0;
line-height: 1.6;
}
&:last-child {
margin-bottom: 0;
}
}
.primary-info {
background: linear-gradient(135deg, rgba($primary-color, 0.08) 0%, rgba($primary-color, 0.04) 100%);
border: 2px solid rgba($primary-color, 0.2);
border-left: 4px solid $primary-color;
&:hover {
background: linear-gradient(135deg, rgba($primary-color, 0.12) 0%, rgba($primary-color, 0.06) 100%);
border-color: rgba($primary-color, 0.3);
box-shadow: 0 4px 16px rgba($primary-color, 0.15);
}
}
.secondary-info {
background: linear-gradient(135deg, rgba($accent-color, 0.08) 0%, rgba($accent-color, 0.04) 100%);
border: 2px solid rgba($accent-color, 0.2);
border-left: 4px solid $accent-color;
&:hover {
background: linear-gradient(135deg, rgba($accent-color, 0.12) 0%, rgba($accent-color, 0.06) 100%);
border-color: rgba($accent-color, 0.3);
box-shadow: 0 4px 16px rgba($accent-color, 0.15);
}
}
.invitation-types {
margin: 12px 0 0 0;
padding-left: 20px;
@media (max-width: $mobile-breakpoint) {
padding-left: 16px;
font-size: 0.9375rem;
}
li {
margin-bottom: 10px;
line-height: 1.6;
&:last-child {
margin-bottom: 0;
}
strong {
color: $primary-color;
font-weight: 600;
}
}
}
.noinvito-actions {
padding: 20px 24px 24px;
background: linear-gradient(to bottom, transparent 0%, rgba(0, 0, 0, 0.02) 100%);
flex-direction: column;
gap: 0;
@media (max-width: $mobile-breakpoint) {
padding: 16px;
}
.action-btn {
border-radius: $border-radius-sm;
font-weight: 500;
padding: 12px 24px;
transition: all $transition-speed cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
@media (max-width: $mobile-breakpoint) {
padding: 10px 20px;
font-size: 0.9375rem;
}
// Effetto ripple
&::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.3);
transform: translate(-50%, -50%);
transition: width 0.6s ease, height 0.6s ease;
}
&:hover {
transform: translateY(-2px);
box-shadow: $shadow-md;
&::before {
width: 300px;
height: 300px;
}
}
&:active {
transform: translateY(0);
}
// Bottone primario (Telegram)
&.q-btn--unelevated {
background: linear-gradient(135deg, $primary-color, $primary-dark);
&:hover {
background: linear-gradient(135deg, darken($primary-color, 5%), $primary-color);
box-shadow: 0 4px 16px rgba($primary-color, 0.4);
}
}
// Bottone outline (Email)
&.q-btn--outline {
&:hover {
background: linear-gradient(135deg, rgba($primary-color, 0.05), rgba($primary-color, 0.02));
}
}
.q-icon {
transition: transform $transition-speed ease;
}
&:hover .q-icon {
transform: scale(1.1) rotate(5deg);
}
}
.q-mb-sm {
margin-bottom: 12px !important;
}
}

View File

@@ -131,6 +131,7 @@ export default defineComponent({
const inputSurname = ref(<any>null);
const inputPassword = ref(<any>null);
const inputPassword2 = ref(<any>null);
const noinvito = ref(false);
const submitBtn = ref(<any>null); // AGGIUNGI QUESTA RIGA
@@ -559,6 +560,7 @@ export default defineComponent({
shared_consts,
isMobile,
submitBtn,
noinvito,
};
},
});

View File

@@ -2,7 +2,7 @@
<div class="signup-container">
<!-- Banner utente già loggato -->
<div
v-if="tools.isLogged() && tools.getUsername() && !collettivo"
v-if="tools.isLogged() && tools.getUsername() && !collettivo && !visureg"
class="already-logged"
>
<q-card class="success-card">
@@ -207,6 +207,19 @@
</template>
</q-input>
<div class="invitante-non-presente">
<q-btn
v-if="!signup.aportador_solidario"
dense
outline
color="primary"
label="Non hai l'invito?"
icon="description"
@click="noinvito = true"
class="policy-btn"
/>
</div>
<q-input
ref="inputEmail"
tabindex="2"
@@ -644,6 +657,94 @@
</q-card-section>
</q-card>
</q-dialog>
<q-dialog
v-model="noinvito"
maximized
>
<q-card class="noinvito-card">
<q-card-section class="row items-center q-pb-none noinvito-header">
<q-icon
name="info"
size="32px"
color="primary"
class="q-mr-sm"
/>
<div class="text-h6">Come entrare in RISO</div>
<q-space />
<q-btn
icon="close"
flat
round
dense
v-close-popup
/>
</q-card-section>
<q-card-section class="noinvito-content">
<!-- Spiegazione principale -->
<div class="info-box primary-info">
<q-icon
name="how_to_reg"
size="24px"
color="primary"
/>
<div>
<p class="text-weight-medium q-mb-sm">Per accedere a RISO hai bisogno di un invito</p>
<p class="text-body2">
L'invito può essere di due tipi:
</p>
<ul class="invitation-types">
<li>
<strong>Username dell'invitante:</strong> inserisci lo username di chi ti ha parlato di RISO
</li>
<li>
<strong>Link di registrazione:</strong> usa il link personale che ti è stato inviato via email o messaggio
</li>
</ul>
</div>
</div>
<!-- Box informativo secondario -->
<div class="info-box secondary-info">
<q-icon
name="groups"
size="24px"
color="secondary"
/>
<div>
<p class="text-weight-medium q-mb-sm">Non conosci nessuno di RISO?</p>
<p class="text-body2">
Nessun problema! Puoi unirti alla comunità attraverso i nostri gruppi territoriali su Telegram
oppure contattarci direttamente via email. Saremo felici di darti il benvenuto! 🌱
</p>
</div>
</div>
</q-card-section>
<!-- Footer con bottoni azione -->
<q-card-actions class="noinvito-actions">
<q-btn
unelevated
color="primary"
icon="telegram"
label="Gruppi Telegram Territoriali"
:href="tools.getLinkGruppiTerritorialiTelegram() ? tools.getLinkGruppiTerritorialiTelegram() : ''"
target="_blank"
class="action-btn full-width q-mb-sm"
no-caps
/>
<q-btn
outline
color="primary"
icon="email"
label="Contattaci via Email"
:href="'mailto:' + (tools.getEmailSupport() || '')"
class="action-btn full-width"
no-caps
/>
</q-card-actions>
</q-card>
</q-dialog>
</div>
</template>

View File

@@ -1,5 +1,8 @@
<template>
<div v-if="tools.isLogged()" class="q-gutter-sm q-pa-xs q-pb-md">
<div
v-if="tools.isLogged()"
class="q-gutter-sm q-pa-xs q-pb-md"
>
<CTitleBanner
class="q-pa-xs"
:title="$t('pages.profile')"
@@ -141,22 +144,22 @@
>
</CMyFieldDb>
<!--
<CMyFieldDb
v-if="myuser"
:title="$t('reg.residency_city')"
table="users"
tablesel="cities"
mykey="profile"
mysubkey="born_city_id"
mysubkey="resid_comune"
mysubkey_tosee="resid_str_comune"
fieldsel_tosee="comune"
label_trans="reg.resid_str_comune"
:useinput="false"
jointable="cities"
:pickup="true"
:type="costanti.FieldType.select_by_server"
:rec="myuser"
/>
-->
<CMyFieldDb
:title="$t('reg.dateofbirth')"
table="users"
@@ -165,7 +168,7 @@
:type="costanti.FieldType.date"
>
</CMyFieldDb>
<CMySelectCity
<!--<CMySelectCity
:label="$t('reg.resid_province')"
table="users"
jointable="provinces"
@@ -177,13 +180,9 @@
:db_id="userStore.my._id"
:db_rec="userStore.my"
>
</CMySelectCity>
</CMySelectCity>-->
<CMySelectCity
v-if="
globalStore.isPresenteCardsByProv(
userStore.my.profile.resid_province
)
"
v-if="globalStore.isPresenteCardsByProv(userStore.my.profile.resid_province)"
:label="$t('reg.resid_card')"
table="users"
jointable="cards"
@@ -367,14 +366,12 @@
</div>
</template>
<script lang="ts" src="./editprofile.ts">
</script>
<script lang="ts" src="./editprofile.ts"></script>
<style lang="scss" scoped>
@import './editprofile.scss';
</style>
<!--<CMyFieldDb :title="$t('reg.username_telegram')"
table="users"
mykey="profile"