mirror of
https://github.com/walkxcode/dashboard-icons.git
synced 2025-10-28 05:59:04 +08:00
feat: add file upload dropzone to icon submission dialog
- Add Dropzone component for direct file uploads - Support multiple image formats (png, jpg, svg, webp) - Show file preview after upload - Add divider between dropzone and GitHub issue templates - Max 5 files with 5MB size limit each
This commit is contained in:
@@ -6,6 +6,7 @@ import Link from "next/link"
|
|||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
|
||||||
|
import { Dropzone, DropzoneContent, DropzoneEmptyState } from "@/components/ui/shadcn-io/dropzone"
|
||||||
import { REPO_PATH } from "@/constants"
|
import { REPO_PATH } from "@/constants"
|
||||||
|
|
||||||
export const ISSUE_TEMPLATES = [
|
export const ISSUE_TEMPLATES = [
|
||||||
@@ -41,8 +42,62 @@ export const ISSUE_TEMPLATES = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
export function IconSubmissionContent({ onClose }: { onClose?: () => void }) {
|
export function IconSubmissionContent({ onClose }: { onClose?: () => void }) {
|
||||||
|
const [files, setFiles] = useState<File[] | undefined>()
|
||||||
|
const [filePreview, setFilePreview] = useState<string | undefined>()
|
||||||
|
|
||||||
|
const handleDrop = (files: File[]) => {
|
||||||
|
console.log(files)
|
||||||
|
setFiles(files)
|
||||||
|
if (files.length > 0) {
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onload = (e) => {
|
||||||
|
if (typeof e.target?.result === 'string') {
|
||||||
|
setFilePreview(e.target?.result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(files[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
|
{/* Dropzone Section */}
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h3 className="text-sm font-medium">Upload Icon Files</h3>
|
||||||
|
<Dropzone
|
||||||
|
accept={{ 'image/*': ['.png', '.jpg', '.jpeg', '.svg', '.webp'] }}
|
||||||
|
onDrop={handleDrop}
|
||||||
|
onError={console.error}
|
||||||
|
src={files}
|
||||||
|
maxFiles={5}
|
||||||
|
maxSize={1024 * 1024 * 5}
|
||||||
|
>
|
||||||
|
<DropzoneEmptyState />
|
||||||
|
<DropzoneContent>
|
||||||
|
{filePreview && (
|
||||||
|
<div className="h-[102px] w-full">
|
||||||
|
<img
|
||||||
|
alt="Preview"
|
||||||
|
className="absolute top-0 left-0 h-full w-full object-cover"
|
||||||
|
src={filePreview}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</DropzoneContent>
|
||||||
|
</Dropzone>
|
||||||
|
{files && files.length > 0 && (
|
||||||
|
<div className="text-xs text-muted-foreground">
|
||||||
|
{files.length} file(s) selected
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Divider */}
|
||||||
|
<div className="border-t pt-4">
|
||||||
|
<p className="text-sm text-muted-foreground mb-3">Or submit via GitHub issue:</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Issue Templates */}
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
{ISSUE_TEMPLATES.map((template) => (
|
{ISSUE_TEMPLATES.map((template) => (
|
||||||
<Link key={template.id} href={template.url} className="w-full group z10" target="_blank" rel="noopener noreferrer">
|
<Link key={template.id} href={template.url} className="w-full group z10" target="_blank" rel="noopener noreferrer">
|
||||||
|
|||||||
Reference in New Issue
Block a user