Messenger/packages/web/src/features/profile/ui/HeroAvatar.tsx
Заид Омар Медхат | Zaid Omar Medhat f5b620111b redesign
2026-07-11 04:49:07 +05:00

53 lines
1.7 KiB
TypeScript

import type { ReactElement, ReactNode, SyntheticEvent } from 'react';
import { CameraIcon } from '../../../shared/ui';
import { useMediaViewer } from '../../messaging';
interface Props {
url: string | null;
/** Placeholder content when there's no photo (initial letter or an icon). */
fallback: ReactNode;
alt: string;
/** When provided, shows a camera overlay that lets the user pick a new photo. */
onPick?: (file: File) => void;
}
// Profile/group hero avatar: click the photo to view it full-size in the
// lightbox; an optional camera overlay lets owners change it. Must be rendered
// inside a MediaViewerProvider.
export const HeroAvatar = ({ url, fallback, alt, onPick }: Props): ReactElement => {
const viewer = useMediaViewer();
const onFile = (event: SyntheticEvent<HTMLInputElement>): void => {
const input = event.currentTarget;
const file = input.files?.[0];
input.value = '';
if (file !== undefined) {
onPick?.(file);
}
};
return (
<div className="hero-avatar-wrap">
{url !== null ? (
<button
type="button"
className="hero-avatar-view"
aria-label="View photo"
onClick={() => {
viewer.open({ type: 'image', url, name: alt });
}}
>
<img src={url} alt="" className="profile-avatar" />
</button>
) : (
<span className="profile-avatar avatar-placeholder">{fallback}</span>
)}
{onPick !== undefined ? (
<label className="hero-avatar-edit" title="Change photo">
<CameraIcon size={18} />
<input type="file" accept="image/*" hidden onChange={onFile} />
</label>
) : null}
</div>
);
};