feat(web): improved user onboarding (#18782)

* wip

* added user metadata key

* wip

* restructure onboarding system and add initial locale

* update language card and fix translation updating

* remove prints

* new card formattings

* fix cursed unmount effect

* add OAuth route onboarding

* remove required admin auth for onboarding

* delete the hotwire button

* update open-api files

* delete import

* fix failing oauth onboarding fields

* fix e2e test

* fix web e2e test

* add onboarding to user registration e2e test

* remove todo

this was a holdover during dev and didn't get deleted

* fix server small tests

* use onDestroy to save settings rather than a bind:this

* change to false for isOnboarded

* fix other auth small test

* provide type annotation in user factory metadata field

* remove onboardingCompelted from UserDto

* move translations to onboarding steps array and mark as derived so they update

* break language selector out into its own component as per @danieldietzler suggestion

* remove hello header on card

* fix flixkering on server privacy card

* label/id fixes

* openapi

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
Brandon Wees
2025-06-02 16:09:13 -05:00
committed by GitHub
parent e7d7886f44
commit 74438f5bd8
36 changed files with 961 additions and 235 deletions
+9 -1
View File
@@ -15,6 +15,7 @@ class LoginResponseDto {
LoginResponseDto({
required this.accessToken,
required this.isAdmin,
required this.isOnboarded,
required this.name,
required this.profileImagePath,
required this.shouldChangePassword,
@@ -26,6 +27,8 @@ class LoginResponseDto {
bool isAdmin;
bool isOnboarded;
String name;
String profileImagePath;
@@ -40,6 +43,7 @@ class LoginResponseDto {
bool operator ==(Object other) => identical(this, other) || other is LoginResponseDto &&
other.accessToken == accessToken &&
other.isAdmin == isAdmin &&
other.isOnboarded == isOnboarded &&
other.name == name &&
other.profileImagePath == profileImagePath &&
other.shouldChangePassword == shouldChangePassword &&
@@ -51,6 +55,7 @@ class LoginResponseDto {
// ignore: unnecessary_parenthesis
(accessToken.hashCode) +
(isAdmin.hashCode) +
(isOnboarded.hashCode) +
(name.hashCode) +
(profileImagePath.hashCode) +
(shouldChangePassword.hashCode) +
@@ -58,12 +63,13 @@ class LoginResponseDto {
(userId.hashCode);
@override
String toString() => 'LoginResponseDto[accessToken=$accessToken, isAdmin=$isAdmin, name=$name, profileImagePath=$profileImagePath, shouldChangePassword=$shouldChangePassword, userEmail=$userEmail, userId=$userId]';
String toString() => 'LoginResponseDto[accessToken=$accessToken, isAdmin=$isAdmin, isOnboarded=$isOnboarded, name=$name, profileImagePath=$profileImagePath, shouldChangePassword=$shouldChangePassword, userEmail=$userEmail, userId=$userId]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
json[r'accessToken'] = this.accessToken;
json[r'isAdmin'] = this.isAdmin;
json[r'isOnboarded'] = this.isOnboarded;
json[r'name'] = this.name;
json[r'profileImagePath'] = this.profileImagePath;
json[r'shouldChangePassword'] = this.shouldChangePassword;
@@ -83,6 +89,7 @@ class LoginResponseDto {
return LoginResponseDto(
accessToken: mapValueOfType<String>(json, r'accessToken')!,
isAdmin: mapValueOfType<bool>(json, r'isAdmin')!,
isOnboarded: mapValueOfType<bool>(json, r'isOnboarded')!,
name: mapValueOfType<String>(json, r'name')!,
profileImagePath: mapValueOfType<String>(json, r'profileImagePath')!,
shouldChangePassword: mapValueOfType<bool>(json, r'shouldChangePassword')!,
@@ -137,6 +144,7 @@ class LoginResponseDto {
static const requiredKeys = <String>{
'accessToken',
'isAdmin',
'isOnboarded',
'name',
'profileImagePath',
'shouldChangePassword',