Auto-sync: 20260428_210000
This commit is contained in:
parent
62015933ee
commit
2aec8d63c9
5 changed files with 27 additions and 17 deletions
|
|
@ -152,17 +152,19 @@ class _PaywallScreenState extends State<PaywallScreen> with SingleTickerProvider
|
||||||
SafeArea(
|
SafeArea(
|
||||||
child: FadeTransition(
|
child: FadeTransition(
|
||||||
opacity: _fadeAnimation,
|
opacity: _fadeAnimation,
|
||||||
child: Column(
|
child: SingleChildScrollView(
|
||||||
children: [
|
physics: const BouncingScrollPhysics(),
|
||||||
Align(
|
child: Column(
|
||||||
alignment: Alignment.topRight,
|
children: [
|
||||||
child: IconButton(
|
Align(
|
||||||
icon: const Icon(Icons.close, color: Colors.white70),
|
alignment: Alignment.topRight,
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
child: IconButton(
|
||||||
|
icon: const Icon(Icons.close, color: Colors.white70),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 10),
|
||||||
const Spacer(),
|
const Icon(Icons.qr_code_scanner_rounded, size: 80, color: Colors.white),
|
||||||
const Icon(Icons.qr_code_scanner_rounded, size: 80, color: Colors.white),
|
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
const Text(
|
const Text(
|
||||||
'Sblocca la Sincronizzazione',
|
'Sblocca la Sincronizzazione',
|
||||||
|
|
@ -235,8 +237,9 @@ class _PaywallScreenState extends State<PaywallScreen> with SingleTickerProvider
|
||||||
child: CircularProgressIndicator(color: Colors.white, strokeWidth: 2),
|
child: CircularProgressIndicator(color: Colors.white, strokeWidth: 2),
|
||||||
)
|
)
|
||||||
: Text(
|
: Text(
|
||||||
'Passa a PRO - \${_yearlyPackage!.storeProduct.priceString} / anno',
|
'Passa a PRO - ${_yearlyPackage!.storeProduct.priceString} / anno',
|
||||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -253,7 +256,7 @@ class _PaywallScreenState extends State<PaywallScreen> with SingleTickerProvider
|
||||||
style: TextStyle(color: Colors.white70, decoration: TextDecoration.underline),
|
style: TextStyle(color: Colors.white70, decoration: TextDecoration.underline),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const SizedBox(height: 30),
|
||||||
|
|
||||||
// Footer Legale (Obbligatorio per Apple)
|
// Footer Legale (Obbligatorio per Apple)
|
||||||
Padding(
|
Padding(
|
||||||
|
|
@ -277,6 +280,7 @@ class _PaywallScreenState extends State<PaywallScreen> with SingleTickerProvider
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,9 @@ import 'package:purchases_flutter/purchases_flutter.dart';
|
||||||
import 'package:cid_app/global_data.dart';
|
import 'package:cid_app/global_data.dart';
|
||||||
|
|
||||||
class SubscriptionService {
|
class SubscriptionService {
|
||||||
// Chiave unificata di test fornita da RevenueCat
|
// Chiavi distinte fornite da RevenueCat per piattaforma
|
||||||
static const _apiKey = 'test_xlLcZsCHGnotDSfUoDBmDCrjfaZ';
|
static const _googleApiKey = 'test_xlLcZsCHGnotDSfUoDBmDCrjfaZ';
|
||||||
|
static const _appleApiKey = 'INSERISCI_QUI_LA_CHIAVE_IOS_REVENUECAT'; // TODO: Sostituire con la chiave per iOS
|
||||||
static const entitlementID = 'pro'; // Il nome dell'entitlement su RevenueCat
|
static const entitlementID = 'pro'; // Il nome dell'entitlement su RevenueCat
|
||||||
|
|
||||||
static Future<void> init() async {
|
static Future<void> init() async {
|
||||||
|
|
@ -14,9 +15,9 @@ class SubscriptionService {
|
||||||
PurchasesConfiguration? configuration;
|
PurchasesConfiguration? configuration;
|
||||||
|
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
configuration = PurchasesConfiguration(_apiKey);
|
configuration = PurchasesConfiguration(_googleApiKey);
|
||||||
} else if (Platform.isIOS) {
|
} else if (Platform.isIOS) {
|
||||||
configuration = PurchasesConfiguration(_apiKey);
|
configuration = PurchasesConfiguration(_appleApiKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configuration != null) {
|
if (configuration != null) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
- **2026-04-28**: Modificato il campo "Telefono / Email" in due campi separati in `comp_6-7.dart` (Contraente) e `comp_9.dart` (Conducente) con implementazione Regex per formati internazionali ed email. Aggiornata logica `pdf_engine.dart` per stampare la stringa concatenata nel PDF e aggiornato il salvataggio locale `profilo_service.dart`.
|
- **2026-04-28**: Modificato il campo "Telefono / Email" in due campi separati in `comp_6-7.dart` (Contraente) e `comp_9.dart` (Conducente) con implementazione Regex per formati internazionali ed email. Aggiornata logica `pdf_engine.dart` per stampare la stringa concatenata nel PDF e aggiornato il salvataggio locale `profilo_service.dart`. **Eseguito e validato test end-to-end** (`full_flow_test.dart`) verificando l'autocompilazione delle email, il bypass OTP e la generazione integra del file PDF.
|
||||||
- **2026-04-28**: Aggiornata la versione di Kotlin a 2.1.0 in `android/build.gradle` per conformità alle nuove specifiche di Flutter, superando la dipendenza obsoleta rimossa da `pdf_render`.
|
- **2026-04-28**: Aggiornata la versione di Kotlin a 2.1.0 in `android/build.gradle` per conformità alle nuove specifiche di Flutter, superando la dipendenza obsoleta rimossa da `pdf_render`.
|
||||||
- **2026-04-28**: Implementata Autocompilazione (Ricorda i miei dati). Creato `ProfiloService` con persistenza locale via `shared_preferences`. Aggiunto popup "Vuoi usare i dati salvati?" su `comp_6-7.dart` e workflow "silenzioso" su `comp_9.dart`.
|
- **2026-04-28**: Implementata Autocompilazione (Ricorda i miei dati). Creato `ProfiloService` con persistenza locale via `shared_preferences`. Aggiunto popup "Vuoi usare i dati salvati?" su `comp_6-7.dart` e workflow "silenzioso" su `comp_9.dart`.
|
||||||
- **2026-04-24**: Implementazione In-App Purchases (RevenueCat) con aggiunta del plugin `purchases_flutter`. Creato `SubscriptionService`, aggiunto campo `isPro` in `GlobalData`, e costruito il Paywall Custom (Glassmorphism) per bloccare la funzionalità "Scambio Dati" agli utenti non paganti.
|
- **2026-04-24**: Implementazione In-App Purchases (RevenueCat) con aggiunta del plugin `purchases_flutter`. Creato `SubscriptionService`, aggiunto campo `isPro` in `GlobalData`, e costruito il Paywall Custom (Glassmorphism) per bloccare la funzionalità "Scambio Dati" agli utenti non paganti.
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ void main() {
|
||||||
GlobalData.Cognome_contraente_A = "ROSSI";
|
GlobalData.Cognome_contraente_A = "ROSSI";
|
||||||
GlobalData.Codice_Fiscale_contraente_A = "RSSMRA80A01H501U";
|
GlobalData.Codice_Fiscale_contraente_A = "RSSMRA80A01H501U";
|
||||||
GlobalData.N_telefono_mail_contraente_A = "+393331234567";
|
GlobalData.N_telefono_mail_contraente_A = "+393331234567";
|
||||||
|
GlobalData.Email_contraente_A = "mario.rossi@email.it";
|
||||||
|
|
||||||
GlobalData.Marca_e_Tipo_A = "FIAT PANDA";
|
GlobalData.Marca_e_Tipo_A = "FIAT PANDA";
|
||||||
GlobalData.Targa_A = "AA123BB";
|
GlobalData.Targa_A = "AA123BB";
|
||||||
|
|
@ -36,6 +37,7 @@ void main() {
|
||||||
GlobalData.Nome_cond_A = "MARIO";
|
GlobalData.Nome_cond_A = "MARIO";
|
||||||
GlobalData.Cognome_cond_A = "ROSSI";
|
GlobalData.Cognome_cond_A = "ROSSI";
|
||||||
GlobalData.N_tel_mail_cond_A = "+393331234567";
|
GlobalData.N_tel_mail_cond_A = "+393331234567";
|
||||||
|
GlobalData.Email_cond_A = "mario.rossi@email.it";
|
||||||
|
|
||||||
// 2. Salva il profilo
|
// 2. Salva il profilo
|
||||||
await ProfiloService.salvaProfilo('A');
|
await ProfiloService.salvaProfilo('A');
|
||||||
|
|
@ -48,17 +50,20 @@ void main() {
|
||||||
GlobalData.Nome_contraente_A = "";
|
GlobalData.Nome_contraente_A = "";
|
||||||
GlobalData.Cognome_contraente_A = "";
|
GlobalData.Cognome_contraente_A = "";
|
||||||
GlobalData.Targa_A = "";
|
GlobalData.Targa_A = "";
|
||||||
|
GlobalData.Email_contraente_A = "";
|
||||||
|
|
||||||
// 5. Ricarica il profilo (Autocompilazione)
|
// 5. Ricarica il profilo (Autocompilazione)
|
||||||
await ProfiloService.caricaProfilo('A');
|
await ProfiloService.caricaProfilo('A');
|
||||||
expect(GlobalData.Nome_contraente_A, "MARIO");
|
expect(GlobalData.Nome_contraente_A, "MARIO");
|
||||||
expect(GlobalData.Targa_A, "AA123BB");
|
expect(GlobalData.Targa_A, "AA123BB");
|
||||||
|
expect(GlobalData.Email_contraente_A, "mario.rossi@email.it");
|
||||||
|
|
||||||
// 6. Simula i dati del Conducente B (dall'altra parte dello scambio)
|
// 6. Simula i dati del Conducente B (dall'altra parte dello scambio)
|
||||||
GlobalData.Nome_contraente_B = "LUIGI";
|
GlobalData.Nome_contraente_B = "LUIGI";
|
||||||
GlobalData.Cognome_contraente_B = "VERDI";
|
GlobalData.Cognome_contraente_B = "VERDI";
|
||||||
GlobalData.Targa_B = "CC987DD";
|
GlobalData.Targa_B = "CC987DD";
|
||||||
GlobalData.N_tel_mail_cond_B = "+393339876543";
|
GlobalData.N_tel_mail_cond_B = "+393339876543";
|
||||||
|
GlobalData.Email_cond_B = "luigi.verdi@email.it";
|
||||||
|
|
||||||
// 7. Simula l'esito della FEA (senza inviare veri SMS)
|
// 7. Simula l'esito della FEA (senza inviare veri SMS)
|
||||||
// Conducente A approva
|
// Conducente A approva
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in a new issue