- sistemazioni Email : registrazione, invio invito, email di benvenuto

- fix circuito
- profilo
This commit is contained in:
Surya Paolo
2025-11-21 20:47:35 +01:00
parent 3c5287a13c
commit 8ab7594f16
88 changed files with 1494 additions and 320 deletions

View File

@@ -13,6 +13,11 @@ export default defineComponent({
required: false,
default: false,
},
login: {
type: Boolean,
required: false,
default: false,
},
},
setup(props) {
const globalStore = useGlobalStore();

View File

@@ -1,13 +1,13 @@
<template>
<!-- Debug Info -->
<div
v-if="tools.isDebugOn()"
v-if="tools.isDebugOn() && !login"
class="debug-info"
>
<span class="debug-label">Debug:</span>
isAppRunning: {{ isAppRunning }} deferredPrompt: {{ !!deferredPrompt }}
homescreen: {{ homescreen }} isInRestrictedWebView: {{ isInRestrictedWebView }}
isInTelegramWebView: {{ tools.isInTelegramWebView() }}
isInAppBrowser: {{ tools.isInAppBrowser() }}
</div>
<!-- Main Content -->
@@ -68,9 +68,9 @@
<h4>Istruzioni per l'installazione</h4>
</div>
<!-- Telegram -->
<!-- Mobile (Telegram e altri) -->
<div
v-if="tools.isInTelegramWebView()"
v-if="$q.platform.is.mobile"
class="instruction-content"
>
<div class="step-list">
@@ -82,18 +82,24 @@
</div>
<div class="step-item">
<span class="step-number">2</span>
<span class="step-text">Scegli <strong>"Apri con..."</strong></span>
<span class="step-text">
Se in alto vedi <strong>"Apri con..."</strong>, cliccalo e scegli
Chrome, Brave o il tuo browser preferito.<br />
Altrimenti scegli <strong>"Installa app"</strong> o
<strong>"Aggiungi alla schermata Home"</strong></span
>
</div>
<div class="step-item">
<span class="step-number">3</span>
<span class="step-text"
>Seleziona il tuo browser (Chrome, Firefox, Safari...)</span
>Scegli il tuo browser preferito (Chrome, Safari, Brave...)</span
>
</div>
</div>
</div>
<!-- Altri WebView -->
<!-- Desktop/Altri -->
<div
v-else
class="instruction-content"
@@ -118,9 +124,70 @@
</transition>
</div>
<!-- App già installata -->
<div
v-else-if="isAppRunning && isPageApp"
class="install-card app-installed"
>
<div class="card-center">
<div class="icon-wrapper success">
<q-icon
name="fas fa-check-circle"
size="64px"
/>
</div>
<h3 class="card-title">App già installata! 🎉</h3>
<p class="card-description">
Ottimo! Stai già usando RISO come app installata. Puoi accedere sempre dalla
tua schermata home.
</p>
<div class="benefits-list">
<div class="benefit-item">
<q-icon
name="fas fa-bolt"
color="primary"
size="24px"
/>
<span>Accesso rapido dalla home</span>
</div>
<div class="benefit-item">
<q-icon
name="fas fa-bell"
color="primary"
size="24px"
/>
<span>Notifiche in tempo reale</span>
</div>
<div class="benefit-item">
<q-icon
name="fas fa-mobile-alt"
color="primary"
size="24px"
/>
<span>Esperienza nativa</span>
</div>
</div>
<q-btn
unelevated
rounded
size="lg"
color="primary"
class="install-btn"
to="/"
>
<q-icon
name="fas fa-home"
class="q-mr-sm"
/>
Vai alla Home
</q-btn>
</div>
</div>
<!-- Browser Esterno - NON in modalità app -->
<div
v-else-if="!isAppRunning && !hideInstallPrompt"
v-else-if="!isAppRunning && (!hideInstallPrompt || isPageApp)"
class="install-card browser-install"
>
<!-- Installazione con Prompt (Android Chrome, Desktop) -->
@@ -264,7 +331,6 @@
</q-btn>
</div>
</div>
<!-- Android -->
<div
v-else-if="$q.platform.is.android"
@@ -307,9 +373,12 @@
</div>
<div class="step-item">
<span class="step-number">2</span>
<span class="step-text"
>Scegli <strong>"Installa app"</strong> o
<strong>"Aggiungi alla home"</strong></span
<span class="step-text">
Se in alto vedi <strong>"Apri con..."</strong>, cliccalo e scegli
Chrome, Brave o il tuo browser preferito.<br />
Altrimenti scegli <strong>"Installa app"</strong> o
<strong>"Aggiungi alla schermata home"</strong></span
>
</div>
<div class="step-item">
@@ -357,7 +426,6 @@
</q-btn>
</div>
</div>
<!-- Browser Desktop (Chrome, Brave, Edge, Firefox, Safari) -->
<div
v-else-if="isDesktopBrowser && browserInfo.supported"
@@ -456,67 +524,6 @@
</div>
</div>
</div>
<!-- ✅ App già installata -->
<div
v-else-if="isAppRunning && isPageApp"
class="install-card app-installed"
>
<div class="card-center">
<div class="icon-wrapper success">
<q-icon
name="fas fa-check-circle"
size="64px"
/>
</div>
<h3 class="card-title">App già installata! 🎉</h3>
<p class="card-description">
Ottimo! Stai già usando RISO come app installata. Puoi accedere sempre dalla
tua schermata home.
</p>
<div class="benefits-list">
<div class="benefit-item">
<q-icon
name="fas fa-bolt"
color="primary"
size="24px"
/>
<span>Accesso rapido dalla home</span>
</div>
<div class="benefit-item">
<q-icon
name="fas fa-bell"
color="primary"
size="24px"
/>
<span>Notifiche in tempo reale</span>
</div>
<div class="benefit-item">
<q-icon
name="fas fa-mobile-alt"
color="primary"
size="24px"
/>
<span>Esperienza nativa</span>
</div>
</div>
<q-btn
unelevated
rounded
size="lg"
color="primary"
class="install-btn"
to="/"
>
<q-icon
name="fas fa-home"
class="q-mr-sm"
/>
Vai alla Home
</q-btn>
</div>
</div>
</transition>
</div>
</template>

View File

@@ -70,9 +70,13 @@ export default defineComponent({
const globalStore = useGlobalStore();
const circuit = ref(<IMyCircuit | ICircuit | null>null);
const account = computed(() =>
circuit.value ? userStore.getAccountByCircuitId(circuit.value._id) : null
);
const account = computed(() => {
if (groupnameSel.value) {
return userStore.getAccountGroupByCircuitId(circuit.value._id, groupnameSel.value);
} else {
return circuit.value ? userStore.getAccountByCircuitId(circuit.value._id) : null;
}
});
const qtarem = computed(() =>
account.value ? circuitStore.getRemainingCoinsToSend(account.value) : 0
@@ -84,7 +88,8 @@ export default defineComponent({
circuitStore.getFidoConcessoByUsername(
props.myuser,
circuit.value._id,
props.username
groupnameSel.value ? '' : props.username,
groupnameSel.value ? groupnameSel.value.groupname : ''
)
);

View File

@@ -37,13 +37,13 @@
v-if="circuit.link_group"
:class="` `"
>
<q-btn
<!--<q-btn
icon="fab fa-telegram"
size="xs"
color="blue"
rounded
@click.stop.prevent="tools.openUrl(circuit.link_group)"
></q-btn>
></q-btn>-->
</div>
</q-item-section>
@@ -321,6 +321,16 @@
size="sm"
>
</q-btn>
<q-btn
v-else-if="groupnameSel"
icon="fas fa-house-user"
class="q-ml-sm"
:color="Number(account.fidoConcesso) > 0 ? 'primary' : 'grey'"
text-color="white"
round
size="sm"
>
</q-btn>
</q-item-label>
</q-item-section>
<q-item-section

View File

@@ -199,7 +199,9 @@ export default defineComponent({
return (
userStore.IsMyCircuitByName(circuititalia.value.name) ||
userStore.IsAskedCircuitByName(circuititalia.value.name) ||
userStore.my.profile.noCircIta || userStore.my.profile.noCircuit || userStore.my.profile.insert_circuito_ita
userStore.my.profile.noCircIta ||
userStore.my.profile.noCircuit ||
userStore.my.profile.insert_circuito_ita
);
}
return false;
@@ -257,7 +259,8 @@ export default defineComponent({
visible: !isTelegramVerified.value,
disabled: false,
title: 'Verifica Telegram',
description: 'Collega il tuo account Telegram per accedere alle community RISO!',
description:
'Collega il tuo account Telegram per partecipare alle community RISO ed essere contattato!',
completed: isTelegramVerified.value,
avatar: {
color: isTelegramVerified.value ? 'positive' : telegramStatus.value.color,
@@ -266,8 +269,16 @@ export default defineComponent({
},
caption: isTelegramVerified.value ? 'Completato!' : telegramStatus.value.message,
badge: {
color: isTelegramVerified.value ? 'positive' : (isTelegramSkipped ? 'red' : 'orange'),
label: isTelegramVerified.value ? 'Fatto' : (isTelegramSkipped ? 'Saltato' : 'Da fare'),
color: isTelegramVerified.value
? 'positive'
: (isTelegramSkipped.value
? 'red'
: 'orange'),
label: isTelegramVerified.value
? 'Fatto'
: (isTelegramSkipped.value
? 'Saltato'
: 'Da fare'),
},
},
{
@@ -275,7 +286,8 @@ export default defineComponent({
visible: true,
disabled: false,
title: 'Circuito RIS Locale',
description: 'Seleziona la tua provincia di residenza per connetterti con la community locale.',
description:
'Seleziona la tua provincia di residenza per connetterti con la community locale.',
completed: stepCircuit.value.checkOk(),
avatar: {
color: stepCircuit.value.checkOk() ? 'positive' : 'orange',
@@ -287,8 +299,16 @@ export default defineComponent({
? 'Completato: ' + stepCircuit.value.extratitle()
: stepCircuit.value.extratitle() || 'Unisciti al circuito della tua zona',
badge: {
color: stepCircuit.value.checkOkReal() ? 'positive' : isSalta(STEP_CIRCUIT) ? 'red' : 'orange',
label: stepCircuit.value.checkOkReal() ? 'Fatto' : isSalta(STEP_CIRCUIT) ? 'Saltato' : 'Da fare',
color: stepCircuit.value.checkOkReal()
? 'positive'
: (isSalta(STEP_CIRCUIT)
? 'red'
: 'orange'),
label: stepCircuit.value.checkOkReal()
? 'Fatto'
: (isSalta(STEP_CIRCUIT)
? 'Saltato'
: 'Da fare'),
},
},
{
@@ -296,7 +316,8 @@ export default defineComponent({
visible: true,
disabled: !(circuititalia.value && stepCircuit.value.checkOkReal()),
title: 'Circuito Italia',
description: 'Entra nel circuito nazionale per accedere a opportunità in tutta Italia.',
description:
'Entra nel circuito nazionale per accedere a opportunità in tutta Italia.',
completed: stepCircuitItalia.value.checkOk(),
avatar: {
color: stepCircuitItalia.value.checkOk() ? 'positive' : 'grey-6',
@@ -308,8 +329,16 @@ export default defineComponent({
? 'Completato!'
: 'Unisciti al circuito nazionale (opzionale)',
badge: {
color: stepCircuitItalia.value.checkOkReal() ? 'positive' : (isSalta(STEP_CIRCUIT_ITALIA)) ? 'red' : 'grey',
label: stepCircuitItalia.value.checkOkReal() ? 'Fatto' : (isSalta(STEP_CIRCUIT_ITALIA)) ? 'Saltato' : 'opzionale',
color: stepCircuitItalia.value.checkOkReal()
? 'positive'
: isSalta(STEP_CIRCUIT_ITALIA)
? 'red'
: 'grey',
label: stepCircuitItalia.value.checkOkReal()
? 'Fatto'
: isSalta(STEP_CIRCUIT_ITALIA)
? 'Saltato'
: 'opzionale',
},
},
]);
@@ -426,8 +455,8 @@ export default defineComponent({
$q.notify({
type: 'positive',
message:
'Token generato! Clicca su "Apri Telegram" per completare la verifica.',
timeout: 3000,
'Token generato! Clicca su "Apri Telegram" per completare la verifica e clicca su START.',
timeout: 5000,
});
} catch (error) {
console.error('Errore nella generazione del token:', error);
@@ -448,7 +477,26 @@ export default defineComponent({
};
const openTelegramDownload = () => {
window.open('https://telegram.org/apps', '_blank');
const userAgent = navigator.userAgent.toLowerCase();
// iOS - vai su App Store
if (/iphone|ipad|ipod/.test(userAgent)) {
window.open(
'https://apps.apple.com/app/telegram-messenger/id686449807',
'_blank'
);
}
// Android - vai su Google Play
else if (/android/.test(userAgent)) {
window.open(
'https://play.google.com/store/apps/details?id=org.telegram.messenger',
'_blank'
);
}
// Desktop - vai alla pagina download
else {
window.open('https://desktop.telegram.org/', '_blank');
}
};
const skipTelegramVerification = () => {
@@ -457,6 +505,7 @@ export default defineComponent({
message:
'<p><strong>RISO utilizza Telegram per connettere la sua community in tutta Italia!</strong></p>' +
'<p style="margin-top: 12px;">' +
'✅ Contatta direttamente i membri usando il bottone "Messaggia"<br>' +
'✅ Chat provinciali e nazionali RISO attive<br>' +
'✅ Migliaia di utenti con cui interagire<br>' +
'✅ Eventi, iniziative e aggiornamenti in tempo reale<br>' +
@@ -516,6 +565,28 @@ export default defineComponent({
}
});
};
const infoTelegramVerification = () => {
$q.dialog({
title: 'Perché Telegram?',
message:
'<p><strong>RISO utilizza Telegram per connettere la sua community in tutta Italia!</strong></p>' +
'<p style="margin-top: 12px;">' +
'✅ Contatta direttamente i membri usando il bottone "Messaggia"<br>' +
'✅ Chat provinciali e nazionali RISO attive<br>' +
'✅ Migliaia di utenti con cui interagire<br>' +
'✅ Eventi, iniziative e aggiornamenti in tempo reale<br>' +
'✅ Gruppi ampi senza limiti WhatsApp<br>' +
'✅ Gratuito, sicuro e senza pubblicità' +
'</p>' +
'<p style="margin-top: 12px;"><em>Unisciti alla community su Telegram e scopri tutto quello che RISO ha da offrire!</em></p>',
html: true,
ok: {
label: 'Chiudi',
color: 'primary',
},
persistent: true,
});
};
const startPolling = () => {
pollingInterval.value = setInterval(async () => {
@@ -541,7 +612,7 @@ export default defineComponent({
} catch (error) {
console.error('Errore nel controllo verifica:', error);
}
}, 3000);
}, 5000);
};
const stopPolling = () => {
@@ -573,7 +644,9 @@ export default defineComponent({
function isSalta(step: number) {
return (
(step === STEP_CIRCUIT && mycircuit.value && userStore.my.profile.noCircuit) ||
(step === STEP_CIRCUIT_ITALIA && circuititalia.value && userStore.my.profile.noCircIta)
(step === STEP_CIRCUIT_ITALIA &&
circuititalia.value &&
userStore.my.profile.noCircIta)
);
}
@@ -808,6 +881,7 @@ export default defineComponent({
startTelegramVerification,
openTelegramBot,
skipTelegramVerification,
infoTelegramVerification,
openTelegramDownload,
// Methods - Navigation

View File

@@ -45,7 +45,11 @@
v-show="stepConfig.visible"
group="gruppo1"
:model-value="openedStep === stepConfig.key"
@update:model-value="(val) => { if (val) openedStep = stepConfig.key }"
@update:model-value="
(val) => {
if (val) openedStep = stepConfig.key;
}
"
:disable="stepConfig.disabled"
class="step-item"
:class="{ 'step-completed': stepConfig.completed }"
@@ -92,7 +96,10 @@
</template>
<!-- Contenuto specifico per ogni step -->
<q-card v-if="!stepConfig.disabled" class="step-content">
<q-card
v-if="!stepConfig.disabled"
class="step-content"
>
<q-card-section class="q-pa-md">
<p class="step-description">
{{ stepConfig.description }}
@@ -121,26 +128,50 @@
rounded
color="positive"
icon="fab fa-telegram"
label="Apri Telegram"
label="Apri Bot Telegram"
@click="openTelegramBot"
class="action-btn"
class="action-btn q-mb-md"
/>
<q-spinner-dots
v-else
color="primary"
size="32px"
/>
<q-banner
v-if="verificationToken"
class="bg-blue-1 text-blue-9"
rounded
>
<div class="text-body2">
<strong>Passo 1:</strong> Clicca il bottone sopra<br />
<strong>Passo 2:</strong> Nel bot clicca <strong>AVVIA</strong> o
<strong>START</strong> <br />
<strong>Passo 3:</strong> Ritorna su questa pagina.
</div>
</q-banner>
<div style="display: flex; justify-content: center">
<q-spinner-dots
v-if="isVerifying && verificationToken"
color="primary"
size="32px"
/>
</div>
<q-btn
flat
v-if="!verificationToken"
rounded
dense
outline
color="grey-7"
label="Perché Telegram?"
icon="help_outline"
@click="skipTelegramVerification"
size="sm"
@click="infoTelegramVerification"
class="skip-btn"
/>
<q-btn
v-if="!verificationToken"
rounded
outline
color="primary"
label="Installa Telegram"
icon="fab fa-telegram"
@click="openTelegramDownload"
class="skip-btn"
/>
</div>
@@ -162,7 +193,9 @@
<div v-if="stepResidence.checkOk()">
<CMySelectCity
v-if="globalStore.isPresenteCardsByProv(contact.profile.resid_province)"
v-if="
globalStore.isPresenteCardsByProv(contact.profile.resid_province)
"
:label="$t('reg.resid_card')"
table="users"
jointable="cards"

View File

@@ -64,7 +64,7 @@ export default defineComponent({
function created() {
onReset()
if (userStore.resStatus === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN) {
if (userStore.resStatus === serv_constants.RIS_CODE__HTTP_INVALID_TOKEN) {
emit('showNotif', 'fetch.error_doppiologin')
}

View File

@@ -1,6 +1,6 @@
<template>
<div>
<div v-if="enablePwa"><CCheckAppRunning /></div>
<div v-if="enablePwa"><CCheckAppRunning :login="true"/></div>
<div class="text-center">
<p>
<logo></logo>

View File

@@ -10,7 +10,7 @@
(site.confpages?.enableRegMultiChoice || !site.confpages?.enabledRegNeedTelegram)
"
>
<CVerifyEmail v-if="isLogged && !isEmailVerified && !telegVerificato" />
<CVerifyEmail v-if="isLogged && !isEmailVerified && !telegVerificato && tools.getUserEmail()" />
</div>
<!-- Waiting for Admission Section -->
@@ -35,24 +35,9 @@
<div class="info-box">
<div class="info-text">
<p>
Sei in attesa di essere ammesso da
Siete in attesa di essere ammessi da
<strong>{{ tools.getAportadorSolidario() }}</strong>
</p>
<p class="small-text">
Riceverai una notifica sulla chat Telegram
<a
:href="tools.getLinkBotTelegram('', '')"
target="_blank"
class="telegram-link"
>
<q-icon
name="fab fa-telegram"
size="16px"
/>
{{ tools.getBotName() }}
</a>
</p>
</div>
</div>

View File

@@ -24,9 +24,9 @@
<div class="info-box">
<q-icon name="info" size="20px" color="primary" />
<div class="info-text">
<p class="instruction-title">Controlla la tua casella email</p>
<p class="instruction-title">Controlla la tua casella email </p>
<p class="instruction-text">
Ti abbiamo inviato un'email a <strong>{{ tools.getUserEmail() }}</strong>
Ti abbiamo inviato un'email a '<strong>{{ tools.getUserEmail() }}</strong>'
</p>
<p class="instruction-text">
Cerca l'email "<strong>Conferma Registrazione</strong>" e clicca sul bottone di verifica

View File

@@ -42,7 +42,7 @@
</h1>
<h2 class="hero-subtitle animate-fade-in-delay">
Rete Italiana di Scambio Orizzontale
Rete Italiana Scambi orizzontali
</h2>
<p class="hero-description animate-fade-in-delay-2">
@@ -855,7 +855,7 @@
<q-separator class="footer-separator" />
<div class="footer-bottom">
<p>{{ currentYear }} RISO - Rete Italiana di Scambio Orizzontale</p>
<p>{{ currentYear }} RISO - Rete Italiana Scambi orizzontali</p>
<p class="footer-values">
Comunità · Fiducia · Scambi Solidali · Sostenibilità
</p>

View File

@@ -857,6 +857,7 @@ $text-light: #666; // Grigio medio
.cta-buttons {
margin-bottom: 4rem;
margin-top: 8px;
@media (max-width: 768px) {
margin-bottom: 1rem;

View File

@@ -112,7 +112,7 @@ export default defineComponent({
},
{
title: 'Usa i RIS',
text: 'Scambia in RIS, anche parzialmente: puoi combinare RIS con Euro, baratto o dono nella stessa transazione. Parti da 0 RIS: quando ricevi vai in positivo, quando offri vai in negativo. Più usi i RIS, meno dipendi dall\'economia tradizionale.'
text: 'Scambia in RIS, anche parzialmente: puoi combinare RIS con Euro, baratto o dono nella stessa transazione. Parti da 0 RIS: quando ricevi vai in positivo, quando invii vai in negativo. Più usi i RIS, meno dipendi dall\'economia tradizionale.'
},
]);

View File

@@ -42,7 +42,7 @@
</h1>
<h2 class="hero-subtitle animate-fade-in-delay">
Rete Italiana di Scambio Orizzontale
Rete Italiana Scambi orizzontali
</h2>
<p class="hero-description animate-fade-in-delay-2">
@@ -309,8 +309,8 @@
<q-card-section>
<p class="ris-description">
Il <strong>RIS</strong> è l'unità di misura del valore dei beni e
servizi per lo scambio tra i membri di una comunità territoriale. È una
moneta complementare basata sulla <strong>fiducia reciproca</strong> tra
servizi per lo scambio tra i membri di una comunità territoriale. È uno strumento di scambio
basato sulla <strong>fiducia reciproca</strong> tra
i membri della comunità.<br />
</p>
<q-separator class="q-my-md" />
@@ -321,7 +321,7 @@
color="positive"
/>
<span
>Parti da 0 RIS: ricevere = credito (+), offrire = debito (-)</span
>Parti da 0 RIS: ricevere = credito (+), inviare = debito (-)</span
>
</div>
<div class="ris-feature-item">
@@ -660,6 +660,8 @@
/>
</div>
<CCheckAppRunning />
<!-- Info App -->
<div class="app-features">
<div class="feature-badge">
@@ -696,7 +698,6 @@
</div>
</div>
<CCheckAppRunning />
</div>
</div>
</section>
@@ -806,7 +807,7 @@
<q-separator class="footer-separator" />
<div class="footer-bottom">
<p>(dal 2021) RISO - Rete Italiana di Scambio Orizzontale</p>
<p>(dal 2021) RISO - Rete Italiana Scambi orizzontali</p>
<p class="footer-values">
Comunità · Fiducia · Scambi Solidali · Sostenibilità
</p>