feat: add hall logo support, fix fonts and build errors
This commit is contained in:
108
src/components/ui/image-upload.tsx
Normal file
108
src/components/ui/image-upload.tsx
Normal file
@@ -0,0 +1,108 @@
|
||||
"use client"
|
||||
|
||||
import { ChangeEvent, useState } from "react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { createClient } from "@/lib/supabase/client"
|
||||
import { ImagePlus, Loader2, X } from "lucide-react"
|
||||
import Image from "next/image"
|
||||
import { toast } from "sonner"
|
||||
|
||||
interface ImageUploadProps {
|
||||
value: string
|
||||
onChange: (url: string) => void
|
||||
disabled?: boolean
|
||||
bucketName?: string
|
||||
}
|
||||
|
||||
export function ImageUpload({
|
||||
value,
|
||||
onChange,
|
||||
disabled,
|
||||
bucketName = "images"
|
||||
}: ImageUploadProps) {
|
||||
const [isUploading, setIsUploading] = useState(false)
|
||||
const supabase = createClient()
|
||||
|
||||
const onUpload = async (e: ChangeEvent<HTMLInputElement>) => {
|
||||
try {
|
||||
const file = e.target.files?.[0]
|
||||
if (!file) return
|
||||
|
||||
setIsUploading(true)
|
||||
|
||||
// 1. Dosya ismini benzersiz yap
|
||||
const fileExt = file.name.split('.').pop()
|
||||
const fileName = `${Math.random()}.${fileExt}`
|
||||
const filePath = `${fileName}`
|
||||
|
||||
// 2. Upload
|
||||
const { error: uploadError } = await supabase.storage
|
||||
.from(bucketName)
|
||||
.upload(filePath, file)
|
||||
|
||||
if (uploadError) {
|
||||
throw uploadError
|
||||
}
|
||||
|
||||
// 3. Public URL getir
|
||||
const { data } = supabase.storage
|
||||
.from(bucketName)
|
||||
.getPublicUrl(filePath)
|
||||
|
||||
onChange(data.publicUrl)
|
||||
toast.success("Resim yüklendi")
|
||||
} catch (error) {
|
||||
toast.error("Resim yüklenirken hata oluştu")
|
||||
console.error(error)
|
||||
} finally {
|
||||
setIsUploading(false)
|
||||
}
|
||||
}
|
||||
|
||||
if (value) {
|
||||
return (
|
||||
<div className="relative w-[200px] h-[200px] rounded-md overflow-hidden border">
|
||||
<div className="z-10 absolute top-2 right-2">
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => onChange("")}
|
||||
variant="destructive"
|
||||
size="icon"
|
||||
disabled={disabled}
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<Image
|
||||
fill
|
||||
className="object-cover"
|
||||
alt="Image"
|
||||
src={value}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-[200px] h-[200px] rounded-md border-dashed border-2 flex items-center justify-center bg-muted/50 relative hover:opacity-75 transition disabled:opacity-50 disabled:cursor-not-allowed">
|
||||
<input
|
||||
type="file"
|
||||
accept="image/*"
|
||||
className="absolute inset-0 w-full h-full opacity-0 cursor-pointer disabled:cursor-not-allowed"
|
||||
onChange={onUpload}
|
||||
disabled={disabled || isUploading}
|
||||
/>
|
||||
{isUploading ? (
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
<div className="text-xs text-muted-foreground">Yükleniyor...</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<ImagePlus className="h-10 w-10 text-muted-foreground" />
|
||||
<div className="text-xs text-muted-foreground">Resim Yükle</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,10 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
Avatar,
|
||||
AvatarFallback,
|
||||
AvatarImage,
|
||||
} from "@/components/ui/avatar"
|
||||
// Avatar imports removed
|
||||
import { Button } from "@/components/ui/button"
|
||||
import {
|
||||
DropdownMenu,
|
||||
@@ -29,11 +25,8 @@ export function UserNav() {
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" className="relative h-8 w-8 rounded-full">
|
||||
<Avatar className="h-8 w-8">
|
||||
<AvatarImage src="/avatars/01.png" alt="@shadcn" />
|
||||
<AvatarFallback>AD</AvatarFallback>
|
||||
</Avatar>
|
||||
<Button variant="outline" className="relative">
|
||||
Seçenekler
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-56" align="end" forceMount>
|
||||
|
||||
Reference in New Issue
Block a user