session creation and show business information
This commit is contained in:
@@ -18,6 +18,7 @@ export 'src/mocks/home_repository_mock.dart';
|
||||
export 'src/mocks/business_repository_mock.dart';
|
||||
export 'src/mocks/order_repository_mock.dart';
|
||||
export 'src/data_connect_module.dart';
|
||||
export 'src/session/client_session_store.dart';
|
||||
|
||||
// Export the generated Data Connect SDK
|
||||
export 'src/dataconnect_generated/generated.dart';
|
||||
|
||||
@@ -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._();
|
||||
}
|
||||
@@ -122,6 +122,7 @@ class AuthRepositoryImpl implements AuthRepositoryInterface {
|
||||
Future<void> signOut() async {
|
||||
try {
|
||||
await _firebaseAuth.signOut();
|
||||
dc.ClientSessionStore.instance.clear();
|
||||
} catch (e) {
|
||||
throw Exception('Error signing out: ${e.toString()}');
|
||||
}
|
||||
@@ -147,10 +148,36 @@ class AuthRepositoryImpl implements AuthRepositoryInterface {
|
||||
throw Exception('User email is missing in profile data.');
|
||||
}
|
||||
|
||||
return domain.User(
|
||||
final domainUser = domain.User(
|
||||
id: user.id,
|
||||
email: email,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.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_event.dart';
|
||||
@@ -116,6 +117,14 @@ class ClientHomePage extends StatelessWidget {
|
||||
Widget _buildHeader(BuildContext context, dynamic i18n) {
|
||||
return BlocBuilder<ClientHomeBloc, ClientHomeState>(
|
||||
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(
|
||||
padding: const EdgeInsets.fromLTRB(
|
||||
UiConstants.space4,
|
||||
@@ -140,12 +149,19 @@ class ClientHomePage extends StatelessWidget {
|
||||
),
|
||||
child: CircleAvatar(
|
||||
backgroundColor: UiColors.primary.withValues(alpha: 0.1),
|
||||
child: Text(
|
||||
'C',
|
||||
style: UiTypography.body2b.copyWith(
|
||||
color: UiColors.primary,
|
||||
),
|
||||
),
|
||||
backgroundImage:
|
||||
photoUrl != null && photoUrl.isNotEmpty
|
||||
? NetworkImage(photoUrl)
|
||||
: null,
|
||||
child:
|
||||
photoUrl != null && photoUrl.isNotEmpty
|
||||
? null
|
||||
: Text(
|
||||
avatarLetter,
|
||||
style: UiTypography.body2b.copyWith(
|
||||
color: UiColors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: UiConstants.space3),
|
||||
@@ -156,7 +172,7 @@ class ClientHomePage extends StatelessWidget {
|
||||
i18n.dashboard.welcome_back,
|
||||
style: UiTypography.footnote2r.textSecondary,
|
||||
),
|
||||
Text('Your Company', style: UiTypography.body1b),
|
||||
Text(businessName, style: UiTypography.body1b),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:core_localization/core_localization.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.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.
|
||||
class SettingsProfileHeader extends StatelessWidget {
|
||||
@@ -12,6 +13,14 @@ class SettingsProfileHeader extends StatelessWidget {
|
||||
/// Builds the profile header UI.
|
||||
Widget build(BuildContext context) {
|
||||
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(
|
||||
backgroundColor: UiColors.bgSecondary,
|
||||
@@ -40,20 +49,28 @@ class SettingsProfileHeader extends StatelessWidget {
|
||||
border: Border.all(color: UiColors.border, width: 2),
|
||||
color: UiColors.white,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'C',
|
||||
style: UiTypography.headline1m.copyWith(
|
||||
color: UiColors.primary,
|
||||
),
|
||||
),
|
||||
child: CircleAvatar(
|
||||
backgroundColor: UiColors.primary.withValues(alpha: 0.1),
|
||||
backgroundImage:
|
||||
photoUrl != null && photoUrl.isNotEmpty
|
||||
? NetworkImage(photoUrl)
|
||||
: null,
|
||||
child:
|
||||
photoUrl != null && photoUrl.isNotEmpty
|
||||
? null
|
||||
: Text(
|
||||
avatarLetter,
|
||||
style: UiTypography.headline1m.copyWith(
|
||||
color: UiColors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text('Your Company', style: UiTypography.body1b.textPrimary),
|
||||
Text(businessName, style: UiTypography.body1b.textPrimary),
|
||||
const SizedBox(height: UiConstants.space1),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
@@ -65,7 +82,7 @@ class SettingsProfileHeader extends StatelessWidget {
|
||||
color: UiColors.textSecondary,
|
||||
),
|
||||
Text(
|
||||
'client@example.com',
|
||||
email,
|
||||
style: UiTypography.footnote1r.textSecondary,
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user