Appearance
Login
- File:
lib/views/login_page.dart
The LoginPage is a Flutter widget that serves as the authentication entry point for the HVC Mobile application. It provides multiple authentication methods including SSO login, rapid connect, QR code scanning, and biometric authentication.
Class Structure
Class Definition
dart
class LoginPage extends StatelessWidget {
static const String routeName = '/LoginPage';
LoginPage({super.key});
}Controllers
dart
final AuthController authController = Get.find();
final ContactsController contactsController = Get.find();
final RealTimeController realTimeController = Get.find();
final MeetingsController meetingsController = Get.find();State Variables
dart
final TextEditingController orgCtrl = TextEditingController();
final storage = GetStorage();Dependencies
Required Packages
flutter/material.dart- Core Flutter UI componentsget/get.dart- State management and routingget_storage/get_storage.dart- Local storagepermission_handler/permission_handler.dart- Permission management
Internal Dependencies
auth_controller.dart- Authentication logiccontacts_controller.dart- Contact managementmeetings_controller.dart- Meeting managementreal_time_controller.dart- Real-time communicationhlk_helpers/- Custom helper utilitiesshared/- Shared constants and configurations
Authentication Methods
1. SSO Login
dart
onTapped: () async {
if (GetUtils.isNullOrBlank(orgCtrl.text.trim())!) {
HlkDialog.showErrorSnackBar('Please enter Organization to proceed');
} else {
await authController.ssoLogin(orgCtrl.text.trim()).whenComplete(
() async {
await realTimeController.onInit();
await contactsController.getMe();
},
);
}
}2. Rapid Connect
dart
onTapped: () async {
if (GetUtils.isNullOrBlank(orgCtrl.text.trim())!) {
HlkDialog.showErrorSnackBar('Please enter Organization to proceed');
} else {
var rapidConn = await meetingsController.rapidConnect(orgCtrl.text.trim());
if (rapidConn != null) {
// Handle rapid connect success
}
}
}3. QR Code Scanning
dart
onTapped: () async => await validatePermission(
Permission.camera,
() => Get.toNamed(NewScannerPage.routeName)
)4. Biometric Authentication
dart
onTapped: () async {
await authController.runBiometric().whenComplete(
() async {
await realTimeController.onInit();
await contactsController.getMe();
},
);
}UI Components
Organization Input Field
dart
TextField(
controller: orgCtrl,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: const BorderSide(
width: 0,
style: BorderStyle.none,
),
),
hintText: 'Enter Organization',
prefixIcon: const Icon(
Icons.business,
color: kAppColorBlue,
),
filled: true,
),
maxLines: 1,
)Action Buttons
Login Button
- Primary action button
- Triggers SSO login
- Shows loading state
Rapid Connect Button
- Secondary action button
- Handles rapid connection flow
- Shows loading state
Scan Code Button
- Outlined button
- Requires camera permission
- Navigates to scanner page
Biometric Button
- Conditional rendering based on
isBioEnabled - Includes fingerprint icon
- Shows loading state
- Conditional rendering based on
State Management
Reactive State
dart
Obx(() => Container(
// UI components that react to state changes
))Loading States
dart
isLoading: authController.loading.valueStorage Management
dart
if (storage.hasData(Constants.ORGANISATION))
orgCtrl.text = storage.read(Constants.ORGANISATION) ?? '';Layout Management
Responsive Design
dart
OrientationBuilder(
builder: (context, orientation) {
isLandscape = orientation == Orientation.landscape;
return Scaffold(
body: isLandscape ? LandscapeLayout() : PortraitLayout()
);
}
)Layout Components
Landscape Layout
- Split screen design
- Left side: Background image with logo
- Right side: Login form
Portrait Layout
- Single column design
- Top: Background image with logo
- Bottom: Login form
Security Features
Biometric Authentication
dart
if (isBioEnabled && isBioTokenValid()) {
Future.delayed(const Duration(seconds: 1), () async {
await authController.runBiometric()
});
}Permission Handling
dart
await validatePermission(
Permission.camera,
() => Get.toNamed(NewScannerPage.routeName)
)