feat: manage organizations from switcher
Rename the centre switcher to organization switcher and wire it to loaded organizations. Add dropdown actions for switching organizations, creating a new organization, and editing the active organization in dialogs. Persist organization changes through dashboard endpoints while preserving the current redirect path.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { redirect, error } from '@sveltejs/kit';
|
||||
import { db } from '$lib/server/db';
|
||||
import { organizations } from '$lib/server/db/schema';
|
||||
import { organizationCreateSchema } from '$lib/schemas/organizations.schema';
|
||||
import { setActiveOrganization } from '$lib/server/organizations';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
function safeRedirect(value: string) {
|
||||
return value.startsWith('/') && !value.startsWith('//') ? value : '/dashboard';
|
||||
}
|
||||
|
||||
export const POST: RequestHandler = async ({ locals, request }) => {
|
||||
if (!locals.user) {
|
||||
redirect(303, '/login');
|
||||
}
|
||||
|
||||
const formData = await request.formData();
|
||||
const parsed = organizationCreateSchema.safeParse(Object.fromEntries(formData));
|
||||
|
||||
if (!parsed.success) {
|
||||
error(400, 'Check the organization details and try again.');
|
||||
}
|
||||
|
||||
const id = crypto.randomUUID();
|
||||
const now = new Date();
|
||||
|
||||
await db.insert(organizations).values({
|
||||
id,
|
||||
name: parsed.data.name,
|
||||
workspace: parsed.data.workspace,
|
||||
addressLine1: parsed.data.addressLine1 || null,
|
||||
addressLine2: parsed.data.addressLine2 || null,
|
||||
city: parsed.data.city || null,
|
||||
region: parsed.data.region || null,
|
||||
postcode: parsed.data.postcode || null,
|
||||
country: parsed.data.country,
|
||||
bankName: parsed.data.bankName || null,
|
||||
bankAccountName: parsed.data.bankAccountName || null,
|
||||
bankAccountNumber: parsed.data.bankAccountNumber || null,
|
||||
bankSortCode: parsed.data.bankSortCode || null,
|
||||
bankIban: parsed.data.bankIban || null,
|
||||
bankSwift: parsed.data.bankSwift || null,
|
||||
createdAt: now,
|
||||
updatedAt: now
|
||||
});
|
||||
|
||||
await setActiveOrganization(locals, id);
|
||||
|
||||
redirect(303, safeRedirect(parsed.data.redirectTo));
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
import { and, eq, isNull } from 'drizzle-orm';
|
||||
import { error, redirect } from '@sveltejs/kit';
|
||||
import { db } from '$lib/server/db';
|
||||
import { organizations } from '$lib/server/db/schema';
|
||||
import { loadOrganizationContext } from '$lib/server/organizations';
|
||||
import { organizationEditSchema } from '$lib/schemas/organizations.schema';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
function safeRedirect(value: FormDataEntryValue | null) {
|
||||
return typeof value === 'string' && value.startsWith('/') && !value.startsWith('//')
|
||||
? value
|
||||
: '/dashboard';
|
||||
}
|
||||
|
||||
export const POST: RequestHandler = async ({ locals, request }) => {
|
||||
if (!locals.user) {
|
||||
redirect(303, '/login');
|
||||
}
|
||||
|
||||
const { activeOrganizationId } = await loadOrganizationContext(locals);
|
||||
const formData = await request.formData();
|
||||
const parsed = organizationEditSchema.safeParse(Object.fromEntries(formData));
|
||||
|
||||
if (!parsed.success || parsed.data.id !== activeOrganizationId) {
|
||||
error(400, 'Check the organization details and try again.');
|
||||
}
|
||||
|
||||
await db
|
||||
.update(organizations)
|
||||
.set({
|
||||
name: parsed.data.name,
|
||||
workspace: parsed.data.workspace,
|
||||
addressLine1: parsed.data.addressLine1 || null,
|
||||
addressLine2: parsed.data.addressLine2 || null,
|
||||
city: parsed.data.city || null,
|
||||
region: parsed.data.region || null,
|
||||
postcode: parsed.data.postcode || null,
|
||||
country: parsed.data.country,
|
||||
bankName: parsed.data.bankName || null,
|
||||
bankAccountName: parsed.data.bankAccountName || null,
|
||||
bankAccountNumber: parsed.data.bankAccountNumber || null,
|
||||
bankSortCode: parsed.data.bankSortCode || null,
|
||||
bankIban: parsed.data.bankIban || null,
|
||||
bankSwift: parsed.data.bankSwift || null,
|
||||
updatedAt: new Date()
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
eq(organizations.id, activeOrganizationId),
|
||||
eq(organizations.id, parsed.data.id),
|
||||
isNull(organizations.archivedAt)
|
||||
)
|
||||
);
|
||||
|
||||
redirect(303, safeRedirect(formData.get('redirectTo')));
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import { setActiveOrganization } from '$lib/server/organizations';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
export const POST: RequestHandler = async ({ locals, request }) => {
|
||||
const formData = await request.formData();
|
||||
const organizationId = formData.get('organizationId');
|
||||
const redirectTo = formData.get('redirectTo');
|
||||
|
||||
if (typeof organizationId === 'string') {
|
||||
await setActiveOrganization(locals, organizationId);
|
||||
}
|
||||
|
||||
redirect(
|
||||
303,
|
||||
typeof redirectTo === 'string' && redirectTo.startsWith('/') ? redirectTo : '/dashboard'
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user