Implemented side tree to devices and rountines screen

This commit is contained in:
Abdullah Alassaf
2025-01-04 17:45:15 +03:00
parent 0341844ea9
commit a98f7e77a3
88 changed files with 1551 additions and 1202 deletions

View File

@ -0,0 +1,127 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class CustomExpansionTile extends StatefulWidget {
final String title;
final List<Widget>? children;
final bool initiallyExpanded;
final bool isSelected; // Add this to track selection
final bool? isExpanded; // External control over expansion
final ValueChanged<bool>? onExpansionChanged; // Notify when expansion changes
final VoidCallback? onItemSelected; // Callback for selecting the item
CustomExpansionTile({
required this.title,
this.children,
this.initiallyExpanded = false,
this.isExpanded, // Allow external control over expansion
this.onExpansionChanged, // Notify when expansion changes
this.onItemSelected, // Trigger item selection when name is tapped
required this.isSelected, // Add this to initialize selection state
});
@override
CustomExpansionTileState createState() => CustomExpansionTileState();
}
class CustomExpansionTileState extends State<CustomExpansionTile> {
bool _isExpanded = false; // Local expansion state
@override
void initState() {
super.initState();
_isExpanded = widget.initiallyExpanded;
}
@override
void didUpdateWidget(CustomExpansionTile oldWidget) {
super.didUpdateWidget(oldWidget);
// Sync local state with external control of expansion state
if (widget.isExpanded != null && widget.isExpanded != _isExpanded) {
setState(() {
_isExpanded = widget.isExpanded!;
});
}
}
// Utility function to capitalize the first letter of the title
String _capitalizeFirstLetter(String text) {
if (text.isEmpty) return text;
return text[0].toUpperCase() + text.substring(1);
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
children: [
// Checkbox with independent state management
Checkbox(
value: widget.isSelected,
onChanged: (bool? value) {
if (widget.onItemSelected != null) {
widget.onItemSelected!();
}
},
side: WidgetStateBorderSide.resolveWith((states) {
return const BorderSide(color: ColorsManager.grayBorder);
}),
fillColor: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return ColorsManager.blue1;
} else {
return ColorsManager.checkBoxFillColor;
}
}),
checkColor: ColorsManager.whiteColors,
),
// Expand/collapse icon, now wrapped in a GestureDetector for specific onTap
if (widget.children != null && widget.children!.isNotEmpty)
GestureDetector(
onTap: () {
setState(() {
_isExpanded = !_isExpanded;
widget.onExpansionChanged?.call(_isExpanded);
});
},
child: Icon(
_isExpanded ? Icons.keyboard_arrow_down : Icons.keyboard_arrow_right,
color: ColorsManager.lightGrayColor,
size: 16.0, // Adjusted size for better alignment
),
),
// The title text, wrapped in GestureDetector to handle selection
Expanded(
child: GestureDetector(
onTap: () {
if (widget.onItemSelected != null) {
widget.onItemSelected!();
}
},
child: Text(
_capitalizeFirstLetter(widget.title),
style: TextStyle(
color: widget.isSelected
? ColorsManager.blackColor // Change color to black when selected
: ColorsManager.lightGrayColor, // Gray when not selected
fontWeight: FontWeight.w400,
),
),
),
),
],
),
// The expanded section (children) that shows when the tile is expanded
if (_isExpanded && widget.children != null && widget.children!.isNotEmpty)
Padding(
padding: const EdgeInsets.only(left: 48.0), // Indented children
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: widget.children!,
),
),
],
);
}
}

View File

@ -0,0 +1,78 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
class CustomSearchBar extends StatelessWidget {
final TextEditingController? controller;
final String hintText;
final Function(String)? onSearchChanged; // Callback for search input changes
const CustomSearchBar({
super.key,
this.controller,
this.hintText = 'Search',
this.onSearchChanged,
});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: ColorsManager.whiteColors,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
spreadRadius: 0,
blurRadius: 8,
offset: const Offset(0, 4),
),
],
),
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 20.0),
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
),
child: TextField(
controller: controller,
style: const TextStyle(
color: Colors.black,
),
onChanged: onSearchChanged, // Call the callback on text change
decoration: InputDecoration(
filled: true,
fillColor: ColorsManager.textFieldGreyColor,
hintText: hintText,
hintStyle: TextStyle(
color: Color(0xB2999999),
fontSize: 12,
fontFamily: 'Aftika',
fontWeight: FontWeight.w400,
height: 0,
letterSpacing: -0.24,
),
suffixIcon: Padding(
padding: const EdgeInsets.only(right: 16),
child: SvgPicture.asset(
Assets.textFieldSearch,
width: 24,
height: 24,
),
),
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(12),
),
contentPadding: const EdgeInsets.symmetric(
vertical: 14,
horizontal: 16,
),
),
),
),
);
}
}

View File

@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
class SpacesSideTree extends StatefulWidget {
final List<CommunityModel> communities;
final String? selectedSpaceUuid;
const SpacesSideTree({
super.key,
required this.communities,
this.selectedSpaceUuid,
});
@override
State<SpacesSideTree> createState() => _SpacesSideTreeState();
}
class _SpacesSideTreeState extends State<SpacesSideTree> {
String _searchQuery = '';
String? _selectedSpaceUuid;
String? _selectedId;
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}