- Sistemato INVITI alla App
- Completamento Profilo - Registrazione tramite Invito, senza richiedere conferma email.
This commit is contained in:
@@ -2,17 +2,21 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
min-height: 120vh;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
@media (max-width: $breakpoint-sm-max) {
|
||||
min-height: 100vh;
|
||||
}
|
||||
}
|
||||
|
||||
.invita-amico-card {
|
||||
max-width: 600px;
|
||||
max-width: 800px;
|
||||
width: 100%;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
|
||||
|
||||
@media (max-width: $breakpoint-sm-max) {
|
||||
max-width: 600px;
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
@@ -47,3 +51,50 @@
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Bottoni selezione metodo
|
||||
.selection-buttons {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@media (max-width: $breakpoint-xs-max) {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.selection-btn {
|
||||
flex: 1;
|
||||
min-height: 180px;
|
||||
border-radius: 12px;
|
||||
border: 2px solid #e0e0e0;
|
||||
background: white;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--q-primary);
|
||||
box-shadow: 0 4px 20px rgba(102, 126, 234, 0.2);
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
@media (max-width: $breakpoint-xs-max) {
|
||||
min-height: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
.selection-btn-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 24px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
@media (max-width: 768px) {
|
||||
padding: 8px 24px;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { useQuasar } from 'quasar';
|
||||
import { useInvitaAmicoStore } from '../../stores/useInvitaAmicoStore';
|
||||
import type { InvitoAmicoForm } from '../../types/invita-amico.types.ts';
|
||||
import { tools } from 'app/src/store/Modules/tools';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
// Chiave localStorage
|
||||
const MESSAGGIO_STORAGE_KEY = 'invita-amico-messaggio-personalizzato';
|
||||
@@ -15,10 +16,12 @@ export default defineComponent({
|
||||
setup(props, { emit }) {
|
||||
// Composables
|
||||
const $q = useQuasar();
|
||||
const { t } = useI18n();
|
||||
const invitaStore = useInvitaAmicoStore();
|
||||
|
||||
// State
|
||||
const mostraCronologia = ref(false);
|
||||
const metodoSelezionato = ref<'email' | 'telegram' | null>(null);
|
||||
const form = reactive<InvitoAmicoForm & { usernameInvitante?: string }>({
|
||||
email: '',
|
||||
messaggio: '',
|
||||
@@ -29,6 +32,20 @@ export default defineComponent({
|
||||
// METHODS
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* Seleziona il metodo di invio (email o telegram)
|
||||
*/
|
||||
const selezionaMetodo = (metodo: 'email' | 'telegram') => {
|
||||
metodoSelezionato.value = metodo;
|
||||
};
|
||||
|
||||
/**
|
||||
* Torna alla schermata di scelta iniziale
|
||||
*/
|
||||
const tornaAllaScelta = () => {
|
||||
metodoSelezionato.value = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Invia invito via email usando lo store Pinia
|
||||
*/
|
||||
@@ -51,7 +68,7 @@ export default defineComponent({
|
||||
message: 'Invito inviato con successo! 🎉',
|
||||
caption: `L'email è stata inviata a ${form.email}`,
|
||||
icon: 'check_circle',
|
||||
timeout: 3000,
|
||||
timeout: 7000,
|
||||
actions: [
|
||||
{
|
||||
label: 'Vedi cronologia',
|
||||
@@ -86,14 +103,14 @@ export default defineComponent({
|
||||
const onInviaTelegram = async () => {
|
||||
emit('telegram-click');
|
||||
|
||||
const success = await invitaStore.inviaInvitoTelegram(form.messaggio);
|
||||
const success = await invitaStore.inviaInvitoTelegram($q, t);
|
||||
|
||||
if (success) {
|
||||
$q.notify({
|
||||
type: 'positive',
|
||||
message: 'Messaggio inviato via Telegram! ✈️',
|
||||
icon: 'telegram',
|
||||
timeout: 2000,
|
||||
timeout: 4000,
|
||||
});
|
||||
} else {
|
||||
$q.notify({
|
||||
@@ -122,7 +139,7 @@ export default defineComponent({
|
||||
type: 'info',
|
||||
message: 'Cronologia cancellata',
|
||||
icon: 'delete',
|
||||
timeout: 2000,
|
||||
timeout: 3000,
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -168,6 +185,9 @@ export default defineComponent({
|
||||
// RETURN
|
||||
return {
|
||||
mostraCronologia,
|
||||
metodoSelezionato,
|
||||
selezionaMetodo,
|
||||
tornaAllaScelta,
|
||||
form,
|
||||
onInviaEmail,
|
||||
onInviaTelegram,
|
||||
|
||||
@@ -12,47 +12,78 @@
|
||||
/>
|
||||
Invita un Amico
|
||||
</div>
|
||||
<div class="text-subtitle2">Condividi la nostra app con i tuoi amici!</div>
|
||||
|
||||
<!-- Stats Badge -->
|
||||
<div
|
||||
v-if="invitaStore.totaleInviti > 0"
|
||||
class="stats-badge q-mt-md"
|
||||
>
|
||||
<q-chip
|
||||
color="white"
|
||||
text-color="primary"
|
||||
icon="email"
|
||||
class="q-mx-xs"
|
||||
>
|
||||
{{ invitaStore.contatoreInvitiRiusciti }} inviati
|
||||
</q-chip>
|
||||
<!--<q-chip
|
||||
v-if="invitaStore.percentualeSuccesso > 0"
|
||||
color="white"
|
||||
text-color="primary"
|
||||
icon="trending_up"
|
||||
class="q-mx-xs"
|
||||
>
|
||||
{{ invitaStore.percentualeSuccesso }}% successo
|
||||
</q-chip>-->
|
||||
</div>
|
||||
<div class="text-subtitle2">Condividi la app con i tuoi amici!</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-separator />
|
||||
|
||||
<!-- Form Section -->
|
||||
<q-card-section>
|
||||
<q-form
|
||||
@submit="onInviaEmail"
|
||||
class="q-gutter-md"
|
||||
>
|
||||
<!-- Schermata Selezione Metodo -->
|
||||
<q-card-section v-if="!metodoSelezionato">
|
||||
<div class="text-center q-mb-lg">
|
||||
<div class="text-h6 text-grey-8 q-mb-xs">Come vuoi invitare?</div>
|
||||
</div>
|
||||
|
||||
<div class="selection-buttons">
|
||||
<q-btn
|
||||
@click="selezionaMetodo('email')"
|
||||
class="selection-btn"
|
||||
unelevated
|
||||
no-caps
|
||||
>
|
||||
<div class="selection-btn-content">
|
||||
<q-icon
|
||||
name="email"
|
||||
size="48px"
|
||||
color="primary"
|
||||
/>
|
||||
<div class="text-h6 q-mt-xs text-grey-9">Email</div>
|
||||
<div class="text-caption text-grey-7">
|
||||
Invia un invito diretto via email
|
||||
</div>
|
||||
</div>
|
||||
</q-btn>
|
||||
|
||||
<q-btn
|
||||
@click="selezionaMetodo('telegram')"
|
||||
class="selection-btn"
|
||||
unelevated
|
||||
no-caps
|
||||
>
|
||||
<div class="selection-btn-content">
|
||||
<q-icon
|
||||
name="telegram"
|
||||
size="48px"
|
||||
color="blue-9"
|
||||
/>
|
||||
<div class="text-h6 q-mt-md text-grey-9">Telegram</div>
|
||||
<div class="text-caption text-grey-7">
|
||||
Condividi tramite Telegram
|
||||
</div>
|
||||
</div>
|
||||
</q-btn>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<!-- Sezione Email (mostrata solo se selezionata) -->
|
||||
<q-card-section v-if="metodoSelezionato === 'email'">
|
||||
<div class="q-mb-md">
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
icon="arrow_back"
|
||||
label="Cambia metodo"
|
||||
color="grey-7"
|
||||
size="sm"
|
||||
@click="tornaAllaScelta"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<q-form @submit="onInviaEmail">
|
||||
<!-- Email Input -->
|
||||
<q-input
|
||||
v-model="form.email"
|
||||
type="email"
|
||||
label="Email del tuo amico *"
|
||||
hint="Inserisci l'indirizzo email della persona che vuoi invitare"
|
||||
label="Email della tua persona amica *"
|
||||
lazy-rules
|
||||
:rules="[
|
||||
(val) => !!val || 'L\'email è obbligatoria',
|
||||
@@ -86,10 +117,9 @@
|
||||
<q-input
|
||||
v-model="form.messaggio"
|
||||
type="textarea"
|
||||
label="Messaggio personalizzato (opzionale)"
|
||||
hint="Aggiungi un messaggio personale al tuo invito"
|
||||
label="Messaggio personale (opzionale)"
|
||||
outlined
|
||||
rows="3"
|
||||
:rows="tools.isMobile() ? 6 : 9"
|
||||
counter
|
||||
maxlength="500"
|
||||
:disable="invitaStore.loading"
|
||||
@@ -113,17 +143,6 @@
|
||||
<q-icon name="message" />
|
||||
</template>
|
||||
</q-input>
|
||||
<!-- Info che viene salvato -->
|
||||
<div
|
||||
v-if="form.messaggio"
|
||||
class="text-caption text-grey-6"
|
||||
>
|
||||
<q-icon
|
||||
name="info"
|
||||
size="xs"
|
||||
/>
|
||||
Questo messaggio sarà riutilizzato nei prossimi inviti
|
||||
</div>
|
||||
|
||||
<!-- Alert errore -->
|
||||
<q-banner
|
||||
@@ -145,23 +164,31 @@
|
||||
icon="email"
|
||||
color="primary"
|
||||
size="lg"
|
||||
class="full-width"
|
||||
class="full-width q-mt-md"
|
||||
outline
|
||||
:loading="invitaStore.loading"
|
||||
:disable="invitaStore.loading || !form.email"
|
||||
unelevated
|
||||
/>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
|
||||
<q-separator inset />
|
||||
|
||||
<!-- Sezione Telegram -->
|
||||
<q-card-section>
|
||||
<!-- Sezione Telegram (mostrata solo se selezionata) -->
|
||||
<q-card-section v-if="metodoSelezionato === 'telegram'">
|
||||
<div class="q-mb-md">
|
||||
<q-btn
|
||||
dense
|
||||
icon="arrow_back"
|
||||
label="Cambia metodo"
|
||||
size="sm"
|
||||
outline
|
||||
@click="tornaAllaScelta"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-center q-mb-md">
|
||||
<div class="text-subtitle1 text-grey-8 q-mb-xs">
|
||||
Oppure invita tramite Telegram
|
||||
Invita tramite Telegram
|
||||
</div>
|
||||
<div class="text-caption text-grey-6">
|
||||
<div class="text-caption text-grey-7">
|
||||
Genera un messaggio da condividere su Telegram
|
||||
</div>
|
||||
</div>
|
||||
@@ -178,8 +205,11 @@
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<!-- Info Section -->
|
||||
<q-card-section class="bg-blue-1">
|
||||
<!-- Info Section (solo per Telegram) -->
|
||||
<q-card-section
|
||||
v-if="metodoSelezionato === 'telegram'"
|
||||
class="bg-blue-1"
|
||||
>
|
||||
<div class="text-center">
|
||||
<q-icon
|
||||
name="info"
|
||||
@@ -188,7 +218,8 @@
|
||||
class="q-mr-xs"
|
||||
/>
|
||||
<span class="text-grey-8">
|
||||
Riceverai sul {{ tools.getBotName() }} il messaggio da inoltrare alla persona amica.
|
||||
Riceverai sul {{ tools.getBotName() }} il messaggio da inoltrare alla
|
||||
persona amica.
|
||||
</span>
|
||||
</div>
|
||||
</q-card-section>
|
||||
@@ -266,6 +297,29 @@
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<!-- Stats Badge -->
|
||||
<div
|
||||
v-if="invitaStore.totaleInviti > 0"
|
||||
class="stats-badge q-mt-md"
|
||||
>
|
||||
<q-chip
|
||||
color="white"
|
||||
text-color="primary"
|
||||
icon="email"
|
||||
class="q-mx-xs"
|
||||
>
|
||||
{{ invitaStore.contatoreInvitiRiusciti }} inviati
|
||||
</q-chip>
|
||||
<!--<q-chip
|
||||
v-if="invitaStore.percentualeSuccesso > 0"
|
||||
color="white"
|
||||
text-color="primary"
|
||||
icon="trending_up"
|
||||
class="q-mx-xs"
|
||||
>
|
||||
{{ invitaStore.percentualeSuccesso }}% successo
|
||||
</q-chip>-->
|
||||
</div>
|
||||
<!-- Bottone per mostrare cronologia -->
|
||||
<q-card-section v-if="invitaStore.hasCronologia && !mostraCronologia">
|
||||
<q-btn
|
||||
|
||||
Reference in New Issue
Block a user