mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-23 19:05:16 +02:00
refactor: extract user avatar color and initials logic into a new utility module, update related components to use the new functions
This commit is contained in:
parent
87caa4b6d0
commit
e0ecea61f8
6 changed files with 65 additions and 63 deletions
|
|
@ -27,14 +27,12 @@ export function ApiKeyContent() {
|
|||
|
||||
return (
|
||||
<div className="space-y-6 min-w-0 overflow-hidden">
|
||||
<Alert className="bg-muted/50 py-3 md:py-4">
|
||||
<Info className="h-3 w-3 md:h-4 md:w-4 shrink-0" />
|
||||
<AlertDescription className="text-xs md:text-sm">
|
||||
{t("api_key_warning_description")}
|
||||
</AlertDescription>
|
||||
<Alert>
|
||||
<Info />
|
||||
<AlertDescription>{t("api_key_warning_description")}</AlertDescription>
|
||||
</Alert>
|
||||
|
||||
<div className="rounded-lg border border-border/60 bg-card p-6 min-w-0 overflow-hidden">
|
||||
<div className="min-w-0 overflow-hidden">
|
||||
<h3 className="mb-4 text-sm font-semibold tracking-tight">{t("your_api_key")}</h3>
|
||||
{isLoading ? (
|
||||
<div className="h-12 w-full animate-pulse rounded-md border border-border/60 bg-muted/30" />
|
||||
|
|
@ -70,7 +68,7 @@ export function ApiKeyContent() {
|
|||
)}
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-border/60 bg-card p-6 min-w-0 overflow-hidden">
|
||||
<div className="min-w-0 overflow-hidden">
|
||||
<h3 className="mb-2 text-sm font-semibold tracking-tight">{t("usage_title")}</h3>
|
||||
<p className="mb-4 text-[11px] text-muted-foreground/60">{t("usage_description")}</p>
|
||||
<div className="flex items-center gap-2 rounded-md border border-border/60 bg-muted/30 px-2.5 py-1.5">
|
||||
|
|
|
|||
|
|
@ -11,8 +11,17 @@ import { Button } from "@/components/ui/button";
|
|||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Spinner } from "@/components/ui/spinner";
|
||||
import { getUserAvatarColor, getUserInitials } from "@/lib/user-avatar";
|
||||
|
||||
function AvatarDisplay({ url, fallback }: { url?: string; fallback: string }) {
|
||||
function AvatarDisplay({
|
||||
url,
|
||||
fallback,
|
||||
bgColor,
|
||||
}: {
|
||||
url?: string;
|
||||
fallback: string;
|
||||
bgColor: string;
|
||||
}) {
|
||||
const [errorUrl, setErrorUrl] = useState<string>();
|
||||
const hasError = errorUrl === url;
|
||||
|
||||
|
|
@ -23,15 +32,19 @@ function AvatarDisplay({ url, fallback }: { url?: string; fallback: string }) {
|
|||
alt="Avatar"
|
||||
width={64}
|
||||
height={64}
|
||||
className="h-16 w-16 rounded-xl object-cover"
|
||||
className="h-16 w-16 rounded-full object-cover select-none"
|
||||
onError={() => setErrorUrl(url)}
|
||||
referrerPolicy="no-referrer"
|
||||
unoptimized
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex h-16 w-16 items-center justify-center rounded-xl bg-muted text-xl font-semibold text-muted-foreground">
|
||||
<div
|
||||
className="flex h-16 w-16 shrink-0 items-center justify-center rounded-full text-xl font-semibold text-white select-none"
|
||||
style={{ backgroundColor: bgColor }}
|
||||
>
|
||||
{fallback}
|
||||
</div>
|
||||
);
|
||||
|
|
@ -50,11 +63,6 @@ export function ProfileContent() {
|
|||
}
|
||||
}, [user]);
|
||||
|
||||
const getInitials = (email: string) => {
|
||||
const name = email.split("@")[0];
|
||||
return name.slice(0, 2).toUpperCase();
|
||||
};
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -69,6 +77,7 @@ export function ProfileContent() {
|
|||
};
|
||||
|
||||
const hasChanges = displayName !== (user?.display_name || "");
|
||||
const avatarBgColor = getUserAvatarColor(user?.email || "");
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
|
@ -78,13 +87,13 @@ export function ProfileContent() {
|
|||
</div>
|
||||
) : (
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
<div className="rounded-lg bg-card">
|
||||
<div className="rounded-lg bg-main-panel">
|
||||
<div className="flex flex-col gap-6">
|
||||
<div className="space-y-2">
|
||||
<Label>{t("profile_avatar")}</Label>
|
||||
<AvatarDisplay
|
||||
url={user?.avatar_url || undefined}
|
||||
fallback={getInitials(user?.email || "")}
|
||||
fallback={getUserInitials(user?.email || "")}
|
||||
bgColor={avatarBgColor}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue