-
-
-
-
- Telegram
-
-
-
-
-
-
-
+
+
+
+
-
-
-
+
+
+
+
+
+
+
Verificato
+
da {{ myuser.aportador_solidario }}
+
+
-
-
-
-
-
-
-
+
+
+
+
Non Verificato
+
da {{ myuser.aportador_solidario }}
+
+
+
+
+
+
+
+
Utente Segnalato
+
+ {{
+ t('db.reporteduser', {
+ date_report: tools.getstrDateTimeShort(myuser.date_report),
+ })
+ }}
+
da: {{ myuser.username_who_report }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
diff --git a/src/statics/lang/it.js b/src/statics/lang/it.js
index 382f98ac..dedf5b6a 100755
--- a/src/statics/lang/it.js
+++ b/src/statics/lang/it.js
@@ -49,6 +49,8 @@ const msg_it = {
data_choose: 'Scegli la Data',
},
profile: {
+ dark_mode_enable: 'Modalità Notte',
+ dark_mode_disable: 'Disabilita Modalità Notte',
info_pers: 'Info Personali',
aggiungi_note: 'Aggiungi note',
da_contattare: 'Da Contattare',
@@ -168,7 +170,6 @@ const msg_it = {
accountslist: 'Conti',
movslist: 'Movimenti',
iscritticonacreis: 'Iscritti Conacreis',
- iscrittiarcadei: 'Iscritti Arcadei',
zoomlist: 'Calendario Zoom',
extralist: 'Lista Extra',
dbop: 'Db Operations',
@@ -391,6 +392,7 @@ const msg_it = {
domanda_blockuser: 'Bloccare {username}?',
domanda_unblockuser: 'Sbloccare {username}?',
domanda_reportuser: 'Segnalare l\'utente {username}?',
+ domanda_verifyuser: 'Verifica l\'utente {username}?',
domanda_blockgroup: 'Bloccare l\'Organizzazione {groupname}?',
reporteduser: 'Utente Segnalato in data {date_report}',
blockedfriend: 'Utente Bloccato',
@@ -439,7 +441,7 @@ const msg_it = {
},
user: {
notregistered: 'Devi registrarti al servizio prima di porter memorizzare i dati',
- loggati: 'Utente non loggato',
+ non_loggato: 'Utente non autenticato',
},
templemail: {
subject: 'Oggetto Email',
@@ -689,7 +691,7 @@ const msg_it = {
surname_opt: 'Cognome (facoltativo)',
username_login: 'Username o email',
scegli_username: 'Inserisci un nome utente per il tuo Profilo:',
- scegli_password: 'Inserisci una Nuova password per accedere alla piattaforma:',
+ scegli_password: 'Scegli una nuova password per accedere:',
password: 'Password',
password_reg: 'Password',
repeatPassword: 'Ripeti password',
@@ -1816,6 +1818,7 @@ const msg_it = {
},
statusreg: {
+ completa_registrazione: 'Completa la registrazione',
invite_by: 'Invitata da',
has_invited: 'ha invitato',
reg: 'Utenti Attivi',
@@ -1836,6 +1839,8 @@ const msg_it = {
nationality_born: 'Nazione di Nascita',
verified: 'Verificata',
nonverified: 'Non Verificata',
+ emailnonverified: 'Verifica la email',
+ emailverified: 'Email Verificata',
req7: 'Con 5 passi entri nella lista d\'Imbarco',
req9: 'Con 7 passi aiuti {sitename} a Crescere!',
req: 'Passi',
diff --git a/src/store/Api/index.ts b/src/store/Api/index.ts
index 9c698abf..3b9c7cb5 100755
--- a/src/store/Api/index.ts
+++ b/src/store/Api/index.ts
@@ -187,9 +187,9 @@ export const Api = {
throw err2 || { status: serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN };
}
} else if (
- status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN ||
- status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_PERMESSI ||
- statuscode2 === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN
+ // status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN ||
+ status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_PERMESSI
+ // || statuscode2 === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN
) {
userStore.setAuth('', '');
const $router = useRouter();
diff --git a/src/store/Modules/fieldsTable.ts b/src/store/Modules/fieldsTable.ts
index d8f3a0ca..3079701b 100755
--- a/src/store/Modules/fieldsTable.ts
+++ b/src/store/Modules/fieldsTable.ts
@@ -4024,151 +4024,6 @@ export const colTableIscrittiConacreis = [
AddCol(DuplicateRec),
];
-export const colTableIscrittiArcadei = [
- AddCol({
- name: 'annoTesseramento',
- label_trans: 'reg.annoTesseramento',
- fieldtype: costanti.FieldType.number,
- }),
- AddCol({
- name: 'numTesseraInterna',
- label_trans: 'reg.numTesseraInterna',
- fieldtype: costanti.FieldType.number,
- }),
- AddCol({
- name: 'metodo_pagamento',
- label_trans: 'reg.metodo_pagamento',
- fieldtype: costanti.FieldType.select,
- jointable: 'metodo_pagamento',
- }),
- AddCol({
- name: 'ha_pagato',
- label_trans: 'reg.ha_pagato',
- fieldtype: costanti.FieldType.boolean,
- }),
- AddCol({ name: 'name', label_trans: 'reg.name', fieldtype: costanti.FieldType.string }),
- AddCol({
- name: 'surname',
- label_trans: 'reg.surname',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'dateofreg',
- label_trans: 'reg.dateofreg',
- fieldtype: costanti.FieldType.onlydate,
- }),
- AddCol({
- name: 'dateofapproved',
- label_trans: 'reg.dateofapproved',
- fieldtype: costanti.FieldType.onlydate,
- }),
- AddCol({
- name: 'email',
- label_trans: 'reg.email',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'email2',
- label_trans: 'reg.email2',
- fieldtype: costanti.FieldType.string,
- }),
- // AddCol({ name: 'fiscalcode', label_trans: 'reg.fiscalcode', fieldtype: costanti.FieldType.string }),
- AddCol({
- name: 'residency_address',
- label_trans: 'reg.residency_address',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'residency_city',
- label_trans: 'reg.residency_city',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'residency_province',
- label_trans: 'reg.residency_province',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'residency_country',
- label_trans: 'reg.residency_country',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'residency_zipcode',
- label_trans: 'reg.residency_zipcode',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'dateofbirth',
- label_trans: 'reg.dateofbirth',
- fieldtype: costanti.FieldType.onlydate,
- }),
- AddCol({
- name: 'born_city',
- label_trans: 'reg.born_city',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'born_province',
- label_trans: 'reg.born_province',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'born_country',
- label_trans: 'reg.born_country',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'cell_phone',
- label_trans: 'reg.cell_phone',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'cell_phone2',
- label_trans: 'reg.cell_phone2',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'doctype',
- label_trans: 'reg.doctype',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'documentnumber',
- label_trans: 'reg.documentnumber',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'quota_versata',
- label_trans: 'reg.quota_versata',
- fieldtype: costanti.FieldType.number,
- }),
- AddCol({
- name: 'categorie_interesse',
- label_trans: 'reg.categorie_interesse',
- fieldtype: costanti.FieldType.multiselect,
- jointable: 'cat_interesse_arcadei',
- }),
- AddCol({
- name: 'altre_comunicazioni',
- label_trans: 'reg.altre_comunicazioni',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'come_ci_hai_conosciuto',
- label_trans: 'reg.come_ci_hai_conosciuto',
- fieldtype: costanti.FieldType.string,
- }),
- AddCol({
- name: 'iscrizione_compilata',
- label_trans: 'reg.iscrizione_compilata',
- fieldtype: costanti.FieldType.boolean,
- }),
- AddCol({ name: 'note', label_trans: 'reg.note', fieldtype: costanti.FieldType.string }),
- AddCol(DeleteRec),
- AddCol(DuplicateRec),
-];
-
export const colTableGestoreOrdini = [
AddCol({ name: 'name', label_trans: 'products.name' }),
AddCol({
@@ -7610,14 +7465,6 @@ export const fieldsTable = {
collabel: 'label',
noshow: true,
},
- {
- value: 'cat_interesse_arcadei',
- label: "Categorie d'Interesse Arcadei",
- columns: colTableGeneric,
- colkey: 'value',
- collabel: 'label',
- noshow: true,
- },
{
value: 'lang',
label: 'Lingua',
diff --git a/src/store/Modules/tools.ts b/src/store/Modules/tools.ts
index b7891d5f..bf6cfcc7 100644
--- a/src/store/Modules/tools.ts
+++ b/src/store/Modules/tools.ts
@@ -2717,6 +2717,17 @@ export const tools = {
return result;
},
+ getUserEmail() {
+ const userStore = useUserStore();
+ return userStore.my?.email;
+ },
+
+ getEmailSupport() {
+ const globalStore = useGlobalStore();
+ const site = globalStore.site;
+ return this.getemailto(site?.contacts.email)
+ },
+
visumenu(elem: IListRoutes) {
// : IListRoutes
@@ -5631,11 +5642,19 @@ export const tools = {
getLinkBotTelegram(aportador_solidario: string, regexpire: string): string {
let mylink = '';
const sep = '-';
- if (tools.isTest() && !import.meta.env.DEV) {
+ /*if (tools.isTest() && !import.meta.env.DEV) {
mylink = tools.getValDb('TELEG_BOT_LINK_TEST', false);
} else {
mylink = tools.getValDb('TELEG_BOT_LINK', false);
+ }*/
+ const globalStore = useGlobalStore();
+ const site = globalStore.site;
+ if (tools.isTest() && !import.meta.env.DEV) {
+ mylink = 'https://t.me/' + site.telegram_bot_name_test
+ } else {
+ mylink = 'https://t.me/' + site.telegram_bot_name
}
+
let add = '';
if (aportador_solidario) {
add = '?start=inv' + sep + aportador_solidario + sep + 'ex' + sep + regexpire;
@@ -6356,6 +6375,33 @@ export const tools = {
});
},
+ verifyUser($q: any, username: string, usernameDest: string) {
+ // Segnala Profilo
+ const userStore = useUserStore();
+ //T_TOLTO
+ $q.dialog({
+ message: t('db.domanda_verifyuser', { username: usernameDest }),
+ ok: { label: t('dialog.yes'), push: true },
+ cancel: { label: t('dialog.cancel') },
+ title: t('db.domanda'),
+ }).onOk(() => {
+ userStore
+ .setFriendsCmd(
+ $q,
+ t,
+ username,
+ usernameDest,
+ shared_consts.FRIENDSCMD.SETTRUST,
+ true
+ )
+ .then((res: any) => {
+ if (res) {
+ tools.showPositiveNotif($q, t('db.trusted', {username: usernameDest}));
+ }
+ });
+ });
+ },
+
refuseReqFriends($q: any, username: string, usernameDest: string) {
//T_TOLTO
const userStore = useUserStore();
@@ -7705,7 +7751,10 @@ export const tools = {
let risultato = false;
- if (userStore.isAdmin || shared_consts.USER_ADMIN_CIRCUITS.includes(userStore.my.username)) {
+ if (
+ userStore.isAdmin ||
+ shared_consts.USER_ADMIN_CIRCUITS.includes(userStore.my.username)
+ ) {
return true;
}
@@ -8250,7 +8299,9 @@ export const tools = {
return {
idSector: tools.getSelectionByTable('sectors', 0, true),
idSkill: tools.getSelectionByTable('skills', 0, true),
- idStatusSkill: tools.getSelectionByTable('statusSkills', [shared_consts.STATUSSKILL_DI_PERSONA]),
+ idStatusSkill: tools.getSelectionByTable('statusSkills', [
+ shared_consts.STATUSSKILL_DI_PERSONA,
+ ]),
idContribType: tools.getSelectionByTable('contribtypes', []),
dateTimeStart: tools.getDateTomorrowByTime(21),
dateTimeEnd: null,
@@ -8644,7 +8695,7 @@ export const tools = {
? ris.last_my_transactions
: [];
- userStore.my.profile.total_transactions = ris.total_transactions
+ userStore.my.profile.total_transactions = ris.total_transactions;
return [{ userId: userStore.my._id }];
}
});
@@ -11061,7 +11112,7 @@ export const tools = {
}
},
- addstrCookie(table): string {
+ addstrCookie(table: string): string {
let addstr = '_' + table;
return addstr;
},
@@ -11193,19 +11244,26 @@ export const tools = {
return Math.ceil((pastDaysOfYear + startOfYear.getDay() + 1) / 7);
},
- getmenuByPath(path: string) {
- const myroutes = static_data.routes;
+ getmenuByPath(path: string): IListRoutes | undefined {
+ if (!path) return undefined;
+ const normalizedPath = tools.norm(path);
- const norm = path
- ? (path.startsWith('/') ? path : `/${path}`).trim().toLowerCase()
- : undefined;
+ function searchMenu(routes: IListRoutes[]): IListRoutes | undefined {
+ for (const route of routes) {
+ if (!route) continue;
- const mymenus = myroutes.find((menu: any) => menu.path === norm);
+ if (tools.norm(route.path) === normalizedPath) return route;
+ if (Array.isArray(route.routes2)) {
+ const found = searchMenu(route.routes2);
+ if (found) return found;
+ }
+ }
+ return undefined;
+ }
- // console.log('mymenus', mymenus, 'path', path, 'norm', norm);
-
- return mymenus;
+ return searchMenu(static_data.routes);
},
+
norm(path?: string): string | undefined {
return typeof path === 'string'
? path
@@ -11219,7 +11277,7 @@ export const tools = {
try {
return /Telegram/.test(navigator.userAgent);
} catch (e) {
- return false
+ return false;
}
},
// FINE !
diff --git a/src/store/UserStore.ts b/src/store/UserStore.ts
index 59bf543d..ae5a05b2 100755
--- a/src/store/UserStore.ts
+++ b/src/store/UserStore.ts
@@ -13,7 +13,6 @@ import type {
IAccount,
IColGridTable,
ISignupIscrizioneConacreisOptions,
- ISignupIscrizioneArcadeiOptions,
IMovQuery,
} from '@src/model';
import { IFriends, ISettings } from '@src/model';
@@ -825,7 +824,7 @@ export const useUserStore = defineStore('UserStore', {
}
}
- return false
+ return false;
// return this.my.verified_email! && this.isTelegIdOk() && this.my.verified_by_aportador!
},
@@ -1063,8 +1062,6 @@ export const useUserStore = defineStore('UserStore', {
});
},
-
-
async addNewSite(paramquery: any) {
console.log(paramquery);
@@ -1214,27 +1211,45 @@ export const useUserStore = defineStore('UserStore', {
return await this.execDbOpUser({ mydata });
}
},
- async savenoCircuit(val: boolean) {
+ async setSkipTelegramVerif(val: boolean) {
const mydata = {
_id: this.my._id,
- dbop: 'noCircuit',
+ dbop: 'telegram_verification_skipped',
value: val,
};
- if (this.my.profile.noCircuit !== val) {
- this.my.profile.noCircuit = val;
+ if (this.my.profile.telegram_verification_skipped !== val) {
+ this.my.profile.telegram_verification_skipped = val;
return await this.execDbOpUser({ mydata });
}
},
- async savenoCircIta(val: boolean) {
+ async savenoCircuit(val: boolean, userId?: string) {
const mydata = {
- _id: this.my._id,
+ _id: userId ? userId : this.my._id,
+ dbop: 'noCircuit',
+ value: val,
+ };
+
+ if (userId) {
+ } else {
+ if (this.my.profile.noCircuit !== val) {
+ this.my.profile.noCircuit = val;
+ }
+ }
+ return await this.execDbOpUser({ mydata });
+ },
+ async savenoCircIta(val: boolean, userId?: string) {
+ const mydata = {
+ _id: userId ? userId : this.my._id,
dbop: 'noCircIta',
value: val,
};
- if (this.my.profile.noCircIta !== val) {
- this.my.profile.noCircIta = val;
- return await this.execDbOpUser({ mydata });
+ if (userId) {
+ } else {
+ if (this.my.profile.noCircIta !== val) {
+ this.my.profile.noCircIta = val;
+ }
}
+ return await this.execDbOpUser({ mydata });
},
async savenoFoto(val: boolean) {
const mydata = {
@@ -1356,7 +1371,12 @@ export const useUserStore = defineStore('UserStore', {
this.my.perm,
shared_consts.Permissions.Grafico.value
);
- this.isCollaboratore = this.isGrafico || this.isCommerciale || this.isEditor || this.isAdmin || this.isManager
+ this.isCollaboratore =
+ this.isGrafico ||
+ this.isCommerciale ||
+ this.isEditor ||
+ this.isAdmin ||
+ this.isManager;
this.my.tokens = [];
this.resetArrToken(this.my.tokens);
@@ -1521,7 +1541,9 @@ export const useUserStore = defineStore('UserStore', {
data_login: tools.getDateNow(),
};
- const index = this.my.tokens.findIndex((token) => token.access === 'auth' && token.token === x_auth_token);
+ const index = this.my.tokens.findIndex(
+ (token) => token.access === 'auth' && token.token === x_auth_token
+ );
if (index === -1) {
this.my.tokens.push(newToken);
} else {
@@ -1579,28 +1601,6 @@ export const useUserStore = defineStore('UserStore', {
});
},
- async iscrivitiArcadei(authData: ISignupIscrizioneArcadeiOptions) {
- console.log('iscrivitiArcadei');
-
- this.setServerCode(tools.CALLING);
-
- authData.userId = this.my._id;
-
- return Api.SendReq('/iscritti_arcadei', 'POST', authData)
- .then((res) => {
- if (res.status === 200) {
- return { code: serv_constants.RIS_ISCRIZIONE_OK, msg: '' };
- } else {
- return { code: toolsext.ERR_GENERICO, msg: '' };
- }
- })
- .catch((error) => {
- console.log('Err', error);
- this.setErrorCatch(error);
- return { code: this.getServerCode, msg: this.getMsg };
- });
- },
-
async signin(router: Router, authData: ISigninOptions) {
// console.log('LOGIN signin')
const globalStore = useGlobalStore();
@@ -1718,7 +1718,6 @@ export const useUserStore = defineStore('UserStore', {
});
},
-
async setGlobal(router: Router, isLogged: boolean) {
const globalStore = useGlobalStore();
@@ -2550,5 +2549,18 @@ export const useUserStore = defineStore('UserStore', {
}
return this.lista_referenti;
},
+
+ async refreshUserData(response: any) {
+ if (response) {
+ this.my.profile.username_telegram = response?.username_telegram;
+ this.my.profile.teleg_id = response?.teleg_id;
+ }
+ },
+
+ async resendEmailVerifyRegistration() {
+ return Api.SendReq('/sendmailreg', 'POST', {}).then((ris: any) => {
+ return ris.data;
+ });
+ },
},
});
diff --git a/src/store/globalStore.ts b/src/store/globalStore.ts
index a0692341..87ed0467 100644
--- a/src/store/globalStore.ts
+++ b/src/store/globalStore.ts
@@ -2579,8 +2579,6 @@ export const useGlobalStore = defineStore('GlobalStore', {
else if (table === 'confpages_lang') myarr = costanti.ArrLang;
else if (table === 'bottype') myarr = shared_consts.BotType;
else if (table === 'visibility') myarr = shared_consts.Visibility;
- else if (table === 'cat_interesse_arcadei')
- myarr = shared_consts.Cat_Interesse_Arcadei;
else if (table === 'pub_to_share') myarr = shared_consts.Pub_to_Share;
else if (table === 'visibilGroup') myarr = shared_consts.VisibilGroup;
else if (table === 'statuscircuit') myarr = shared_consts.StatusCircuit;
@@ -2666,23 +2664,27 @@ export const useGlobalStore = defineStore('GlobalStore', {
},
getMsgServerError() {
- if (this.serverError) {
- if (this.serverMsgError) {
- let mymsg = this.serverMsgError.msgerr || this.serverMsgError.data!.msgerr || this.serverMsgError.msgerr!.message
- if (this.serverMsgError.status === 500) {
- return 'Errore Interno del Server';
- } else if (mymsg === '') {
- return 'Codice Errore ' + this.serverMsgError.status;
- }
- try {
- return mymsg
- } catch (e) {
- return this.serverMsgError.msgerr;
+ try {
+ if (this.serverError) {
+ if (this.serverMsgError) {
+ let mymsg = this.serverMsgError!.msgerr || this.serverMsgError.data!.msgerr || this.serverMsgError.msgerr!.message || this.serverMsgError
+ if (this.serverMsgError.status === 500) {
+ return 'Errore Interno del Server';
+ } else if (mymsg === '') {
+ return 'Codice Errore ' + this.serverMsgError.status;
+ }
+ try {
+ return mymsg
+ } catch (e) {
+ return this.serverMsgError.msgerr;
+ }
}
}
- }
- return '';
+ return '';
+ } catch (e) {
+ return '';
+ }
},
getTableJoinLabelValueByName(col: IColGridTable) {
@@ -3520,5 +3522,9 @@ export const useGlobalStore = defineStore('GlobalStore', {
this.inStampa = value;
// console.log('inStampa', this.inStampa)
},
+
+ async sendInviteEmail(email: string) {
+ // ...
+ }
},
});
diff --git a/src/stores/useInvitaAmicoStore.ts b/src/stores/useInvitaAmicoStore.ts
new file mode 100644
index 00000000..5cea0127
--- /dev/null
+++ b/src/stores/useInvitaAmicoStore.ts
@@ -0,0 +1,394 @@
+// stores/useInvitaAmicoStore.ts
+import { defineStore } from 'pinia';
+import { ref, computed } from 'vue';
+import type {
+ InvitoAmicoForm,
+ InvitoAmicoRequest,
+ InvitoAmicoResponse,
+} from '../types/invita-amico.types.ts';
+import { useUserStore } from '../store/index.js';
+import { Api } from '../store/Api/index.js';
+
+/**
+ * Store Pinia per la gestione degli inviti amici
+ * Gestisce lo stato, le chiamate API e la cronologia degli inviti
+ */
+export const useInvitaAmicoStore = defineStore('invitaAmico', () => {
+ // ==========================================
+ // STATE
+ // ==========================================
+
+ // Loading state
+ const loading = ref(false);
+
+ // Errori
+ const error = ref
(null);
+
+ // Ultimo invito inviato con successo
+ const ultimoInvitoInviato = ref<{
+ email: string;
+ data: Date;
+ successo: boolean;
+ } | null>(null);
+
+ // Cronologia inviti (ultimi 10)
+ const cronologiaInviti = ref<
+ Array<{
+ id: string;
+ email: string;
+ usernameInvitante?: string;
+ messaggio?: string;
+ data: Date;
+ successo: boolean;
+ errore?: string;
+ }>
+ >([]);
+
+ // Contatori
+ const contatoreInvitiRiusciti = ref(0);
+ const contatoreInvitiFalliti = ref(0);
+
+ // ==========================================
+ // GETTERS
+ // ==========================================
+
+ /**
+ * Verifica se ci sono inviti in cronologia
+ */
+ const hasCronologia = computed(() => cronologiaInviti.value.length > 0);
+
+ /**
+ * Numero totale di inviti
+ */
+ const totaleInviti = computed(
+ () => contatoreInvitiRiusciti.value + contatoreInvitiFalliti.value
+ );
+
+ /**
+ * Percentuale successo inviti
+ */
+ const percentualeSuccesso = computed(() => {
+ if (totaleInviti.value === 0) return 0;
+ return Math.round((contatoreInvitiRiusciti.value / totaleInviti.value) * 100);
+ });
+
+ /**
+ * Ultimi 5 inviti
+ */
+ const ultimi5Inviti = computed(() => cronologiaInviti.value.slice(0, 5));
+
+ /**
+ * Verifica se un'email è già stata invitata (nelle ultime 24h)
+ */
+ const isEmailGiaInvitata = computed(() => (email: string) => {
+ const now = new Date();
+ const oreIndietro24 = new Date(now.getTime() - 24 * 60 * 60 * 1000);
+
+ return cronologiaInviti.value.some(
+ (invito) =>
+ invito.email.toLowerCase() === email.toLowerCase() &&
+ invito.data > oreIndietro24 &&
+ invito.successo
+ );
+ });
+
+ // ==========================================
+ // ACTIONS
+ // ==========================================
+
+ /**
+ * Invia un invito via email
+ */
+ const inviaInvitoEmail = async (
+ idapp: string,
+ emailAmico: string,
+ messaggioPersonalizzato?: string
+ ): Promise => {
+ // Reset errori
+ error.value = null;
+ loading.value = true;
+
+ const userStore = useUserStore();
+
+ let usernameInvitante = userStore.my.username;
+
+ try {
+ // Validazione email
+ if (!emailAmico || !isValidEmail(emailAmico)) {
+ throw new Error('Email non valida');
+ }
+
+ // Check se già invitata recentemente
+ if (isEmailGiaInvitata.value(emailAmico)) {
+ throw new Error('Questa email è già stata invitata nelle ultime 24 ore');
+ }
+
+ // Prepara request
+ const requestBody: InvitoAmicoRequest = {
+ emailAmico,
+ messaggioPersonalizzato,
+ usernameInvitante,
+ };
+
+ // Chiamata API
+ const response = await Api.SendReq('/inviti/invia-email', 'POST', requestBody);
+
+ if (!response.data) {
+ throw new Error("Errore durante l'invio");
+ }
+
+ const data: InvitoAmicoResponse = response.data;
+
+ if (data.success) {
+ // Aggiorna stato successo
+ ultimoInvitoInviato.value = {
+ email: emailAmico,
+ data: new Date(),
+ successo: true,
+ };
+
+ // Incrementa contatore
+ contatoreInvitiRiusciti.value++;
+
+ // Aggiungi a cronologia
+ aggiungiACronologia({
+ email: emailAmico,
+ usernameInvitante,
+ messaggio: messaggioPersonalizzato,
+ successo: true,
+ });
+
+ return data;
+ } else {
+ throw new Error(data.message || 'Invio fallito');
+ }
+ } catch (err) {
+ // Gestione errori
+ const errorMessage = err instanceof Error ? err.message : 'Errore sconosciuto';
+ error.value = errorMessage;
+
+ // Incrementa contatore fallimenti
+ contatoreInvitiFalliti.value++;
+
+ // Aggiungi a cronologia come fallito
+ aggiungiACronologia({
+ email: emailAmico,
+ usernameInvitante,
+ messaggio: messaggioPersonalizzato,
+ successo: false,
+ errore: errorMessage,
+ });
+
+ // Ritorna risposta di errore
+ return {
+ success: false,
+ message: errorMessage,
+ emailInviata: false,
+ };
+ } finally {
+ loading.value = false;
+ }
+ };
+
+ /**
+ * Invia invito via Telegram
+ * (placeholder - integra con la tua logica esistente)
+ */
+ const inviaInvitoTelegram = async (messaggio?: string): Promise => {
+ loading.value = true;
+ error.value = null;
+
+ try {
+ // TODO: Integra con la tua logica Telegram esistente
+ // Esempio:
+ // await telegramBotService.sendMessage(messaggio);
+
+ console.log('Invio via Telegram:', messaggio);
+
+ // Simula invio
+ await new Promise((resolve) => setTimeout(resolve, 1000));
+
+ return true;
+ } catch (err) {
+ error.value = err instanceof Error ? err.message : 'Errore invio Telegram';
+ return false;
+ } finally {
+ loading.value = false;
+ }
+ };
+
+ /**
+ * Aggiunge un invito alla cronologia
+ */
+ const aggiungiACronologia = (invito: {
+ email: string;
+ usernameInvitante?: string;
+ messaggio?: string;
+ successo: boolean;
+ errore?: string;
+ }) => {
+ const nuovoInvito = {
+ id: generateId(),
+ ...invito,
+ data: new Date(),
+ };
+
+ // Aggiungi in testa
+ cronologiaInviti.value.unshift(nuovoInvito);
+
+ // Mantieni solo gli ultimi 10
+ if (cronologiaInviti.value.length > 10) {
+ cronologiaInviti.value = cronologiaInviti.value.slice(0, 10);
+ }
+
+ // Salva in localStorage
+ salvaInLocalStorage();
+ };
+
+ /**
+ * Cancella un invito dalla cronologia
+ */
+ const rimuoviDaCronologia = (id: string) => {
+ cronologiaInviti.value = cronologiaInviti.value.filter((invito) => invito.id !== id);
+ salvaInLocalStorage();
+ };
+
+ /**
+ * Cancella tutta la cronologia
+ */
+ const svuotaCronologia = () => {
+ cronologiaInviti.value = [];
+ salvaInLocalStorage();
+ };
+
+ /**
+ * Reset dello stato
+ */
+ const resetStato = () => {
+ loading.value = false;
+ error.value = null;
+ ultimoInvitoInviato.value = null;
+ };
+
+ /**
+ * Reset contatori
+ */
+ const resetContatori = () => {
+ contatoreInvitiRiusciti.value = 0;
+ contatoreInvitiFalliti.value = 0;
+ localStorage.removeItem('invita-amico-contatori');
+ };
+
+ /**
+ * Carica dati da localStorage
+ */
+ const caricaDaLocalStorage = () => {
+ try {
+ // Carica cronologia
+ const cronologiaSalvata = localStorage.getItem('invita-amico-cronologia');
+ if (cronologiaSalvata) {
+ const parsed = JSON.parse(cronologiaSalvata);
+ // Converte stringhe date in oggetti Date
+ cronologiaInviti.value = parsed.map((invito: any) => ({
+ ...invito,
+ data: new Date(invito.data),
+ }));
+ }
+
+ // Carica contatori
+ const contatoriSalvati = localStorage.getItem('invita-amico-contatori');
+ if (contatoriSalvati) {
+ const parsed = JSON.parse(contatoriSalvati);
+ contatoreInvitiRiusciti.value = parsed.riusciti || 0;
+ contatoreInvitiFalliti.value = parsed.falliti || 0;
+ }
+ } catch (err) {
+ console.error('Errore caricamento localStorage:', err);
+ }
+ };
+
+ /**
+ * Salva dati in localStorage
+ */
+ const salvaInLocalStorage = () => {
+ try {
+ // Salva cronologia
+ localStorage.setItem(
+ 'invita-amico-cronologia',
+ JSON.stringify(cronologiaInviti.value)
+ );
+
+ // Salva contatori
+ localStorage.setItem(
+ 'invita-amico-contatori',
+ JSON.stringify({
+ riusciti: contatoreInvitiRiusciti.value,
+ falliti: contatoreInvitiFalliti.value,
+ })
+ );
+ } catch (err) {
+ console.error('Errore salvataggio localStorage:', err);
+ }
+ };
+
+ // ==========================================
+ // UTILITY
+ // ==========================================
+
+ /**
+ * Validazione email
+ */
+ const isValidEmail = (email: string): boolean => {
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+ return emailRegex.test(email);
+ };
+
+ /**
+ * Genera ID univoco
+ */
+ const generateId = (): string => {
+ return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
+ };
+
+ // ==========================================
+ // INIZIALIZZAZIONE
+ // ==========================================
+
+ // Carica dati all'avvio
+ caricaDaLocalStorage();
+
+ // ==========================================
+ // RETURN
+ // ==========================================
+
+ return {
+ // State
+ loading,
+ error,
+ ultimoInvitoInviato,
+ cronologiaInviti,
+ contatoreInvitiRiusciti,
+ contatoreInvitiFalliti,
+
+ // Getters
+ hasCronologia,
+ totaleInviti,
+ percentualeSuccesso,
+ ultimi5Inviti,
+ isEmailGiaInvitata,
+
+ // Actions
+ inviaInvitoEmail,
+ inviaInvitoTelegram,
+ aggiungiACronologia,
+ rimuoviDaCronologia,
+ svuotaCronologia,
+ resetStato,
+ resetContatori,
+ caricaDaLocalStorage,
+ salvaInLocalStorage,
+
+ // Utility
+ isValidEmail,
+ };
+});
diff --git a/src/types/invita-amico.types.ts b/src/types/invita-amico.types.ts
new file mode 100644
index 00000000..2e28fb26
--- /dev/null
+++ b/src/types/invita-amico.types.ts
@@ -0,0 +1,29 @@
+// Types per il componente Invita Amico
+
+export interface InvitoAmicoForm {
+ email: string;
+ messaggio?: string;
+}
+
+export interface InvitoAmicoRequest {
+ idapp?: string;
+ emailAmico: string;
+ messaggioPersonalizzato?: string;
+ usernameInvitante?: string;
+}
+
+export interface InvitoAmicoResponse {
+ success: boolean;
+ message: string;
+ emailInviata?: boolean;
+}
+
+export interface EmailInvitoTemplate {
+ to: string;
+ subject: string;
+ html: string;
+ usernameInvitante?: string;
+ linkRegistrazione: string;
+ nomeApp: string;
+ baseUrl: string;
+}
diff --git a/src/views/login/iscrizionearcadei/iscrizionearcadei.scss b/src/views/login/iscrizionearcadei/iscrizionearcadei.scss
deleted file mode 100755
index 6a3d2337..00000000
--- a/src/views/login/iscrizionearcadei/iscrizionearcadei.scss
+++ /dev/null
@@ -1,12 +0,0 @@
-.signup {
- width: 100%;
- margin: 0 auto;
- max-width: 450px;
-}
-
-
-.wrapper {
- display: flex;
- align-items: center;
- justify-content: center;
-}
diff --git a/src/views/login/iscrizionearcadei/iscrizionearcadei.ts b/src/views/login/iscrizionearcadei/iscrizionearcadei.ts
deleted file mode 100755
index 72ed51f9..00000000
--- a/src/views/login/iscrizionearcadei/iscrizionearcadei.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { defineComponent, ref, computed } from 'vue'
-import { useI18n } from 'vue-i18n'
-import { useUserStore } from '@store/UserStore'
-import { useGlobalStore } from '@store/globalStore'
-import { useQuasar } from 'quasar'
-
-import { CMyPage } from '../../../components/CMyPage'
-import { LandingFooter } from '../../../components/LandingFooter'
-import { CTitleBanner } from '../../../components/CTitleBanner'
-import { CSignUpIscrizioneArcadei } from '@src/components/CSignUpIscrizioneArcadei'
-
-export default defineComponent({
- name: 'Iscrizionearcadei',
- props: {
- mystr: {
- type: String,
- required: true,
- default: '',
- },
- myval: {
- type: Number,
- required: true,
- default: 0,
- },
- mybool: {
- type: Boolean,
- required: true,
- default: false,
- },
- },
- components: { CSignUpIscrizioneArcadei, CMyPage, LandingFooter, CTitleBanner },
- setup(props, { emit }) {
- const userStore = useUserStore()
-
- function isSocio() {
- return userStore.my.profile.socio
- }
-
- return {
- isSocio,
- }
- }
-})
diff --git a/src/views/login/iscrizionearcadei/iscrizionearcadei.vue b/src/views/login/iscrizionearcadei/iscrizionearcadei.vue
deleted file mode 100755
index 3b578981..00000000
--- a/src/views/login/iscrizionearcadei/iscrizionearcadei.vue
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/user/mygroup/mygroup.vue b/src/views/user/mygroup/mygroup.vue
index 19506f03..87dc7078 100755
--- a/src/views/user/mygroup/mygroup.vue
+++ b/src/views/user/mygroup/mygroup.vue
@@ -64,19 +64,6 @@
-
@@ -252,9 +242,7 @@
type="a"
size="md"
rounded
- :label="
- t('reg.website') + ' ' + tools.getMainUrl(getLinkWebSite())
- "
+ :label="t('reg.website') + ' ' + tools.getMainUrl(getLinkWebSite())"
:href="getLinkWebSite()"
target="__blank"
>
@@ -388,13 +376,25 @@
- Nessun Circuito RIS ancora abilitato da parte del gruppo
+
+ Nessun circuito RIS è ancora stato abilitato per questo
+ gruppo.
-
+
+
Nessun Circuito RIS ancora abilitato da parte del gruppo