- aggiornata la grafica della Home di RISO
- Profilo Completition - Email Verificata - Invita un Amico (invio di email)
This commit is contained in:
831
src/components/CProfileCompletitionBanner/CProfileCompletitionBanner.ts
Executable file
831
src/components/CProfileCompletitionBanner/CProfileCompletitionBanner.ts
Executable file
@@ -0,0 +1,831 @@
|
||||
import type { PropType } from 'vue';
|
||||
import { computed, defineComponent, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
||||
|
||||
import { tools } from '@tools';
|
||||
import { useGlobalStore } from '@store/globalStore';
|
||||
import { useUserStore } from '@store/UserStore';
|
||||
import { useCircuitStore } from '@store/CircuitStore';
|
||||
import { Api } from 'app/src/store/Api';
|
||||
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import type { ICircuit, IUserFields } from 'model';
|
||||
import { costanti } from '@costanti';
|
||||
import { shared_consts } from '@src/common/shared_vuejs';
|
||||
|
||||
import { CMySelectCity } from '@src/components/CMySelectCity';
|
||||
import { CMyCircuit } from '@src/components/CMyCircuit';
|
||||
import { CMyUser } from '@src/components/CMyUser';
|
||||
|
||||
const STEP_CITY = 100;
|
||||
const STEP_CIRCUIT = 200;
|
||||
const STEP_CIRCUIT_ITALIA = 210;
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CProfileCompletitionBanner',
|
||||
components: {
|
||||
CMySelectCity,
|
||||
CMyCircuit,
|
||||
CMyUser,
|
||||
},
|
||||
props: {
|
||||
showAlsoIfSkipped: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
mycontact: {
|
||||
type: Object as PropType<IUserFields | null>,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
myusername: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
|
||||
setup(props) {
|
||||
const $q = useQuasar();
|
||||
const { t } = useI18n();
|
||||
const userStore = useUserStore();
|
||||
const circuitStore = useCircuitStore();
|
||||
const globalStore = useGlobalStore();
|
||||
const $router = useRouter();
|
||||
const $route = useRoute();
|
||||
|
||||
// ========================================
|
||||
// TELEGRAM VERIFICATION STATE
|
||||
// ========================================
|
||||
const verificationToken = ref(null);
|
||||
const isGeneratingToken = ref(false);
|
||||
const isVerifying = ref(false);
|
||||
const pollingInterval = ref(null);
|
||||
|
||||
// ========================================
|
||||
// TUTORIAL STATE
|
||||
// ========================================
|
||||
const contact = ref(<IUserFields | null>null);
|
||||
const activeStep = ref<string | null>('telegram');
|
||||
const currentStepIndex = ref(0); // Indice step corrente per navigazione
|
||||
const nascondiavviso = ref(false);
|
||||
const showBanner_utenti_verif = ref(true);
|
||||
const circuitsel = ref('');
|
||||
const mycircuit = ref(<ICircuit | undefined | null>null);
|
||||
const circuititalia = ref(<ICircuit | undefined | null>null);
|
||||
const mylistcircuits = ref(<ICircuit[] | undefined>[]);
|
||||
const usersList = ref({ show: false, title: '', list: [] });
|
||||
|
||||
// Stato apertura/chiusura expansion items - controlla quale step è aperto
|
||||
const openedStep = ref<string | null>(null);
|
||||
|
||||
// ========================================
|
||||
// COMPUTED - TELEGRAM
|
||||
// ========================================
|
||||
const isTelegramSkipped = computed(() => {
|
||||
return userStore.my?.profile?.telegram_verification_skipped;
|
||||
});
|
||||
|
||||
const isTelegramVerified = computed(() => {
|
||||
return (
|
||||
!!(userStore.my?.profile?.username_telegram && userStore.my?.profile?.teleg_id) ||
|
||||
(!props.showAlsoIfSkipped && isTelegramSkipped.value)
|
||||
);
|
||||
});
|
||||
|
||||
const telegramStatus = computed(() => {
|
||||
if (isVerifying.value) {
|
||||
return {
|
||||
icon: 'hourglass_empty',
|
||||
color: 'orange',
|
||||
message: 'In attesa di verifica...',
|
||||
};
|
||||
}
|
||||
return {
|
||||
icon: 'fab fa-telegram',
|
||||
color: 'grey-6',
|
||||
message: 'Collega il tuo account Telegram',
|
||||
};
|
||||
});
|
||||
|
||||
// ========================================
|
||||
// COMPUTED - TUTORIAL STEPS
|
||||
// ========================================
|
||||
const strProv = computed(() => {
|
||||
if (contact.value && contact.value.profile.resid_province) {
|
||||
return contact.value.profile.resid_province;
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
const card = computed(() => {
|
||||
if (contact.value && contact.value.profile.resid_card) {
|
||||
return contact.value.profile.resid_card;
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
const userstoverify = computed(() => {
|
||||
return userStore.my.profile.userstoverify;
|
||||
});
|
||||
|
||||
// Step definitions
|
||||
const stepResidence = computed(() => ({
|
||||
step: STEP_CITY,
|
||||
title: t('tutorial.step_residence_title'),
|
||||
extratitle: function () {
|
||||
return contact.value?.profile.resid_province
|
||||
? ': ' + contact.value.profile.resid_province
|
||||
: '';
|
||||
},
|
||||
label: t('tutorial.step_residence'),
|
||||
checkOk: function (): boolean {
|
||||
return contact.value
|
||||
? !!contact.value.profile.resid_province &&
|
||||
contact.value.profile.resid_province !== '' &&
|
||||
contact.value.profile.resid_province !== '0'
|
||||
: false;
|
||||
},
|
||||
checkOkReal: function (): boolean {
|
||||
return this.checkOk();
|
||||
},
|
||||
icon: 'house',
|
||||
required: true,
|
||||
}));
|
||||
|
||||
const stepCircuit = computed(() => ({
|
||||
step: STEP_CIRCUIT,
|
||||
title: t('tutorial.step_circuito_title'),
|
||||
extratitle: function () {
|
||||
return mycircuit.value ? ': ' + mycircuit.value.name : '';
|
||||
},
|
||||
label: t('tutorial.step_circuito'),
|
||||
label_ok: t('tutorial.step_circuito_ok'),
|
||||
checkOk: function () {
|
||||
if (mycircuit.value) {
|
||||
return (
|
||||
userStore.IsMyCircuitByName(mycircuit.value.name) ||
|
||||
userStore.IsAskedCircuitByName(mycircuit.value.name) ||
|
||||
userStore.my.profile.noCircuit
|
||||
);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
checkOkReal: function () {
|
||||
if (mycircuit.value) {
|
||||
return (
|
||||
userStore.IsMyCircuitByName(mycircuit.value.name) ||
|
||||
userStore.IsAskedCircuitByName(mycircuit.value.name)
|
||||
);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
icon: 'img: /images/1ris_rosso_100.png',
|
||||
required: false,
|
||||
}));
|
||||
|
||||
const stepCircuitItalia = computed(() => ({
|
||||
step: STEP_CIRCUIT_ITALIA,
|
||||
title: t('tutorial.step_circuito_italia_title') || 'Circuito Italia',
|
||||
extratitle: function () {
|
||||
return circuititalia.value ? ': ' + circuititalia.value.name : '';
|
||||
},
|
||||
label: t('tutorial.step_circuito_italia') || 'Unisciti al circuito nazionale',
|
||||
checkOk: function (reale?: boolean) {
|
||||
if (circuititalia.value) {
|
||||
return (
|
||||
userStore.IsMyCircuitByName(circuititalia.value.name) ||
|
||||
userStore.IsAskedCircuitByName(circuititalia.value.name) ||
|
||||
userStore.my.profile.noCircIta || userStore.my.profile.noCircuit
|
||||
);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
checkOkReal: function () {
|
||||
if (circuititalia.value) {
|
||||
return (
|
||||
userStore.IsMyCircuitByName(circuititalia.value.name) ||
|
||||
userStore.IsAskedCircuitByName(circuititalia.value.name)
|
||||
);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
icon: 'img: /images/1ris_rosso_100.png',
|
||||
required: false,
|
||||
}));
|
||||
|
||||
// ========================================
|
||||
// COMPUTED - LISTA STEP ORDINATA E CONFIGURAZIONE UI
|
||||
// ========================================
|
||||
const orderedSteps = computed(() => {
|
||||
const steps = [];
|
||||
|
||||
// Step 1: Telegram
|
||||
steps.push({
|
||||
key: 'telegram',
|
||||
name: 'Telegram',
|
||||
completed: isTelegramVerified.value,
|
||||
step: 0,
|
||||
});
|
||||
|
||||
// Step 3: Circuito Locale (solo se disponibile)
|
||||
steps.push({
|
||||
key: 'circuit',
|
||||
name: 'Circuito Locale',
|
||||
completed: stepCircuit.value.checkOk(),
|
||||
step: STEP_CIRCUIT,
|
||||
});
|
||||
|
||||
// Step 4: Circuito Italia (solo se circuito locale completato)
|
||||
steps.push({
|
||||
key: 'circuitItalia',
|
||||
name: 'Circuito Italia',
|
||||
completed: stepCircuitItalia.value.checkOk(),
|
||||
step: STEP_CIRCUIT_ITALIA,
|
||||
});
|
||||
|
||||
return steps;
|
||||
});
|
||||
|
||||
// Configurazione UI per ogni step
|
||||
const stepsConfig = computed(() => [
|
||||
{
|
||||
key: 'telegram',
|
||||
visible: !isTelegramVerified.value,
|
||||
disabled: false,
|
||||
title: 'Verifica Telegram',
|
||||
description: 'Collega il tuo account Telegram per accedere alle community RISO!',
|
||||
completed: isTelegramVerified.value,
|
||||
avatar: {
|
||||
color: isTelegramVerified.value ? 'positive' : telegramStatus.value.color,
|
||||
icon: isTelegramVerified.value ? 'check' : telegramStatus.value.icon,
|
||||
isImage: false,
|
||||
},
|
||||
caption: isTelegramVerified.value ? 'Completato!' : telegramStatus.value.message,
|
||||
badge: {
|
||||
color: isTelegramVerified.value ? 'positive' : 'orange',
|
||||
label: isTelegramVerified.value ? 'Fatto' : 'Da fare',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'circuit',
|
||||
visible: !!mycircuit.value,
|
||||
disabled: false,
|
||||
title: 'Circuito 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',
|
||||
icon: stepCircuit.value.checkOk() ? 'check' : '',
|
||||
isImage: !stepCircuit.value.checkOk(),
|
||||
imageSrc: '/images/1ris_rosso_100.png',
|
||||
},
|
||||
caption: stepCircuit.value.checkOk()
|
||||
? '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',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'circuitItalia',
|
||||
visible: true,
|
||||
disabled: !(circuititalia.value && stepCircuit.value.checkOkReal()),
|
||||
title: 'Circuito 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',
|
||||
icon: stepCircuitItalia.value.checkOk() ? 'check' : '',
|
||||
isImage: !stepCircuitItalia.value.checkOk(),
|
||||
imageSrc: '/images/1ris_rosso_100.png',
|
||||
},
|
||||
caption: stepCircuitItalia.value.checkOk()
|
||||
? 'Completato!'
|
||||
: 'Unisciti al circuito nazionale (opzionale)',
|
||||
badge: {
|
||||
color: stepCircuitItalia.value.checkOkReal() ? 'positive' : (isSalta(STEP_CIRCUIT_ITALIA) || isSalta(STEP_CIRCUIT)) ? 'red' : 'grey',
|
||||
label: stepCircuitItalia.value.checkOkReal() ? 'Fatto' : (isSalta(STEP_CIRCUIT_ITALIA) || isSalta(STEP_CIRCUIT)) ? 'Saltato' : 'opzionale',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
// ========================================
|
||||
// COMPUTED - NAVIGATION
|
||||
// ========================================
|
||||
const canGoPrevious = computed(() => {
|
||||
return currentStepIndex.value > 0;
|
||||
});
|
||||
|
||||
const canGoNext = computed(() => {
|
||||
return currentStepIndex.value < orderedSteps.value.length - 1;
|
||||
});
|
||||
|
||||
const currentStep = computed(() => {
|
||||
return orderedSteps.value[currentStepIndex.value];
|
||||
});
|
||||
|
||||
const canAdvanceCurrentStep = computed(() => {
|
||||
if (!currentStep.value) return false;
|
||||
return currentStep.value.completed;
|
||||
});
|
||||
|
||||
const showSkipButton = computed(() => {
|
||||
if (!currentStep.value) return false;
|
||||
return isSalta(currentStep.value.step);
|
||||
});
|
||||
|
||||
const isCurrentStepCircuit = computed(() => {
|
||||
if (!currentStep.value) return false;
|
||||
// Mostra bottone Salta se lo step corrente è un circuito (locale o italia)
|
||||
return (
|
||||
currentStep.value.step === STEP_CIRCUIT ||
|
||||
currentStep.value.step === STEP_CIRCUIT_ITALIA
|
||||
);
|
||||
});
|
||||
|
||||
// ========================================
|
||||
// COMPUTED - COMPLETION
|
||||
// ========================================
|
||||
const totalSteps = computed(() => {
|
||||
let count = 0;
|
||||
count++; // Telegram
|
||||
if (mycircuit.value) count++; // Circuito Locale
|
||||
if (circuititalia.value) count++; // Circuito Italia
|
||||
return count;
|
||||
});
|
||||
|
||||
const completedSteps = computed(() => {
|
||||
let count = 0;
|
||||
if (isTelegramVerified.value) count++;
|
||||
if (stepCircuit.value.checkOk()) count++;
|
||||
if (stepCircuitItalia.value.checkOk()) count++;
|
||||
return count;
|
||||
});
|
||||
|
||||
const completionPercentage = computed(() => {
|
||||
if (totalSteps.value === 0) return 100;
|
||||
return Math.round((completedSteps.value / totalSteps.value) * 100);
|
||||
});
|
||||
|
||||
const isProfileComplete = computed(() => {
|
||||
return completionPercentage.value === 100;
|
||||
});
|
||||
|
||||
// ========================================
|
||||
// METHODS - NAVIGATION
|
||||
// ========================================
|
||||
function goToPreviousStep() {
|
||||
if (canGoPrevious.value) {
|
||||
currentStepIndex.value--;
|
||||
updateExpandedSteps();
|
||||
}
|
||||
}
|
||||
|
||||
function goToNextStep() {
|
||||
if (canGoNext.value && canAdvanceCurrentStep.value) {
|
||||
currentStepIndex.value++;
|
||||
updateExpandedSteps();
|
||||
}
|
||||
}
|
||||
|
||||
function skipCurrentStep() {
|
||||
if (!currentStep.value) return;
|
||||
askToConfirmSkip(currentStep.value.step);
|
||||
}
|
||||
|
||||
function updateExpandedSteps() {
|
||||
// Apri lo step corrente
|
||||
const current = orderedSteps.value[currentStepIndex.value];
|
||||
if (current) {
|
||||
openedStep.value = current.key;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// TELEGRAM METHODS
|
||||
// ========================================
|
||||
const startTelegramVerification = async () => {
|
||||
isGeneratingToken.value = true;
|
||||
|
||||
try {
|
||||
const response = await Api.SendReq('/api/telegram/generate-token', 'POST', {
|
||||
username: userStore.my.username,
|
||||
});
|
||||
|
||||
verificationToken.value = response.data.token;
|
||||
isVerifying.value = true;
|
||||
|
||||
startPolling();
|
||||
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
message:
|
||||
'Token generato! Clicca su "Apri Telegram" per completare la verifica.',
|
||||
timeout: 3000,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Errore nella generazione del token:', error);
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: 'Errore nella generazione del token. Riprova.',
|
||||
timeout: 2000,
|
||||
});
|
||||
} finally {
|
||||
isGeneratingToken.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const openTelegramBot = () => {
|
||||
const telegramUrl =
|
||||
tools.getLinkBotTelegram('', '') + `?start=${verificationToken.value}`;
|
||||
window.open(telegramUrl, '_blank');
|
||||
};
|
||||
|
||||
const openTelegramDownload = () => {
|
||||
window.open('https://telegram.org/apps', '_blank');
|
||||
};
|
||||
|
||||
const skipTelegramVerification = () => {
|
||||
$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;">' +
|
||||
'✅ 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,
|
||||
options: {
|
||||
type: 'radio',
|
||||
model: 'install',
|
||||
items: [
|
||||
{
|
||||
label: 'Non ho Telegram, voglio installarlo ora',
|
||||
value: 'install',
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
label: 'Salto per ora (potrò farlo in seguito)',
|
||||
value: 'skip',
|
||||
color: 'grey-7',
|
||||
},
|
||||
],
|
||||
},
|
||||
cancel: {
|
||||
label: 'Annulla',
|
||||
flat: true,
|
||||
color: 'grey-7',
|
||||
},
|
||||
ok: {
|
||||
label: 'Conferma',
|
||||
color: 'primary',
|
||||
},
|
||||
persistent: true,
|
||||
}).onOk((choice) => {
|
||||
if (choice === 'install') {
|
||||
openTelegramDownload();
|
||||
$q.notify({
|
||||
type: 'info',
|
||||
message: 'Torna qui dopo aver installato Telegram!',
|
||||
icon: 'fab fa-telegram',
|
||||
timeout: 3000,
|
||||
});
|
||||
} else {
|
||||
stopPolling();
|
||||
isVerifying.value = false;
|
||||
verificationToken.value = null;
|
||||
|
||||
userStore.setSkipTelegramVerif(true);
|
||||
|
||||
$q.notify({
|
||||
type: 'info',
|
||||
message: 'Potrai collegare Telegram in seguito dalle impostazioni.',
|
||||
icon: 'info',
|
||||
timeout: 2500,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const startPolling = () => {
|
||||
pollingInterval.value = setInterval(async () => {
|
||||
try {
|
||||
const response = await Api.SendReq('/api/telegram/check-verification', 'GET', {
|
||||
token: verificationToken.value,
|
||||
});
|
||||
|
||||
if (response.data.verified) {
|
||||
stopPolling();
|
||||
isVerifying.value = false;
|
||||
verificationToken.value = null;
|
||||
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
message: 'Telegram verificato con successo!',
|
||||
icon: 'check_circle',
|
||||
timeout: 3000,
|
||||
});
|
||||
|
||||
await userStore.refreshUserData(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Errore nel controllo verifica:', error);
|
||||
}
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
const stopPolling = () => {
|
||||
if (pollingInterval.value) {
|
||||
clearInterval(pollingInterval.value);
|
||||
pollingInterval.value = null;
|
||||
}
|
||||
};
|
||||
|
||||
// ========================================
|
||||
// CIRCUIT SKIP METHODS
|
||||
// ========================================
|
||||
function isAskedToCircuit(): boolean {
|
||||
return !!(
|
||||
mycircuit.value &&
|
||||
!userStore.IsMyCircuitByName(mycircuit.value.name) &&
|
||||
!userStore.IsAskedCircuitByName(mycircuit.value.name)
|
||||
);
|
||||
}
|
||||
|
||||
function isAskedToCircuitItalia(): boolean {
|
||||
return !!(
|
||||
circuititalia.value &&
|
||||
!userStore.IsMyCircuitByName(circuititalia.value.name) &&
|
||||
!userStore.IsAskedCircuitByName(circuititalia.value.name)
|
||||
);
|
||||
}
|
||||
|
||||
function isSalta(step: number) {
|
||||
return (
|
||||
(step === STEP_CIRCUIT && mycircuit.value && isAskedToCircuit()) ||
|
||||
(step === STEP_CIRCUIT_ITALIA && circuititalia.value && isAskedToCircuitItalia())
|
||||
);
|
||||
}
|
||||
|
||||
function askToConfirmSkip(mystep: number) {
|
||||
if (mystep === STEP_CIRCUIT) {
|
||||
return $q
|
||||
.dialog({
|
||||
message: t('circuit.skipentercircuit'),
|
||||
html: true,
|
||||
ok: {
|
||||
label: t('dialog.yes'),
|
||||
push: false,
|
||||
},
|
||||
title: '',
|
||||
cancel: true,
|
||||
persistent: false,
|
||||
})
|
||||
.onOk(() => {
|
||||
userStore.savenoCircuit(isAskedToCircuit());
|
||||
// Avanza allo step successivo
|
||||
if (canGoNext.value) {
|
||||
goToNextStep();
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.onCancel(() => {
|
||||
return false;
|
||||
});
|
||||
} else if (mystep === STEP_CIRCUIT_ITALIA) {
|
||||
askToConfirmSkipItalia(mystep);
|
||||
}
|
||||
}
|
||||
|
||||
function askToConfirmSkipItalia(mystep: number) {
|
||||
return $q
|
||||
.dialog({
|
||||
message: t('circuit.skipentercircuit_italia'),
|
||||
html: true,
|
||||
ok: {
|
||||
label: t('dialog.yes'),
|
||||
push: false,
|
||||
},
|
||||
title: '',
|
||||
cancel: true,
|
||||
persistent: false,
|
||||
})
|
||||
.onOk(() => {
|
||||
if (mystep === STEP_CIRCUIT_ITALIA) {
|
||||
userStore.savenoCircIta(isAskedToCircuitItalia());
|
||||
}
|
||||
// Avanza allo step successivo
|
||||
if (canGoNext.value) {
|
||||
goToNextStep();
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.onCancel(() => {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// TUTORIAL METHODS
|
||||
// ========================================
|
||||
const updateContact = () => {
|
||||
if (!props.mycontact) {
|
||||
contact.value = userStore.my;
|
||||
} else {
|
||||
contact.value = props.mycontact;
|
||||
}
|
||||
|
||||
if (
|
||||
contact.value &&
|
||||
contact.value.profile &&
|
||||
contact.value.profile.resid_province === '0'
|
||||
) {
|
||||
contact.value.profile.resid_province = '';
|
||||
}
|
||||
|
||||
// Trova il primo step non completato e aprilo
|
||||
const firstIncompleteIndex = orderedSteps.value.findIndex(
|
||||
(step) => !step.completed
|
||||
);
|
||||
if (firstIncompleteIndex !== -1) {
|
||||
currentStepIndex.value = firstIncompleteIndex;
|
||||
updateExpandedSteps();
|
||||
}
|
||||
};
|
||||
|
||||
// ========================================
|
||||
// WATCHERS
|
||||
// ========================================
|
||||
watch(
|
||||
() => strProv.value,
|
||||
(newval: string) => {
|
||||
mycircuit.value = circuitStore.getCircuitByProvinceAndCard(
|
||||
strProv.value,
|
||||
card.value
|
||||
);
|
||||
if (!globalStore.isPresenteCardsByProv(strProv.value)) {
|
||||
if (contact.value && contact.value.profile.resid_card) {
|
||||
contact.value.profile.resid_card = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => card.value,
|
||||
() => {
|
||||
mycircuit.value = circuitStore.getCircuitByProvinceAndCard(
|
||||
strProv.value,
|
||||
card.value
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => circuitsel.value,
|
||||
() => {
|
||||
if (circuitsel.value) {
|
||||
mycircuit.value = circuitStore.getCircuitByName(circuitsel.value);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Watch per aggiornare lo step corrente quando uno viene completato
|
||||
watch([isTelegramVerified, () => stepCircuit.value.checkOk()], () => {
|
||||
// Trova il primo step non completato
|
||||
const firstIncompleteIndex = orderedSteps.value.findIndex(
|
||||
(step) => !step.completed
|
||||
);
|
||||
if (
|
||||
firstIncompleteIndex !== -1 &&
|
||||
firstIncompleteIndex !== currentStepIndex.value
|
||||
) {
|
||||
// Aggiorna solo se diverso dallo step corrente
|
||||
currentStepIndex.value = firstIncompleteIndex;
|
||||
updateExpandedSteps();
|
||||
}
|
||||
});
|
||||
|
||||
// Watch per sincronizzare openedStep con currentStepIndex
|
||||
// Quando l'utente apre manualmente uno step diverso, aggiorna currentStepIndex
|
||||
watch(openedStep, (newOpenedStep) => {
|
||||
if (newOpenedStep) {
|
||||
const stepIndex = orderedSteps.value.findIndex(
|
||||
(step) => step.key === newOpenedStep
|
||||
);
|
||||
if (stepIndex !== -1 && stepIndex !== currentStepIndex.value) {
|
||||
currentStepIndex.value = stepIndex;
|
||||
}
|
||||
} else {
|
||||
// Se openedStep è null (tutti chiusi), apri lo step corrente
|
||||
// Questo garantisce che ci sia sempre almeno uno step aperto
|
||||
if (orderedSteps.value.length > 0) {
|
||||
const current = orderedSteps.value[currentStepIndex.value];
|
||||
if (current) {
|
||||
openedStep.value = current.key;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// ========================================
|
||||
// LIFECYCLE
|
||||
// ========================================
|
||||
onMounted(() => {
|
||||
// Initialize circuits
|
||||
circuititalia.value = circuitStore.getCircuitByPath('ris_italia');
|
||||
|
||||
// Initialize contact
|
||||
if (userStore.isUserOk()) {
|
||||
updateContact();
|
||||
|
||||
// Initialize circuits based on residence
|
||||
if (contact.value?.profile.resid_province) {
|
||||
mylistcircuits.value = circuitStore.getCircuitsNameByProvince(strProv.value);
|
||||
mycircuit.value = circuitStore.getCircuitByProvinceAndCard(
|
||||
strProv.value,
|
||||
card.value
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
stopPolling();
|
||||
});
|
||||
|
||||
return {
|
||||
// State
|
||||
contact,
|
||||
activeStep,
|
||||
currentStepIndex,
|
||||
verificationToken,
|
||||
isGeneratingToken,
|
||||
isVerifying,
|
||||
nascondiavviso,
|
||||
showBanner_utenti_verif,
|
||||
circuitsel,
|
||||
mycircuit,
|
||||
circuititalia,
|
||||
mylistcircuits,
|
||||
usersList,
|
||||
openedStep,
|
||||
|
||||
// Computed
|
||||
isTelegramVerified,
|
||||
isTelegramSkipped,
|
||||
telegramStatus,
|
||||
isProfileComplete,
|
||||
completionPercentage,
|
||||
totalSteps,
|
||||
completedSteps,
|
||||
stepResidence,
|
||||
stepCircuit,
|
||||
stepCircuitItalia,
|
||||
userstoverify,
|
||||
|
||||
// Navigation Computed
|
||||
canGoPrevious,
|
||||
canGoNext,
|
||||
canAdvanceCurrentStep,
|
||||
showSkipButton,
|
||||
isCurrentStepCircuit,
|
||||
orderedSteps,
|
||||
currentStep,
|
||||
stepsConfig,
|
||||
|
||||
// Methods - Telegram
|
||||
startTelegramVerification,
|
||||
openTelegramBot,
|
||||
skipTelegramVerification,
|
||||
openTelegramDownload,
|
||||
|
||||
// Methods - Navigation
|
||||
goToPreviousStep,
|
||||
goToNextStep,
|
||||
skipCurrentStep,
|
||||
|
||||
// Methods - Circuit
|
||||
isSalta,
|
||||
askToConfirmSkip,
|
||||
askToConfirmSkipItalia,
|
||||
|
||||
// Stores & Utils
|
||||
tools,
|
||||
userStore,
|
||||
globalStore,
|
||||
costanti,
|
||||
t,
|
||||
$q,
|
||||
};
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user