- aggiornati form registrazione
- Login - Password dimenticata - Aggiorna password. - Email registrazione - Ammetti Utente
This commit is contained in:
@@ -22,6 +22,7 @@ const msg_website_it = {
|
||||
myhosps2: 'myhosps2',
|
||||
mygood2: 'mygood2',
|
||||
InvitoReg: 'Invito',
|
||||
Ammetti: 'Ammetti',
|
||||
installaApp: 'Installa App',
|
||||
fundraising: 'Sostieni il Progetto',
|
||||
notifs: 'Configura le Notifiche',
|
||||
@@ -45,7 +46,7 @@ const msg_website_it = {
|
||||
presentazione: 'Presentazione',
|
||||
presentazione2: 'Presentazione',
|
||||
invita: 'Invita Persone',
|
||||
SignUp: 'Modulo di Registrazione',
|
||||
SignUp: 'Crea il tuo account',
|
||||
SignUpCollettivo: 'Reg. Collettiva:',
|
||||
SignUpCollettivo2: 'Registrazione Collettiva:',
|
||||
need_Telegram: 'Per poter utilizzare la Piattaforma occorre avere <a href="https://play.google.com/store/apps/details?id=org.telegram.messenger" target="_blank">Telegram</a> installato<br>',
|
||||
|
||||
@@ -0,0 +1,667 @@
|
||||
// ========================================
|
||||
// VARIABILI (Sincronizzate con CSignUp)
|
||||
// ========================================
|
||||
$primary-color: #1976d2;
|
||||
$primary-light: #42a5f5;
|
||||
$primary-dark: #1565c0;
|
||||
$accent-color: #26a69a;
|
||||
$positive-color: #21ba45;
|
||||
$negative-color: #c10015;
|
||||
$info-color: #31ccec;
|
||||
|
||||
$border-radius: 16px;
|
||||
$border-radius-sm: 12px;
|
||||
$border-radius-lg: 24px;
|
||||
|
||||
$transition-speed: 0.3s;
|
||||
$shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
$shadow-md: 0 4px 16px rgba(0, 0, 0, 0.12);
|
||||
$shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.16);
|
||||
|
||||
$mobile-breakpoint: 768px;
|
||||
|
||||
// ========================================
|
||||
// CONTAINER PRINCIPALE
|
||||
// ========================================
|
||||
.registration-container {
|
||||
width: 100%;
|
||||
min-height: 60vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 6px;
|
||||
min-height: 100vh;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// BOTTONE INIZIALE
|
||||
// ========================================
|
||||
.start-button-wrapper {
|
||||
text-align: center;
|
||||
animation: fadeInUp 0.6s ease;
|
||||
}
|
||||
|
||||
.start-btn {
|
||||
min-width: 200px;
|
||||
height: 56px;
|
||||
border-radius: $border-radius;
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
text-transform: none;
|
||||
box-shadow: $shadow-lg;
|
||||
background: linear-gradient(135deg, $primary-color, $primary-light);
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 12px 40px rgba(25, 118, 210, 0.4);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
min-width: 180px;
|
||||
height: 52px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// CARD PRINCIPALE
|
||||
// ========================================
|
||||
.registration-card {
|
||||
width: 100%;
|
||||
max-width: 700px;
|
||||
border-radius: $border-radius-lg;
|
||||
box-shadow: $shadow-lg;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
animation: fadeInUp 0.6s ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
max-width: 100%;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// CAROUSEL
|
||||
// ========================================
|
||||
.modern-carousel {
|
||||
background: transparent;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
height: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
.carousel-slide {
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// SLIDE CONTENT
|
||||
// ========================================
|
||||
.slide-content {
|
||||
width: 100%;
|
||||
padding: 10px 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
animation: fadeIn 0.4s ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 10px 8px;
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.slide-icon-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, rgba(25, 118, 210, 0.1), rgba(38, 166, 154, 0.1));
|
||||
margin-bottom: 8px;
|
||||
animation: scaleIn 0.6s ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
|
||||
.q-icon {
|
||||
font-size: 48px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slide-title {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
line-height: 1.3;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 1.375rem;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// ACTION BUTTONS (Yes/No)
|
||||
// ========================================
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
gap: 12px;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
border-radius: $border-radius;
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
text-transform: none;
|
||||
box-shadow: $shadow-md;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: $shadow-lg;
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
height: 52px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.yes-btn {
|
||||
background: linear-gradient(135deg, $positive-color, #26a69a);
|
||||
}
|
||||
|
||||
.no-btn {
|
||||
background: linear-gradient(135deg, $negative-color, #e91e63);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LINKS LIST
|
||||
// ========================================
|
||||
.links-list {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.link-item {
|
||||
background: linear-gradient(to right, rgba(25, 118, 210, 0.05), transparent);
|
||||
border-radius: $border-radius-sm;
|
||||
padding: 12px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateX(4px);
|
||||
box-shadow: $shadow-sm;
|
||||
background: linear-gradient(to right, rgba(25, 118, 210, 0.1), transparent);
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-link {
|
||||
margin-top: 16px;
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
margin-top: 12px;
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-link-text {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: $primary-color;
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
&:hover {
|
||||
color: $primary-dark;
|
||||
transform: translateX(4px);
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// NO INVITED CONTENT
|
||||
// ========================================
|
||||
.no-invited-content {
|
||||
width: 100%;
|
||||
max-width: 550px;
|
||||
}
|
||||
|
||||
.instructions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
margin-top: 24px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
gap: 16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.instruction-item {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: flex-start;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
gap: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.instruction-number {
|
||||
flex-shrink: 0;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, $primary-color, $accent-color);
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
box-shadow: $shadow-sm;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
}
|
||||
|
||||
.instruction-content {
|
||||
flex: 1;
|
||||
|
||||
p {
|
||||
margin: 0 0 12px;
|
||||
font-size: 1rem;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.9375rem;
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.instruction-note {
|
||||
font-size: 0.9375rem;
|
||||
color: #666;
|
||||
font-style: italic;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
}
|
||||
|
||||
.telegram-btn {
|
||||
margin-top: 12px;
|
||||
border-radius: $border-radius-sm;
|
||||
text-transform: none;
|
||||
font-weight: 600;
|
||||
box-shadow: $shadow-sm;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: $shadow-md;
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
margin-top: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// WITH INVITED CONTENT
|
||||
// ========================================
|
||||
.with-invited-content {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.registration-options {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
margin-top: 24px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
gap: 16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.option-btn {
|
||||
width: 100%;
|
||||
height: 64px;
|
||||
border-radius: $border-radius;
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
text-transform: none;
|
||||
box-shadow: $shadow-md;
|
||||
transition: all $transition-speed ease;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: $shadow-lg;
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
height: 76px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.telegram-option {
|
||||
background: linear-gradient(135deg, $primary-color, $primary-light);
|
||||
}
|
||||
|
||||
.email-option {
|
||||
border-width: 2px;
|
||||
|
||||
&:hover {
|
||||
background: rgba(25, 118, 210, 0.08);
|
||||
}
|
||||
}
|
||||
|
||||
.recommended-badge {
|
||||
top: -8px;
|
||||
right: -8px;
|
||||
padding: 4px 12px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
border-radius: 12px;
|
||||
box-shadow: $shadow-sm;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.6875rem;
|
||||
padding: 3px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
margin: 8px 0;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: calc(50% - 40px);
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, rgba(0, 0, 0, 0.12));
|
||||
}
|
||||
|
||||
&::before {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&::after {
|
||||
right: 0;
|
||||
background: linear-gradient(to left, transparent, rgba(0, 0, 0, 0.12));
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
padding: 4px 12px;
|
||||
background: white;
|
||||
color: #666;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// SINGLE REGISTRATION
|
||||
// ========================================
|
||||
.single-registration {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-top: 24px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
margin-top: 16px;
|
||||
gap: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.registration-text {
|
||||
font-size: 1.125rem;
|
||||
color: #666;
|
||||
margin: 0;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.register-btn {
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
height: 56px;
|
||||
border-radius: $border-radius;
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
text-transform: none;
|
||||
background: linear-gradient(135deg, $primary-color, $primary-light);
|
||||
box-shadow: $shadow-md;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: $shadow-lg;
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
max-width: 100%;
|
||||
height: 52px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// BACK BUTTON
|
||||
// ========================================
|
||||
.back-btn {
|
||||
margin-top: 24px;
|
||||
border-radius: $border-radius-sm;
|
||||
text-transform: none;
|
||||
font-weight: 500;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
margin-top: 16px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// NAVIGATION DOTS
|
||||
// ========================================
|
||||
.navigation-dots {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 16px;
|
||||
background: linear-gradient(to top, rgba(0, 0, 0, 0.02), transparent);
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 12px;
|
||||
gap: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background: #d0d0d0;
|
||||
cursor: pointer;
|
||||
transition: all $transition-speed ease;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
|
||||
&.visible {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
&.active {
|
||||
width: 24px;
|
||||
border-radius: 5px;
|
||||
background: $primary-color;
|
||||
}
|
||||
|
||||
&:hover:not(.active) {
|
||||
background: #a0a0a0;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
|
||||
&.active {
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// ANIMAZIONI
|
||||
// ========================================
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scaleIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// RESPONSIVE UTILITIES
|
||||
// ========================================
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
// Fix per iOS Safari
|
||||
.registration-container {
|
||||
min-height: -webkit-fill-available;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// UTILITY CLASSES (Legacy)
|
||||
// ========================================
|
||||
.centermydiv2 {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dialog_card {
|
||||
background: white;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
|
||||
.my-custom-border {
|
||||
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||
border-radius: $border-radius-sm;
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { useQuasar } from 'quasar'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { CContactUser } from '@src/components/CContactUser'
|
||||
import { CMyUser } from '@src/components/CMyUser'
|
||||
import { Logo } from '@src/components/logo'
|
||||
import { DefaultProfile, useUserStore } from '@store/UserStore'
|
||||
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
@@ -14,7 +15,7 @@ import { useGlobalStore } from '@store/globalStore'
|
||||
export default defineComponent({
|
||||
name: 'CRegistration',
|
||||
emits: ['regEventEmail'],
|
||||
components: { CMyUser, CContactUser },
|
||||
components: { CMyUser, CContactUser, Logo },
|
||||
props: {
|
||||
slide: {
|
||||
type: String,
|
||||
@@ -57,14 +58,18 @@ export default defineComponent({
|
||||
|
||||
const actionType = ref(costanti.ACTIONTYPE.LINK_REG)
|
||||
|
||||
function clickToRegister() {
|
||||
// Responsive detection
|
||||
const isMobile = ref(false)
|
||||
const checkMobile = () => {
|
||||
isMobile.value = window.innerWidth <= 768
|
||||
}
|
||||
|
||||
function clickToRegister() {
|
||||
//if (site.value.confpages.enableRegByBot) {
|
||||
//$router.push('/bot')
|
||||
//} else {
|
||||
$router.push('/registrati/' + tools.getInvitante())
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
function mounted() {
|
||||
@@ -76,6 +81,10 @@ export default defineComponent({
|
||||
chooseReg.value = true
|
||||
slide.value = 'second'
|
||||
}
|
||||
|
||||
// Check mobile on mount
|
||||
checkMobile()
|
||||
window.addEventListener('resize', checkMobile)
|
||||
}
|
||||
|
||||
function regEventEmail() {
|
||||
@@ -91,16 +100,29 @@ export default defineComponent({
|
||||
|
||||
if (invitante) {
|
||||
start.value = true
|
||||
slide.value = 'second';
|
||||
noInvited.value = false;
|
||||
chooseReg.value = true;
|
||||
slide.value = 'second'
|
||||
noInvited.value = false
|
||||
chooseReg.value = true
|
||||
} else {
|
||||
start.value = true
|
||||
}
|
||||
}
|
||||
|
||||
// Determina se mostrare un dot specifico
|
||||
function shouldShowDot(slideName: string) {
|
||||
// Non mostrare 'sceglilink' se non ci sono link
|
||||
if (slideName === 'sceglilink' && listlinksreg.value.length === 0) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
onMounted(mounted)
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', checkMobile)
|
||||
})
|
||||
|
||||
return {
|
||||
tools,
|
||||
site,
|
||||
@@ -115,6 +137,8 @@ export default defineComponent({
|
||||
listlinksreg,
|
||||
actionType,
|
||||
t,
|
||||
isMobile,
|
||||
shouldShowDot,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,223 +1,275 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="site.confpages?.enableReg"
|
||||
class="row q-ma-sm centermydiv2 q-pa-sm justify-center align-center"
|
||||
class="registration-container"
|
||||
>
|
||||
<div v-if="!start">
|
||||
<!-- Bottone Iniziale -->
|
||||
<div
|
||||
v-if="!start"
|
||||
class="start-button-wrapper"
|
||||
>
|
||||
<q-btn
|
||||
rounded
|
||||
glossy
|
||||
icon="fas fa-user-plus"
|
||||
size="md"
|
||||
unelevated
|
||||
size="lg"
|
||||
color="primary"
|
||||
icon="person_add"
|
||||
@click="buttRegistrati()"
|
||||
:label="$t('reg.submit')"
|
||||
>
|
||||
</q-btn>
|
||||
class="start-btn"
|
||||
/>
|
||||
</div>
|
||||
<q-carousel
|
||||
|
||||
<!-- Carousel Registrazione -->
|
||||
<q-card
|
||||
v-if="start"
|
||||
v-model="slide"
|
||||
transition-prev="scale"
|
||||
transition-next="scale"
|
||||
animated
|
||||
control-color="white"
|
||||
navigation
|
||||
padding
|
||||
height="500px"
|
||||
:class="`text-white bg-primary shadow-1 rounded-borders`"
|
||||
class="registration-card"
|
||||
>
|
||||
<q-carousel-slide
|
||||
name="start"
|
||||
class="column no-wrap flex-center"
|
||||
<q-carousel
|
||||
v-model="slide"
|
||||
transition-prev="slide-right"
|
||||
transition-next="slide-left"
|
||||
animated
|
||||
swipeable
|
||||
class="modern-carousel"
|
||||
:height="isMobile ? 'auto' : '500px'"
|
||||
>
|
||||
<q-icon
|
||||
name="fas fa-user-plus"
|
||||
size="56px"
|
||||
/>
|
||||
<div class="q-mt-md text-center">
|
||||
<span class="text-h6 text-white"> {{ t('reg.invitante') }}</span>
|
||||
<q-card class="dialog_card q-mb-lg">
|
||||
<q-card-section class="column q-ma-sm q-pa-sm q-col-gutter-sm">
|
||||
<!-- Slide 1: Hai un Invitante? -->
|
||||
<q-carousel-slide
|
||||
name="start"
|
||||
class="carousel-slide"
|
||||
>
|
||||
<div class="slide-content">
|
||||
<div class="slide-icon-wrapper">
|
||||
<q-icon
|
||||
name="person_add"
|
||||
size="64px"
|
||||
color="primary"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<h2 class="slide-title">{{ t('reg.invitante') }}</h2>
|
||||
|
||||
<div class="action-buttons">
|
||||
<q-btn
|
||||
rounded
|
||||
glossy
|
||||
unelevated
|
||||
size="lg"
|
||||
color="positive"
|
||||
icon="check"
|
||||
@click="
|
||||
listlinksreg.length > 0 ? (slide = 'sceglilink') : (slide = 'second');
|
||||
noInvited = false;
|
||||
chooseReg = true;
|
||||
"
|
||||
:label="$t('dialog.yes')"
|
||||
>
|
||||
</q-btn>
|
||||
class="action-btn yes-btn"
|
||||
/>
|
||||
|
||||
<q-btn
|
||||
rounded
|
||||
glossy
|
||||
unelevated
|
||||
size="lg"
|
||||
color="negative"
|
||||
icon="close"
|
||||
@click="
|
||||
slide = 'second';
|
||||
noInvited = true;
|
||||
chooseReg = false;
|
||||
"
|
||||
:label="$t('dialog.no')"
|
||||
class="action-btn no-btn"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-carousel-slide>
|
||||
|
||||
<!-- Slide 2: Scegli Link (se disponibile) -->
|
||||
<q-carousel-slide
|
||||
name="sceglilink"
|
||||
class="carousel-slide"
|
||||
>
|
||||
<div class="slide-content">
|
||||
<h2 class="slide-title">{{ t('reg.title_reg_con_link') }}</h2>
|
||||
|
||||
<div class="links-list">
|
||||
<div
|
||||
v-for="(rec, i) in listlinksreg"
|
||||
:key="i"
|
||||
class="link-item"
|
||||
>
|
||||
</q-btn>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
</q-carousel-slide>
|
||||
<q-carousel-slide name="sceglilink">
|
||||
<q-card class="dialog_card q-mb-lg">
|
||||
<div class="q-ma-sm q-pa-sm text-h6 text-blue text-bold">{{ t('reg.title_reg_con_link') }}</div>
|
||||
<q-card-section class="column q-ma-sm q-pa-sm q-col-gutter-sm text-black">
|
||||
<div
|
||||
v-for="(rec, i) in listlinksreg"
|
||||
:key="i"
|
||||
>
|
||||
<div class="q-pa-xs q-ma-xs q-border q-rounded my-custom-border">
|
||||
<CMyUser
|
||||
:mycontact="rec"
|
||||
:visu="costanti.FIND_PEOPLE"
|
||||
@setCmd="tools.setCmd"
|
||||
:actionType="actionType"
|
||||
:hideellipses="true"
|
||||
>
|
||||
</CMyUser>
|
||||
<!--<CContactUser
|
||||
:myuser="rec"
|
||||
:showBtnActivities="false"
|
||||
:sendRIS="false"
|
||||
:actionType="actionType"
|
||||
/>
|
||||
</div>-->
|
||||
</div>
|
||||
|
||||
<div class="q-ma-md q-pa-md">
|
||||
<div class="custom-link">
|
||||
<a
|
||||
href="/registrati"
|
||||
target="_blank"
|
||||
>👉🏻 {{ t('reg.scelgo_l_invitante') }}</a
|
||||
class="custom-link-text"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<q-btn
|
||||
rounded
|
||||
glossy
|
||||
size="md"
|
||||
color="primary"
|
||||
@click="slide = 'start'"
|
||||
:label="$t('dialog.indietro')"
|
||||
>
|
||||
</q-btn>
|
||||
<q-icon
|
||||
name="arrow_forward"
|
||||
size="20px"
|
||||
/>
|
||||
{{ t('reg.scelgo_l_invitante') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-carousel-slide>
|
||||
<q-carousel-slide name="second">
|
||||
<div
|
||||
v-if="noInvited"
|
||||
class="text-h7"
|
||||
>
|
||||
<div class="text-center text-bold text-h6">Se ancora non sei stato invitato:</div>
|
||||
<br />
|
||||
1️⃣ 👉🏻 Entra nei gruppi Territoriali su Telegram:<br />
|
||||
<div class="text-center">
|
||||
<q-btn
|
||||
type="a"
|
||||
rounded
|
||||
icon="fab fa-telegram"
|
||||
color="positive"
|
||||
href="https://t.me/riso_canale/3"
|
||||
target="_blank"
|
||||
label="Progetto RISO"
|
||||
>
|
||||
</q-btn>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
2️⃣ 👉🏻 sul post del canale fissato in alto, troverai tutte le info sul progetto e su come entrare nel gruppo
|
||||
della tua provincia.<br />
|
||||
Potrai cosi richiedere il link una volta entrato nella chat di gruppo.<br />
|
||||
</div>
|
||||
<div v-else-if="chooseReg">
|
||||
<div class="row justify-center items-center">
|
||||
<q-icon
|
||||
name="fas fa-user-plus"
|
||||
size="27px"
|
||||
class="q-mx-md"
|
||||
<q-btn
|
||||
flat
|
||||
color="grey-7"
|
||||
icon="arrow_back"
|
||||
@click="slide = 'start'"
|
||||
:label="$t('dialog.indietro')"
|
||||
class="back-btn"
|
||||
/>
|
||||
<span class="text-h6 text-white"> {{ t('reg.page_title') }}</span>
|
||||
<q-card class="q-mt-sm dialog_card q-mb-sm">
|
||||
<q-card-section>
|
||||
<div
|
||||
v-if="site.confpages?.enableRegMultiChoice"
|
||||
style=""
|
||||
class="column q-ma-sm centermydiv2 q-pa-sm justify-center"
|
||||
>
|
||||
<q-btn
|
||||
rounded
|
||||
type="a"
|
||||
class="col-xs-12 col-sm-6 flex-item-btn items-center q-my-md"
|
||||
icon="fab fa-telegram"
|
||||
size="md"
|
||||
color="primary"
|
||||
:href="invited ? tools.getLinkBotTelegram(invited, regexpire) : `/bot`"
|
||||
:label="$t('reg.bytelegram')"
|
||||
>
|
||||
<q-badge
|
||||
color="red"
|
||||
align="bottom"
|
||||
floating
|
||||
>Consigliato</q-badge
|
||||
>
|
||||
</q-btn>
|
||||
<br />
|
||||
<div :class="$q.dark.isActive ? `text-white` : `text-black` + ` col-12 text-center`">
|
||||
<div class="bg-grey-4">
|
||||
<br />
|
||||
se non hai Telegram puoi registrarti con solo l'email ma
|
||||
<span style="text-decoration: underline">non potrai contattare gli iscritti</span>.
|
||||
<q-btn
|
||||
rounded
|
||||
class="flex-item-btn col-xs-12 col-sm-6"
|
||||
outline
|
||||
icon="fas fa-envelope"
|
||||
size="0.75rem"
|
||||
:color="$q.dark.isActive ? `black` : `white`"
|
||||
:text-color="$q.dark.isActive ? `white` : `black`"
|
||||
@click="regEventEmail"
|
||||
:label="$t('reg.byemail')"
|
||||
>
|
||||
</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
</q-carousel-slide>
|
||||
|
||||
<!-- Slide 3: Scelta Registrazione -->
|
||||
<q-carousel-slide
|
||||
name="second"
|
||||
class="carousel-slide"
|
||||
>
|
||||
<div class="slide-content">
|
||||
<!-- Caso: Non Invitato -->
|
||||
<div
|
||||
v-if="noInvited"
|
||||
class="no-invited-content"
|
||||
>
|
||||
<div class="slide-icon-wrapper">
|
||||
<q-icon
|
||||
name="info"
|
||||
size="56px"
|
||||
color="info"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<h2 class="slide-title">Se ancora non sei stato invitato:</h2>
|
||||
|
||||
<div class="instructions">
|
||||
<div class="instruction-item">
|
||||
<div class="instruction-number">1</div>
|
||||
<div class="instruction-content">
|
||||
<p>Entra nei gruppi Territoriali su Telegram</p>
|
||||
<q-btn
|
||||
unelevated
|
||||
color="positive"
|
||||
icon="fab fa-telegram"
|
||||
href="https://t.me/riso_canale/3"
|
||||
target="_blank"
|
||||
label="Progetto RISO"
|
||||
class="telegram-btn"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
style="margin-top: 10px; text-align: center"
|
||||
>
|
||||
Registrati<br />
|
||||
<q-btn
|
||||
rounded
|
||||
size="md"
|
||||
color="primary"
|
||||
@click="clickToRegister"
|
||||
:label="$t('reg.submit')"
|
||||
>
|
||||
</q-btn>
|
||||
|
||||
<div class="instruction-item">
|
||||
<div class="instruction-number">2</div>
|
||||
<div class="instruction-content">
|
||||
<p>
|
||||
Sul post del canale fissato in alto, troverai tutte le info sul
|
||||
progetto e su come entrare nel gruppo della tua provincia.
|
||||
</p>
|
||||
<p class="instruction-note">
|
||||
Potrai così richiedere il link una volta entrato nella chat di
|
||||
gruppo.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Caso: Con Invitante -->
|
||||
<div
|
||||
v-else-if="chooseReg"
|
||||
class="with-invited-content"
|
||||
>
|
||||
<div class="flex justify-center">
|
||||
<logo
|
||||
class="signup-logo "
|
||||
mystyle="width: 50px !important; height: 50px !important;"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Multi Choice: Telegram vs Email -->
|
||||
<div
|
||||
v-if="site.confpages?.enableRegMultiChoice"
|
||||
class="registration-options"
|
||||
>
|
||||
<q-btn
|
||||
unelevated
|
||||
size="lg"
|
||||
color="primary"
|
||||
icon="fab fa-telegram"
|
||||
type="a"
|
||||
:href="invited ? tools.getLinkBotTelegram(invited, regexpire) : `/bot`"
|
||||
:label="$t('reg.bytelegram')"
|
||||
class="option-btn telegram-option"
|
||||
>
|
||||
<q-badge
|
||||
color="positive"
|
||||
floating
|
||||
class="recommended-badge"
|
||||
>
|
||||
Consigliato
|
||||
</q-badge>
|
||||
</q-btn>
|
||||
|
||||
<div class="divider">
|
||||
<span>oppure</span>
|
||||
</div>
|
||||
|
||||
<q-btn
|
||||
outline
|
||||
size="lg"
|
||||
color="primary"
|
||||
icon="email"
|
||||
@click="regEventEmail"
|
||||
:label="$t('reg.byemail')"
|
||||
class="option-btn email-option"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Single Choice: Solo Registrati -->
|
||||
<div
|
||||
v-else
|
||||
class="single-registration"
|
||||
>
|
||||
<p class="registration-text">Registrati</p>
|
||||
<q-btn
|
||||
unelevated
|
||||
size="lg"
|
||||
color="primary"
|
||||
icon="person_add"
|
||||
@click="clickToRegister"
|
||||
:label="$t('reg.submit')"
|
||||
class="register-btn"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-carousel-slide>
|
||||
</q-carousel>
|
||||
</q-carousel-slide>
|
||||
</q-carousel>
|
||||
|
||||
<!-- Navigation Indicators -->
|
||||
<div
|
||||
v-if="start"
|
||||
class="navigation-dots"
|
||||
>
|
||||
<div
|
||||
v-for="(s, i) in ['start', 'sceglilink', 'second']"
|
||||
:key="i"
|
||||
class="nav-dot"
|
||||
:class="{ active: slide === s, visible: shouldShowDot(s) }"
|
||||
@click="slide = s"
|
||||
></div>
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,5 +1,414 @@
|
||||
// ========================================
|
||||
// VARIABILI (Sincronizzate con CSignUp)
|
||||
// ========================================
|
||||
$primary-color: #1976d2;
|
||||
$primary-light: #42a5f5;
|
||||
$primary-dark: #1565c0;
|
||||
$accent-color: #26a69a;
|
||||
$positive-color: #21ba45;
|
||||
$negative-color: #c10015;
|
||||
|
||||
$border-radius: 16px;
|
||||
$border-radius-sm: 12px;
|
||||
$border-radius-lg: 24px;
|
||||
|
||||
$transition-speed: 0.3s;
|
||||
$shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
$shadow-md: 0 4px 16px rgba(0, 0, 0, 0.12);
|
||||
$shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.16);
|
||||
|
||||
$mobile-breakpoint: 768px;
|
||||
|
||||
// ========================================
|
||||
// CONTAINER PRINCIPALE
|
||||
// ========================================
|
||||
.signin-container {
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
background-attachment: fixed;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 12px;
|
||||
align-items: flex-start;
|
||||
padding-top: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// PWA CHECK
|
||||
// ========================================
|
||||
.pwa-check {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
z-index: 10;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// CARD PRINCIPALE
|
||||
// ========================================
|
||||
.signin-card {
|
||||
width: 100%;
|
||||
max-width: 450px;
|
||||
border-radius: $border-radius-lg;
|
||||
box-shadow: $shadow-lg;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
animation: fadeInUp 0.6s ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
max-width: 100%;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// HEADER
|
||||
// ========================================
|
||||
.signin-header {
|
||||
text-align: center;
|
||||
padding: 32px 24px 24px;
|
||||
background: linear-gradient(to bottom, rgba(103, 126, 234, 0.05), transparent);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 24px 16px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.signin-logo {
|
||||
margin: 0 auto 16px;
|
||||
animation: scaleIn 0.6s ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
margin: 0 auto 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.signin-title {
|
||||
font-size: 2rem;
|
||||
font-weight: 600;
|
||||
margin: 0 0 8px;
|
||||
background: linear-gradient(135deg, $primary-color, $accent-color);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 1.5rem;
|
||||
margin: 0 0 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.signin-subtitle {
|
||||
font-size: 1rem;
|
||||
color: #666;
|
||||
margin: 0;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// FORM
|
||||
// ========================================
|
||||
.signin-form {
|
||||
padding: 32px 24px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// INPUT FIELDS
|
||||
// ========================================
|
||||
.modern-input {
|
||||
:deep(.q-field__control) {
|
||||
border-radius: $border-radius-sm;
|
||||
min-height: 56px;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
min-height: 52px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
&:before {
|
||||
border-color: rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
&:hover:before {
|
||||
border-color: $primary-light;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.q-field__label) {
|
||||
font-size: 1rem;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.9375rem;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.q-field__prepend) {
|
||||
.q-icon {
|
||||
font-size: 24px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.q-field--focused {
|
||||
:deep(.q-field__control) {
|
||||
box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
&.q-field--error {
|
||||
animation: shake 0.4s ease;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// SUBMIT BUTTON
|
||||
// ========================================
|
||||
.submit-btn {
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
border-radius: $border-radius;
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
text-transform: none;
|
||||
background: linear-gradient(135deg, $primary-color, $primary-light);
|
||||
box-shadow: $shadow-md;
|
||||
transition: all $transition-speed ease;
|
||||
margin-top: 8px;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: $shadow-lg;
|
||||
background: linear-gradient(135deg, $primary-dark, $primary-color);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
height: 52px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// FORGOT PASSWORD
|
||||
// ========================================
|
||||
.forgot-password {
|
||||
text-align: center;
|
||||
margin-top: -8px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
margin-top: -4px;
|
||||
}
|
||||
}
|
||||
|
||||
.forgot-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
font-size: 0.9375rem;
|
||||
transition: all $transition-speed ease;
|
||||
padding: 8px 12px;
|
||||
border-radius: $border-radius-sm;
|
||||
|
||||
&:hover {
|
||||
color: $primary-color;
|
||||
background: rgba(25, 118, 210, 0.06);
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.875rem;
|
||||
padding: 6px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// DIVIDER
|
||||
// ========================================
|
||||
.divider {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
margin: 8px 0;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: calc(50% - 80px);
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, rgba(0, 0, 0, 0.12));
|
||||
}
|
||||
|
||||
&::before {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&::after {
|
||||
right: 0;
|
||||
background: linear-gradient(to left, transparent, rgba(0, 0, 0, 0.12));
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
padding: 4px 16px;
|
||||
background: white;
|
||||
color: #666;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.8125rem;
|
||||
padding: 3px 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// REGISTRATION SECTION
|
||||
// ========================================
|
||||
.register-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 16px;
|
||||
background: linear-gradient(to bottom, rgba(33, 186, 69, 0.05), transparent);
|
||||
border-radius: $border-radius;
|
||||
border: 1px solid rgba(33, 186, 69, 0.15);
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 12px;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.register-text {
|
||||
margin: 0;
|
||||
font-size: 0.9375rem;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
}
|
||||
|
||||
.register-btn {
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
height: 52px;
|
||||
border-radius: $border-radius;
|
||||
font-size: 1.0625rem;
|
||||
font-weight: 600;
|
||||
text-transform: none;
|
||||
background: linear-gradient(135deg, $positive-color, #26a69a);
|
||||
box-shadow: $shadow-sm;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: $shadow-md;
|
||||
background: linear-gradient(135deg, #1e8e3e, $positive-color);
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
max-width: 100%;
|
||||
height: 48px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// ANIMAZIONI
|
||||
// ========================================
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scaleIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
0%, 100% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
25% {
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
75% {
|
||||
transform: translateX(10px);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// RESPONSIVE UTILITIES
|
||||
// ========================================
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
// Fix per iOS Safari
|
||||
.signin-container {
|
||||
min-height: -webkit-fill-available;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LEGACY CLASS (per compatibilità)
|
||||
// ========================================
|
||||
.signin {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
max-width: 450px;
|
||||
}
|
||||
}
|
||||
@@ -1,127 +1,151 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="enablePwa"><CCheckAppRunning :login="true"/></div>
|
||||
<div class="text-center">
|
||||
<p>
|
||||
<logo></logo>
|
||||
</p>
|
||||
<div class="signin-container">
|
||||
<!-- PWA Check -->
|
||||
<div v-if="enablePwa" class="pwa-check">
|
||||
<CCheckAppRunning :login="true" />
|
||||
</div>
|
||||
|
||||
<q-form ref="myForm" @submit="onSubmit" @reset="onReset">
|
||||
<div class="q-gutter-xs">
|
||||
<q-input
|
||||
ref="refUsername"
|
||||
v-model="signin.username"
|
||||
rounded
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
:label="$t('reg.username_login')"
|
||||
:rules="[
|
||||
(val) => !!val || t('reg.err.required'),
|
||||
(val) =>
|
||||
val.length >= 4 ||
|
||||
t('reg.err.atleast') + ' 4 ' + t('reg.err.char'),
|
||||
]"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="person" />
|
||||
</template>
|
||||
</q-input>
|
||||
<q-input
|
||||
ref="refPassword"
|
||||
v-model="signin.password"
|
||||
:type="typePassword"
|
||||
rounded
|
||||
outlined
|
||||
dense
|
||||
debounce="500"
|
||||
@update:model-value="checkAutoCompletion"
|
||||
v-on:keyup.enter="onSubmit()"
|
||||
:label="$t('reg.password')"
|
||||
:rules="[
|
||||
(val) => !!val || t('reg.err.required'),
|
||||
(val) =>
|
||||
val.length >= 8 ||
|
||||
t('reg.err.atleast') + ' 8 ' + t('reg.err.char'),
|
||||
]"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-btn
|
||||
v-if="!autoCompleteTriggered"
|
||||
tabindex="-1"
|
||||
:icon="
|
||||
typePassword === `password` ? `fas fa-eye-slash` : `fas fa-eye`
|
||||
"
|
||||
@click="showPassword"
|
||||
>
|
||||
</q-btn>
|
||||
</template>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="vpn_key" />
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<div style="text-align: center">
|
||||
<q-btn
|
||||
type="submit"
|
||||
rounded
|
||||
size="md"
|
||||
color="primary"
|
||||
:label="$t('login.enter')"
|
||||
>
|
||||
</q-btn>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div class="text-center" style="margin-bottom: 10px">
|
||||
<a :href="getlinkforgetpwd()" style="color: gray">{{
|
||||
t('reg.forgetpassword')
|
||||
}}</a>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="
|
||||
site.confpages &&
|
||||
site.confpages?.enableReg &&
|
||||
showregbutt &&
|
||||
site.confpages?.enableRegByBot
|
||||
"
|
||||
style="margin-top: 10px; text-align: center"
|
||||
>
|
||||
Se non sei ancora Registrato:<br />
|
||||
<q-btn
|
||||
type="a"
|
||||
rounded
|
||||
size="md"
|
||||
color="primary"
|
||||
href="/bot"
|
||||
:label="$t('reg.submit')"
|
||||
>
|
||||
</q-btn>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="site.confpages && site.confpages?.enableReg && showregbutt"
|
||||
style="margin-top: 10px; text-align: center"
|
||||
>
|
||||
Se non sei ancora Registrato:<br />
|
||||
<q-btn
|
||||
rounded
|
||||
size="md"
|
||||
color="primary"
|
||||
to="/registrati"
|
||||
:label="$t('reg.submit')"
|
||||
>
|
||||
</q-btn>
|
||||
</div>
|
||||
<!-- Login Card -->
|
||||
<q-card class="signin-card">
|
||||
<!-- Header con Logo -->
|
||||
<div class="signin-header">
|
||||
<logo class="signin-logo" mystyle="width: 60px !important; height: 60px !important;" />
|
||||
<h1 class="signin-title">{{ t('login.enter') }}</h1>
|
||||
<p class="signin-subtitle">Accedi al tuo account</p>
|
||||
</div>
|
||||
</q-form>
|
||||
|
||||
<!-- Form -->
|
||||
<q-card-section class="signin-form">
|
||||
<q-form ref="myForm" @submit="onSubmit" @reset="onReset">
|
||||
<div class="form-fields">
|
||||
<!-- Username Input -->
|
||||
<q-input
|
||||
ref="refUsername"
|
||||
v-model="signin.username"
|
||||
filled
|
||||
class="modern-input"
|
||||
:label="$t('reg.username_login')"
|
||||
tabindex="1"
|
||||
lazy-rules
|
||||
:rules="[
|
||||
(val) => !!val || t('reg.err.required'),
|
||||
(val) =>
|
||||
val.length >= 4 ||
|
||||
t('reg.err.atleast') + ' 4 ' + t('reg.err.char'),
|
||||
]"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="person" color="primary" />
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<!-- Password Input -->
|
||||
<q-input
|
||||
ref="refPassword"
|
||||
v-model="signin.password"
|
||||
:type="typePassword"
|
||||
filled
|
||||
class="modern-input"
|
||||
:label="$t('reg.password')"
|
||||
tabindex="2"
|
||||
debounce="500"
|
||||
@update:model-value="checkAutoCompletion"
|
||||
v-on:keyup.enter="onSubmit()"
|
||||
lazy-rules
|
||||
:rules="[
|
||||
(val) => !!val || t('reg.err.required'),
|
||||
(val) =>
|
||||
val.length >= 8 ||
|
||||
t('reg.err.atleast') + ' 8 ' + t('reg.err.char'),
|
||||
]"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="lock" color="primary" />
|
||||
</template>
|
||||
<template v-slot:append>
|
||||
<q-btn
|
||||
v-if="!autoCompleteTriggered"
|
||||
flat
|
||||
round
|
||||
dense
|
||||
tabindex="-1"
|
||||
:icon="typePassword === 'password' ? 'visibility_off' : 'visibility'"
|
||||
@click="showPassword"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<q-btn
|
||||
type="submit"
|
||||
unelevated
|
||||
size="lg"
|
||||
color="primary"
|
||||
:label="$t('login.enter')"
|
||||
class="submit-btn"
|
||||
tabindex="3"
|
||||
/>
|
||||
|
||||
<!-- Forgot Password Link -->
|
||||
<div class="forgot-password">
|
||||
<a :href="getlinkforgetpwd()" class="forgot-link">
|
||||
<q-icon name="help_outline" size="18px" />
|
||||
{{ t('reg.forgetpassword') }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Divider -->
|
||||
<div v-if="site.confpages && site.confpages?.enableReg && showregbutt" class="divider">
|
||||
<span>Non hai un account?</span>
|
||||
</div>
|
||||
|
||||
<!-- Registration Button (Bot) -->
|
||||
<div
|
||||
v-if="
|
||||
site.confpages &&
|
||||
site.confpages?.enableReg &&
|
||||
showregbutt &&
|
||||
site.confpages?.enableRegByBot
|
||||
"
|
||||
class="register-section"
|
||||
>
|
||||
<p class="register-text">Se non sei ancora registrato:</p>
|
||||
<q-btn
|
||||
type="a"
|
||||
unelevated
|
||||
size="lg"
|
||||
color="positive"
|
||||
icon="person_add"
|
||||
href="/bot"
|
||||
:label="$t('reg.submit')"
|
||||
class="register-btn"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Registration Button (Standard) -->
|
||||
<div
|
||||
v-else-if="site.confpages && site.confpages?.enableReg && showregbutt"
|
||||
class="register-section"
|
||||
>
|
||||
<p class="register-text">Se non sei ancora registrato:</p>
|
||||
<q-btn
|
||||
unelevated
|
||||
size="lg"
|
||||
color="positive"
|
||||
icon="person_add"
|
||||
to="/registrati"
|
||||
:label="$t('reg.submit')"
|
||||
class="register-btn"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" src="./CSignIn.ts">
|
||||
</script>
|
||||
<script lang="ts" src="./CSignIn.ts"></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './CSignIn.scss';
|
||||
|
||||
@@ -1,46 +1,843 @@
|
||||
// ========================================
|
||||
// VARIABILI E CONFIGURAZIONE
|
||||
// ========================================
|
||||
$primary-color: #1976d2;
|
||||
$primary-light: #42a5f5;
|
||||
$primary-dark: #1565c0;
|
||||
$accent-color: #26a69a;
|
||||
$positive-color: #21ba45;
|
||||
$negative-color: #c10015;
|
||||
$warning-color: #f2c037;
|
||||
|
||||
$border-radius: 16px;
|
||||
$border-radius-sm: 12px;
|
||||
$border-radius-lg: 24px;
|
||||
|
||||
$transition-speed: 0.3s;
|
||||
$shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
$shadow-md: 0 4px 16px rgba(0, 0, 0, 0.12);
|
||||
$shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.16);
|
||||
|
||||
$mobile-breakpoint: 768px;
|
||||
$mobile-footer-height: 80px;
|
||||
|
||||
// ========================================
|
||||
// CONTAINER PRINCIPALE
|
||||
// ========================================
|
||||
.signup-container {
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
background-attachment: fixed;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 0;
|
||||
align-items: flex-start;
|
||||
background: linear-gradient(180deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// CARDS DI SISTEMA (Success, Error, Warning)
|
||||
// ========================================
|
||||
.already-logged,
|
||||
.already-registered {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
animation: fadeInUp 0.5s ease;
|
||||
}
|
||||
|
||||
.success-card,
|
||||
.error-card,
|
||||
.warning-card,
|
||||
.telegram-card {
|
||||
border-radius: $border-radius-lg;
|
||||
box-shadow: $shadow-lg;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
|
||||
.q-icon {
|
||||
animation: scaleIn 0.5s ease;
|
||||
}
|
||||
}
|
||||
|
||||
.success-card {
|
||||
border-top: 4px solid $positive-color;
|
||||
}
|
||||
|
||||
.error-card {
|
||||
border-top: 4px solid $negative-color;
|
||||
}
|
||||
|
||||
.warning-card {
|
||||
border-top: 4px solid $warning-color;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
min-width: 140px;
|
||||
border-radius: $border-radius-sm;
|
||||
text-transform: none;
|
||||
font-weight: 500;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: $shadow-md;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// FORM PRINCIPALE
|
||||
// ========================================
|
||||
.signup-form {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
animation: fadeInUp 0.5s ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
max-width: 100%;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// HEADER
|
||||
// ========================================
|
||||
.signup-header {
|
||||
text-align: center;
|
||||
padding: 0 10px 10px;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: $border-radius-lg $border-radius-lg 0 0;
|
||||
box-shadow: $shadow-sm;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 6px 8px;
|
||||
border-radius: 0;
|
||||
margin: 8px;
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
|
||||
.signup-logo {
|
||||
margin: 2px auto 2px;
|
||||
animation: rotateIn 0.6s ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
margin: 2px auto;
|
||||
}
|
||||
}
|
||||
|
||||
.signup-title {
|
||||
h1 {
|
||||
margin: 0;
|
||||
background: linear-gradient(135deg, $primary-color, $accent-color);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
font-size: 2rem;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 8px 0 0;
|
||||
font-size: 1rem;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.875rem;
|
||||
margin: 4px 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// FORM CONTENT
|
||||
// ========================================
|
||||
.form-content {
|
||||
background: white;
|
||||
border-radius: $border-radius-lg;
|
||||
box-shadow: $shadow-lg;
|
||||
overflow: hidden;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
border-radius: 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// PROGRESS STEPPER
|
||||
// ========================================
|
||||
.progress-stepper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 24px 20px;
|
||||
background: linear-gradient(to bottom, rgba(103, 126, 234, 0.05), transparent);
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 12px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.step-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
&.active .step-circle {
|
||||
background: $primary-color;
|
||||
color: white;
|
||||
transform: scale(1.15);
|
||||
box-shadow: 0 4px 12px rgba(25, 118, 210, 0.4);
|
||||
}
|
||||
|
||||
&.completed .step-circle {
|
||||
background: $positive-color;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.step-circle {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
background: #e0e0e0;
|
||||
color: #757575;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: 600;
|
||||
font-size: 0.875rem;
|
||||
transition: all $transition-speed ease;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.step-line {
|
||||
width: 60px;
|
||||
height: 3px;
|
||||
background: linear-gradient(to right, #e0e0e0, #bdbdbd);
|
||||
margin: 0 4px;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.completed + & {
|
||||
background: linear-gradient(to right, $positive-color, $primary-color);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// CAROUSEL
|
||||
// ========================================
|
||||
.carousel-wrapper {
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: $mobile-footer-height;
|
||||
}
|
||||
}
|
||||
|
||||
.modern-carousel {
|
||||
background: transparent;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
flex: 1;
|
||||
height: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
.carousel-slide {
|
||||
padding: 0;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// SLIDE CONTENT
|
||||
// ========================================
|
||||
.slide-content {
|
||||
padding: 5px 16px 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
animation: fadeIn 0.4s ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 0px 16px 16px;
|
||||
gap: 12px;
|
||||
min-height: calc(100vh - 280px);
|
||||
}
|
||||
|
||||
&.final-slide {
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
min-height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slide-header {
|
||||
text-align: center;
|
||||
padding-bottom: 16px;
|
||||
border-bottom: 2px solid rgba(0, 0, 0, 0.05);
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.q-icon {
|
||||
margin-bottom: 12px;
|
||||
animation: bounceIn 0.6s ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 32px !important;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slide-title {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 600;
|
||||
margin: 12px 0 8px;
|
||||
color: #1a1a1a;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 1.25rem;
|
||||
margin: 8px 0 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.slide-subtitle {
|
||||
font-size: 1rem;
|
||||
color: #666;
|
||||
margin: 0;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// FORM FIELDS
|
||||
// ========================================
|
||||
.form-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.modern-input {
|
||||
:deep(.q-field__control) {
|
||||
border-radius: $border-radius-sm;
|
||||
min-height: 56px;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
min-height: 48px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
&:before {
|
||||
border-color: rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
&:hover:before {
|
||||
border-color: $primary-light;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.q-field__label) {
|
||||
font-size: 1rem;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.q-field__prepend) {
|
||||
.q-icon {
|
||||
font-size: 24px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.q-field--focused {
|
||||
:deep(.q-field__control) {
|
||||
box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.password-hint {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
background: rgba(103, 126, 234, 0.08);
|
||||
border-radius: $border-radius-sm;
|
||||
font-size: 0.875rem;
|
||||
color: #666;
|
||||
margin-top: 8px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 8px;
|
||||
font-size: 0.8125rem;
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// SUMMARY CARD (Slide 4)
|
||||
// ========================================
|
||||
.summary-card {
|
||||
background: linear-gradient(135deg, rgba(103, 126, 234, 0.08), rgba(118, 75, 162, 0.08));
|
||||
padding: 20px;
|
||||
border-radius: $border-radius;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 12px;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.summary-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px;
|
||||
background: white;
|
||||
border-radius: $border-radius-sm;
|
||||
font-size: 1rem;
|
||||
color: #333;
|
||||
box-shadow: $shadow-sm;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 10px;
|
||||
gap: 10px;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
transform: translateX(4px);
|
||||
box-shadow: $shadow-md;
|
||||
}
|
||||
|
||||
.q-icon {
|
||||
font-size: 24px;
|
||||
flex-shrink: 0;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-weight: 500;
|
||||
word-break: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// POLICY SECTION
|
||||
// ========================================
|
||||
.policy-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
padding-top: 16px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
gap: 12px;
|
||||
padding-top: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.policy-btn {
|
||||
text-transform: none;
|
||||
font-weight: 500;
|
||||
align-self: center;
|
||||
border-radius: $border-radius-sm;
|
||||
padding: 8px 16px;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.875rem;
|
||||
padding: 4px 16px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(25, 118, 210, 0.08);
|
||||
}
|
||||
}
|
||||
|
||||
.terms-checkbox {
|
||||
padding: 16px;
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
border-radius: $border-radius-sm;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 0px 12px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
:deep(.q-checkbox__label) {
|
||||
font-size: 0.9375rem;
|
||||
line-height: 1.5;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.terms-text {
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// NAVIGATION BUTTONS
|
||||
// ========================================
|
||||
.navigation-buttons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 20px 32px;
|
||||
background: linear-gradient(to top, rgba(0, 0, 0, 0.02), transparent);
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 12px 16px;
|
||||
background: white;
|
||||
box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.1);
|
||||
z-index: 1000;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
&.mobile {
|
||||
.nav-btn {
|
||||
flex: 1;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
flex: 0 0 auto;
|
||||
min-width: 48px;
|
||||
padding: 0 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-btn {
|
||||
min-height: 48px;
|
||||
border-radius: $border-radius-sm;
|
||||
font-weight: 600;
|
||||
text-transform: none;
|
||||
font-size: 1rem;
|
||||
transition: all $transition-speed ease;
|
||||
box-shadow: $shadow-sm;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
min-height: 44px;
|
||||
font-size: 0.9375rem;
|
||||
}
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: $shadow-md;
|
||||
}
|
||||
|
||||
&:active:not(:disabled) {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
min-width: 120px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
min-width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.next-btn,
|
||||
.submit-btn {
|
||||
flex: 1;
|
||||
max-width: 300px;
|
||||
background: linear-gradient(135deg, $primary-color, $primary-light);
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: linear-gradient(135deg, $primary-dark, $primary-color);
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background: linear-gradient(135deg, $positive-color, #26a69a);
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: linear-gradient(135deg, #1e8e3e, $positive-color);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// DEBUG STEPPER
|
||||
// ========================================
|
||||
.debug-stepper {
|
||||
padding: 16px 32px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 12px 16px;
|
||||
margin-bottom: $mobile-footer-height;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// TELEGRAM SECTION
|
||||
// ========================================
|
||||
.telegram-section {
|
||||
padding: 20px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// ANIMAZIONI
|
||||
// ========================================
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scaleIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bounceIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.3);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
70% {
|
||||
transform: scale(0.9);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotateIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: rotate(0);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// UTILITY CLASSES
|
||||
// ========================================
|
||||
.signup {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
max-width: 450px;
|
||||
max-width: 800px;
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.clCellCode {
|
||||
border-radius: 32px;
|
||||
border-right: #2d2260;
|
||||
height: 50px;
|
||||
font-size: 1rem;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
// Legacy classes (mantenute per compatibilità)
|
||||
.clCellCode,
|
||||
.clCell {
|
||||
border-radius: 32px;
|
||||
border-right: #2d2260;
|
||||
height: 50px;
|
||||
font-size: 1rem;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.vue-country-select{
|
||||
.vue-country-select {
|
||||
border-radius: 32px;
|
||||
}
|
||||
|
||||
.myuserinvitante{
|
||||
.myuserinvitante {
|
||||
font-weight: bold;
|
||||
color: red;
|
||||
color: $negative-color;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.cosa_chiedere{
|
||||
font-weight: bold;
|
||||
color: blue;
|
||||
font-size: 1rem;
|
||||
padding: 10px;
|
||||
// ========================================
|
||||
// RESPONSIVE UTILITIES
|
||||
// ========================================
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
// Assicura che il body non scrolli quando necessario
|
||||
body.signup-open {
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// Fix per iOS Safari
|
||||
.signup-container {
|
||||
min-height: -webkit-fill-available;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// DARK MODE SUPPORT (opzionale)
|
||||
// ========================================
|
||||
// @media (prefers-color-scheme: dark) {
|
||||
// .signup-container {
|
||||
// background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
|
||||
// }
|
||||
|
||||
// .signup-header,
|
||||
// .form-content {
|
||||
// background: #2a2a3e;
|
||||
// color: #ffffff;
|
||||
// }
|
||||
|
||||
// .slide-title {
|
||||
// color: #ffffff;
|
||||
// }
|
||||
|
||||
// .slide-subtitle {
|
||||
// color: #b0b0b0;
|
||||
// }
|
||||
|
||||
// .summary-card {
|
||||
// background: linear-gradient(135deg, rgba(103, 126, 234, 0.15), rgba(118, 75, 162, 0.15));
|
||||
// }
|
||||
|
||||
// .summary-item {
|
||||
// background: #3a3a4e;
|
||||
// color: #ffffff;
|
||||
// }
|
||||
|
||||
// .modern-input {
|
||||
// :deep(.q-field__control) {
|
||||
// background: #3a3a4e;
|
||||
// color: #ffffff;
|
||||
// }
|
||||
|
||||
// :deep(.q-field__label) {
|
||||
// color: #b0b0b0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
.signup-header {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.signup-logo {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.signup-title {
|
||||
text-align: center;
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
font-size: 1.5rem;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,16 @@ import { CTitleBanner } from '../CTitleBanner';
|
||||
import { CCopyBtn } from '../CCopyBtn';
|
||||
import { CRegistration } from '../CRegistration';
|
||||
import { PagePolicy } from '../PagePolicy';
|
||||
import { computed, defineComponent, onMounted, reactive, ref, watch } from 'vue';
|
||||
import {
|
||||
computed,
|
||||
defineComponent,
|
||||
nextTick,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
reactive,
|
||||
ref,
|
||||
watch,
|
||||
} from 'vue';
|
||||
import { CSignIn } from '@src/components/CSignIn';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
@@ -123,6 +132,14 @@ export default defineComponent({
|
||||
const inputPassword = ref(<any>null);
|
||||
const inputPassword2 = ref(<any>null);
|
||||
|
||||
const submitBtn = ref(<any>null); // AGGIUNGI QUESTA RIGA
|
||||
|
||||
// Responsive detection
|
||||
const isMobile = ref(false);
|
||||
const checkMobile = () => {
|
||||
isMobile.value = window.innerWidth <= 768;
|
||||
};
|
||||
|
||||
const invitaStore = useInvitaAmicoStore();
|
||||
|
||||
const checkifDisabled = computed(() => {
|
||||
@@ -132,7 +149,7 @@ export default defineComponent({
|
||||
ret =
|
||||
!signup.email ||
|
||||
(tools.getAskToVerifyReg() &&
|
||||
(!signup.aportador_solidario || inputAportador.value.hasError)) ||
|
||||
(!signup.aportador_solidario || inputAportador.value?.hasError)) ||
|
||||
(inputEmail.value && inputEmail.value.hasError);
|
||||
} else if (slide.value === '2') {
|
||||
// Username
|
||||
@@ -158,6 +175,37 @@ export default defineComponent({
|
||||
return ret;
|
||||
});
|
||||
|
||||
// Auto-focus sul primo campo quando cambia slide
|
||||
watch(
|
||||
() => slide.value,
|
||||
async (newSlide) => {
|
||||
await nextTick();
|
||||
|
||||
if (newSlide === '1') {
|
||||
// Step 1: Focus su aportador o email
|
||||
if (inputAportador.value && props.showaportador) {
|
||||
inputAportador.value.focus();
|
||||
} else if (inputEmail.value) {
|
||||
inputEmail.value.focus();
|
||||
}
|
||||
} else if (newSlide === '2') {
|
||||
// Step 2: Focus su username
|
||||
if (inputUsername.value) {
|
||||
inputUsername.value.focus();
|
||||
}
|
||||
} else if (newSlide === '3') {
|
||||
// Step 3: Focus su password
|
||||
if (inputPassword.value) {
|
||||
inputPassword.value.focus();
|
||||
}
|
||||
} else if (newSlide === '4') {
|
||||
if (submitBtn.value) {
|
||||
submitBtn.value.$el.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const typePassword = ref('password');
|
||||
|
||||
const ap_iniziale = ref('');
|
||||
@@ -452,20 +500,27 @@ export default defineComponent({
|
||||
onMounted(async () => {
|
||||
const token = props.token;
|
||||
|
||||
// Check mobile on mount
|
||||
checkMobile();
|
||||
window.addEventListener('resize', checkMobile);
|
||||
|
||||
if (token) {
|
||||
// carica le info della registrazione
|
||||
const risinvite = await invitaStore.ottieniInvitoByToken(token);
|
||||
if (risinvite && risinvite.email) {
|
||||
signup.email = risinvite.email;
|
||||
if (risinvite.usernameInvitante)
|
||||
signup.aportador_solidario = risinvite.usernameInvitante
|
||||
|
||||
slide.value = '2'
|
||||
signup.aportador_solidario = risinvite.usernameInvitante;
|
||||
|
||||
slide.value = '2';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', checkMobile);
|
||||
});
|
||||
|
||||
created();
|
||||
|
||||
return {
|
||||
@@ -502,6 +557,8 @@ export default defineComponent({
|
||||
inputPassword,
|
||||
inputPassword2,
|
||||
shared_consts,
|
||||
isMobile,
|
||||
submitBtn,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,29 +1,68 @@
|
||||
// ========================================
|
||||
// VARIABILI
|
||||
// ========================================
|
||||
$transition-speed: 0.3s;
|
||||
$mobile-breakpoint: 768px;
|
||||
|
||||
.svgclass {
|
||||
color: white;
|
||||
transform: translateY(0px);
|
||||
|
||||
}
|
||||
|
||||
|
||||
.svgclass_animate {
|
||||
transform: translateY(-70px);
|
||||
color: red;
|
||||
}
|
||||
|
||||
#sun {
|
||||
animation: gravity 5s infinite;
|
||||
|
||||
}
|
||||
|
||||
#logoimg {
|
||||
height: 100px;
|
||||
width: auto;
|
||||
@media screen and (max-width: 600px) {
|
||||
// ========================================
|
||||
// LOGO WRAPPER
|
||||
// ========================================
|
||||
.logo-wrapper {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
// Hover effect subtile
|
||||
&:hover {
|
||||
.logo-image {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes gravity {
|
||||
// ========================================
|
||||
// LOGO IMAGE
|
||||
// ========================================
|
||||
.logo-image {
|
||||
height: 100px;
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
object-fit: contain;
|
||||
transition: all $transition-speed ease;
|
||||
filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.1));
|
||||
|
||||
// Animazione ingresso
|
||||
animation: logoEntrance 0.8s ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
// Animazione hover
|
||||
&:hover {
|
||||
filter: drop-shadow(0 4px 16px rgba(0, 0, 0, 0.15));
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// ANIMAZIONI
|
||||
// ========================================
|
||||
|
||||
// Animazione ingresso logo
|
||||
@keyframes logoEntrance {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.8) translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1) translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Animazione rotazione 3D (per elementi speciali)
|
||||
@keyframes rotate3D {
|
||||
0% {
|
||||
transform: rotateY(0deg);
|
||||
}
|
||||
@@ -32,8 +71,161 @@
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// CLASSI UTILITY (per animazioni personalizzate)
|
||||
// ========================================
|
||||
|
||||
// Rotazione continua
|
||||
.logo-rotate {
|
||||
.logo-image {
|
||||
animation: rotate3D 10s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
// Pulsazione
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
|
||||
.logo-pulse {
|
||||
.logo-image {
|
||||
animation: pulse 2s ease-in-out infinite;
|
||||
}
|
||||
}
|
||||
|
||||
// Flottante
|
||||
@keyframes float {
|
||||
0%, 100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
}
|
||||
|
||||
.logo-float {
|
||||
.logo-image {
|
||||
animation: float 3s ease-in-out infinite;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LEGACY SUPPORT (per compatibilità)
|
||||
// ========================================
|
||||
|
||||
// Supporto per ID legacy
|
||||
#logo {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#logoimg {
|
||||
height: 100px;
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
object-fit: contain;
|
||||
transition: all $transition-speed ease;
|
||||
filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.1));
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
height: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
// Classi SVG legacy
|
||||
.svgclass {
|
||||
color: white;
|
||||
transform: translateY(0);
|
||||
transition: all $transition-speed ease;
|
||||
}
|
||||
|
||||
.svgclass_animate {
|
||||
transform: translateY(-70px);
|
||||
color: red;
|
||||
}
|
||||
|
||||
// Animazione legacy per elementi specifici
|
||||
#sun {
|
||||
animation: rotate3D 10s linear infinite;
|
||||
}
|
||||
|
||||
#smile {
|
||||
opacity: 0.1 !important;
|
||||
fill: red;
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// TEMI SPECIALI
|
||||
// ========================================
|
||||
|
||||
// Logo con glow effect
|
||||
.logo-glow {
|
||||
.logo-image {
|
||||
filter: drop-shadow(0 0 20px rgba(103, 126, 234, 0.5));
|
||||
animation: glowPulse 2s ease-in-out infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes glowPulse {
|
||||
0%, 100% {
|
||||
filter: drop-shadow(0 0 20px rgba(103, 126, 234, 0.5));
|
||||
}
|
||||
50% {
|
||||
filter: drop-shadow(0 0 30px rgba(103, 126, 234, 0.8));
|
||||
}
|
||||
}
|
||||
|
||||
// Logo con effetto rainbow (opzionale)
|
||||
.logo-rainbow {
|
||||
.logo-image {
|
||||
animation: rainbowFilter 3s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rainbowFilter {
|
||||
0% {
|
||||
filter: hue-rotate(0deg) drop-shadow(0 2px 8px rgba(0, 0, 0, 0.1));
|
||||
}
|
||||
100% {
|
||||
filter: hue-rotate(360deg) drop-shadow(0 2px 8px rgba(0, 0, 0, 0.1));
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// DARK MODE SUPPORT
|
||||
// ========================================
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.logo-image {
|
||||
filter: drop-shadow(0 2px 8px rgba(255, 255, 255, 0.15));
|
||||
|
||||
&:hover {
|
||||
filter: drop-shadow(0 4px 16px rgba(255, 255, 255, 0.25));
|
||||
}
|
||||
}
|
||||
|
||||
#logoimg {
|
||||
filter: drop-shadow(0 2px 8px rgba(255, 255, 255, 0.15));
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// PRINT STYLES
|
||||
// ========================================
|
||||
@media print {
|
||||
.logo-wrapper,
|
||||
#logo {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
.logo-image,
|
||||
#logoimg {
|
||||
max-height: 60px;
|
||||
filter: none;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,16 @@
|
||||
<template>
|
||||
<div id="logo">
|
||||
<img id="logoimg" :alt="logoalt()" :src=logoimg() :style="mystyle">
|
||||
</div>
|
||||
<div class="logo-wrapper">
|
||||
<img
|
||||
class="logo-image"
|
||||
:alt="logoalt()"
|
||||
:src="logoimg()"
|
||||
:style="mystyle"
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" src="./logo.ts">
|
||||
</script>
|
||||
|
||||
<script lang="ts" src="./logo.ts"></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './logo.scss';
|
||||
@import './logo.scss';
|
||||
</style>
|
||||
|
||||
@@ -43,7 +43,7 @@ const msg_website_it = {
|
||||
presentazione: 'Presentazione',
|
||||
presentazione2: 'Presentazione',
|
||||
invita: 'Invita Persone',
|
||||
SignUp: 'Modulo di Registrazione:',
|
||||
SignUp: 'Unisciti a {sitename}!',
|
||||
SignUpCollettivo: 'Reg. Collettiva:',
|
||||
SignUpCollettivo2: 'Registrazione Collettiva:',
|
||||
need_Telegram: 'Per poter utilizzare la Piattaforma occorre avere <a href="https://play.google.com/store/apps/details?id=org.telegram.messenger" target="_blank">Telegram</a> installato<br>',
|
||||
|
||||
@@ -10,6 +10,11 @@ export interface ILinkReg {
|
||||
idlink: string
|
||||
}
|
||||
|
||||
export interface IAmmetti {
|
||||
token: string
|
||||
username: string
|
||||
}
|
||||
|
||||
export interface ICallResult {
|
||||
code?: string
|
||||
msg?: string
|
||||
|
||||
@@ -666,6 +666,17 @@ function getRoutesAd(site: ISites) {
|
||||
infooter: false,
|
||||
separator: false
|
||||
},
|
||||
{
|
||||
active: true,
|
||||
order: 1005,
|
||||
path: '/ammetti/:token/:username',
|
||||
materialIcon: 'how_to_reg',
|
||||
name: 'pages.Ammetti',
|
||||
component: () => import('@src/views/login/ammetti/ammetti.vue'),
|
||||
inmenu: false,
|
||||
infooter: false,
|
||||
separator: false
|
||||
},
|
||||
{
|
||||
active: true,
|
||||
order: 1001,
|
||||
|
||||
@@ -704,6 +704,7 @@ const msg_it = {
|
||||
onlyadult: 'Confermo di essere Maggiorenne',
|
||||
submit: 'Registrati',
|
||||
title_verif_reg: 'Verifica Registrazione',
|
||||
title_ammetti_membro: 'Ammetti Membro',
|
||||
reg_ok: 'Registrazione Effettuata con Successo',
|
||||
verificato: 'Verificato',
|
||||
non_verificato: 'Non Verificato',
|
||||
@@ -829,7 +830,7 @@ const msg_it = {
|
||||
},
|
||||
reset: {
|
||||
title_reset_pwd: 'Reimposta la tua Password',
|
||||
send_reset_pwd: 'Invia Reimposta la password',
|
||||
send_reset_pwd: 'Reimposta la password',
|
||||
resend_reset_pwd: 'Rimanda nuovamente',
|
||||
incorso: 'Richiesta Nuova Email...',
|
||||
email_sent: 'Email inviata',
|
||||
|
||||
@@ -6,6 +6,9 @@ export const serv_constants = {
|
||||
RIS_CODE_EMAIL_ALREADY_VERIFIED: -5,
|
||||
RIS_CODE_EMAIL_VERIFIED: 1,
|
||||
|
||||
RIS_CODE_AMMESSO: 1,
|
||||
RIS_CODE_GIA_AMMESSO: -5,
|
||||
|
||||
RIS_CODE_REC_DUPLICATED_DESCR_CITY_USER: -110,
|
||||
RIS_CODE_REC_ALREADY_EXIST_SYMBOL: -102,
|
||||
RIS_CODE_REC_ALREADY_EXIST_CODE: -101,
|
||||
|
||||
@@ -19,7 +19,7 @@ import type {
|
||||
import { IFriends, ISettings } from '@src/model';
|
||||
import { tools } from '@tools';
|
||||
import translate from '@src/globalroutines/util';
|
||||
import type { ILinkReg, IToken } from '@model/other';
|
||||
import type { IAmmetti, ILinkReg, IToken } from '@model/other';
|
||||
import { ICallResult, IResult } from '@model/other';
|
||||
|
||||
import objectId from '@src/js/objectId';
|
||||
@@ -1111,6 +1111,31 @@ export const useUserStore = defineStore('UserStore', {
|
||||
return { code: this.getServerCode, msg: error.getMsgError() };
|
||||
});
|
||||
},
|
||||
async ammetti(paramquery: IAmmetti) {
|
||||
const usertosend = {
|
||||
token: paramquery.token,
|
||||
username: paramquery.username,
|
||||
};
|
||||
console.log(usertosend);
|
||||
|
||||
this.setServerCode(tools.CALLING);
|
||||
|
||||
return Api.SendReq('/ammetti', 'POST', usertosend)
|
||||
.then((res) => {
|
||||
// console.log("RITORNO 2 ");
|
||||
// mutations.setServerCode(myres);
|
||||
if (res.data.code === serv_constants.RIS_CODE_AMMESSO) {
|
||||
console.log('AMMESSO !!');
|
||||
} else {
|
||||
console.log('Risultato di ammetti: ', res.data.code);
|
||||
}
|
||||
return { code: res.data.code, msg: res.data.msg };
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setErrorCatch(error);
|
||||
return { code: this.getServerCode, msg: error.getMsgError() };
|
||||
});
|
||||
},
|
||||
|
||||
async unsubscribe(paramquery: any) {
|
||||
return Api.SendReq('/news/unsubscribe', 'POST', paramquery)
|
||||
|
||||
37
src/views/login/ammetti/ammetti.scss
Executable file
37
src/views/login/ammetti/ammetti.scss
Executable file
@@ -0,0 +1,37 @@
|
||||
.mypanel {
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
|
||||
}
|
||||
|
||||
.admission-header {
|
||||
background: linear-gradient(135deg, var(--q-primary) 0%, #1976d2 100%);
|
||||
border-radius: 16px;
|
||||
padding: 48px 24px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.result-card {
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
||||
|
||||
.q-card-section {
|
||||
padding: 32px 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.opacity-80 {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
// Responsive
|
||||
@media (max-width: 600px) {
|
||||
.admission-header {
|
||||
padding: 32px 16px;
|
||||
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
94
src/views/login/ammetti/ammetti.ts
Executable file
94
src/views/login/ammetti/ammetti.ts
Executable file
@@ -0,0 +1,94 @@
|
||||
import { defineComponent, onMounted, ref } from 'vue';
|
||||
|
||||
import { serv_constants } from '../../../store/Modules/serv_constants';
|
||||
|
||||
import type { IAmmetti, ILinkReg } from '../../../model/other';
|
||||
import { ICallResult } from '../../../model/other';
|
||||
import { CSigninNoreg } from '../../../components/CSigninNoreg';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useGlobalStore } from '@store/globalStore';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { useUserStore } from '@store/UserStore';
|
||||
import { tools } from '@tools';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Ammetti',
|
||||
components: { CSigninNoreg },
|
||||
|
||||
setup(props) {
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
const $router = useRouter();
|
||||
const { t } = useI18n();
|
||||
const globalStore = useGlobalStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const isLoading = ref(false);
|
||||
|
||||
const username = ref('')
|
||||
|
||||
const risultato = ref('---');
|
||||
const riscode = ref(0);
|
||||
|
||||
function myrisultato() {
|
||||
return risultato;
|
||||
}
|
||||
|
||||
function giaammesso() {
|
||||
return riscode.value !== serv_constants.RIS_CODE_AMMESSO;
|
||||
}
|
||||
|
||||
function ammettiok() {
|
||||
return riscode.value === serv_constants.RIS_CODE_AMMESSO;
|
||||
}
|
||||
|
||||
function load() {
|
||||
console.log('load Ammetti');
|
||||
|
||||
isLoading.value = true
|
||||
|
||||
username.value = (route.params.username) ? route.params.username.toString() : '';
|
||||
let param: IAmmetti = { token: '', username: '' };
|
||||
if (route.params.token) param = { token: route.params.token.toString(), username: username.value };
|
||||
|
||||
// console.log('idlink = ', param)
|
||||
return userStore
|
||||
.ammetti(param)
|
||||
.then((ris: any) => {
|
||||
riscode.value = ris.code;
|
||||
risultato.value = ris.msg;
|
||||
isLoading.value = false
|
||||
})
|
||||
.catch((err: any) => {
|
||||
console.log('ERR = ' + err);
|
||||
isLoading.value = false
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
load();
|
||||
});
|
||||
|
||||
const goToProfile = () => {
|
||||
// Naviga al profilo del membro ammesso
|
||||
router.push(`/my/${username.value}`);
|
||||
};
|
||||
|
||||
const goHome = () => {
|
||||
router.push('/');
|
||||
};
|
||||
return {
|
||||
tools,
|
||||
ammettiok,
|
||||
giaammesso,
|
||||
myrisultato,
|
||||
t,
|
||||
isLoading,
|
||||
goHome,
|
||||
goToProfile,
|
||||
};
|
||||
},
|
||||
});
|
||||
106
src/views/login/ammetti/ammetti.vue
Executable file
106
src/views/login/ammetti/ammetti.vue
Executable file
@@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<q-page class="vreg">
|
||||
<div class="q-pa-md">
|
||||
<!-- Header con gradient -->
|
||||
<div class="admission-header q-mb-lg">
|
||||
<div class="text-center">
|
||||
<q-icon
|
||||
name="person_add"
|
||||
size="64px"
|
||||
class="q-mb-md"
|
||||
color="white"
|
||||
/>
|
||||
<h4 class="text-h4 text-white q-my-none q-mb-sm">
|
||||
{{ t('reg.title_ammetti_membro') }}
|
||||
</h4>
|
||||
<p class="text-subtitle1 text-white opacity-80">
|
||||
Gestione ammissione nuovo membro
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Loading state -->
|
||||
<transition
|
||||
enter-active-class="animated fadeIn"
|
||||
leave-active-class="animated fadeOut"
|
||||
mode="out-in"
|
||||
>
|
||||
<div v-if="isLoading" class="text-center q-py-xl">
|
||||
<q-spinner-dots color="primary" size="50px" />
|
||||
<p class="text-subtitle1 text-grey-7 q-mt-md">
|
||||
Elaborazione in corso...
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Result card -->
|
||||
<q-card v-else class="result-card" flat bordered>
|
||||
<!-- Already admitted warning -->
|
||||
<q-card-section
|
||||
v-if="giaammesso()"
|
||||
class="bg-warning text-white"
|
||||
>
|
||||
<div class="row items-center q-gutter-md">
|
||||
<q-icon name="warning" size="48px" />
|
||||
<div class="col">
|
||||
<div class="text-h6 q-mb-xs">Attenzione</div>
|
||||
<div class="text-body1">{{ myrisultato() }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<!-- Success message -->
|
||||
<q-card-section
|
||||
v-else-if="ammettiok()"
|
||||
class="bg-positive text-white"
|
||||
>
|
||||
<div class="row items-center q-gutter-md">
|
||||
<q-icon name="check_circle" size="48px" />
|
||||
<div class="col">
|
||||
<div class="text-h6 q-mb-xs">Ammissione Completata</div>
|
||||
<div class="text-body1">{{ myrisultato() }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<!-- Actions -->
|
||||
<q-card-actions align="center" class="q-pa-md">
|
||||
<q-btn
|
||||
v-if="ammettiok()"
|
||||
label="Visualizza Profilo"
|
||||
color="primary"
|
||||
unelevated
|
||||
icon="person"
|
||||
@click="goToProfile"
|
||||
class="q-px-xl"
|
||||
/>
|
||||
<q-btn
|
||||
label="Torna alla Home"
|
||||
color="primary"
|
||||
outline
|
||||
@click="goHome"
|
||||
/>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</transition>
|
||||
|
||||
<!-- Info card (optional) -->
|
||||
<q-card flat bordered class="q-mt-md bg-blue-1">
|
||||
<q-card-section>
|
||||
<div class="row items-center q-gutter-sm">
|
||||
<q-icon name="info" color="primary" size="24px" />
|
||||
<div class="text-body2 text-grey-8">
|
||||
L'ammissione del membro verrà notificata via email e Telegram
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
</q-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" src="./ammetti.ts">
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './ammetti.scss';
|
||||
</style>
|
||||
@@ -1,7 +1,10 @@
|
||||
.signup {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
max-width: 450px;
|
||||
max-width: 800px;
|
||||
@media (max-width: 800px) {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,400 @@
|
||||
// ========================================
|
||||
// VARIABILI (Sincronizzate)
|
||||
// ========================================
|
||||
$primary-color: #1976d2;
|
||||
$primary-light: #42a5f5;
|
||||
$primary-dark: #1565c0;
|
||||
$accent-color: #26a69a;
|
||||
$positive-color: #21ba45;
|
||||
$negative-color: #c10015;
|
||||
|
||||
$border-radius: 16px;
|
||||
$border-radius-sm: 12px;
|
||||
$border-radius-lg: 24px;
|
||||
|
||||
$transition-speed: 0.3s;
|
||||
$shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
$shadow-md: 0 4px 16px rgba(0, 0, 0, 0.12);
|
||||
$shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.16);
|
||||
|
||||
$mobile-breakpoint: 768px;
|
||||
|
||||
// ========================================
|
||||
// CONTAINER PRINCIPALE
|
||||
// ========================================
|
||||
.reset-password-container {
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
background-attachment: fixed;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 12px;
|
||||
align-items: flex-start;
|
||||
padding-top: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// CARD PRINCIPALE
|
||||
// ========================================
|
||||
.reset-card {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
border-radius: $border-radius-lg;
|
||||
box-shadow: $shadow-lg;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
animation: fadeInUp 0.6s ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
max-width: 100%;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// HEADER
|
||||
// ========================================
|
||||
.reset-header {
|
||||
text-align: center;
|
||||
padding: 40px 24px 24px;
|
||||
background: linear-gradient(to bottom, rgba(103, 126, 234, 0.05), transparent);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
|
||||
|
||||
&.success {
|
||||
background: linear-gradient(to bottom, rgba(33, 186, 69, 0.08), transparent);
|
||||
border-bottom-color: rgba(33, 186, 69, 0.15);
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 32px 16px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
margin: 0 auto 20px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, rgba(25, 118, 210, 0.1), rgba(38, 166, 154, 0.1));
|
||||
animation: scaleIn 0.6s ease;
|
||||
|
||||
&.success {
|
||||
background: linear-gradient(135deg, rgba(33, 186, 69, 0.15), rgba(38, 166, 154, 0.15));
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin: 0 auto 16px;
|
||||
|
||||
.q-icon {
|
||||
font-size: 48px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.reset-title {
|
||||
font-size: 1.875rem;
|
||||
font-weight: 600;
|
||||
margin: 0 0 12px;
|
||||
color: #1a1a1a;
|
||||
line-height: 1.3;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 1.5rem;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.reset-subtitle {
|
||||
font-size: 1rem;
|
||||
color: #666;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.9375rem;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// FORM
|
||||
// ========================================
|
||||
.reset-form {
|
||||
padding: 32px 24px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// INPUT FIELDS
|
||||
// ========================================
|
||||
.modern-input {
|
||||
:deep(.q-field__control) {
|
||||
border-radius: $border-radius-sm;
|
||||
min-height: 56px;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
min-height: 52px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
&:before {
|
||||
border-color: rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
&:hover:before {
|
||||
border-color: $primary-light;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.q-field__label) {
|
||||
font-size: 1rem;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.9375rem;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.q-field__prepend) {
|
||||
.q-icon {
|
||||
font-size: 24px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.q-field--focused {
|
||||
:deep(.q-field__control) {
|
||||
box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
&.q-field--error {
|
||||
animation: shake 0.4s ease;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// CODE INPUT
|
||||
// ========================================
|
||||
.code-input-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.code-input {
|
||||
:deep(.q-field__control) {
|
||||
input {
|
||||
text-align: center;
|
||||
font-size: 1.5rem;
|
||||
letter-spacing: 8px;
|
||||
font-weight: 600;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 1.25rem;
|
||||
letter-spacing: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.code-hint {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
background: rgba(103, 126, 234, 0.06);
|
||||
border-radius: $border-radius-sm;
|
||||
font-size: 0.875rem;
|
||||
color: #666;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 10px;
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
.q-icon {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// BUTTONS
|
||||
// ========================================
|
||||
.submit-btn {
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
border-radius: $border-radius;
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
text-transform: none;
|
||||
background: linear-gradient(135deg, $primary-color, $primary-light);
|
||||
box-shadow: $shadow-md;
|
||||
transition: all $transition-speed ease;
|
||||
margin-top: 8px;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: $shadow-lg;
|
||||
background: linear-gradient(135deg, $primary-dark, $primary-color);
|
||||
}
|
||||
|
||||
&:active:not(:disabled) {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
height: 52px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.confirm-btn {
|
||||
background: linear-gradient(135deg, $positive-color, #26a69a);
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: linear-gradient(135deg, #1e8e3e, $positive-color);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LINKS
|
||||
// ========================================
|
||||
.back-link,
|
||||
.resend-link {
|
||||
text-align: center;
|
||||
margin-top: 4px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.link-text {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
font-size: 0.9375rem;
|
||||
transition: all $transition-speed ease;
|
||||
padding: 8px 12px;
|
||||
border-radius: $border-radius-sm;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $primary-color;
|
||||
background: rgba(25, 118, 210, 0.06);
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.875rem;
|
||||
padding: 6px 10px;
|
||||
}
|
||||
|
||||
.q-icon {
|
||||
font-size: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// ANIMAZIONI
|
||||
// ========================================
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scaleIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
0%, 100% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
25% {
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
75% {
|
||||
transform: translateX(10px);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// RESPONSIVE UTILITIES
|
||||
// ========================================
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
.reset-password-container {
|
||||
min-height: -webkit-fill-available;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LEGACY CLASSES
|
||||
// ========================================
|
||||
.padding {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.mybanner {
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -1,92 +1,133 @@
|
||||
<template>
|
||||
<form
|
||||
v-if="!emailinviata()"
|
||||
@submit.prevent.stop="submit"
|
||||
class="row justify-center text-center padding"
|
||||
>
|
||||
<div class="q-gutter-sm q-ma-sm">
|
||||
<div>
|
||||
<q-banner
|
||||
rounded
|
||||
class="bg-primary text-white"
|
||||
style="text-align: center"
|
||||
>
|
||||
<span class="mybanner">{{ t('reset.title_reset_pwd') }}</span>
|
||||
</q-banner>
|
||||
<br />
|
||||
|
||||
<q-input
|
||||
ref="emailRef"
|
||||
v-model="form.email"
|
||||
rounded
|
||||
outlined
|
||||
autocomplete="email"
|
||||
maxlength="50"
|
||||
debounce="1000"
|
||||
:error="v$.email.$error"
|
||||
:error-message="tools.errorMsg('email', v$.email)"
|
||||
:label="$t('reg.email')"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="email" />
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<br />
|
||||
|
||||
<div class="center q-ma-sm">
|
||||
<q-btn
|
||||
rounded
|
||||
size="lg"
|
||||
color="primary"
|
||||
type="submit"
|
||||
:disable="v$.$error || v$.$invalid"
|
||||
>{{ t('reset.send_reset_pwd') }}
|
||||
</q-btn>
|
||||
<div class="reset-password-container">
|
||||
<!-- Card Reset Password -->
|
||||
<q-card class="reset-card">
|
||||
<!-- Stato 1: Richiesta Email -->
|
||||
<form v-if="!emailinviata()" @submit.prevent.stop="submit">
|
||||
<!-- Header -->
|
||||
<div class="reset-header">
|
||||
<div class="icon-wrapper">
|
||||
<q-icon name="lock_reset" size="56px" color="primary" />
|
||||
</div>
|
||||
<h1 class="reset-title">{{ t('reset.title_reset_pwd') }}</h1>
|
||||
<p class="reset-subtitle">Inserisci la tua email per recuperare l'accesso</p>
|
||||
</div>
|
||||
|
||||
<!-- Form Section -->
|
||||
<q-card-section class="reset-form">
|
||||
<div class="form-fields">
|
||||
<!-- Email Input -->
|
||||
<q-input
|
||||
ref="emailRef"
|
||||
v-model="form.email"
|
||||
filled
|
||||
class="modern-input"
|
||||
autocomplete="email"
|
||||
maxlength="50"
|
||||
debounce="1000"
|
||||
tabindex="1"
|
||||
:error="v$.email.$error"
|
||||
:error-message="tools.errorMsg('email', v$.email)"
|
||||
:label="$t('reg.email')"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="email" color="primary" />
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<q-btn
|
||||
type="submit"
|
||||
unelevated
|
||||
size="lg"
|
||||
color="primary"
|
||||
icon="send"
|
||||
:disable="v$.$error || v$.$invalid"
|
||||
:label="t('reset.send_reset_pwd')"
|
||||
class="submit-btn"
|
||||
tabindex="2"
|
||||
/>
|
||||
|
||||
<!-- Back to Login -->
|
||||
<div class="back-link">
|
||||
<a href="/signin" class="link-text">
|
||||
<q-icon name="arrow_back" size="18px" />
|
||||
Torna al login
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</form>
|
||||
|
||||
<!-- Stato 2: Conferma Codice -->
|
||||
<div v-else>
|
||||
<!-- Success Header -->
|
||||
<div class="reset-header success">
|
||||
<div class="icon-wrapper success">
|
||||
<q-icon name="mark_email_read" size="56px" color="positive" />
|
||||
</div>
|
||||
<h1 class="reset-title">{{ t('reset.email_sent') }}</h1>
|
||||
<p class="reset-subtitle">
|
||||
<strong>{{ t('reset.check_email') }}</strong>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Code Verification Section -->
|
||||
<q-card-section class="reset-form">
|
||||
<div class="form-fields">
|
||||
<!-- Code Input -->
|
||||
<div class="code-input-wrapper">
|
||||
<q-input
|
||||
v-model="form.tokenforgot_code"
|
||||
filled
|
||||
class="modern-input code-input"
|
||||
label="Inserisci il codice a 6 cifre"
|
||||
debounce="1000"
|
||||
:maxlength="6"
|
||||
type="text"
|
||||
inputmode="numeric"
|
||||
pattern="[0-9]*"
|
||||
tabindex="1"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="pin" color="primary" />
|
||||
</template>
|
||||
</q-input>
|
||||
<div class="code-hint">
|
||||
<q-icon name="info" size="16px" color="grey-6" />
|
||||
<span>Controlla la tua casella email e spam</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Confirm Button -->
|
||||
<q-btn
|
||||
@click="checkCode"
|
||||
unelevated
|
||||
size="lg"
|
||||
color="positive"
|
||||
icon="check_circle"
|
||||
type="submit"
|
||||
:disable="v$.$error || v$.$invalid"
|
||||
:label="t('reset.confirmcode_reset')"
|
||||
class="submit-btn confirm-btn"
|
||||
tabindex="2"
|
||||
/>
|
||||
|
||||
<!-- Resend Link -->
|
||||
<div class="resend-link">
|
||||
<a @click.prevent="submit" class="link-text">
|
||||
<q-icon name="refresh" size="18px" />
|
||||
Non hai ricevuto il codice? Invia di nuovo
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div v-else>
|
||||
<q-banner rounded class="bg-positive text-white" style="text-align: center">
|
||||
<span class="mybanner">{{ t('reset.email_sent') }}</span>
|
||||
</q-banner>
|
||||
<br />
|
||||
|
||||
<div>
|
||||
<strong>{{ t('reset.check_email') }}</strong>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<q-input
|
||||
v-model="form.tokenforgot_code"
|
||||
rounded
|
||||
outlined
|
||||
label="Inserisci il codice a 6 cifre"
|
||||
debounce="1000"
|
||||
:maxlength="6"
|
||||
type="number"
|
||||
>
|
||||
</q-input>
|
||||
|
||||
<br /><br />
|
||||
|
||||
<div class="center q-ma-sm">
|
||||
<q-btn
|
||||
@click="checkCode"
|
||||
rounded
|
||||
size="lg"
|
||||
color="primary"
|
||||
type="submit"
|
||||
:disable="v$.$error || v$.$invalid"
|
||||
>{{ t('reset.confirmcode_reset') }}
|
||||
</q-btn>
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" src="./requestresetpwd.ts">
|
||||
</script>
|
||||
<script lang="ts" src="./requestresetpwd.ts"></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './requestresetpwd';
|
||||
|
||||
@@ -1,6 +1,376 @@
|
||||
.mypanel {
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
// ========================================
|
||||
// VARIABILI (Sincronizzate)
|
||||
// ========================================
|
||||
$primary-color: #1976d2;
|
||||
$primary-light: #42a5f5;
|
||||
$primary-dark: #1565c0;
|
||||
$accent-color: #26a69a;
|
||||
$positive-color: #21ba45;
|
||||
$negative-color: #c10015;
|
||||
|
||||
$border-radius: 16px;
|
||||
$border-radius-sm: 12px;
|
||||
$border-radius-lg: 24px;
|
||||
|
||||
$transition-speed: 0.3s;
|
||||
$shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
$shadow-md: 0 4px 16px rgba(0, 0, 0, 0.12);
|
||||
$shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.16);
|
||||
|
||||
$mobile-breakpoint: 768px;
|
||||
|
||||
// ========================================
|
||||
// CONTAINER PRINCIPALE
|
||||
// ========================================
|
||||
.update-password-container {
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
background-attachment: fixed;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 12px;
|
||||
align-items: flex-start;
|
||||
padding-top: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// CARD PRINCIPALE
|
||||
// ========================================
|
||||
.update-card {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
border-radius: $border-radius-lg;
|
||||
box-shadow: $shadow-lg;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
animation: fadeInUp 0.6s ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
max-width: 100%;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// HEADER
|
||||
// ========================================
|
||||
.update-header {
|
||||
text-align: center;
|
||||
padding: 40px 24px 24px;
|
||||
background: linear-gradient(to bottom, rgba(103, 126, 234, 0.05), transparent);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
|
||||
|
||||
&.success {
|
||||
background: linear-gradient(to bottom, rgba(33, 186, 69, 0.08), transparent);
|
||||
border-bottom-color: rgba(33, 186, 69, 0.15);
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 32px 16px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
margin: 0 auto 20px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, rgba(25, 118, 210, 0.1), rgba(38, 166, 154, 0.1));
|
||||
animation: scaleIn 0.6s ease;
|
||||
|
||||
&.success {
|
||||
background: linear-gradient(135deg, rgba(33, 186, 69, 0.15), rgba(38, 166, 154, 0.15));
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin: 0 auto 16px;
|
||||
|
||||
.q-icon {
|
||||
font-size: 48px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.update-title {
|
||||
font-size: 1.875rem;
|
||||
font-weight: 600;
|
||||
margin: 0 0 12px;
|
||||
color: #1a1a1a;
|
||||
line-height: 1.3;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 1.5rem;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.update-subtitle {
|
||||
font-size: 1rem;
|
||||
color: #666;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.9375rem;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// FORM
|
||||
// ========================================
|
||||
.update-form {
|
||||
padding: 32px 24px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// INPUT FIELDS
|
||||
// ========================================
|
||||
.modern-input {
|
||||
:deep(.q-field__control) {
|
||||
border-radius: $border-radius-sm;
|
||||
min-height: 56px;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
min-height: 52px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
&:before {
|
||||
border-color: rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
&:hover:before {
|
||||
border-color: $primary-light;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.q-field__label) {
|
||||
font-size: 1rem;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 0.9375rem;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.q-field__prepend) {
|
||||
.q-icon {
|
||||
font-size: 24px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.q-field--focused {
|
||||
:deep(.q-field__control) {
|
||||
box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
&.q-field--error {
|
||||
animation: shake 0.4s ease;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// PASSWORD HINT
|
||||
// ========================================
|
||||
.password-hint {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
background: rgba(103, 126, 234, 0.08);
|
||||
border-radius: $border-radius-sm;
|
||||
font-size: 0.875rem;
|
||||
color: #666;
|
||||
margin-top: -8px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 10px;
|
||||
font-size: 0.8125rem;
|
||||
margin-top: -4px;
|
||||
}
|
||||
|
||||
.q-icon {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// BUTTONS
|
||||
// ========================================
|
||||
.submit-btn {
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
border-radius: $border-radius;
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
text-transform: none;
|
||||
background: linear-gradient(135deg, $positive-color, #26a69a);
|
||||
box-shadow: $shadow-md;
|
||||
transition: all $transition-speed ease;
|
||||
margin-top: 8px;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: $shadow-lg;
|
||||
background: linear-gradient(135deg, #1e8e3e, $positive-color);
|
||||
}
|
||||
|
||||
&:active:not(:disabled) {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
height: 52px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// SUCCESS MESSAGE
|
||||
// ========================================
|
||||
.success-message {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 24px;
|
||||
font-size: 1rem;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
margin: 0 0 20px;
|
||||
font-size: 0.9375rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
min-width: 200px;
|
||||
height: 52px;
|
||||
border-radius: $border-radius;
|
||||
font-size: 1.0625rem;
|
||||
font-weight: 600;
|
||||
text-transform: none;
|
||||
background: linear-gradient(135deg, $primary-color, $primary-light);
|
||||
box-shadow: $shadow-md;
|
||||
transition: all $transition-speed ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: $shadow-lg;
|
||||
background: linear-gradient(135deg, $primary-dark, $primary-color);
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
width: 100%;
|
||||
min-width: auto;
|
||||
height: 48px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// ANIMAZIONI
|
||||
// ========================================
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scaleIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
0%, 100% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
25% {
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
75% {
|
||||
transform: translateX(10px);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// RESPONSIVE UTILITIES
|
||||
// ========================================
|
||||
@media (max-width: $mobile-breakpoint) {
|
||||
.update-password-container {
|
||||
min-height: -webkit-fill-available;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// LEGACY CLASSES
|
||||
// ========================================
|
||||
.mypanel {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.padding {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.mybanner {
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -1,107 +1,132 @@
|
||||
<template>
|
||||
<div class="mypanel">
|
||||
<form @submit.prevent.stop="submit" class="q-col-gutter-lg row justify-center text-center padding q-pa-md">
|
||||
|
||||
<div v-if="!emailsent">
|
||||
<q-banner
|
||||
rounded
|
||||
dense
|
||||
class="bg-primary text-white"
|
||||
style="text-align: center;">
|
||||
<span class="mybanner">{{ t('reset.title_update_pwd') }}</span>
|
||||
</q-banner>
|
||||
|
||||
<div class="q-my-lg"></div>
|
||||
|
||||
<div class="column">
|
||||
|
||||
<q-input
|
||||
v-model="form.password"
|
||||
:type="typePassword"
|
||||
dense
|
||||
rounded outlined
|
||||
@blur="v$.password.$touch"
|
||||
:error="v$.password.$error"
|
||||
:error-message="`${tools.errorMsg('password', v$.password)}`"
|
||||
maxlength="30"
|
||||
:label="$t('reg.password')">
|
||||
|
||||
|
||||
<template v-slot:append>
|
||||
<q-btn
|
||||
tabindex="-1"
|
||||
:icon="typePassword === `password` ? `fas fa-eye-slash` : `fas fa-eye`"
|
||||
@click="showPassword"
|
||||
>
|
||||
</q-btn>
|
||||
</template>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="vpn_key"/>
|
||||
</template>
|
||||
|
||||
|
||||
</q-input>
|
||||
|
||||
<div class="q-my-sm"></div>
|
||||
|
||||
<q-input
|
||||
v-model="form.repeatPassword"
|
||||
:type="typePassword"
|
||||
dense
|
||||
maxlength="30"
|
||||
rounded outlined
|
||||
@blur="v$.repeatPassword.$touch"
|
||||
:error="v$.repeatPassword.$error"
|
||||
:error-message="`${tools.errorMsg('repeatpassword', v$.repeatPassword)}`"
|
||||
|
||||
:label="$t('reg.repeatPassword')">
|
||||
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="vpn_key"/>
|
||||
</template>
|
||||
<template v-slot:append>
|
||||
<q-btn
|
||||
tabindex="-1"
|
||||
:icon="typePassword === `password` ? `fas fa-eye-slash` : `fas fa-eye`"
|
||||
@click="showPassword"
|
||||
>
|
||||
</q-btn>
|
||||
</template>
|
||||
|
||||
</q-input>
|
||||
|
||||
<div class="q-my-sm"></div>
|
||||
|
||||
<div align="center">
|
||||
<q-btn rounded size="lg" color="primary" type="submit" :disable="v$.$error">
|
||||
{{ t('reset.update_password') }}
|
||||
</q-btn>
|
||||
<div class="update-password-container">
|
||||
<!-- Card Update Password -->
|
||||
<q-card class="update-card">
|
||||
<!-- Stato 1: Form Aggiornamento Password -->
|
||||
<form v-if="!emailsent" @submit.prevent.stop="submit">
|
||||
<!-- Header -->
|
||||
<div class="update-header">
|
||||
<div class="icon-wrapper">
|
||||
<q-icon name="lock_open" size="56px" color="primary" />
|
||||
</div>
|
||||
<h1 class="update-title">{{ t('reset.title_update_pwd') }}</h1>
|
||||
<p class="update-subtitle">Crea una nuova password sicura</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- Form Section -->
|
||||
<q-card-section class="update-form">
|
||||
<div class="form-fields">
|
||||
<!-- Password Input -->
|
||||
<q-input
|
||||
v-model="form.password"
|
||||
:type="typePassword"
|
||||
filled
|
||||
class="modern-input"
|
||||
@blur="v$.password.$touch"
|
||||
:error="v$.password.$error"
|
||||
:error-message="`${tools.errorMsg('password', v$.password)}`"
|
||||
maxlength="30"
|
||||
tabindex="1"
|
||||
:label="$t('reg.password')"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="vpn_key" color="primary" />
|
||||
</template>
|
||||
<template v-slot:append>
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
dense
|
||||
tabindex="-1"
|
||||
:icon="typePassword === 'password' ? 'visibility_off' : 'visibility'"
|
||||
@click="showPassword"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<!-- Repeat Password Input -->
|
||||
<q-input
|
||||
v-model="form.repeatPassword"
|
||||
:type="typePassword"
|
||||
filled
|
||||
class="modern-input"
|
||||
maxlength="30"
|
||||
@blur="v$.repeatPassword.$touch"
|
||||
:error="v$.repeatPassword.$error"
|
||||
:error-message="`${tools.errorMsg('repeatpassword', v$.repeatPassword)}`"
|
||||
tabindex="2"
|
||||
:label="$t('reg.repeatPassword')"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="lock" color="primary" />
|
||||
</template>
|
||||
<template v-slot:append>
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
dense
|
||||
tabindex="-1"
|
||||
:icon="typePassword === 'password' ? 'visibility_off' : 'visibility'"
|
||||
@click="showPassword"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<!-- Password Hint -->
|
||||
<div class="password-hint">
|
||||
<q-icon name="info" size="16px" color="grey-6" />
|
||||
<span>Minimo 8 caratteri, includi lettere e numeri</span>
|
||||
</div>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<q-btn
|
||||
type="submit"
|
||||
unelevated
|
||||
size="lg"
|
||||
color="positive"
|
||||
icon="check_circle"
|
||||
:disable="v$.$error"
|
||||
:label="t('reset.update_password')"
|
||||
class="submit-btn"
|
||||
tabindex="3"
|
||||
/>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</form>
|
||||
|
||||
<!-- Stato 2: Successo -->
|
||||
<div v-else>
|
||||
<q-banner
|
||||
rounded
|
||||
class="bg-primary text-white"
|
||||
style="text-align: center;">
|
||||
<span class="mybanner">{{ t('reset.email_sent') }}</span>
|
||||
</q-banner>
|
||||
<br>
|
||||
|
||||
<div>
|
||||
{{ t('reset.check_email') }}
|
||||
<!-- Success Header -->
|
||||
<div class="update-header success">
|
||||
<div class="icon-wrapper success">
|
||||
<q-icon name="check_circle" size="56px" color="positive" />
|
||||
</div>
|
||||
<h1 class="update-title">{{ t('reset.email_sent') }}</h1>
|
||||
<p class="update-subtitle">
|
||||
<strong>{{ t('reset.check_email') }}</strong>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Success Message -->
|
||||
<q-card-section class="update-form">
|
||||
<div class="success-message">
|
||||
<p>La tua password è stata aggiornata con successo!</p>
|
||||
<q-btn
|
||||
unelevated
|
||||
color="primary"
|
||||
icon="login"
|
||||
label="Vai al Login"
|
||||
to="/login"
|
||||
class="action-btn"
|
||||
/>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" src="./updatepassword.ts">
|
||||
</script>
|
||||
<script lang="ts" src="./updatepassword.ts"></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './updatepassword';
|
||||
|
||||
Reference in New Issue
Block a user