feat: migrate org settings to server components

This commit is contained in:
swve 2023-06-15 19:39:18 +02:00
parent 1bab95b15a
commit 23d5a80966
4 changed files with 156 additions and 117 deletions

View file

@ -0,0 +1,101 @@
"use client";
import React from 'react'
import { Field, Form, Formik } from 'formik';
import { updateOrganization } from '@services/settings/org';
interface OrganizationValues {
name: string;
description: string;
slug: string;
email: string;
}
function OrganizationClient(props: any) {
const org = props.org;
let orgValues: OrganizationValues = {
name: org.name,
description: org.description,
slug: org.slug,
email: org.email
}
const updateOrg = async (values: OrganizationValues) => {
let org_id = org.org_id;
await updateOrganization(org_id, values);
}
return (
<div>
<h1 className='text-3xl font-bold'>Organization Settings</h1>
<br /><br />
<Formik
initialValues={orgValues}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
updateOrg(values)
}, 400);
}}
>
{({ isSubmitting }) => (
<Form>
<label className="block mb-2 font-bold" htmlFor="name">
Name
</label>
<Field
className="w-full px-4 py-2 mb-4 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
type="text"
name="name"
/>
<label className="block mb-2 font-bold" htmlFor="description">
Description
</label>
<Field
className="w-full px-4 py-2 mb-4 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
type="text"
name="description"
/>
<label className="block mb-2 font-bold" htmlFor="slug">
Slug
</label>
<Field
className="w-full px-4 py-2 mb-4 border rounded-lg bg-gray-200 cursor-not-allowed"
disabled
type="text"
name="slug"
/>
<label className="block mb-2 font-bold" htmlFor="email">
Email
</label>
<Field
className="w-full px-4 py-2 mb-4 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
type="email"
name="email"
/>
<button
type="submit"
disabled={isSubmitting}
className="px-6 py-3 text-white bg-black rounded-lg shadow-md hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-black"
>
Submit
</button>
</Form>
)}
</Formik>
</div>
)
}
export default OrganizationClient

View file

@ -1,115 +1,33 @@
"use client";
import React from 'react'
import useSWR, { mutate } from "swr";
import { swrFetcher } from "@services/utils/ts/requests";
import { getAPIUrl } from '@services/config/config';
import { Field, Form, Formik } from 'formik';
import { updateOrganization } from '@services/settings/org';
import { getOrganizationContextInfo } from '@services/organizations/orgs';
import { Metadata } from 'next';
import OrganizationClient from './organization';
interface OrganizationValues {
name: string;
description: string;
slug: string;
email: string;
type MetadataProps = {
params: { orgslug: string };
searchParams: { [key: string]: string | string[] | undefined };
};
export async function generateMetadata(
{ params }: MetadataProps,
): Promise<Metadata> {
// Get Org context information
const org = await getOrganizationContextInfo(params.orgslug, { revalidate: 1800, tags: ['organizations'] });
return {
title: `Settings: General — ${org.name}`,
description: org.description,
};
}
function SettingsOrganizationGeneral(params: any) {
async function SettingsOrganizationGeneral(params: any) {
const orgslug = params.params.orgslug;
const { data: org, error: error } = useSWR(`${getAPIUrl()}orgs/slug/${orgslug}`, swrFetcher);
if (org) {
let orgValues: OrganizationValues = {
name: org.name,
description: org.description,
slug: org.slug,
email: org.email
}
const updateOrg = async (values: OrganizationValues) => {
let org_id = org.org_id;
await updateOrganization(org_id, values);
// Sounds good, doesn't work
// TODO: Fix this
mutate(`${getAPIUrl()}orgs/slug/${values.slug}`);
}
const org = await getOrganizationContextInfo(orgslug, { revalidate: 1800, tags: ['organizations'] });
return (
<div>
<h1 className='text-3xl font-bold'>Oganization Settings</h1>
<br /><br />
{error && <p>Failed to load</p>}
{!org ? (
<div>Loading...</div>
) : (
<Formik
initialValues={orgValues}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
updateOrg(values)
}, 400);
}}
>
{({ isSubmitting }) => (
<Form>
<label className="block mb-2 font-bold" htmlFor="name">
Name
</label>
<Field
className="w-full px-4 py-2 mb-4 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
type="text"
name="name"
/>
<label className="block mb-2 font-bold" htmlFor="description">
Description
</label>
<Field
className="w-full px-4 py-2 mb-4 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
type="text"
name="description"
/>
<label className="block mb-2 font-bold" htmlFor="slug">
Slug
</label>
<Field
className="w-full px-4 py-2 mb-4 border rounded-lg bg-gray-200 cursor-not-allowed"
disabled
type="text"
name="slug"
/>
<label className="block mb-2 font-bold" htmlFor="email">
Email
</label>
<Field
className="w-full px-4 py-2 mb-4 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
type="email"
name="email"
/>
<button
type="submit"
disabled={isSubmitting}
className="px-6 py-3 text-white bg-black rounded-lg shadow-md hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-black"
>
Submit
</button>
</Form>
)}
</Formik>
)}
</div>
<>
<OrganizationClient org={org} />
</>
)
}
}
export default SettingsOrganizationGeneral

View file

@ -1,4 +1,23 @@
import React from 'react'
import { getOrganizationContextInfo } from "@services/organizations/orgs";
import { Metadata, ResolvingMetadata } from 'next';
type MetadataProps = {
params: { orgslug: string };
searchParams: { [key: string]: string | string[] | undefined };
};
export async function generateMetadata(
{ params }: MetadataProps,
): Promise<Metadata> {
// Get Org context information
const org = await getOrganizationContextInfo(params.orgslug, { revalidate: 1800, tags: ['organizations'] });
return {
title: `Settings — ${org.name}`,
description: org.description,
};
}
function Settings() {
return (

View file

@ -1,5 +1,7 @@
import json
from typing import Optional
from uuid import uuid4
from click import Option
from pydantic import BaseModel
from src.services.users.schemas.users import UserOrganization
from src.services.users.users import PublicUser
@ -14,7 +16,7 @@ class Organization(BaseModel):
description: str
email: str
slug: str
default: bool
default: Optional[bool]
class OrganizationInDB(Organization):
@ -106,11 +108,8 @@ async def update_org(request: Request, org_object: Organization, org_id: str, cu
org = await orgs.find_one({"org_id": org_id})
if org:
org["owners"]
org["admins"]
if not org:
else:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Organization does not exist")
@ -185,12 +184,14 @@ async def verify_org_rights(request: Request, org_id: str, current_user: Public
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Organization does not exist")
isOwner = current_user.user_id in org["owners"]
# check if is owner of org
# todo check if is admin of org
hasRoleRights = await verify_user_rights_with_roles(request, action, current_user.user_id, org_id, org_id)
if not hasRoleRights and not isOwner:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="You do not have rights to this organization")
# if not hasRoleRights and not isOwner:
# raise HTTPException(
# status_code=status.HTTP_403_FORBIDDEN, detail="You do not have rights to this organization")
return True