Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Messages Tab 📫 #46

Merged
merged 5 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
<img src="assets/thumbnail/hotelyn_logo.png" height="51" alt="Hotelyn logo" />
</p>
<p align="center">The most incredible 🏨 app in the 🌎</p>
<a href="https://github.com/enzoftware/hotelyn/actions"><img src="https://github.com/enzoftware/hotelyn/actions/workflows/main.yaml/badge.svg" alt="Build Status"></a>
<p align="center">⚠️ I'm reimagining and restructuring various aspects of the Hotelyn app. This includes improvements to the user interface, performance optimizations, and the incorporation of exciting new functionalities ⚠️</p>
Binary file added assets/images/messages/empty.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions ios/Flutter/flutter_export_environment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
export "FLUTTER_ROOT=/Users/enzolizama/Development/flutter"
export "FLUTTER_APPLICATION_PATH=/Users/enzolizama/Projects/hotelyn"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_TARGET=lib/main.dart"
export "FLUTTER_TARGET=/Users/enzolizama/Projects/hotelyn/lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1"
export "DART_DEFINES=RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==,RkxVVFRFUl9XRUJfQ0FOVkFTS0lUX1VSTD1odHRwczovL3d3dy5nc3RhdGljLmNvbS9mbHV0dGVyLWNhbnZhc2tpdC8zZjNlNTYwMjM2NTM5YjdlMjcwMmY1YWM3OTBiMmE0NjkxYjMyZDQ5Lw=="
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=.dart_tool/package_config.json"
export "PACKAGE_CONFIG=/Users/enzolizama/Projects/hotelyn/.dart_tool/package_config.json"
35 changes: 35 additions & 0 deletions lib/components/app_bar.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import 'package:flutter/widgets.dart';
import 'package:hotelyn/components/text_style/hotelyn_text_style.dart';

class HotelynHomeAppBar extends StatelessWidget implements PreferredSizeWidget {
const HotelynHomeAppBar({
super.key,
required this.title,
required this.iconData,
this.onIconPressed,
});

final String title;
final IconData iconData;
final VoidCallback? onIconPressed;

@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 60, left: 20, right: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
title,
style: HotelynTextStyle.h1,
),
Icon(iconData, size: 24),
],
),
);
}

@override
Size get preferredSize => const Size(double.infinity, 120);
}
30 changes: 30 additions & 0 deletions lib/components/text_input/hotelyn_search_input.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import 'package:hotelyn/components/theme/hotelyn_colors.dart';

class HotelynSearchInput extends StatelessWidget {
const HotelynSearchInput({
super.key,
required this.hintText,
});

final String hintText;

final _radius = 30.0;

@override
Widget build(BuildContext context) {
return TextField(
autofocus: false,
decoration: InputDecoration(
filled: true,
fillColor: HotelynAppColors.lightGrey,
prefixIcon: const Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(_radius)),
borderSide: BorderSide.none,
),
hintText: hintText,
),
);
}
}
6 changes: 5 additions & 1 deletion lib/features/home/home_tab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hotelyn/components/navigation_bar/navigation_bar.dart';
import 'package:hotelyn/components/navigation_bar/navigation_bar_cubit.dart';
import 'package:hotelyn/components/navigation_bar/navigation_bar_state.dart';
import 'package:hotelyn/features/messages/messages_cubit.dart';
import 'package:hotelyn/features/messages/messages_tab.dart';
import 'package:hotelyn/features/profile/profile_cubit.dart';
import 'package:hotelyn/features/profile/profile_tab.dart';
Expand All @@ -25,6 +26,9 @@ class HomePage extends StatelessWidget {
BlocProvider<ProfileCubit>(
create: (_) => ProfileCubit(),
),
BlocProvider<MessagesCubit>(
create: (_) => MessagesCubit(),
),
],
child: BlocBuilder<NavigationBarCubit, NavigationBarState>(
builder: (context, state) {
Expand All @@ -34,7 +38,7 @@ class HomePage extends StatelessWidget {
body: <Widget>[
const HomeTab(),
const SearchTab(),
const MesssagesTab(),
const MessagesTab(),
const ProfileTab()
].elementAt(index),
);
Expand Down
15 changes: 2 additions & 13 deletions lib/features/home/widgets/home_header.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:hotelyn/components/text_input/hotelyn_search_input.dart';
import 'package:hotelyn/components/text_style/hotelyn_text_style.dart';
import 'package:hotelyn/components/theme/hotelyn_colors.dart';

Expand Down Expand Up @@ -44,19 +45,7 @@ class HotelynHeader extends SliverPersistentHeaderDelegate {
),
SizedBox(height: 32),
// TODO: Split in different widget and pass controller
TextField(
autofocus: false,
decoration: InputDecoration(
filled: true,
fillColor: HotelynAppColors.lightGrey,
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(30)),
borderSide: BorderSide.none,
),
hintText: 'Search hotel',
),
),
HotelynSearchInput(hintText: 'Search hotel'),
],
),
),
Expand Down
10 changes: 10 additions & 0 deletions lib/features/messages/messages_cubit.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hotelyn/features/messages/messages_state.dart';

class MessagesCubit extends Cubit<MessagesState> {
MessagesCubit() : super(MessagesEmpty()) {
_load();
}

void _load() {}
}
9 changes: 9 additions & 0 deletions lib/features/messages/messages_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
sealed class MessagesState {}

class MessagesLoading extends MessagesState {}

class MessagesEmpty extends MessagesState {}

class MessagesLoadSuccess extends MessagesState {}

class MessagesError extends MessagesState {}
98 changes: 96 additions & 2 deletions lib/features/messages/messages_tab.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,104 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hotelyn/components/app_bar.dart';
import 'package:hotelyn/components/text_style/hotelyn_text_style.dart';
import 'package:hotelyn/features/messages/messages_cubit.dart';
import 'package:hotelyn/features/messages/messages_state.dart';

class MesssagesTab extends StatelessWidget {
const MesssagesTab({super.key});
class MessagesTab extends StatelessWidget {
const MessagesTab({super.key});

@override
Widget build(BuildContext context) {
return BlocConsumer<MessagesCubit, MessagesState>(
listener: (context, state) {
// TODO: implement listener
},
builder: (context, state) {
return Scaffold(
appBar: HotelynHomeAppBar(
title: 'Messages',
iconData: Icons.notifications,
onIconPressed: () {},
),
body: Builder(
builder: (context) {
return switch (state) {
MessagesLoading() => const MessagesLoadingScreen(),
MessagesEmpty() => const MessagesEmptyScreen(),
MessagesError() => const MessagesErrorScreen(),
MessagesLoadSuccess() => const MessagesLoadSuccessScreen(),
};
},
),
floatingActionButton: state is MessagesEmpty
? FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.message_rounded),
)
: null,
);
},
);
}
}

class MessagesLoadSuccessScreen extends StatelessWidget {
const MessagesLoadSuccessScreen({super.key});

@override
Widget build(BuildContext context) {
return const Placeholder();
}
}

class MessagesErrorScreen extends StatelessWidget {
const MessagesErrorScreen({super.key});

@override
Widget build(BuildContext context) {
return const Placeholder();
}
}

class MessagesLoadingScreen extends StatelessWidget {
const MessagesLoadingScreen({super.key});

@override
Widget build(BuildContext context) {
return const Center(
child: CircularProgressIndicator(),
);
}
}

class MessagesEmptyScreen extends StatelessWidget {
const MessagesEmptyScreen({super.key});

@override
Widget build(BuildContext context) {
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/messages/empty.png',
width: 200,
height: 200,
),
const SizedBox(height: 30),
const Text(
'No Messages Here',
style: HotelynTextStyle.h1,
),
const SizedBox(height: 12),
const Text(
'Lets start messaging with others or with seller',
style: HotelynTextStyle.description,
),
],
),
);
}
}
23 changes: 6 additions & 17 deletions lib/features/profile/profile_tab.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hotelyn/components/app_bar.dart';
import 'package:hotelyn/components/avatar/hotelyn_avatar.dart';
import 'package:hotelyn/components/text_style/hotelyn_text_style.dart';
import 'package:hotelyn/features/profile/profile_cubit.dart';
Expand All @@ -16,7 +17,11 @@ class ProfileTab extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
appBar: HotelynHomeAppBar(
title: 'Profile',
iconData: Icons.settings,
onIconPressed: () {},
),
body: BlocBuilder<ProfileCubit, ProfileState>(
builder: (context, state) {
return switch (state) {
Expand Down Expand Up @@ -54,7 +59,6 @@ class ProfileDataScreen extends StatelessWidget {
child: SingleChildScrollView(
child: Column(
children: [
ProfileTabAppBar(),
SizedBox(height: 32),
ProfileUserInformationSection(),
SizedBox(height: 24),
Expand Down Expand Up @@ -85,18 +89,3 @@ class ProfileUserInformationSection extends StatelessWidget {
);
}
}

class ProfileTabAppBar extends StatelessWidget {
const ProfileTabAppBar({super.key});

@override
Widget build(BuildContext context) {
return const Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Profile', style: HotelynTextStyle.h1),
Icon(Icons.settings_outlined),
],
);
}
}
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ flutter:
- assets/images/
- assets/images/hotelyn/
- assets/images/onboarding/
- assets/images/messages/
- assets/icons/

fonts:
Expand Down
12 changes: 12 additions & 0 deletions test/features/messages/messages_cubit_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:hotelyn/features/messages/messages_cubit.dart';
import 'package:hotelyn/features/messages/messages_state.dart';

void main() {
group('MessagesCubit', () {
test('constructor', () {
final cubit = MessagesCubit();
expect(cubit.state, isA<MessagesEmpty>());
});
});
}
Loading