mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-08-26 06:39:41 +00:00
Compare commits
96 Commits
b1b72fa8aa
...
SP-1913-FE
Author | SHA1 | Date | |
---|---|---|---|
9a4fdb2f88 | |||
1558806cc3 | |||
a4391aa73e | |||
2d69e3c72f | |||
cd8ffc99ea | |||
83895d3dda | |||
f1cf8d88d3 | |||
0f9cbd22a2 | |||
9d0a1f4883 | |||
7d77809750 | |||
56a03443be | |||
5a35f8e62e | |||
6943ee07ac | |||
47340c3235 | |||
527c04de9a | |||
1448aa97ce | |||
16b79ae12f | |||
6dbb6b6a6e | |||
c4ed30f539 | |||
99924c1e62 | |||
04d1c37308 | |||
dfdf4fb27c | |||
3859dc67d8 | |||
ae3eb6fca8 | |||
f341dcd482 | |||
e98b091253 | |||
77d6d822cb | |||
f1aab13263 | |||
a56e422bf5 | |||
97530dd351 | |||
a57b6e0853 | |||
8f71fcb96a | |||
845397e819 | |||
2077ef053f | |||
d21850edc8 | |||
85f53ed1f2 | |||
5fde74fc7d | |||
994efc302b | |||
c403048da7 | |||
04b7a506be | |||
19ddf443a9 | |||
3779176978 | |||
7c5bca35fc | |||
aed3004a31 | |||
8ae4e561c2 | |||
4241d11cb6 | |||
ef8c9efff0 | |||
c59d2b7fd6 | |||
71f0da9299 | |||
e6d9000ee2 | |||
7dc103f904 | |||
e4c41bab90 | |||
7f3dfebf15 | |||
0de882d43b | |||
6a737e5d43 | |||
c323d88790 | |||
68153e41ed | |||
6a7174b929 | |||
59058cf2d2 | |||
b6d4084ca7 | |||
2b110b7c91 | |||
066fe4bc95 | |||
85d65b2d96 | |||
a64a9f1d12 | |||
94f9c1beea | |||
a7487f5434 | |||
c0b74162e9 | |||
dfd8c5fa31 | |||
60b8ee8b50 | |||
9d60f913eb | |||
40251b846b | |||
1323bceca1 | |||
0eb4652f26 | |||
460639b681 | |||
35c8a73156 | |||
ce65b068ff | |||
96f107f972 | |||
a3a7937021 | |||
9bf715501b | |||
c65f4a7fab | |||
7af8887d4f | |||
2f89c3486c | |||
5589e5b587 | |||
d3bd363b70 | |||
3a4fce966c | |||
6bdd28ec57 | |||
652163fdae | |||
b738596b50 | |||
0ad562b6ce | |||
995ce480cb | |||
076c80fe44 | |||
b41733ee40 | |||
fe090175e3 | |||
85544c69f8 | |||
9f71bbff63 | |||
deb227034a |
4
assets/icons/search_icon.svg
Normal file
4
assets/icons/search_icon.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M1.89852 11.08C-0.632759 8.54864 -0.632708 4.42983 1.89852 1.8985C4.42985 -0.632833 8.54861 -0.632833 11.0799 1.8985C13.2274 4.04599 13.5526 7.23986 12.0565 9.73392C12.0565 9.73392 11.949 9.91422 12.0942 10.0593C12.9222 10.8872 15.4065 13.3716 15.4065 13.3716C16.0658 14.0308 16.2227 14.9527 15.638 15.5374L15.5374 15.638C14.9527 16.2227 14.0308 16.0658 13.3716 15.4065C13.3716 15.4065 10.8926 12.9275 10.0662 12.1012C9.91414 11.9491 9.73389 12.0566 9.73389 12.0566C7.23988 13.5526 4.04601 13.2275 1.89852 11.08ZM9.88131 9.88133C11.7517 8.01094 11.7516 4.96763 9.88125 3.09724C8.01086 1.22689 4.96755 1.22684 3.09721 3.09724C1.22681 4.96758 1.22681 8.01094 3.09721 9.88133C4.9676 11.7516 8.01086 11.7516 9.88131 9.88133Z" fill="#999999" fill-opacity="0.7"/>
|
||||||
|
<path d="M9.46701 6.10386C9.55406 6.10386 9.64256 6.08674 9.72786 6.05072C10.0686 5.9065 10.228 5.51333 10.0838 5.17253C9.17738 3.03045 6.69729 2.0252 4.55526 2.93164C4.21451 3.07586 4.05509 3.46903 4.1993 3.80983C4.34357 4.15063 4.73664 4.30995 5.07755 4.16579C6.539 3.54737 8.23126 4.23326 8.84962 5.69471C8.95781 5.95031 9.20594 6.10386 9.46701 6.10386Z" fill="#999999" fill-opacity="0.7"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
9
assets/images/4_sceen_switch.svg
Normal file
9
assets/images/4_sceen_switch.svg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M38.0142 39.2553L35.3682 40H20.9308H19.9999H19.0691H1.24111C0.555643 40 0 39.4444 0 38.7589V1.24111C0 0.555643 0.555643 0 1.24111 0H19.0682H20.1226H20.9543H35.4255L38.2625 1.24111C38.9479 1.24111 39.5036 1.79675 39.5036 2.48221L39.2553 38.0142C39.2553 38.6997 38.6997 39.2553 38.0142 39.2553Z" fill="#E9E9E9"/>
|
||||||
|
<path d="M38.7585 0H35.0352C35.7206 0 36.2763 0.555643 36.2763 1.24111V38.7589C36.2763 39.4444 35.7206 40 35.0352 40H38.7585C39.4439 40 39.9996 39.4444 39.9996 38.7589V1.24111C39.9996 0.555643 39.4439 0 38.7585 0Z" fill="#D1D1D1"/>
|
||||||
|
<path opacity="0.6" d="M12.0283 31.8319V33.3212C12.0283 34.0067 11.6086 34.5623 11.0908 34.5623H6.96582C6.44804 34.5623 6.02832 34.0067 6.02832 33.3212V31.8319C6.02832 31.1465 6.44804 30.5908 6.96582 30.5908H11.0908C11.6086 30.5908 12.0283 31.1465 12.0283 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||||
|
<path opacity="0.6" d="M12.0283 7.24109V8.73042C12.0283 9.41588 11.6086 9.97153 11.0908 9.97153H6.96582C6.44804 9.97153 6.02832 9.41588 6.02832 8.73042V7.24109C6.02832 6.55563 6.44804 5.99998 6.96582 5.99998H11.0908C11.6086 5.99998 12.0283 6.55563 12.0283 7.24109Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||||
|
<path opacity="0.6" d="M26.0283 31.8319V33.3212C26.0283 34.0067 26.448 34.5623 26.9658 34.5623H31.0908C31.6086 34.5623 32.0283 34.0067 32.0283 33.3212V31.8319C32.0283 31.1465 31.6086 30.5908 31.0908 30.5908H26.9658C26.448 30.5908 26.0283 31.1465 26.0283 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||||
|
<path opacity="0.6" d="M26.0283 7.24109V8.73042C26.0283 9.41588 26.448 9.97153 26.9658 9.97153H31.0908C31.6086 9.97153 32.0283 9.41588 32.0283 8.73042V7.24109C32.0283 6.55563 31.6086 5.99998 31.0908 5.99998H26.9658C26.448 5.99998 26.0283 6.55563 26.0283 7.24109Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||||
|
<path d="M19.0693 0H20.931V40H19.0693V0Z" fill="#D1D1D1"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
12
assets/images/6_sceen_switch.svg
Normal file
12
assets/images/6_sceen_switch.svg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M38.0142 39.2553L35.3682 40H20.9308H19.9999H19.0691H1.24111C0.555643 40 0 39.4444 0 38.7589V1.24111C0 0.555651 0.555643 7.62939e-06 1.24111 7.62939e-06H19.0682H20.1226H20.9543H35.4255L38.2625 1.24111C38.9479 1.24111 39.5036 1.79676 39.5036 2.48222L39.2553 38.0142C39.2553 38.6997 38.6997 39.2553 38.0142 39.2553Z" fill="#E9E9E9"/>
|
||||||
|
<path d="M38.7585 0H35.0352C35.7206 0 36.2763 0.555643 36.2763 1.24111V38.7589C36.2763 39.4444 35.7206 40 35.0352 40H38.7585C39.4439 40 39.9996 39.4444 39.9996 38.7589V1.24111C39.9996 0.555643 39.4439 0 38.7585 0Z" fill="#D1D1D1"/>
|
||||||
|
<path opacity="0.6" d="M8.64062 31.8319V33.3212C8.64062 34.0067 8.22091 34.5623 7.70312 34.5623H3.57813C3.06034 34.5623 2.64062 34.0067 2.64062 33.3212V31.8319C2.64062 31.1464 3.06034 30.5908 3.57813 30.5908H7.70312C8.22091 30.5908 8.64062 31.1464 8.64062 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||||
|
<path opacity="0.6" d="M8.64062 7.24109V8.73042C8.64062 9.41588 8.22091 9.97152 7.70312 9.97152H3.57813C3.06034 9.97152 2.64062 9.41588 2.64062 8.73042V7.24109C2.64062 6.55563 3.06034 5.99998 3.57813 5.99998H7.70312C8.22091 5.99998 8.64062 6.55563 8.64062 7.24109Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||||
|
<path opacity="0.6" d="M27.6406 31.8319V33.3212C27.6406 34.0067 28.0603 34.5623 28.5781 34.5623H32.7031C33.2209 34.5623 33.6406 34.0067 33.6406 33.3212V31.8319C33.6406 31.1464 33.2209 30.5908 32.7031 30.5908H28.5781C28.0603 30.5908 27.6406 31.1464 27.6406 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||||
|
<path opacity="0.6" d="M27.6406 7.24109V8.73042C27.6406 9.41588 28.0603 9.97152 28.5781 9.97152H32.7031C33.2209 9.97152 33.6406 9.41588 33.6406 8.73042V7.24109C33.6406 6.55563 33.2209 5.99998 32.7031 5.99998H28.5781C28.0603 5.99998 27.6406 6.55563 27.6406 7.24109Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||||
|
<path opacity="0.6" d="M15.0625 31.8319V33.3212C15.0625 34.0067 15.4822 34.5623 16 34.5623H20.125C20.6428 34.5623 21.0625 34.0067 21.0625 33.3212V31.8319C21.0625 31.1464 20.6428 30.5908 20.125 30.5908H16C15.4822 30.5908 15.0625 31.1464 15.0625 31.8319Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||||
|
<path opacity="0.6" d="M15.0625 7.24109V8.73042C15.0625 9.41588 15.4822 9.97152 16 9.97152H20.125C20.6428 9.97152 21.0625 9.41588 21.0625 8.73042V7.24109C21.0625 6.55563 20.6428 5.99998 20.125 5.99998H16C15.4822 5.99998 15.0625 6.55563 15.0625 7.24109Z" fill="#023DFE" fill-opacity="0.5"/>
|
||||||
|
<path d="M23.125 0H24.9867V40H23.125V0Z" fill="#D1D1D1"/>
|
||||||
|
<path d="M11.1719 0H13.0335V40H11.1719V0Z" fill="#D1D1D1"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
@ -66,7 +66,7 @@ class _DialogDropdownState extends State<DialogDropdown> {
|
|||||||
child: Material(
|
child: Material(
|
||||||
elevation: 4.0,
|
elevation: 4.0,
|
||||||
child: Container(
|
child: Container(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
constraints: const BoxConstraints(
|
constraints: const BoxConstraints(
|
||||||
maxHeight: 200.0, // Set max height for dropdown
|
maxHeight: 200.0, // Set max height for dropdown
|
||||||
),
|
),
|
||||||
@ -87,12 +87,10 @@ class _DialogDropdownState extends State<DialogDropdown> {
|
|||||||
child: ListTile(
|
child: ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
item,
|
item,
|
||||||
style: Theme.of(context)
|
style:
|
||||||
.textTheme
|
Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
.bodyMedium
|
color: ColorsManager.textPrimaryColor,
|
||||||
?.copyWith(
|
),
|
||||||
color: ColorsManager.textPrimaryColor,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
widget.onSelected(item);
|
widget.onSelected(item);
|
||||||
|
@ -14,7 +14,7 @@ class EditChip extends StatelessWidget {
|
|||||||
this.label = 'Edit',
|
this.label = 'Edit',
|
||||||
required this.onTap,
|
required this.onTap,
|
||||||
this.labelColor = ColorsManager.spaceColor,
|
this.labelColor = ColorsManager.spaceColor,
|
||||||
this.backgroundColor = ColorsManager.whiteColors,
|
this.backgroundColor = ColorsManager.white,
|
||||||
this.borderColor = ColorsManager.spaceColor,
|
this.borderColor = ColorsManager.spaceColor,
|
||||||
this.borderRadius = 16.0,
|
this.borderRadius = 16.0,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
@ -24,10 +24,9 @@ class EditChip extends StatelessWidget {
|
|||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
child: Chip(
|
child: Chip(
|
||||||
label: Text(
|
label: Text(label,
|
||||||
label,
|
style:
|
||||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: labelColor)
|
Theme.of(context).textTheme.bodySmall!.copyWith(color: labelColor)),
|
||||||
),
|
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(borderRadius),
|
borderRadius: BorderRadius.circular(borderRadius),
|
||||||
|
@ -17,8 +17,7 @@ class TagDialogTextfieldDropdown extends StatefulWidget {
|
|||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_DialogTextfieldDropdownState createState() =>
|
_DialogTextfieldDropdownState createState() => _DialogTextfieldDropdownState();
|
||||||
_DialogTextfieldDropdownState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DialogTextfieldDropdownState extends State<TagDialogTextfieldDropdown> {
|
class _DialogTextfieldDropdownState extends State<TagDialogTextfieldDropdown> {
|
||||||
@ -97,7 +96,7 @@ class _DialogTextfieldDropdownState extends State<TagDialogTextfieldDropdown> {
|
|||||||
child: Material(
|
child: Material(
|
||||||
elevation: 4.0,
|
elevation: 4.0,
|
||||||
child: Container(
|
child: Container(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
constraints: const BoxConstraints(maxHeight: 200.0),
|
constraints: const BoxConstraints(maxHeight: 200.0),
|
||||||
child: StatefulBuilder(
|
child: StatefulBuilder(
|
||||||
builder: (context, setStateDropdown) {
|
builder: (context, setStateDropdown) {
|
||||||
@ -122,8 +121,7 @@ class _DialogTextfieldDropdownState extends State<TagDialogTextfieldDropdown> {
|
|||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium
|
.bodyMedium
|
||||||
?.copyWith(
|
?.copyWith(
|
||||||
color: ColorsManager
|
color: ColorsManager.textPrimaryColor)),
|
||||||
.textPrimaryColor)),
|
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_controller.text = tag.tag ?? '';
|
_controller.text = tag.tag ?? '';
|
||||||
widget.onSelected(tag);
|
widget.onSelected(tag);
|
||||||
|
@ -5,19 +5,20 @@ class CustomExpansionTile extends StatefulWidget {
|
|||||||
final String title;
|
final String title;
|
||||||
final List<Widget>? children;
|
final List<Widget>? children;
|
||||||
final bool initiallyExpanded;
|
final bool initiallyExpanded;
|
||||||
final bool isSelected; // Add this to track selection
|
final bool isSelected;
|
||||||
final bool? isExpanded; // External control over expansion
|
final bool? isExpanded;
|
||||||
final ValueChanged<bool>? onExpansionChanged; // Notify when expansion changes
|
final ValueChanged<bool>? onExpansionChanged;
|
||||||
final VoidCallback? onItemSelected; // Callback for selecting the item
|
final VoidCallback? onItemSelected;
|
||||||
|
|
||||||
CustomExpansionTile({
|
const CustomExpansionTile({
|
||||||
|
super.key,
|
||||||
required this.title,
|
required this.title,
|
||||||
this.children,
|
this.children,
|
||||||
this.initiallyExpanded = false,
|
this.initiallyExpanded = false,
|
||||||
this.isExpanded, // Allow external control over expansion
|
this.isExpanded,
|
||||||
this.onExpansionChanged, // Notify when expansion changes
|
this.onExpansionChanged,
|
||||||
this.onItemSelected, // Trigger item selection when name is tapped
|
this.onItemSelected,
|
||||||
required this.isSelected, // Add this to initialize selection state
|
required this.isSelected,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -25,7 +26,7 @@ class CustomExpansionTile extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CustomExpansionTileState extends State<CustomExpansionTile> {
|
class CustomExpansionTileState extends State<CustomExpansionTile> {
|
||||||
bool _isExpanded = false; // Local expansion state
|
bool _isExpanded = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -36,7 +37,6 @@ class CustomExpansionTileState extends State<CustomExpansionTile> {
|
|||||||
@override
|
@override
|
||||||
void didUpdateWidget(CustomExpansionTile oldWidget) {
|
void didUpdateWidget(CustomExpansionTile oldWidget) {
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
// Sync local state with external control of expansion state
|
|
||||||
if (widget.isExpanded != null && widget.isExpanded != _isExpanded) {
|
if (widget.isExpanded != null && widget.isExpanded != _isExpanded) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isExpanded = widget.isExpanded!;
|
_isExpanded = widget.isExpanded!;
|
||||||
@ -44,7 +44,6 @@ class CustomExpansionTileState extends State<CustomExpansionTile> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility function to capitalize the first letter of the title
|
|
||||||
String _capitalizeFirstLetter(String text) {
|
String _capitalizeFirstLetter(String text) {
|
||||||
if (text.isEmpty) return text;
|
if (text.isEmpty) return text;
|
||||||
return text[0].toUpperCase() + text.substring(1);
|
return text[0].toUpperCase() + text.substring(1);
|
||||||
@ -56,7 +55,6 @@ class CustomExpansionTileState extends State<CustomExpansionTile> {
|
|||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
// Expand/collapse icon, now wrapped in a GestureDetector for specific onTap
|
|
||||||
if (widget.children != null && widget.children!.isNotEmpty)
|
if (widget.children != null && widget.children!.isNotEmpty)
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@ -70,38 +68,33 @@ class CustomExpansionTileState extends State<CustomExpansionTile> {
|
|||||||
? Icons.keyboard_arrow_down
|
? Icons.keyboard_arrow_down
|
||||||
: Icons.keyboard_arrow_right,
|
: Icons.keyboard_arrow_right,
|
||||||
color: ColorsManager.lightGrayColor,
|
color: ColorsManager.lightGrayColor,
|
||||||
size: 16.0, // Adjusted size for better alignment
|
size: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// The title text, wrapped in GestureDetector to handle selection
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (widget.onItemSelected != null) {
|
if (widget.onItemSelected != null) {
|
||||||
widget.onItemSelected!();
|
widget.onItemSelected!.call();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
_capitalizeFirstLetter(widget.title),
|
_capitalizeFirstLetter(widget.title),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: widget.isSelected
|
color: widget.isSelected
|
||||||
? ColorsManager
|
? ColorsManager.blackColor
|
||||||
.blackColor // Change color to black when selected
|
: ColorsManager.lightGrayColor,
|
||||||
: ColorsManager
|
fontWeight:
|
||||||
.lightGrayColor, // Gray when not selected
|
widget.isSelected ? FontWeight.w600 : FontWeight.w400,
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
// The expanded section (children) that shows when the tile is expanded
|
if (_isExpanded && widget.children != null && widget.children!.isNotEmpty)
|
||||||
if (_isExpanded &&
|
|
||||||
widget.children != null &&
|
|
||||||
widget.children!.isNotEmpty)
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 24.0), // Indented children
|
padding: const EdgeInsets.only(left: 24),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: widget.children!,
|
children: widget.children!,
|
||||||
|
@ -7,7 +7,7 @@ class CustomSearchBar extends StatefulWidget {
|
|||||||
final TextEditingController? controller;
|
final TextEditingController? controller;
|
||||||
final String hintText;
|
final String hintText;
|
||||||
final String? searchQuery;
|
final String? searchQuery;
|
||||||
final Function(String)? onSearchChanged; // Callback for search input changes
|
final void Function(String)? onSearchChanged;
|
||||||
|
|
||||||
const CustomSearchBar({
|
const CustomSearchBar({
|
||||||
super.key,
|
super.key,
|
||||||
@ -34,10 +34,10 @@ class _CustomSearchBarState extends State<CustomSearchBar> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.black.withOpacity(0.2),
|
color: ColorsManager.shadowBlackColor.withValues(alpha: 0.1),
|
||||||
spreadRadius: 0,
|
spreadRadius: 0,
|
||||||
blurRadius: 8,
|
blurRadius: 8,
|
||||||
offset: const Offset(0, 4),
|
offset: const Offset(0, 4),
|
||||||
@ -57,7 +57,7 @@ class _CustomSearchBarState extends State<CustomSearchBar> {
|
|||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
),
|
),
|
||||||
onChanged: widget.onSearchChanged, // Call the callback on text change
|
onChanged: widget.onSearchChanged,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
filled: true,
|
filled: true,
|
||||||
fillColor: ColorsManager.textFieldGreyColor,
|
fillColor: ColorsManager.textFieldGreyColor,
|
||||||
|
@ -1,22 +1,9 @@
|
|||||||
import 'package:firebase_core/firebase_core.dart';
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:syncrow_web/firebase_options.dart';
|
import 'package:syncrow_web/firebase_options.dart';
|
||||||
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
|
|
||||||
import 'package:syncrow_web/services/locator.dart';
|
import 'package:syncrow_web/services/locator.dart';
|
||||||
import 'package:syncrow_web/utils/app_routes.dart';
|
import 'package:syncrow_web/syncrow_app.dart';
|
||||||
import 'package:syncrow_web/utils/constants/routes_const.dart';
|
|
||||||
import 'package:syncrow_web/utils/navigation_service.dart';
|
|
||||||
import 'package:syncrow_web/utils/theme/theme.dart';
|
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
try {
|
try {
|
||||||
@ -33,59 +20,5 @@ Future<void> main() async {
|
|||||||
);
|
);
|
||||||
initialSetup();
|
initialSetup();
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
runApp(MyApp());
|
runApp(const SyncrowApp());
|
||||||
}
|
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
|
||||||
MyApp({super.key});
|
|
||||||
|
|
||||||
final GoRouter _router = GoRouter(
|
|
||||||
initialLocation: RoutesConst.auth,
|
|
||||||
routes: AppRoutes.getRoutes(),
|
|
||||||
redirect: (context, state) async {
|
|
||||||
final checkToken = await AuthBloc.getTokenAndValidate();
|
|
||||||
final loggedIn = checkToken == 'Success';
|
|
||||||
final goingToLogin = state.uri.toString() == RoutesConst.auth;
|
|
||||||
|
|
||||||
if (!loggedIn && !goingToLogin) return RoutesConst.auth;
|
|
||||||
if (loggedIn && goingToLogin) return RoutesConst.home;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return MultiBlocProvider(
|
|
||||||
providers: [
|
|
||||||
BlocProvider<CreateRoutineBloc>(
|
|
||||||
create: (context) => CreateRoutineBloc(),
|
|
||||||
),
|
|
||||||
BlocProvider(create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
|
||||||
BlocProvider<VisitorPasswordBloc>(
|
|
||||||
create: (context) => VisitorPasswordBloc(),
|
|
||||||
),
|
|
||||||
BlocProvider<RoutineBloc>(
|
|
||||||
create: (context) => RoutineBloc(),
|
|
||||||
),
|
|
||||||
BlocProvider<SpaceTreeBloc>(
|
|
||||||
create: (context) => SpaceTreeBloc(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
child: MaterialApp.router(
|
|
||||||
debugShowCheckedModeBanner: false,
|
|
||||||
scrollBehavior: const MaterialScrollBehavior().copyWith(
|
|
||||||
dragDevices: {
|
|
||||||
PointerDeviceKind.mouse,
|
|
||||||
PointerDeviceKind.touch,
|
|
||||||
PointerDeviceKind.stylus,
|
|
||||||
PointerDeviceKind.unknown,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
key: NavigationService.navigatorKey,
|
|
||||||
// scaffoldMessengerKey: NavigationService.snackbarKey,
|
|
||||||
theme: myTheme,
|
|
||||||
routerConfig: _router,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,9 @@
|
|||||||
import 'package:firebase_core/firebase_core.dart';
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:syncrow_web/firebase_options.dart';
|
import 'package:syncrow_web/firebase_options.dart';
|
||||||
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
|
|
||||||
import 'package:syncrow_web/services/locator.dart';
|
import 'package:syncrow_web/services/locator.dart';
|
||||||
import 'package:syncrow_web/utils/app_routes.dart';
|
import 'package:syncrow_web/syncrow_app.dart';
|
||||||
import 'package:syncrow_web/utils/constants/routes_const.dart';
|
|
||||||
import 'package:syncrow_web/utils/navigation_service.dart';
|
|
||||||
import 'package:syncrow_web/utils/theme/theme.dart';
|
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
try {
|
try {
|
||||||
@ -33,59 +20,5 @@ Future<void> main() async {
|
|||||||
);
|
);
|
||||||
initialSetup();
|
initialSetup();
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
runApp(MyApp());
|
runApp(const SyncrowApp());
|
||||||
}
|
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
|
||||||
MyApp({super.key});
|
|
||||||
|
|
||||||
final GoRouter _router = GoRouter(
|
|
||||||
initialLocation: RoutesConst.auth,
|
|
||||||
routes: AppRoutes.getRoutes(),
|
|
||||||
redirect: (context, state) async {
|
|
||||||
final checkToken = await AuthBloc.getTokenAndValidate();
|
|
||||||
final loggedIn = checkToken == 'Success';
|
|
||||||
final goingToLogin = state.uri.toString() == RoutesConst.auth;
|
|
||||||
|
|
||||||
if (!loggedIn && !goingToLogin) return RoutesConst.auth;
|
|
||||||
if (loggedIn && goingToLogin) return RoutesConst.home;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return MultiBlocProvider(
|
|
||||||
providers: [
|
|
||||||
BlocProvider<CreateRoutineBloc>(
|
|
||||||
create: (context) => CreateRoutineBloc(),
|
|
||||||
),
|
|
||||||
BlocProvider(create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
|
||||||
BlocProvider<VisitorPasswordBloc>(
|
|
||||||
create: (context) => VisitorPasswordBloc(),
|
|
||||||
),
|
|
||||||
BlocProvider<RoutineBloc>(
|
|
||||||
create: (context) => RoutineBloc(),
|
|
||||||
),
|
|
||||||
BlocProvider<SpaceTreeBloc>(
|
|
||||||
create: (context) => SpaceTreeBloc(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
child: MaterialApp.router(
|
|
||||||
debugShowCheckedModeBanner: false,
|
|
||||||
scrollBehavior: const MaterialScrollBehavior().copyWith(
|
|
||||||
dragDevices: {
|
|
||||||
PointerDeviceKind.mouse,
|
|
||||||
PointerDeviceKind.touch,
|
|
||||||
PointerDeviceKind.stylus,
|
|
||||||
PointerDeviceKind.unknown,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
key: NavigationService.navigatorKey,
|
|
||||||
// scaffoldMessengerKey: NavigationService.snackbarKey,
|
|
||||||
theme: myTheme,
|
|
||||||
routerConfig: _router,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,16 @@
|
|||||||
import 'package:firebase_core/firebase_core.dart';
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:syncrow_web/firebase_options.dart';
|
import 'package:syncrow_web/firebase_options.dart';
|
||||||
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
|
|
||||||
import 'package:syncrow_web/services/locator.dart';
|
import 'package:syncrow_web/services/locator.dart';
|
||||||
import 'package:syncrow_web/utils/app_routes.dart';
|
import 'package:syncrow_web/syncrow_app.dart';
|
||||||
import 'package:syncrow_web/utils/constants/routes_const.dart';
|
|
||||||
import 'package:syncrow_web/utils/navigation_service.dart';
|
|
||||||
import 'package:syncrow_web/utils/theme/theme.dart';
|
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
try {
|
try {
|
||||||
const environment = String.fromEnvironment('FLAVOR', defaultValue: 'staging');
|
const environment = String.fromEnvironment(
|
||||||
|
'FLAVOR',
|
||||||
|
defaultValue: 'staging',
|
||||||
|
);
|
||||||
await dotenv.load(fileName: '.env.$environment');
|
await dotenv.load(fileName: '.env.$environment');
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
await Firebase.initializeApp(
|
await Firebase.initializeApp(
|
||||||
@ -30,59 +20,5 @@ Future<void> main() async {
|
|||||||
);
|
);
|
||||||
initialSetup();
|
initialSetup();
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
runApp(MyApp());
|
runApp(const SyncrowApp());
|
||||||
}
|
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
|
||||||
MyApp({super.key});
|
|
||||||
|
|
||||||
final GoRouter _router = GoRouter(
|
|
||||||
initialLocation: RoutesConst.auth,
|
|
||||||
routes: AppRoutes.getRoutes(),
|
|
||||||
redirect: (context, state) async {
|
|
||||||
final checkToken = await AuthBloc.getTokenAndValidate();
|
|
||||||
final loggedIn = checkToken == 'Success';
|
|
||||||
final goingToLogin = state.uri.toString() == RoutesConst.auth;
|
|
||||||
|
|
||||||
if (!loggedIn && !goingToLogin) return RoutesConst.auth;
|
|
||||||
if (loggedIn && goingToLogin) return RoutesConst.home;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return MultiBlocProvider(
|
|
||||||
providers: [
|
|
||||||
BlocProvider<CreateRoutineBloc>(
|
|
||||||
create: (context) => CreateRoutineBloc(),
|
|
||||||
),
|
|
||||||
BlocProvider(create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
|
||||||
BlocProvider<VisitorPasswordBloc>(
|
|
||||||
create: (context) => VisitorPasswordBloc(),
|
|
||||||
),
|
|
||||||
BlocProvider<RoutineBloc>(
|
|
||||||
create: (context) => RoutineBloc(),
|
|
||||||
),
|
|
||||||
BlocProvider<SpaceTreeBloc>(
|
|
||||||
create: (context) => SpaceTreeBloc(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
child: MaterialApp.router(
|
|
||||||
debugShowCheckedModeBanner: false,
|
|
||||||
scrollBehavior: const MaterialScrollBehavior().copyWith(
|
|
||||||
dragDevices: {
|
|
||||||
PointerDeviceKind.mouse,
|
|
||||||
PointerDeviceKind.touch,
|
|
||||||
PointerDeviceKind.stylus,
|
|
||||||
PointerDeviceKind.unknown,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
key: NavigationService.navigatorKey,
|
|
||||||
// scaffoldMessengerKey: NavigationService.snackbarKey,
|
|
||||||
theme: myTheme,
|
|
||||||
routerConfig: _router,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ part 'events_event.dart';
|
|||||||
part 'events_state.dart';
|
part 'events_state.dart';
|
||||||
|
|
||||||
class CalendarEventsBloc extends Bloc<CalendarEventsEvent, CalendarEventState> {
|
class CalendarEventsBloc extends Bloc<CalendarEventsEvent, CalendarEventState> {
|
||||||
final EventController eventController = EventController();
|
EventController eventController = EventController();
|
||||||
final CalendarSystemService calendarService;
|
final CalendarSystemService calendarService;
|
||||||
|
|
||||||
CalendarEventsBloc({
|
CalendarEventsBloc({
|
||||||
@ -20,7 +20,9 @@ class CalendarEventsBloc extends Bloc<CalendarEventsEvent, CalendarEventState> {
|
|||||||
on<AddEvent>(_onAddEvent);
|
on<AddEvent>(_onAddEvent);
|
||||||
on<DisposeResources>(_onDisposeResources);
|
on<DisposeResources>(_onDisposeResources);
|
||||||
on<GoToWeek>(_onGoToWeek);
|
on<GoToWeek>(_onGoToWeek);
|
||||||
|
on<ResetEvents>(_onResetEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onLoadEvents(
|
Future<void> _onLoadEvents(
|
||||||
LoadEvents event,
|
LoadEvents event,
|
||||||
Emitter<CalendarEventState> emit,
|
Emitter<CalendarEventState> emit,
|
||||||
@ -126,4 +128,18 @@ class CalendarEventsBloc extends Bloc<CalendarEventsEvent, CalendarEventState> {
|
|||||||
eventController.dispose();
|
eventController.dispose();
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onResetEvents(
|
||||||
|
ResetEvents event,
|
||||||
|
Emitter<CalendarEventState> emit,
|
||||||
|
) {
|
||||||
|
if (calendarService is MemoryCalendarServiceWithRemoteFallback) {
|
||||||
|
(calendarService as MemoryCalendarServiceWithRemoteFallback)
|
||||||
|
.memoryService
|
||||||
|
.clear();
|
||||||
|
}
|
||||||
|
eventController.dispose();
|
||||||
|
eventController = EventController();
|
||||||
|
emit(EventsInitial());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,3 +29,10 @@ class CheckWeekHasEvents extends CalendarEventsEvent {
|
|||||||
final DateTime weekStart;
|
final DateTime weekStart;
|
||||||
const CheckWeekHasEvents(this.weekStart);
|
const CheckWeekHasEvents(this.weekStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ResetEvents extends CalendarEventsEvent {
|
||||||
|
const ResetEvents();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [];
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
|
import 'package:calendar_view/calendar_view.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:calendar_view/calendar_view.dart';
|
import 'package:syncrow_web/pages/access_management/booking_system/data/services/memory_bookable_space_service.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/booking_system/data/services/remote_calendar_service.dart';
|
import 'package:syncrow_web/pages/access_management/booking_system/data/services/remote_calendar_service.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/booking_system/domain/LoadEventsParam.dart';
|
import 'package:syncrow_web/pages/access_management/booking_system/domain/LoadEventsParam.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/booking_system/presentation/bloc/calendar/events_bloc.dart';
|
import 'package:syncrow_web/pages/access_management/booking_system/presentation/bloc/calendar/events_bloc.dart';
|
||||||
@ -8,7 +9,6 @@ import 'package:syncrow_web/pages/access_management/booking_system/presentation/
|
|||||||
import 'package:syncrow_web/pages/access_management/booking_system/presentation/bloc/date_selection/date_selection_event.dart';
|
import 'package:syncrow_web/pages/access_management/booking_system/presentation/bloc/date_selection/date_selection_event.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/booking_system/presentation/bloc/date_selection/date_selection_state.dart';
|
import 'package:syncrow_web/pages/access_management/booking_system/presentation/bloc/date_selection/date_selection_state.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/booking_system/presentation/bloc/selected_bookable_space_bloc/selected_bookable_space_bloc.dart';
|
import 'package:syncrow_web/pages/access_management/booking_system/presentation/bloc/selected_bookable_space_bloc/selected_bookable_space_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/booking_system/data/services/memory_bookable_space_service.dart';
|
|
||||||
import 'package:syncrow_web/pages/access_management/booking_system/presentation/view/widgets/booking_sidebar.dart';
|
import 'package:syncrow_web/pages/access_management/booking_system/presentation/view/widgets/booking_sidebar.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/booking_system/presentation/view/widgets/custom_calendar_page.dart';
|
import 'package:syncrow_web/pages/access_management/booking_system/presentation/view/widgets/custom_calendar_page.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/booking_system/presentation/view/widgets/icon_text_button.dart';
|
import 'package:syncrow_web/pages/access_management/booking_system/presentation/view/widgets/icon_text_button.dart';
|
||||||
@ -19,14 +19,44 @@ import 'package:syncrow_web/utils/color_manager.dart';
|
|||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
|
||||||
class BookingPage extends StatefulWidget {
|
class BookingPage extends StatefulWidget {
|
||||||
const BookingPage({super.key});
|
final PageController? pageController;
|
||||||
|
const BookingPage({super.key, this.pageController});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<BookingPage> createState() => _BookingPageState();
|
State<BookingPage> createState() => _BookingPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BookingPageState extends State<BookingPage> {
|
class _BookingPageState extends State<BookingPage> {
|
||||||
late final EventController _eventController;
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MultiBlocProvider(
|
||||||
|
providers: [
|
||||||
|
BlocProvider(create: (_) => SelectedBookableSpaceBloc()),
|
||||||
|
BlocProvider(create: (_) => DateSelectionBloc()),
|
||||||
|
BlocProvider(
|
||||||
|
create: (_) => CalendarEventsBloc(
|
||||||
|
calendarService: MemoryCalendarServiceWithRemoteFallback(
|
||||||
|
remoteService: RemoteCalendarService(HTTPService()),
|
||||||
|
memoryService: MemoryCalendarService(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
child: _BookingPageContent(widget.pageController),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BookingPageContent extends StatefulWidget {
|
||||||
|
final PageController? pageController;
|
||||||
|
const _BookingPageContent(this.pageController);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_BookingPageContent> createState() => _BookingPageContentState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BookingPageContentState extends State<_BookingPageContent> {
|
||||||
|
late EventController _eventController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -40,7 +70,7 @@ class _BookingPageState extends State<BookingPage> {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _dispatchLoadEvents(BuildContext context) {
|
void _loadEvents(BuildContext context) {
|
||||||
final selectedRoom =
|
final selectedRoom =
|
||||||
context.read<SelectedBookableSpaceBloc>().state.selectedBookableSpace;
|
context.read<SelectedBookableSpaceBloc>().state.selectedBookableSpace;
|
||||||
final dateState = context.read<DateSelectionBloc>().state;
|
final dateState = context.read<DateSelectionBloc>().state;
|
||||||
@ -60,186 +90,164 @@ class _BookingPageState extends State<BookingPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MultiBlocProvider(
|
return BlocListener<SelectedBookableSpaceBloc, SelectedBookableSpaceState>(
|
||||||
providers: [
|
listener: (context, state) {
|
||||||
BlocProvider(create: (_) => SelectedBookableSpaceBloc()),
|
if (state.selectedBookableSpace != null) {
|
||||||
BlocProvider(create: (_) => DateSelectionBloc()),
|
context.read<CalendarEventsBloc>().add(const ResetEvents());
|
||||||
BlocProvider(
|
_loadEvents(context);
|
||||||
create: (_) => CalendarEventsBloc(
|
}
|
||||||
calendarService: MemoryCalendarServiceWithRemoteFallback(
|
},
|
||||||
remoteService: RemoteCalendarService(
|
child: BlocListener<DateSelectionBloc, DateSelectionState>(
|
||||||
HTTPService(),
|
listener: (context, state) {
|
||||||
),
|
_loadEvents(context);
|
||||||
memoryService: MemoryCalendarService(),
|
},
|
||||||
),
|
child: BlocListener<CalendarEventsBloc, CalendarEventState>(
|
||||||
)),
|
|
||||||
],
|
|
||||||
child: Builder(
|
|
||||||
builder: (context) =>
|
|
||||||
BlocListener<CalendarEventsBloc, CalendarEventState>(
|
|
||||||
listenWhen: (prev, curr) => curr is EventsLoaded,
|
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state is EventsLoaded) {
|
if (state is EventsLoaded) {
|
||||||
_eventController.removeWhere((_) => true);
|
_eventController.removeWhere((_) => true);
|
||||||
_eventController.addAll(state.events);
|
_eventController.addAll(state.events);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: BlocListener<SelectedBookableSpaceBloc,
|
child: Row(
|
||||||
SelectedBookableSpaceState>(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
listener: (context, state) => _dispatchLoadEvents(context),
|
children: [
|
||||||
child: BlocListener<DateSelectionBloc, DateSelectionState>(
|
Expanded(
|
||||||
listener: (context, state) => _dispatchLoadEvents(context),
|
child: Container(
|
||||||
child: Row(
|
decoration: BoxDecoration(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
color: ColorsManager.white,
|
||||||
children: [
|
boxShadow: [
|
||||||
Expanded(
|
BoxShadow(
|
||||||
child: Container(
|
color: ColorsManager.blackColor.withOpacity(0.1),
|
||||||
decoration: BoxDecoration(
|
offset: const Offset(3, 0),
|
||||||
color: ColorsManager.whiteColors,
|
blurRadius: 6,
|
||||||
boxShadow: [
|
spreadRadius: 0,
|
||||||
BoxShadow(
|
|
||||||
color: ColorsManager.blackColor.withOpacity(0.1),
|
|
||||||
offset: const Offset(3, 0),
|
|
||||||
blurRadius: 6,
|
|
||||||
spreadRadius: 0,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
child: Column(
|
],
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
flex: 2,
|
|
||||||
child: BlocBuilder<SelectedBookableSpaceBloc,
|
|
||||||
SelectedBookableSpaceState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
return BookingSidebar(
|
|
||||||
onRoomSelected: (selectedRoom) {
|
|
||||||
context
|
|
||||||
.read<SelectedBookableSpaceBloc>()
|
|
||||||
.add(SelectBookableSpace(selectedRoom));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: BlocBuilder<DateSelectionBloc,
|
|
||||||
DateSelectionState>(
|
|
||||||
builder: (context, dateState) {
|
|
||||||
return CustomCalendarPage(
|
|
||||||
selectedDate: dateState.selectedDate,
|
|
||||||
onDateChanged: (day, month, year) {
|
|
||||||
final newDate = DateTime(year, month, day);
|
|
||||||
context
|
|
||||||
.read<DateSelectionBloc>()
|
|
||||||
.add(SelectDate(newDate));
|
|
||||||
context.read<DateSelectionBloc>().add(
|
|
||||||
SelectDateFromSidebarCalendar(newDate));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Expanded(
|
child: Column(
|
||||||
flex: 5,
|
children: [
|
||||||
child: Padding(
|
Expanded(
|
||||||
padding: const EdgeInsets.all(20.0),
|
flex: 2,
|
||||||
child: Column(
|
child: BlocBuilder<SelectedBookableSpaceBloc,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
SelectedBookableSpaceState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
return BookingSidebar(
|
||||||
|
onRoomSelected: (selectedRoom) {
|
||||||
|
context
|
||||||
|
.read<SelectedBookableSpaceBloc>()
|
||||||
|
.add(SelectBookableSpace(selectedRoom));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: BlocBuilder<DateSelectionBloc, DateSelectionState>(
|
||||||
|
builder: (context, dateState) {
|
||||||
|
return CustomCalendarPage(
|
||||||
|
selectedDate: dateState.selectedDate,
|
||||||
|
onDateChanged: (day, month, year) {
|
||||||
|
final newDate = DateTime(year, month, day);
|
||||||
|
context
|
||||||
|
.read<DateSelectionBloc>()
|
||||||
|
.add(SelectDate(newDate));
|
||||||
|
context
|
||||||
|
.read<DateSelectionBloc>()
|
||||||
|
.add(SelectDateFromSidebarCalendar(newDate));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 5,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(20.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
children: [
|
||||||
Row(
|
SvgTextButton(
|
||||||
children: [
|
svgAsset: Assets.homeIcon,
|
||||||
SvgTextButton(
|
label: 'Manage Bookable Spaces',
|
||||||
svgAsset: Assets.homeIcon,
|
onPressed: () {
|
||||||
label: 'Manage Bookable Spaces',
|
widget.pageController!.jumpToPage(2);
|
||||||
onPressed: () {},
|
|
||||||
),
|
|
||||||
const SizedBox(width: 20),
|
|
||||||
SvgTextButton(
|
|
||||||
svgAsset: Assets.groupIcon,
|
|
||||||
label: 'Manage Users',
|
|
||||||
onPressed: () {},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
BlocBuilder<DateSelectionBloc,
|
|
||||||
DateSelectionState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
final weekStart = state.weekStart;
|
|
||||||
final weekEnd =
|
|
||||||
weekStart.add(const Duration(days: 6));
|
|
||||||
return WeekNavigation(
|
|
||||||
weekStart: weekStart,
|
|
||||||
weekEnd: weekEnd,
|
|
||||||
onPreviousWeek: () {
|
|
||||||
context
|
|
||||||
.read<DateSelectionBloc>()
|
|
||||||
.add(PreviousWeek());
|
|
||||||
},
|
|
||||||
onNextWeek: () {
|
|
||||||
context
|
|
||||||
.read<DateSelectionBloc>()
|
|
||||||
.add(NextWeek());
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
const SizedBox(width: 20),
|
||||||
|
SvgTextButton(
|
||||||
|
svgAsset: Assets.groupIcon,
|
||||||
|
label: 'Manage Users',
|
||||||
|
onPressed: () {},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Expanded(
|
BlocBuilder<DateSelectionBloc, DateSelectionState>(
|
||||||
flex: 5,
|
builder: (context, state) {
|
||||||
child: BlocBuilder<SelectedBookableSpaceBloc,
|
final weekStart = state.weekStart;
|
||||||
SelectedBookableSpaceState>(
|
final weekEnd = weekStart.add(const Duration(days: 6));
|
||||||
builder: (context, roomState) {
|
return WeekNavigation(
|
||||||
final selectedRoom =
|
weekStart: weekStart,
|
||||||
roomState.selectedBookableSpace;
|
weekEnd: weekEnd,
|
||||||
return BlocBuilder<DateSelectionBloc,
|
onPreviousWeek: () {
|
||||||
DateSelectionState>(
|
context
|
||||||
builder: (context, dateState) {
|
.read<DateSelectionBloc>()
|
||||||
return BlocListener<CalendarEventsBloc,
|
.add(PreviousWeek());
|
||||||
CalendarEventState>(
|
},
|
||||||
listenWhen: (prev, curr) =>
|
onNextWeek: () {
|
||||||
curr is EventsLoaded,
|
context.read<DateSelectionBloc>().add(NextWeek());
|
||||||
listener: (context, state) {
|
},
|
||||||
if (state is EventsLoaded) {
|
);
|
||||||
_eventController
|
},
|
||||||
.removeWhere((_) => true);
|
),
|
||||||
_eventController.addAll(state.events);
|
],
|
||||||
}
|
),
|
||||||
},
|
const SizedBox(height: 20),
|
||||||
child: WeeklyCalendarPage(
|
Expanded(
|
||||||
startTime: selectedRoom
|
flex: 5,
|
||||||
?.bookableConfig.startTime,
|
child: BlocBuilder<SelectedBookableSpaceBloc,
|
||||||
endTime: selectedRoom
|
SelectedBookableSpaceState>(
|
||||||
?.bookableConfig.endTime,
|
builder: (context, roomState) {
|
||||||
weekStart: dateState.weekStart,
|
final selectedRoom = roomState.selectedBookableSpace;
|
||||||
selectedDate: dateState.selectedDate,
|
return BlocBuilder<DateSelectionBloc,
|
||||||
eventController: _eventController,
|
DateSelectionState>(
|
||||||
selectedDateFromSideBarCalender: context
|
builder: (context, dateState) {
|
||||||
.watch<DateSelectionBloc>()
|
return BlocBuilder<CalendarEventsBloc,
|
||||||
.state
|
CalendarEventState>(
|
||||||
.selectedDateFromSideBarCalender,
|
builder: (context, eventState) {
|
||||||
),
|
return WeeklyCalendarPage(
|
||||||
|
key: ValueKey(selectedRoom?.uuid ?? 'no-room'),
|
||||||
|
startTime:
|
||||||
|
selectedRoom?.bookableConfig.startTime,
|
||||||
|
endTime: selectedRoom?.bookableConfig.endTime,
|
||||||
|
weekStart: dateState.weekStart,
|
||||||
|
selectedDate: dateState.selectedDate,
|
||||||
|
eventController: _eventController,
|
||||||
|
selectedDateFromSideBarCalender: context
|
||||||
|
.watch<DateSelectionBloc>()
|
||||||
|
.state
|
||||||
|
.selectedDateFromSideBarCalender,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
);
|
||||||
),
|
},
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -76,21 +76,29 @@ class __SidebarContentState extends State<_SidebarContent> {
|
|||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
const _SidebarHeader(title: 'Spaces'),
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: ColorsManager.white,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: ColorsManager.blackColor.withOpacity(0.1),
|
||||||
|
offset: const Offset(0, 4),
|
||||||
|
blurRadius: 4,
|
||||||
|
spreadRadius: 0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: _SidebarHeader(title: 'Spaces')),
|
||||||
|
),
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: ColorsManager.blackColor.withOpacity(0.1),
|
color: ColorsManager.blackColor.withOpacity(0.1),
|
||||||
offset: const Offset(0, -2),
|
offset: const Offset(0, 4),
|
||||||
blurRadius: 4,
|
|
||||||
spreadRadius: 0,
|
|
||||||
),
|
|
||||||
BoxShadow(
|
|
||||||
color: ColorsManager.blackColor.withOpacity(0.1),
|
|
||||||
offset: const Offset(0, 2),
|
|
||||||
blurRadius: 4,
|
blurRadius: 4,
|
||||||
spreadRadius: 0,
|
spreadRadius: 0,
|
||||||
),
|
),
|
||||||
@ -100,8 +108,8 @@ class __SidebarContentState extends State<_SidebarContent> {
|
|||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding:
|
||||||
horizontal: 16.0, vertical: 8.0),
|
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: ColorsManager.counterBackgroundColor,
|
color: ColorsManager.counterBackgroundColor,
|
||||||
@ -111,12 +119,10 @@ class __SidebarContentState extends State<_SidebarContent> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
style: Theme.of(context)
|
style:
|
||||||
.textTheme
|
Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
.bodyMedium
|
color: ColorsManager.blackColor,
|
||||||
?.copyWith(
|
),
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
),
|
|
||||||
controller: searchController,
|
controller: searchController,
|
||||||
onChanged: _handleSearch,
|
onChanged: _handleSearch,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
@ -166,8 +172,7 @@ class __SidebarContentState extends State<_SidebarContent> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
itemCount:
|
itemCount: state.displayedRooms.length + (state.hasMore ? 1 : 0),
|
||||||
state.displayedRooms.length + (state.hasMore ? 1 : 0),
|
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
if (index == state.displayedRooms.length) {
|
if (index == state.displayedRooms.length) {
|
||||||
return _buildLoadMoreIndicator(state);
|
return _buildLoadMoreIndicator(state);
|
||||||
@ -178,9 +183,7 @@ class __SidebarContentState extends State<_SidebarContent> {
|
|||||||
room: room,
|
room: room,
|
||||||
isSelected: state.selectedRoomId == room.uuid,
|
isSelected: state.selectedRoomId == room.uuid,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context
|
context.read<SidebarBloc>().add(SelectRoomEvent(room.uuid));
|
||||||
.read<SidebarBloc>()
|
|
||||||
.add(SelectRoomEvent(room.uuid));
|
|
||||||
widget.onRoomSelected(room);
|
widget.onRoomSelected(room);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -220,7 +223,7 @@ class _SidebarHeader extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(10.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
|
@ -66,18 +66,28 @@ class _CustomCalendarPageState extends State<CustomCalendarPage> {
|
|||||||
weekdayLabels: const ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
|
weekdayLabels: const ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
|
||||||
);
|
);
|
||||||
|
|
||||||
return CalendarDatePicker2(
|
return Container(
|
||||||
config: config,
|
decoration: const BoxDecoration(
|
||||||
value: [_selectedDate],
|
border: Border(
|
||||||
onValueChanged: (dates) {
|
top: BorderSide(
|
||||||
final picked = dates.first;
|
color: ColorsManager.textGray,
|
||||||
if (picked != null) {
|
width: 1.0,
|
||||||
setState(() {
|
),
|
||||||
_selectedDate = picked;
|
),
|
||||||
});
|
),
|
||||||
widget.onDateChanged(picked.day, picked.month, picked.year);
|
child: CalendarDatePicker2(
|
||||||
}
|
config: config,
|
||||||
},
|
value: [_selectedDate],
|
||||||
|
onValueChanged: (dates) {
|
||||||
|
final picked = dates.first;
|
||||||
|
if (picked != null) {
|
||||||
|
setState(() {
|
||||||
|
_selectedDate = picked;
|
||||||
|
});
|
||||||
|
widget.onDateChanged(picked.day, picked.month, picked.year);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,15 +32,17 @@ class EventTileWidget extends StatelessWidget {
|
|||||||
return Expanded(
|
return Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
padding: EdgeInsets.all(5),
|
padding: const EdgeInsets.all(5),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: isEventEnded
|
color: isEventEnded
|
||||||
? ColorsManager.grayColor.withOpacity(0.1)
|
? ColorsManager.grayColor.withOpacity(0.1)
|
||||||
: ColorsManager.blue1.withOpacity(0.1),
|
: ColorsManager.blue1.withOpacity(0.1),
|
||||||
borderRadius: BorderRadius.circular(6),
|
borderRadius: BorderRadius.circular(6),
|
||||||
border: const Border(
|
border: Border(
|
||||||
left: BorderSide(
|
left: BorderSide(
|
||||||
color: ColorsManager.grayColor,
|
color: isEventEnded
|
||||||
|
? ColorsManager.grayColor
|
||||||
|
: ColorsManager.secondaryColor,
|
||||||
width: 4,
|
width: 4,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -21,7 +21,7 @@ class RoomListItem extends StatelessWidget {
|
|||||||
groupValue: isSelected ? room.uuid : null,
|
groupValue: isSelected ? room.uuid : null,
|
||||||
visualDensity: const VisualDensity(vertical: -4),
|
visualDensity: const VisualDensity(vertical: -4),
|
||||||
onChanged: (value) => onTap(),
|
onChanged: (value) => onTap(),
|
||||||
activeColor: ColorsManager.primaryColor,
|
activeColor: ColorsManager.secondaryColor,
|
||||||
title: Text(
|
title: Text(
|
||||||
room.spaceName,
|
room.spaceName,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
|
@ -14,26 +14,33 @@ class WeekDayHeader extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column(
|
return ColoredBox(
|
||||||
children: [
|
color: isSelectedDay
|
||||||
Text(
|
? ColorsManager.secondaryColor.withOpacity(0.1)
|
||||||
DateFormat('EEE').format(date).toUpperCase(),
|
: Colors.transparent,
|
||||||
style: TextStyle(
|
child: Column(
|
||||||
fontWeight: FontWeight.w400,
|
children: [
|
||||||
fontSize: 14,
|
const SizedBox(
|
||||||
color: isSelectedDay ? Colors.blue : Colors.black,
|
height: 10,
|
||||||
),
|
),
|
||||||
),
|
Text(
|
||||||
Text(
|
DateFormat('EEE').format(date).toUpperCase(),
|
||||||
DateFormat('d').format(date),
|
style: const TextStyle(
|
||||||
style: TextStyle(
|
fontWeight: FontWeight.w400,
|
||||||
fontWeight: FontWeight.w700,
|
fontSize: 14,
|
||||||
fontSize: 20,
|
color: ColorsManager.blackColor,
|
||||||
color:
|
),
|
||||||
isSelectedDay ? ColorsManager.blue1 : ColorsManager.blackColor,
|
|
||||||
),
|
),
|
||||||
),
|
Text(
|
||||||
],
|
DateFormat('d').format(date),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
fontSize: 30,
|
||||||
|
color: ColorsManager.blackColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ class WeekNavigation extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
|
width: 250,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: ColorsManager.circleRolesBackground,
|
color: ColorsManager.circleRolesBackground,
|
||||||
@ -32,6 +33,8 @@ class WeekNavigation extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
IconButton(
|
IconButton(
|
||||||
iconSize: 15,
|
iconSize: 15,
|
||||||
@ -40,12 +43,16 @@ class WeekNavigation extends StatelessWidget {
|
|||||||
onPressed: onPreviousWeek,
|
onPressed: onPreviousWeek,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Text(
|
SizedBox(
|
||||||
_getMonthYearText(weekStart, weekEnd),
|
width: 120,
|
||||||
style: const TextStyle(
|
child: Text(
|
||||||
color: ColorsManager.lightGrayColor,
|
_getMonthYearText(weekStart, weekEnd),
|
||||||
fontSize: 14,
|
style: const TextStyle(
|
||||||
fontWeight: FontWeight.w400,
|
color: ColorsManager.lightGrayColor,
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
|
@ -24,7 +24,7 @@ class WeeklyCalendarPage extends StatelessWidget {
|
|||||||
});
|
});
|
||||||
static const double timeLineWidth = 65;
|
static const double timeLineWidth = 65;
|
||||||
static const int totalDays = 7;
|
static const int totalDays = 7;
|
||||||
static const double dayColumnWidth = 220;
|
static const double dayColumnWidth = 220;
|
||||||
|
|
||||||
final double calendarContentWidth =
|
final double calendarContentWidth =
|
||||||
timeLineWidth + (totalDays * dayColumnWidth);
|
timeLineWidth + (totalDays * dayColumnWidth);
|
||||||
@ -57,13 +57,10 @@ class WeeklyCalendarPage extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const double timeLineWidth = 90;
|
||||||
|
|
||||||
const double timeLineWidth = 65;
|
|
||||||
|
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
|
|
||||||
bool isInRange(DateTime date, DateTime start, DateTime end) {
|
bool isInRange(DateTime date, DateTime start, DateTime end) {
|
||||||
!date.isBefore(start) && !date.isAfter(end);
|
!date.isBefore(start) && !date.isAfter(end);
|
||||||
// remove this line and Check if the date is within the range
|
// remove this line and Check if the date is within the range
|
||||||
@ -100,7 +97,6 @@ class WeeklyCalendarPage extends StatelessWidget {
|
|||||||
width: width,
|
width: width,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.orange.withOpacity(0.13),
|
color: Colors.orange.withOpacity(0.13),
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else if (isSelected) {
|
} else if (isSelected) {
|
||||||
@ -110,7 +106,6 @@ class WeeklyCalendarPage extends StatelessWidget {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color:
|
color:
|
||||||
ColorsManager.spaceColor.withOpacity(0.07),
|
ColorsManager.spaceColor.withOpacity(0.07),
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -143,7 +138,7 @@ class WeeklyCalendarPage extends StatelessWidget {
|
|||||||
heightPerMinute: 1.7,
|
heightPerMinute: 1.7,
|
||||||
showLiveTimeLineInAllDays: false,
|
showLiveTimeLineInAllDays: false,
|
||||||
showVerticalLines: true,
|
showVerticalLines: true,
|
||||||
emulateVerticalOffsetBy: -80,
|
emulateVerticalOffsetBy: -95,
|
||||||
startDay: WeekDays.monday,
|
startDay: WeekDays.monday,
|
||||||
liveTimeIndicatorSettings:
|
liveTimeIndicatorSettings:
|
||||||
const LiveTimeIndicatorSettings(
|
const LiveTimeIndicatorSettings(
|
||||||
@ -161,7 +156,7 @@ class WeeklyCalendarPage extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
timeLineWidth: timeLineWidth,
|
timeLineWidth: timeLineWidth,
|
||||||
weekPageHeaderBuilder: (start, end) => Container(),
|
weekPageHeaderBuilder: (start, end) => Container(),
|
||||||
weekTitleHeight: 60,
|
weekTitleHeight: 90,
|
||||||
weekNumberBuilder: (firstDayOfWeek) => Padding(
|
weekNumberBuilder: (firstDayOfWeek) => Padding(
|
||||||
padding: const EdgeInsets.only(right: 15, bottom: 10),
|
padding: const EdgeInsets.only(right: 15, bottom: 10),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -208,8 +203,6 @@ class WeeklyCalendarPage extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSameDay(DateTime d1, DateTime d2) {
|
bool isSameDay(DateTime d1, DateTime d2) {
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:syncrow_web/pages/access_management/booking_system/presentation/view/widgets/icon_text_button.dart';
|
|
||||||
|
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
|
||||||
|
|
||||||
class BookingPage extends StatelessWidget {
|
|
||||||
final PageController pageController;
|
|
||||||
const BookingPage({
|
|
||||||
super.key,
|
|
||||||
required this.pageController,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
color: Colors.blueGrey[100],
|
|
||||||
child: const Center(
|
|
||||||
child: Text(
|
|
||||||
'Side bar',
|
|
||||||
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
Expanded(
|
|
||||||
flex: 4,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(20.0),
|
|
||||||
child: SizedBox(
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
SvgTextButton(
|
|
||||||
svgAsset: Assets.homeIcon,
|
|
||||||
label: 'Manage Bookable Spaces',
|
|
||||||
onPressed: () {
|
|
||||||
pageController.jumpToPage(2);
|
|
||||||
}),
|
|
||||||
const SizedBox(width: 20),
|
|
||||||
SvgTextButton(
|
|
||||||
svgAsset: Assets.groupIcon,
|
|
||||||
label: 'Manage Users',
|
|
||||||
onPressed: () {})
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
))
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
class NonBookableSpacesParams {
|
class NonBookableSpacesParams {
|
||||||
final int currentPage;
|
final int currentPage;
|
||||||
String? searchedWords;
|
final String? searchedWords;
|
||||||
NonBookableSpacesParams({
|
NonBookableSpacesParams({
|
||||||
required this.currentPage,
|
required this.currentPage,
|
||||||
this.searchedWords,
|
this.searchedWords,
|
||||||
|
@ -10,51 +10,123 @@ part 'setup_bookable_spaces_state.dart';
|
|||||||
class SetupBookableSpacesBloc
|
class SetupBookableSpacesBloc
|
||||||
extends Bloc<SetupBookableSpacesEvent, SetupBookableSpacesState> {
|
extends Bloc<SetupBookableSpacesEvent, SetupBookableSpacesState> {
|
||||||
NonBookableSpacesService nonBookableSpacesService;
|
NonBookableSpacesService nonBookableSpacesService;
|
||||||
List<BookableSpacemodel> selectedBookableSpaces = [];
|
|
||||||
SetupBookableSpacesBloc(this.nonBookableSpacesService)
|
SetupBookableSpacesBloc(this.nonBookableSpacesService)
|
||||||
: super(SetupBookableSpacesInitial()) {
|
: super(const SetupBookableSpacesInitial(bookableSpaces: [])) {
|
||||||
on<AddToBookableSpaceEvent>(_onAddToBookableSpaceEvent);
|
on<AddToBookableSpaceEvent>(_onAddToBookableSpaceEvent);
|
||||||
on<RemoveFromBookableSpaceEvent>(_onRemoveFromBookableSpaceEvent);
|
on<RemoveFromBookableSpaceEvent>(_onRemoveFromBookableSpaceEvent);
|
||||||
|
on<AddBookableDaysEvent>(_onAddBookableDays);
|
||||||
|
on<ChangeStartTimeEvent>(_onChangeStartTimeEvent);
|
||||||
|
on<ChangeEndTimeEvent>(_onChangeEndTimeEvent);
|
||||||
|
on<ChangeCostEvent>(_onChangeCostEvent);
|
||||||
|
|
||||||
on<CheckConfigurValidityEvent>(_onCheckConfigurValidityEvent);
|
on<CheckConfigurValidityEvent>(_onCheckConfigurValidityEvent);
|
||||||
on<EditModeSelected>(_onEditModeSelected);
|
on<EditModeSelected>(_onEditModeSelected);
|
||||||
}
|
}
|
||||||
TimeOfDay? get endTime =>
|
List<BookableSpacemodel> get currentBookableSpaces {
|
||||||
selectedBookableSpaces.first.spaceConfig!.bookingEndTime;
|
return switch (state) {
|
||||||
|
AddNonBookableSpaceIntoBookableState(:final bookableSpaces) =>
|
||||||
TimeOfDay? get startTime =>
|
bookableSpaces,
|
||||||
selectedBookableSpaces.first.spaceConfig!.bookingStartTime;
|
RemoveBookableSpaceIntoNonBookableState(:final bookableSpaces) =>
|
||||||
|
bookableSpaces,
|
||||||
|
SetupBookableSpacesInitial(:final bookableSpaces) => bookableSpaces,
|
||||||
|
InProgressState(:final bookableSpaces) => bookableSpaces,
|
||||||
|
ValidSaveButtonState(:final bookableSpaces) => bookableSpaces,
|
||||||
|
UnValidSaveButtonState(:final bookableSpaces) => bookableSpaces,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void _onAddToBookableSpaceEvent(
|
void _onAddToBookableSpaceEvent(
|
||||||
AddToBookableSpaceEvent event,
|
AddToBookableSpaceEvent event,
|
||||||
Emitter<SetupBookableSpacesState> emit,
|
Emitter<SetupBookableSpacesState> emit,
|
||||||
) {
|
) {
|
||||||
emit(InProgressState());
|
emit(InProgressState(bookableSpaces: state.bookableSpaces));
|
||||||
selectedBookableSpaces.add(event.nonBookableSpace);
|
final updatedSpaces = List<BookableSpacemodel>.from(state.bookableSpaces);
|
||||||
emit(AddNonBookableSpaceIntoBookableState(
|
|
||||||
bookableSpaces: selectedBookableSpaces));
|
updatedSpaces.add(event.nonBookableSpace);
|
||||||
|
|
||||||
|
emit(AddNonBookableSpaceIntoBookableState(bookableSpaces: updatedSpaces));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onRemoveFromBookableSpaceEvent(RemoveFromBookableSpaceEvent event,
|
void _onRemoveFromBookableSpaceEvent(RemoveFromBookableSpaceEvent event,
|
||||||
Emitter<SetupBookableSpacesState> emit) {
|
Emitter<SetupBookableSpacesState> emit) {
|
||||||
emit(InProgressState());
|
emit(InProgressState(bookableSpaces: state.bookableSpaces));
|
||||||
selectedBookableSpaces.remove(event.bookableSpace);
|
state.bookableSpaces.remove(event.bookableSpace);
|
||||||
emit(RemoveBookableSpaceIntoNonBookableState(
|
emit(RemoveBookableSpaceIntoNonBookableState(
|
||||||
bookableSpaces: selectedBookableSpaces));
|
bookableSpaces: state.bookableSpaces));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onAddBookableDays(
|
||||||
|
AddBookableDaysEvent event, Emitter<SetupBookableSpacesState> emit) {
|
||||||
|
final updatedSpaces = state.bookableSpaces.map((space) {
|
||||||
|
final updatedConfig = space.spaceConfig?.copyWith(
|
||||||
|
bookableDays: event.bookableDays,
|
||||||
|
);
|
||||||
|
|
||||||
|
return space.copyWith(spaceConfig: updatedConfig);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
emit(SetupBookableSpacesInitial(bookableSpaces: updatedSpaces));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onChangeStartTimeEvent(
|
||||||
|
ChangeStartTimeEvent event, Emitter<SetupBookableSpacesState> emit) {
|
||||||
|
final updatedSpaces = state.bookableSpaces.map((space) {
|
||||||
|
final updatedConfig = space.spaceConfig?.copyWith(
|
||||||
|
bookingStartTime: event.startTime,
|
||||||
|
);
|
||||||
|
|
||||||
|
return space.copyWith(spaceConfig: updatedConfig);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
emit(SetupBookableSpacesInitial(bookableSpaces: updatedSpaces));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onChangeEndTimeEvent(
|
||||||
|
ChangeEndTimeEvent event, Emitter<SetupBookableSpacesState> emit) {
|
||||||
|
final updatedSpaces = state.bookableSpaces.map((space) {
|
||||||
|
final updatedConfig = space.spaceConfig?.copyWith(
|
||||||
|
bookingEndTime: event.endTime,
|
||||||
|
);
|
||||||
|
|
||||||
|
return space.copyWith(spaceConfig: updatedConfig);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
emit(SetupBookableSpacesInitial(bookableSpaces: updatedSpaces));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onChangeCostEvent(
|
||||||
|
ChangeCostEvent event, Emitter<SetupBookableSpacesState> emit) {
|
||||||
|
final updatedSpaces = state.bookableSpaces.map((space) {
|
||||||
|
final updatedConfig = space.spaceConfig?.copyWith(
|
||||||
|
cost: event.cost,
|
||||||
|
);
|
||||||
|
|
||||||
|
return space.copyWith(spaceConfig: updatedConfig);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
emit(SetupBookableSpacesInitial(bookableSpaces: updatedSpaces));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onCheckConfigurValidityEvent(CheckConfigurValidityEvent event,
|
void _onCheckConfigurValidityEvent(CheckConfigurValidityEvent event,
|
||||||
Emitter<SetupBookableSpacesState> emit) {
|
Emitter<SetupBookableSpacesState> emit) {
|
||||||
if (selectedBookableSpaces.first.spaceConfig!.isValid) {
|
if (state.bookableSpaces.first.spaceConfig!.isValid) {
|
||||||
emit(ValidSaveButtonState());
|
emit(ValidSaveButtonState(
|
||||||
|
bookableSpaces: state.bookableSpaces,
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
emit(UnValidSaveButtonState());
|
emit(UnValidSaveButtonState(
|
||||||
|
bookableSpaces: state.bookableSpaces,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onEditModeSelected(
|
void _onEditModeSelected(
|
||||||
EditModeSelected event, Emitter<SetupBookableSpacesState> emit) {
|
EditModeSelected event,
|
||||||
selectedBookableSpaces.clear();
|
Emitter<SetupBookableSpacesState> emit,
|
||||||
selectedBookableSpaces.add(event.editingBookableSpace);
|
) {
|
||||||
|
final updatedList = [event.editingBookableSpace];
|
||||||
|
|
||||||
|
emit(SetupBookableSpacesInitial(bookableSpaces: updatedList));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,34 @@ class RemoveFromBookableSpaceEvent extends SetupBookableSpacesEvent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AddBookableDaysEvent extends SetupBookableSpacesEvent {
|
||||||
|
final List<String> bookableDays;
|
||||||
|
const AddBookableDaysEvent({
|
||||||
|
required this.bookableDays,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChangeCostEvent extends SetupBookableSpacesEvent {
|
||||||
|
final int cost;
|
||||||
|
const ChangeCostEvent({
|
||||||
|
required this.cost,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChangeStartTimeEvent extends SetupBookableSpacesEvent {
|
||||||
|
final TimeOfDay startTime;
|
||||||
|
const ChangeStartTimeEvent({
|
||||||
|
required this.startTime,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChangeEndTimeEvent extends SetupBookableSpacesEvent {
|
||||||
|
final TimeOfDay endTime;
|
||||||
|
const ChangeEndTimeEvent({
|
||||||
|
required this.endTime,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
class CheckConfigurValidityEvent extends SetupBookableSpacesEvent {}
|
class CheckConfigurValidityEvent extends SetupBookableSpacesEvent {}
|
||||||
|
|
||||||
class EditModeSelected extends SetupBookableSpacesEvent {
|
class EditModeSelected extends SetupBookableSpacesEvent {
|
||||||
|
@ -1,32 +1,37 @@
|
|||||||
part of 'setup_bookable_spaces_bloc.dart';
|
part of 'setup_bookable_spaces_bloc.dart';
|
||||||
|
|
||||||
sealed class SetupBookableSpacesState extends Equatable {
|
sealed class SetupBookableSpacesState extends Equatable {
|
||||||
const SetupBookableSpacesState();
|
final List<BookableSpacemodel> bookableSpaces;
|
||||||
|
const SetupBookableSpacesState({required this.bookableSpaces});
|
||||||
|
TimeOfDay? get startTime =>
|
||||||
|
bookableSpaces.first.spaceConfig!.bookingStartTime;
|
||||||
|
TimeOfDay? get endTime => bookableSpaces.first.spaceConfig!.bookingEndTime;
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [];
|
List<Object> get props => [];
|
||||||
}
|
}
|
||||||
|
|
||||||
final class SetupBookableSpacesInitial extends SetupBookableSpacesState {}
|
final class SetupBookableSpacesInitial extends SetupBookableSpacesState {
|
||||||
|
const SetupBookableSpacesInitial({required super.bookableSpaces});
|
||||||
|
}
|
||||||
|
|
||||||
class AddNonBookableSpaceIntoBookableState extends SetupBookableSpacesState {
|
class AddNonBookableSpaceIntoBookableState extends SetupBookableSpacesState {
|
||||||
final List<BookableSpacemodel> bookableSpaces;
|
const AddNonBookableSpaceIntoBookableState({required super.bookableSpaces});
|
||||||
const AddNonBookableSpaceIntoBookableState({
|
|
||||||
required this.bookableSpaces,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class InProgressState extends SetupBookableSpacesState {}
|
class InProgressState extends SetupBookableSpacesState {
|
||||||
|
const InProgressState({required super.bookableSpaces});
|
||||||
|
}
|
||||||
|
|
||||||
class RemoveBookableSpaceIntoNonBookableState extends SetupBookableSpacesState {
|
class RemoveBookableSpaceIntoNonBookableState extends SetupBookableSpacesState {
|
||||||
final List<BookableSpacemodel> bookableSpaces;
|
|
||||||
const RemoveBookableSpaceIntoNonBookableState({
|
const RemoveBookableSpaceIntoNonBookableState({
|
||||||
required this.bookableSpaces,
|
required super.bookableSpaces,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class ValidSaveButtonState extends SetupBookableSpacesState {}
|
class ValidSaveButtonState extends SetupBookableSpacesState {
|
||||||
|
const ValidSaveButtonState({required super.bookableSpaces});
|
||||||
class UnValidSaveButtonState extends SetupBookableSpacesState {}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class UnValidSaveButtonState extends SetupBookableSpacesState {
|
||||||
|
const UnValidSaveButtonState({required super.bookableSpaces});
|
||||||
|
}
|
||||||
|
@ -52,20 +52,20 @@ class _SetupBookableSpacesDialogState extends State<SetupBookableSpacesDialog> {
|
|||||||
),
|
),
|
||||||
)..add(
|
)..add(
|
||||||
LoadUnBookableSpacesEvent(
|
LoadUnBookableSpacesEvent(
|
||||||
nonBookableSpacesParams:
|
nonBookableSpacesParams: NonBookableSpacesParams(currentPage: 1),
|
||||||
NonBookableSpacesParams(currentPage: 1),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
BlocProvider<SetupBookableSpacesBloc>(
|
BlocProvider<SetupBookableSpacesBloc>(
|
||||||
create: widget.editingBookableSpace == null
|
create: widget.editingBookableSpace == null
|
||||||
? (context) => SetupBookableSpacesBloc(
|
? (context) =>
|
||||||
RemoteNonBookableSpaces(HTTPService()))
|
SetupBookableSpacesBloc(RemoteNonBookableSpaces(HTTPService()))
|
||||||
: (context) => SetupBookableSpacesBloc(
|
: (context) =>
|
||||||
RemoteNonBookableSpaces(HTTPService()))
|
SetupBookableSpacesBloc(RemoteNonBookableSpaces(HTTPService()))
|
||||||
..add(EditModeSelected(
|
..add(
|
||||||
editingBookableSpace: widget.editingBookableSpace!,
|
EditModeSelected(
|
||||||
)),
|
editingBookableSpace: widget.editingBookableSpace!),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) => SendBookableSpacesBloc(
|
create: (context) => SendBookableSpacesBloc(
|
||||||
@ -74,7 +74,7 @@ class _SetupBookableSpacesDialogState extends State<SetupBookableSpacesDialog> {
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
child: AlertDialog(
|
child: AlertDialog(
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
backgroundColor: ColorsManager.white,
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
title: Center(
|
title: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
@ -115,16 +115,14 @@ class _SetupBookableSpacesDialogState extends State<SetupBookableSpacesDialog> {
|
|||||||
),
|
),
|
||||||
Builder(builder: (context) {
|
Builder(builder: (context) {
|
||||||
final stepsState = context.watch<StepsCubit>().state;
|
final stepsState = context.watch<StepsCubit>().state;
|
||||||
final setupBookableSpacesBloc =
|
final bookableSpaces =
|
||||||
context.watch<SetupBookableSpacesBloc>();
|
context.watch<SetupBookableSpacesBloc>().state.bookableSpaces;
|
||||||
final selectedSpaces =
|
|
||||||
setupBookableSpacesBloc.selectedBookableSpaces;
|
|
||||||
return stepsState is StepOneState
|
return stepsState is StepOneState
|
||||||
? NextFirstStepButton(selectedSpaces: selectedSpaces)
|
? const NextFirstStepButton()
|
||||||
: SaveSecondStepButton(
|
: SaveSecondStepButton(
|
||||||
selectedSpaces: selectedSpaces,
|
|
||||||
pointsController: pointsController,
|
pointsController: pointsController,
|
||||||
isEditingMode: widget.editingBookableSpace != null,
|
isEditingMode: widget.editingBookableSpace != null,
|
||||||
|
bookableSpaces: bookableSpaces,
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -21,16 +21,14 @@ class BookableSpaceSwitchActivationWidget extends StatelessWidget {
|
|||||||
return Center(
|
return Center(
|
||||||
child: Transform.scale(
|
child: Transform.scale(
|
||||||
scale: 0.7,
|
scale: 0.7,
|
||||||
child:
|
child: BlocConsumer<UpdateBookableSpacesBloc, UpdateBookableSpacesState>(
|
||||||
BlocConsumer<UpdateBookableSpacesBloc, UpdateBookableSpacesState>(
|
|
||||||
listener: (context, updateState) {
|
listener: (context, updateState) {
|
||||||
if (updateState is UpdateBookableSpaceSuccess) {
|
if (updateState is UpdateBookableSpaceSuccess) {
|
||||||
context.read<BookableSpacesBloc>().add(
|
context.read<BookableSpacesBloc>().add(
|
||||||
InsertUpdatedSpaceEvent(
|
InsertUpdatedSpaceEvent(
|
||||||
bookableSpaces: bookableSpaces,
|
bookableSpaces: bookableSpaces,
|
||||||
bookableSpace: space,
|
bookableSpace: space,
|
||||||
updatedBookableSpaceConfig:
|
updatedBookableSpaceConfig: updateState.bookableSpaceConfig,
|
||||||
updateState.bookableSpaceConfig,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -42,16 +40,16 @@ class BookableSpaceSwitchActivationWidget extends StatelessWidget {
|
|||||||
return const Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
}
|
}
|
||||||
return Switch(
|
return Switch(
|
||||||
trackOutlineColor: WidgetStateProperty.resolveWith<Color>(
|
trackOutlineColor:
|
||||||
(Set<WidgetState> states) {
|
WidgetStateProperty.resolveWith<Color>((Set<WidgetState> states) {
|
||||||
return ColorsManager.whiteColors;
|
return ColorsManager.white;
|
||||||
}),
|
}),
|
||||||
value: space.spaceConfig!.availability,
|
value: space.spaceConfig!.availability,
|
||||||
activeTrackColor: ColorsManager.blueColor,
|
activeTrackColor: ColorsManager.dialogBlueTitle,
|
||||||
inactiveTrackColor: ColorsManager.grayBorder,
|
inactiveTrackColor: ColorsManager.grayBorder,
|
||||||
thumbColor: WidgetStateProperty.resolveWith<Color>(
|
thumbColor:
|
||||||
(Set<WidgetState> states) {
|
WidgetStateProperty.resolveWith<Color>((Set<WidgetState> states) {
|
||||||
return ColorsManager.whiteColors;
|
return ColorsManager.white;
|
||||||
}),
|
}),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<UpdateBookableSpacesBloc>().add(
|
context.read<UpdateBookableSpacesBloc>().add(
|
||||||
|
@ -17,6 +17,8 @@ class BookingPeriodWidget extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final state = context.watch<SetupBookableSpacesBloc>().state;
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@ -32,122 +34,108 @@ class BookingPeriodWidget extends StatelessWidget {
|
|||||||
const Text('Booking Period'),
|
const Text('Booking Period'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 5),
|
||||||
Container(
|
Container(
|
||||||
width: 300,
|
width: 230,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(8),
|
||||||
color: ColorsManager.graysColor,
|
color: ColorsManager.circleRolesBackground,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
offset: Offset.zero,
|
||||||
|
blurRadius: 4,
|
||||||
|
spreadRadius: 0,
|
||||||
|
color: ColorsManager.timePickerColor.withValues(alpha: 0.15),
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
TimePickerWidget(
|
TimePickerWidget(
|
||||||
title: editingBookableSpace == null
|
title: editingBookableSpace?.spaceConfig?.bookingStartTime
|
||||||
? 'Start Time'
|
?.format(context) ??
|
||||||
: editingBookableSpace!.spaceConfig!.bookingStartTime!
|
'Start Time',
|
||||||
.format(context),
|
onTimePicked: (pickedStartTime) {
|
||||||
onTimePicked: (timePicked) {
|
if (pickedStartTime == null) return;
|
||||||
if (timePicked == null) {
|
|
||||||
|
if (state.endTime != null &&
|
||||||
|
isEndTimeAfterStartTime(
|
||||||
|
pickedStartTime, state.endTime!)) {
|
||||||
|
_showInvalidSnackBar(
|
||||||
|
context, "You can't choose Start Time after End Time");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final setupBookableSpacesBloc =
|
|
||||||
context.read<SetupBookableSpacesBloc>();
|
|
||||||
|
|
||||||
if (setupBookableSpacesBloc.endTime != null &&
|
context.read<SetupBookableSpacesBloc>().add(
|
||||||
isEndTimeAfterStartTime(
|
ChangeStartTimeEvent(startTime: pickedStartTime),
|
||||||
timePicked, setupBookableSpacesBloc.endTime!)) {
|
);
|
||||||
ScaffoldMessenger.of(context).clearSnackBars();
|
context.read<SetupBookableSpacesBloc>().add(
|
||||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
CheckConfigurValidityEvent(),
|
||||||
content:
|
);
|
||||||
Text("You can't choose start Time Before End time"),
|
|
||||||
duration: Duration(seconds: 2),
|
|
||||||
backgroundColor: ColorsManager.red,
|
|
||||||
));
|
|
||||||
throw Exception();
|
|
||||||
} else {
|
|
||||||
for (int i = 0;
|
|
||||||
i <
|
|
||||||
setupBookableSpacesBloc
|
|
||||||
.selectedBookableSpaces.length;
|
|
||||||
i++) {
|
|
||||||
final space =
|
|
||||||
setupBookableSpacesBloc.selectedBookableSpaces[i];
|
|
||||||
final updatedConfig = space.spaceConfig
|
|
||||||
?.copyWith(bookingStartTime: timePicked);
|
|
||||||
final updatedSpace =
|
|
||||||
space.copyWith(spaceConfig: updatedConfig);
|
|
||||||
|
|
||||||
setupBookableSpacesBloc.selectedBookableSpaces[i] =
|
|
||||||
updatedSpace;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
const Icon(
|
const Icon(
|
||||||
Icons.arrow_right_alt,
|
Icons.arrow_right_alt,
|
||||||
color: ColorsManager.grayColor,
|
color: ColorsManager.grayColor,
|
||||||
|
size: 13,
|
||||||
),
|
),
|
||||||
TimePickerWidget(
|
TimePickerWidget(
|
||||||
title: editingBookableSpace == null
|
title: editingBookableSpace?.spaceConfig?.bookingEndTime
|
||||||
? 'End Time'
|
?.format(context) ??
|
||||||
: editingBookableSpace!.spaceConfig!.bookingEndTime!
|
'End Time',
|
||||||
.format(context),
|
onTimePicked: (pickedEndTime) {
|
||||||
onTimePicked: (timePicked) {
|
if (pickedEndTime == null) return;
|
||||||
if (timePicked == null) {
|
|
||||||
|
if (state.startTime != null &&
|
||||||
|
isEndTimeAfterStartTime(
|
||||||
|
state.startTime!, pickedEndTime)) {
|
||||||
|
_showInvalidSnackBar(
|
||||||
|
context, "You can't choose End Time before Start Time");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final setupBookableSpacesBloc =
|
|
||||||
context.read<SetupBookableSpacesBloc>();
|
|
||||||
if (setupBookableSpacesBloc.startTime != null &&
|
|
||||||
isEndTimeAfterStartTime(
|
|
||||||
setupBookableSpacesBloc.startTime!, timePicked)) {
|
|
||||||
ScaffoldMessenger.of(context).clearSnackBars();
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
|
||||||
content:
|
|
||||||
Text("You can't choose End Time After Start time"),
|
|
||||||
duration: Duration(seconds: 2),
|
|
||||||
backgroundColor: ColorsManager.red,
|
|
||||||
));
|
|
||||||
throw Exception();
|
|
||||||
} else {
|
|
||||||
for (int i = 0;
|
|
||||||
i <
|
|
||||||
setupBookableSpacesBloc
|
|
||||||
.selectedBookableSpaces.length;
|
|
||||||
i++) {
|
|
||||||
final space =
|
|
||||||
setupBookableSpacesBloc.selectedBookableSpaces[i];
|
|
||||||
final updatedConfig = space.spaceConfig
|
|
||||||
?.copyWith(bookingEndTime: timePicked);
|
|
||||||
final updatedSpace =
|
|
||||||
space.copyWith(spaceConfig: updatedConfig);
|
|
||||||
|
|
||||||
setupBookableSpacesBloc.selectedBookableSpaces[i] =
|
context.read<SetupBookableSpacesBloc>().add(
|
||||||
updatedSpace;
|
ChangeEndTimeEvent(endTime: pickedEndTime),
|
||||||
}
|
);
|
||||||
}
|
context.read<SetupBookableSpacesBloc>().add(
|
||||||
|
CheckConfigurValidityEvent(),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
const SizedBox(width: 15),
|
||||||
Container(
|
Container(
|
||||||
width: 50,
|
width: 30,
|
||||||
height: 32,
|
height: 32,
|
||||||
|
alignment: Alignment.center,
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topLeft: Radius.circular(10),
|
topLeft: Radius.circular(10),
|
||||||
bottomLeft: Radius.circular(10),
|
bottomLeft: Radius.circular(10),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
alignment: Alignment.center,
|
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.clockIcon,
|
Assets.clockIcon,
|
||||||
height: 15,
|
height: 18,
|
||||||
color: ColorsManager.blackColor.withValues(alpha: 0.4),
|
color: ColorsManager.blackColor.withValues(alpha: 0.4),
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _showInvalidSnackBar(BuildContext context, String message) {
|
||||||
|
ScaffoldMessenger.of(context).clearSnackBars();
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(message),
|
||||||
|
duration: const Duration(seconds: 2),
|
||||||
|
backgroundColor: ColorsManager.red,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,15 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart';
|
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/blocs/setup_bookable_spaces_bloc/setup_bookable_spaces_bloc.dart';
|
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/blocs/setup_bookable_spaces_bloc/setup_bookable_spaces_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/widgets/custom_checkbox_widget.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
class CheckBoxSpaceWidget extends StatelessWidget {
|
class CheckBoxSpaceWidget extends StatelessWidget {
|
||||||
final BookableSpacemodel nonBookableSpace;
|
final BookableSpacemodel nonBookableSpace;
|
||||||
final List<BookableSpacemodel> selectedSpaces;
|
|
||||||
|
|
||||||
const CheckBoxSpaceWidget({
|
const CheckBoxSpaceWidget({
|
||||||
super.key,
|
super.key,
|
||||||
required this.nonBookableSpace,
|
required this.nonBookableSpace,
|
||||||
required this.selectedSpaces,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -32,22 +31,25 @@ class CheckBoxSpaceWidget extends StatelessWidget {
|
|||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
return Checkbox(
|
return CustomCheckboxWidget(
|
||||||
value: isChecked,
|
value: isChecked,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
final bloc = context.read<SetupBookableSpacesBloc>();
|
final bloc = context.read<SetupBookableSpacesBloc>();
|
||||||
|
|
||||||
if (value ?? false) {
|
if (value ?? false) {
|
||||||
bloc.add(AddToBookableSpaceEvent(
|
bloc.add(AddToBookableSpaceEvent(
|
||||||
nonBookableSpace: nonBookableSpace));
|
nonBookableSpace: nonBookableSpace,
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
bloc.add(RemoveFromBookableSpaceEvent(
|
bloc.add(RemoveFromBookableSpaceEvent(
|
||||||
bookableSpace: nonBookableSpace));
|
bookableSpace: nonBookableSpace,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(width: 5),
|
const SizedBox(width: 15),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@ -55,15 +57,17 @@ class CheckBoxSpaceWidget extends StatelessWidget {
|
|||||||
Text(
|
Text(
|
||||||
nonBookableSpace.spaceName,
|
nonBookableSpace.spaceName,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.w700,
|
||||||
color: ColorsManager.textGray,
|
fontSize: 12,
|
||||||
|
color: ColorsManager.titleGray,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
nonBookableSpace.spaceVirtualAddress,
|
nonBookableSpace.spaceVirtualAddress,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 12,
|
fontWeight: FontWeight.w400,
|
||||||
color: ColorsManager.textGray,
|
fontSize: 10,
|
||||||
|
color: ColorsManager.titleGray,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
|
class CustomCheckboxWidget extends StatelessWidget {
|
||||||
|
final bool value;
|
||||||
|
final ValueChanged<bool?> onChanged;
|
||||||
|
final double? outHeight;
|
||||||
|
final double? outWidth;
|
||||||
|
final double? iconSize;
|
||||||
|
const CustomCheckboxWidget({
|
||||||
|
super.key,
|
||||||
|
required this.value,
|
||||||
|
required this.onChanged,
|
||||||
|
this.outWidth,
|
||||||
|
this.outHeight,
|
||||||
|
this.iconSize,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => onChanged(!value),
|
||||||
|
child: Container(
|
||||||
|
width: outWidth ?? 17,
|
||||||
|
height: outHeight ?? 17,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: value ? Colors.white : ColorsManager.checkBoxFillColor,
|
||||||
|
border: value
|
||||||
|
? Border.all(color: ColorsManager.secondaryColor, width: 1)
|
||||||
|
: Border.all(color: ColorsManager.checkBoxBorderGray, width: 1),
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: value
|
||||||
|
? Center(
|
||||||
|
child: Container(
|
||||||
|
width: outWidth != null ? outWidth! - 4 : 13,
|
||||||
|
height: outHeight != null ? outHeight! - 4 : 13,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: ColorsManager.secondaryColor,
|
||||||
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
),
|
||||||
|
child: const Icon(
|
||||||
|
Icons.check,
|
||||||
|
size: 12,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -20,38 +20,53 @@ class EditBookableSpaceButtonWidget extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Center(
|
return Center(
|
||||||
child: ElevatedButton(
|
child: Container(
|
||||||
onPressed: () {
|
decoration: BoxDecoration(
|
||||||
final bookableBloc = context.read<BookableSpacesBloc>();
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
boxShadow: [
|
||||||
showDialog(
|
BoxShadow(
|
||||||
context: context,
|
offset: Offset.zero,
|
||||||
builder: (context) => MultiBlocProvider(
|
blurRadius: 3,
|
||||||
providers: [
|
spreadRadius: 0,
|
||||||
BlocProvider.value(
|
color: ColorsManager.timePickerColor.withValues(
|
||||||
value: bookableBloc,
|
alpha: 0.3,
|
||||||
),
|
|
||||||
BlocProvider(
|
|
||||||
create: (context) => UpdateBookableSpacesBloc(
|
|
||||||
RemoteUpdateBookableSpaceService(HTTPService()),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
child: SetupBookableSpacesDialog(
|
|
||||||
editingBookableSpace: space,
|
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
);
|
],
|
||||||
},
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
fixedSize: const Size(50, 30),
|
|
||||||
elevation: 1,
|
|
||||||
),
|
),
|
||||||
child: SvgPicture.asset(
|
child: ElevatedButton(
|
||||||
Assets.settings,
|
onPressed: () {
|
||||||
height: 15,
|
final bookableBloc = context.read<BookableSpacesBloc>();
|
||||||
color: ColorsManager.blue1,
|
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => MultiBlocProvider(
|
||||||
|
providers: [
|
||||||
|
BlocProvider.value(
|
||||||
|
value: bookableBloc,
|
||||||
|
),
|
||||||
|
BlocProvider(
|
||||||
|
create: (context) => UpdateBookableSpacesBloc(
|
||||||
|
RemoteUpdateBookableSpaceService(HTTPService()),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
child: SetupBookableSpacesDialog(
|
||||||
|
editingBookableSpace: space,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
minimumSize: const Size(45, 30),
|
||||||
|
elevation: 0,
|
||||||
|
),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.settings,
|
||||||
|
height: 13,
|
||||||
|
color: ColorsManager.blue1,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -66,18 +66,19 @@ class PaginationButtonsWidget extends StatelessWidget {
|
|||||||
height: 30,
|
height: 30,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: i == currentPage
|
color: i == currentPage
|
||||||
? ColorsManager.dialogBlueTitle
|
? ColorsManager.dialogBlueTitle
|
||||||
: Colors.grey[300],
|
: ColorsManager.white,
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
border: Border.all(
|
||||||
|
color: ColorsManager.lightGrayBorderColor,
|
||||||
|
)),
|
||||||
child: Text(
|
child: Text(
|
||||||
'$i',
|
'$i',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: i == currentPage ? Colors.white : Colors.black,
|
color: i == currentPage ? Colors.white : Colors.black,
|
||||||
fontWeight: i == currentPage
|
fontWeight:
|
||||||
? FontWeight.bold
|
i == currentPage ? FontWeight.bold : FontWeight.normal,
|
||||||
: FontWeight.normal,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -127,18 +128,21 @@ class PaginationButtonsWidget extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildArrowButton(
|
Widget _buildArrowButton({required String label, required VoidCallback onTap}) {
|
||||||
{required String label, required VoidCallback onTap}) {
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
alignment: Alignment.center,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.grey[300],
|
color: ColorsManager.white,
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
border: Border.all(
|
||||||
|
color: ColorsManager.lightGrayBorderColor,
|
||||||
|
)),
|
||||||
child: Text(
|
child: Text(
|
||||||
label,
|
label,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
|
@ -24,20 +24,37 @@ class RowOfButtonsTitleWidget extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
ElevatedButton(
|
Container(
|
||||||
style: ElevatedButton.styleFrom(
|
decoration: BoxDecoration(
|
||||||
padding: EdgeInsets.zero,
|
borderRadius: BorderRadius.circular(12),
|
||||||
shape: RoundedRectangleBorder(
|
boxShadow: [
|
||||||
borderRadius: BorderRadius.circular(12),
|
BoxShadow(
|
||||||
|
offset: Offset.zero,
|
||||||
|
blurRadius: 3,
|
||||||
|
spreadRadius: 0,
|
||||||
|
color: ColorsManager.timePickerColor.withValues(
|
||||||
|
alpha: 0.3,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
minimumSize: const Size(50, 40),
|
||||||
|
elevation: 0,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
child: SvgPicture.asset(
|
||||||
child: SvgPicture.asset(
|
Assets.backButtonIcon,
|
||||||
Assets.backButtonIcon,
|
height: 15,
|
||||||
height: 15,
|
),
|
||||||
),
|
onPressed: () {
|
||||||
onPressed: () {
|
pageController.jumpToPage(1);
|
||||||
pageController.jumpToPage(1);
|
}),
|
||||||
}),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
),
|
),
|
||||||
|
@ -1,32 +1,42 @@
|
|||||||
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:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart';
|
|
||||||
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/blocs/setup_bookable_spaces_bloc/setup_bookable_spaces_bloc.dart';
|
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/blocs/setup_bookable_spaces_bloc/setup_bookable_spaces_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/blocs/steps_cubit/cubit/steps_cubit.dart';
|
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/blocs/steps_cubit/cubit/steps_cubit.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/widgets/buttons_divider_bottom_dialog_widget.dart';
|
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/widgets/buttons_divider_bottom_dialog_widget.dart';
|
||||||
|
|
||||||
class NextFirstStepButton extends StatelessWidget {
|
class NextFirstStepButton extends StatelessWidget {
|
||||||
final List<BookableSpacemodel> selectedSpaces;
|
|
||||||
|
|
||||||
const NextFirstStepButton({
|
const NextFirstStepButton({
|
||||||
super.key,
|
super.key,
|
||||||
required this.selectedSpaces,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ButtonsDividerBottomDialogWidget(
|
return BlocBuilder<SetupBookableSpacesBloc, SetupBookableSpacesState>(
|
||||||
title: 'Next',
|
builder: (context, state) {
|
||||||
onNextPressed: selectedSpaces.isEmpty
|
return switch (state) {
|
||||||
? null
|
SetupBookableSpacesInitial() => ButtonsDividerBottomDialogWidget(
|
||||||
: () {
|
title: 'Next',
|
||||||
context.read<StepsCubit>().goToNextStep();
|
onNextPressed: null,
|
||||||
context
|
onCancelPressed: () => context.pop(),
|
||||||
.read<SetupBookableSpacesBloc>()
|
),
|
||||||
.add(CheckConfigurValidityEvent());
|
AddNonBookableSpaceIntoBookableState(:final bookableSpaces) ||
|
||||||
},
|
RemoveBookableSpaceIntoNonBookableState(:final bookableSpaces) =>
|
||||||
onCancelPressed: () => context.pop(),
|
ButtonsDividerBottomDialogWidget(
|
||||||
|
title: 'Next',
|
||||||
|
onNextPressed: bookableSpaces.isEmpty
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
context.read<StepsCubit>().goToNextStep();
|
||||||
|
context.read<SetupBookableSpacesBloc>().add(
|
||||||
|
CheckConfigurValidityEvent(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onCancelPressed: () => context.pop(),
|
||||||
|
),
|
||||||
|
_ => const SizedBox(),
|
||||||
|
};
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,14 @@ import 'package:syncrow_web/utils/color_manager.dart';
|
|||||||
|
|
||||||
class PointsPartWidget extends StatefulWidget {
|
class PointsPartWidget extends StatefulWidget {
|
||||||
final BookableSpacemodel? editingBookableSpace;
|
final BookableSpacemodel? editingBookableSpace;
|
||||||
|
final TextEditingController pointsController;
|
||||||
|
|
||||||
const PointsPartWidget({
|
const PointsPartWidget({
|
||||||
super.key,
|
super.key,
|
||||||
required this.pointsController,
|
required this.pointsController,
|
||||||
this.editingBookableSpace,
|
this.editingBookableSpace,
|
||||||
});
|
});
|
||||||
|
|
||||||
final TextEditingController pointsController;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<PointsPartWidget> createState() => _PointsPartWidgetState();
|
State<PointsPartWidget> createState() => _PointsPartWidgetState();
|
||||||
}
|
}
|
||||||
@ -24,26 +24,28 @@ class PointsPartWidget extends StatefulWidget {
|
|||||||
class _PointsPartWidgetState extends State<PointsPartWidget> {
|
class _PointsPartWidgetState extends State<PointsPartWidget> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
if (widget.editingBookableSpace != null) {
|
if (widget.editingBookableSpace != null) {
|
||||||
widget.pointsController.text =
|
widget.pointsController.text =
|
||||||
widget.editingBookableSpace!.spaceConfig!.cost.toString();
|
widget.editingBookableSpace!.spaceConfig!.cost.toString();
|
||||||
}
|
}
|
||||||
super.initState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<TogglePointsSwitchCubit, TogglePointsSwitchState>(
|
return BlocBuilder<TogglePointsSwitchCubit, TogglePointsSwitchState>(
|
||||||
builder: (context, state) {
|
builder: (context, switchState) {
|
||||||
|
final isSwitchOn = switchState is ActivatePointsSwitch;
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
if (state is ActivatePointsSwitch)
|
if (isSwitchOn)
|
||||||
Text(
|
Text(
|
||||||
'* ',
|
'* ',
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
@ -52,87 +54,59 @@ class _PointsPartWidgetState extends State<PointsPartWidget> {
|
|||||||
.copyWith(color: Colors.red),
|
.copyWith(color: Colors.red),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
const SizedBox(
|
const SizedBox(width: 11),
|
||||||
width: 11,
|
|
||||||
),
|
|
||||||
const Text('Points/hrs'),
|
const Text('Points/hrs'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Transform.scale(
|
Transform.scale(
|
||||||
scale: 0.7,
|
scale: 0.7,
|
||||||
child: Switch(
|
child: Switch(
|
||||||
trackOutlineColor: WidgetStateProperty.resolveWith<Color>(
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
(Set<WidgetState> states) {
|
trackOutlineColor: WidgetStateProperty.all(ColorsManager.white),
|
||||||
return ColorsManager.whiteColors;
|
activeTrackColor: ColorsManager.dialogBlueTitle,
|
||||||
}),
|
inactiveTrackColor: ColorsManager.lightGrayBorderColor,
|
||||||
activeTrackColor: ColorsManager.blueColor,
|
thumbColor: WidgetStateProperty.all(ColorsManager.white),
|
||||||
inactiveTrackColor: ColorsManager.grayBorder,
|
value: isSwitchOn,
|
||||||
thumbColor: WidgetStateProperty.resolveWith<Color>(
|
|
||||||
(Set<WidgetState> states) {
|
|
||||||
return ColorsManager.whiteColors;
|
|
||||||
}),
|
|
||||||
value: state is ActivatePointsSwitch,
|
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
|
final toggleCubit = context.read<TogglePointsSwitchCubit>();
|
||||||
final bloc = context.read<SetupBookableSpacesBloc>();
|
final bloc = context.read<SetupBookableSpacesBloc>();
|
||||||
|
|
||||||
final updatedCost = value ? -1 : 0;
|
final updatedCost = value ? -1 : 0;
|
||||||
|
|
||||||
final switchCubit =
|
|
||||||
context.read<TogglePointsSwitchCubit>();
|
|
||||||
if (value) {
|
if (value) {
|
||||||
switchCubit.activateSwitch();
|
toggleCubit.activateSwitch();
|
||||||
} else {
|
} else {
|
||||||
switchCubit.unActivateSwitch();
|
toggleCubit.unActivateSwitch();
|
||||||
widget.pointsController.clear();
|
widget.pointsController.clear();
|
||||||
}
|
}
|
||||||
|
bloc.add(ChangeCostEvent(cost: updatedCost));
|
||||||
for (int i = 0;
|
|
||||||
i < bloc.selectedBookableSpaces.length;
|
|
||||||
i++) {
|
|
||||||
final space = bloc.selectedBookableSpaces[i];
|
|
||||||
final updatedConfig =
|
|
||||||
space.spaceConfig?.copyWith(cost: updatedCost);
|
|
||||||
final updatedSpace =
|
|
||||||
space.copyWith(spaceConfig: updatedConfig);
|
|
||||||
|
|
||||||
bloc.selectedBookableSpaces[i] = updatedSpace;
|
|
||||||
}
|
|
||||||
|
|
||||||
bloc.add(CheckConfigurValidityEvent());
|
bloc.add(CheckConfigurValidityEvent());
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(height: 5),
|
||||||
height: 5,
|
if (isSwitchOn)
|
||||||
),
|
|
||||||
if (state is ActivatePointsSwitch)
|
|
||||||
SearchUnbookableSpacesWidget(
|
SearchUnbookableSpacesWidget(
|
||||||
title: 'Ex: 0',
|
title: 'Ex: 0',
|
||||||
height: 40,
|
topPadding: 0,
|
||||||
onChanged: (p0) {
|
blur: 1,
|
||||||
|
raduis: 10,
|
||||||
|
height: 34,
|
||||||
|
controller: widget.pointsController,
|
||||||
|
suffix: const SizedBox(),
|
||||||
|
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||||
|
onChanged: (_) {
|
||||||
final updatedCost =
|
final updatedCost =
|
||||||
int.tryParse(widget.pointsController.text) ?? 0;
|
int.tryParse(widget.pointsController.text) ?? 0;
|
||||||
|
|
||||||
final bloc = context.read<SetupBookableSpacesBloc>();
|
|
||||||
|
|
||||||
for (var i = 0; i < bloc.selectedBookableSpaces.length; i++) {
|
|
||||||
final space = bloc.selectedBookableSpaces[i];
|
|
||||||
final updatedConfig =
|
|
||||||
space.spaceConfig?.copyWith(cost: updatedCost);
|
|
||||||
final updatedSpace =
|
|
||||||
space.copyWith(spaceConfig: updatedConfig);
|
|
||||||
|
|
||||||
bloc.selectedBookableSpaces[i] = updatedSpace;
|
|
||||||
}
|
|
||||||
|
|
||||||
context
|
context
|
||||||
.read<SetupBookableSpacesBloc>()
|
.read<SetupBookableSpacesBloc>()
|
||||||
.add(CheckConfigurValidityEvent());
|
.add(ChangeCostEvent(cost: updatedCost));
|
||||||
|
context.read<SetupBookableSpacesBloc>().add(
|
||||||
|
CheckConfigurValidityEvent(),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
controller: widget.pointsController,
|
|
||||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
|
||||||
suffix: const SizedBox(),
|
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
const SizedBox(),
|
const SizedBox(),
|
||||||
|
@ -10,68 +10,68 @@ import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/prese
|
|||||||
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/widgets/buttons_divider_bottom_dialog_widget.dart';
|
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/widgets/buttons_divider_bottom_dialog_widget.dart';
|
||||||
|
|
||||||
class SaveSecondStepButton extends StatelessWidget {
|
class SaveSecondStepButton extends StatelessWidget {
|
||||||
final List<BookableSpacemodel> selectedSpaces;
|
|
||||||
final TextEditingController pointsController;
|
final TextEditingController pointsController;
|
||||||
final bool isEditingMode;
|
final bool isEditingMode;
|
||||||
|
final List<BookableSpacemodel> bookableSpaces;
|
||||||
|
|
||||||
const SaveSecondStepButton({
|
const SaveSecondStepButton({
|
||||||
super.key,
|
super.key,
|
||||||
required this.selectedSpaces,
|
|
||||||
required this.pointsController,
|
required this.pointsController,
|
||||||
required this.isEditingMode,
|
required this.isEditingMode,
|
||||||
|
required this.bookableSpaces,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocConsumer<SendBookableSpacesBloc, SendBookableSpacesState>(
|
return BlocListener<SendBookableSpacesBloc, SendBookableSpacesState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state is SendBookableSpacesSuccess) {
|
if (state is SendBookableSpacesSuccess) {
|
||||||
context.read<NonBookableSpacesBloc>().add(CallInitStateEvent());
|
context.read<NonBookableSpacesBloc>().add(CallInitStateEvent());
|
||||||
} else if (state is SendBookableSpacesError) {
|
} else if (state is SendBookableSpacesError) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(content: Text(state.error)),
|
||||||
content: Text(state.error),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
builder: (context, state) {
|
child: BlocBuilder<SetupBookableSpacesBloc, SetupBookableSpacesState>(
|
||||||
return ButtonsDividerBottomDialogWidget(
|
builder: (context, state) {
|
||||||
title: 'Save',
|
return ButtonsDividerBottomDialogWidget(
|
||||||
onNextPressed: state is UnValidSaveButtonState
|
title: 'Save',
|
||||||
? null
|
onNextPressed: state is UnValidSaveButtonState
|
||||||
: () {
|
? null
|
||||||
if (selectedSpaces.any(
|
: () {
|
||||||
(element) => element.isValid,
|
if (bookableSpaces.any((e) => e.isValid)) {
|
||||||
)) {
|
if (isEditingMode) {
|
||||||
isEditingMode
|
callEditLogic(context);
|
||||||
? callEditLogic(context)
|
} else {
|
||||||
: context.read<SendBookableSpacesBloc>().add(
|
context.read<SendBookableSpacesBloc>().add(
|
||||||
SendBookableSpacesToApi(
|
SendBookableSpacesToApi(
|
||||||
selectedBookableSpaces: context
|
selectedBookableSpaces: bookableSpaces,
|
||||||
.read<SetupBookableSpacesBloc>()
|
),
|
||||||
.selectedBookableSpaces),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
onCancelPressed: () => context.pop(),
|
},
|
||||||
);
|
onCancelPressed: () => context.pop(),
|
||||||
},
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void callEditLogic(BuildContext context) {
|
void callEditLogic(BuildContext context) {
|
||||||
context.read<UpdateBookableSpacesBloc>().add(
|
print(bookableSpaces.first.spaceConfig!.cost);
|
||||||
UpdateBookableSpace(
|
if (bookableSpaces.isNotEmpty) {
|
||||||
onSuccess: () =>
|
context.read<UpdateBookableSpacesBloc>().add(
|
||||||
context.read<NonBookableSpacesBloc>().add(CallInitStateEvent()),
|
UpdateBookableSpace(
|
||||||
updatedParam: UpdateBookableSpaceParam.fromBookableModel(
|
onSuccess: () => context
|
||||||
context
|
.read<NonBookableSpacesBloc>()
|
||||||
.read<SetupBookableSpacesBloc>()
|
.add(CallInitStateEvent()),
|
||||||
.selectedBookableSpaces
|
updatedParam: UpdateBookableSpaceParam.fromBookableModel(
|
||||||
.first,
|
bookableSpaces.first,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,30 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
|
||||||
class SearchUnbookableSpacesWidget extends StatelessWidget {
|
class SearchUnbookableSpacesWidget extends StatelessWidget {
|
||||||
final String title;
|
final String title;
|
||||||
final Widget? suffix;
|
final Widget? suffix;
|
||||||
final double? height;
|
final double? height;
|
||||||
final double? width;
|
final double? width;
|
||||||
|
final double? blur;
|
||||||
|
final double? raduis;
|
||||||
|
final double? topPadding;
|
||||||
final TextEditingController? controller;
|
final TextEditingController? controller;
|
||||||
final List<TextInputFormatter>? inputFormatters;
|
final List<TextInputFormatter>? inputFormatters;
|
||||||
final void Function(String)? onChanged;
|
final void Function(String)? onChanged;
|
||||||
const SearchUnbookableSpacesWidget({
|
const SearchUnbookableSpacesWidget({
|
||||||
required this.title,
|
required this.title,
|
||||||
this.controller,
|
this.controller,
|
||||||
|
this.blur,
|
||||||
this.onChanged,
|
this.onChanged,
|
||||||
this.suffix,
|
this.suffix,
|
||||||
this.height,
|
this.height,
|
||||||
this.width,
|
this.width,
|
||||||
|
this.topPadding,
|
||||||
|
this.raduis,
|
||||||
this.inputFormatters,
|
this.inputFormatters,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
@ -25,16 +33,17 @@ class SearchUnbookableSpacesWidget extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
width: width ?? 480,
|
width: width ?? 480,
|
||||||
height: height ?? 30,
|
height: height ?? 40,
|
||||||
padding: const EdgeInsets.only(top: 4),
|
padding: const EdgeInsets.only(top: 4),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(raduis ?? 15),
|
||||||
boxShadow: const [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: ColorsManager.shadowOfSearchTextfield,
|
color: ColorsManager.shadowOfSearchTextfield.withValues(alpha: 0.15),
|
||||||
offset: Offset(0, 4),
|
offset: Offset.zero,
|
||||||
blurRadius: 5,
|
blurRadius: blur ?? 5,
|
||||||
|
spreadRadius: 0,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -43,14 +52,21 @@ class SearchUnbookableSpacesWidget extends StatelessWidget {
|
|||||||
inputFormatters: inputFormatters,
|
inputFormatters: inputFormatters,
|
||||||
onChanged: onChanged,
|
onChanged: onChanged,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
contentPadding:
|
contentPadding: EdgeInsets.symmetric(
|
||||||
const EdgeInsets.symmetric(vertical: 5, horizontal: 15),
|
vertical: topPadding ?? 5,
|
||||||
|
horizontal: 15,
|
||||||
|
),
|
||||||
hintText: title,
|
hintText: title,
|
||||||
hintStyle: const TextStyle(color: ColorsManager.hintTextGrey),
|
hintStyle: const TextStyle(color: ColorsManager.hintTextGrey),
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
suffixIcon: suffix ??
|
suffixIcon: Padding(
|
||||||
const Icon(Icons.search,
|
padding: const EdgeInsets.all(10),
|
||||||
size: 20, color: ColorsManager.hintTextGrey),
|
child: suffix ??
|
||||||
|
SvgPicture.asset(
|
||||||
|
Assets.searchIcon,
|
||||||
|
height: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
|
@ -26,7 +26,7 @@ class StepTwoDetailsWidget extends StatelessWidget {
|
|||||||
editingBookableSpace: editingBookableSpace,
|
editingBookableSpace: editingBookableSpace,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 20,
|
height: 30,
|
||||||
),
|
),
|
||||||
BookingPeriodWidget(
|
BookingPeriodWidget(
|
||||||
editingBookableSpace: editingBookableSpace,
|
editingBookableSpace: editingBookableSpace,
|
||||||
|
@ -26,14 +26,14 @@ class StepperPartWidget extends StatelessWidget {
|
|||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.only(left: 3),
|
padding: const EdgeInsets.only(left: 3),
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
height: 50,
|
height: 40,
|
||||||
child: const VerticalDivider(
|
child: const VerticalDivider(
|
||||||
width: 8,
|
width: 8,
|
||||||
)),
|
)),
|
||||||
const CircleTitleStepperWidget(
|
const CircleTitleStepperWidget(
|
||||||
title: 'Settings',
|
title: 'Settings',
|
||||||
titleColor: ColorsManager.softGray,
|
titleColor: ColorsManager.softGray,
|
||||||
circleColor: ColorsManager.whiteColors,
|
circleColor: ColorsManager.white,
|
||||||
borderColor: ColorsManager.textGray,
|
borderColor: ColorsManager.textGray,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@ -49,7 +49,7 @@ class StepperPartWidget extends StatelessWidget {
|
|||||||
titleColor: ColorsManager.softGray,
|
titleColor: ColorsManager.softGray,
|
||||||
cicleIcon: Icon(
|
cicleIcon: Icon(
|
||||||
Icons.check,
|
Icons.check,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
size: 12,
|
size: 12,
|
||||||
),
|
),
|
||||||
circleColor: ColorsManager.trueIconGreen,
|
circleColor: ColorsManager.trueIconGreen,
|
||||||
@ -59,7 +59,7 @@ class StepperPartWidget extends StatelessWidget {
|
|||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.only(left: 3),
|
padding: const EdgeInsets.only(left: 3),
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
height: 50,
|
height: 40,
|
||||||
child: const VerticalDivider(
|
child: const VerticalDivider(
|
||||||
width: 8,
|
width: 8,
|
||||||
)),
|
)),
|
||||||
|
@ -12,7 +12,7 @@ class TimePickerWidget extends StatefulWidget {
|
|||||||
required this.onTimePicked,
|
required this.onTimePicked,
|
||||||
required this.title,
|
required this.title,
|
||||||
});
|
});
|
||||||
late SetupBookableSpacesBloc setupBookableSpacesBloc;
|
late final SetupBookableSpacesBloc setupBookableSpacesBloc;
|
||||||
final void Function(TimeOfDay? timePicked) onTimePicked;
|
final void Function(TimeOfDay? timePicked) onTimePicked;
|
||||||
@override
|
@override
|
||||||
State<TimePickerWidget> createState() => _TimePickerWidgetState();
|
State<TimePickerWidget> createState() => _TimePickerWidgetState();
|
||||||
@ -47,13 +47,17 @@ class _TimePickerWidgetState extends State<TimePickerWidget> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (tempTime == null) return;
|
||||||
|
|
||||||
widget.onTimePicked(tempTime);
|
widget.onTimePicked(tempTime);
|
||||||
timePicked = tempTime;
|
timePicked = tempTime;
|
||||||
|
|
||||||
widget.setupBookableSpacesBloc.add(CheckConfigurValidityEvent());
|
widget.setupBookableSpacesBloc.add(CheckConfigurValidityEvent());
|
||||||
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
width: 100,
|
|
||||||
height: 32,
|
height: 32,
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
|
@ -36,9 +36,7 @@ class UnbookableListWidget extends StatelessWidget {
|
|||||||
if (index < nonBookableSpaces.data.length) {
|
if (index < nonBookableSpaces.data.length) {
|
||||||
return CheckBoxSpaceWidget(
|
return CheckBoxSpaceWidget(
|
||||||
nonBookableSpace: nonBookableSpaces.data[index],
|
nonBookableSpace: nonBookableSpaces.data[index],
|
||||||
selectedSpaces: context
|
|
||||||
.read<SetupBookableSpacesBloc>()
|
|
||||||
.selectedBookableSpaces,
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return const Padding(
|
return const Padding(
|
||||||
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart';
|
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/blocs/setup_bookable_spaces_bloc/setup_bookable_spaces_bloc.dart';
|
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/blocs/setup_bookable_spaces_bloc/setup_bookable_spaces_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/widgets/custom_checkbox_widget.dart';
|
||||||
|
|
||||||
class WeekDaysCheckboxRow extends StatefulWidget {
|
class WeekDaysCheckboxRow extends StatefulWidget {
|
||||||
final BookableSpacemodel? editingBookableSpace;
|
final BookableSpacemodel? editingBookableSpace;
|
||||||
@ -24,6 +25,7 @@ class _WeekDaysCheckboxRowState extends State<WeekDaysCheckboxRow> {
|
|||||||
'Sat': false,
|
'Sat': false,
|
||||||
'Sun': false,
|
'Sun': false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@ -40,52 +42,66 @@ class _WeekDaysCheckboxRowState extends State<WeekDaysCheckboxRow> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Row(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: _daysChecked.entries.map((entry) {
|
children: [
|
||||||
return Expanded(
|
Row(
|
||||||
child: Row(
|
children: [
|
||||||
children: [
|
Text(
|
||||||
Expanded(
|
'* ',
|
||||||
child: Checkbox(
|
style: Theme.of(context)
|
||||||
value: entry.value,
|
.textTheme
|
||||||
onChanged: (newValue) {
|
.bodyMedium!
|
||||||
setState(() {
|
.copyWith(color: Colors.red),
|
||||||
_daysChecked[entry.key] = newValue ?? false;
|
),
|
||||||
});
|
const Text('Days'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: _daysChecked.entries.map((entry) {
|
||||||
|
return Expanded(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
CustomCheckboxWidget(
|
||||||
|
outHeight: 16,
|
||||||
|
outWidth: 16,
|
||||||
|
value: entry.value,
|
||||||
|
onChanged: (newValue) {
|
||||||
|
setState(() {
|
||||||
|
_daysChecked[entry.key] = newValue ?? false;
|
||||||
|
});
|
||||||
|
|
||||||
final selectedDays = _daysChecked.entries
|
final selectedDays = _daysChecked.entries
|
||||||
.where((e) => e.value)
|
.where((e) => e.value)
|
||||||
.map((e) => e.key)
|
.map((e) => e.key)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
final bloc = context.read<SetupBookableSpacesBloc>();
|
context.read<SetupBookableSpacesBloc>().add(
|
||||||
|
AddBookableDaysEvent(bookableDays: selectedDays),
|
||||||
for (int i = 0;
|
);
|
||||||
i < bloc.selectedBookableSpaces.length;
|
context.read<SetupBookableSpacesBloc>().add(
|
||||||
i++) {
|
CheckConfigurValidityEvent(),
|
||||||
final space = bloc.selectedBookableSpaces[i];
|
);
|
||||||
final updatedConfig = space.spaceConfig
|
},
|
||||||
?.copyWith(bookableDays: selectedDays);
|
),
|
||||||
final updatedSpace =
|
const SizedBox(width: 8),
|
||||||
space.copyWith(spaceConfig: updatedConfig);
|
Expanded(
|
||||||
|
child: Text(
|
||||||
bloc.selectedBookableSpaces[i] = updatedSpace;
|
entry.key,
|
||||||
}
|
style: const TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
bloc.add(CheckConfigurValidityEvent());
|
fontWeight: FontWeight.w400,
|
||||||
},
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
Expanded(
|
);
|
||||||
child: Text(
|
}).toList(),
|
||||||
entry.key,
|
),
|
||||||
style: const TextStyle(fontSize: 10),
|
],
|
||||||
)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,8 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/bloc/access_bloc.dart';
|
import 'package:syncrow_web/pages/access_management/bloc/access_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/bloc/access_event.dart';
|
import 'package:syncrow_web/pages/access_management/bloc/access_event.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/booking_system/view/booking_page.dart';
|
|
||||||
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/screens/manage_bookable_spaces_screen.dart';
|
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/screens/manage_bookable_spaces_screen.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/booking_system/presentation/view/booking_page.dart' hide BookingPage;
|
import 'package:syncrow_web/pages/access_management/booking_system/presentation/view/booking_page.dart';
|
||||||
import 'package:syncrow_web/pages/access_management/view/access_overview_content.dart';
|
import 'package:syncrow_web/pages/access_management/view/access_overview_content.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
|
@ -104,7 +104,7 @@ abstract final class RangeOfAqiChartsHelper {
|
|||||||
) {
|
) {
|
||||||
return LineTouchData(
|
return LineTouchData(
|
||||||
touchTooltipData: LineTouchTooltipData(
|
touchTooltipData: LineTouchTooltipData(
|
||||||
getTooltipColor: (touchTooltipItem) => ColorsManager.whiteColors,
|
getTooltipColor: (touchTooltipItem) => ColorsManager.white,
|
||||||
tooltipBorder: const BorderSide(
|
tooltipBorder: const BorderSide(
|
||||||
color: ColorsManager.semiTransparentBlack,
|
color: ColorsManager.semiTransparentBlack,
|
||||||
),
|
),
|
||||||
|
@ -77,7 +77,7 @@ class AqiDistributionChart extends StatelessWidget {
|
|||||||
BarTouchData _barTouchData(BuildContext context) {
|
BarTouchData _barTouchData(BuildContext context) {
|
||||||
return BarTouchData(
|
return BarTouchData(
|
||||||
touchTooltipData: BarTouchTooltipData(
|
touchTooltipData: BarTouchTooltipData(
|
||||||
getTooltipColor: (_) => ColorsManager.whiteColors,
|
getTooltipColor: (_) => ColorsManager.white,
|
||||||
tooltipBorder: const BorderSide(
|
tooltipBorder: const BorderSide(
|
||||||
color: ColorsManager.semiTransparentBlack,
|
color: ColorsManager.semiTransparentBlack,
|
||||||
),
|
),
|
||||||
|
@ -65,7 +65,7 @@ class AqiGauge extends StatelessWidget {
|
|||||||
pointer: GaugePointer.circle(
|
pointer: GaugePointer.circle(
|
||||||
position: const GaugePointerPosition.surface(),
|
position: const GaugePointerPosition.surface(),
|
||||||
radius: MediaQuery.sizeOf(context).width * 0.004,
|
radius: MediaQuery.sizeOf(context).width * 0.004,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
border: GaugePointerBorder(
|
border: GaugePointerBorder(
|
||||||
width: 6,
|
width: 6,
|
||||||
color: statusColor,
|
color: statusColor,
|
||||||
|
@ -20,7 +20,7 @@ class AqiLocationInfoCell extends StatelessWidget {
|
|||||||
return Expanded(
|
return Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
|
@ -62,7 +62,7 @@ class AqiSubValueWidget extends StatelessWidget {
|
|||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsetsDirectional.all(10),
|
padding: const EdgeInsetsDirectional.all(10),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
@ -46,7 +46,7 @@ class _AqiTypeDropdownState extends State<AqiTypeDropdown> {
|
|||||||
value: widget.selectedAqiType,
|
value: widget.selectedAqiType,
|
||||||
isDense: true,
|
isDense: true,
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
dropdownColor: ColorsManager.whiteColors,
|
dropdownColor: ColorsManager.white,
|
||||||
underline: const SizedBox.shrink(),
|
underline: const SizedBox.shrink(),
|
||||||
icon: const RotatedBox(
|
icon: const RotatedBox(
|
||||||
quarterTurns: 1,
|
quarterTurns: 1,
|
||||||
|
@ -107,7 +107,7 @@ class RangeOfAqiChart extends StatelessWidget {
|
|||||||
show: true,
|
show: true,
|
||||||
getDotPainter: (_, __, ___, ____) => FlDotCirclePainter(
|
getDotPainter: (_, __, ___, ____) => FlDotCirclePainter(
|
||||||
radius: 2,
|
radius: 2,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
strokeWidth: 2,
|
strokeWidth: 2,
|
||||||
strokeColor: color,
|
strokeColor: color,
|
||||||
),
|
),
|
||||||
|
@ -45,7 +45,7 @@ class _MonthPickerWidgetState extends State<MonthPickerWidget> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Dialog(
|
return Dialog(
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
backgroundColor: ColorsManager.white,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsetsDirectional.all(20),
|
padding: const EdgeInsetsDirectional.all(20),
|
||||||
width: 320,
|
width: 320,
|
||||||
@ -108,7 +108,7 @@ class _MonthPickerWidgetState extends State<MonthPickerWidget> {
|
|||||||
style: context.textTheme.titleSmall?.copyWith(
|
style: context.textTheme.titleSmall?.copyWith(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -217,7 +217,7 @@ class _MonthPickerWidgetState extends State<MonthPickerWidget> {
|
|||||||
style: context.textTheme.titleSmall?.copyWith(
|
style: context.textTheme.titleSmall?.copyWith(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: isSelected
|
color: isSelected
|
||||||
? ColorsManager.whiteColors
|
? ColorsManager.white
|
||||||
: isFutureMonth
|
: isFutureMonth
|
||||||
? ColorsManager.blackColor.withValues(alpha: 0.3)
|
? ColorsManager.blackColor.withValues(alpha: 0.3)
|
||||||
: ColorsManager.blackColor.withValues(alpha: 0.8),
|
: ColorsManager.blackColor.withValues(alpha: 0.8),
|
||||||
|
@ -59,7 +59,7 @@ class _AnalyticsSpaceTreeViewState extends State<AnalyticsSpaceTreeView> {
|
|||||||
: state.communityList;
|
: state.communityList;
|
||||||
return Container(
|
return Container(
|
||||||
height: MediaQuery.sizeOf(context).height,
|
height: MediaQuery.sizeOf(context).height,
|
||||||
decoration: const BoxDecoration(color: ColorsManager.whiteColors),
|
decoration: const BoxDecoration(color: ColorsManager.white),
|
||||||
child: state is SpaceTreeLoadingState
|
child: state is SpaceTreeLoadingState
|
||||||
? const Center(child: CircularProgressIndicator())
|
? const Center(child: CircularProgressIndicator())
|
||||||
: Column(
|
: Column(
|
||||||
|
@ -33,7 +33,7 @@ class _YearPickerWidgetState extends State<YearPickerWidget> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Dialog(
|
return Dialog(
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
backgroundColor: ColorsManager.white,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsetsDirectional.all(20),
|
padding: const EdgeInsetsDirectional.all(20),
|
||||||
width: 320,
|
width: 320,
|
||||||
@ -92,7 +92,7 @@ class _YearPickerWidgetState extends State<YearPickerWidget> {
|
|||||||
style: context.textTheme.titleSmall?.copyWith(
|
style: context.textTheme.titleSmall?.copyWith(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -144,7 +144,7 @@ class _YearPickerWidgetState extends State<YearPickerWidget> {
|
|||||||
style: context.textTheme.titleSmall?.copyWith(
|
style: context.textTheme.titleSmall?.copyWith(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: isSelected
|
color: isSelected
|
||||||
? ColorsManager.whiteColors
|
? ColorsManager.white
|
||||||
: ColorsManager.blackColor.withValues(alpha: 0.8),
|
: ColorsManager.blackColor.withValues(alpha: 0.8),
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
|
@ -81,7 +81,7 @@ abstract final class EnergyManagementChartsHelper {
|
|||||||
|
|
||||||
static LineTouchTooltipData lineTouchTooltipData() {
|
static LineTouchTooltipData lineTouchTooltipData() {
|
||||||
return LineTouchTooltipData(
|
return LineTouchTooltipData(
|
||||||
getTooltipColor: (touchTooltipItem) => ColorsManager.whiteColors,
|
getTooltipColor: (touchTooltipItem) => ColorsManager.white,
|
||||||
tooltipBorder: const BorderSide(color: ColorsManager.semiTransparentBlack),
|
tooltipBorder: const BorderSide(color: ColorsManager.semiTransparentBlack),
|
||||||
tooltipRoundedRadius: 16,
|
tooltipRoundedRadius: 16,
|
||||||
showOnTopOfTheChartBoxArea: false,
|
showOnTopOfTheChartBoxArea: false,
|
||||||
|
@ -72,7 +72,7 @@ class AnalyticsDeviceDropdown extends StatelessWidget {
|
|||||||
value: state.selectedDevice,
|
value: state.selectedDevice,
|
||||||
isDense: true,
|
isDense: true,
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
dropdownColor: ColorsManager.whiteColors,
|
dropdownColor: ColorsManager.white,
|
||||||
underline: const SizedBox.shrink(),
|
underline: const SizedBox.shrink(),
|
||||||
icon: const RotatedBox(
|
icon: const RotatedBox(
|
||||||
quarterTurns: 1,
|
quarterTurns: 1,
|
||||||
|
@ -18,7 +18,6 @@ class EnergyConsumptionByPhasesChart extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BarChart(
|
return BarChart(
|
||||||
BarChartData(
|
BarChartData(
|
||||||
|
|
||||||
gridData: EnergyManagementChartsHelper.gridData().copyWith(
|
gridData: EnergyManagementChartsHelper.gridData().copyWith(
|
||||||
checkToShowHorizontalLine: (value) => true,
|
checkToShowHorizontalLine: (value) => true,
|
||||||
horizontalInterval: 250,
|
horizontalInterval: 250,
|
||||||
@ -74,7 +73,7 @@ class EnergyConsumptionByPhasesChart extends StatelessWidget {
|
|||||||
BarTouchData _barTouchData(BuildContext context) {
|
BarTouchData _barTouchData(BuildContext context) {
|
||||||
return BarTouchData(
|
return BarTouchData(
|
||||||
touchTooltipData: BarTouchTooltipData(
|
touchTooltipData: BarTouchTooltipData(
|
||||||
getTooltipColor: (touchTooltipItem) => ColorsManager.whiteColors,
|
getTooltipColor: (touchTooltipItem) => ColorsManager.white,
|
||||||
tooltipBorder: const BorderSide(
|
tooltipBorder: const BorderSide(
|
||||||
color: ColorsManager.semiTransparentBlack,
|
color: ColorsManager.semiTransparentBlack,
|
||||||
),
|
),
|
||||||
|
@ -34,7 +34,7 @@ class HeatMapTooltip extends StatelessWidget {
|
|||||||
style: context.textTheme.bodySmall?.copyWith(
|
style: context.textTheme.bodySmall?.copyWith(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Divider(height: 2, thickness: 1),
|
const Divider(height: 2, thickness: 1),
|
||||||
@ -43,7 +43,7 @@ class HeatMapTooltip extends StatelessWidget {
|
|||||||
style: context.textTheme.bodySmall?.copyWith(
|
style: context.textTheme.bodySmall?.copyWith(
|
||||||
fontSize: 10,
|
fontSize: 10,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -64,7 +64,7 @@ class OccupancyChart extends StatelessWidget {
|
|||||||
BarTouchData _barTouchData(BuildContext context) {
|
BarTouchData _barTouchData(BuildContext context) {
|
||||||
return BarTouchData(
|
return BarTouchData(
|
||||||
touchTooltipData: BarTouchTooltipData(
|
touchTooltipData: BarTouchTooltipData(
|
||||||
getTooltipColor: (touchTooltipItem) => ColorsManager.whiteColors,
|
getTooltipColor: (touchTooltipItem) => ColorsManager.white,
|
||||||
tooltipBorder: const BorderSide(
|
tooltipBorder: const BorderSide(
|
||||||
color: ColorsManager.semiTransparentBlack,
|
color: ColorsManager.semiTransparentBlack,
|
||||||
),
|
),
|
||||||
|
@ -121,7 +121,8 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
|
|||||||
const Spacer(),
|
const Spacer(),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 2,
|
flex: 2,
|
||||||
child: _buildLoginFormFields(context, loginBloc, size),
|
child:
|
||||||
|
_buildLoginFormFields(context, loginBloc, size),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
],
|
],
|
||||||
@ -147,8 +148,8 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
|
|||||||
child: Form(
|
child: Form(
|
||||||
key: loginBloc.loginFormKey,
|
key: loginBloc.loginFormKey,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding:
|
padding: EdgeInsets.symmetric(
|
||||||
EdgeInsets.symmetric(horizontal: size.width * 0.02, vertical: size.width * 0.003),
|
horizontal: size.width * 0.02, vertical: size.width * 0.003),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@ -303,10 +304,8 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
|
|||||||
decoration: textBoxDecoration()!.copyWith(
|
decoration: textBoxDecoration()!.copyWith(
|
||||||
errorStyle: const TextStyle(height: 0),
|
errorStyle: const TextStyle(height: 0),
|
||||||
hintText: 'Enter your email address',
|
hintText: 'Enter your email address',
|
||||||
hintStyle: Theme.of(context)
|
hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
.textTheme
|
color: ColorsManager.grayColor, fontWeight: FontWeight.w400)),
|
||||||
.bodySmall!
|
|
||||||
.copyWith(color: ColorsManager.grayColor, fontWeight: FontWeight.w400)),
|
|
||||||
style: const TextStyle(color: Colors.black),
|
style: const TextStyle(color: Colors.black),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -338,7 +337,7 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
|
|||||||
controller: loginBloc.loginPasswordController,
|
controller: loginBloc.loginPasswordController,
|
||||||
onFieldSubmitted: (value) {
|
onFieldSubmitted: (value) {
|
||||||
if (loginBloc.loginFormKey.currentState!.validate()) {
|
if (loginBloc.loginFormKey.currentState!.validate()) {
|
||||||
loginBloc.add(LoginButtonPressed(
|
loginBloc.add(LoginButtonPressed(
|
||||||
username: loginBloc.loginEmailController.text,
|
username: loginBloc.loginEmailController.text,
|
||||||
password: value,
|
password: value,
|
||||||
));
|
));
|
||||||
@ -348,17 +347,18 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
|
|||||||
},
|
},
|
||||||
decoration: textBoxDecoration()!.copyWith(
|
decoration: textBoxDecoration()!.copyWith(
|
||||||
hintText: 'At least 8 characters',
|
hintText: 'At least 8 characters',
|
||||||
hintStyle: Theme.of(context)
|
hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
.textTheme
|
color: ColorsManager.grayColor, fontWeight: FontWeight.w400),
|
||||||
.bodySmall!
|
|
||||||
.copyWith(color: ColorsManager.grayColor, fontWeight: FontWeight.w400),
|
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
loginBloc.add(PasswordVisibleEvent(newValue: loginBloc.obscureText));
|
loginBloc
|
||||||
|
.add(PasswordVisibleEvent(newValue: loginBloc.obscureText));
|
||||||
},
|
},
|
||||||
icon: SizedBox(
|
icon: SizedBox(
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
loginBloc.obscureText ? Assets.visiblePassword : Assets.invisiblePassword,
|
loginBloc.obscureText
|
||||||
|
? Assets.visiblePassword
|
||||||
|
: Assets.invisiblePassword,
|
||||||
height: 15,
|
height: 15,
|
||||||
width: 15,
|
width: 15,
|
||||||
),
|
),
|
||||||
@ -386,10 +386,8 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
|
|||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
"Forgot Password?",
|
"Forgot Password?",
|
||||||
style: Theme.of(context)
|
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
.textTheme
|
color: Colors.black, fontSize: 14, fontWeight: FontWeight.w400),
|
||||||
.bodySmall!
|
|
||||||
.copyWith(color: Colors.black, fontSize: 14, fontWeight: FontWeight.w400),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -466,8 +464,8 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
|
|||||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: loginBloc.checkValidate
|
color: loginBloc.checkValidate
|
||||||
? ColorsManager.whiteColors
|
? ColorsManager.white
|
||||||
: ColorsManager.whiteColors.withOpacity(0.2),
|
: ColorsManager.white.withOpacity(0.2),
|
||||||
)),
|
)),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (loginBloc.loginFormKey.currentState!.validate()) {
|
if (loginBloc.loginFormKey.currentState!.validate()) {
|
||||||
@ -494,7 +492,8 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
child: Text(
|
child: Text(
|
||||||
loginBloc.validate,
|
loginBloc.validate,
|
||||||
style: const TextStyle(fontWeight: FontWeight.w700, color: ColorsManager.red),
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.w700, color: ColorsManager.red),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
@ -56,7 +56,7 @@ class SearchResetButtons extends StatelessWidget {
|
|||||||
decoration: containerDecoration,
|
decoration: containerDecoration,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: DefaultButton(
|
child: DefaultButton(
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
backgroundColor: ColorsManager.white,
|
||||||
borderRadius: 9,
|
borderRadius: 9,
|
||||||
onPressed: onReset,
|
onPressed: onReset,
|
||||||
child: Text(
|
child: Text(
|
||||||
|
@ -35,7 +35,7 @@ class CurtainToggle extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
ClipOval(
|
ClipOval(
|
||||||
child: Container(
|
child: Container(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.curtainIcon,
|
Assets.curtainIcon,
|
||||||
width: 60,
|
width: 60,
|
||||||
|
@ -127,13 +127,11 @@ class _DynamicTableState extends State<DynamicTable> {
|
|||||||
controller: _horizontalScrollController,
|
controller: _horizontalScrollController,
|
||||||
thumbVisibility: true,
|
thumbVisibility: true,
|
||||||
trackVisibility: true,
|
trackVisibility: true,
|
||||||
notificationPredicate: (notif) =>
|
notificationPredicate: (notif) => notif.metrics.axis == Axis.horizontal,
|
||||||
notif.metrics.axis == Axis.horizontal,
|
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
controller: _horizontalScrollController,
|
controller: _horizontalScrollController,
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
physics:
|
physics: widget.isEmpty ? const NeverScrollableScrollPhysics() : null,
|
||||||
widget.isEmpty ? const NeverScrollableScrollPhysics() : null,
|
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: _totalTableWidth,
|
width: _totalTableWidth,
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -195,29 +193,25 @@ class _DynamicTableState extends State<DynamicTable> {
|
|||||||
widget.headers[colIndex] == 'Settings'
|
widget.headers[colIndex] == 'Settings'
|
||||||
? buildSettingsIcon(
|
? buildSettingsIcon(
|
||||||
width: _settingsColumnWidth,
|
width: _settingsColumnWidth,
|
||||||
onTap: () => widget
|
onTap: () => widget.onSettingsPressed
|
||||||
.onSettingsPressed
|
|
||||||
?.call(rowIndex),
|
?.call(rowIndex),
|
||||||
)
|
)
|
||||||
: _buildTableCell(
|
: _buildTableCell(
|
||||||
row[colIndex].toString(),
|
row[colIndex].toString(),
|
||||||
width: widget.headers[
|
width: widget.headers[colIndex] ==
|
||||||
colIndex] ==
|
|
||||||
'Settings'
|
'Settings'
|
||||||
? _settingsColumnWidth
|
? _settingsColumnWidth
|
||||||
: (_totalTableWidth -
|
: (_totalTableWidth -
|
||||||
(widget.withCheckBox
|
(widget.withCheckBox
|
||||||
? _checkboxColumnWidth
|
? _checkboxColumnWidth
|
||||||
: 0) -
|
: 0) -
|
||||||
(widget.headers
|
(widget.headers.contains(
|
||||||
.contains(
|
'Settings')
|
||||||
'Settings')
|
|
||||||
? _settingsColumnWidth
|
? _settingsColumnWidth
|
||||||
: 0)) /
|
: 0)) /
|
||||||
(widget.headers.length -
|
(widget.headers.length -
|
||||||
(widget.headers
|
(widget.headers.contains(
|
||||||
.contains(
|
'Settings')
|
||||||
'Settings')
|
|
||||||
? 1
|
? 1
|
||||||
: 0)),
|
: 0)),
|
||||||
rowIndex: rowIndex,
|
rowIndex: rowIndex,
|
||||||
@ -241,7 +235,7 @@ class _DynamicTableState extends State<DynamicTable> {
|
|||||||
|
|
||||||
Widget _buildEmptyState() => Container(
|
Widget _buildEmptyState() => Container(
|
||||||
height: widget.size.height,
|
height: widget.size.height,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
@ -281,9 +275,8 @@ class _DynamicTableState extends State<DynamicTable> {
|
|||||||
),
|
),
|
||||||
child: Checkbox(
|
child: Checkbox(
|
||||||
value: _selectAll,
|
value: _selectAll,
|
||||||
onChanged: widget.withSelectAll && widget.data.isNotEmpty
|
onChanged:
|
||||||
? _toggleSelectAll
|
widget.withSelectAll && widget.data.isNotEmpty ? _toggleSelectAll : null,
|
||||||
: null,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -300,7 +293,7 @@ class _DynamicTableState extends State<DynamicTable> {
|
|||||||
width: 1.0,
|
width: 1.0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
),
|
),
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Center(
|
child: Center(
|
||||||
@ -341,9 +334,7 @@ class _DynamicTableState extends State<DynamicTable> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildTableCell(String content,
|
Widget _buildTableCell(String content,
|
||||||
{required double width,
|
{required double width, required int rowIndex, required int columnIndex}) {
|
||||||
required int rowIndex,
|
|
||||||
required int columnIndex}) {
|
|
||||||
bool isBatteryLevel = content.endsWith('%');
|
bool isBatteryLevel = content.endsWith('%');
|
||||||
double? batteryLevel;
|
double? batteryLevel;
|
||||||
|
|
||||||
@ -415,7 +406,7 @@ class _DynamicTableState extends State<DynamicTable> {
|
|||||||
height: _fixedRowHeight,
|
height: _fixedRowHeight,
|
||||||
padding: const EdgeInsets.only(left: 15, top: 10, bottom: 10),
|
padding: const EdgeInsets.only(left: 15, top: 10, bottom: 10),
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
border: Border(
|
border: Border(
|
||||||
bottom: BorderSide(
|
bottom: BorderSide(
|
||||||
color: ColorsManager.boxDivider,
|
color: ColorsManager.boxDivider,
|
||||||
|
@ -27,8 +27,8 @@ class BatchAcMode extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
_buildIconContainer(context, TempModes.cold, Assets.freezing,
|
_buildIconContainer(
|
||||||
value == TempModes.cold),
|
context, TempModes.cold, Assets.freezing, value == TempModes.cold),
|
||||||
_buildIconContainer(
|
_buildIconContainer(
|
||||||
context, TempModes.hot, Assets.acSun, value == TempModes.hot),
|
context, TempModes.hot, Assets.acSun, value == TempModes.hot),
|
||||||
_buildIconContainer(context, TempModes.wind, Assets.acAirConditioner,
|
_buildIconContainer(context, TempModes.wind, Assets.acAirConditioner,
|
||||||
@ -56,7 +56,7 @@ class BatchAcMode extends StatelessWidget {
|
|||||||
height: 50,
|
height: 50,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: isSelected ? Colors.blue : Colors.transparent,
|
color: isSelected ? Colors.blue : Colors.transparent,
|
||||||
width: 2.0,
|
width: 2.0,
|
||||||
|
@ -32,8 +32,8 @@ class BatchFanSpeedControl extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
_buildIconContainer(context, FanSpeeds.auto, Assets.acFanAuto,
|
_buildIconContainer(context, FanSpeeds.auto, Assets.acFanAuto,
|
||||||
value == FanSpeeds.auto),
|
value == FanSpeeds.auto),
|
||||||
_buildIconContainer(context, FanSpeeds.low, Assets.acFanLow,
|
_buildIconContainer(
|
||||||
value == FanSpeeds.low),
|
context, FanSpeeds.low, Assets.acFanLow, value == FanSpeeds.low),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
@ -52,8 +52,8 @@ class BatchFanSpeedControl extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildIconContainer(BuildContext context, FanSpeeds speed,
|
Widget _buildIconContainer(
|
||||||
String assetPath, bool isSelected) {
|
BuildContext context, FanSpeeds speed, String assetPath, bool isSelected) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.read<AcBloc>().add(
|
context.read<AcBloc>().add(
|
||||||
@ -69,7 +69,7 @@ class BatchFanSpeedControl extends StatelessWidget {
|
|||||||
height: 50,
|
height: 50,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: isSelected ? Colors.blue : Colors.transparent,
|
color: isSelected ? Colors.blue : Colors.transparent,
|
||||||
width: 2.0,
|
width: 2.0,
|
||||||
|
@ -27,8 +27,8 @@ class AcMode extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
_buildIconContainer(context, TempModes.cold, Assets.freezing,
|
_buildIconContainer(
|
||||||
value == TempModes.cold),
|
context, TempModes.cold, Assets.freezing, value == TempModes.cold),
|
||||||
_buildIconContainer(
|
_buildIconContainer(
|
||||||
context, TempModes.hot, Assets.acSun, value == TempModes.hot),
|
context, TempModes.hot, Assets.acSun, value == TempModes.hot),
|
||||||
_buildIconContainer(context, TempModes.wind, Assets.acAirConditioner,
|
_buildIconContainer(context, TempModes.wind, Assets.acAirConditioner,
|
||||||
@ -56,7 +56,7 @@ class AcMode extends StatelessWidget {
|
|||||||
height: 50,
|
height: 50,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: isSelected ? Colors.blue : Colors.transparent,
|
color: isSelected ? Colors.blue : Colors.transparent,
|
||||||
width: 2.0,
|
width: 2.0,
|
||||||
|
@ -38,7 +38,7 @@ class AcToggle extends StatelessWidget {
|
|||||||
height: 60,
|
height: 60,
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
|
@ -31,8 +31,8 @@ class FanSpeedControl extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
_buildIconContainer(context, FanSpeeds.auto, Assets.acFanAuto,
|
_buildIconContainer(context, FanSpeeds.auto, Assets.acFanAuto,
|
||||||
value == FanSpeeds.auto),
|
value == FanSpeeds.auto),
|
||||||
_buildIconContainer(context, FanSpeeds.low, Assets.acFanLow,
|
_buildIconContainer(
|
||||||
value == FanSpeeds.low),
|
context, FanSpeeds.low, Assets.acFanLow, value == FanSpeeds.low),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
@ -51,8 +51,8 @@ class FanSpeedControl extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildIconContainer(BuildContext context, FanSpeeds speed,
|
Widget _buildIconContainer(
|
||||||
String assetPath, bool isSelected) {
|
BuildContext context, FanSpeeds speed, String assetPath, bool isSelected) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.read<AcBloc>().add(
|
context.read<AcBloc>().add(
|
||||||
@ -68,7 +68,7 @@ class FanSpeedControl extends StatelessWidget {
|
|||||||
height: 50,
|
height: 50,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: isSelected ? Colors.blue : Colors.transparent,
|
color: isSelected ? Colors.blue : Colors.transparent,
|
||||||
width: 2.0,
|
width: 2.0,
|
||||||
|
@ -35,8 +35,7 @@ class _DeviceManagementPageState extends State<DeviceManagementPage> {
|
|||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) =>
|
create: (context) => DeviceManagementBloc()..add(FetchDevices(context)),
|
||||||
DeviceManagementBloc()..add(FetchDevices(context)),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: WebScaffold(
|
child: WebScaffold(
|
||||||
@ -59,8 +58,9 @@ class _DeviceManagementPageState extends State<DeviceManagementPage> {
|
|||||||
BlocProvider.of<CreateRoutineBloc>(context)
|
BlocProvider.of<CreateRoutineBloc>(context)
|
||||||
.add(const ResetSelectedEvent());
|
.add(const ResetSelectedEvent());
|
||||||
|
|
||||||
context.read<RoutineBloc>().add(
|
context
|
||||||
const TriggerSwitchTabsEvent(isRoutineTab: false));
|
.read<RoutineBloc>()
|
||||||
|
.add(const TriggerSwitchTabsEvent(isRoutineTab: false));
|
||||||
context
|
context
|
||||||
.read<DeviceManagementBloc>()
|
.read<DeviceManagementBloc>()
|
||||||
.add(FetchDevices(context));
|
.add(FetchDevices(context));
|
||||||
@ -69,7 +69,7 @@ class _DeviceManagementPageState extends State<DeviceManagementPage> {
|
|||||||
'Devices',
|
'Devices',
|
||||||
style: context.textTheme.titleMedium?.copyWith(
|
style: context.textTheme.titleMedium?.copyWith(
|
||||||
color: !state.routineTab
|
color: !state.routineTab
|
||||||
? ColorsManager.whiteColors
|
? ColorsManager.white
|
||||||
: ColorsManager.grayColor,
|
: ColorsManager.grayColor,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
!state.routineTab ? FontWeight.w700 : FontWeight.w400,
|
!state.routineTab ? FontWeight.w700 : FontWeight.w400,
|
||||||
@ -86,17 +86,17 @@ class _DeviceManagementPageState extends State<DeviceManagementPage> {
|
|||||||
BlocProvider.of<CreateRoutineBloc>(context)
|
BlocProvider.of<CreateRoutineBloc>(context)
|
||||||
.add(const ResetSelectedEvent());
|
.add(const ResetSelectedEvent());
|
||||||
|
|
||||||
context.read<RoutineBloc>().add(
|
context
|
||||||
const TriggerSwitchTabsEvent(isRoutineTab: true));
|
.read<RoutineBloc>()
|
||||||
|
.add(const TriggerSwitchTabsEvent(isRoutineTab: true));
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'Workflow Automation',
|
'Workflow Automation',
|
||||||
style: context.textTheme.titleMedium?.copyWith(
|
style: context.textTheme.titleMedium?.copyWith(
|
||||||
color: state.routineTab
|
color: state.routineTab
|
||||||
? ColorsManager.whiteColors
|
? ColorsManager.white
|
||||||
: ColorsManager.grayColor,
|
: ColorsManager.grayColor,
|
||||||
fontWeight:
|
fontWeight: state.routineTab ? FontWeight.w700 : FontWeight.w400,
|
||||||
state.routineTab ? FontWeight.w700 : FontWeight.w400,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -120,8 +120,7 @@ class _DeviceManagementPageState extends State<DeviceManagementPage> {
|
|||||||
} else if (deviceState is DeviceManagementLoaded) {
|
} else if (deviceState is DeviceManagementLoaded) {
|
||||||
return DeviceManagementBody(devices: deviceState.devices);
|
return DeviceManagementBody(devices: deviceState.devices);
|
||||||
} else if (deviceState is DeviceManagementFiltered) {
|
} else if (deviceState is DeviceManagementFiltered) {
|
||||||
return DeviceManagementBody(
|
return DeviceManagementBody(devices: deviceState.filteredDevices);
|
||||||
devices: deviceState.filteredDevices);
|
|
||||||
} else {
|
} else {
|
||||||
return const DeviceManagementBody(devices: []);
|
return const DeviceManagementBody(devices: []);
|
||||||
}
|
}
|
||||||
|
@ -120,8 +120,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
content: Text(
|
content: Text(
|
||||||
'This Device is Offline',
|
'This Device is Offline',
|
||||||
),
|
),
|
||||||
duration:
|
duration: Duration(seconds: 2),
|
||||||
Duration(seconds: 2),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
@ -135,13 +134,11 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
device: selectedDevices.first,
|
device: selectedDevices.first,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else if (selectedDevices.length >
|
} else if (selectedDevices.length > 1) {
|
||||||
1) {
|
final productTypes = selectedDevices
|
||||||
final productTypes =
|
.map(
|
||||||
selectedDevices
|
(device) => device.productType)
|
||||||
.map((device) =>
|
.toSet();
|
||||||
device.productType)
|
|
||||||
.toSet();
|
|
||||||
if (productTypes.length == 1) {
|
if (productTypes.length == 1) {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
@ -224,13 +221,11 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
device.batteryLevel != null
|
device.batteryLevel != null
|
||||||
? '${device.batteryLevel}%'
|
? '${device.batteryLevel}%'
|
||||||
: '-',
|
: '-',
|
||||||
formatDateTime(
|
formatDateTime(DateTime.fromMillisecondsSinceEpoch(
|
||||||
DateTime.fromMillisecondsSinceEpoch(
|
(device.createTime ?? 0) * 1000)),
|
||||||
(device.createTime ?? 0) * 1000)),
|
|
||||||
device.online == true ? 'Online' : 'Offline',
|
device.online == true ? 'Online' : 'Offline',
|
||||||
formatDateTime(
|
formatDateTime(DateTime.fromMillisecondsSinceEpoch(
|
||||||
DateTime.fromMillisecondsSinceEpoch(
|
(device.updateTime ?? 0) * 1000)),
|
||||||
(device.updateTime ?? 0) * 1000)),
|
|
||||||
'Settings',
|
'Settings',
|
||||||
];
|
];
|
||||||
}).toList(),
|
}).toList(),
|
||||||
@ -273,7 +268,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
child: Material(
|
child: Material(
|
||||||
child: Container(
|
child: Container(
|
||||||
width: MediaQuery.of(context).size.width * 0.3,
|
width: MediaQuery.of(context).size.width * 0.3,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
child: DeviceSettingsPanel(
|
child: DeviceSettingsPanel(
|
||||||
device: device,
|
device: device,
|
||||||
onClose: () => Navigator.of(context).pop(),
|
onClose: () => Navigator.of(context).pop(),
|
||||||
|
@ -18,7 +18,7 @@ class AccurteCalibratingDialog extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(_) {
|
Widget build(_) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
backgroundColor: ColorsManager.white,
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
content: AccurateDialogWidget(
|
content: AccurateDialogWidget(
|
||||||
title: 'Calibrating',
|
title: 'Calibrating',
|
||||||
|
@ -16,7 +16,7 @@ class AccurateCalibrationDialog extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(_) {
|
Widget build(_) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
backgroundColor: ColorsManager.white,
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
content: AccurateDialogWidget(
|
content: AccurateDialogWidget(
|
||||||
title: 'Accurate Calibration',
|
title: 'Accurate Calibration',
|
||||||
|
@ -17,7 +17,7 @@ class CalibrateCompletedDialog extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(_) {
|
Widget build(_) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
backgroundColor: ColorsManager.white,
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
content: SizedBox(
|
content: SizedBox(
|
||||||
height: 250,
|
height: 250,
|
||||||
|
@ -20,7 +20,7 @@ class CurtainActionWidget extends StatelessWidget {
|
|||||||
height: 60,
|
height: 60,
|
||||||
width: 60,
|
width: 60,
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 60,
|
height: 60,
|
||||||
|
@ -164,7 +164,7 @@ class _CurtainSliderWidgetState extends State<CurtainSliderWidget> {
|
|||||||
divisions: 10, // 10% step
|
divisions: 10, // 10% step
|
||||||
activeColor: ColorsManager.minBlueDot,
|
activeColor: ColorsManager.minBlueDot,
|
||||||
thumbColor: ColorsManager.primaryColor,
|
thumbColor: ColorsManager.primaryColor,
|
||||||
inactiveColor: ColorsManager.whiteColors,
|
inactiveColor: ColorsManager.white,
|
||||||
|
|
||||||
// Start dragging — use local control
|
// Start dragging — use local control
|
||||||
onChangeStart: (_) {
|
onChangeStart: (_) {
|
||||||
|
@ -47,10 +47,9 @@ class PrefReversCardWidget extends StatelessWidget {
|
|||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.all(3),
|
padding: const EdgeInsets.all(3),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
borderRadius: const BorderRadius.horizontal(
|
borderRadius: const BorderRadius.horizontal(
|
||||||
left: Radius.circular(10),
|
left: Radius.circular(10), right: Radius.circular(10)),
|
||||||
right: Radius.circular(10)),
|
|
||||||
border: Border.all(color: ColorsManager.grayBorder)),
|
border: Border.all(color: ColorsManager.grayBorder)),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.reverseArrows,
|
Assets.reverseArrows,
|
||||||
|
@ -22,7 +22,7 @@ class CurtainModulePrefrencesDialog extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(_) {
|
Widget build(_) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
backgroundColor: ColorsManager.CircleImageBackground,
|
backgroundColor: ColorsManager.circleImageBackground,
|
||||||
contentPadding: const EdgeInsets.all(20),
|
contentPadding: const EdgeInsets.all(20),
|
||||||
title: Center(
|
title: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
|
@ -63,7 +63,7 @@ class _QuickCalibratingDialogState extends State<QuickCalibratingDialog> {
|
|||||||
@override
|
@override
|
||||||
Widget build(_) {
|
Widget build(_) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
backgroundColor: ColorsManager.white,
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
content: AccurateDialogWidget(
|
content: AccurateDialogWidget(
|
||||||
title: 'Calibrating',
|
title: 'Calibrating',
|
||||||
|
@ -18,7 +18,7 @@ class QuickCalibrationDialog extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(_) {
|
Widget build(_) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
backgroundColor: ColorsManager.white,
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
content: AccurateDialogWidget(
|
content: AccurateDialogWidget(
|
||||||
title: 'Quick Calibration',
|
title: 'Quick Calibration',
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart';
|
||||||
@ -47,8 +46,8 @@ class DeviceSettingsPanel extends StatelessWidget {
|
|||||||
return BlocBuilder<SettingDeviceBloc, DeviceSettingsState>(
|
return BlocBuilder<SettingDeviceBloc, DeviceSettingsState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final _bloc = context.read<SettingDeviceBloc>();
|
final _bloc = context.read<SettingDeviceBloc>();
|
||||||
final iconPath = DeviceIconTypeHelper.getDeviceIconByTypeCode(
|
final iconPath =
|
||||||
device.productType);
|
DeviceIconTypeHelper.getDeviceIconByTypeCode(device.productType);
|
||||||
final deviceInfo = state is DeviceSettingsUpdate
|
final deviceInfo = state is DeviceSettingsUpdate
|
||||||
? state.deviceInfo ?? DeviceInfoModel.empty()
|
? state.deviceInfo ?? DeviceInfoModel.empty()
|
||||||
: DeviceInfoModel.empty();
|
: DeviceInfoModel.empty();
|
||||||
@ -77,11 +76,9 @@ class DeviceSettingsPanel extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Device Settings',
|
'Device Settings',
|
||||||
style: context.theme.textTheme.titleLarge!
|
style: context.theme.textTheme.titleLarge!.copyWith(
|
||||||
.copyWith(
|
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
color: ColorsManager.vividBlue
|
color: ColorsManager.vividBlue.withOpacity(0.7),
|
||||||
.withOpacity(0.7),
|
|
||||||
fontSize: 24),
|
fontSize: 24),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -98,7 +95,7 @@ class DeviceSettingsPanel extends StatelessWidget {
|
|||||||
backgroundColor:
|
backgroundColor:
|
||||||
ColorsManager.grayBorder.withOpacity(0.5),
|
ColorsManager.grayBorder.withOpacity(0.5),
|
||||||
child: CircleAvatar(
|
child: CircleAvatar(
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
backgroundColor: ColorsManager.white,
|
||||||
radius: 36,
|
radius: 36,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
iconPath,
|
iconPath,
|
||||||
@ -116,8 +113,7 @@ class DeviceSettingsPanel extends StatelessWidget {
|
|||||||
const SizedBox(height: 15),
|
const SizedBox(height: 15),
|
||||||
Text(
|
Text(
|
||||||
'Device Name:',
|
'Device Name:',
|
||||||
style: context.textTheme.bodyMedium!
|
style: context.textTheme.bodyMedium!.copyWith(
|
||||||
.copyWith(
|
|
||||||
color: ColorsManager.grayColor,
|
color: ColorsManager.grayColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -143,13 +139,13 @@ class DeviceSettingsPanel extends StatelessWidget {
|
|||||||
_bloc.add(const ChangeNameEvent(
|
_bloc.add(const ChangeNameEvent(
|
||||||
value: false));
|
value: false));
|
||||||
deviceManagementBloc
|
deviceManagementBloc
|
||||||
..add(UpdateDeviceName(
|
..add(UpdateDeviceName(
|
||||||
deviceId: device.uuid!,
|
deviceId: device.uuid!,
|
||||||
newName: _bloc
|
newName:
|
||||||
.nameController
|
_bloc.nameController.text))
|
||||||
.text))..add(ResetSelectedDevices());
|
..add(ResetSelectedDevices());
|
||||||
},
|
},
|
||||||
decoration:const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
isDense: true,
|
isDense: true,
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
@ -164,18 +160,16 @@ class DeviceSettingsPanel extends StatelessWidget {
|
|||||||
width: 15,
|
width: 15,
|
||||||
height: 25,
|
height: 25,
|
||||||
child: Visibility(
|
child: Visibility(
|
||||||
visible:
|
visible: _bloc.editName != true,
|
||||||
_bloc.editName != true,
|
|
||||||
replacement: const SizedBox(),
|
replacement: const SizedBox(),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_bloc.add(
|
_bloc.add(
|
||||||
const ChangeNameEvent(
|
const ChangeNameEvent(
|
||||||
value: true));
|
value: true));
|
||||||
},
|
},
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets
|
Assets.editNameIconSettings,
|
||||||
.editNameIconSettings,
|
|
||||||
color: ColorsManager
|
color: ColorsManager
|
||||||
.lightGrayBorderColor,
|
.lightGrayBorderColor,
|
||||||
height: 15,
|
height: 15,
|
||||||
|
@ -32,7 +32,7 @@ class _SubSpaceDialogState extends State<SubSpaceDialog> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Dialog(
|
return Dialog(
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
backgroundColor: ColorsManager.white,
|
||||||
insetPadding: const EdgeInsets.symmetric(horizontal: 24, vertical: 60),
|
insetPadding: const EdgeInsets.symmetric(horizontal: 24, vertical: 60),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(28),
|
borderRadius: BorderRadius.circular(28),
|
||||||
|
@ -6,6 +6,7 @@ import 'package:syncrow_web/pages/device_managment/garage_door/bloc/garage_door_
|
|||||||
import 'package:syncrow_web/pages/device_managment/garage_door/helper/garage_door_helper.dart';
|
import 'package:syncrow_web/pages/device_managment/garage_door/helper/garage_door_helper.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/garage_door/models/garage_door_model.dart';
|
import 'package:syncrow_web/pages/device_managment/garage_door/models/garage_door_model.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/garage_door/schedule_view/schedule_garage_view.dart';
|
import 'package:syncrow_web/pages/device_managment/garage_door/schedule_view/schedule_garage_view.dart';
|
||||||
|
import 'package:syncrow_web/pages/device_managment/schedule_device/schedule_widgets/schedual_view.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/shared/icon_name_status_container.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/icon_name_status_container.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||||
@ -94,11 +95,18 @@ class GarageDoorControlView extends StatelessWidget
|
|||||||
FetchGarageDoorSchedulesEvent(
|
FetchGarageDoorSchedulesEvent(
|
||||||
deviceId: deviceId, category: 'doorcontact_state'),
|
deviceId: deviceId, category: 'doorcontact_state'),
|
||||||
);
|
);
|
||||||
showDialog(
|
|
||||||
|
showDialog<void>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (ctx) => BlocProvider.value(
|
builder: (ctx) => BlocProvider.value(
|
||||||
value: BlocProvider.of<GarageDoorBloc>(context),
|
value: BlocProvider.of<GarageDoorBloc>(context),
|
||||||
child: BuildGarageDoorScheduleView(status: status),
|
child: BuildScheduleView(
|
||||||
|
deviceUuid: deviceId,
|
||||||
|
category: 'Timer',
|
||||||
|
code: 'doorcontact_state',
|
||||||
|
countdownCode: 'Timer',
|
||||||
|
deviceType: 'GD',
|
||||||
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
name: 'Scheduling',
|
name: 'Scheduling',
|
||||||
|
@ -109,7 +109,7 @@ class _DeviceItem extends StatelessWidget {
|
|||||||
height: 60,
|
height: 60,
|
||||||
width: 60,
|
width: 60,
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
device.icon ?? 'assets/icons/gateway.svg',
|
device.icon ?? 'assets/icons/gateway.svg',
|
||||||
width: 35,
|
width: 35,
|
||||||
|
@ -36,7 +36,7 @@ class _EnergyConsumptionPageState extends State<EnergyConsumptionPage> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
const Row(
|
const Row(
|
||||||
|
@ -22,7 +22,7 @@ class PowerClampInfoCard extends StatelessWidget {
|
|||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 6),
|
margin: const EdgeInsets.symmetric(horizontal: 6),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
),
|
),
|
||||||
height: 55,
|
height: 55,
|
||||||
|
@ -12,8 +12,7 @@ import 'package:syncrow_web/utils/constants/assets.dart';
|
|||||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
//Smart Power Clamp
|
//Smart Power Clamp
|
||||||
class SmartPowerDeviceControl extends StatelessWidget
|
class SmartPowerDeviceControl extends StatelessWidget with HelperResponsiveLayout {
|
||||||
with HelperResponsiveLayout {
|
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
|
|
||||||
const SmartPowerDeviceControl({super.key, required this.deviceId});
|
const SmartPowerDeviceControl({super.key, required this.deviceId});
|
||||||
@ -129,7 +128,7 @@ class SmartPowerDeviceControl extends StatelessWidget
|
|||||||
bottom: 10,
|
bottom: 10,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
),
|
),
|
||||||
height: 300,
|
height: 300,
|
||||||
@ -149,8 +148,7 @@ class SmartPowerDeviceControl extends StatelessWidget
|
|||||||
onPressed: blocProvider.currentPage <= 0
|
onPressed: blocProvider.currentPage <= 0
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
blocProvider
|
blocProvider.add(SmartPowerArrowPressedEvent(-1));
|
||||||
.add(SmartPowerArrowPressedEvent(-1));
|
|
||||||
pageController.previousPage(
|
pageController.previousPage(
|
||||||
duration: const Duration(milliseconds: 300),
|
duration: const Duration(milliseconds: 300),
|
||||||
curve: Curves.easeInOut,
|
curve: Curves.easeInOut,
|
||||||
@ -172,8 +170,7 @@ class SmartPowerDeviceControl extends StatelessWidget
|
|||||||
onPressed: blocProvider.currentPage >= 3
|
onPressed: blocProvider.currentPage >= 3
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
blocProvider
|
blocProvider.add(SmartPowerArrowPressedEvent(1));
|
||||||
.add(SmartPowerArrowPressedEvent(1));
|
|
||||||
pageController.nextPage(
|
pageController.nextPage(
|
||||||
duration: const Duration(milliseconds: 300),
|
duration: const Duration(milliseconds: 300),
|
||||||
curve: Curves.easeInOut,
|
curve: Curves.easeInOut,
|
||||||
@ -202,8 +199,8 @@ class SmartPowerDeviceControl extends StatelessWidget
|
|||||||
blocProvider.add(SelectDateEvent(context: context));
|
blocProvider.add(SelectDateEvent(context: context));
|
||||||
blocProvider.add(FilterRecordsByDateEvent(
|
blocProvider.add(FilterRecordsByDateEvent(
|
||||||
selectedDate: blocProvider.dateTime!,
|
selectedDate: blocProvider.dateTime!,
|
||||||
viewType: blocProvider
|
viewType:
|
||||||
.views[blocProvider.currentIndex]));
|
blocProvider.views[blocProvider.currentIndex]));
|
||||||
},
|
},
|
||||||
widget: blocProvider.dateSwitcher(),
|
widget: blocProvider.dateSwitcher(),
|
||||||
chartData: blocProvider.energyDataList.isNotEmpty
|
chartData: blocProvider.energyDataList.isNotEmpty
|
||||||
|
@ -287,7 +287,8 @@ class ScheduleBloc extends Bloc<ScheduleEvent, ScheduleState> {
|
|||||||
try {
|
try {
|
||||||
if (state is ScheduleLoaded) {
|
if (state is ScheduleLoaded) {
|
||||||
Status status = Status(code: '', value: '');
|
Status status = Status(code: '', value: '');
|
||||||
if (event.deviceType == 'CUR_2') {
|
if (event.deviceType == 'CUR_2' ||
|
||||||
|
event.deviceType == 'GD' ) {
|
||||||
status = status.copyWith(
|
status = status.copyWith(
|
||||||
code: 'control',
|
code: 'control',
|
||||||
value: event.functionOn == true ? 'open' : 'close');
|
value: event.functionOn == true ? 'open' : 'close');
|
||||||
|
@ -69,7 +69,7 @@ class CountdownModeButtons extends StatelessWidget {
|
|||||||
countDownCode: countDownCode),
|
countDownCode: countDownCode),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
backgroundColor: ColorsManager.primaryColorWithOpacity,
|
backgroundColor: ColorsManager.secondaryColor,
|
||||||
child: const Text('Save'),
|
child: const Text('Save'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -63,7 +63,7 @@ class InchingModeButtons extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
backgroundColor: ColorsManager.primaryColor,
|
backgroundColor: ColorsManager.secondaryColor,
|
||||||
child: const Text('Save'),
|
child: const Text('Save'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -31,11 +31,12 @@ class BuildScheduleView extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (_) => ScheduleBloc(deviceId: deviceUuid,)
|
create: (_) => ScheduleBloc(
|
||||||
|
deviceId: deviceUuid,
|
||||||
|
)
|
||||||
..add(ScheduleGetEvent(category: category))
|
..add(ScheduleGetEvent(category: category))
|
||||||
..add(ScheduleFetchStatusEvent(
|
..add(ScheduleFetchStatusEvent(
|
||||||
deviceId: deviceUuid,
|
deviceId: deviceUuid, countdownCode: countdownCode ?? '')),
|
||||||
countdownCode: countdownCode ?? '')),
|
|
||||||
child: Dialog(
|
child: Dialog(
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
insetPadding: const EdgeInsets.all(20),
|
insetPadding: const EdgeInsets.all(20),
|
||||||
@ -56,7 +57,7 @@ class BuildScheduleView extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
const ScheduleHeader(),
|
const ScheduleHeader(),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
if (deviceType == 'CUR_2')
|
if (deviceType == 'CUR_2' || deviceType == 'GD')
|
||||||
const SizedBox()
|
const SizedBox()
|
||||||
else
|
else
|
||||||
ScheduleModeSelector(
|
ScheduleModeSelector(
|
||||||
@ -76,8 +77,7 @@ class BuildScheduleView extends StatelessWidget {
|
|||||||
category: category,
|
category: category,
|
||||||
time: '',
|
time: '',
|
||||||
function: Status(
|
function: Status(
|
||||||
code: code.toString(),
|
code: code.toString(), value: true),
|
||||||
value: true),
|
|
||||||
days: [],
|
days: [],
|
||||||
),
|
),
|
||||||
isEdit: false,
|
isEdit: false,
|
||||||
@ -96,7 +96,7 @@ class BuildScheduleView extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (deviceType != 'CUR_2')
|
if (deviceType != 'CUR_2'|| deviceType != 'GD')
|
||||||
if (state.scheduleMode == ScheduleModes.countdown ||
|
if (state.scheduleMode == ScheduleModes.countdown ||
|
||||||
state.scheduleMode == ScheduleModes.inching)
|
state.scheduleMode == ScheduleModes.inching)
|
||||||
CountdownInchingView(
|
CountdownInchingView(
|
||||||
|
@ -30,7 +30,7 @@ class ScheduleControlButton extends StatelessWidget {
|
|||||||
height: 60,
|
height: 60,
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
),
|
),
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 4),
|
margin: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
padding: const EdgeInsets.all(12),
|
padding: const EdgeInsets.all(12),
|
||||||
|
@ -13,7 +13,7 @@ class ScheduleHeader extends StatelessWidget {
|
|||||||
Text(
|
Text(
|
||||||
'Scheduling',
|
'Scheduling',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: ColorsManager.primaryColorWithOpacity,
|
color: ColorsManager.opaquePrimary,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
fontSize: 30,
|
fontSize: 30,
|
||||||
),
|
),
|
||||||
|
@ -24,12 +24,13 @@ class ScheduleManagementUI extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 170,
|
width: 177,
|
||||||
height: 40,
|
height: 40,
|
||||||
child: DefaultButton(
|
child: DefaultButton(
|
||||||
borderColor: ColorsManager.grayColor.withOpacity(0.5),
|
borderWidth: 4,
|
||||||
padding: 2,
|
borderColor: ColorsManager.neutralGray,
|
||||||
backgroundColor: ColorsManager.graysColor,
|
padding: 8,
|
||||||
|
backgroundColor: ColorsManager.textFieldGreyColor,
|
||||||
borderRadius: 15,
|
borderRadius: 15,
|
||||||
onPressed: onAddSchedule,
|
onPressed: onAddSchedule,
|
||||||
child: Row(
|
child: Row(
|
||||||
|
@ -39,7 +39,7 @@ class ScheduleModeButtons extends StatelessWidget {
|
|||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
height: 40,
|
height: 40,
|
||||||
onPressed: onSave,
|
onPressed: onSave,
|
||||||
backgroundColor: ColorsManager.primaryColorWithOpacity,
|
backgroundColor: ColorsManager.secondaryColor,
|
||||||
child: const Text('Save'),
|
child: const Text('Save'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -194,7 +194,7 @@ class _ScheduleTableView extends StatelessWidget {
|
|||||||
child: Text(_getSelectedDays(
|
child: Text(_getSelectedDays(
|
||||||
ScheduleModel.parseSelectedDays(schedule.days)))),
|
ScheduleModel.parseSelectedDays(schedule.days)))),
|
||||||
Center(child: Text(formatIsoStringToTime(schedule.time, context))),
|
Center(child: Text(formatIsoStringToTime(schedule.time, context))),
|
||||||
if (deviceType == 'CUR_2')
|
if (deviceType == 'CUR_2' || deviceType == 'GD')
|
||||||
Center(
|
Center(
|
||||||
child: Text(schedule.function.value == true ? 'open' : 'close'))
|
child: Text(schedule.function.value == true ? 'open' : 'close'))
|
||||||
else
|
else
|
||||||
|
@ -76,7 +76,7 @@ class _FactoryResetWidgetState extends State<FactoryResetWidget> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
'Reset',
|
'Reset',
|
||||||
style: context.textTheme.bodyMedium!.copyWith(
|
style: context.textTheme.bodyMedium!.copyWith(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
),
|
),
|
||||||
@ -95,7 +95,7 @@ class _FactoryResetWidgetState extends State<FactoryResetWidget> {
|
|||||||
children: [
|
children: [
|
||||||
ClipOval(
|
ClipOval(
|
||||||
child: Container(
|
child: Container(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
height: 60,
|
height: 60,
|
||||||
width: 60,
|
width: 60,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
|
@ -45,7 +45,7 @@ class IconNameStatusContainer extends StatelessWidget {
|
|||||||
height: 60,
|
height: 60,
|
||||||
width: 60,
|
width: 60,
|
||||||
padding: EdgeInsets.all(paddingAmount ?? 8),
|
padding: EdgeInsets.all(paddingAmount ?? 8),
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
icon,
|
icon,
|
||||||
width: 35,
|
width: 35,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart';
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
|
||||||
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
|
|
||||||
class PresenceSpaceType extends StatelessWidget {
|
class PresenceSpaceType extends StatelessWidget {
|
||||||
const PresenceSpaceType({
|
const PresenceSpaceType({
|
||||||
@ -59,7 +59,7 @@ class PresenceSpaceType extends StatelessWidget {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(100),
|
borderRadius: BorderRadius.circular(100),
|
||||||
color: value == spaceType
|
color: value == spaceType
|
||||||
? ColorsManager.primaryColorWithOpacity
|
? ColorsManager.opaquePrimary
|
||||||
: ColorsManager.textGray,
|
: ColorsManager.textGray,
|
||||||
),
|
),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
|
@ -52,7 +52,7 @@ class ToggleWidget extends StatelessWidget {
|
|||||||
height: 60,
|
height: 60,
|
||||||
width: 60,
|
width: 60,
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
icon ?? Assets.lightPulp,
|
icon ?? Assets.lightPulp,
|
||||||
width: 35,
|
width: 35,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart';
|
import 'package:syncrow_web/pages/device_managment/three_gang_switch/bloc/living_room_bloc.dart';
|
||||||
@ -7,7 +6,8 @@ import 'package:syncrow_web/utils/color_manager.dart';
|
|||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
|
||||||
class CeilingLight extends StatelessWidget {
|
class CeilingLight extends StatelessWidget {
|
||||||
const CeilingLight({super.key, required this.value, required this.code, required this.deviceId});
|
const CeilingLight(
|
||||||
|
{super.key, required this.value, required this.code, required this.deviceId});
|
||||||
|
|
||||||
final bool value;
|
final bool value;
|
||||||
final String code;
|
final String code;
|
||||||
@ -24,7 +24,7 @@ class CeilingLight extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
ClipOval(
|
ClipOval(
|
||||||
child: Container(
|
child: Container(
|
||||||
color: ColorsManager.whiteColors,
|
color: ColorsManager.white,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.lightPulp,
|
Assets.lightPulp,
|
||||||
width: 60,
|
width: 60,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user