Skip to content

Commit 156cc11

Browse files
Merge remote-tracking branch 'origin/main' into winston/update-user-details-doc-to-include-ecosystem
2 parents 7d34045 + 5dfde0f commit 156cc11

File tree

47 files changed

+784
-127
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+784
-127
lines changed

.changeset/hot-adults-doubt.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": minor
3+
---
4+
5+
New `useLinkProfile()` hook to link profiles to inapp and ecosystem accounts

apps/dashboard/src/@/api/team.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ export type Team = {
99
slug: string;
1010
createdAt: string;
1111
updatedAt: string;
12-
deletedAt: string | null;
13-
bannedAt: string | null;
14-
// image: string; // -> TODO
12+
deletedAt?: string;
13+
bannedAt?: string;
14+
image?: string;
1515
billingPlan: "pro" | "growth" | "free";
1616
billingStatus: "validPayment" | (string & {}); // what's the other value?
17-
// billingEmail: string;
17+
billingEmail: string;
1818
// billingExternalId: string;
1919
// billingType: "STRIPE" | ??
2020
// billingCustomerPayload: ?? | null

apps/dashboard/src/app/team/[team_slug]/(team)/~/settings/general/GeneralSettingsPage.stories.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,9 @@ const testTeam: Team = {
3838
slug: "team-slug-foo-bar",
3939
createdAt: "2023-07-07T19:21:33.604Z",
4040
updatedAt: "2024-07-11T00:01:02.241Z",
41-
deletedAt: null,
42-
bannedAt: null,
4341
billingStatus: "validPayment",
4442
billingPlan: "free",
43+
billingEmail: "[email protected]",
4544
};
4645

4746
function Story() {
@@ -52,6 +51,10 @@ function Story() {
5251
updateTeamImage={async () => {
5352
await new Promise((resolve) => setTimeout(resolve, 1000));
5453
}}
54+
updateTeamField={async (value) => {
55+
console.log(value);
56+
await new Promise((resolve) => setTimeout(resolve, 1000));
57+
}}
5558
/>
5659
<ComponentVariantions />
5760
<Toaster richColors />

apps/dashboard/src/app/team/[team_slug]/(team)/~/settings/general/TeamGeneralSettingsPage.tsx

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,51 @@
11
"use client";
22

33
import type { Team } from "@/api/team";
4-
import type { ThirdwebClient } from "thirdweb";
4+
import { getThirdwebClient } from "@/constants/thirdweb.server";
5+
import { useDashboardRouter } from "@/lib/DashboardRouter";
56
import { upload } from "thirdweb/storage";
67
import { TeamGeneralSettingsPageUI } from "./TeamGeneralSettingsPageUI";
8+
import { updateTeam } from "./updateTeam";
79

810
export function TeamGeneralSettingsPage(props: {
911
team: Team;
10-
client: ThirdwebClient;
12+
authToken: string;
1113
}) {
14+
const router = useDashboardRouter();
15+
1216
return (
1317
<TeamGeneralSettingsPageUI
1418
team={props.team}
19+
updateTeamField={async (teamValue) => {
20+
await updateTeam({
21+
teamId: props.team.id,
22+
value: teamValue,
23+
});
24+
25+
// Current page's slug is updated
26+
if (teamValue.slug) {
27+
router.replace(`/team/${teamValue.slug}/~/settings`);
28+
} else {
29+
router.refresh();
30+
}
31+
}}
1532
updateTeamImage={async (file) => {
33+
let uri: string | undefined = undefined;
34+
1635
if (file) {
1736
// upload to IPFS
18-
const uri = await upload({
19-
client: props.client,
37+
uri = await upload({
38+
client: getThirdwebClient(props.authToken),
2039
files: [file],
2140
});
22-
23-
// TODO - Implement updating the account image with uri
24-
console.log(uri);
25-
} else {
26-
// TODO - Implement deleting the account image
2741
}
2842

29-
throw new Error("Not implemented");
43+
await updateTeam({
44+
teamId: props.team.id,
45+
value: {
46+
image: uri,
47+
},
48+
});
3049
}}
3150
/>
3251
);

apps/dashboard/src/app/team/[team_slug]/(team)/~/settings/general/TeamGeneralSettingsPageUI.tsx

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,37 @@ import { DangerSettingCard } from "@/components/blocks/DangerSettingCard";
55
import { SettingsCard } from "@/components/blocks/SettingsCard";
66
import { CopyTextButton } from "@/components/ui/CopyTextButton";
77
import { Input } from "@/components/ui/input";
8+
import { useThirdwebClient } from "@/constants/thirdweb.client";
89
import { useDashboardRouter } from "@/lib/DashboardRouter";
910
import { useMutation } from "@tanstack/react-query";
1011
import { FileInput } from "components/shared/FileInput";
1112
import { useState } from "react";
1213
import { toast } from "sonner";
14+
import { resolveScheme } from "thirdweb/storage";
15+
16+
type UpdateTeamField = (team: Partial<Team>) => Promise<void>;
1317

1418
export function TeamGeneralSettingsPageUI(props: {
1519
team: Team;
1620
updateTeamImage: (file: File | undefined) => Promise<void>;
21+
updateTeamField: UpdateTeamField;
1722
}) {
1823
const hasPermissionToDelete = false; // TODO
1924
return (
2025
<div className="flex flex-col gap-8">
21-
<TeamNameFormControl team={props.team} />
22-
<TeamSlugFormControl team={props.team} />
23-
<TeamAvatarFormControl updateTeamImage={props.updateTeamImage} />
26+
<TeamNameFormControl
27+
team={props.team}
28+
updateTeamField={props.updateTeamField}
29+
/>
30+
<TeamSlugFormControl
31+
team={props.team}
32+
updateTeamField={props.updateTeamField}
33+
/>
34+
{/* THIS IS NOT WORKING - CAN"T UPDATE IMAGE */}
35+
<TeamAvatarFormControl
36+
updateTeamImage={props.updateTeamImage}
37+
avatar={props.team.image}
38+
/>
2439
<TeamIdCard team={props.team} />
2540
<LeaveTeamCard enabled={false} teamName={props.team.name} />
2641
<DeleteTeamCard
@@ -33,17 +48,13 @@ export function TeamGeneralSettingsPageUI(props: {
3348

3449
function TeamNameFormControl(props: {
3550
team: Team;
51+
updateTeamField: UpdateTeamField;
3652
}) {
3753
const [teamName, setTeamName] = useState(props.team.name);
3854
const maxTeamNameLength = 32;
3955

40-
// TODO - implement
4156
const updateTeamMutation = useMutation({
42-
mutationFn: async (teamName: string) => {
43-
await new Promise((resolve) => setTimeout(resolve, 3000));
44-
console.log("Updating team name to", teamName);
45-
throw new Error("Not implemented");
46-
},
57+
mutationFn: (name: string) => props.updateTeamField({ name }),
4758
});
4859

4960
function handleSave() {
@@ -82,20 +93,14 @@ function TeamNameFormControl(props: {
8293

8394
function TeamSlugFormControl(props: {
8495
team: Team;
96+
updateTeamField: (team: Partial<Team>) => Promise<void>;
8597
}) {
8698
const [teamSlug, setTeamSlug] = useState(props.team.slug);
8799
const [isTeamTaken] = useState(false);
88100
const maxTeamURLLength = 48;
89101

90-
// TODO - implement
91102
const updateTeamMutation = useMutation({
92-
mutationFn: async (_slug: string) => {
93-
// set isTeamTaken to true if team URL is taken
94-
// Fake loading
95-
await new Promise((resolve) => setTimeout(resolve, 3000));
96-
console.log("Updating team slug to", _slug);
97-
throw new Error("Not implemented");
98-
},
103+
mutationFn: (slug: string) => props.updateTeamField({ slug: slug }),
99104
});
100105

101106
function handleSave() {
@@ -144,8 +149,17 @@ function TeamSlugFormControl(props: {
144149

145150
function TeamAvatarFormControl(props: {
146151
updateTeamImage: (file: File | undefined) => Promise<void>;
152+
avatar: string | undefined;
147153
}) {
148-
const [teamAvatar, setTeamAvatar] = useState<File>(); // TODO: prefill with team avatar
154+
const client = useThirdwebClient();
155+
const teamUrl = props.avatar
156+
? resolveScheme({
157+
client: client,
158+
uri: props.avatar,
159+
})
160+
: undefined;
161+
162+
const [teamAvatar, setTeamAvatar] = useState<File | undefined>();
149163

150164
const updateTeamAvatarMutation = useMutation({
151165
mutationFn: async (_avatar: File | undefined) => {
@@ -186,6 +200,7 @@ function TeamAvatarFormControl(props: {
186200
setValue={setTeamAvatar}
187201
className="w-20 rounded-full lg:w-28"
188202
disableHelperText
203+
fileUrl={teamUrl}
189204
/>
190205
</div>
191206
</SettingsCard>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"use server";
2+
3+
import type { Team } from "@/api/team";
4+
import { API_SERVER_URL } from "@/constants/env";
5+
import { getAuthToken } from "../../../../../../api/lib/getAuthToken";
6+
7+
export async function updateTeam(params: {
8+
teamId: string;
9+
value: Partial<Team>;
10+
}) {
11+
const authToken = getAuthToken();
12+
13+
if (!authToken) {
14+
throw new Error("No auth token");
15+
}
16+
17+
const res = await fetch(`${API_SERVER_URL}/v1/teams/${params.teamId}`, {
18+
method: "PUT",
19+
headers: {
20+
"Content-Type": "application/json",
21+
Authorization: `Bearer ${authToken}`,
22+
},
23+
body: JSON.stringify(params.value),
24+
});
25+
26+
if (!res.ok) {
27+
throw new Error("failed to update team");
28+
}
29+
}

apps/dashboard/src/app/team/[team_slug]/(team)/~/settings/members/TeamMembersSettingsPage.stories.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,9 @@ const freeTeam: Team = {
4040
slug: "team-slug-foo-bar",
4141
createdAt: "2023-07-07T19:21:33.604Z",
4242
updatedAt: "2024-07-11T00:01:02.241Z",
43-
deletedAt: null,
44-
bannedAt: null,
4543
billingStatus: "validPayment",
4644
billingPlan: "free",
45+
billingEmail: "[email protected]",
4746
};
4847

4948
const proTeam: Team = {
@@ -52,10 +51,9 @@ const proTeam: Team = {
5251
slug: "team-slug-foo-bar",
5352
createdAt: "2023-07-07T19:21:33.604Z",
5453
updatedAt: "2024-07-11T00:01:02.241Z",
55-
deletedAt: null,
56-
bannedAt: null,
5754
billingStatus: "validPayment",
5855
billingPlan: "pro",
56+
billingEmail: "[email protected]",
5957
};
6058

6159
function createMemberStub(id: string, role: TeamAccountRole): TeamMember {

apps/dashboard/src/app/team/[team_slug]/(team)/~/settings/page.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { getTeamBySlug } from "@/api/team";
2-
import { getThirdwebClient } from "@/constants/thirdweb.server";
32
import { notFound } from "next/navigation";
43
import { getAuthToken } from "../../../../../api/lib/getAuthToken";
54
import { TeamGeneralSettingsPage } from "./general/TeamGeneralSettingsPage";
@@ -15,7 +14,5 @@ export default async function Page(props: {
1514
notFound();
1615
}
1716

18-
return (
19-
<TeamGeneralSettingsPage team={team} client={getThirdwebClient(token)} />
20-
);
17+
return <TeamGeneralSettingsPage team={team} authToken={token} />;
2118
}

apps/dashboard/src/app/team/[team_slug]/[project_slug]/contracts/_components/GetStartedWithContractsDeploy.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ const DeployOptions = () => {
108108
/>
109109

110110
<button
111-
className="mt-3 flex cursor-pointer items-center gap-2 rounded-lg border border-border bg-muted/50 p-4 hover:bg-muted"
111+
className="mt-3 flex w-full cursor-pointer items-center gap-2 rounded-lg border border-border bg-muted/50 p-4 hover:bg-muted"
112112
type="button"
113113
onClick={() => {
114114
activeTabContent.onClick?.();
@@ -136,7 +136,9 @@ const DeployOptions = () => {
136136
}`}
137137
/>
138138
<div>
139-
<h4 className="font-semibold text-lg">{activeTabContent.title}</h4>
139+
<h4 className="text-start font-semibold text-lg">
140+
{activeTabContent.title}
141+
</h4>
140142
<p className="text-muted-foreground text-sm">
141143
{activeTabContent.description}
142144
</p>

apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ export const CustomContractForm: React.FC<CustomContractFormProps> = ({
145145

146146
const customFactoryAbi = useCustomFactoryAbi(
147147
customFactoryAddress,
148-
Number(customFactoryNetwork),
148+
customFactoryNetwork ? Number(customFactoryNetwork) : undefined,
149149
);
150150

151151
const isTWPublisher = checkTwPublisher(metadata?.publisher);

0 commit comments

Comments
 (0)