diff --git a/lib/presentation/pages/profile/profile_page.dart b/lib/presentation/pages/profile/profile_page.dart index 0b5054b..51c95c5 100644 --- a/lib/presentation/pages/profile/profile_page.dart +++ b/lib/presentation/pages/profile/profile_page.dart @@ -1,12 +1,65 @@ import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; +import '../../../common/theme/theme.dart'; +import '../../components/spacer/spacer.dart'; +import 'widgets/account_info.dart'; +import 'widgets/app_setting.dart'; +import 'widgets/business_setting.dart'; +import 'widgets/danger_zone.dart'; +import 'widgets/header.dart'; +import 'widgets/support.dart'; + @RoutePage() -class ProfilePage extends StatelessWidget { +class ProfilePage extends StatefulWidget { const ProfilePage({super.key}); + @override + State createState() => _ProfilePageState(); +} + +class _ProfilePageState extends State { @override Widget build(BuildContext context) { - return Center(child: Text('ProfilePage')); + return Scaffold( + backgroundColor: AppColor.background, + appBar: AppBar( + title: Text( + 'Profile', + style: AppStyle.xxl.copyWith( + color: AppColor.textWhite, + fontWeight: FontWeight.w600, + ), + ), + backgroundColor: AppColor.primary, + elevation: 0, + actions: [ + IconButton( + icon: const Icon(Icons.edit, color: AppColor.textWhite), + onPressed: () { + // Navigate to edit profile + }, + ), + ], + ), + body: SingleChildScrollView( + child: Column( + children: [ + ProfileHeader(), + const SpaceHeight(20), + ProfileAccountInfo(), + const SpaceHeight(12), + ProfileBusinessSetting(), + const SpaceHeight(12), + ProfileAppSetting(), + const SpaceHeight(12), + ProfileSupport(), + const SpaceHeight(12), + ProfileDangerZone(), + const SpaceHeight(30), + ], + ), + ), + ); } } diff --git a/lib/presentation/pages/profile/widgets/account_info.dart b/lib/presentation/pages/profile/widgets/account_info.dart new file mode 100644 index 0000000..710c325 --- /dev/null +++ b/lib/presentation/pages/profile/widgets/account_info.dart @@ -0,0 +1,83 @@ +import 'package:flutter/material.dart'; + +import '../../../../common/theme/theme.dart'; +import 'divider.dart'; +import 'profile_tile.dart'; + +class ProfileAccountInfo extends StatelessWidget { + const ProfileAccountInfo({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.symmetric(horizontal: AppValue.margin), + decoration: BoxDecoration( + color: AppColor.surface, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 10, + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.all(16), + child: Text( + 'Account Information', + style: AppStyle.xl.copyWith( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + ), + + ProfileTile( + icon: Icons.email_outlined, + title: 'Email', + subtitle: 'john.doe@business.com', + onTap: () { + // Edit email + }, + ), + + ProfileDivider(), + + ProfileTile( + icon: Icons.phone_outlined, + title: 'Phone Number', + subtitle: '+62 812 3456 7890', + onTap: () { + // Edit phone + }, + ), + + ProfileDivider(), + + ProfileTile( + icon: Icons.location_on_outlined, + title: 'Address', + subtitle: 'Jl. Merdeka No. 123, Jakarta', + onTap: () { + // Edit address + }, + ), + + ProfileDivider(), + + ProfileTile( + icon: Icons.calendar_today_outlined, + title: 'Member Since', + subtitle: 'January 15, 2024', + showArrow: false, + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/profile/widgets/app_setting.dart b/lib/presentation/pages/profile/widgets/app_setting.dart new file mode 100644 index 0000000..16b8e44 --- /dev/null +++ b/lib/presentation/pages/profile/widgets/app_setting.dart @@ -0,0 +1,100 @@ +import 'package:flutter/material.dart'; + +import '../../../../common/theme/theme.dart'; +import 'divider.dart'; +import 'profile_switch_tile.dart'; +import 'profile_tile.dart'; + +class ProfileAppSetting extends StatefulWidget { + const ProfileAppSetting({super.key}); + + @override + State createState() => _ProfileAppSettingState(); +} + +class _ProfileAppSettingState extends State { + bool _notificationsEnabled = true; + bool _darkModeEnabled = false; + + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.symmetric(horizontal: AppValue.margin), + decoration: BoxDecoration( + color: AppColor.surface, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 10, + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.all(16), + child: Text( + 'App Settings', + style: AppStyle.xl.copyWith( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + ), + + ProfileSwitchTile( + icon: Icons.notifications_outlined, + title: 'Notifications', + subtitle: 'Receive app notifications', + value: _notificationsEnabled, + onChanged: (value) { + setState(() { + _notificationsEnabled = value; + }); + }, + ), + + ProfileDivider(), + + ProfileSwitchTile( + icon: Icons.dark_mode_outlined, + title: 'Dark Mode', + subtitle: 'Switch to dark theme', + value: _darkModeEnabled, + onChanged: (value) { + setState(() { + _darkModeEnabled = value; + }); + }, + ), + + ProfileDivider(), + + ProfileTile( + icon: Icons.language_outlined, + title: 'Language', + subtitle: 'English (US)', + onTap: () { + // Show language selector + }, + ), + + ProfileDivider(), + + ProfileTile( + icon: Icons.security_outlined, + title: 'Security & Privacy', + subtitle: 'Manage your security settings', + onTap: () { + // Navigate to security settings + }, + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/profile/widgets/business_setting.dart b/lib/presentation/pages/profile/widgets/business_setting.dart new file mode 100644 index 0000000..c29d58d --- /dev/null +++ b/lib/presentation/pages/profile/widgets/business_setting.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; + +import '../../../../common/theme/theme.dart'; +import 'divider.dart'; +import 'profile_tile.dart'; + +class ProfileBusinessSetting extends StatelessWidget { + const ProfileBusinessSetting({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.symmetric(horizontal: AppValue.margin), + decoration: BoxDecoration( + color: AppColor.surface, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 10, + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.all(16), + child: Text( + 'Business Settings', + style: AppStyle.xl.copyWith( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + ), + + ProfileTile( + icon: Icons.business_outlined, + title: 'Business Information', + subtitle: 'Manage your business details', + onTap: () { + // Navigate to business info + }, + ), + + ProfileDivider(), + + ProfileTile( + icon: Icons.people_outline, + title: 'Staff Management', + subtitle: 'Manage employees and permissions', + onTap: () { + // Navigate to staff management + }, + ), + + ProfileDivider(), + + ProfileTile( + icon: Icons.payment_outlined, + title: 'Payment Methods', + subtitle: 'Configure payment options', + onTap: () { + // Navigate to payment settings + }, + ), + + ProfileDivider(), + + ProfileTile( + icon: Icons.receipt_long_outlined, + title: 'Tax Settings', + subtitle: 'Configure tax rates and policies', + onTap: () { + // Navigate to tax settings + }, + ), + + ProfileDivider(), + + ProfileTile( + icon: Icons.print_outlined, + title: 'Receipt & Print Settings', + subtitle: 'Configure receipt templates', + onTap: () { + // Navigate to print settings + }, + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/profile/widgets/danger_zone.dart b/lib/presentation/pages/profile/widgets/danger_zone.dart new file mode 100644 index 0000000..376247f --- /dev/null +++ b/lib/presentation/pages/profile/widgets/danger_zone.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; + +import '../../../../common/theme/theme.dart'; +import '../../../components/spacer/spacer.dart'; +import 'profile_tile.dart'; + +class ProfileDangerZone extends StatelessWidget { + const ProfileDangerZone({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.symmetric(horizontal: AppValue.margin), + decoration: BoxDecoration( + color: AppColor.surface, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: AppColor.error.withOpacity(0.3)), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 10, + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(16), + child: Row( + children: [ + Icon(Icons.warning_outlined, color: AppColor.error, size: 20), + const SpaceWidth(8), + Text( + 'Danger Zone', + style: AppStyle.xl.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.error, + ), + ), + ], + ), + ), + + ProfileTile( + icon: Icons.logout, + title: 'Logout', + subtitle: 'Sign out from your account', + iconColor: AppColor.error, + textColor: AppColor.error, + onTap: () {}, + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/profile/widgets/divider.dart b/lib/presentation/pages/profile/widgets/divider.dart new file mode 100644 index 0000000..12add2b --- /dev/null +++ b/lib/presentation/pages/profile/widgets/divider.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; + +import '../../../../common/theme/theme.dart'; + +class ProfileDivider extends StatelessWidget { + const ProfileDivider({super.key}); + + @override + Widget build(BuildContext context) { + return Divider( + height: 1, + thickness: 1, + color: AppColor.border, + indent: 16, + endIndent: 16, + ); + } +} diff --git a/lib/presentation/pages/profile/widgets/header.dart b/lib/presentation/pages/profile/widgets/header.dart new file mode 100644 index 0000000..8688b9a --- /dev/null +++ b/lib/presentation/pages/profile/widgets/header.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; + +import '../../../../common/theme/theme.dart'; +import '../../../components/spacer/spacer.dart'; + +class ProfileHeader extends StatelessWidget { + const ProfileHeader({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: AppColor.primaryGradient, + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ), + child: Column( + children: [ + const SpaceHeight(20), + + // Profile Picture + Container( + width: 100, + height: 100, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all(color: AppColor.textWhite, width: 3), + color: AppColor.primaryLight, + ), + child: ClipOval( + child: Container( + color: AppColor.primaryLight, + child: const Icon( + Icons.person, + size: 50, + color: AppColor.textWhite, + ), + ), + ), + ), + + const SpaceHeight(16), + + // Name + Text( + 'John Doe', + style: AppStyle.h5.copyWith( + fontSize: 24, + fontWeight: FontWeight.bold, + color: AppColor.textWhite, + ), + ), + + const SpaceHeight(4), + + // Role Badge + Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6), + decoration: BoxDecoration( + color: AppColor.textWhite.withOpacity(0.2), + borderRadius: BorderRadius.circular(20), + ), + child: Text( + 'Business Owner', + style: AppStyle.md.copyWith( + color: AppColor.textWhite, + fontWeight: FontWeight.w500, + ), + ), + ), + + const SpaceHeight(30), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/profile/widgets/profile_switch_tile.dart b/lib/presentation/pages/profile/widgets/profile_switch_tile.dart new file mode 100644 index 0000000..a7d8a71 --- /dev/null +++ b/lib/presentation/pages/profile/widgets/profile_switch_tile.dart @@ -0,0 +1,51 @@ +import 'package:flutter/material.dart'; + +import '../../../../common/theme/theme.dart'; + +class ProfileSwitchTile extends StatelessWidget { + final IconData icon; + final String title; + final String? subtitle; + final bool value; + final ValueChanged onChanged; + const ProfileSwitchTile({ + super.key, + required this.icon, + required this.title, + this.subtitle, + required this.value, + required this.onChanged, + }); + + @override + Widget build(BuildContext context) { + return ListTile( + leading: Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: AppColor.primary.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: Icon(icon, color: AppColor.primary, size: 20), + ), + title: Text( + title, + style: AppStyle.lg.copyWith( + fontWeight: FontWeight.w500, + color: AppColor.textPrimary, + ), + ), + subtitle: subtitle != null + ? Text( + subtitle!, + style: AppStyle.md.copyWith(color: AppColor.textSecondary), + ) + : null, + trailing: Switch( + value: value, + onChanged: onChanged, + activeColor: AppColor.primary, + ), + ); + } +} diff --git a/lib/presentation/pages/profile/widgets/profile_tile.dart b/lib/presentation/pages/profile/widgets/profile_tile.dart new file mode 100644 index 0000000..6f71ef1 --- /dev/null +++ b/lib/presentation/pages/profile/widgets/profile_tile.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; + +import '../../../../common/theme/theme.dart'; + +class ProfileTile extends StatelessWidget { + final IconData icon; + final String title; + final String? subtitle; + final VoidCallback? onTap; + final bool showArrow; + final Color? iconColor; + final Color? textColor; + const ProfileTile({ + super.key, + required this.icon, + required this.title, + this.subtitle, + this.onTap, + this.showArrow = true, + this.iconColor, + this.textColor, + }); + + @override + Widget build(BuildContext context) { + return ListTile( + leading: Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: (iconColor ?? AppColor.primary).withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: Icon(icon, color: iconColor ?? AppColor.primary, size: 20), + ), + title: Text( + title, + style: AppStyle.lg.copyWith( + fontWeight: FontWeight.w500, + color: textColor ?? AppColor.textPrimary, + ), + ), + subtitle: subtitle != null + ? Text( + subtitle!, + style: AppStyle.md.copyWith(color: AppColor.textSecondary), + ) + : null, + trailing: showArrow + ? Icon(Icons.chevron_right, color: AppColor.textLight, size: 20) + : null, + onTap: onTap, + ); + } +} diff --git a/lib/presentation/pages/profile/widgets/support.dart b/lib/presentation/pages/profile/widgets/support.dart new file mode 100644 index 0000000..f229dee --- /dev/null +++ b/lib/presentation/pages/profile/widgets/support.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; + +import '../../../../common/theme/theme.dart'; +import 'divider.dart'; +import 'profile_tile.dart'; + +class ProfileSupport extends StatelessWidget { + const ProfileSupport({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.symmetric(horizontal: AppValue.margin), + decoration: BoxDecoration( + color: AppColor.surface, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 10, + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.all(16), + child: Text( + 'Support', + style: AppStyle.xl.copyWith( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + ), + + ProfileTile( + icon: Icons.help_outline, + title: 'Help Center', + subtitle: 'Get help and support', + onTap: () { + // Navigate to help center + }, + ), + + ProfileDivider(), + + ProfileTile( + icon: Icons.feedback_outlined, + title: 'Send Feedback', + subtitle: 'Help us improve the app', + onTap: () { + // Open feedback form + }, + ), + + ProfileDivider(), + + ProfileTile( + icon: Icons.info_outline, + title: 'About', + subtitle: 'App version and information', + onTap: () { + // Show about dialog + }, + ), + ], + ), + ); + } +}