Add store logo and app icon uploads to settings page

AvatarUpload component now supports custom category and placeholder
icon props. Settings page shows two upload circles: Store Logo (for
PDFs/invoices, uses ImageIcon placeholder) and App Icon (for sidebar/
login, uses Building placeholder). Added 'company' to allowed file
entity types.
This commit is contained in:
Ryan Moon
2026-03-29 16:14:08 -05:00
parent 653fff6ce2
commit 8d75586f8b
3 changed files with 26 additions and 9 deletions

View File

@@ -23,9 +23,11 @@ function entityFilesOptions(entityType: string, entityId: string) {
}
interface AvatarUploadProps {
entityType: 'user' | 'member'
entityType: 'user' | 'member' | 'company'
entityId: string
size?: 'sm' | 'md' | 'lg'
category?: string
placeholderIcon?: React.ComponentType<{ className?: string }>
}
const sizeClasses = {
@@ -40,16 +42,17 @@ const iconSizes = {
lg: 'h-12 w-12',
}
export function AvatarUpload({ entityType, entityId, size = 'lg' }: AvatarUploadProps) {
export function AvatarUpload({ entityType, entityId, size = 'lg', category = 'profile', placeholderIcon: PlaceholderIcon }: AvatarUploadProps) {
const queryClient = useQueryClient()
const token = useAuthStore((s) => s.token)
const fileInputRef = useRef<HTMLInputElement>(null)
const [uploading, setUploading] = useState(false)
const IconComponent = PlaceholderIcon ?? User
const { data: filesData } = useQuery(entityFilesOptions(entityType, entityId))
// Find profile image from files
const profileFile = filesData?.data?.find((f) => f.path.includes('/profile-'))
// Find image by category
const profileFile = filesData?.data?.find((f) => f.path.includes(`/${category}-`))
const imageUrl = profileFile ? `/v1/files/serve/${profileFile.path}` : null
async function handleUpload(file: File) {
@@ -59,7 +62,7 @@ export function AvatarUpload({ entityType, entityId, size = 'lg' }: AvatarUpload
formData.append('file', file)
formData.append('entityType', entityType)
formData.append('entityId', entityId)
formData.append('category', 'profile')
formData.append('category', category)
// Delete existing profile image first
if (profileFile) {
@@ -105,7 +108,7 @@ export function AvatarUpload({ entityType, entityId, size = 'lg' }: AvatarUpload
className="h-full w-full object-cover"
/>
) : (
<User className={`${iconSizes[size]} text-muted-foreground`} />
<IconComponent className={`${iconSizes[size]} text-muted-foreground`} />
)}
</div>
<Button