session creation and show business information

This commit is contained in:
José Salazar
2026-01-22 18:17:24 -05:00
parent 9ddb0435ed
commit a70468ceb4
5 changed files with 127 additions and 17 deletions

View File

@@ -18,6 +18,7 @@ export 'src/mocks/home_repository_mock.dart';
export 'src/mocks/business_repository_mock.dart'; export 'src/mocks/business_repository_mock.dart';
export 'src/mocks/order_repository_mock.dart'; export 'src/mocks/order_repository_mock.dart';
export 'src/data_connect_module.dart'; export 'src/data_connect_module.dart';
export 'src/session/client_session_store.dart';
// Export the generated Data Connect SDK // Export the generated Data Connect SDK
export 'src/dataconnect_generated/generated.dart'; export 'src/dataconnect_generated/generated.dart';

View File

@@ -0,0 +1,49 @@
import 'package:krow_domain/krow_domain.dart' as domain;
class ClientBusinessSession {
final String id;
final String businessName;
final String? email;
final String? city;
final String? contactName;
final String? companyLogoUrl;
const ClientBusinessSession({
required this.id,
required this.businessName,
this.email,
this.city,
this.contactName,
this.companyLogoUrl,
});
}
class ClientSession {
final domain.User user;
final String? userPhotoUrl;
final ClientBusinessSession? business;
const ClientSession({
required this.user,
required this.userPhotoUrl,
required this.business,
});
}
class ClientSessionStore {
ClientSession? _session;
ClientSession? get session => _session;
void setSession(ClientSession session) {
_session = session;
}
void clear() {
_session = null;
}
static final ClientSessionStore instance = ClientSessionStore._();
ClientSessionStore._();
}

View File

@@ -122,6 +122,7 @@ class AuthRepositoryImpl implements AuthRepositoryInterface {
Future<void> signOut() async { Future<void> signOut() async {
try { try {
await _firebaseAuth.signOut(); await _firebaseAuth.signOut();
dc.ClientSessionStore.instance.clear();
} catch (e) { } catch (e) {
throw Exception('Error signing out: ${e.toString()}'); throw Exception('Error signing out: ${e.toString()}');
} }
@@ -147,10 +148,36 @@ class AuthRepositoryImpl implements AuthRepositoryInterface {
throw Exception('User email is missing in profile data.'); throw Exception('User email is missing in profile data.');
} }
return domain.User( final domainUser = domain.User(
id: user.id, id: user.id,
email: email, email: email,
role: user.role.stringValue, role: user.role.stringValue,
); );
final businessResponse = await _dataConnect.getBusinessesByUserId(
userId: firebaseUserId,
).execute();
final business = businessResponse.data.businesses.isNotEmpty
? businessResponse.data.businesses.first
: null;
dc.ClientSessionStore.instance.setSession(
dc.ClientSession(
user: domainUser,
userPhotoUrl: user.photoUrl,
business: business == null
? null
: dc.ClientBusinessSession(
id: business.id,
businessName: business.businessName,
email: business.email,
city: business.city,
contactName: business.contactName,
companyLogoUrl: business.companyLogoUrl,
),
),
);
return domainUser;
} }
} }

View File

@@ -3,6 +3,7 @@ import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_modular/flutter_modular.dart'; import 'package:flutter_modular/flutter_modular.dart';
import 'package:krow_data_connect/krow_data_connect.dart' as dc;
import '../blocs/client_home_bloc.dart'; import '../blocs/client_home_bloc.dart';
import '../blocs/client_home_event.dart'; import '../blocs/client_home_event.dart';
@@ -116,6 +117,14 @@ class ClientHomePage extends StatelessWidget {
Widget _buildHeader(BuildContext context, dynamic i18n) { Widget _buildHeader(BuildContext context, dynamic i18n) {
return BlocBuilder<ClientHomeBloc, ClientHomeState>( return BlocBuilder<ClientHomeBloc, ClientHomeState>(
builder: (context, state) { builder: (context, state) {
final session = dc.ClientSessionStore.instance.session;
final businessName =
session?.business?.businessName ?? 'Your Company';
final photoUrl = session?.userPhotoUrl;
final avatarLetter = businessName.trim().isNotEmpty
? businessName.trim()[0].toUpperCase()
: 'C';
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB( padding: const EdgeInsets.fromLTRB(
UiConstants.space4, UiConstants.space4,
@@ -140,12 +149,19 @@ class ClientHomePage extends StatelessWidget {
), ),
child: CircleAvatar( child: CircleAvatar(
backgroundColor: UiColors.primary.withValues(alpha: 0.1), backgroundColor: UiColors.primary.withValues(alpha: 0.1),
child: Text( backgroundImage:
'C', photoUrl != null && photoUrl.isNotEmpty
style: UiTypography.body2b.copyWith( ? NetworkImage(photoUrl)
color: UiColors.primary, : null,
), child:
), photoUrl != null && photoUrl.isNotEmpty
? null
: Text(
avatarLetter,
style: UiTypography.body2b.copyWith(
color: UiColors.primary,
),
),
), ),
), ),
const SizedBox(width: UiConstants.space3), const SizedBox(width: UiConstants.space3),
@@ -156,7 +172,7 @@ class ClientHomePage extends StatelessWidget {
i18n.dashboard.welcome_back, i18n.dashboard.welcome_back,
style: UiTypography.footnote2r.textSecondary, style: UiTypography.footnote2r.textSecondary,
), ),
Text('Your Company', style: UiTypography.body1b), Text(businessName, style: UiTypography.body1b),
], ],
), ),
], ],

View File

@@ -2,6 +2,7 @@ import 'package:core_localization/core_localization.dart';
import 'package:design_system/design_system.dart'; import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart'; import 'package:flutter_modular/flutter_modular.dart';
import 'package:krow_data_connect/krow_data_connect.dart' as dc;
/// A widget that displays the profile header with avatar and company info. /// A widget that displays the profile header with avatar and company info.
class SettingsProfileHeader extends StatelessWidget { class SettingsProfileHeader extends StatelessWidget {
@@ -12,6 +13,14 @@ class SettingsProfileHeader extends StatelessWidget {
/// Builds the profile header UI. /// Builds the profile header UI.
Widget build(BuildContext context) { Widget build(BuildContext context) {
final labels = t.client_settings.profile; final labels = t.client_settings.profile;
final session = dc.ClientSessionStore.instance.session;
final businessName =
session?.business?.businessName ?? 'Your Company';
final email = session?.user.email ?? 'client@example.com';
final photoUrl = session?.userPhotoUrl;
final avatarLetter = businessName.trim().isNotEmpty
? businessName.trim()[0].toUpperCase()
: 'C';
return SliverAppBar( return SliverAppBar(
backgroundColor: UiColors.bgSecondary, backgroundColor: UiColors.bgSecondary,
@@ -40,20 +49,28 @@ class SettingsProfileHeader extends StatelessWidget {
border: Border.all(color: UiColors.border, width: 2), border: Border.all(color: UiColors.border, width: 2),
color: UiColors.white, color: UiColors.white,
), ),
child: Center( child: CircleAvatar(
child: Text( backgroundColor: UiColors.primary.withValues(alpha: 0.1),
'C', backgroundImage:
style: UiTypography.headline1m.copyWith( photoUrl != null && photoUrl.isNotEmpty
color: UiColors.primary, ? NetworkImage(photoUrl)
), : null,
), child:
photoUrl != null && photoUrl.isNotEmpty
? null
: Text(
avatarLetter,
style: UiTypography.headline1m.copyWith(
color: UiColors.primary,
),
),
), ),
), ),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text('Your Company', style: UiTypography.body1b.textPrimary), Text(businessName, style: UiTypography.body1b.textPrimary),
const SizedBox(height: UiConstants.space1), const SizedBox(height: UiConstants.space1),
Row( Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
@@ -65,7 +82,7 @@ class SettingsProfileHeader extends StatelessWidget {
color: UiColors.textSecondary, color: UiColors.textSecondary,
), ),
Text( Text(
'client@example.com', email,
style: UiTypography.footnote1r.textSecondary, style: UiTypography.footnote1r.textSecondary,
), ),
], ],