84 lines
3.1 KiB
TypeScript
84 lines
3.1 KiB
TypeScript
import { Card } from '@/components/ui/card';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Label } from '@/components/ui/label';
|
|
import { Camera, Upload, Save } from 'lucide-react';
|
|
|
|
interface EditProfileImagesCardProps {
|
|
avatar: string;
|
|
banner: string;
|
|
bannerUrl?: string;
|
|
onBannerUrlChange?: (url: string) => void;
|
|
loading: boolean;
|
|
onFileChange: (e: React.ChangeEvent<HTMLInputElement>, type: 'avatar' | 'banner') => void;
|
|
onSave: () => void;
|
|
}
|
|
|
|
export function EditProfileImagesCard({
|
|
avatar,
|
|
banner,
|
|
bannerUrl,
|
|
onBannerUrlChange,
|
|
loading,
|
|
onFileChange,
|
|
onSave,
|
|
}: EditProfileImagesCardProps) {
|
|
const bannerSrc = banner || 'https://via.placeholder.com/1200x400';
|
|
return (
|
|
<Card variant="default" className="p-0 overflow-hidden relative group">
|
|
<div className="h-48 md:h-64 bg-card relative">
|
|
<img src={bannerSrc} alt="" className="w-full h-full object-cover opacity-80" />
|
|
<div className="absolute inset-0 bg-black/20 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity">
|
|
<label className="cursor-pointer bg-black/60 hover:bg-black/80 text-foreground px-4 py-2 rounded-lg flex items-center gap-2 backdrop-blur border border-white/10">
|
|
<Camera className="w-4 h-4" /> Change Banner
|
|
<input
|
|
type="file"
|
|
className="hidden"
|
|
accept="image/*"
|
|
onChange={(e) => onFileChange(e, 'banner')}
|
|
/>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div className="px-8 relative -mt-16 mb-6 flex items-end justify-between">
|
|
<div className="relative group/avatar">
|
|
<div className="w-32 h-32 rounded-full border-4 border-border bg-muted overflow-hidden relative">
|
|
<img src={avatar} alt="" className="w-full h-full object-cover" />
|
|
<div className="absolute inset-0 bg-black/40 flex items-center justify-center opacity-0 group-hover/avatar:opacity-100 transition-opacity">
|
|
<label className="cursor-pointer p-2 bg-black/50 rounded-full hover:bg-black/70 text-foreground">
|
|
<Upload className="w-5 h-5" />
|
|
<input
|
|
type="file"
|
|
className="hidden"
|
|
accept="image/*"
|
|
onChange={(e) => onFileChange(e, 'avatar')}
|
|
/>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<Button
|
|
variant="primary"
|
|
icon={<Save className="w-4 h-4" />}
|
|
onClick={onSave}
|
|
disabled={loading}
|
|
>
|
|
{loading ? 'Saving...' : 'Save Changes'}
|
|
</Button>
|
|
</div>
|
|
{onBannerUrlChange && (
|
|
<div className="px-8 pb-4 space-y-2">
|
|
<Label htmlFor="banner-url">Banner URL</Label>
|
|
<Input
|
|
id="banner-url"
|
|
type="url"
|
|
placeholder="https://example.com/banner.jpg"
|
|
value={bannerUrl ?? ''}
|
|
onChange={(e) => onBannerUrlChange(e.target.value)}
|
|
className="max-w-md"
|
|
/>
|
|
</div>
|
|
)}
|
|
</Card>
|
|
);
|
|
}
|