chore(ui): shopinbit step 4 forms cleanup
What changed, and why it matters
This commit is a routine user-interface cleanup for the ShopinBit checkout flow. It swaps one dialog widget for another, adjusts spacing and padding, replaces a Material icon with an SVG icon, removes an unused internal warning dialog, and tweaks dropdown positioning. There is no indication of any security fix or behavior change that would affect user safety.
No security action required. Treat as a normal UI maintenance commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff is a pure UI refactor in Dart/Flutter files under lib/pages/shopinbit/step_4_components. Changes include: replacing DesktopDialog with SDialog in shopinbit_step_4.dart; removing SingleChildScrollView and switching Expanded to Flexible; adjusting EdgeInsets and SizedBox heights; replacing Icons.info_outline with SvgPicture.asset(Assets.svg.circleInfo); removing the unused _DesktopBrowserWarning private widget from shopinbit_privacy_checkbox.dart; removing ClipRRect wrappers around DropdownButton2 widgets and changing dropdown offset from Offset(0, 0) to Offset(0, -10); adding mainAxisSize: MainAxisSize.min to a Column. No logic, validation, network, crypto, or storage code is modified.
Changed components
lib/pages/shopinbit/shopinbit_step_4.dartlib/pages/shopinbit/step_4_components/shopinbit_car_research_form.dartlib/pages/shopinbit/step_4_components/shopinbit_concierge_form.dartlib/pages/shopinbit/step_4_components/shopinbit_country_picker.dartlib/pages/shopinbit/step_4_components/shopinbit_privacy_checkbox.dartlib/pages/shopinbit/step_4_components/shopinbit_step4_dropdown.dartlib/pages/shopinbit/step_4_components/shopinbit_step4_header.dartlib/pages/shopinbit/step_4_components/shopinbit_travel_form.dartInspect captured patch +159 / −199
diff --git a/lib/pages/shopinbit/shopinbit_step_4.dart b/lib/pages/shopinbit/shopinbit_step_4.dart
index 67a67a7..3927795 100644
--- a/lib/pages/shopinbit/shopinbit_step_4.dart
+++ b/lib/pages/shopinbit/shopinbit_step_4.dart
@@ -7,9 +7,9 @@ import "../../utilities/util.dart";
import "../../widgets/background.dart";
import "../../widgets/conditional_parent.dart";
import "../../widgets/custom_buttons/app_bar_icon_button.dart";
-import "../../widgets/desktop/desktop_dialog.dart";
import "../../widgets/desktop/desktop_dialog_close_button.dart";
import "../../widgets/dialogs/nested_navigator_dialog/nested_navigator_dialog.dart";
+import "../../widgets/dialogs/s_dialog.dart";
import "step_4_components/shopinbit_car_research_form.dart";
import "step_4_components/shopinbit_concierge_form.dart";
import "step_4_components/shopinbit_generic_form.dart";
@@ -48,33 +48,35 @@ class _ShopInBitStep4DesktopShell extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return DesktopDialog(
- maxWidth: 580,
- maxHeight: 750,
- child: Column(
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Row(
- children: [
- const AppBarBackButton(isCompact: true, iconSize: 23),
- Text("ShopinBit", style: STextStyles.desktopH3(context)),
- ],
- ),
- DesktopDialogCloseButton(
- onPressedOverride: () =>
- confirmCloseNestedNavigatorDialog(context),
+ return SDialog(
+ child: SizedBox(
+ width: 580,
+ child: Column(
+ mainAxisSize: .min,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ children: [
+ const AppBarBackButton(isCompact: true, iconSize: 23),
+ Text("ShopinBit", style: STextStyles.desktopH3(context)),
+ ],
+ ),
+ DesktopDialogCloseButton(
+ onPressedOverride: () =>
+ confirmCloseNestedNavigatorDialog(context),
+ ),
+ ],
+ ),
+ Flexible(
+ child: Padding(
+ padding: const .only(left: 32, right: 32, bottom: 32, top: 16),
+ child: content,
),
- ],
- ),
- Expanded(
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
- child: SingleChildScrollView(child: content),
),
- ),
- ],
+ ],
+ ),
),
);
}
diff --git a/lib/pages/shopinbit/step_4_components/shopinbit_car_research_form.dart b/lib/pages/shopinbit/step_4_components/shopinbit_car_research_form.dart
index 30df425..35cd7d6 100644
--- a/lib/pages/shopinbit/step_4_components/shopinbit_car_research_form.dart
+++ b/lib/pages/shopinbit/step_4_components/shopinbit_car_research_form.dart
@@ -3,10 +3,12 @@ import "dart:async";
import "package:flutter/material.dart";
import "package:flutter/services.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
+import "package:flutter_svg/flutter_svg.dart";
import "../../../models/shopinbit/shopinbit_order_model.dart";
import "../../../providers/db/drift_provider.dart";
import "../../../themes/stack_colors.dart";
+import "../../../utilities/assets.dart";
import "../../../utilities/text_styles.dart";
import "../../../utilities/util.dart";
import "../../../widgets/rounded_white_container.dart";
@@ -292,12 +294,12 @@ class _ShopInBitCarResearchFormState
onChanged: (v) => setState(() => _feeAcknowledged = v),
label: "I acknowledge the \u20AC223 research fee",
),
- SizedBox(height: isDesktop ? 16 : 12),
+ SizedBox(height: isDesktop ? 24 : 16),
ShopInBitPrivacyCheckbox(
value: _privacyAccepted,
onChanged: (v) => setState(() => _privacyAccepted = v),
),
- SizedBox(height: isDesktop ? 16 : 12),
+ SizedBox(height: isDesktop ? 32 : 20),
ShopInBitStep4SubmitButton(
submitting: _submitting,
enabled: _canContinue,
@@ -321,15 +323,22 @@ class _CarResearchFeeInfo extends StatelessWidget {
: STextStyles.w500_14(context);
return RoundedWhiteContainer(
+ borderColor: isDesktop
+ ? Theme.of(context).extension<StackColors>()!.textFieldDefaultBG
+ : null,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
- Icon(
- Icons.info_outline,
- size: 20,
- color: Theme.of(
- context,
- ).extension<StackColors>()!.textFieldActiveSearchIconLeft,
+ SvgPicture.asset(
+ Assets.svg.circleInfo,
+ width: 20,
+ height: 20,
+ colorFilter: ColorFilter.mode(
+ Theme.of(
+ context,
+ ).extension<StackColors>()!.textFieldActiveSearchIconLeft,
+ .srcIn,
+ ),
),
const SizedBox(width: 12),
Expanded(
diff --git a/lib/pages/shopinbit/step_4_components/shopinbit_concierge_form.dart b/lib/pages/shopinbit/step_4_components/shopinbit_concierge_form.dart
index 1c8a07e..968d349 100644
--- a/lib/pages/shopinbit/step_4_components/shopinbit_concierge_form.dart
+++ b/lib/pages/shopinbit/step_4_components/shopinbit_concierge_form.dart
@@ -183,17 +183,17 @@ class _ShopInBitConciergeFormState
onChanged: (v) => setState(() => _noLimit = v),
label: "No budget limit",
),
- SizedBox(height: isDesktop ? 12 : 12),
+ SizedBox(height: isDesktop ? 24 : 16),
ShopInBitCountryPicker(
selectedIso: _selectedCountryIso,
onChanged: (iso) => setState(() => _selectedCountryIso = iso),
),
- SizedBox(height: isDesktop ? 12 : 12),
+ SizedBox(height: isDesktop ? 16 : 12),
ShopInBitPrivacyCheckbox(
value: _privacyAccepted,
onChanged: (v) => setState(() => _privacyAccepted = v),
),
- SizedBox(height: isDesktop ? 16 : 12),
+ SizedBox(height: isDesktop ? 32 : 20),
ShopInBitStep4SubmitButton(
submitting: _submitting,
enabled: _canContinue,
diff --git a/lib/pages/shopinbit/step_4_components/shopinbit_country_picker.dart b/lib/pages/shopinbit/step_4_components/shopinbit_country_picker.dart
index f0feb9d..4f59c68 100644
--- a/lib/pages/shopinbit/step_4_components/shopinbit_country_picker.dart
+++ b/lib/pages/shopinbit/step_4_components/shopinbit_country_picker.dart
@@ -78,88 +78,85 @@ class _ShopInBitCountryPickerState
).copyWith(color: stackColors.textFieldDefaultSearchIconLeft)
: STextStyles.fieldLabel(context);
- return ClipRRect(
- borderRadius: BorderRadius.circular(Constants.size.circularBorderRadius),
- child: DropdownButtonHideUnderline(
- child: DropdownButton2<String>(
- value: widget.selectedIso,
- items: _countries
- .map(
- (c) => DropdownMenuItem<String>(
- value: c["iso"] as String,
- child: Text(c["label"] as String, style: itemStyle),
- ),
- )
- .toList(),
- onMenuStateChange: (isOpen) {
- if (!isOpen) {
- _searchController.clear();
- }
- },
- onChanged: _loading ? null : widget.onChanged,
- hint: Text(
- _loading ? "Loading countries..." : widget.hintText,
- style: hintStyle,
- ),
- isExpanded: true,
- buttonStyleData: ButtonStyleData(
- decoration: BoxDecoration(
- color: stackColors.textFieldDefaultBG,
- borderRadius: BorderRadius.circular(
- Constants.size.circularBorderRadius,
+ return DropdownButtonHideUnderline(
+ child: DropdownButton2<String>(
+ value: widget.selectedIso,
+ items: _countries
+ .map(
+ (c) => DropdownMenuItem<String>(
+ value: c["iso"] as String,
+ child: Text(c["label"] as String, style: itemStyle),
),
+ )
+ .toList(),
+ onMenuStateChange: (isOpen) {
+ if (!isOpen) {
+ _searchController.clear();
+ }
+ },
+ onChanged: _loading ? null : widget.onChanged,
+ hint: Text(
+ _loading ? "Loading countries..." : widget.hintText,
+ style: hintStyle,
+ ),
+ isExpanded: true,
+ buttonStyleData: ButtonStyleData(
+ decoration: BoxDecoration(
+ color: stackColors.textFieldDefaultBG,
+ borderRadius: BorderRadius.circular(
+ Constants.size.circularBorderRadius,
),
),
- iconStyleData: IconStyleData(
- icon: Padding(
- padding: const EdgeInsets.only(right: 10),
- child: SvgPicture.asset(
- Assets.svg.chevronDown,
- width: 12,
- height: 6,
- color: stackColors.textFieldActiveSearchIconRight,
- ),
+ ),
+ iconStyleData: IconStyleData(
+ icon: Padding(
+ padding: const EdgeInsets.only(right: 10),
+ child: SvgPicture.asset(
+ Assets.svg.chevronDown,
+ width: 12,
+ height: 6,
+ color: stackColors.textFieldActiveSearchIconRight,
),
),
- dropdownStyleData: DropdownStyleData(
- offset: const Offset(0, 0),
- elevation: 0,
- maxHeight: 300,
- decoration: BoxDecoration(
- color: stackColors.textFieldDefaultBG,
- borderRadius: BorderRadius.circular(
- Constants.size.circularBorderRadius,
- ),
+ ),
+ dropdownStyleData: DropdownStyleData(
+ offset: const Offset(0, -10),
+ elevation: 0,
+ maxHeight: 300,
+ decoration: BoxDecoration(
+ color: stackColors.textFieldDefaultBG,
+ borderRadius: BorderRadius.circular(
+ Constants.size.circularBorderRadius,
),
),
- dropdownSearchData: DropdownSearchData<String>(
- searchController: _searchController,
- searchInnerWidgetHeight: 48,
- searchInnerWidget: TextFormField(
- controller: _searchController,
- decoration: InputDecoration(
- isDense: true,
- contentPadding: const EdgeInsets.symmetric(
- horizontal: 16,
- vertical: 14,
- ),
- hintText: "Search...",
- hintStyle: STextStyles.fieldLabel(context),
- border: InputBorder.none,
+ ),
+ dropdownSearchData: DropdownSearchData<String>(
+ searchController: _searchController,
+ searchInnerWidgetHeight: 48,
+ searchInnerWidget: TextFormField(
+ controller: _searchController,
+ decoration: InputDecoration(
+ isDense: true,
+ contentPadding: const EdgeInsets.symmetric(
+ horizontal: 16,
+ vertical: 14,
),
+ hintText: "Search...",
+ hintStyle: STextStyles.fieldLabel(context),
+ border: InputBorder.none,
),
- searchMatchFn: (item, searchValue) {
- final String? label = _countries
- .where((c) => c["iso"] == item.value)
- .map((c) => c["label"] as String)
- .firstOrNull;
- return label?.toLowerCase().contains(searchValue.toLowerCase()) ??
- false;
- },
- ),
- menuItemStyleData: const MenuItemStyleData(
- padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
),
+ searchMatchFn: (item, searchValue) {
+ final String? label = _countries
+ .where((c) => c["iso"] == item.value)
+ .map((c) => c["label"] as String)
+ .firstOrNull;
+ return label?.toLowerCase().contains(searchValue.toLowerCase()) ??
+ false;
+ },
+ ),
+ menuItemStyleData: const MenuItemStyleData(
+ padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
),
),
);
diff --git a/lib/pages/shopinbit/step_4_components/shopinbit_privacy_checkbox.dart b/lib/pages/shopinbit/step_4_components/shopinbit_privacy_checkbox.dart
index d5d3347..5135a89 100644
--- a/lib/pages/shopinbit/step_4_components/shopinbit_privacy_checkbox.dart
+++ b/lib/pages/shopinbit/step_4_components/shopinbit_privacy_checkbox.dart
@@ -3,9 +3,6 @@ import "package:flutter/material.dart";
import "../../../utilities/text_styles.dart";
import "../../../utilities/util.dart";
-import "../../../widgets/desktop/desktop_dialog.dart";
-import "../../../widgets/desktop/primary_button.dart";
-import "../../../widgets/desktop/secondary_button.dart";
import "../../../widgets/dialogs/request_external_link_navigation_dialog.dart";
const String _shopInBitPrivacyUrl =
@@ -81,46 +78,3 @@ class ShopInBitPrivacyCheckbox extends StatelessWidget {
);
}
}
-
-class _DesktopBrowserWarning extends StatelessWidget {
- const _DesktopBrowserWarning({required this.message});
-
- final String message;
-
- @override
- Widget build(BuildContext context) {
- return DesktopDialog(
- maxWidth: 550,
- maxHeight: 250,
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 20),
- child: Column(
- children: [
- Text("Attention", style: STextStyles.desktopH2(context)),
- const SizedBox(height: 16),
- Text(message, style: STextStyles.desktopTextSmall(context)),
- const SizedBox(height: 35),
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- SecondaryButton(
- width: 200,
- buttonHeight: ButtonHeight.l,
- label: "Cancel",
- onPressed: () => Navigator.of(context).pop(false),
- ),
- const SizedBox(width: 20),
- PrimaryButton(
- width: 200,
- buttonHeight: ButtonHeight.l,
- label: "Continue",
- onPressed: () => Navigator.of(context).pop(true),
- ),
- ],
- ),
- ],
- ),
- ),
- );
- }
-}
diff --git a/lib/pages/shopinbit/step_4_components/shopinbit_step4_dropdown.dart b/lib/pages/shopinbit/step_4_components/shopinbit_step4_dropdown.dart
index baae092..d3b2e53 100644
--- a/lib/pages/shopinbit/step_4_components/shopinbit_step4_dropdown.dart
+++ b/lib/pages/shopinbit/step_4_components/shopinbit_step4_dropdown.dart
@@ -38,54 +38,51 @@ class ShopInBitStep4Dropdown extends StatelessWidget {
).copyWith(color: stackColors.textFieldDefaultSearchIconLeft)
: STextStyles.fieldLabel(context);
- return ClipRRect(
- borderRadius: BorderRadius.circular(Constants.size.circularBorderRadius),
- child: DropdownButtonHideUnderline(
- child: DropdownButton2<String>(
- value: value,
- items: items
- .map(
- (item) => DropdownMenuItem<String>(
- value: item,
- child: Text(item, style: itemStyle),
- ),
- )
- .toList(),
- onChanged: onChanged,
- hint: Text(hintText, style: hintStyle),
- isExpanded: true,
- buttonStyleData: ButtonStyleData(
- decoration: BoxDecoration(
- color: stackColors.textFieldDefaultBG,
- borderRadius: BorderRadius.circular(
- Constants.size.circularBorderRadius,
+ return DropdownButtonHideUnderline(
+ child: DropdownButton2<String>(
+ value: value,
+ items: items
+ .map(
+ (item) => DropdownMenuItem<String>(
+ value: item,
+ child: Text(item, style: itemStyle),
),
+ )
+ .toList(),
+ onChanged: onChanged,
+ hint: Text(hintText, style: hintStyle),
+ isExpanded: true,
+ buttonStyleData: ButtonStyleData(
+ decoration: BoxDecoration(
+ color: stackColors.textFieldDefaultBG,
+ borderRadius: BorderRadius.circular(
+ Constants.size.circularBorderRadius,
),
),
- iconStyleData: IconStyleData(
- icon: Padding(
- padding: const EdgeInsets.only(right: 10),
- child: SvgPicture.asset(
- Assets.svg.chevronDown,
- width: 12,
- height: 6,
- color: stackColors.textFieldActiveSearchIconRight,
- ),
+ ),
+ iconStyleData: IconStyleData(
+ icon: Padding(
+ padding: const EdgeInsets.only(right: 10),
+ child: SvgPicture.asset(
+ Assets.svg.chevronDown,
+ width: 12,
+ height: 6,
+ color: stackColors.textFieldActiveSearchIconRight,
),
),
- dropdownStyleData: DropdownStyleData(
- offset: const Offset(0, 0),
- elevation: 0,
- decoration: BoxDecoration(
- color: stackColors.textFieldDefaultBG,
- borderRadius: BorderRadius.circular(
- Constants.size.circularBorderRadius,
- ),
+ ),
+ dropdownStyleData: DropdownStyleData(
+ offset: const Offset(0, -10),
+ elevation: 0,
+ decoration: BoxDecoration(
+ color: stackColors.textFieldDefaultBG,
+ borderRadius: BorderRadius.circular(
+ Constants.size.circularBorderRadius,
),
),
- menuItemStyleData: const MenuItemStyleData(
- padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
- ),
+ ),
+ menuItemStyleData: const MenuItemStyleData(
+ padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
),
),
);
diff --git a/lib/pages/shopinbit/step_4_components/shopinbit_step4_header.dart b/lib/pages/shopinbit/step_4_components/shopinbit_step4_header.dart
index 4c81d7d..c7b20e1 100644
--- a/lib/pages/shopinbit/step_4_components/shopinbit_step4_header.dart
+++ b/lib/pages/shopinbit/step_4_components/shopinbit_step4_header.dart
@@ -17,6 +17,7 @@ class ShopInBitStep4Header extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
+ mainAxisSize: .min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (!Util.isDesktop) ...[
diff --git a/lib/pages/shopinbit/step_4_components/shopinbit_travel_form.dart b/lib/pages/shopinbit/step_4_components/shopinbit_travel_form.dart
index 80382eb..0f2e5a6 100644
--- a/lib/pages/shopinbit/step_4_components/shopinbit_travel_form.dart
+++ b/lib/pages/shopinbit/step_4_components/shopinbit_travel_form.dart
@@ -398,7 +398,7 @@ class _ShopInBitTravelFormState extends ConsumerState<ShopInBitTravelForm> {
errorText: destinationsError,
onChanged: (_) => setState(() {}),
),
- SizedBox(height: isDesktop ? 12 : 8),
+ SizedBox(height: isDesktop ? 16 : 12),
ShopInBitLabeledCheckbox(
value: _needsRecommendations,
onChanged: (v) => setState(() => _needsRecommendations = v),
@@ -531,12 +531,12 @@ class _ShopInBitTravelFormState extends ConsumerState<ShopInBitTravelForm> {
// Travel doesn't collect delivery country: destinations are in the
// form and the API field is set to "DE" on submit.
- SizedBox(height: isDesktop ? 16 : 12),
+ SizedBox(height: isDesktop ? 24 : 16),
ShopInBitPrivacyCheckbox(
value: _privacyAccepted,
onChanged: (v) => setState(() => _privacyAccepted = v),
),
- SizedBox(height: isDesktop ? 16 : 12),
+ SizedBox(height: isDesktop ? 32 : 20),
ShopInBitStep4SubmitButton(
submitting: _submitting,
enabled: _canContinue,
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.