Skip to content

Commit

Permalink
[TOOL-2891] Fix Team dashboard not loading if team slug contains spec…
Browse files Browse the repository at this point in the history
…ial characters (#5867)

## Problem solved

Short description of the bug fixed or feature added

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on improving the handling of `team_slug` and validating the `teamSlug` input in the settings UI. It enhances the URL decoding process and adds error handling for invalid team URLs.

### Detailed summary
- Updated `team_slug` retrieval to decode the URL component in `layout.tsx`.
- Modified project retrieval logic to decode `team_slug`.
- Replaced `isTeamTaken` state with `errorMessage` state for better error handling.
- Added validation for `teamSlug` input to check for empty values and invalid characters.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
  • Loading branch information
MananTank committed Jan 1, 2025
1 parent 8136ec9 commit 8b1a60d
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 11 deletions.
4 changes: 3 additions & 1 deletion apps/dashboard/src/app/team/[team_slug]/(team)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ export default async function TeamLayout(props: {
redirect("/login");
}

const team = teams.find((t) => t.slug === params.team_slug);
const team = teams.find(
(t) => t.slug === decodeURIComponent(params.team_slug),
);
const teamsAndProjects = await Promise.all(
teams.map(async (team) => ({
team,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ function TeamSlugFormControl(props: {
updateTeamField: (team: Partial<Team>) => Promise<void>;
}) {
const [teamSlug, setTeamSlug] = useState(props.team.slug);
const [isTeamTaken] = useState(false);
const maxTeamURLLength = 48;
const [errorMessage, setErrorMessage] = useState<string | undefined>();

const updateTeamMutation = useMutation({
mutationFn: (slug: string) => props.updateTeamField({ slug: slug }),
Expand All @@ -120,14 +120,10 @@ function TeamSlugFormControl(props: {
"This is your team's URL namespace on thirdweb. All your team's projects and settings can be accessed using this URL",
}}
bottomText={`Please use ${maxTeamURLLength} characters at maximum.`}
errorText={
isTeamTaken
? "Team URL is taken, Please choose another one."
: undefined
}
errorText={errorMessage}
saveButton={{
onClick: handleSave,
disabled: teamSlug.length === 0,
disabled: errorMessage !== undefined,
isPending: updateTeamMutation.isPending,
}}
noPermissionText={undefined} // TODO
Expand All @@ -139,7 +135,17 @@ function TeamSlugFormControl(props: {
<Input
value={teamSlug}
onChange={(e) => {
setTeamSlug(e.target.value.slice(0, maxTeamURLLength));
const value = e.target.value.slice(0, maxTeamURLLength);
setTeamSlug(value);
if (value.trim().length === 0) {
setErrorMessage("Team URL can not be empty");
} else if (/[^a-zA-Z0-9-]/.test(value)) {
setErrorMessage(
"Invalid Team URL. Only letters, numbers and hyphens are allowed",
);
} else {
setErrorMessage(undefined);
}
}}
className="truncate border-0 font-mono"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ export default async function TeamLayout(props: {
redirect("/login");
}

const team = teams.find((t) => t.slug === params.team_slug);
const team = teams.find(
(t) => t.slug === decodeURIComponent(params.team_slug),
);

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

const project = teamsAndProjects
.find((t) => t.team.slug === params.team_slug)
.find((t) => t.team.slug === decodeURIComponent(params.team_slug))
?.projects.find((p) => p.slug === params.project_slug);

if (!project) {
Expand Down

0 comments on commit 8b1a60d

Please sign in to comment.