chore: code refactor

This commit is contained in:
gosangam
2026-06-13 02:24:42 +05:30
parent cc5633c37a
commit 439664a97d
151 changed files with 1387 additions and 1138 deletions
+7 -47
View File
@@ -34,6 +34,7 @@ import { Settings, X } from "lucide-react";
import { cn } from "@/lib/utils";
import type { RelationshipResult, RelationshipState } from "@/lib/social";
import { ProfileActions } from "@/components/profile/profile-actions";
import { UserAvatar } from "@/components/ui/user-avatar";
import {
FollowListDrawer,
type FollowMode,
@@ -110,10 +111,14 @@ export function ProfileHeader({
return (
<>
<header className="flex flex-col items-center text-center gap-4 pt-4 pb-6 sm:pt-6 sm:pb-8">
<Avatar
<UserAvatar
src={avatarURL}
name={name}
onZoom={avatarURL ? () => setZoomOpen(true) : undefined}
className="size-24 sm:size-28"
textClassName="text-3xl"
interactive
onClick={avatarURL ? () => setZoomOpen(true) : undefined}
ariaLabel={`View ${name}'s profile picture`}
/>
<div className="space-y-2">
<div className="space-y-1">
@@ -242,51 +247,6 @@ function Stat({
);
}
function Avatar({
src,
name,
onZoom,
}: {
src: string | null;
name: string;
/** Provided when the avatar should be interactive — the parent shows
* the zoom modal on click. Omit (or pass undefined) to render the
* initials placeholder as a plain non-clickable element. */
onZoom?: () => void;
}) {
if (src) {
return (
<button
type="button"
onClick={onZoom}
aria-label={`View ${name}'s profile picture`}
className="rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
<Image
src={src}
alt={name}
width={112}
height={112}
className="size-24 sm:size-28 rounded-full object-cover ring-1 ring-foreground/10 hover:ring-foreground/30 transition"
unoptimized
/>
</button>
);
}
const initials =
name
.split(/\s+/)
.map((p) => p[0])
.slice(0, 2)
.join("")
.toUpperCase() || "?";
return (
<div className="size-24 sm:size-28 rounded-full bg-primary/15 text-primary flex items-center justify-center text-3xl font-semibold ring-1 ring-foreground/10">
{initials}
</div>
);
}
/**
* AvatarZoomModal — portaled full-screen overlay with the avatar shown
* inside a large circular crop. Click the backdrop or press Escape to
+2 -28
View File
@@ -14,9 +14,9 @@
import { useState } from "react";
import Link from "next/link";
import Image from "next/image";
import { usePathname, useRouter } from "next/navigation";
import { User as UserIcon, FolderOpen, Bookmark, LogOut, Menu } from "lucide-react";
import { UserAvatar } from "@/components/ui/user-avatar";
import {
Drawer,
DrawerContent,
@@ -98,7 +98,7 @@ function MobileSidebar({ user }: { user: User }) {
function SidebarHeader({ user }: { user: User }) {
return (
<div className="flex items-center gap-3 px-3 py-3 rounded-lg bg-card ring-1 ring-foreground/10">
<Avatar src={user.avatar_url} name={user.name} />
<UserAvatar src={user.avatar_url} name={user.name} />
<div className="min-w-0">
<p className="text-sm font-semibold text-foreground truncate">
{user.name}
@@ -161,29 +161,3 @@ function SidebarFooter() {
);
}
function Avatar({ src, name }: { src: string | null; name: string }) {
if (src) {
return (
<Image
src={src}
alt={name}
width={40}
height={40}
className="size-10 rounded-full object-cover ring-1 ring-foreground/10 shrink-0"
unoptimized
/>
);
}
const initials =
name
.split(/\s+/)
.map((p) => p[0])
.slice(0, 2)
.join("")
.toUpperCase() || "?";
return (
<div className="size-10 rounded-full bg-primary/15 text-primary flex items-center justify-center text-sm font-semibold ring-1 ring-foreground/10 shrink-0">
{initials}
</div>
);
}
+7 -28
View File
@@ -6,8 +6,8 @@
* thing visitors do, plus an action slot for an "Edit profile" button.
*/
import Image from "next/image";
import type { User } from "@/lib/auth";
import { UserAvatar } from "@/components/ui/user-avatar";
export function ProfileViewHeader({
user,
@@ -20,7 +20,12 @@ export function ProfileViewHeader({
}) {
return (
<header className="flex flex-col sm:flex-row sm:items-center gap-5 sm:gap-6">
<Avatar src={user.avatar_url} name={user.name} />
<UserAvatar
src={user.avatar_url}
name={user.name}
className="size-20 sm:size-22"
textClassName="text-2xl"
/>
<div className="flex-1 min-w-0">
<div className="flex items-start justify-between gap-3">
<div className="min-w-0">
@@ -43,29 +48,3 @@ export function ProfileViewHeader({
);
}
function Avatar({ src, name }: { src: string | null; name: string }) {
if (src) {
return (
<Image
src={src}
alt={name}
width={88}
height={88}
className="size-20 sm:size-22 rounded-full object-cover ring-1 ring-foreground/10"
unoptimized
/>
);
}
const initials =
name
.split(/\s+/)
.map((p) => p[0])
.slice(0, 2)
.join("")
.toUpperCase() || "?";
return (
<div className="size-20 sm:size-22 rounded-full bg-primary/15 text-primary flex items-center justify-center text-2xl font-semibold ring-1 ring-foreground/10">
{initials}
</div>
);
}