diff --git a/frontend/spa/src/components/Forms/OrganizationRegistrationForm/OrganizationRegistrationForm.tsx b/frontend/spa/src/components/Forms/OrganizationRegistrationForm/OrganizationRegistrationForm.tsx index bb376238..9ec858f0 100644 --- a/frontend/spa/src/components/Forms/OrganizationRegistrationForm/OrganizationRegistrationForm.tsx +++ b/frontend/spa/src/components/Forms/OrganizationRegistrationForm/OrganizationRegistrationForm.tsx @@ -8,12 +8,19 @@ import Button from '@/components/ui/Button.tsx'; import apiService from '@/services/ApiService.ts'; import { useToast } from '@/hooks/use-toast.ts'; -const schema = z.object({ - organizationName: z.string().min(1, 'Organization name is required'), - firstName: z.string().min(1, 'First name is required'), - lastName: z.string().min(1, 'Last name is required'), - email: z.string().email('Invalid email address'), -}); +const schema = z + .object({ + organizationName: z.string().min(1, 'Organization name is required'), + firstName: z.string().min(1, 'First name is required'), + lastName: z.string().min(1, 'Last name is required'), + email: z.string().email('Invalid email address'), + password: z.string().min(8, 'Password must be at least 8 characters long'), + passwordConfirm: z.string().min(8, 'Password must be at least 8 characters long'), + }) + .refine((data) => data.password === data.passwordConfirm, { + message: "Passwords don't match", + path: ['passwordConfirm'], + }); type FormFields = z.infer; @@ -43,6 +50,7 @@ export function OrganizationRegistrationForm(props: Props) { type: 'EINGETRAGENER_VEREIN', slug: apiService.organization.createSlug(data.organizationName), }, + newPassword: data.password, }); showSuccess(t('organization.registration.success')); @@ -68,7 +76,12 @@ export function OrganizationRegistrationForm(props: Props) {
- +
+ +
+
+ +

diff --git a/frontend/spa/src/components/views/OrganizationSettingsView.tsx b/frontend/spa/src/components/views/OrganizationSettingsView.tsx index eb7f2f55..91d4ffc6 100644 --- a/frontend/spa/src/components/views/OrganizationSettingsView.tsx +++ b/frontend/spa/src/components/views/OrganizationSettingsView.tsx @@ -60,18 +60,26 @@ function OrganizationSettingsView() { } organizationTreeService.ensureRootBommelCreated(organization.id).then((bommel) => { - setRootBommel(bommel); + if (bommel) { + setRootBommel(bommel); + } else { + setIsOrganizationError(true); + } }); }, []); return ( <> - - - + {!isOrganizationError && } -

Structure:

- {isOrganizationError ?
Error
: } + {isOrganizationError ? ( +
{t('organization.settings.error')}
+ ) : ( + <> +

Structure:

+ + + )} ); } diff --git a/frontend/spa/src/locales/de.json b/frontend/spa/src/locales/de.json index 6fc1d0a9..9e8b9c94 100644 --- a/frontend/spa/src/locales/de.json +++ b/frontend/spa/src/locales/de.json @@ -21,6 +21,7 @@ "success": "Organisation erfolgreich erstellt" }, "settings": { + "error": "Organisationsstruktur konnte nicht geladen werden", "saveError": "Einstellung konnte nicht gespeichert werden", "saved": "Einstellungen erfolgreich gespeichert" } diff --git a/frontend/spa/src/locales/en.json b/frontend/spa/src/locales/en.json index 2757555d..980323a7 100644 --- a/frontend/spa/src/locales/en.json +++ b/frontend/spa/src/locales/en.json @@ -21,6 +21,7 @@ "success": "Organisation successfully created" }, "settings": { + "error": "Failed to load organization structure", "saveError": "Failed to save setting", "saved": "Settings successfully saved" } diff --git a/frontend/spa/src/locales/uk.json b/frontend/spa/src/locales/uk.json index 59569967..7b06c80d 100644 --- a/frontend/spa/src/locales/uk.json +++ b/frontend/spa/src/locales/uk.json @@ -21,6 +21,7 @@ "success": "Організацію успішно створено" }, "settings": { + "error": "Не вдалося завантажити структуру організації", "saveError": "Не вдалося зберегти налаштування", "saved": "Налаштування успішно збережені" } diff --git a/frontend/spa/src/services/OrganizationTreeService.ts b/frontend/spa/src/services/OrganizationTreeService.ts index 210286b3..6dbc4fd5 100644 --- a/frontend/spa/src/services/OrganizationTreeService.ts +++ b/frontend/spa/src/services/OrganizationTreeService.ts @@ -144,18 +144,19 @@ export class OrganizationTreeService { const loadRootBommel = async () => { return await apiService.bommel.getRootBommel(organizationId); }; + const createRootBommel = async () => { return await apiService.bommel.createRootBommel({ - organization: { id: organizationId }, + organizationId, name: 'root', emoji: '', children: [], parent: undefined, }); }; - try { - let rootBommel = await loadRootBommel(); + try { + let rootBommel = await loadRootBommel().catch(() => undefined); if (!rootBommel) { rootBommel = await createRootBommel(); } @@ -163,6 +164,7 @@ export class OrganizationTreeService { return rootBommel; } catch (e) { console.error('Failed to load root bommel', e); + debugger; return await createRootBommel(); } } diff --git a/frontend/spa/src/services/api/BommelService.ts b/frontend/spa/src/services/api/BommelService.ts index 4d9e9e1a..1fbc2b64 100644 --- a/frontend/spa/src/services/api/BommelService.ts +++ b/frontend/spa/src/services/api/BommelService.ts @@ -11,7 +11,7 @@ export class BommelService { } async deleteBommel(id: number) { - await fetch(`${this.baseUrl}/bommel/${id}`, { method: 'DELETE' }); + await fetch(`${this.baseUrl}/bommel/${id}?recursive=true`, { method: 'DELETE' }); } async createBommel(data: Partial) { @@ -23,13 +23,13 @@ export class BommelService { return response.json(); } - async createRootBommel(data: Partial & { organization: { id: number } }) { + async createRootBommel(data: Partial & { organizationId: number }): Promise { const response = await fetch(`${this.baseUrl}/bommel/root`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); - return response.json(); + return response.status === 200 || response.status === 201 ? response.json() : undefined; } async getBommelChildren(id: string) { diff --git a/frontend/spa/src/services/api/OrganizationService.ts b/frontend/spa/src/services/api/OrganizationService.ts index 281f082e..94e1b920 100644 --- a/frontend/spa/src/services/api/OrganizationService.ts +++ b/frontend/spa/src/services/api/OrganizationService.ts @@ -4,6 +4,7 @@ type RegisterOrganizationPayload = { lastName: string; email: string; }; + newPassword: string; organization: { profilePicture?: string; website?: string;