forked from formbricks/formbricks
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rewrite profile settings page to server component (formbricks#642)
* Chore: moved profile settings to server component * ran pnpm format * fisxed a build issue * made requested changes * made some refactors --------- Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
- Loading branch information
1 parent
2ff508a
commit 3439220
Showing
9 changed files
with
349 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
apps/web/app/(app)/environments/[environmentId]/settings/profile/EditAvatar.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
"use client"; | ||
|
||
import AvatarPlaceholder from "@/images/avatar-placeholder.png"; | ||
import { Button, ProfileAvatar } from "@formbricks/ui"; | ||
import Image from "next/image"; | ||
import { Session } from "next-auth"; | ||
|
||
export function EditAvatar({ session }:{session: Session | null}) { | ||
return ( | ||
<div> | ||
{session?.user?.image ? ( | ||
<Image | ||
src={AvatarPlaceholder} | ||
width="100" | ||
height="100" | ||
className="h-24 w-24 rounded-full" | ||
alt="Avatar placeholder" | ||
/> | ||
) : ( | ||
<ProfileAvatar userId={session!.user.id} /> | ||
)} | ||
|
||
<Button className="mt-4" variant="darkCTA" disabled={true}> | ||
Upload Image | ||
</Button> | ||
</div> | ||
); | ||
} |
47 changes: 47 additions & 0 deletions
47
apps/web/app/(app)/environments/[environmentId]/settings/profile/EditName.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
"use client"; | ||
|
||
import { Button, Input, Label } from "@formbricks/ui"; | ||
import { useForm } from "react-hook-form"; | ||
import toast from "react-hot-toast"; | ||
import { profileEditAction } from "./actions"; | ||
import { TProfile } from "@formbricks/types/v1/profile"; | ||
|
||
export function EditName({ profile }: { profile: TProfile }) { | ||
|
||
const { | ||
register, | ||
handleSubmit, | ||
formState: { isSubmitting }, | ||
} = useForm<{name:string}>() | ||
|
||
return ( | ||
<> | ||
<form | ||
className="w-full max-w-sm items-center" | ||
onSubmit={handleSubmit(async(data) => { | ||
try { | ||
await profileEditAction(profile.id, data); | ||
toast.success("Your name was updated successfully."); | ||
} catch (error) { | ||
toast.error(`Error: ${error.message}`); | ||
} | ||
})}> | ||
<Label htmlFor="fullname">Full Name</Label> | ||
<Input | ||
type="text" | ||
id="fullname" | ||
defaultValue={profile.name ? profile.name : ""} | ||
{...register("name")} | ||
/> | ||
|
||
<div className="mt-4"> | ||
<Label htmlFor="email">Email</Label> | ||
<Input type="email" id="fullname" defaultValue={profile.email} disabled /> | ||
</div> | ||
<Button type="submit" variant="darkCTA" className="mt-4" loading={isSubmitting}> | ||
Update | ||
</Button> | ||
</form> | ||
</> | ||
); | ||
} |
12 changes: 12 additions & 0 deletions
12
apps/web/app/(app)/environments/[environmentId]/settings/profile/actions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
"use server"; | ||
|
||
import { updateProfile, deleteProfile } from "@formbricks/lib/services/profile"; | ||
import { Prisma } from "@prisma/client"; | ||
|
||
export async function profileEditAction(userId: string, data: Prisma.UserUpdateInput) { | ||
return await updateProfile(userId, data); | ||
} | ||
|
||
export async function profileDeleteAction(userId: string) { | ||
return await deleteProfile(userId); | ||
} |
54 changes: 54 additions & 0 deletions
54
apps/web/app/(app)/environments/[environmentId]/settings/profile/loading.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
function LoadingCard({ title, description, skeletonLines }) { | ||
return ( | ||
<div className="my-4 rounded-lg border border-slate-200"> | ||
<div className="grid content-center rounded-lg bg-slate-100 px-6 py-5 text-left text-slate-900"> | ||
<h3 className="text-lg font-medium leading-6">{title}</h3> | ||
<p className="mt-1 text-sm text-slate-500">{description}</p> | ||
</div> | ||
<div className="w-full"> | ||
<div className="rounded-lg px-6 py-5 hover:bg-slate-100"> | ||
{skeletonLines.map((line, index) => ( | ||
<div key={index} className="mt-4"> | ||
<div className={`animate-pulse rounded-full bg-gray-200 ${line.classes}`}></div> | ||
</div> | ||
))} | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default function Loading() { | ||
const cards = [ | ||
{ | ||
title: "Personal Information", | ||
description: "Update your personal information", | ||
skeletonLines: [ | ||
{ classes: "h-4 w-28" }, | ||
{ classes: "h-6 w-64" }, | ||
{ classes: "h-4 w-28" }, | ||
{ classes: "h-6 w-64" }, | ||
{ classes: "h-8 w-24" }, | ||
], | ||
}, | ||
{ | ||
title: "Avatar", | ||
description: "Assist your team in identifying you on Formbricks.", | ||
skeletonLines: [{ classes: "h-10 w-10" }, { classes: "h-8 w-24" }], | ||
}, | ||
{ | ||
title: "Delete account", | ||
description: "Delete your account with all of your personal information and data.", | ||
skeletonLines: [{ classes: "h-4 w-60" }, { classes: "h-8 w-24" }], | ||
}, | ||
]; | ||
|
||
return ( | ||
<div> | ||
<h2 className="my-4 text-2xl font-medium leading-6 text-slate-800">Profile</h2> | ||
{cards.map((card, index) => ( | ||
<LoadingCard key={index} {...card} /> | ||
))} | ||
</div> | ||
); | ||
} |
46 changes: 29 additions & 17 deletions
46
apps/web/app/(app)/environments/[environmentId]/settings/profile/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,37 @@ | ||
import SettingsCard from "../SettingsCard"; | ||
import SettingsTitle from "../SettingsTitle"; | ||
export const revalidate = REVALIDATION_INTERVAL; | ||
|
||
import { REVALIDATION_INTERVAL } from "@formbricks/lib/constants"; | ||
import { getServerSession } from "next-auth"; | ||
import { EditName, EditAvatar, DeleteAccount } from "./editProfile"; | ||
import { authOptions } from "@/app/api/auth/[...nextauth]/authOptions"; | ||
import SettingsCard from "../SettingsCard"; | ||
import SettingsTitle from "../SettingsTitle"; | ||
import { DeleteAccount } from "./DeleteAccount"; | ||
import { EditName } from "./EditName"; | ||
import { EditAvatar } from "./EditAvatar"; | ||
import { getProfile } from "@formbricks/lib/services/profile"; | ||
|
||
export default async function ProfileSettingsPage() { | ||
const session = await getServerSession(authOptions); | ||
const profile = session ? await getProfile(session.user.id) : null; | ||
|
||
return ( | ||
<div> | ||
<SettingsTitle title="Profile" /> | ||
<SettingsCard title="Personal Information" description="Update your personal information."> | ||
<EditName /> | ||
</SettingsCard> | ||
<SettingsCard title="Avatar" description="Assist your team in identifying you on Formbricks."> | ||
<EditAvatar session={session} /> | ||
</SettingsCard> | ||
<SettingsCard | ||
title="Delete account" | ||
description="Delete your account with all of your personal information and data."> | ||
<DeleteAccount session={session} /> | ||
</SettingsCard> | ||
</div> | ||
<> | ||
{profile && ( | ||
<div> | ||
<SettingsTitle title="Profile" /> | ||
<SettingsCard title="Personal Information" description="Update your personal information."> | ||
<EditName profile={profile} /> | ||
</SettingsCard> | ||
<SettingsCard title="Avatar" description="Assist your team in identifying you on Formbricks."> | ||
<EditAvatar session={session} /> | ||
</SettingsCard> | ||
<SettingsCard | ||
title="Delete account" | ||
description="Delete your account with all of your personal information and data."> | ||
<DeleteAccount session={session} profile={profile} /> | ||
</SettingsCard> | ||
</div> | ||
)} | ||
</> | ||
); | ||
} |
Oops, something went wrong.