mirror of
https://github.com/nimbusdotstorage/Nimbus
synced 2026-04-22 17:45:03 +02:00
Merge branch 'main' of github.com:nimbusdotstorage/Nimbus into license
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 320 KiB After Width: | Height: | Size: 472 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 320 KiB After Width: | Height: | Size: 483 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 434 KiB After Width: | Height: | Size: 500 KiB |
@@ -1,19 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from "@/components/ui/card";
|
||||
import type { ComponentProps, ReactNode } from "react";
|
||||
import { ArrowLeft, ArrowRight } from "lucide-react";
|
||||
import type { AuthCardProps } from "@/lib/types";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import Link from "next/link";
|
||||
|
||||
interface AuthCardProps extends ComponentProps<"div"> {
|
||||
title: string;
|
||||
description: string;
|
||||
navigationType: "signin" | "signup";
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export function AuthCard({ title, description, navigationType, children, className, ...props }: AuthCardProps) {
|
||||
const oppositeAction = navigationType === "signin" ? "signup" : "signin";
|
||||
const oppositeActionText = navigationType === "signin" ? "Sign up" : "Sign in";
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { useState, type ChangeEvent } from "react";
|
||||
import type { PasswordInputProps } from "@/lib/types";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Eye, EyeClosed } from "lucide-react";
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
interface PasswordInputProps extends Omit<ComponentProps<typeof Input>, "type"> {
|
||||
value?: string;
|
||||
onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
|
||||
}
|
||||
import { useState } from "react";
|
||||
|
||||
export function PasswordInput({ className, ...props }: PasswordInputProps) {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import type { SocialAuthButtonProps } from "@/lib/types";
|
||||
import { Google } from "@/components/icons/google";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
type SocialProvider = "google";
|
||||
type AuthAction = "signin" | "signup";
|
||||
|
||||
interface SocialAuthButtonProps extends Omit<ComponentProps<typeof Button>, "children" | "variant" | "type"> {
|
||||
provider: SocialProvider;
|
||||
action: AuthAction;
|
||||
}
|
||||
|
||||
const providerConfig = {
|
||||
google: {
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import type { CreateFolderDialogProps } from "@/lib/types";
|
||||
import { useState, type FormEvent } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Label } from "@/components/ui/label";
|
||||
@@ -13,12 +14,6 @@ import { Input } from "@/components/ui/input";
|
||||
import { toast } from "sonner";
|
||||
import type React from "react";
|
||||
|
||||
interface CreateFolderDialogProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
onCreateFolder: (folderName: string, parentId?: string | undefined) => void;
|
||||
}
|
||||
|
||||
export function CreateFolderDialog({ open, onOpenChange, onCreateFolder }: CreateFolderDialogProps) {
|
||||
const [folderName, setFolderName] = useState("");
|
||||
|
||||
|
||||
@@ -8,16 +8,11 @@ import {
|
||||
} from "@/components/ui/dialog";
|
||||
import { UploadZone } from "@/components/upload/upload-zone";
|
||||
import { useState, useEffect, type FormEvent } from "react";
|
||||
import type { UploadFileDialogProps } from "@/lib/types";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { toast } from "sonner";
|
||||
import type React from "react";
|
||||
|
||||
interface UploadFileDialogProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
onUpload: (files: FileList) => void;
|
||||
}
|
||||
|
||||
export function UploadFileDialog({ open, onOpenChange, onUpload }: UploadFileDialogProps) {
|
||||
const [selectedFiles, setSelectedFiles] = useState<FileList | null>(null);
|
||||
const [isUploading, setIsUploading] = useState(false);
|
||||
|
||||
@@ -8,16 +8,11 @@ import {
|
||||
} from "@/components/ui/dialog";
|
||||
import { UploadZone } from "@/components/upload/upload-zone";
|
||||
import { useEffect, useState, type FormEvent } from "react";
|
||||
import { type UploadFileDialogProps } from "@/lib/types";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface UploadFolderDialogProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
onUpload: (files: FileList) => void;
|
||||
}
|
||||
|
||||
export function UploadFolderDialog({ open, onOpenChange, onUpload }: UploadFolderDialogProps) {
|
||||
export function UploadFolderDialog({ open, onOpenChange, onUpload }: UploadFileDialogProps) {
|
||||
const [selectedFolder, setSelectedFolder] = useState<FileList | null>(null);
|
||||
const [isUploading, setIsUploading] = useState(false);
|
||||
const [uploadProgress, setUploadProgress] = useState(0);
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
import { Sheet, SheetClose, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "@/components/ui/sheet";
|
||||
import { FileText, Folder, Image, Video, X } from "lucide-react";
|
||||
import type { FileItem, FolderContentItem } from "@/lib/types";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { createRequest } from "@/hooks/createRequest";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useRequest } from "@/hooks/useRequest";
|
||||
import { Loader } from "@/components/loader";
|
||||
import type { FileItem } from "@/lib/types";
|
||||
import { parseError } from "@/utils/error";
|
||||
import { useEffect } from "react";
|
||||
|
||||
interface FolderContentItem extends FileItem {
|
||||
path?: string;
|
||||
}
|
||||
|
||||
export function FilePreview() {
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
@@ -6,7 +6,6 @@ import { Sidebar, SidebarContent, SidebarHeader, SidebarRail } from "@/component
|
||||
import SidebarFolders from "@/components/main-sidebar/sidebar-folders";
|
||||
import StorageFooter from "@/components/main-sidebar/sidebar-footer";
|
||||
import { QuickAccess } from "@/components/main-sidebar/quick-access";
|
||||
import type { Source } from "@/components/main-sidebar/sources";
|
||||
import UploadButton from "@/components/main-sidebar/upload";
|
||||
import TagMenu from "@/components/main-sidebar/tag-menu";
|
||||
import Sources from "@/components/main-sidebar/sources";
|
||||
@@ -14,6 +13,7 @@ import { HardDrive, Users, Server } from "lucide-react";
|
||||
import GoogleDriveIcon from "@/public/googledrive";
|
||||
import OneDriveIcon from "@/public/onedrive";
|
||||
import GoogleCloudIcon from "@/public/gcp";
|
||||
import type { Source } from "@/lib/types";
|
||||
import AzureIcon from "@/public/azure";
|
||||
import AWSIcon from "@/public/aws";
|
||||
|
||||
|
||||
@@ -9,15 +9,7 @@ import {
|
||||
import { SidebarMenu, SidebarMenuButton, SidebarMenuItem } from "@/components/ui/sidebar";
|
||||
import { Plus, ChevronDown } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import type { ComponentType } from "react";
|
||||
|
||||
export interface Source {
|
||||
name: string;
|
||||
icon: ComponentType<{ className?: string }>;
|
||||
value: string;
|
||||
backgroundColor: string;
|
||||
textColor?: string;
|
||||
}
|
||||
import type { Source } from "@/lib/types";
|
||||
|
||||
// ! This is a temporary implementation, will need to figure out the data to be passed from API
|
||||
export default function Sources({
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
import type { CreateRequestOptions } from "@/lib/types";
|
||||
import { clientEnv } from "@/lib/env/client-env";
|
||||
|
||||
type Params = Record<string, string | number | null | undefined>;
|
||||
|
||||
type CreateRequestOptions = {
|
||||
path: string;
|
||||
pathParams?: Params;
|
||||
queryParams?: Params;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a request function that can be used to fetch data from an API.
|
||||
* @param options - The options for the request.
|
||||
|
||||
@@ -3,15 +3,11 @@ import { authClient } from "@nimbus/auth/auth-client";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { clientEnv } from "@/lib/env/client-env";
|
||||
import { useState, useCallback } from "react";
|
||||
import type { AuthState } from "@/lib/types";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { toast } from "sonner";
|
||||
import axios from "axios";
|
||||
|
||||
interface AuthState {
|
||||
isLoading: boolean;
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
export const signInWithGoogle = async () => {
|
||||
await authClient.signIn.social({
|
||||
provider: "google",
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import type { DeleteFileParams } from "@/lib/types";
|
||||
import { clientEnv } from "@/lib/env/client-env";
|
||||
import axios, { type AxiosError } from "axios";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface DeleteFileParams {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export function useFileOperations() {
|
||||
const deleteFileMutation = useMutation({
|
||||
mutationFn: async ({ id }: DeleteFileParams) => {
|
||||
|
||||
@@ -1,19 +1,7 @@
|
||||
import type { UseRequestParams, UseRequestReturn } from "@/lib/types";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { parseError } from "@/utils/error";
|
||||
|
||||
type UseRequestParams = {
|
||||
request: (signal: AbortSignal) => Promise<Response>;
|
||||
triggers?: unknown[];
|
||||
manual?: boolean;
|
||||
};
|
||||
|
||||
type UseRequestReturn<ResponseBody> = {
|
||||
data: ResponseBody | null;
|
||||
error: Error | null;
|
||||
isLoading: boolean;
|
||||
refetch: () => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* A hook that fetches data from an API and returns the data, refetch function, error, and loading state.
|
||||
* @param options - The options for the request.
|
||||
|
||||
@@ -1,24 +1,11 @@
|
||||
// TODO: Move to useFileOperations.ts
|
||||
|
||||
import type { CreateFolderParams } from "@/lib/types";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { clientEnv } from "@/lib/env/client-env";
|
||||
import axios, { type AxiosError } from "axios";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import axios from "axios";
|
||||
|
||||
type AxiosError = {
|
||||
response?: {
|
||||
data?: {
|
||||
message?: string;
|
||||
};
|
||||
};
|
||||
message: string;
|
||||
};
|
||||
|
||||
interface CreateFolderParams {
|
||||
name: string;
|
||||
parentId?: string;
|
||||
}
|
||||
|
||||
export function useUpload() {
|
||||
const [uploadFileOpen, setUploadFileOpen] = useState(false);
|
||||
@@ -60,7 +47,7 @@ export function useUpload() {
|
||||
},
|
||||
onError: (error: AxiosError) => {
|
||||
console.error("Error creating folder:", error);
|
||||
const errorMessage = error.response?.data?.message || error.message || "Failed to create folder";
|
||||
const errorMessage = error.message || "Failed to create folder";
|
||||
toast.error(errorMessage);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
// TODO: Turn this into the typing file for the front end
|
||||
// This file holds all the custom interfaces and types for the Next.js front end app.
|
||||
|
||||
import type { ChangeEvent, ComponentProps, ComponentType, ReactNode } from "react";
|
||||
import type { Button } from "@/components/ui/button";
|
||||
import type { Input } from "@/components/ui/input";
|
||||
|
||||
import type { ChangeEvent, ComponentProps, ComponentType, ReactNode } from "react";
|
||||
import type { Button } from "@/components/ui/button";
|
||||
import type { Input } from "@/components/ui/input";
|
||||
|
||||
export interface FileItem {
|
||||
id: string;
|
||||
@@ -7,3 +15,82 @@ export interface FileItem {
|
||||
size?: string;
|
||||
modified: string;
|
||||
}
|
||||
|
||||
export interface CreateFolderDialogProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
onCreateFolder: (folderName: string, parentId?: string | undefined) => void;
|
||||
}
|
||||
|
||||
export interface UploadFileDialogProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
onUpload: (files: FileList) => void;
|
||||
}
|
||||
|
||||
export interface FolderContentItem extends FileItem {
|
||||
path?: string;
|
||||
}
|
||||
|
||||
export interface Source {
|
||||
name: string;
|
||||
icon: ComponentType<{ className?: string }>;
|
||||
value: string;
|
||||
backgroundColor: string;
|
||||
textColor?: string;
|
||||
}
|
||||
|
||||
export interface AuthState {
|
||||
isLoading: boolean;
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
export interface DeleteFileParams {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface AuthCardProps extends ComponentProps<"div"> {
|
||||
title: string;
|
||||
description: string;
|
||||
navigationType: "signin" | "signup";
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export type Params = Record<string, string | number | null | undefined>;
|
||||
|
||||
export type CreateRequestOptions = {
|
||||
path: string;
|
||||
pathParams?: Params;
|
||||
queryParams?: Params;
|
||||
};
|
||||
|
||||
export type UseRequestParams = {
|
||||
request: (signal: AbortSignal) => Promise<Response>;
|
||||
triggers?: unknown[];
|
||||
manual?: boolean;
|
||||
};
|
||||
|
||||
export type UseRequestReturn<ResponseBody> = {
|
||||
data: ResponseBody | null;
|
||||
error: Error | null;
|
||||
isLoading: boolean;
|
||||
refetch: () => Promise<void>;
|
||||
};
|
||||
|
||||
export interface CreateFolderParams {
|
||||
name: string;
|
||||
parentId?: string;
|
||||
}
|
||||
|
||||
export type SocialProvider = "google";
|
||||
export type AuthAction = "signin" | "signup";
|
||||
|
||||
export interface SocialAuthButtonProps extends Omit<ComponentProps<typeof Button>, "children" | "variant" | "type"> {
|
||||
provider: SocialProvider;
|
||||
action: AuthAction;
|
||||
}
|
||||
|
||||
export interface PasswordInputProps extends Omit<ComponentProps<typeof Input>, "type"> {
|
||||
value?: string;
|
||||
onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user