Skip to content
Open
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
22 changes: 21 additions & 1 deletion app/[username]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
import React from "react";
import { DashboardSidebar } from "@/components/layout/SideBar";
import { DashboardNavbar } from "@/components/layout/DashboardNavBar";

export default function PublicProfileLayout({
children,
}: {
children: React.ReactNode;
}) {
return <section className="min-h-screen bg-[#0a0a0a]">{children}</section>;
return (
<div className="flex h-screen overflow-hidden bg-dashboard-bg">
{/* Sidebar */}
<div className="no-scrollbar h-full">
<DashboardSidebar />
</div>

{/* Main content area (navbar + page) */}
<div className="flex min-w-0 flex-1 flex-col overflow-hidden">
{/* Top navbar */}
<DashboardNavbar />

{/* Page content */}
<main className="no-scrollbar flex-1 overflow-y-auto bg-app-bg">
{children}
</main>
</div>
</div>
);
}
83 changes: 72 additions & 11 deletions app/[username]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,78 @@
"use client";

import React from "react";
import { useParams } from "next/navigation";
import DashboardMetrics from "@/components/dashboard/DashboardMetrics";
import { UserTokenList } from "@/components/dashboard/UserTokenList";
import { TokenData } from "@/components/dashboard/TokenList";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Prefer import type for type-only imports.

TokenData is used only as a type annotation and should be imported with import type for better clarity and tree-shaking.

♻️ Suggested fix
-import { TokenData } from "`@/components/dashboard/TokenList`";
+import type { TokenData } from "`@/components/dashboard/TokenList`";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { TokenData } from "@/components/dashboard/TokenList";
import type { TokenData } from "`@/components/dashboard/TokenList`";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/`[username]/page.tsx at line 7, The import of TokenData in page.tsx is a
type-only import — replace the current value import with a type-only import for
TokenData (from "`@/components/dashboard/TokenList`") so it reads as a type
import; update the import statement that references TokenData and ensure no
runtime usage of TokenData remains so the compiler/tree-shaker treats it as
type-only.

Source: Coding guidelines


const mockUserTokens: TokenData[] = [
{
tokenId: "0xa1b2c3",
name: "Vaccine Certificate",
type: "Health",
expiresIn: "3 years",
endorsements: 87,
},
{
tokenId: "0xd4e5f6",
name: "University Degree",
type: "Education",
expiresIn: "Never",
endorsements: 142,
},
{
tokenId: "0xg7h8i9",
name: "KYC Verified",
type: "Identity",
expiresIn: "2 years",
endorsements: 56,
},
{
tokenId: "0xj0k1l2",
name: "Employment Record",
type: "Work",
expiresIn: "1 year",
endorsements: 24,
},
{
tokenId: "0xm3n4o5",
name: "Open Source Contributor",
type: "Skill",
expiresIn: "Never",
endorsements: 203,
},
];

export default function UsernamePage() {
const params = useParams<{ username: string }>();
const username = params?.username ?? "";

export default async function UsernamePage({
params,
}: {
params: Promise<{ username: string }>;
}) {
const { username } = await params;
return (
<main className="flex min-h-screen items-center justify-center bg-app-bg">
<h1 className="font-utsaha text-2xl font-semibold text-white">
@{username}
</h1>
</main>
<div className="flex h-full flex-col gap-8 bg-app-bg pb-12">
<DashboardMetrics
name={username}
age={20}
nationality="Indian"
walletAddress="0x9032345320958093280943r82"
endorsers={128}
lastUpdated="1 Day Ago"
trustScore={92}
trustFlags="None"
trustDescription="Their On-Chain Reputation is excellent"
totalEndorsements={70}
activeTokens={14}
socials={3}
badgesEarned="300+ Trust Received"
/>

<div className="px-4 sm:px-6 md:pr-14 md:pl-10">
<UserTokenList
tokens={mockUserTokens}
onEndorse={(id) => console.log("Endorsing token:", id)}
onRevoke={(id) => console.log("Revoking token:", id)}
/>
</div>
</div>
);
}
58 changes: 58 additions & 0 deletions components/dashboard/UserTokenList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"use client";

import React from "react";
import { TokenCard } from "../cards/TokenCard";
import { TokenData } from "./TokenList";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Prefer import type for type-only imports.

TokenData is used only as a type annotation and should be imported with import type to improve clarity and enable better tree-shaking.

♻️ Suggested fix
-import { TokenData } from "./TokenList";
+import type { TokenData } from "./TokenList";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { TokenData } from "./TokenList";
import type { TokenData } from "./TokenList";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/dashboard/UserTokenList.tsx` at line 5, Replace the value import
of TokenData with a type-only import since TokenData is used purely as a type
annotation; update the import statement that currently references TokenData in
UserTokenList (the line importing from "./TokenList") to use `import type` so
the module loader/tree-shaker treats it as a type-only dependency.

Source: Coding guidelines


interface UserTokenListProps {
tokens: TokenData[];
className?: string;
onRevoke?: (tokenId: string) => void;
onEndorse?: (tokenId: string) => void;
onViewAll?: (tokenId: string) => void;
}

export function UserTokenList({
tokens,
className = "",
onRevoke,
onEndorse,
onViewAll,
}: UserTokenListProps) {
return (
<div
className={`w-full overflow-hidden rounded-2xl border border-card-border bg-card-bg p-4 sm:p-6 ${className}`}
>
{/* Section Title */}
<h2 className="mb-5 font-utsaha text-xl text-white md:mb-6 md:text-2xl">
Tokens
</h2>

{/* Token Cards */}
<div className="flex flex-col gap-3">
{tokens.length === 0 ? (
<div className="flex items-center justify-center py-12 font-utsaha text-lg text-gray-500">
No tokens found.
</div>
) : (
tokens.map((token) => (
<TokenCard
key={token.tokenId}
variant="discover"
tokenId={token.tokenId}
name={token.name}
type={token.type}
expiresIn={token.expiresIn}
endorsements={token.endorsements}
onRevoke={onRevoke ? () => onRevoke(token.tokenId) : undefined}
onEndorse={onEndorse ? () => onEndorse(token.tokenId) : undefined}
onViewAll={onViewAll ? () => onViewAll(token.tokenId) : undefined}
/>
))
)}
</div>
</div>
);
}

export default UserTokenList;
15 changes: 12 additions & 3 deletions components/layout/DashboardNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ export function DashboardNavbar() {
setIsCreateModalOpen(false);
};

const knownRoutes = ["/", "/home", "/dashboard", "/discover", "/settings"];
const firstSegment = pathname?.split("/").filter(Boolean)[0] ?? "";
const isUserProfile =
pathname !== "/" &&
!knownRoutes.includes(pathname) &&
firstSegment.length > 0;
Comment on lines +23 to +28

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Refactor route detection to use path segments for robustness.

The current logic checks the full pathname against knownRoutes, which works for the current flat route structure but would misidentify nested routes (e.g., /dashboard/settings) as user profiles. Checking the first path segment against known route segments would be more maintainable and future-proof.

♻️ Suggested refactor
- const knownRoutes = ["/", "/home", "/dashboard", "/discover", "/settings"];
+ const knownRouteSegments = ["home", "dashboard", "discover", "settings"];
  const firstSegment = pathname?.split("/").filter(Boolean)[0] ?? "";
  const isUserProfile =
    pathname !== "/" &&
-   !knownRoutes.includes(pathname) &&
-   firstSegment.length > 0;
+   firstSegment !== "" &&
+   !knownRouteSegments.includes(firstSegment);

This approach correctly handles both /dashboard and potential future routes like /dashboard/settings.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/layout/DashboardNavBar.tsx` around lines 23 - 28, The
route-detection logic misuses knownRoutes (full path strings) against pathname,
so nested routes like "/dashboard/settings" are flagged as profiles; update the
logic to compare the first path segment (firstSegment) against a list of known
route segments instead of the full pathname: change knownRoutes to a list of
segment names (e.g., "","home","dashboard","discover","settings" or without
empty string and handle "/" separately) and then compute isUserProfile by
checking pathname !== "/" && !knownRouteSegments.includes(firstSegment) &&
firstSegment.length > 0, keeping the existing variables (knownRoutes /
firstSegment / isUserProfile / pathname) for easy location.


const isDiscover = pathname === "/discover";

const getPageTitle = () => {
Expand All @@ -33,9 +40,11 @@ export function DashboardNavbar() {
<>
<nav className="flex h-[72px] w-full shrink-0 items-center justify-between border-b border-white/5 bg-dashboard-bg pr-5 pl-16 lg:px-8">
<div className="flex min-w-0 flex-1 items-center gap-4">
<h1 className="shrink-0 font-utsaha text-xl tracking-wide text-white">
{getPageTitle()}
</h1>
{!isUserProfile && (
<h1 className="shrink-0 font-utsaha text-xl tracking-wide text-white">
{getPageTitle()}
</h1>
)}

{isDiscover && (
<SearchBar placeholder="Search by Token ID or Decentralized ID…" />
Expand Down
Loading