From a1167a2d03cbadd25dd13f4689daa9375091b219 Mon Sep 17 00:00:00 2001 From: solocla Date: Fri, 4 Sep 2026 08:15:25 +0200 Subject: [PATCH] fixed pages --- .gitignore | 3 + android/app/build.gradle.kts | 27 +- lib/screens/lessons_page.dart | 23 +- lib/screens/meditation_page.dart | 2 +- lib/screens/reschedule_page.dart | 22 +- lib/screens/splash_page.dart | 80 +++--- lib/screens/teacher_add_participant_page.dart | 4 + lib/screens/teacher_class_detail_page.dart | 252 ++++++++++++++---- lib/screens/teacher_panel_page.dart | 21 ++ lib/services/teacher_api.dart | 34 +++ lib/widgets/app_bottom_nav.dart | 2 +- lib/widgets/app_drawer.dart | 47 +--- lib/widgets/yogibook_background.dart | 18 +- pubspec.yaml | 2 +- 14 files changed, 363 insertions(+), 174 deletions(-) diff --git a/.gitignore b/.gitignore index 3820a95..23d0866 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + +key.properties +*.jks \ No newline at end of file diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 7cf154c..b09bcef 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -1,3 +1,6 @@ +import java.util.Properties +import java.io.FileInputStream + plugins { id("com.android.application") id("kotlin-android") @@ -5,6 +8,12 @@ plugins { id("dev.flutter.flutter-gradle-plugin") } +val keystoreProperties = Properties() +val keystorePropertiesFile = rootProject.file("key.properties") +if (keystorePropertiesFile.exists()) { + keystoreProperties.load(FileInputStream(keystorePropertiesFile)) +} + android { namespace = "it.yogasoul.yogibook" compileSdk = flutter.compileSdkVersion @@ -20,25 +29,29 @@ android { } defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId = "it.yogasoul.yogibook" - // You can update the following values to match your application needs. - // For more information, see: https://flutter.dev/to/review-gradle-config. minSdk = flutter.minSdkVersion targetSdk = flutter.targetSdkVersion versionCode = flutter.versionCode versionName = flutter.versionName } + signingConfigs { + create("release") { + keyAlias = keystoreProperties["keyAlias"] as String + keyPassword = keystoreProperties["keyPassword"] as String + storeFile = keystoreProperties["storeFile"]?.let { file(it) } + storePassword = keystoreProperties["storePassword"] as String + } + } + buildTypes { release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig = signingConfigs.getByName("debug") + signingConfig = signingConfigs.getByName("release") } } } flutter { source = "../.." -} +} \ No newline at end of file diff --git a/lib/screens/lessons_page.dart b/lib/screens/lessons_page.dart index b77ff5d..fa96d99 100644 --- a/lib/screens/lessons_page.dart +++ b/lib/screens/lessons_page.dart @@ -9,7 +9,6 @@ import 'meditation_page.dart'; import '../widgets/app_drawer.dart'; import '../widgets/app_bottom_nav.dart'; import 'package:url_launcher/url_launcher.dart'; -import '../widgets/yogibook_background.dart'; import 'reschedule_page.dart'; import 'orders_page.dart'; @@ -116,22 +115,9 @@ class _LessonsPageState extends State { backgroundColor: Colors.transparent, elevation: 0, centerTitle: true, - title: Column( - children: [ - const Text( - 'Le mie lezioni', - style: TextStyle(fontWeight: FontWeight.w800, fontSize: 18), - ), - const SizedBox(height: 2), - Text( - widget.school.name, - style: const TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Colors.black54, - ), - ), - ], + title: const Text( + 'Le mie lezioni', + style: TextStyle(fontWeight: FontWeight.w800, fontSize: 18), ), actions: [ Padding( @@ -158,7 +144,8 @@ class _LessonsPageState extends State { userFirstName: widget.userFirstName, ), - body: YogibookBackground( + body: Container( + color: const Color(0xFFE2FDFF), child: SafeArea( top: false, child: Column( diff --git a/lib/screens/meditation_page.dart b/lib/screens/meditation_page.dart index 2b264a4..fda7bd0 100644 --- a/lib/screens/meditation_page.dart +++ b/lib/screens/meditation_page.dart @@ -273,7 +273,7 @@ class _MeditationPageState extends State elevation: 0, centerTitle: true, title: const Text( - 'Meditazione', + 'Respira', style: TextStyle(fontWeight: FontWeight.w800, fontSize: 18), ), actions: [ diff --git a/lib/screens/reschedule_page.dart b/lib/screens/reschedule_page.dart index 1eaf983..f37aa4b 100644 --- a/lib/screens/reschedule_page.dart +++ b/lib/screens/reschedule_page.dart @@ -81,6 +81,11 @@ class _ReschedulePageState extends State { return s[0].toUpperCase() + s.substring(1); } + String _dateLabel(String ymd) { + final dt = DateFormat('yyyy-MM-dd').parse(ymd); + return DateFormat('dd/MM/yyyy').format(dt); + } + @override Widget build(BuildContext context) { const green = Color(0xFF10B981); @@ -176,6 +181,7 @@ class _ReschedulePageState extends State { return _SlotCard( slot: s, weekday: _weekdayLabel(s.date), + dateLabel: _dateLabel(s.date), onChoose: () => _confirm(s), ); }, @@ -239,11 +245,13 @@ class _ReschedulePageState extends State { class _SlotCard extends StatelessWidget { final AvailableSlot slot; final String weekday; + final String dateLabel; final VoidCallback onChoose; const _SlotCard({ required this.slot, required this.weekday, + required this.dateLabel, required this.onChoose, }); @@ -316,7 +324,7 @@ class _SlotCard extends StatelessWidget { ), const SizedBox(height: 4), Text( - '$weekday ${slot.date} • ${slot.time}', + '$weekday $dateLabel • ${slot.time}', style: const TextStyle( fontSize: 12, color: Colors.black54, @@ -325,10 +333,18 @@ class _SlotCard extends StatelessWidget { ), const SizedBox(height: 2), Text( - 'Posti liberi: ${slot.freePlaces}/${slot.maxCapacity}', + isBooked + ? 'Già prenotato' + : isFull + ? 'Non disponibile' + : 'Disponibile', style: TextStyle( fontSize: 12, - color: isFull ? orange : Colors.black45, + color: isFull + ? const Color(0xFF9AA0A6) + : isBooked + ? orange + : green, fontWeight: FontWeight.w700, ), ), diff --git a/lib/screens/splash_page.dart b/lib/screens/splash_page.dart index 52439eb..a7b112c 100644 --- a/lib/screens/splash_page.dart +++ b/lib/screens/splash_page.dart @@ -18,7 +18,7 @@ class _SplashPageState extends State { static const Color kRed = Color(0xFFB01E28); Timer? _timer; - int _seconds = 5; // countdown iniziale + int _seconds = 8; // countdown iniziale // Evita doppie navigazioni: countdown, tap e sblocco possono // altrimenti innescare più push. @@ -176,44 +176,50 @@ class _SplashPageState extends State { Positioned( left: 0, right: 0, - bottom: 30, - child: Column( - children: [ - Container( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 10, - ), - decoration: BoxDecoration( - color: Colors.white.withOpacity(0.75), - borderRadius: BorderRadius.circular(16), - ), - child: Image.asset( - 'assets/images/yogibook_logo.png', - height: 40, - fit: BoxFit.contain, - ), - ), - const SizedBox(height: 14), - Container( - width: 40, - height: 40, - alignment: Alignment.center, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Colors.white.withValues(alpha: 0.25), - border: Border.all(color: Colors.white, width: 1.5), - ), - child: Text( - '$_seconds', - style: const TextStyle( - color: Colors.white, - fontWeight: FontWeight.w900, - fontSize: 18, + bottom: 0, + child: SafeArea( + top: false, + child: Padding( + padding: const EdgeInsets.only(bottom: 20), + child: Column( + children: [ + Container( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 10, + ), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.75), + borderRadius: BorderRadius.circular(16), + ), + child: Image.asset( + 'assets/images/yogibook_logo.png', + height: 40, + fit: BoxFit.contain, + ), ), - ), + const SizedBox(height: 14), + Container( + width: 40, + height: 40, + alignment: Alignment.center, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.white.withValues(alpha: 0.25), + border: Border.all(color: Colors.white, width: 1.5), + ), + child: Text( + '$_seconds', + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.w900, + fontSize: 18, + ), + ), + ), + ], ), - ], + ), ), ), ], diff --git a/lib/screens/teacher_add_participant_page.dart b/lib/screens/teacher_add_participant_page.dart index e5e8cb2..abdf87d 100644 --- a/lib/screens/teacher_add_participant_page.dart +++ b/lib/screens/teacher_add_participant_page.dart @@ -109,6 +109,10 @@ class _TeacherAddParticipantPageState extends State { _mode = 'omaggio'; } }); + // DEBUG temporaneo — rimuovere dopo diagnosi + _snack('DEBUG ordini: ${o.length} totali, ${usable.length} con residui'); + // DEBUG temporaneo + _snack('DEBUG: ${o.length} ordini totali, ${usable.length} con residui'); } catch (e) { _snack('$e'); } finally { diff --git a/lib/screens/teacher_class_detail_page.dart b/lib/screens/teacher_class_detail_page.dart index dccab34..3a70b80 100644 --- a/lib/screens/teacher_class_detail_page.dart +++ b/lib/screens/teacher_class_detail_page.dart @@ -27,8 +27,9 @@ class _TeacherClassDetailPageState extends State { // copia locale modificabile dei partecipanti (per aggiornare la UI) late List _participants; - int _busyBookingId = - 0; // booking in aggiornamento (per disabilitare il tasto) + int _busyBookingId = 0; // booking in aggiornamento + bool _changed = + false; // true se ci sono state modifiche (per refresh lista)/ booking in aggiornamento (per disabilitare il tasto) @override void initState() { @@ -100,6 +101,7 @@ class _TeacherClassDetailPageState extends State { ); }); } + _changed = true; _snack(markLost ? 'Segnata come persa.' : 'Ripristinata.'); } catch (e) { _snack('$e'); @@ -143,6 +145,7 @@ class _TeacherClassDetailPageState extends State { setState(() { _participants.removeWhere((x) => x.bookingId == p.bookingId); }); + _changed = true; _snack('Prenotazione eliminata.'); } catch (e) { _snack('$e'); @@ -151,6 +154,129 @@ class _TeacherClassDetailPageState extends State { } } + Future _confirmPending(TeacherParticipant p) async { + setState(() => _busyBookingId = p.bookingId); + try { + await TeacherApi.confirmPending( + token: widget.token, + bookingId: p.bookingId, + ); + // da pending a confermato: aggiorna lo stato locale + final idx = _participants.indexWhere((x) => x.bookingId == p.bookingId); + if (idx != -1) { + setState(() { + _participants[idx] = TeacherParticipant( + bookingId: p.bookingId, + fullName: p.fullName, + isLost: false, + isPending: false, + ); + }); + } + _changed = true; + _snack('${p.fullName} confermato.'); + } catch (e) { + _snack('$e'); + } finally { + if (mounted) setState(() => _busyBookingId = 0); + } + } + + Widget _pendingTile(TeacherParticipant p) { + final busy = _busyBookingId == p.bookingId; + return Container( + margin: const EdgeInsets.only(bottom: 8), + padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12), + decoration: BoxDecoration( + color: const Color(0xFFFFFBF0), + borderRadius: BorderRadius.circular(14), + border: Border.all(color: const Color(0xFFF5E6B8)), + ), + child: Row( + children: [ + Container( + width: 42, + height: 42, + alignment: Alignment.center, + decoration: const BoxDecoration( + color: Color(0xFFE0A800), + shape: BoxShape.circle, + ), + child: Text( + _initials(p.fullName), + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.w800, + fontSize: 15, + ), + ), + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + p.fullName, + style: const TextStyle( + fontWeight: FontWeight.w700, + fontSize: 15, + ), + ), + const SizedBox(height: 2), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 2, + ), + decoration: BoxDecoration( + color: const Color(0xFFFFF4D6), + borderRadius: BorderRadius.circular(20), + ), + child: const Text( + 'In attesa', + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w800, + color: Color(0xFF8A6D00), + ), + ), + ), + ], + ), + ), + if (busy) + const SizedBox( + width: 36, + height: 36, + child: Padding( + padding: EdgeInsets.all(8), + child: CircularProgressIndicator(strokeWidth: 2), + ), + ) + else ...[ + IconButton( + onPressed: () => _confirmPending(p), + tooltip: 'Conferma', + icon: const Icon( + Icons.check_circle_outline_rounded, + color: Color(0xFF1A7F52), + ), + ), + IconButton( + onPressed: () => _deleteBooking(p), + tooltip: 'Rimuovi', + icon: const Icon( + Icons.delete_outline_rounded, + color: Colors.black45, + ), + ), + ], + ], + ), + ); + } + Future _reprogram(TeacherParticipant p) async { final done = await Navigator.push( context, @@ -173,63 +299,85 @@ class _TeacherClassDetailPageState extends State { @override Widget build(BuildContext context) { - final active = _participants.where((p) => !p.isLost).toList(); - final lost = _participants.where((p) => p.isLost).toList(); + final pending = _participants.where((p) => p.isPending).toList(); + final active = _participants + .where((p) => !p.isPending && !p.isLost) + .toList(); + final lost = _participants.where((p) => !p.isPending && p.isLost).toList(); final cls = widget.cls; - return Scaffold( - appBar: AppBar( - backgroundColor: Colors.transparent, - elevation: 0, - centerTitle: true, - title: const Text( - 'Dettaglio classe', - style: TextStyle(fontWeight: FontWeight.w800, fontSize: 18), + return PopScope( + canPop: true, + onPopInvokedWithResult: (didPop, result) { + // quando si esce, se ci sono state modifiche la lista si aggiorna + }, + child: Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + elevation: 0, + centerTitle: true, + leading: IconButton( + icon: const Icon(Icons.arrow_back), + onPressed: () => Navigator.pop(context, _changed), + ), + title: const Text( + 'Dettaglio classe', + style: TextStyle(fontWeight: FontWeight.w800, fontSize: 18), + ), ), - ), - body: YogibookBackground( - child: SafeArea( - top: false, - child: ListView( - padding: const EdgeInsets.fromLTRB(16, 8, 16, 24), - children: [ - _headerCard(), - const SizedBox(height: 18), - _sectionLabel('Iscritti (${active.length})'), - const SizedBox(height: 8), - if (active.isEmpty) - _emptyRow('Nessun iscritto attivo.') - else - ...active.map((p) => _tile(p)), - if (lost.isNotEmpty) ...[ + body: YogibookBackground( + child: SafeArea( + top: false, + child: ListView( + padding: const EdgeInsets.fromLTRB(16, 8, 16, 24), + children: [ + _headerCard(), const SizedBox(height: 18), - _sectionLabel('Lezioni perse (${lost.length})'), + if (pending.isNotEmpty) ...[ + _sectionLabel('In attesa di conferma (${pending.length})'), + const SizedBox(height: 8), + ...pending.map((p) => _pendingTile(p)), + const SizedBox(height: 18), + ], + _sectionLabel('Iscritti (${active.length})'), const SizedBox(height: 8), - ...lost.map((p) => _tile(p)), - ], - const SizedBox(height: 20), - SizedBox( - width: double.infinity, - height: 50, - child: ElevatedButton.icon( - style: ElevatedButton.styleFrom( - backgroundColor: kGreen, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(14), + if (active.isEmpty) + _emptyRow('Nessun iscritto attivo.') + else + ...active.map((p) => _tile(p)), + if (lost.isNotEmpty) ...[ + const SizedBox(height: 18), + _sectionLabel('Lezioni perse (${lost.length})'), + const SizedBox(height: 8), + ...lost.map((p) => _tile(p)), + ], + const SizedBox(height: 20), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton.icon( + style: ElevatedButton.styleFrom( + backgroundColor: kGreen, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(14), + ), ), - ), - icon: const Icon(Icons.person_add_alt_1, color: Colors.white), - label: const Text( - 'Aggiungi partecipante', - style: TextStyle( - fontWeight: FontWeight.w900, + icon: const Icon( + Icons.person_add_alt_1, color: Colors.white, ), + label: const Text( + 'Aggiungi partecipante', + style: TextStyle( + fontWeight: FontWeight.w900, + color: Colors.white, + ), + ), + onPressed: _openAddParticipant, ), - onPressed: _openAddParticipant, ), - ), - ], + ], + ), ), ), ), @@ -245,10 +393,8 @@ class _TeacherClassDetailPageState extends State { ), ); if (added == true && mounted) { - _snack( - 'Partecipante aggiunto. Aggiorna il pannello per vedere la lista.', - ); - // torna al pannello classi, che ricaricando mostrerà i dati aggiornati + _changed = true; + _snack('Partecipante aggiunto.'); Navigator.pop(context, true); } } diff --git a/lib/screens/teacher_panel_page.dart b/lib/screens/teacher_panel_page.dart index 6e1f682..3f71ae9 100644 --- a/lib/screens/teacher_panel_page.dart +++ b/lib/screens/teacher_panel_page.dart @@ -392,6 +392,27 @@ class _ClassCard extends StatelessWidget { color: fillColor, ), ), + if (cls.participants.any((p) => p.isPending)) ...[ + const SizedBox(width: 8), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 6, + vertical: 2, + ), + decoration: BoxDecoration( + color: const Color(0xFFFFF4D6), + borderRadius: BorderRadius.circular(12), + ), + child: Text( + '${cls.participants.where((p) => p.isPending).length} in attesa', + style: const TextStyle( + fontSize: 11, + fontWeight: FontWeight.w800, + color: Color(0xFF8A6D00), + ), + ), + ), + ], ], ), ], diff --git a/lib/services/teacher_api.dart b/lib/services/teacher_api.dart index aef2eab..2ad08be 100644 --- a/lib/services/teacher_api.dart +++ b/lib/services/teacher_api.dart @@ -9,11 +9,13 @@ class TeacherParticipant { final int bookingId; final String fullName; final bool isLost; + final bool isPending; const TeacherParticipant({ required this.bookingId, required this.fullName, required this.isLost, + this.isPending = false, }); factory TeacherParticipant.fromMap(Map m) => @@ -21,6 +23,7 @@ class TeacherParticipant { bookingId: (m['booking_id'] as num?)?.toInt() ?? 0, fullName: (m['full_name'] ?? '').toString().trim(), isLost: m['is_lost'] == true, + isPending: m['is_pending'] == true, ); } @@ -407,4 +410,35 @@ class TeacherApi { throw Exception(data['error'] ?? data['message'] ?? 'Errore inserimento'); } } + + /// Conferma una prenotazione in attesa (pending -> booked). + static Future confirmPending({ + required String token, + required int bookingId, + }) async { + final uri = Uri.parse( + '${ApiConfig.laravelApiBase}/api_teacher_confirm_pending.php', + ); + + final res = await http.post( + uri, + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/x-www-form-urlencoded', + 'Authorization': 'Bearer $token', + }, + body: 'booking_id=$bookingId', + ); + + Map data; + try { + data = jsonDecode(res.body) as Map; + } catch (_) { + throw Exception('RAW(${res.statusCode}): ${res.body}'); + } + + if (res.statusCode != 200 || data['success'] != true) { + throw Exception(data['error'] ?? data['message'] ?? 'Errore conferma'); + } + } } diff --git a/lib/widgets/app_bottom_nav.dart b/lib/widgets/app_bottom_nav.dart index ba9255d..4f48ba1 100644 --- a/lib/widgets/app_bottom_nav.dart +++ b/lib/widgets/app_bottom_nav.dart @@ -95,7 +95,7 @@ class AppBottomNav extends StatelessWidget { ), BottomNavigationBarItem( icon: Icon(Icons.self_improvement_rounded), - label: 'Meditazione', + label: 'Respira', ), ], ); diff --git a/lib/widgets/app_drawer.dart b/lib/widgets/app_drawer.dart index f81b88b..028b37e 100644 --- a/lib/widgets/app_drawer.dart +++ b/lib/widgets/app_drawer.dart @@ -6,9 +6,9 @@ import '../config/api_config.dart'; import '../screens/login_page.dart'; import '../screens/medical_certificates_page.dart'; -import '../screens/lessons_page.dart'; + import '../screens/orders_detail_page.dart'; -import '../screens/account_page.dart'; + import '../screens/settings_page.dart'; import '../screens/teacher_panel_page.dart'; import '../services/role_service.dart'; @@ -159,24 +159,6 @@ class AppDrawer extends StatelessWidget { }, ), - ListTile( - leading: const Icon(Icons.event_note_rounded), - title: const Text('Lezioni'), - onTap: () { - Navigator.of(context).pop(); - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (_) => LessonsPage( - token: token, - school: school, - userFirstName: userFirstName, - ), - ), - ); - }, - ), - ListTile( leading: const Icon(Icons.shopping_bag_rounded), title: const Text('Ordini'), @@ -195,24 +177,6 @@ class AppDrawer extends StatelessWidget { }, ), - ListTile( - leading: const Icon(Icons.person_rounded), - title: const Text('Account'), - onTap: () { - Navigator.of(context).pop(); - Navigator.push( - context, - MaterialPageRoute( - builder: (_) => AccountPage( - token: token, - school: school, - userFirstName: userFirstName, - ), - ), - ); - }, - ), - ListTile( leading: const Icon(Icons.settings_rounded), title: const Text('Impostazioni'), @@ -235,10 +199,13 @@ class AppDrawer extends StatelessWidget { ListTile( leading: const Icon(Icons.privacy_tip_outlined), - title: const Text('Cookie e Privacy Policy'), + title: const Text('Privacy Policy'), onTap: () { Navigator.of(context).pop(); - _openUrl(context, 'https://yogasoul.it/cookie-policy/'); + _openUrl( + context, + 'https://yogasoul.it/privacy-policy-yogibook/', + ); }, ), diff --git a/lib/widgets/yogibook_background.dart b/lib/widgets/yogibook_background.dart index 0586d9b..9bf8a48 100644 --- a/lib/widgets/yogibook_background.dart +++ b/lib/widgets/yogibook_background.dart @@ -9,27 +9,19 @@ class YogibookBackground extends StatelessWidget { Widget build(BuildContext context) { return Stack( children: [ - // --- SFONDO (gradient) - Container( - decoration: const BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topLeft, - end: Alignment.bottomRight, - colors: [Color(0xFFF4F6FA), Color(0xFFEFF7F3), Color(0xFFF4F6FA)], - ), - ), - ), + // --- SFONDO (tinta piatta) + Container(color: const Color(0xFFE2FDFF)), // --- BOLLE decorative - const _BgBlob(color: Color(0x3310B981), size: 280, top: -70, left: -90), + const _BgBlob(color: Color(0x9962BBC1), size: 280, top: -70, left: -90), const _BgBlob( - color: Color(0x22F59E0B), + color: Color(0x99F4ECE1), size: 230, bottom: 80, right: -70, ), const _BgBlob( - color: Color(0x227C3AED), + color: Color(0x99E1D0B8), size: 190, bottom: -55, left: 35, diff --git a/pubspec.yaml b/pubspec.yaml index 8dd347f..3541a12 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: yogibook_app -description: "A new Flutter project." +description: "Prenotazione YogaSoul" # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: "none" # Remove this line if you wish to publish to pub.dev