mirror of
https://github.com/kyantech/Palmr.git
synced 2025-10-22 22:02:00 +00:00
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:
3937
apps/app/pnpm-lock.yaml
generated
3937
apps/app/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
|
@@ -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 (
|
||||
|
@@ -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();
|
||||
|
@@ -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();
|
||||
|
@@ -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();
|
||||
|
@@ -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 (
|
||||
|
@@ -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>
|
||||
);
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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":
|
||||
|
@@ -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>
|
||||
) : (
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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 };
|
||||
|
@@ -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,
|
||||
}
|
||||
};
|
||||
|
@@ -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,
|
||||
}
|
||||
};
|
||||
|
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -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 };
|
||||
|
@@ -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 };
|
||||
|
@@ -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));
|
||||
|
Reference in New Issue
Block a user