Files
myprojplanet_vite/src/stores/useInvitaAmicoStore.ts
Surya Paolo b8df3ea721 - aggiornata la grafica della Home di RISO
- Profilo Completition
- Email Verificata
- Invita un Amico (invio di email)
2025-11-15 19:38:39 +01:00

395 lines
9.5 KiB
TypeScript

// 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<string | null>(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<InvitoAmicoResponse> => {
// 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<boolean> => {
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,
};
});