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
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 961 additions and 235 deletions

View file

@ -7922,6 +7922,101 @@
]
}
},
"/users/me/onboarding": {
"delete": {
"operationId": "deleteUserOnboarding",
"parameters": [],
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Users"
]
},
"get": {
"operationId": "getUserOnboarding",
"parameters": [],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OnboardingResponseDto"
}
}
},
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Users"
]
},
"put": {
"operationId": "setUserOnboarding",
"parameters": [],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OnboardingDto"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OnboardingResponseDto"
}
}
},
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Users"
]
}
},
"/users/me/preferences": {
"get": {
"operationId": "getMyPreferences",
@ -10404,6 +10499,9 @@
"isAdmin": {
"type": "boolean"
},
"isOnboarded": {
"type": "boolean"
},
"name": {
"type": "string"
},
@ -10423,6 +10521,7 @@
"required": [
"accessToken",
"isAdmin",
"isOnboarded",
"name",
"profileImagePath",
"shouldChangePassword",
@ -11067,6 +11166,28 @@
],
"type": "object"
},
"OnboardingDto": {
"properties": {
"isOnboarded": {
"type": "boolean"
}
},
"required": [
"isOnboarded"
],
"type": "object"
},
"OnboardingResponseDto": {
"properties": {
"isOnboarded": {
"type": "boolean"
}
},
"required": [
"isOnboarded"
],
"type": "object"
},
"PartnerDirection": {
"enum": [
"shared-by",

View file

@ -512,6 +512,7 @@ export type LoginCredentialDto = {
export type LoginResponseDto = {
accessToken: string;
isAdmin: boolean;
isOnboarded: boolean;
name: string;
profileImagePath: string;
shouldChangePassword: boolean;
@ -1470,6 +1471,12 @@ export type UserUpdateMeDto = {
name?: string;
password?: string;
};
export type OnboardingResponseDto = {
isOnboarded: boolean;
};
export type OnboardingDto = {
isOnboarded: boolean;
};
export type CreateProfileImageDto = {
file: Blob;
};
@ -3582,6 +3589,32 @@ export function setUserLicense({ licenseKeyDto }: {
body: licenseKeyDto
})));
}
export function deleteUserOnboarding(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchText("/users/me/onboarding", {
...opts,
method: "DELETE"
}));
}
export function getUserOnboarding(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: OnboardingResponseDto;
}>("/users/me/onboarding", {
...opts
}));
}
export function setUserOnboarding({ onboardingDto }: {
onboardingDto: OnboardingDto;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: OnboardingResponseDto;
}>("/users/me/onboarding", oazapfts.json({
...opts,
method: "PUT",
body: onboardingDto
})));
}
export function getMyPreferences(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;