833 lines
25 KiB
TypeScript
Executable File
833 lines
25 KiB
TypeScript
Executable File
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 RIS 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 RIS Locale',
|
|
completed: stepCircuit.value.checkOk(),
|
|
step: STEP_CIRCUIT,
|
|
});
|
|
|
|
// Step 4: Circuito Italia (solo se circuito locale completato)
|
|
steps.push({
|
|
key: 'circuitItalia',
|
|
name: 'Circuito RIS 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: true,
|
|
disabled: false,
|
|
title: 'Circuito RIS 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)) ? 'red' : 'grey',
|
|
label: stepCircuitItalia.value.checkOkReal() ? 'Fatto' : (isSalta(STEP_CIRCUIT_ITALIA)) ? '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
|
|
count++; // Circuito Locale
|
|
// if (mycircuit.value)
|
|
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 && userStore.my.profile.noCircuit) ||
|
|
(step === STEP_CIRCUIT_ITALIA && circuititalia.value && userStore.my.profile.noCircIta)
|
|
);
|
|
}
|
|
|
|
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,
|
|
};
|
|
},
|
|
});
|