style: reorganize imports and format code for consistency

Refactor import statements and code formatting across multiple files to improve readability and maintain consistency. This includes reordering imports, fixing linting issues, and standardizing code style.
This commit is contained in:
Daniel Luiz Alves
2025-04-11 15:01:32 -03:00
parent e55f090235
commit b4cecf9e32
25 changed files with 2430 additions and 2037 deletions

3937
apps/app/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
import type { EmptyStateProps } from "../types";
import { Button } from "@/components/ui/button";
import { useTranslations } from "next-intl";
import { IconCloudUpload, IconFolder } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import { Button } from "@/components/ui/button";
import type { EmptyStateProps } from "../types";
export function EmptyState({ onUpload }: EmptyStateProps) {
const t = useTranslations();

View File

@@ -1,9 +1,9 @@
import { FilesTable } from "@/components/tables/files-table";
import { Card, CardContent } from "@/components/ui/card";
import { FileListProps } from "../types";
import { EmptyState } from "./empty-state";
import { Header } from "./header";
import { SearchBar } from "./search-bar";
import { FilesTable } from "@/components/tables/files-table";
import { Card, CardContent } from "@/components/ui/card";
export function FileList({ files, filteredFiles, fileManager, searchQuery, onSearch, onUpload }: FileListProps) {
return (

View File

@@ -1,7 +1,8 @@
import type { HeaderProps } from "../types";
import { Button } from "@/components/ui/button";
import { useTranslations } from "next-intl";
import { IconCloudUpload } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import { Button } from "@/components/ui/button";
import type { HeaderProps } from "../types";
export function Header({ onUpload }: HeaderProps) {
const t = useTranslations();

View File

@@ -1,7 +1,8 @@
import type { SearchBarProps } from "../types";
import { Input } from "@/components/ui/input";
import { useTranslations } from "next-intl";
import { IconSearch } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import { Input } from "@/components/ui/input";
import type { SearchBarProps } from "../types";
export function SearchBar({ searchQuery, onSearch, totalFiles, filteredCount }: SearchBarProps) {
const t = useTranslations();

View File

@@ -1,10 +1,11 @@
"use client";
import { useEffect, useState } from "react";
import { useTranslations } from "next-intl";
import { toast } from "sonner";
import { useFileManager } from "@/hooks/use-file-manager";
import { listFiles } from "@/http/endpoints";
import { useTranslations } from "next-intl";
import { useEffect, useState } from "react";
import { toast } from "sonner";
export function useFiles() {
const t = useTranslations();

View File

@@ -1,7 +1,7 @@
import type { FilesModalsProps } from "../types";
import { FileActionsModals } from "@/components/modals/file-actions-modals";
import { FilePreviewModal } from "@/components/modals/file-preview-modal";
import { UploadFileModal } from "@/components/modals/upload-file-modal";
import type { FilesModalsProps } from "../types";
export function FilesModals({ fileManager, modals, onSuccess }: FilesModalsProps) {
return (

View File

@@ -1,13 +1,14 @@
"use client";
import { IconFolderOpen } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import { ProtectedRoute } from "@/components/auth/protected-route";
import { FileManagerLayout } from "@/components/layout/file-manager-layout";
import { LoadingScreen } from "@/components/layout/loading-screen";
import { FileList } from "./components/file-list";
import { useFiles } from "./hooks/use-files";
import { FilesModals } from "./modals/files-modals";
import { FileManagerLayout } from "@/components/layout/file-manager-layout";
import { LoadingScreen } from "@/components/layout/loading-screen";
import { IconFolderOpen } from "@tabler/icons-react";
export default function FilesPage() {
const t = useTranslations();
@@ -19,21 +20,23 @@ export default function FilesPage() {
}
return (
<FileManagerLayout
breadcrumbLabel={t("files.breadcrumb")}
icon={<IconFolderOpen size={20}/>}
title={t("files.pageTitle")}
>
<FileList
fileManager={fileManager}
files={files}
filteredFiles={filteredFiles}
searchQuery={searchQuery}
onSearch={handleSearch}
onUpload={modals.onOpenUploadModal}
/>
<ProtectedRoute>
<FileManagerLayout
breadcrumbLabel={t("files.breadcrumb")}
icon={<IconFolderOpen size={20} />}
title={t("files.pageTitle")}
>
<FileList
fileManager={fileManager}
files={files}
filteredFiles={filteredFiles}
searchQuery={searchQuery}
onSearch={handleSearch}
onUpload={modals.onOpenUploadModal}
/>
<FilesModals fileManager={fileManager} modals={modals} onSuccess={loadFiles} />
</FileManagerLayout>
<FilesModals fileManager={fileManager} modals={modals} onSuccess={loadFiles} />
</FileManagerLayout>
</ProtectedRoute>
);
}

View File

@@ -1,10 +1,11 @@
import { addFiles, listFiles, removeFiles } from "@/http/endpoints";
import { Button } from "@/components/ui/button";
import { useTranslations } from "next-intl";
import { useEffect, useState } from "react";
import { IconFile, IconArrowLeft, IconArrowRight } from "@tabler/icons-react";
import { IconArrowLeft, IconArrowRight, IconFile } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { addFiles, listFiles, removeFiles } from "@/http/endpoints";
interface FileSelectorProps {
shareId: string;

View File

@@ -1,13 +1,14 @@
"use client";
import { useShareContext } from "@/contexts/share-context";
import { addRecipients, removeRecipients, notifyRecipients } from "@/http/endpoints";
import { useEffect, useState } from "react";
import { IconBell, IconMail, IconPlus, IconTrash } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { useState, useEffect } from "react";
import { IconPlus, IconTrash, IconMail, IconBell } from "@tabler/icons-react";
import { toast } from "sonner";
import { useTranslations } from "next-intl";
import { useShareContext } from "@/contexts/share-context";
import { addRecipients, notifyRecipients, removeRecipients } from "@/http/endpoints";
interface Recipient {
id: string;

View File

@@ -4,8 +4,6 @@ import { IconLayoutDashboard } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import { Navbar } from "@/components/layout/navbar";
import { DefaultFooter } from "@/components/ui/default-footer";
import { Separator } from "@/components/ui/separator";
import {
Breadcrumb,
BreadcrumbItem,
@@ -13,6 +11,8 @@ import {
BreadcrumbList,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";
import { DefaultFooter } from "@/components/ui/default-footer";
import { Separator } from "@/components/ui/separator";
interface FileManagerLayoutProps {
children: ReactNode;

View File

@@ -1,19 +1,14 @@
import { createShare } from "@/http/endpoints";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";
import { useTranslations } from "next-intl";
import { useState } from "react";
import { IconCalendar, IconEye, IconLock, IconShare } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import { toast } from "sonner";
import { IconShare, IconLock, IconCalendar, IconEye } from "@tabler/icons-react";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { createShare } from "@/http/endpoints";
interface CreateShareModalProps {
isOpen: boolean;
@@ -72,12 +67,9 @@ export function CreateShareModal({ isOpen, onClose, onSuccess }: CreateShareModa
<div className="flex flex-col gap-4">
<div className="space-y-2">
<Label>{t("createShare.nameLabel")}</Label>
<Input
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
/>
<Input value={formData.name} onChange={(e) => setFormData({ ...formData, name: e.target.value })} />
</div>
<div className="space-y-2">
<Label className="flex items-center gap-2">
<IconCalendar size={16} />
@@ -139,11 +131,7 @@ export function CreateShareModal({ isOpen, onClose, onSuccess }: CreateShareModa
{t("common.cancel")}
</Button>
<Button disabled={isLoading} onClick={handleSubmit}>
{isLoading ? (
<div className="animate-spin"></div>
) : (
t("createShare.create")
)}
{isLoading ? <div className="animate-spin"></div> : t("createShare.create")}
</Button>
</DialogFooter>
</DialogContent>

View File

@@ -1,15 +1,16 @@
import { IconEdit, IconTrash } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { IconEdit, IconTrash } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import { Input } from "@/components/ui/input";
interface FileActionsModalsProps {
fileToRename: { id: string; name: string; description?: string } | null;
@@ -109,9 +110,11 @@ export function FileActionsModals({
</DialogHeader>
<DialogDescription>
<p className="text-base font-semibold mb-2 text-foreground">{t("fileActions.deleteConfirmation")}</p>
<p>{fileToDelete?.name && (fileToDelete.name.length > 50
? fileToDelete.name.substring(0, 50) + "..."
: fileToDelete.name) || ''}</p>
<p>
{(fileToDelete?.name &&
(fileToDelete.name.length > 50 ? fileToDelete.name.substring(0, 50) + "..." : fileToDelete.name)) ||
""}
</p>
<p className="text-sm mt-2 text-amber-500">{t("fileActions.deleteWarning")}</p>
</DialogDescription>
<DialogFooter>

View File

@@ -1,20 +1,17 @@
"use client";
/* eslint-disable jsx-a11y/media-has-caption */
import { useEffect, useState } from "react";
import { IconDownload } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import { toast } from "sonner";
import { AspectRatio } from "@/components/ui/aspect-ratio";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogFooter, DialogHeader } from "@/components/ui/dialog";
import { ScrollArea } from "@/components/ui/scroll-area";
import { getDownloadUrl } from "@/http/endpoints";
import { getFileIcon } from "@/utils/file-icons";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogHeader,
DialogFooter,
} from "@/components/ui/dialog";
import { useTranslations } from "next-intl";
import { useState, useEffect } from "react";
import { IconDownload } from "@tabler/icons-react";
import { toast } from "sonner";
import { AspectRatio } from "@/components/ui/aspect-ratio";
import { ScrollArea } from "@/components/ui/scroll-area";
interface FilePreviewModalProps {
isOpen: boolean;
@@ -132,11 +129,7 @@ export function FilePreviewModal({ isOpen, onClose, file }: FilePreviewModalProp
case "image":
return (
<AspectRatio ratio={16 / 9} className="bg-muted">
<img
src={previewUrl}
alt={file.name}
className="object-contain w-full h-full rounded-md"
/>
<img src={previewUrl} alt={file.name} className="object-contain w-full h-full rounded-md" />
</AspectRatio>
);
case "audio":

View File

@@ -1,19 +1,14 @@
import type { ListUserShares200SharesItem } from "@/http/models/listUserShares200SharesItem";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { useEffect, useState } from "react";
import { IconCopy } from "@tabler/icons-react";
import { customNanoid } from "@/lib/utils";
import { useTranslations } from "next-intl";
import { useState, useEffect } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import type { ListUserShares200SharesItem } from "@/http/models/listUserShares200SharesItem";
import { customNanoid } from "@/lib/utils";
interface GenerateShareLinkModalProps {
shareId: string | null;
share: ListUserShares200SharesItem | null;
@@ -22,7 +17,7 @@ interface GenerateShareLinkModalProps {
onGenerate: (shareId: string, alias: string) => Promise<void>;
}
const generateCustomId = () => customNanoid(10, '0123456789abcdefghijklmnopqrstuvwxyz');
const generateCustomId = () => customNanoid(10, "0123456789abcdefghijklmnopqrstuvwxyz");
export function GenerateShareLinkModal({
shareId,
@@ -100,10 +95,7 @@ export function GenerateShareLinkModal({
)}
<DialogFooter>
{!generatedLink ? (
<Button
disabled={!alias || isLoading}
onClick={handleGenerate}
>
<Button disabled={!alias || isLoading} onClick={handleGenerate}>
{isEdit ? t("generateShareLink.updateButton") : t("generateShareLink.generateButton")}
</Button>
) : (

View File

@@ -1,21 +1,22 @@
import { useEffect, useState } from "react";
import { useTranslations } from "next-intl";
import { toast } from "sonner";
import { FileSelector } from "@/components/general/file-selector";
import { RecipientSelector } from "@/components/general/recipient-selector";
import { updateSharePassword } from "@/http/endpoints";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import {
Dialog,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { useTranslations } from "next-intl";
import { useState, useEffect } from "react";
import { toast } from "sonner";
import { Switch } from "@/components/ui/switch";
import { updateSharePassword } from "@/http/endpoints";
export interface ShareActionsModalsProps {
shareToDelete: any;
@@ -133,10 +134,7 @@ export function ShareActionsModals({
<div className="flex flex-col gap-4">
<div className="grid w-full items-center gap-1.5">
<Label>{t("shareActions.nameLabel")}</Label>
<Input
value={editForm.name}
onChange={(e) => setEditForm({ ...editForm, name: e.target.value })}
/>
<Input value={editForm.name} onChange={(e) => setEditForm({ ...editForm, name: e.target.value })} />
</div>
<div className="grid w-full items-center gap-1.5">
<Label>{t("shareActions.expirationLabel")}</Label>

View File

@@ -1,21 +1,22 @@
import { getShare } from "@/http/endpoints";
import { getFileIcon } from "@/utils/file-icons";
import { Button } from "@/components/ui/button";
import { useEffect, useState } from "react";
import { IconLock, IconLockOpen, IconMail } from "@tabler/icons-react";
import { format } from "date-fns";
import { useTranslations } from "next-intl";
import { toast } from "sonner";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Loader } from "@/components/ui/loader";
import { format } from "date-fns";
import { useTranslations } from "next-intl";
import { useEffect, useState } from "react";
import { IconLock, IconLockOpen, IconMail } from "@tabler/icons-react";
import { toast } from "sonner";
import { getShare } from "@/http/endpoints";
import { getFileIcon } from "@/utils/file-icons";
interface ShareDetailsModalProps {
shareId: string | null;
@@ -147,14 +148,16 @@ export function ShareDetailsModal({ shareId, onClose }: ShareDetailsModalProps)
)}
{share.security?.maxViews && (
<Badge variant="secondary">
{t("shareDetails.maxViews")} { share.security.maxViews }
{t("shareDetails.maxViews")} {share.security.maxViews}
</Badge>
)}
</div>
</div>
<div className="rounded-lg border p-4">
<h3 className="font-medium">{t("shareDetails.files")} ({share.files?.length || 0})</h3>
<h3 className="font-medium">
{t("shareDetails.files")} ({share.files?.length || 0})
</h3>
<div className="mt-3 flex flex-wrap gap-2">
{share.files?.map((file: ShareFile) => {
const { icon: FileIcon, color } = getFileIcon(file.name);
@@ -185,9 +188,7 @@ export function ShareDetailsModal({ shareId, onClose }: ShareDetailsModalProps)
)}
</div>
<DialogFooter>
<Button onClick={onClose}>
{t("common.close")}
</Button>
<Button onClick={onClose}>{t("common.close")}</Button>
</DialogFooter>
</DialogContent>
</Dialog>

View File

@@ -1,22 +1,17 @@
"use client";
import { getPresignedUrl, registerFile } from "@/http/endpoints";
import { generateSafeFileName } from "@/utils/file-utils";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from "@/components/ui/dialog";
import { Progress } from "@/components/ui/progress";
import { useEffect, useRef, useState } from "react";
import { IconCloudUpload, IconFileText, IconFileTypePdf, IconFileTypography, IconPhoto } from "@tabler/icons-react";
import axios from "axios";
import { useTranslations } from "next-intl";
import { useState, useRef, useEffect } from "react";
import { IconCloudUpload, IconFileText, IconPhoto, IconFileTypography, IconFileTypePdf } from "@tabler/icons-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Progress } from "@/components/ui/progress";
import { getPresignedUrl, registerFile } from "@/http/endpoints";
import { generateSafeFileName } from "@/utils/file-utils";
interface UploadFileModalProps {
isOpen: boolean;
onClose: () => void;
@@ -151,19 +146,12 @@ export function UploadFileModal({ isOpen, onClose, onSuccess }: UploadFileModalP
<div className="flex items-center gap-2">
{/* <IconFile size={24} className="text-gray-500" /> */}
<span className="font-medium">
{selectedFile.name.length > 40
? selectedFile.name.substring(0, 40) + "..."
: selectedFile.name}
{' '} ({selectedFile.size / 1000} KB)
{selectedFile.name.length > 40 ? selectedFile.name.substring(0, 40) + "..." : selectedFile.name} (
{selectedFile.size / 1000} KB)
</span>
</div>
</div>
{isUploading && (
<Progress
value={uploadProgress}
className="w-full"
/>
)}
{isUploading && <Progress value={uploadProgress} className="w-full" />}
</div>
)}
</div>
@@ -171,14 +159,8 @@ export function UploadFileModal({ isOpen, onClose, onSuccess }: UploadFileModalP
<Button variant="outline" onClick={handleClose}>
{t("common.cancel")}
</Button>
<Button
variant="default"
disabled={!selectedFile || isUploading}
onClick={handleUpload}
>
{isUploading && (
<IconCloudUpload className="mr-2 h-4 w-4 animate-spin" />
)}
<Button variant="default" disabled={!selectedFile || isUploading} onClick={handleUpload}>
{isUploading && <IconCloudUpload className="mr-2 h-4 w-4 animate-spin" />}
{t("uploadFile.upload")}
</Button>
</DialogFooter>

View File

@@ -1,11 +1,9 @@
"use client"
"use client";
import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio"
import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
function AspectRatio({
...props
}: React.ComponentProps<typeof AspectRatioPrimitive.Root>) {
return <AspectRatioPrimitive.Root data-slot="aspect-ratio" {...props} />
function AspectRatio({ ...props }: React.ComponentProps<typeof AspectRatioPrimitive.Root>) {
return <AspectRatioPrimitive.Root data-slot="aspect-ratio" {...props} />;
}
export { AspectRatio }
export { AspectRatio };

View File

@@ -1,11 +1,11 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { ChevronRight, MoreHorizontal } from "lucide-react"
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { ChevronRight, MoreHorizontal } from "lucide-react";
import { cn } from "@/lib/utils"
import { cn } from "@/lib/utils";
function Breadcrumb({ ...props }: React.ComponentProps<"nav">) {
return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} />
return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} />;
}
function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
@@ -18,17 +18,11 @@ function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
)}
{...props}
/>
)
);
}
function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">) {
return (
<li
data-slot="breadcrumb-item"
className={cn("inline-flex items-center gap-1.5", className)}
{...props}
/>
)
return <li data-slot="breadcrumb-item" className={cn("inline-flex items-center gap-1.5", className)} {...props} />;
}
function BreadcrumbLink({
@@ -36,17 +30,13 @@ function BreadcrumbLink({
className,
...props
}: React.ComponentProps<"a"> & {
asChild?: boolean
asChild?: boolean;
}) {
const Comp = asChild ? Slot : "a"
const Comp = asChild ? Slot : "a";
return (
<Comp
data-slot="breadcrumb-link"
className={cn("hover:text-foreground transition-colors", className)}
{...props}
/>
)
<Comp data-slot="breadcrumb-link" className={cn("hover:text-foreground transition-colors", className)} {...props} />
);
}
function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) {
@@ -59,14 +49,10 @@ function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) {
className={cn("text-foreground font-normal", className)}
{...props}
/>
)
);
}
function BreadcrumbSeparator({
children,
className,
...props
}: React.ComponentProps<"li">) {
function BreadcrumbSeparator({ children, className, ...props }: React.ComponentProps<"li">) {
return (
<li
data-slot="breadcrumb-separator"
@@ -77,13 +63,10 @@ function BreadcrumbSeparator({
>
{children ?? <ChevronRight />}
</li>
)
);
}
function BreadcrumbEllipsis({
className,
...props
}: React.ComponentProps<"span">) {
function BreadcrumbEllipsis({ className, ...props }: React.ComponentProps<"span">) {
return (
<span
data-slot="breadcrumb-ellipsis"
@@ -95,7 +78,7 @@ function BreadcrumbEllipsis({
<MoreHorizontal className="size-4" />
<span className="sr-only">More</span>
</span>
)
);
}
export {
@@ -106,4 +89,4 @@ export {
BreadcrumbPage,
BreadcrumbSeparator,
BreadcrumbEllipsis,
}
};

View File

@@ -1,39 +1,28 @@
"use client"
"use client";
import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { XIcon } from "lucide-react"
import * as React from "react";
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { XIcon } from "lucide-react";
import { cn } from "@/lib/utils"
import { cn } from "@/lib/utils";
function Dialog({
...props
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
return <DialogPrimitive.Root data-slot="dialog" {...props} />
function Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>) {
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
}
function DialogTrigger({
...props
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
}
function DialogPortal({
...props
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
function DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
}
function DialogClose({
...props
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
}
function DialogOverlay({
className,
...props
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
function DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
return (
<DialogPrimitive.Overlay
data-slot="dialog-overlay"
@@ -43,14 +32,10 @@ function DialogOverlay({
)}
{...props}
/>
)
);
}
function DialogContent({
className,
children,
...props
}: React.ComponentProps<typeof DialogPrimitive.Content>) {
function DialogContent({ className, children, ...props }: React.ComponentProps<typeof DialogPrimitive.Content>) {
return (
<DialogPortal data-slot="dialog-portal">
<DialogOverlay />
@@ -69,7 +54,7 @@ function DialogContent({
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</DialogPortal>
)
);
}
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
@@ -79,46 +64,37 @@ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
{...props}
/>
)
);
}
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="dialog-footer"
className={cn(
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
className
)}
className={cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className)}
{...props}
/>
)
);
}
function DialogTitle({
className,
...props
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {
return (
<DialogPrimitive.Title
data-slot="dialog-title"
className={cn("text-lg leading-none font-semibold", className)}
{...props}
/>
)
);
}
function DialogDescription({
className,
...props
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {
return (
<DialogPrimitive.Description
data-slot="dialog-description"
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
)
);
}
export {
@@ -132,4 +108,4 @@ export {
DialogPortal,
DialogTitle,
DialogTrigger,
}
};

View File

@@ -6,32 +6,18 @@ interface LoaderProps extends React.HTMLAttributes<HTMLDivElement> {
export function Loader({ className, size = "md", ...props }: LoaderProps) {
return (
<div
role="status"
className={cn("animate-spin", className)}
{...props}
>
<div role="status" className={cn("animate-spin", className)} {...props}>
<svg
className={cn(
"text-muted-foreground/20",
{
"h-4 w-4": size === "sm",
"h-6 w-6": size === "md",
"h-8 w-8": size === "lg",
}
)}
className={cn("text-muted-foreground/20", {
"h-4 w-4": size === "sm",
"h-6 w-6": size === "md",
"h-8 w-8": size === "lg",
})}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
<path
className="opacity-75"
fill="currentColor"
@@ -41,4 +27,4 @@ export function Loader({ className, size = "md", ...props }: LoaderProps) {
<span className="sr-only">Loading...</span>
</div>
);
}
}

View File

@@ -1,21 +1,13 @@
"use client"
"use client";
import * as React from "react"
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
import * as React from "react";
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
import { cn } from "@/lib/utils"
import { cn } from "@/lib/utils";
function ScrollArea({
className,
children,
...props
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
function ScrollArea({ className, children, ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
return (
<ScrollAreaPrimitive.Root
data-slot="scroll-area"
className={cn("relative", className)}
{...props}
>
<ScrollAreaPrimitive.Root data-slot="scroll-area" className={cn("relative", className)} {...props}>
<ScrollAreaPrimitive.Viewport
data-slot="scroll-area-viewport"
className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
@@ -25,7 +17,7 @@ function ScrollArea({
<ScrollBar />
<ScrollAreaPrimitive.Corner />
</ScrollAreaPrimitive.Root>
)
);
}
function ScrollBar({
@@ -39,10 +31,8 @@ function ScrollBar({
orientation={orientation}
className={cn(
"flex touch-none p-px transition-colors select-none",
orientation === "vertical" &&
"h-full w-2.5 border-l border-l-transparent",
orientation === "horizontal" &&
"h-2.5 flex-col border-t border-t-transparent",
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent",
orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent",
className
)}
{...props}
@@ -52,7 +42,7 @@ function ScrollBar({
className="bg-border relative flex-1 rounded-full"
/>
</ScrollAreaPrimitive.ScrollAreaScrollbar>
)
);
}
export { ScrollArea, ScrollBar }
export { ScrollArea, ScrollBar };

View File

@@ -1,14 +1,11 @@
"use client"
"use client";
import * as React from "react"
import * as SwitchPrimitive from "@radix-ui/react-switch"
import * as React from "react";
import * as SwitchPrimitive from "@radix-ui/react-switch";
import { cn } from "@/lib/utils"
import { cn } from "@/lib/utils";
function Switch({
className,
...props
}: React.ComponentProps<typeof SwitchPrimitive.Root>) {
function Switch({ className, ...props }: React.ComponentProps<typeof SwitchPrimitive.Root>) {
return (
<SwitchPrimitive.Root
data-slot="switch"
@@ -25,7 +22,7 @@ function Switch({
)}
/>
</SwitchPrimitive.Root>
)
);
}
export { Switch }
export { Switch };

View File

@@ -1,6 +1,6 @@
import { clsx, type ClassValue } from "clsx";
import { customAlphabet } from "nanoid";
import { twMerge } from "tailwind-merge";
import { customAlphabet } from 'nanoid';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));