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
6 changes: 4 additions & 2 deletions packages/kal-backend/src/lib/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@ async function syncUserFromLogto(
const now = new Date();
const usersCollection = db.collection<User>("users");

const displayName = claims.name || claims.username;
// Use name, username, or email (before @) as display name
const displayName = claims.name || claims.username || claims.email?.split("@")[0] || "";

// Upsert user - create if not exists, update if exists
const result = await usersCollection.findOneAndUpdate(
{ logtoId: claims.sub },
{
$set: {
email: claims.email || "",
name: displayName,
// Only update name if we have a value (don't overwrite with empty)
...(displayName ? { name: displayName } : {}),
updatedAt: now,
},
$setOnInsert: {
Expand Down
13 changes: 8 additions & 5 deletions packages/kal-frontend/src/app/dashboard/client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ export default function DashboardClient({ logtoId, email, name }: DashboardClien
return (
<>
<AuthUpdater logtoId={logtoId} email={email} name={name} />
<DashboardContentWrapper expectedLogtoId={logtoId} />
<DashboardContentWrapper expectedLogtoId={logtoId} nameProp={name} />
</>
);
}

function DashboardContentWrapper({ expectedLogtoId }: { expectedLogtoId?: string }) {
function DashboardContentWrapper({ expectedLogtoId, nameProp }: { expectedLogtoId?: string; nameProp?: string | null }) {
const { logtoId } = useAuth();

// Wait until context is updated with the Logto ID
Expand All @@ -46,10 +46,10 @@ function DashboardContentWrapper({ expectedLogtoId }: { expectedLogtoId?: string
);
}

return <DashboardContent />;
return <DashboardContent nameProp={nameProp} />;
}

function DashboardContent() {
function DashboardContent({ nameProp }: { nameProp?: string | null }) {
const [showGenerateModal, setShowGenerateModal] = useState(false);
const [newKeyName, setNewKeyName] = useState("");
const [newKeyExpiration, setNewKeyExpiration] = useState<"1_week" | "1_month" | "never">("1_month");
Expand Down Expand Up @@ -116,6 +116,9 @@ function DashboardContent() {
const dailyRemaining = Math.max(0, limits.dailyLimit - dailyUsed);
const dailyPercentage = Math.min(100, (dailyUsed / limits.dailyLimit) * 100);

// Use userInfo from backend, or fall back to prop from Logto claims
const displayName = userInfo?.name || nameProp || "Developer";

return (
<div className="dashboard-content">
{/* Usage Stats Section */}
Expand All @@ -128,7 +131,7 @@ function DashboardContent() {
</div>
<div className="profile-info">
<p className="profile-name">
{isLoadingUser ? "Loading..." : userInfo?.name || "Developer"}
{isLoadingUser ? "Loading..." : displayName}
</p>
<p className="profile-email">{userInfo?.email}</p>
</div>
Expand Down