test upload file to server

This commit is contained in:
Kenta420 2024-02-05 11:45:54 +07:00
parent 16e0e4f9d8
commit aaa60216b2
43 changed files with 1814 additions and 285 deletions

View file

@ -1,29 +1,32 @@
import { DashboardIcon, FileTextIcon, RocketIcon } from '@radix-ui/react-icons'
import React from 'react'
import { Link } from 'react-router-dom'
const Sidebar: React.FC = () => {
export type MenuList = {
title: string
icon: React.ComponentType<{ className?: string }>
link: string
}[]
interface SideBarProps {
menuList: MenuList
}
const Sidebar: React.FC<SideBarProps> = ({ menuList }) => {
return (
<aside className="fixed top-0 left-0 z-40 w-64 pt-20 h-screen">
<div className="h-full px-3 pb-4 overflow-y-auto bg-zinc-700">
<ul className="space-y-2 font-medium">
<li>
<Link to="/" className="flex items-center px-3 py-2 text-sm text-white rounded-md hover:bg-zinc-500">
<DashboardIcon className="inline-block w-6 h-6 mr-3" />
Dashboard
</Link>
</li>
<li>
<Link to="/recipes" className="flex items-center px-3 py-2 text-sm text-white rounded-md hover:bg-zinc-500">
<FileTextIcon className="inline-block w-6 h-6 mr-3" />
Recipes
</Link>
</li>
<li>
<Link to="/android" className="flex items-center px-3 py-2 text-sm text-white rounded-md hover:bg-zinc-500">
<RocketIcon className="inline-block w-6 h-6 mr-3" />
Android
</Link>
</li>
{menuList.map((item, index) => (
<li key={index}>
<Link
to={item.link}
className="flex items-center px-3 py-2 text-sm text-white rounded-md hover:bg-zinc-500"
>
{<item.icon className="inline-block w-6 h-6 mr-3" />}
{item.title}
</Link>
</li>
))}
</ul>
</div>
</aside>

View file

@ -0,0 +1,76 @@
import * as React from "react"
import { cn } from "@/lib/utils"
const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-xl border bg-card text-card-foreground shadow",
className
)}
{...props}
/>
))
Card.displayName = "Card"
const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
))
CardHeader.displayName = "CardHeader"
const CardTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
<h3
ref={ref}
className={cn("font-semibold leading-none tracking-tight", className)}
{...props}
/>
))
CardTitle.displayName = "CardTitle"
const CardDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<p
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
CardDescription.displayName = "CardDescription"
const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
))
CardContent.displayName = "CardContent"
const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
))
CardFooter.displayName = "CardFooter"
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }

View file

@ -0,0 +1,71 @@
import { Card, CardContent } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { cn } from '@/lib/utils'
import React, { type ChangeEvent, useRef } from 'react'
interface DropzoneProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'> {
classNameWrapper?: string
className?: string
dropMessage: string
handleOnDrop: (acceptedFiles: FileList | null) => void
}
const Dropzone = React.forwardRef<HTMLDivElement, DropzoneProps>(
({ className, classNameWrapper, dropMessage, handleOnDrop, ...props }, ref) => {
const inputRef = useRef<HTMLInputElement | null>(null)
// Function to handle drag over event
const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault()
e.stopPropagation()
handleOnDrop(null)
}
// Function to handle drop event
const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault()
e.stopPropagation()
const { files } = e.dataTransfer
if (inputRef.current) {
inputRef.current.files = files
handleOnDrop(files)
}
}
// Function to simulate a click on the file input element
const handleButtonClick = () => {
if (inputRef.current) {
inputRef.current.click()
}
}
return (
<Card
ref={ref}
className={cn(
`border-2 border-dashed bg-muted hover:cursor-pointer hover:border-muted-foreground/50`,
classNameWrapper
)}
>
<CardContent
className="flex flex-col items-center justify-center space-y-2 px-2 py-4 text-xs"
onDragOver={handleDragOver}
onDrop={handleDrop}
onClick={handleButtonClick}
>
<div className="flex items-center justify-center text-muted-foreground">
<span className="font-medium">{dropMessage}</span>
<Input
{...props}
value={undefined}
ref={inputRef}
type="file"
className={cn('hidden', className)}
onChange={(e: ChangeEvent<HTMLInputElement>) => handleOnDrop(e.target.files)}
/>
</div>
</CardContent>
</Card>
)
}
)
export default Dropzone