Initial commit
This commit is contained in:
144
lib/views/home/panels/home_categories.dart
Normal file
144
lib/views/home/panels/home_categories.dart
Normal file
@@ -0,0 +1,144 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:hum/core/constants/app_text.dart';
|
||||
import 'package:hum/core/constants/app_theme.dart';
|
||||
import 'package:hum/core/utils/icon_mapper.dart';
|
||||
import 'package:phosphor_flutter/phosphor_flutter.dart';
|
||||
|
||||
class HomePanelCategory extends StatefulWidget {
|
||||
final List<Map<String, dynamic>> categories;
|
||||
const HomePanelCategory({super.key, this.categories = const []});
|
||||
|
||||
@override
|
||||
State<HomePanelCategory> createState() => _HomePanelCategoryState();
|
||||
}
|
||||
|
||||
Stream<List<Map<String, dynamic>>> categoriesStream() {
|
||||
return FirebaseFirestore.instance
|
||||
.collection('categories')
|
||||
.snapshots()
|
||||
.map((snapshot) => snapshot.docs.map((doc) => doc.data()).toList());
|
||||
}
|
||||
|
||||
class _HomePanelCategoryState extends State<HomePanelCategory> {
|
||||
List<String> selectedCategories = [];
|
||||
|
||||
bool isSelected(String categoryId, int index) {
|
||||
if (selectedCategories.contains(categoryId)) {
|
||||
return true;
|
||||
} else if (index == 0 && selectedCategories.isEmpty) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void toggleCategory(String category) {
|
||||
if (category.toLowerCase() == 'all') {
|
||||
selectedCategories.clear();
|
||||
setState(() => selectedCategories = selectedCategories);
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedCategories.contains(category)) {
|
||||
selectedCategories.remove(category);
|
||||
} else {
|
||||
selectedCategories.add(category);
|
||||
}
|
||||
|
||||
setState(() => selectedCategories = selectedCategories);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
backgroundColor: CupertinoDynamicColor.resolve(colorBarBackground, context),
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
automaticallyImplyLeading: false,
|
||||
trailing: CupertinoButton(
|
||||
padding: EdgeInsets.all(0),
|
||||
child: Text(doneLabel),
|
||||
onPressed: () => Navigator.of(context).maybePop(),
|
||||
),
|
||||
),
|
||||
|
||||
child: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: CustomScrollView(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
slivers: [
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.only(top: 12, bottom: 24),
|
||||
sliver: SliverGrid(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
mainAxisSpacing: 8,
|
||||
crossAxisSpacing: 8,
|
||||
childAspectRatio: 1.7, // width / height ratio
|
||||
),
|
||||
delegate: SliverChildBuilderDelegate((context, index) {
|
||||
final category = widget.categories[index];
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
toggleCategory(category['id']);
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: CupertinoDynamicColor.resolve(
|
||||
(isSelected(category['id'], index))
|
||||
? colorBarControl.withAlpha(30)
|
||||
: colorBarControl.withAlpha(10),
|
||||
context,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: BoxBorder.all(
|
||||
width: 2,
|
||||
color: (isSelected(category['id'], index))
|
||||
? CupertinoColors.activeGreen
|
||||
: colorBarControlBordeer.withValues(alpha: 0.2),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
spacing: 10,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
PhosphorIcon(
|
||||
PhosphorIconHelper.fromString(
|
||||
category['icon'] ?? 'home',
|
||||
style: (isSelected(category['id'], index)) ? 'fill' : 'duotone',
|
||||
),
|
||||
size: 40,
|
||||
color: (isSelected(category['id'], index))
|
||||
? CupertinoColors.activeGreen
|
||||
: CupertinoColors.white.withAlpha(140),
|
||||
),
|
||||
|
||||
Text(
|
||||
category['name'] ?? 'Unnamed',
|
||||
style: TextStyle(
|
||||
color: (isSelected(category['id'], index))
|
||||
? CupertinoColors.activeGreen
|
||||
: CupertinoColors.white.withAlpha(180),
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}, childCount: widget.categories.length),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
153
lib/views/home/panels/home_filters.dart
Normal file
153
lib/views/home/panels/home_filters.dart
Normal file
@@ -0,0 +1,153 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hum/core/constants/app_text.dart';
|
||||
import 'package:hum/core/constants/app_theme.dart';
|
||||
import 'package:hum/widgets/widget_buttons.dart';
|
||||
import 'package:hum/widgets/widget_text_fields.dart';
|
||||
|
||||
class HomeFilters extends StatefulWidget {
|
||||
const HomeFilters({super.key});
|
||||
|
||||
@override
|
||||
State<HomeFilters> createState() => _HomeFiltersState();
|
||||
}
|
||||
|
||||
String locationFriendly = 'San Francisco';
|
||||
TextEditingController ctrlLocation = TextEditingController();
|
||||
final UniqueKey keyCtrlLocation = UniqueKey();
|
||||
String filterDateStartFriendly = 'May 22nd, 2027';
|
||||
String filterDateEndFriendly = 'June 3rd, 2027';
|
||||
|
||||
class _HomeFiltersState extends State<HomeFilters> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
backgroundColor: CupertinoDynamicColor.resolve(colorBarBackground, context),
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
automaticallyImplyLeading: false,
|
||||
// leading: CupertinoButton(
|
||||
// padding: EdgeInsets.zero,
|
||||
// onPressed: () => Navigator.of(
|
||||
// context,
|
||||
// ).maybePop(),
|
||||
// child: Text(
|
||||
// 'Close',
|
||||
// ),
|
||||
// ),
|
||||
// middle: Text(
|
||||
// 'Filters',
|
||||
// ),
|
||||
trailing: CupertinoButton(
|
||||
padding: EdgeInsets.all(0),
|
||||
child: Text('Done'),
|
||||
onPressed: () => Navigator.of(context).maybePop(),
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Column(
|
||||
spacing: 16,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// LOCATION
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
LBLFilter(label: filterLocation),
|
||||
Opacity(
|
||||
opacity: 0.7,
|
||||
child: Row(
|
||||
spacing: 4,
|
||||
children: [
|
||||
Icon(CupertinoIcons.globe, color: CupertinoColors.lightBackgroundGray, size: 18),
|
||||
Text(locationFriendly, style: TextStyle(fontSize: 15)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
TXTFieldInput(
|
||||
key: keyCtrlLocation,
|
||||
controller: ctrlLocation,
|
||||
placeholder: filterLocationPlaceholder,
|
||||
inputType: TextInputType.text,
|
||||
),
|
||||
|
||||
BTNFilledIcon(
|
||||
text: 'Current Location',
|
||||
color: colorBarButton,
|
||||
icon: CupertinoIcons.location_fill,
|
||||
action: () {},
|
||||
),
|
||||
|
||||
// SizedBox(
|
||||
// width: double.infinity,
|
||||
// child: CupertinoSlider(
|
||||
// value: 30,
|
||||
// min: 1,
|
||||
// max: 100,
|
||||
// onChanged:
|
||||
// (
|
||||
// value,
|
||||
// ) => {},
|
||||
// ),
|
||||
// ),
|
||||
Divider(),
|
||||
|
||||
// DATES
|
||||
LBLFilter(label: filterDates),
|
||||
|
||||
Column(
|
||||
spacing: 6,
|
||||
children: [
|
||||
BTNComplex(
|
||||
label: filterLabelStartDate,
|
||||
text: filterDateStartFriendly,
|
||||
iconLeading: CupertinoIcons.calendar,
|
||||
color: CupertinoDynamicColor.resolve(colorBarButton, context),
|
||||
textColor: CupertinoDynamicColor.resolve(colorAccentSecondary, context),
|
||||
action: () {},
|
||||
),
|
||||
|
||||
Center(
|
||||
child: Opacity(opacity: .5, child: Icon(CupertinoIcons.arrow_down, color: Colors.white)),
|
||||
),
|
||||
|
||||
BTNComplex(
|
||||
label: filterLabelEndDate,
|
||||
text: filterDateEndFriendly,
|
||||
iconLeading: CupertinoIcons.calendar,
|
||||
color: CupertinoDynamicColor.resolve(colorBarButton, context),
|
||||
textColor: CupertinoDynamicColor.resolve(colorAccentPrimary, context),
|
||||
action: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Divider(),
|
||||
|
||||
// PRICING
|
||||
LBLFilter(label: filterPricing),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class LBLFilter extends StatelessWidget {
|
||||
const LBLFilter({super.key, required this.label});
|
||||
|
||||
final String label;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Opacity(
|
||||
opacity: .5,
|
||||
child: Text(label, style: TextStyle(fontSize: 16, fontWeight: FontWeight.w300)),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user