- asggiunto bottone "installa app" sulla email di conferma registrazione e anche la Guida "/guida".

- migliorato InvitaAmico
This commit is contained in:
Surya Paolo
2025-11-19 11:39:36 +01:00
parent 05a3617103
commit 57436f088b
25 changed files with 270 additions and 113 deletions

View File

@@ -353,11 +353,11 @@
// Responsive
@media (max-width: 768px) {
.install-app-container {
padding: 1rem;
padding: 0rem;
}
.install-card {
padding: 1.5rem;
padding: 0.5rem;
}
.icon-wrapper {
@@ -401,10 +401,10 @@
}
.platform-header {
padding: 1rem;
padding: 0.5rem;
.platform-info {
gap: 0.75rem;
gap: 0.5rem;
.platform-text {
h4 {
@@ -419,7 +419,7 @@
}
.platform-content {
padding: 1rem;
padding: 0.5rem;
.screenshots {
grid-template-columns: 1fr;
@@ -427,36 +427,6 @@
}
}
@media (max-width: 480px) {
.card-title {
font-size: 1.25rem;
}
.card-description {
font-size: 0.95rem;
}
.instructions-box {
.instructions-header {
flex-direction: column;
text-align: center;
h4 {
font-size: 1.1rem;
}
}
}
.platform-header {
.platform-info {
.icon-wrapper {
width: 50px;
height: 50px;
}
}
}
}
// Dark mode
body.body--dark {
.install-card {

View File

@@ -5,7 +5,14 @@ import { useQuasar } from 'quasar';
export default defineComponent({
name: 'CCheckAppRunning',
setup() {
props: {
isPageApp: {
type: Boolean,
required: false,
default: false,
}
},
setup(props) {
const globalStore = useGlobalStore();
const $q = useQuasar();

View File

@@ -248,7 +248,7 @@
<div class="platform-info">
<div class="icon-wrapper android">
<q-icon
name="fab fa-android"
name="fas fa-mobile-alt"
size="48px"
/>
</div>
@@ -393,6 +393,67 @@
</div>
</div>
</div>
<!-- ✅ App già installata -->
<div
v-else-if="isAppRunning && isPageApp"
class="install-card app-installed"
>
<div class="card-center">
<div class="icon-wrapper success">
<q-icon
name="fas fa-check-circle"
size="64px"
/>
</div>
<h3 class="card-title">App già installata! 🎉</h3>
<p class="card-description">
Ottimo! Stai già usando RISO come app installata. Puoi accedere sempre dalla
tua schermata home.
</p>
<div class="benefits-list">
<div class="benefit-item">
<q-icon
name="fas fa-bolt"
color="primary"
size="24px"
/>
<span>Accesso rapido dalla home</span>
</div>
<div class="benefit-item">
<q-icon
name="fas fa-bell"
color="primary"
size="24px"
/>
<span>Notifiche in tempo reale</span>
</div>
<div class="benefit-item">
<q-icon
name="fas fa-mobile-alt"
color="primary"
size="24px"
/>
<span>Esperienza nativa</span>
</div>
</div>
<q-btn
unelevated
rounded
size="lg"
color="primary"
class="install-btn"
to="/"
>
<q-icon
name="fas fa-home"
class="q-mr-sm"
/>
Vai alla Home
</q-btn>
</div>
</div>
</transition>
</div>
</template>

View File

@@ -826,7 +826,6 @@ export default defineComponent({
globalStore,
costanti,
t,
$q,
};
},
});

View File

@@ -62,8 +62,8 @@
.selection-btn {
flex: 0 1 calc(33.33% - 8px); // Desktop: max 1/3 dello spazio, non cresce
min-width: 140px;
min-height: 140px;
min-width: 120px;
min-height: 120px;
border-radius: 12px;
border: 2px solid #e0e0e0;
background: white;

View File

@@ -156,6 +156,17 @@ function getDynamicPages(site: ISites): IListRoutes[] {
inmenu: false,
infooter: false,
},
{
active: true,
order: 120,
path: '/installaapp',
materialIcon: 'fas fa-user',
name: 'pages.installaApp',
component: () => import('@src/views/admin/installaApp/installaApp.vue'),
meta: { },
inmenu: false,
infooter: false,
},
{
active: true,
order: 120,

View File

@@ -165,11 +165,10 @@ export const Api = {
} else {
// Se il refresh token fallisce, logout dell'utente
// userStore.setAuth('', '');
const $router = useRouter();
throw { code: toolsext.ERR_RETRY_LOGIN };
}
} catch (err2) {
console.error('Errore durante il refresh token:', err2);
console.error('Errore durante il check Token Scaduto:', err2);
let mystatus = err2?.code || err2?.status;
@@ -192,7 +191,6 @@ export const Api = {
// || statuscode2 === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN
) {
userStore.setAuth('', '');
const $router = useRouter();
throw { status: toolsext.ERR_RETRY_LOGIN };
}

View File

@@ -2726,7 +2726,7 @@ export const tools = {
getEmailSupport() {
const globalStore = useGlobalStore();
const site = globalStore.site;
return this.getemailto(site?.contacts.email)
return this.getemailto(site?.contacts.email);
},
visumenu(elem: IListRoutes) {
@@ -5651,9 +5651,9 @@ export const tools = {
const globalStore = useGlobalStore();
const site = globalStore.site;
if (tools.isTest() && !import.meta.env.DEV) {
mylink = 'https://t.me/' + site.telegram_bot_name_test
mylink = 'https://t.me/' + site.telegram_bot_name_test;
} else {
mylink = 'https://t.me/' + site.telegram_bot_name
mylink = 'https://t.me/' + site.telegram_bot_name;
}
let add = '';
@@ -6397,7 +6397,7 @@ export const tools = {
)
.then((res: any) => {
if (res) {
tools.showPositiveNotif($q, t('db.trusted', {username: usernameDest}));
tools.showPositiveNotif($q, t('db.trusted', { username: usernameDest }));
}
});
});
@@ -11273,21 +11273,37 @@ export const tools = {
.toLowerCase()
: undefined;
},
isInTelegramWebView() {
try {
return /Telegram/.test(navigator.userAgent);
// Verifica che siamo lato client
if (typeof window === 'undefined') {
return false;
}
// Metodo 1: Controlla oggetti globali di Telegram
const win = window as any;
if (win.Telegram || win.TelegramWebviewProxy || win.TelegramWebApp) {
return true;
}
// Metodo 2: User Agent (case-insensitive)
const ua = navigator.userAgent.toLowerCase();
if (ua.includes('telegram')) {
return true;
}
return false;
} catch (e) {
console.error('Errore rilevamento Telegram:', e);
return false;
}
},
pageExist(path: string) {
const globalStore = useGlobalStore();
const page = globalStore.getPage(path)
const page = globalStore.getPage(path);
return !!page
}
return !!page;
},
// FINE !

View File

@@ -0,0 +1 @@
export { default as gestoreordini } from './installaApp.vue'

View File

@@ -0,0 +1,41 @@
$heightBtn: 100%;
.card .product-image {
height: 300px;
}
.mycol{
color:gray;
}
.q-item__label--caption{
color: blue;
}
.ordstat{
text-align: center;
border: 1px solid #8778cb;
border-radius: 10px;
padding: 5px;
}
.confermato {
font-weight: bold;
color: green;
}
.note {
font-style: italic;
color:blue;
}
.totali {
font-weight: bold;
color: blue;
font-size: 1rem;
}
.totaliacq {
font-weight: bold;
color: red;
font-size: 1rem;
}

View File

@@ -0,0 +1,39 @@
import { defineComponent, onMounted, ref, watch } from 'vue'
import { tools } from '@tools'
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { toolsext } from '@store/Modules/toolsext'
import { useQuasar } from 'quasar'
import { costanti } from '@costanti'
import { shared_consts } from '@src/common/shared_vuejs'
import { CTitleBanner } from '@src/components/CTitleBanner'
import { CCheckAppRunning } from '@src/components/CCheckAppRunning'
export default defineComponent({
name: 'installaApp',
components: { CTitleBanner, CCheckAppRunning },
props: {},
setup() {
const $router = useRouter()
const $q = useQuasar()
const { t } = useI18n()
async function mounted() {
}
onMounted(mounted)
return {
costanti,
tools,
toolsext,
shared_consts,
t,
}
}
})

View File

@@ -0,0 +1,13 @@
<template>
<q-page>
<CTitleBanner title="Installa App"></CTitleBanner>
<CCheckAppRunning :isPageApp="true" />
</q-page>
</template>
<script lang="ts" src="./installaApp.ts">
</script>
<style lang="scss" scoped>
@import "./installaApp.scss";
</style>