Added /profile to see your profile
This commit is contained in:
@@ -303,6 +303,12 @@ html, body {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.mx-tweet-avatar--lg {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.mx-compose-body { flex: 1; }
|
||||
|
||||
.mx-compose-textarea, .mx-edit-textarea {
|
||||
@@ -964,4 +970,6 @@ html, body {
|
||||
}
|
||||
.mx-header { padding: 0.75rem 1rem; }
|
||||
.mx-detail { padding: 0.875rem 1rem; }
|
||||
/* 5-item nav: slightly smaller labels so nothing wraps */
|
||||
.mx-mobile-nav-item { font-size: 0.6rem; }
|
||||
}
|
||||
|
||||
@@ -1208,7 +1208,7 @@ function UserList() {
|
||||
);
|
||||
}
|
||||
|
||||
function UserDetail({ userId }: { userId: string }) {
|
||||
function UserDetail({ userId, isStandalone = false }: { userId: string; isStandalone?: boolean }) {
|
||||
const { userId: currentUserId } = useContext(AuthCtx);
|
||||
const { follow, unfollow, isPending } = useFollowUser(userId);
|
||||
const { data: user, isLoading, isError } = useQuery({
|
||||
@@ -1228,30 +1228,38 @@ function UserDetail({ userId }: { userId: string }) {
|
||||
if (isLoading) return <Spinner />;
|
||||
if (isError || !user) return <ErrorBanner message="Could not load user" />;
|
||||
|
||||
const canFollow = !!currentUserId && currentUserId !== userId;
|
||||
const isOwnProfile = currentUserId === userId;
|
||||
const canFollow = !!currentUserId && !isOwnProfile;
|
||||
const amIFollowing = user.amIFollowing ?? false;
|
||||
|
||||
return (
|
||||
<div className="mx-detail">
|
||||
<div className="mx-detail-header">
|
||||
<a href="/users" className="mx-back-btn">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" />
|
||||
</svg>
|
||||
Back
|
||||
</a>
|
||||
</div>
|
||||
{!isStandalone && (
|
||||
<div className="mx-detail-header">
|
||||
<a href="/users" className="mx-back-btn">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" />
|
||||
</svg>
|
||||
Back
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
<div className="mx-detail-body">
|
||||
<div className="mx-detail-author">
|
||||
<div className="mx-tweet-avatar">
|
||||
<span>M</span>
|
||||
<div className="mx-tweet-avatar mx-tweet-avatar--lg">
|
||||
<span>{user.email?.[0]?.toUpperCase() ?? "M"}</span>
|
||||
</div>
|
||||
<div style={{ flex: 1 }}>
|
||||
<div style={{ display: "flex", alignItems: "center", gap: "12px" }}>
|
||||
<div style={{ display: "flex", alignItems: "center", gap: "12px", flexWrap: "wrap" }}>
|
||||
<span className="mx-tweet-handle">{user.email}</span>
|
||||
{canFollow && (
|
||||
<FollowButton amIFollowing={amIFollowing} isPending={isPending} onToggle={amIFollowing ? unfollow : follow} />
|
||||
)}
|
||||
{isOwnProfile && isStandalone && (
|
||||
<a href="/sign-out" className="mx-btn-cancel" style={{ textDecoration: "none", fontSize: "0.8rem" }}>
|
||||
Sign out
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
<div style={{ fontSize: "0.85rem", color: "var(--mx-muted)", marginTop: "6px", display: "flex", gap: "16px" }}>
|
||||
<span><strong>{user.followerCount ?? 0}</strong> followers</span>
|
||||
@@ -1264,6 +1272,25 @@ function UserDetail({ userId }: { userId: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
function MyProfile() {
|
||||
const { userId } = useContext(AuthCtx);
|
||||
|
||||
if (!userId) {
|
||||
return (
|
||||
<div className="mx-empty">
|
||||
<div className="mx-empty-icon">◎</div>
|
||||
<p className="mx-empty-title">Your profile</p>
|
||||
<p className="mx-empty-sub">
|
||||
<a href="/sign-in" style={{ color: "var(--mx-accent)", textDecoration: "none" }}>Sign in</a>
|
||||
{" "}to view your profile.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <UserDetail userId={userId} isStandalone />;
|
||||
}
|
||||
|
||||
// ── Mobile bottom nav ─────────────────────────────────────────────────────────
|
||||
|
||||
function MobileNav({
|
||||
@@ -1276,6 +1303,7 @@ function MobileNav({
|
||||
const onFeedPage = page === "feed" || page === "tweet";
|
||||
const onFollowingPage = page === "following";
|
||||
const onUsersPage = page === "users" || page === "user-detail";
|
||||
const onProfilePage = page === "profile";
|
||||
|
||||
return (
|
||||
<nav className="mx-mobile-nav">
|
||||
@@ -1328,6 +1356,16 @@ function MobileNav({
|
||||
</svg>
|
||||
<span>Users</span>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="/profile"
|
||||
className={`mx-mobile-nav-item${onProfilePage ? " mx-mobile-nav-item--active" : ""}`}
|
||||
>
|
||||
<svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" />
|
||||
</svg>
|
||||
<span>Profile</span>
|
||||
</a>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
@@ -1379,6 +1417,7 @@ function App() {
|
||||
const onFeedPage = page === "feed" || page === "tweet";
|
||||
const onFollowingPage = page === "following";
|
||||
const onUsersPage = page === "users" || page === "user-detail";
|
||||
const onProfilePage = page === "profile";
|
||||
|
||||
function renderMain() {
|
||||
switch (page) {
|
||||
@@ -1419,6 +1458,15 @@ function App() {
|
||||
<UserDetail userId={profileUserId!} />
|
||||
</>
|
||||
);
|
||||
case "profile":
|
||||
return (
|
||||
<>
|
||||
<header className="mx-header">
|
||||
<h1 className="mx-header-title">My Profile</h1>
|
||||
</header>
|
||||
<MyProfile />
|
||||
</>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<>
|
||||
@@ -1475,6 +1523,12 @@ function App() {
|
||||
</svg>
|
||||
Users
|
||||
</a>
|
||||
<a className={`mx-nav-item${onProfilePage ? " mx-nav-active" : ""}`} href="/profile">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" />
|
||||
</svg>
|
||||
Profile
|
||||
</a>
|
||||
</nav>
|
||||
<div className="mx-sidebar-footer">
|
||||
{email ? (
|
||||
|
||||
Reference in New Issue
Block a user