Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/dashboard/src/@/actions/updateAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { API_SERVER_URL } from "../constants/env";
export async function updateAccount(values: {
name?: string;
email?: string;
image?: string | null;
}) {
const token = await getAuthToken();

Expand Down
1 change: 1 addition & 0 deletions apps/dashboard/src/@3rdweb-sdk/react/hooks/useApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export type Account = {
id: string;
isStaff: boolean;
creatorWalletAddress: string;
image?: string | null;
name?: string;
email?: string;
advancedEnabled: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export type AccountHeaderCompProps = {
connectButton: React.ReactNode;
teamsAndProjects: Array<{ team: Team; projects: Project[] }>;
createProject: (team: Team) => void;
account: Pick<Account, "email" | "id"> | undefined;
account: Pick<Account, "email" | "id" | "image"> | undefined;
client: ThirdwebClient;
};

Expand All @@ -41,10 +41,9 @@ export function AccountHeaderDesktopUI(props: AccountHeaderCompProps) {
href="/account"
className="flex flex-row items-center gap-2 font-normal text-sm"
>
{/* TODO - set account Image */}
<GradientAvatar
id={props.account?.id || "default"}
src={""}
src={props.account?.image || ""}
className="size-6"
client={props.client}
/>
Expand Down Expand Up @@ -90,10 +89,9 @@ export function AccountHeaderMobileUI(props: AccountHeaderCompProps) {
"flex flex-row items-center gap-2 font-normal text-foreground text-sm",
)}
>
{/* TODO - set account image */}
<GradientAvatar
id={props.account?.id}
src={props.account ? "" : undefined}
src={props.account?.image || ""}
className="size-6"
client={props.client}
/>
Expand Down
21 changes: 19 additions & 2 deletions apps/dashboard/src/app/account/settings/AccountSettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { updateAccount } from "@/actions/updateAccount";
import { useDashboardRouter } from "@/lib/DashboardRouter";
import type { Account } from "@3rdweb-sdk/react/hooks/useApi";
import type { ThirdwebClient } from "thirdweb";
import { upload } from "thirdweb/storage";
import { AccountSettingsPageUI } from "./AccountSettingsPageUI";

export function AccountSettingsPage(props: {
Expand All @@ -23,9 +24,25 @@ export function AccountSettingsPage(props: {
</div>
<div className="container max-w-[950px] grow pt-8 pb-20">
<AccountSettingsPageUI
// TODO - remove hide props these when these fields are functional
hideAvatar
hideDeleteAccount
client={props.client}
updateAccountAvatar={async (file) => {
let uri: string | undefined = undefined;

if (file) {
// upload to IPFS
uri = await upload({
client: props.client,
files: [file],
});
}

await updateAccount({
image: uri,
});

router.refresh();
}}
account={props.account}
updateEmailWithOTP={async (otp) => {
const res = await confirmEmailWithOTP(otp);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Checkbox, CheckboxWithLabel } from "@/components/ui/checkbox";
import { getThirdwebClient } from "@/constants/thirdweb.server";
import type { Meta, StoryObj } from "@storybook/react";
import { useState } from "react";
import { Toaster } from "sonner";
Expand Down Expand Up @@ -33,6 +34,8 @@ export const Mobile: Story = {
},
};

const client = getThirdwebClient();

function Variants() {
const [isVerifiedEmail, setIsVerifiedEmail] = useState(true);
const [sendEmailFails, setSendEmailFails] = useState(false);
Expand Down Expand Up @@ -74,6 +77,10 @@ function Variants() {
? new Date().toISOString()
: undefined,
}}
client={client}
updateAccountAvatar={async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
}}
updateEmailWithOTP={async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
if (emailConfirmationFails) {
Expand Down
33 changes: 23 additions & 10 deletions apps/dashboard/src/app/account/settings/AccountSettingsPageUI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
InputOTPSlot,
} from "@/components/ui/input-otp";
import { useDashboardRouter } from "@/lib/DashboardRouter";
import { resolveSchemeWithErrorHandler } from "@/lib/resolveSchemeWithErrorHandler";
import { cn } from "@/lib/utils";
import type { Account } from "@3rdweb-sdk/react/hooks/useApi";
import { zodResolver } from "@hookform/resolvers/zod";
Expand All @@ -39,30 +40,35 @@ import { EllipsisIcon } from "lucide-react";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import type { ThirdwebClient } from "thirdweb";
import { z } from "zod";
import { FileInput } from "../../../components/shared/FileInput";

type MinimalAccount = Pick<
Account,
"name" | "email" | "emailConfirmedAt" | "unconfirmedEmail"
"name" | "email" | "emailConfirmedAt" | "unconfirmedEmail" | "image"
>;

export function AccountSettingsPageUI(props: {
account: MinimalAccount;
// TODO - remove hide props these when these fields are functional
hideAvatar?: boolean;
hideDeleteAccount?: boolean;
sendEmail: (email: string) => Promise<void>;
updateName: (name: string) => Promise<void>;
updateEmailWithOTP: (otp: string) => Promise<void>;
updateAccountAvatar: (avatar: File | undefined) => Promise<void>;
client: ThirdwebClient;
}) {
return (
<div className="flex flex-col gap-8">
{!props.hideAvatar && <AccountAvatarFormControl />}
<AccountNameFormControl
name={props.account.name || ""}
updateName={(name) => props.updateName(name)}
/>
<AccountAvatarFormControl
updateAccountAvatar={props.updateAccountAvatar}
avatar={props.account.image || undefined}
client={props.client}
/>
<AccountEmailFormControl
email={props.account.email || ""}
status={props.account.emailConfirmedAt ? "verified" : "unverified"}
Expand All @@ -75,18 +81,24 @@ export function AccountSettingsPageUI(props: {
);
}

function AccountAvatarFormControl() {
function AccountAvatarFormControl(props: {
updateAccountAvatar: (avatar: File | undefined) => Promise<void>;
avatar: string | undefined;
client: ThirdwebClient;
}) {
const accountAvatarUrl = resolveSchemeWithErrorHandler({
client: props.client,
uri: props.avatar,
});
const [avatar, setAvatar] = useState<File>();

// TODO - implement
const updateAvatarMutation = useMutation({
mutationFn: async () => {
await new Promise((resolve) => setTimeout(resolve, 3000));
mutationFn: (_avatar: File | undefined) => {
return props.updateAccountAvatar(_avatar);
},
});

function handleSave() {
const promises = updateAvatarMutation.mutateAsync();
const promises = updateAvatarMutation.mutateAsync(avatar);
toast.promise(promises, {
success: "Account avatar updated successfully",
error: "Failed to update account avatar",
Expand Down Expand Up @@ -118,6 +130,7 @@ function AccountAvatarFormControl() {
setValue={setAvatar}
className="w-20 rounded-full lg:w-28"
disableHelperText
fileUrl={accountAvatarUrl}
/>
</div>
</SettingsCard>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type { ThirdwebClient } from "thirdweb";
export function AccountButton(props: {
logout: () => void;
connectButton: React.ReactNode;
account?: Pick<Account, "email" | "id">;
account?: Pick<Account, "email" | "id" | "image">;
client: ThirdwebClient;
}) {
const { setTheme, theme } = useTheme();
Expand All @@ -35,11 +35,10 @@ export function AccountButton(props: {
>
{/* Don't remove the div */}
<div>
{/* TODO - set account image */}
<GradientAvatar
id={props.account?.id || "default"}
src={""}
className="size-9"
src={props.account?.image || ""}
className="size-9 border"
client={props.client}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function NebulaAccountButton(props: {
<div className="shrink-0">
<GradientAvatar
id={props.account?.id || "default"}
src={""}
src={props.account?.image || ""}
className="size-9 rounded-lg"
client={client}
/>
Expand All @@ -88,7 +88,7 @@ export function NebulaAccountButton(props: {
<div className="shrink-0">
<GradientAvatar
id={props.account?.id || "default"}
src={""}
src={props.account?.image || ""}
className="size-9 rounded-full"
client={client}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getTeamSettingsLinks } from "./getTeamSettingsLinks";

export function TeamSettingsSidebar(props: {
team: Team;
account: Pick<Account, "id"> | undefined;
account: Pick<Account, "id" | "image"> | undefined;
client: ThirdwebClient;
}) {
const teamLinks = getTeamSettingsLinks(props.team.slug);
Expand All @@ -34,7 +34,7 @@ export function TeamSettingsSidebar(props: {
team={props.team}
titleAvatarIcon={{
id: props.account?.id,
src: "", // TODO - set account image
src: props.account?.image || "",
}}
client={props.client}
/>
Expand All @@ -60,7 +60,7 @@ function RenderLinkGroup(props: {
<div className="flex items-center gap-1.5 px-4">
<GradientAvatar
src={props.titleAvatarIcon.src}
className="size-4"
className="size-[18px]"
id={props.titleAvatarIcon.id}
client={props.client}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
"use client";

import type { Team } from "@/api/team";
import { useThirdwebClient } from "@/constants/thirdweb.client";
import { getThirdwebClient } from "@/constants/thirdweb.server";
import { useDashboardRouter } from "@/lib/DashboardRouter";
import type { ThirdwebClient } from "thirdweb";
import { upload } from "thirdweb/storage";
import { TeamGeneralSettingsPageUI } from "./TeamGeneralSettingsPageUI";
import { updateTeam } from "./updateTeam";

export function TeamGeneralSettingsPage(props: {
team: Team;
authToken: string;
client: ThirdwebClient;
}) {
const router = useDashboardRouter();
const client = useThirdwebClient();

return (
<TeamGeneralSettingsPageUI
team={props.team}
client={client}
client={props.client}
updateTeamField={async (teamValue) => {
await updateTeam({
teamId: props.team.id,
Expand All @@ -38,7 +36,7 @@ export function TeamGeneralSettingsPage(props: {
if (file) {
// upload to IPFS
uri = await upload({
client: getThirdwebClient(props.authToken),
client: props.client,
files: [file],
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ function TeamAvatarFormControl(props: {
disabled: false,
isPending: updateTeamAvatarMutation.isPending,
}}
noPermissionText={undefined} // TODO
noPermissionText={undefined}
errorText={undefined}
>
<div className="flex flex-row gap-4 md:justify-between">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getTeamBySlug } from "@/api/team";
import { getThirdwebClient } from "@/constants/thirdweb.server";
import { notFound } from "next/navigation";
import { getAuthToken } from "../../../../../api/lib/getAuthToken";
import { TeamGeneralSettingsPage } from "./general/TeamGeneralSettingsPage";
Expand All @@ -14,5 +15,7 @@ export default async function Page(props: {
notFound();
}

return <TeamGeneralSettingsPage team={team} authToken={token} />;
return (
<TeamGeneralSettingsPage team={team} client={getThirdwebClient(token)} />
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function TeamSelectionUI(props: {
currentTeam: Team | undefined;
teamsAndProjects: Array<{ team: Team; projects: Project[] }>;
upgradeTeamLink: string | undefined;
account: Pick<Account, "email" | "id"> | undefined;
account: Pick<Account, "email" | "id" | "image"> | undefined;
client: ThirdwebClient;
}) {
const { setHoveredTeam, currentTeam, teamsAndProjects } = props;
Expand Down Expand Up @@ -52,9 +52,8 @@ export function TeamSelectionUI(props: {
asChild
>
<Link href="/account">
{/* TODO set Image src */}
<GradientAvatar
src={""}
src={props.account?.image || ""}
className="size-4"
id={props.account?.id}
client={props.client}
Expand Down
Loading