-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
'use client' | ||
import { Role } from '@/modules/firebase/role' | ||
import { Button } from '@/packages/design-system/src/components/Button' | ||
import { Input } from '@/packages/design-system/src/components/Input' | ||
import { | ||
Select, | ||
SelectContent, | ||
SelectItem, | ||
SelectTrigger, | ||
SelectValue, | ||
} from '@/packages/design-system/src/components/Select' | ||
import type { Data } from './page' | ||
import { useUser } from '@/modules/firebase/UserProvider' | ||
Check warning on line 13 in app/(dashboard)/users/[id]/EditUserForm.tsx GitHub Actions / ESLint Report Analysisapp/(dashboard)/users/[id]/EditUserForm.tsx#L13
|
||
import { Field } from '@/packages/design-system/src/forms/Field' | ||
Check warning on line 14 in app/(dashboard)/users/[id]/EditUserForm.tsx GitHub Actions / ESLint Report Analysisapp/(dashboard)/users/[id]/EditUserForm.tsx#L14
|
||
import { useForm } from '@/packages/design-system/src/forms/useForm' | ||
Check warning on line 15 in app/(dashboard)/users/[id]/EditUserForm.tsx GitHub Actions / ESLint Report Analysisapp/(dashboard)/users/[id]/EditUserForm.tsx#L15
|
||
import { editUserFormSchema } from './utils' | ||
|
||
interface EditUserDialogFormProps { | ||
data: Data | ||
} | ||
|
||
export const EditUserForm = ({ data }: EditUserDialogFormProps) => { | ||
const authUser = useUser() | ||
const form = useForm({ | ||
formSchema: editUserFormSchema, | ||
defaultValues: { | ||
email: data.authUser.email ?? '', | ||
displayName: data.authUser.displayName ?? '', | ||
role: data.role.role, | ||
organizationId: data.user?.organization, | ||
invitationCode: data.user?.invitationCode, | ||
}, | ||
}) | ||
|
||
const handleSubmit = form.handleSubmit((data) => { | ||
console.log(data) | ||
}) | ||
|
||
return ( | ||
<form onSubmit={handleSubmit}> | ||
<Field | ||
control={form.control} | ||
name="email" | ||
label="Email" | ||
render={({ field }) => <Input type="email" {...field} />} | ||
/> | ||
<Field | ||
control={form.control} | ||
name="displayName" | ||
label="Display name" | ||
render={({ field }) => <Input {...field} />} | ||
/> | ||
<Field | ||
control={form.control} | ||
name="invitationCode" | ||
label="Invitation code" | ||
render={({ field }) => <Input {...field} />} | ||
/> | ||
{authUser.role === Role.admin && ( | ||
<Field | ||
control={form.control} | ||
name="organizationId" | ||
label="Organization" | ||
render={({ field }) => ( | ||
<Select onValueChange={field.onChange} {...field}> | ||
<SelectTrigger> | ||
<SelectValue placeholder="Organization" /> | ||
</SelectTrigger> | ||
<SelectContent> | ||
{data.organizations.map((organization) => ( | ||
<SelectItem value={organization.id} key={organization.id}> | ||
{organization.name} | ||
</SelectItem> | ||
))} | ||
</SelectContent> | ||
</Select> | ||
)} | ||
/> | ||
)} | ||
<Field | ||
control={form.control} | ||
name="role" | ||
label="Role" | ||
render={({ field }) => ( | ||
<Select | ||
onValueChange={field.onChange} | ||
{...field} | ||
disabled={authUser.uid === data.authUser.id} | ||
> | ||
<SelectTrigger> | ||
<SelectValue placeholder="Roles" /> | ||
</SelectTrigger> | ||
<SelectContent> | ||
<SelectItem value={Role.clinician} itemText="Clinician"> | ||
<div className="flex flex-col"> | ||
<b>Clinician</b> | ||
<p>Clinician can access their organization data </p> | ||
</div> | ||
</SelectItem> | ||
<SelectItem value={Role.owner} itemText="Organization owner"> | ||
<div className="flex flex-col"> | ||
<b>Organization owner</b> | ||
<p> | ||
Organization owner can manage their organization users and | ||
data | ||
</p> | ||
</div> | ||
</SelectItem> | ||
<SelectItem value={Role.admin} itemText="Admin"> | ||
<div className="flex flex-col"> | ||
<b>Admin</b> | ||
<p>Admin can modify every organization and invite users</p> | ||
</div> | ||
</SelectItem> | ||
</SelectContent> | ||
</Select> | ||
)} | ||
/> | ||
|
||
<Button type="submit">Save user</Button> | ||
</form> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
'use server' | ||
import { revalidatePath } from 'next/cache' | ||
Check failure on line 2 in app/(dashboard)/users/[id]/actions.tsx GitHub Actions / ESLint Report Analysisapp/(dashboard)/users/[id]/actions.tsx#L2
|
||
import { type z } from 'zod' | ||
import { type editUserFormSchema } from '@/app/(dashboard)/users/[id]/utils' | ||
import { getAuthenticatedOnlyApp } from '@/modules/firebase/guards' | ||
import { routes } from '@/modules/routes' | ||
|
||
export const editUser = async (payload: z.infer<typeof editUserFormSchema>) => { | ||
const { callables } = await getAuthenticatedOnlyApp() | ||
Check failure on line 9 in app/(dashboard)/users/[id]/actions.tsx GitHub Actions / ESLint Report Analysisapp/(dashboard)/users/[id]/actions.tsx#L9
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// | ||
// This source file is part of the Stanford Biodesign Digital Health ENGAGE-HF open-source project | ||
// | ||
// SPDX-FileCopyrightText: 2023 Stanford University and the project authors (see CONTRIBUTORS.md) | ||
// | ||
// SPDX-License-Identifier: MIT | ||
// | ||
import { Users } from 'lucide-react' | ||
import { notFound } from 'next/navigation' | ||
import { EditUserForm } from './EditUserForm' | ||
Check warning on line 10 in app/(dashboard)/users/[id]/page.tsx GitHub Actions / ESLint Report Analysisapp/(dashboard)/users/[id]/page.tsx#L10
|
||
import { | ||
allowRoles, | ||
getAuthenticatedOnlyApp, | ||
getUserRole, | ||
} from '@/modules/firebase/guards' | ||
import { Role } from '@/modules/firebase/role' | ||
import { mapAuthData } from '@/modules/firebase/user' | ||
import { getDocData, getDocsData } from '@/modules/firebase/utils' | ||
import { getUserName } from '@/packages/design-system/src/modules/auth/user' | ||
import { PageTitle } from '@/packages/design-system/src/molecules/DashboardLayout' | ||
import { DashboardLayout } from '../../DashboardLayout' | ||
|
||
const getData = async (userId: string) => { | ||
const { refs, docRefs } = await getAuthenticatedOnlyApp() | ||
const organizations = await getDocsData(refs.organizations()) | ||
const user = await getDocData(docRefs.user(userId)) | ||
const allAuthData = await mapAuthData([userId], (data, id) => ({ | ||
id, | ||
...data, | ||
})) | ||
const authUser = allAuthData.at(0) | ||
|
||
if (!authUser) { | ||
notFound() | ||
} | ||
return { | ||
user, | ||
organizations, | ||
authUser, | ||
role: await getUserRole(userId), | ||
} | ||
} | ||
|
||
export type Data = Awaited<ReturnType<typeof getData>> | ||
|
||
const UserPage = async ({ params }: { params: { id: string } }) => { | ||
await allowRoles([Role.admin, Role.owner]) | ||
const data = await getData(params.id) | ||
|
||
return ( | ||
<DashboardLayout | ||
title={ | ||
<PageTitle | ||
title="Edit user" | ||
subTitle={getUserName(data.authUser)} | ||
icon={<Users />} | ||
/> | ||
} | ||
> | ||
<div className="mx-auto w-full max-w-[800px]"> | ||
<EditUserForm data={data} /> | ||
</div> | ||
</DashboardLayout> | ||
) | ||
} | ||
|
||
export default UserPage | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { z } from 'zod' | ||
import { Role } from '@/modules/firebase/role' | ||
|
||
export const editUserFormSchema = z.object({ | ||
email: z.string().min(1, 'Email is required'), | ||
displayName: z.string(), | ||
invitationCode: z.string().optional(), | ||
organizationId: z.string().optional(), | ||
role: z.nativeEnum(Role), | ||
}) |