Skip to content

Commit 945b0d1

Browse files
committed
[TOOL-2891] Fix Team dashboard not loading if team slug contains special characters
1 parent 8136ec9 commit 945b0d1

File tree

3 files changed

+21
-11
lines changed

3 files changed

+21
-11
lines changed

apps/dashboard/src/app/team/[team_slug]/(team)/layout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ export default async function TeamLayout(props: {
2020
redirect("/login");
2121
}
2222

23-
const team = teams.find((t) => t.slug === params.team_slug);
23+
const team = teams.find(
24+
(t) => t.slug === decodeURIComponent(params.team_slug),
25+
);
2426
const teamsAndProjects = await Promise.all(
2527
teams.map(async (team) => ({
2628
team,

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

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ function TeamSlugFormControl(props: {
9797
updateTeamField: (team: Partial<Team>) => Promise<void>;
9898
}) {
9999
const [teamSlug, setTeamSlug] = useState(props.team.slug);
100-
const [isTeamTaken] = useState(false);
101100
const maxTeamURLLength = 48;
101+
const [errorMessage, setErrorMessage] = useState<string | undefined>();
102102

103103
const updateTeamMutation = useMutation({
104104
mutationFn: (slug: string) => props.updateTeamField({ slug: slug }),
@@ -120,14 +120,10 @@ function TeamSlugFormControl(props: {
120120
"This is your team's URL namespace on thirdweb. All your team's projects and settings can be accessed using this URL",
121121
}}
122122
bottomText={`Please use ${maxTeamURLLength} characters at maximum.`}
123-
errorText={
124-
isTeamTaken
125-
? "Team URL is taken, Please choose another one."
126-
: undefined
127-
}
123+
errorText={errorMessage}
128124
saveButton={{
129125
onClick: handleSave,
130-
disabled: teamSlug.length === 0,
126+
disabled: errorMessage !== undefined,
131127
isPending: updateTeamMutation.isPending,
132128
}}
133129
noPermissionText={undefined} // TODO
@@ -139,7 +135,17 @@ function TeamSlugFormControl(props: {
139135
<Input
140136
value={teamSlug}
141137
onChange={(e) => {
142-
setTeamSlug(e.target.value.slice(0, maxTeamURLLength));
138+
const value = e.target.value.slice(0, maxTeamURLLength);
139+
setTeamSlug(value);
140+
if (value.trim().length === 0) {
141+
setErrorMessage("Team URL can not be empty");
142+
} else if (/[^a-zA-Z0-9-]/.test(value)) {
143+
setErrorMessage(
144+
"Invalid Team URL. Only letters, numbers and hyphens are allowed",
145+
);
146+
} else {
147+
setErrorMessage(undefined);
148+
}
143149
}}
144150
className="truncate border-0 font-mono"
145151
/>

apps/dashboard/src/app/team/[team_slug]/[project_slug]/layout.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ export default async function TeamLayout(props: {
2020
redirect("/login");
2121
}
2222

23-
const team = teams.find((t) => t.slug === params.team_slug);
23+
const team = teams.find(
24+
(t) => t.slug === decodeURIComponent(params.team_slug),
25+
);
2426

2527
if (!team) {
2628
// not a valid team, redirect back to 404
@@ -35,7 +37,7 @@ export default async function TeamLayout(props: {
3537
);
3638

3739
const project = teamsAndProjects
38-
.find((t) => t.team.slug === params.team_slug)
40+
.find((t) => t.team.slug === decodeURIComponent(params.team_slug))
3941
?.projects.find((p) => p.slug === params.project_slug);
4042

4143
if (!project) {

0 commit comments

Comments
 (0)