Skip to content

Commit e40b23a

Browse files
authored
feat: edit business details + improve setup copy (#90)
1 parent be48551 commit e40b23a

10 files changed

Lines changed: 537 additions & 121 deletions

File tree

apps/web/src/app/data/services/account.service.ts

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,11 @@
11
import { Injectable, signal, WritableSignal, inject } from '@angular/core';
22
import { ApiService } from '../../core/services/api.service';
33
import { Account, LoginLink } from '@zoneless/shared-types';
4-
import { CreateAccountInput } from '@zoneless/shared-schemas';
5-
6-
/**
7-
* Input type for updating an account.
8-
* All fields are optional - only provided fields will be updated.
9-
* Protected fields (id, object, created, payouts_enabled, details_submitted, tos_acceptance)
10-
* cannot be updated directly.
11-
*/
12-
export type AccountUpdateInput = Partial<
13-
Omit<
14-
Account,
15-
| 'id'
16-
| 'object'
17-
| 'created'
18-
| 'payouts_enabled'
19-
| 'details_submitted'
20-
| 'tos_acceptance'
21-
| 'individual'
22-
>
23-
>;
4+
import {
5+
CreateAccountInput,
6+
UpdateAccountInput,
7+
} from '@zoneless/shared-schemas';
8+
import { SettingsCardRow } from '../../shared';
249

2510
@Injectable({
2611
providedIn: 'root',
@@ -59,7 +44,7 @@ export class AccountService {
5944

6045
async UpdateAccount(
6146
accountId: string,
62-
data: AccountUpdateInput
47+
data: UpdateAccountInput
6348
): Promise<Account> {
6449
this.loading.set(true);
6550
try {
@@ -162,4 +147,38 @@ export class AccountService {
162147

163148
return account.email ?? individual?.email ?? account.id;
164149
}
150+
151+
/**
152+
* Display title for the Business details settings card.
153+
*/
154+
GetBusinessDetailsTitle(account: Account | null): string {
155+
if (!account) return 'Business details';
156+
return (
157+
account.business_profile?.name?.trim() ||
158+
account.settings?.dashboard?.display_name?.trim() ||
159+
'Business details'
160+
);
161+
}
162+
163+
GetBusinessDetailsCardRows(account: Account | null): SettingsCardRow[] {
164+
if (!account) return [];
165+
166+
return [
167+
{
168+
label: 'Logo',
169+
value: account.settings?.branding?.logo || '—',
170+
type: 'text',
171+
},
172+
{
173+
label: 'Terms of Service',
174+
value: account.settings?.terms_url || '—',
175+
type: 'text',
176+
},
177+
{
178+
label: 'Privacy Policy',
179+
value: account.settings?.privacy_url || '—',
180+
type: 'text',
181+
},
182+
];
183+
}
165184
}

apps/web/src/app/features/account/settings/settings.component.html

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,21 @@
22
<h1>Settings</h1>
33
</div>
44

5-
<!-- Personal Details Card -->
5+
<!-- Business Details Card (platform only) -->
6+
@if (authService.isPlatform()) {
7+
<div class="view-section">
8+
<div class="settings-section-title">Business details</div>
9+
<app-settings-card
10+
[title]="accountService.GetBusinessDetailsTitle(accountService.account())"
11+
[rows]="accountService.GetBusinessDetailsCardRows(accountService.account())"
12+
[showEditButton]="true"
13+
(editClicked)="OnEditBusinessClick()"
14+
></app-settings-card>
15+
</div>
16+
}
17+
18+
<!-- Personal Details Card (connected accounts only) -->
19+
@if (!authService.isPlatform()) {
620
<div class="view-section">
721
<div class="settings-section-title">Personal details</div>
822
<app-settings-card
@@ -12,6 +26,7 @@ <h1>Settings</h1>
1226
(editClicked)="OnEditPersonClick()"
1327
></app-settings-card>
1428
</div>
29+
}
1530

1631
<!-- External Wallet Card -->
1732
@if (externalWalletService.wallet()) {
@@ -37,7 +52,29 @@ <h1>Settings</h1>
3752
</button>
3853
</div>
3954

55+
<!-- Edit Business Details Slide Panel -->
56+
@if (authService.isPlatform()) {
57+
<app-slide-panel
58+
[isOpen]="editBusinessPanelOpen()"
59+
title="Edit business details"
60+
[loading]="editBusinessLoading()"
61+
submitLabel="Save"
62+
[submitDisabled]="false"
63+
(closed)="OnEditBusinessPanelClosed()"
64+
(submitted)="OnEditBusinessSubmit()"
65+
>
66+
<app-business-profile-form
67+
#editBusinessForm
68+
mode="edit"
69+
[account]="accountService.account()"
70+
[isOpen]="editBusinessPanelOpen()"
71+
[showErrors]="editBusinessShowErrors()"
72+
></app-business-profile-form>
73+
</app-slide-panel>
74+
}
75+
4076
<!-- Edit Person Slide Panel -->
77+
@if (!authService.isPlatform()) {
4178
<app-slide-panel
4279
[isOpen]="editPersonPanelOpen()"
4380
title="Edit personal details"
@@ -55,6 +92,7 @@ <h1>Settings</h1>
5592
[showErrors]="editPersonShowErrors()"
5693
></app-person-form>
5794
</app-slide-panel>
95+
}
5896

5997
<!-- Edit Wallet Slide Panel -->
6098
<app-slide-panel

apps/web/src/app/features/account/settings/settings.component.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,23 @@ import {
2020
TransactionService,
2121
WebhookEndpointService,
2222
TopupService,
23+
ConfigService,
2324
} from '../../../data';
2425
import {
26+
BusinessProfileFormComponent,
2527
ExternalWalletFormComponent,
2628
PersonFormComponent,
2729
SettingsCardComponent,
30+
SlidePanelComponent,
2831
} from '../../../shared';
29-
import { SlidePanelComponent } from '../../../shared';
3032

3133
@Component({
3234
selector: 'app-settings',
3335
imports: [
3436
SlidePanelComponent,
3537
PersonFormComponent,
3638
ExternalWalletFormComponent,
39+
BusinessProfileFormComponent,
3740
SettingsCardComponent,
3841
],
3942
templateUrl: './settings.component.html',
@@ -43,6 +46,8 @@ import { SlidePanelComponent } from '../../../shared';
4346
export class SettingsComponent implements OnInit {
4447
@ViewChild('editPersonForm') editPersonForm!: PersonFormComponent;
4548
@ViewChild('editWalletForm') editWalletForm!: ExternalWalletFormComponent;
49+
@ViewChild('editBusinessForm')
50+
editBusinessForm!: BusinessProfileFormComponent;
4651

4752
readonly personService = inject(PersonService);
4853
readonly externalWalletService = inject(ExternalWalletService);
@@ -53,6 +58,7 @@ export class SettingsComponent implements OnInit {
5358
readonly webhookEndpointService = inject(WebhookEndpointService);
5459
readonly apiKeyService = inject(ApiKeyService);
5560
readonly topupService = inject(TopupService);
61+
readonly configService = inject(ConfigService);
5662
readonly router = inject(Router);
5763
private readonly metaService = inject(MetaService);
5864

@@ -67,10 +73,54 @@ export class SettingsComponent implements OnInit {
6773
editWalletShowErrors: WritableSignal<boolean> = signal(false);
6874
walletFormValid: WritableSignal<boolean> = signal(false);
6975

76+
// Edit business details panel state
77+
editBusinessPanelOpen: WritableSignal<boolean> = signal(false);
78+
editBusinessLoading: WritableSignal<boolean> = signal(false);
79+
editBusinessShowErrors: WritableSignal<boolean> = signal(false);
80+
7081
ngOnInit(): void {
7182
this.metaService.SetMetaTitle('Settings');
7283
}
7384

85+
// Edit Business Panel
86+
OnEditBusinessClick(): void {
87+
this.editBusinessShowErrors.set(false);
88+
this.editBusinessPanelOpen.set(true);
89+
}
90+
91+
OnEditBusinessPanelClosed(): void {
92+
this.editBusinessPanelOpen.set(false);
93+
this.editBusinessShowErrors.set(false);
94+
}
95+
96+
async OnEditBusinessSubmit(): Promise<void> {
97+
if (!this.editBusinessForm) return;
98+
99+
this.editBusinessShowErrors.set(true);
100+
101+
if (!this.editBusinessForm.ValidateAll()) {
102+
return;
103+
}
104+
105+
const account = this.GetAccount();
106+
if (!account) return;
107+
108+
this.editBusinessLoading.set(true);
109+
110+
try {
111+
const updateData = this.editBusinessForm.GetUpdateData();
112+
await this.accountService.UpdateAccount(account.id, updateData);
113+
this.configService.ClearConfig();
114+
await this.configService.LoadConfig();
115+
this.editBusinessPanelOpen.set(false);
116+
this.editBusinessShowErrors.set(false);
117+
} catch (error) {
118+
console.error('Failed to update business details:', error);
119+
} finally {
120+
this.editBusinessLoading.set(false);
121+
}
122+
}
123+
74124
// Edit Person Panel
75125
OnEditPersonClick(): void {
76126
this.editPersonShowErrors.set(false);

0 commit comments

Comments
 (0)