Add basic UI for referral screen and apply code
This commit is contained in:
parent
12c65f3d2e
commit
db27608b9c
155
lib/ui/growth/apply_code_screen.dart
Normal file
155
lib/ui/growth/apply_code_screen.dart
Normal file
|
@ -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<ApplyCodeScreen> createState() => _ApplyCodeScreenState();
|
||||
}
|
||||
|
||||
class _ApplyCodeScreenState extends State<ApplyCodeScreen> {
|
||||
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: <Widget>[
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
229
lib/ui/growth/referral_screen.dart
Normal file
229
lib/ui/growth/referral_screen.dart
Normal file
|
@ -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<ReferralScreen> createState() => _ReferralScreenState();
|
||||
}
|
||||
|
||||
class _ReferralScreenState extends State<ReferralScreen> {
|
||||
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: <Widget>[
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue