diff --git a/CHANGELOG.md b/CHANGELOG.md index dcc8c67..bf1afaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Fixed +- EULA screen now always displays in English regardless of the selected app language; all UI strings (title, buttons, checkbox, dialogs) are hardcoded English so the legal agreement is consistent across locales +- Replaced placeholder briefcase icon in EULA header with the actual BMS SVG logo +- Expanded EULA from 10 to 15 sections: added Definitions, Grant of License, License Tiers, Restrictions, IP Ownership, License Key enforcement, User Data and Privacy, Updates and Support, Warranty Disclaimer, Liability Cap, Indemnification, Termination, Governing Law, Severability, and Entire Agreement +- Window title bar now reads "BMS - Business Management System" on both macOS (via AppInfo.xcconfig) and Windows (via Runner.rc); Flutter MaterialApp title updated to match + ### Added - MySQL sync engine: bidirectional SQLite-to-MySQL sync running as a 30-second background interval when a MySQL connection is configured; SQLite remains the primary local-first store; MySQL is the shared hub for multi-terminal and cloud-backup scenarios - `SyncService` with per-table push (SQLite to MySQL) and pull (MySQL to SQLite) using `updated_at` as the change cursor; last-write-wins conflict resolution diff --git a/lib/app.dart b/lib/app.dart index ba64746..2bb5539 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -17,7 +17,7 @@ class BmsApp extends ConsumerWidget { final langCode = ref.watch(languageProvider); return MaterialApp.router( - title: 'BMS', + title: 'BMS - Business Management System', theme: AppTheme.light, routerConfig: router, debugShowCheckedModeBanner: false, diff --git a/lib/features/eula/presentation/eula_screen.dart b/lib/features/eula/presentation/eula_screen.dart index 2e3e57d..6cdd1d3 100644 --- a/lib/features/eula/presentation/eula_screen.dart +++ b/lib/features/eula/presentation/eula_screen.dart @@ -1,54 +1,171 @@ import 'package:bms/core/theme/app_colors.dart'; import 'package:bms/core/theme/app_text_styles.dart'; -import 'package:bms/l10n/l10n.dart'; import 'package:bms/providers/eula_provider.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +// The EULA is a legal document and must always be displayed in English, +// regardless of the user's selected application language. const _eulaText = ''' END-USER LICENSE AGREEMENT (EULA) Business Management System (BMS) IMPORTANT - READ CAREFULLY BEFORE USING THIS SOFTWARE -This End-User License Agreement ("Agreement") is a legal contract between you ("Licensee") and the BMS software provider ("Licensor"). By clicking "Accept & Continue" you agree to be bound by the terms of this Agreement. If you do not agree, click "Decline" to exit. +This End-User License Agreement ("Agreement") is a legally binding contract between you, either an individual or a single legal entity ("Licensee"), and the BMS software provider ("Licensor"). By clicking "Accept & Continue" or by installing, copying, or otherwise using the Software, you acknowledge that you have read this Agreement, understand it, and agree to be bound by its terms and conditions. If you do not agree, click "Decline" and the application will close. -1. GRANT OF LICENSE -Licensor grants you a non-exclusive, non-transferable license to install and use one copy of BMS on devices associated with your license key, solely for your internal business operations. -2. RESTRICTIONS -You may not: -(a) copy, modify, or distribute the software without prior written consent; -(b) reverse engineer, decompile, or disassemble the software; -(c) sublicense, rent, lease, or lend the software to any third party; -(d) remove or alter any proprietary notices, labels, or marks. +1. DEFINITIONS -3. OWNERSHIP -The software and all copies thereof are proprietary to Licensor and title thereto remains with Licensor. All rights in the software not specifically granted in this Agreement are reserved. +"Software" means the Business Management System (BMS) application, including all files, modules, updates, upgrades, and associated documentation provided by Licensor. -4. LICENSE KEY -The software requires activation with a valid license key. You must not share, transfer, or disclose your license key to unauthorized parties. +"License Key" means the unique alphanumeric code issued by Licensor that activates and validates your license to use the Software. -5. DATA AND PRIVACY -You retain full ownership of all business data entered into the software. The software connects to Licensor's licensing servers solely for the purpose of license validation. No personally identifiable business data is transmitted to Licensor without your explicit consent. +"Device" means a single physical computer or workstation on which the Software is installed and activated. -6. DISCLAIMER OF WARRANTIES -THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +"User Data" means all business records, transactions, customer information, inventory data, and any other data you enter into or generate using the Software. -7. LIMITATION OF LIABILITY -IN NO EVENT SHALL LICENSOR BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES, HOWEVER CAUSED, INCLUDING LOSS OF PROFITS, BUSINESS INTERRUPTION, OR LOSS OF DATA, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -8. TERM AND TERMINATION -This Agreement is effective until terminated. Your rights under this Agreement will terminate automatically if you breach any term. Upon termination, you must cease all use of the software and destroy all copies. +2. GRANT OF LICENSE -9. GOVERNING LAW -This Agreement shall be governed by the laws of the jurisdiction in which Licensor is incorporated, without regard to conflict of law provisions. +Subject to the terms of this Agreement and payment of applicable license fees, Licensor grants you a limited, non-exclusive, non-transferable, non-sublicensable license to: -10. ENTIRE AGREEMENT -This Agreement constitutes the entire agreement between the parties with respect to the software and supersedes all prior understandings and agreements. +(a) Install and use one activated instance of the Software on the number of Devices permitted by your purchased license tier (Free, Pro, or Enterprise); -By accepting this Agreement you confirm that you have read, understood, and agree to all the terms and conditions stated above. +(b) Make one (1) archival copy of the Software solely for backup purposes, provided that such copy includes all copyright and proprietary notices. + +This license is granted solely for your internal business operations. No rights are granted except as expressly stated herein. + + +3. LICENSE TIERS AND FEATURES + +The Software is offered in the following tiers, each activating a defined set of features: + +- Free Tier: Point-of-sale, inventory management, and customer records. +- Pro Tier: All Free features plus reports, goods received notes, cheques, petty cash, and debtor management. +- Enterprise Tier: All Pro features plus user management, API access, and multi-branch support. + +Feature access is enforced at runtime via your License Key. Attempting to access features outside your licensed tier is prohibited. + + +4. RESTRICTIONS + +You may NOT, and may not permit any third party to: + +(a) Copy, reproduce, distribute, publish, or sublicense the Software or any portion thereof without prior written consent from Licensor; + +(b) Modify, adapt, translate, reverse engineer, decompile, disassemble, or create derivative works based on the Software; + +(c) Rent, lease, lend, sell, resell, or transfer the Software or any License Key to any third party; + +(d) Remove, alter, or obscure any copyright, trademark, patent, or other proprietary notices embedded in the Software; + +(e) Use the Software to develop a competing product or service; + +(f) Circumvent, disable, or otherwise interfere with the license enforcement mechanisms, activation servers, or security features of the Software; + +(g) Share, publish, or disclose your License Key to any unauthorized person; + +(h) Use the Software in any manner that violates applicable local, national, or international laws or regulations. + + +5. INTELLECTUAL PROPERTY AND OWNERSHIP + +The Software, including but not limited to its source code, object code, interfaces, design, architecture, algorithms, and documentation, is and shall remain the exclusive intellectual property of Licensor. This Agreement does not convey to you any ownership interest in the Software, but only a limited right of use as expressly set forth herein. + +All trademarks, service marks, trade names, and logos associated with BMS are the property of Licensor. Nothing in this Agreement grants you the right to use any such marks. + + +6. LICENSE KEY AND ACTIVATION + +6.1 The Software requires online activation using a valid License Key issued by Licensor. You must keep your License Key confidential and must not share it. + +6.2 The Software may contact Licensor's licensing servers periodically to validate your License Key. An internet connection may be required for initial activation and periodic revalidation. + +6.3 A grace period of seven (7) days is provided for offline use after the last successful validation. After the grace period expires, the Software will require revalidation before permitting access. + +6.4 Licensor reserves the right to revoke a License Key if it detects fraudulent use, key sharing, or any breach of this Agreement. + + +7. USER DATA AND PRIVACY + +7.1 You retain full ownership of all User Data. Licensor makes no claim to your business data. + +7.2 The Software stores User Data locally on your device using a SQLite database. Data is stored unencrypted at the database level. Optional MySQL sync is available for multi-device deployments and operates entirely within your own infrastructure. + +7.3 The Software communicates with Licensor's servers solely for the purpose of license key activation and validation. No User Data, business records, customer information, or personally identifiable information is transmitted to Licensor. + +7.4 Licensor will handle any personal data it collects (such as device identifiers for license enforcement) in accordance with applicable data protection laws. + + +8. UPDATES AND SUPPORT + +8.1 Licensor may, at its sole discretion, provide updates, patches, or new versions of the Software. Such updates may be subject to additional terms. + +8.2 Support is provided according to the support plan associated with your license tier. Licensor is not obligated to provide support under this Agreement unless a separate support agreement exists. + +8.3 Licensor reserves the right to discontinue the Software or any feature at any time with reasonable notice. + + +9. DISCLAIMER OF WARRANTIES + +THE SOFTWARE IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTY OF ANY KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, LICENSOR EXPRESSLY DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, INCLUDING WITHOUT LIMITATION: + +- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE; +- WARRANTIES OF NON-INFRINGEMENT OF THIRD-PARTY RIGHTS; +- WARRANTIES THAT THE SOFTWARE WILL BE UNINTERRUPTED, ERROR-FREE, OR SECURE; +- WARRANTIES REGARDING THE ACCURACY OR COMPLETENESS OF THE SOFTWARE OR ITS OUTPUTS. + +YOU ASSUME THE ENTIRE RISK ARISING OUT OF YOUR USE OF THE SOFTWARE AND ANY OUTPUT PRODUCED THEREBY. + + +10. LIMITATION OF LIABILITY + +10.1 TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL LICENSOR, ITS DIRECTORS, EMPLOYEES, AGENTS, OR SUPPLIERS BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, CONSEQUENTIAL, OR PUNITIVE DAMAGES, INCLUDING BUT NOT LIMITED TO: + +- LOSS OF PROFITS, REVENUE, OR BUSINESS; +- LOSS OF DATA OR BUSINESS INTERRUPTION; +- COST OF SUBSTITUTE GOODS OR SERVICES; + +EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +10.2 IN NO EVENT SHALL LICENSOR'S TOTAL CUMULATIVE LIABILITY ARISING OUT OF OR RELATED TO THIS AGREEMENT EXCEED THE GREATER OF (A) THE AMOUNT YOU PAID FOR THE SOFTWARE LICENSE IN THE TWELVE (12) MONTHS PRECEDING THE CLAIM, OR (B) ONE HUNDRED US DOLLARS (USD 100). + + +11. INDEMNIFICATION + +You agree to indemnify, defend, and hold harmless Licensor and its officers, directors, employees, and agents from and against any claims, liabilities, damages, losses, costs, and expenses (including reasonable legal fees) arising out of or related to: (a) your use of the Software in violation of this Agreement; (b) your violation of any applicable law or regulation; or (c) infringement of any third-party rights caused by your use of the Software. + + +12. TERM AND TERMINATION + +12.1 This Agreement is effective upon your acceptance and shall continue until terminated. + +12.2 This Agreement terminates automatically and without notice if you breach any term herein. + +12.3 Upon termination, you must immediately cease all use of the Software and destroy all copies in your possession or control, including backup copies. + +12.4 Sections 5 (Intellectual Property), 7 (User Data), 9 (Disclaimer of Warranties), 10 (Limitation of Liability), 11 (Indemnification), and 13 (Governing Law) shall survive termination. + + +13. GOVERNING LAW AND DISPUTE RESOLUTION + +This Agreement shall be governed by and construed in accordance with the laws of the jurisdiction in which Licensor is incorporated, without regard to its conflict of law provisions. Any dispute arising from this Agreement that cannot be resolved by good-faith negotiation shall be subject to the exclusive jurisdiction of the courts of that jurisdiction. + + +14. SEVERABILITY + +If any provision of this Agreement is found to be invalid, illegal, or unenforceable, that provision shall be modified to the minimum extent necessary to make it enforceable, and the remaining provisions shall continue in full force and effect. + + +15. ENTIRE AGREEMENT + +This Agreement constitutes the entire agreement between you and Licensor with respect to the Software and supersedes all prior or contemporaneous understandings, agreements, negotiations, representations, and warranties, whether written or oral, relating to the Software. + + +BY CLICKING "ACCEPT & CONTINUE" YOU CONFIRM THAT YOU HAVE READ, UNDERSTOOD, AND AGREE TO ALL THE TERMS AND CONDITIONS OF THIS END-USER LICENSE AGREEMENT. '''; class EulaScreen extends ConsumerStatefulWidget { @@ -90,19 +207,21 @@ class _EulaScreenState extends ConsumerState { if (!_agreed || _accepting) return; setState(() => _accepting = true); await ref.read(eulaProvider.notifier).accept(); - // Router will redirect automatically once eulaProvider emits true. } Future _decline() async { await showDialog( context: context, builder: (ctx) => AlertDialog( - title: Text(context.l10n.eulaDeclineTitle), - content: Text(context.l10n.eulaDeclineMessage), + title: const Text('Decline Agreement'), + content: const Text( + 'You must accept the License Agreement to use BMS. ' + 'The application will close if you decline.', + ), actions: [ TextButton( onPressed: () => Navigator.of(ctx).pop(), - child: Text(context.l10n.cancel), + child: const Text('Cancel'), ), FilledButton( style: FilledButton.styleFrom(backgroundColor: AppColors.error), @@ -110,7 +229,7 @@ class _EulaScreenState extends ConsumerState { Navigator.of(ctx).pop(); SystemNavigator.pop(); }, - child: Text(context.l10n.eulaDeclineConfirm), + child: const Text('Close App'), ), ], ), @@ -124,7 +243,7 @@ class _EulaScreenState extends ConsumerState { body: SafeArea( child: Column( children: [ - _Header(), + const _Header(), Expanded( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 24), @@ -160,6 +279,8 @@ class _EulaScreenState extends ConsumerState { } class _Header extends StatelessWidget { + const _Header(); + @override Widget build(BuildContext context) { return Container( @@ -169,35 +290,29 @@ class _Header extends StatelessWidget { color: AppColors.surface, border: Border(bottom: BorderSide(color: AppColors.border)), ), - child: Column( + child: const Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ - Container( - width: 40, - height: 40, - decoration: BoxDecoration( - color: AppColors.primary, - borderRadius: BorderRadius.circular(8), - ), - child: const Icon(Icons.business_center, - color: Colors.white, size: 22), - ), - const SizedBox(width: 12), - const Text('BMS', style: AppTextStyles.titleLarge), + _LogoBadge(), + SizedBox(width: 12), + Text('BMS', style: AppTextStyles.titleLarge), ], ), - const SizedBox(height: 16), + SizedBox(height: 16), Text( - context.l10n.eulaTitle, + 'License & Terms of Use', style: AppTextStyles.headlineMedium, ), - const SizedBox(height: 4), + SizedBox(height: 4), Text( - context.l10n.eulaSubtitle, - style: AppTextStyles.bodyMedium - .copyWith(color: AppColors.textSecondary), + 'Please read and accept the End-User License Agreement before continuing.', + style: TextStyle( + fontFamily: 'Poppins', + fontSize: 14, + color: AppColors.textSecondary, + ), ), ], ), @@ -205,6 +320,19 @@ class _Header extends StatelessWidget { } } +class _LogoBadge extends StatelessWidget { + const _LogoBadge(); + + @override + Widget build(BuildContext context) { + return SizedBox( + width: 40, + height: 40, + child: SvgPicture.asset('assets/images/bms_logo.svg'), + ); + } +} + class _TermsCard extends StatelessWidget { const _TermsCard({required this.controller}); final ScrollController controller; @@ -247,25 +375,36 @@ class _ScrollHint extends StatelessWidget { @override Widget build(BuildContext context) { if (scrolledToBottom) { - return Row( + return const Row( children: [ - const Icon(Icons.check_circle, color: AppColors.success, size: 16), - const SizedBox(width: 6), - Text( - context.l10n.eulaScrollComplete, - style: AppTextStyles.bodySmall.copyWith(color: AppColors.success), + Icon(Icons.check_circle, color: AppColors.success, size: 16), + SizedBox(width: 6), + Flexible( + child: Text( + 'You have read the full agreement', + style: TextStyle( + fontFamily: 'Poppins', + fontSize: 12, + color: AppColors.success, + ), + ), ), ], ); } - return Row( + return const Row( children: [ - const Icon(Icons.keyboard_arrow_down, - color: AppColors.textSecondary, size: 16), - const SizedBox(width: 6), - Text( - context.l10n.eulaScrollHint, - style: AppTextStyles.bodySmall.copyWith(color: AppColors.textSecondary), + Icon(Icons.keyboard_arrow_down, color: AppColors.textSecondary, size: 16), + SizedBox(width: 6), + Flexible( + child: Text( + 'Scroll to the bottom to enable acceptance', + style: TextStyle( + fontFamily: 'Poppins', + fontSize: 12, + color: AppColors.textSecondary, + ), + ), ), ], ); @@ -303,11 +442,11 @@ class _AgreementCheckbox extends StatelessWidget { child: Padding( padding: const EdgeInsets.only(top: 12), child: Text( - context.l10n.eulaCheckboxLabel, - style: AppTextStyles.bodyMedium.copyWith( - color: enabled - ? AppColors.textPrimary - : AppColors.textDisabled, + 'I have read and agree to the End-User License Agreement and Terms of Use', + style: TextStyle( + fontFamily: 'Poppins', + fontSize: 14, + color: enabled ? AppColors.textPrimary : AppColors.textDisabled, ), ), ), @@ -343,7 +482,7 @@ class _ActionButtons extends StatelessWidget { side: const BorderSide(color: AppColors.error), padding: const EdgeInsets.symmetric(vertical: 14), ), - child: Text(context.l10n.eulaDecline), + child: const Text('Decline'), ), ), const SizedBox(width: 12), @@ -365,7 +504,7 @@ class _ActionButtons extends StatelessWidget { color: Colors.white, ), ) - : Text(context.l10n.eulaAccept), + : const Text('Accept & Continue'), ), ), ], diff --git a/macos/Runner/Info.plist b/macos/Runner/Info.plist index 4789daa..61f04ec 100644 --- a/macos/Runner/Info.plist +++ b/macos/Runner/Info.plist @@ -12,6 +12,8 @@ $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 + CFBundleDisplayName + BMS - Business Management System CFBundleName $(PRODUCT_NAME) CFBundlePackageType diff --git a/windows/runner/Runner.rc b/windows/runner/Runner.rc index 31ca5c3..70e20f3 100644 --- a/windows/runner/Runner.rc +++ b/windows/runner/Runner.rc @@ -90,12 +90,12 @@ BEGIN BLOCK "040904e4" BEGIN VALUE "CompanyName", "lk.getbms" "\0" - VALUE "FileDescription", "bms" "\0" + VALUE "FileDescription", "BMS - Business Management System" "\0" VALUE "FileVersion", VERSION_AS_STRING "\0" VALUE "InternalName", "bms" "\0" VALUE "LegalCopyright", "Copyright (C) 2026 lk.getbms. All rights reserved." "\0" VALUE "OriginalFilename", "bms.exe" "\0" - VALUE "ProductName", "bms" "\0" + VALUE "ProductName", "BMS - Business Management System" "\0" VALUE "ProductVersion", VERSION_AS_STRING "\0" END END