From db27608b9ceb8f61f5fefdceef802b071899bde0 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Wed, 15 Feb 2023 15:58:41 +0530 Subject: [PATCH] Add basic UI for referral screen and apply code --- lib/ui/growth/apply_code_screen.dart | 155 +++++++++++++ lib/ui/growth/referral_screen.dart | 229 ++++++++++++++++++++ lib/ui/settings/general_section_widget.dart | 16 ++ 3 files changed, 400 insertions(+) create mode 100644 lib/ui/growth/apply_code_screen.dart create mode 100644 lib/ui/growth/referral_screen.dart diff --git a/lib/ui/growth/apply_code_screen.dart b/lib/ui/growth/apply_code_screen.dart new file mode 100644 index 000000000..19aee5ce4 --- /dev/null +++ b/lib/ui/growth/apply_code_screen.dart @@ -0,0 +1,155 @@ +import "package:flutter/material.dart"; +import "package:photos/extensions/input_formatter.dart"; +import "package:photos/theme/ente_theme.dart"; +import "package:photos/ui/components/button_widget.dart"; +import "package:photos/ui/components/icon_button_widget.dart"; +import "package:photos/ui/components/models/button_type.dart"; +import "package:photos/ui/components/title_bar_title_widget.dart"; +import "package:photos/ui/components/title_bar_widget.dart"; + +class ApplyCodeScreen extends StatefulWidget { + const ApplyCodeScreen({super.key}); + + @override + State createState() => _ApplyCodeScreenState(); +} + +class _ApplyCodeScreenState extends State { + late TextEditingController _textController; + + late FocusNode textFieldFocusNode; + String code = ""; + + @override + void initState() { + _textController = TextEditingController(); + textFieldFocusNode = FocusNode(); + super.initState(); + } + + @override + void dispose() { + _textController.dispose(); + textFieldFocusNode.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final colorScheme = getEnteColorScheme(context); + final textStyle = getEnteTextTheme(context); + textFieldFocusNode.requestFocus(); + return Scaffold( + body: CustomScrollView( + primary: false, + slivers: [ + TitleBarWidget( + flexibleSpaceTitle: const TitleBarTitleWidget( + title: "Apply code", + ), + actionIcons: [ + IconButtonWidget( + icon: Icons.close_outlined, + iconButtonType: IconButtonType.secondary, + onTap: () { + // Go three screen back, similar to pop thrice + Navigator.of(context) + ..pop() + ..pop() + ..pop(); + }, + ), + ], + ), + SliverList( + delegate: SliverChildBuilderDelegate( + (delegateBuildContext, index) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 20), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Column( + children: [ + Text( + "Enter the code provided by your friend to " + "claim free storage for both of you", + style: textStyle.small + .copyWith(color: colorScheme.textMuted), + ), + const SizedBox(height: 24), + _getInputField(), + // Container with 8 border radius and red color + ], + ), + ], + ), + ), + ); + }, + childCount: 1, + ), + ), + SliverFillRemaining( + child: SafeArea( + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + ButtonWidget( + buttonType: ButtonType.neutral, + buttonSize: ButtonSize.large, + labelText: "Apply", + isDisabled: code.trim().length < 4, + onTap: () async { + debugPrint("yet to implement"); + }, + ) + ], + ), + ), + ), + ), + ], + ), + ); + } + + Widget _getInputField() { + return TextFormField( + controller: _textController, + focusNode: textFieldFocusNode, + style: getEnteTextTheme(context).body, + inputFormatters: [UpperCaseTextFormatter()], + textCapitalization: TextCapitalization.sentences, + decoration: InputDecoration( + focusedBorder: OutlineInputBorder( + borderRadius: const BorderRadius.all(Radius.circular(4.0)), + borderSide: + BorderSide(color: getEnteColorScheme(context).strokeMuted), + ), + fillColor: getEnteColorScheme(context).fillFaint, + filled: true, + hintText: 'Enter referral code', + contentPadding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 14, + ), + border: UnderlineInputBorder( + borderSide: BorderSide.none, + borderRadius: BorderRadius.circular(8), + ), + ), + onChanged: (value) { + code = value.trim(); + setState(() {}); + }, + autocorrect: false, + keyboardType: TextInputType.emailAddress, + textInputAction: TextInputAction.next, + ); + } +} diff --git a/lib/ui/growth/referral_screen.dart b/lib/ui/growth/referral_screen.dart new file mode 100644 index 000000000..3309fd984 --- /dev/null +++ b/lib/ui/growth/referral_screen.dart @@ -0,0 +1,229 @@ +import "package:dotted_border/dotted_border.dart"; +import "package:flutter/material.dart"; +import "package:photos/theme/ente_theme.dart"; +import "package:photos/ui/components/captioned_text_widget.dart"; +import "package:photos/ui/components/divider_widget.dart"; +import "package:photos/ui/components/icon_button_widget.dart"; +import "package:photos/ui/components/menu_item_widget/menu_item_widget.dart"; +import "package:photos/ui/components/title_bar_title_widget.dart"; +import "package:photos/ui/components/title_bar_widget.dart"; +import "package:photos/ui/growth/apply_code_screen.dart"; +import "package:photos/ui/tools/debug/app_storage_viewer.dart"; +import "package:photos/utils/navigation_util.dart"; + +class ReferralScreen extends StatefulWidget { + const ReferralScreen({super.key}); + + @override + State createState() => _ReferralScreenState(); +} + +class _ReferralScreenState extends State { + bool canApplyCode = true; + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + final colorScheme = getEnteColorScheme(context); + final textStyle = getEnteTextTheme(context); + return Scaffold( + body: CustomScrollView( + primary: false, + slivers: [ + TitleBarWidget( + flexibleSpaceTitle: const TitleBarTitleWidget( + title: "Claim free storage", + ), + flexibleSpaceCaption: "Invite friends to claim free storage", + actionIcons: [ + IconButtonWidget( + icon: Icons.close_outlined, + iconButtonType: IconButtonType.secondary, + onTap: () { + Navigator.pop(context); + Navigator.pop(context); + }, + ), + ], + ), + SliverList( + delegate: SliverChildBuilderDelegate( + (delegateBuildContext, index) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 20), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Container with 8 border radius and red color + Container( + width: double.infinity, + decoration: BoxDecoration( + border: Border.all( + color: colorScheme.strokeFaint, + width: 1, + ), + borderRadius: BorderRadius.circular(8), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 12, + horizontal: 12, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + "1. Give this code to your " + "friends", + ), + const SizedBox(height: 12), + Center( + child: DottedBorder( + color: colorScheme.strokeMuted, + //color of dotted/dash line + strokeWidth: 1, + //thickness of dash/dots + dashPattern: const [6, 6], + radius: const Radius.circular(8), + child: Padding( + padding: const EdgeInsets.only( + left: 26.0, + top: 14, + right: 12, + bottom: 14, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "AX17D9EB", + style: + textStyle.bodyBold.copyWith( + color: colorScheme.primary700, + ), + ), + const SizedBox(width: 12), + Icon( + Icons.adaptive.share, + size: 22, + color: colorScheme.strokeMuted, + ) + ], + ), + ), + ), + ), + const SizedBox(height: 12), + const Text( + "2. They sign up for a paid plan", + ), + const SizedBox(height: 12), + const Text( + "3. Both of you get 10 GB* free", + ), + ], + ), + ), + ), + const SizedBox(height: 4), + Text( + "* You can at max double your storage", + style: textStyle.mini.copyWith( + color: colorScheme.textMuted, + ), + textAlign: TextAlign.left, + ), + const SizedBox(height: 24), + canApplyCode + ? MenuItemWidget( + captionedTextWidget: + const CaptionedTextWidget( + title: "Apply code", + ), + menuItemColor: colorScheme.fillFaint, + trailingWidget: Icon( + Icons.chevron_right_outlined, + color: colorScheme.strokeBase, + ), + singleBorderRadius: 8, + alignCaptionedTextToLeft: true, + isBottomBorderRadiusRemoved: true, + onTap: () async { + routeToPage( + context, const ApplyCodeScreen()); + }, + ) + : const SizedBox.shrink(), + canApplyCode + ? DividerWidget( + dividerType: DividerType.menu, + bgColor: colorScheme.fillFaint, + ) + : const SizedBox.shrink(), + MenuItemWidget( + captionedTextWidget: const CaptionedTextWidget( + title: "FAQ", + ), + menuItemColor: colorScheme.fillFaint, + trailingWidget: Icon( + Icons.chevron_right_outlined, + color: colorScheme.strokeBase, + ), + singleBorderRadius: 8, + isTopBorderRadiusRemoved: canApplyCode, + alignCaptionedTextToLeft: true, + onTap: () async { + routeToPage(context, const AppStorageViewer()); + }, + ), + const SizedBox(height: 24), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0, + vertical: 6.0, + ), + child: Text( + "You have claimed 0 GB so far", + style: textStyle.small.copyWith( + color: colorScheme.textMuted, + ), + ), + ), + MenuItemWidget( + captionedTextWidget: const CaptionedTextWidget( + title: "Details", + ), + menuItemColor: colorScheme.fillFaint, + trailingWidget: Icon( + Icons.chevron_right_outlined, + color: colorScheme.strokeBase, + ), + singleBorderRadius: 8, + alignCaptionedTextToLeft: true, + onTap: () async { + routeToPage(context, const AppStorageViewer()); + }, + ), + ], + ), + ], + ), + ), + ); + }, + childCount: 1, + ), + ), + ], + ), + ); + } +} diff --git a/lib/ui/settings/general_section_widget.dart b/lib/ui/settings/general_section_widget.dart index 23b9eff89..6ddb27f41 100644 --- a/lib/ui/settings/general_section_widget.dart +++ b/lib/ui/settings/general_section_widget.dart @@ -6,6 +6,7 @@ import 'package:photos/ui/advanced_settings_screen.dart'; import 'package:photos/ui/components/captioned_text_widget.dart'; import 'package:photos/ui/components/expandable_menu_item_widget.dart'; import 'package:photos/ui/components/menu_item_widget/menu_item_widget.dart'; +import "package:photos/ui/growth/referral_screen.dart"; import 'package:photos/ui/payment/subscription.dart'; import 'package:photos/ui/settings/common_settings.dart'; import 'package:photos/utils/navigation_util.dart'; @@ -51,6 +52,21 @@ class GeneralSectionWidget extends StatelessWidget { }, ), sectionOptionSpacing, + MenuItemWidget( + captionedTextWidget: const CaptionedTextWidget( + title: "Referrals", + ), + pressedColor: getEnteColorScheme(context).fillFaint, + trailingIcon: Icons.chevron_right_outlined, + trailingIconIsMuted: true, + onTap: () async { + routeToPage( + context, + const ReferralScreen(), + ); + }, + ), + sectionOptionSpacing, MenuItemWidget( captionedTextWidget: const CaptionedTextWidget( title: "Advanced",