chore: add Biome for formatting and linting (#116)

- Add Biome as formatter and linter (replaces Prettier)
- Configure Husky + lint-staged for pre-commit hooks
- Add VS Code settings for format on save
- Ignore components/ui/ (shadcn generated code)
- Remove semicolons, use 4-space indent
- Reformat all files to new style
This commit is contained in:
Dayuan Jiang
2025-12-06 12:46:40 +09:00
committed by GitHub
parent 215a101f54
commit 150eb1ff63
41 changed files with 3992 additions and 2401 deletions

View File

@@ -1,40 +1,44 @@
"use client";
"use client"
import React, { useEffect, useState } from "react";
import Image from "next/image";
import { X } from "lucide-react";
import { X } from "lucide-react"
import Image from "next/image"
import React, { useEffect, useState } from "react"
interface FilePreviewListProps {
files: File[];
onRemoveFile: (fileToRemove: File) => void;
files: File[]
onRemoveFile: (fileToRemove: File) => void
}
export function FilePreviewList({ files, onRemoveFile }: FilePreviewListProps) {
const [selectedImage, setSelectedImage] = useState<string | null>(null);
const [selectedImage, setSelectedImage] = useState<string | null>(null)
// Cleanup object URLs on unmount
useEffect(() => {
const objectUrls = files
.filter((file) => file.type.startsWith("image/"))
.map((file) => URL.createObjectURL(file));
.map((file) => URL.createObjectURL(file))
return () => {
objectUrls.forEach(URL.revokeObjectURL);
};
}, [files]);
objectUrls.forEach(URL.revokeObjectURL)
}
}, [files])
if (files.length === 0) return null;
if (files.length === 0) return null
return (
<>
<div className="flex flex-wrap gap-2 mt-2 p-2 bg-muted/50 rounded-md">
{files.map((file, index) => {
const imageUrl = file.type.startsWith("image/") ? URL.createObjectURL(file) : null;
const imageUrl = file.type.startsWith("image/")
? URL.createObjectURL(file)
: null
return (
<div key={file.name + index} className="relative group">
<div
className="w-20 h-20 border rounded-md overflow-hidden bg-muted cursor-pointer"
onClick={() => imageUrl && setSelectedImage(imageUrl)}
onClick={() =>
imageUrl && setSelectedImage(imageUrl)
}
>
{file.type.startsWith("image/") ? (
<Image
@@ -59,7 +63,7 @@ export function FilePreviewList({ files, onRemoveFile }: FilePreviewListProps) {
<X className="h-3 w-3" />
</button>
</div>
);
)
})}
</div>
@@ -89,5 +93,5 @@ export function FilePreviewList({ files, onRemoveFile }: FilePreviewListProps) {
</div>
)}
</>
);
)
}