mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
refactoring some files.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client"
|
||||
|
||||
import {PageParams} from "@/types/next";
|
||||
import {RegisterForm} from "@/components/wrappers/auth/Register/RegisterForm/RegisterForm";
|
||||
import {RegisterForm} from "@/components/wrappers/auth/Register/register-form/RegisterForm";
|
||||
|
||||
export default function RoutePage(props: PageParams<{}>) {
|
||||
return (
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
import Link from 'next/link'
|
||||
|
||||
import {PageParams} from "@/types/next";
|
||||
import {prisma} from "@/prisma";
|
||||
import {CardsWithPagination} from "@/components/wrappers/common/cards-with-pagination";
|
||||
import {Button} from "@/components/ui/button";
|
||||
import Link from 'next/link'
|
||||
import {Page, PageActions, PageContent, PageHeader, PageTitle} from "@/features/layout/page";
|
||||
import {ProjectCard} from "@/components/wrappers/dashboard/projects/ProjectCard/ProjectCard";
|
||||
import {requiredCurrentUser} from "@/auth/current-user";
|
||||
import {getCurrentOrganizationId} from "@/features/dashboard/organization-cookie";
|
||||
|
||||
|
||||
export default async function RoutePage(props: PageParams<{}>) {
|
||||
|
||||
// const {searchParams} = props
|
||||
// const organizationId = searchParams?.organizationId || "default";
|
||||
|
||||
const user = await requiredCurrentUser()
|
||||
|
||||
const currentOrganizationId = await getCurrentOrganizationId()
|
||||
|
||||
const projects = await prisma.project.findMany({
|
||||
where: {
|
||||
organization: {
|
||||
slug: "default",
|
||||
// id: organizationId,
|
||||
users: {
|
||||
some: {
|
||||
userId: user.id
|
||||
},
|
||||
},
|
||||
id: currentOrganizationId,
|
||||
// users: {
|
||||
// some: {
|
||||
// userId: user.id
|
||||
// },
|
||||
// },
|
||||
}
|
||||
},
|
||||
include: {
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
import {prisma} from "@/prisma";
|
||||
import {PageParams} from "@/types/next";
|
||||
import {Page, PageContent, PageDescription, PageHeader, PageTitle} from "@/features/layout/page";
|
||||
import {Page, PageActions, PageContent, PageDescription, PageHeader, PageTitle} from "@/features/layout/page";
|
||||
import {requiredCurrentUser} from "@/auth/current-user";
|
||||
import {SettingsTabs} from "@/components/wrappers/dashboard/settings/SettingsTabs/SettingsTabs";
|
||||
import {getCurrentOrganizationId} from "@/features/dashboard/organization-cookie";
|
||||
import {Button} from "@/components/ui/button";
|
||||
import {ButtonWithConfirm} from "@/components/wrappers/common/button/button-with-confirm";
|
||||
|
||||
|
||||
export default async function RoutePage(props: PageParams<{}>) {
|
||||
const user = await requiredCurrentUser()
|
||||
|
||||
const defaultOrganization = await prisma.organization.findUnique({
|
||||
where: {slug: "default"},
|
||||
});
|
||||
const currentOrganizationId = await getCurrentOrganizationId()
|
||||
|
||||
const users = await prisma.user.findMany({
|
||||
where: {
|
||||
organizations: {
|
||||
some: {
|
||||
organizationId: defaultOrganization.id
|
||||
organizationId: currentOrganizationId
|
||||
},
|
||||
},
|
||||
deleted: {not: true},
|
||||
@@ -38,6 +39,10 @@ export default async function RoutePage(props: PageParams<{}>) {
|
||||
<PageTitle>
|
||||
Settings
|
||||
</PageTitle>
|
||||
<PageActions>
|
||||
{/*<Button variant="destructive">Delete Organization</Button>*/}
|
||||
<ButtonWithConfirm text="Delete Organization" variant="destructive"/>
|
||||
</PageActions>
|
||||
</PageHeader>
|
||||
<PageDescription>
|
||||
Manage your organization settings.
|
||||
|
||||
+2
-2
@@ -11,8 +11,8 @@ import {Input} from "@/components/ui/input";
|
||||
import {Form} from "@/components/ui/form"
|
||||
import {Button} from "@/components/ui/button";
|
||||
import {TooltipProvider, TooltipTrigger, Tooltip, TooltipContent} from "@/components/ui/tooltip";
|
||||
import {RegisterSchema, RegisterType} from "@/components/wrappers/auth/Register/RegisterForm/register-form.schema";
|
||||
import {registerUserAction} from "@/components/wrappers/auth/Register/RegisterForm/register-form.action";
|
||||
import {RegisterSchema, RegisterType} from "@/components/wrappers/auth/Register/register-form/register-form.schema";
|
||||
import {registerUserAction} from "@/components/wrappers/auth/Register/register-form/register-form.action";
|
||||
import {PasswordInput} from "@/components/wrappers/auth/PaswordInput/password-input";
|
||||
|
||||
export type registerFormProps = {
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
"use server"
|
||||
import {RegisterSchema} from "@/components/wrappers/auth/Register/RegisterForm/register-form.schema";
|
||||
import {RegisterSchema} from "@/components/wrappers/auth/Register/register-form/register-form.schema";
|
||||
import {action} from "@/safe-actions";
|
||||
import {prisma} from "@/prisma";
|
||||
import {hashPassword} from "@/utils/password";
|
||||
+7
-3
@@ -1,4 +1,5 @@
|
||||
"use client"
|
||||
|
||||
import {Button} from "@/components/ui/button";
|
||||
import {useState} from "react";
|
||||
import {Loader2} from "lucide-react";
|
||||
@@ -15,15 +16,17 @@ export type VariantButton = {
|
||||
export type ButtonWithConfirmProps = {
|
||||
icon?: any,
|
||||
text: string,
|
||||
variant?: keyof VariantButton ,
|
||||
variant?: keyof VariantButton,
|
||||
className?: string,
|
||||
onClick?: () => void,
|
||||
isPending? : boolean
|
||||
isPending?: boolean
|
||||
};
|
||||
|
||||
export const ButtonWithConfirm = (props: ButtonWithConfirmProps) => {
|
||||
|
||||
const [isConfirming, setIsConfirming] = useState(false)
|
||||
return(
|
||||
|
||||
return (
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (isConfirming) {
|
||||
@@ -42,4 +45,5 @@ export const ButtonWithConfirm = (props: ButtonWithConfirmProps) => {
|
||||
</>
|
||||
</Button>
|
||||
)
|
||||
|
||||
}
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
"use client"
|
||||
|
||||
import {Button} from "@/components/ui/button";
|
||||
import {ButtonHTMLAttributes, useState} from "react";
|
||||
import {ButtonHTMLAttributes} from "react";
|
||||
import {Loader2} from "lucide-react";
|
||||
|
||||
export type VariantButton = {
|
||||
@@ -6,19 +6,8 @@ import {Check, ChevronDown} from "lucide-react"
|
||||
|
||||
import {cn} from "@/lib/utils"
|
||||
import {Button} from "@/components/ui/button"
|
||||
import {
|
||||
Command,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
CommandInput,
|
||||
CommandItem,
|
||||
CommandList,
|
||||
} from "@/components/ui/command"
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover"
|
||||
import {Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList} from "@/components/ui/command"
|
||||
import {Popover, PopoverContent, PopoverTrigger} from "@/components/ui/popover"
|
||||
import {FormControl} from "@/components/ui/form";
|
||||
import {SidebarMenuButton} from "@/components/ui/sidebar";
|
||||
import {Separator} from "@/components/ui/separator";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {EmailForm} from "@/components/wrappers/dashboard/admin/AdminEmailTab/EmailForm/EmailForm";
|
||||
import {Settings} from "@prisma/client";
|
||||
import {Send} from "lucide-react";
|
||||
import {ButtonWithLoading} from "@/components/wrappers/common/button/ButtonWithLoading/ButtonWithLoading";
|
||||
import {ButtonWithLoading} from "@/components/wrappers/common/button/button-with-loading";
|
||||
import {useMutation} from "@tanstack/react-query";
|
||||
import {sendEmail} from "@/utils/email-helper";
|
||||
import TestEmailSettings from "../../../../../../emails/TestEmailSettings";
|
||||
|
||||
@@ -5,7 +5,7 @@ import {Label} from "@/components/ui/label";
|
||||
import {StorageS3Form} from "@/components/wrappers/dashboard/admin/AdminStorageTab/StorageS3Form/StorageS3Form";
|
||||
import {useState} from "react";
|
||||
import {Settings} from "@prisma/client";
|
||||
import {ButtonWithLoading} from "@/components/wrappers/common/button/ButtonWithLoading/ButtonWithLoading";
|
||||
import {ButtonWithLoading} from "@/components/wrappers/common/button/button-with-loading";
|
||||
import {useMutation} from "@tanstack/react-query";
|
||||
import {checkConnexionToS3} from "@/features/upload/public/upload.action";
|
||||
import {toast} from "sonner";
|
||||
|
||||
@@ -4,8 +4,8 @@ import {Card, CardContent, CardHeader} from "@/components/ui/card";
|
||||
import Link from "next/link";
|
||||
import {ValueIcon} from "@radix-ui/react-icons";
|
||||
import {Circle} from "lucide-react";
|
||||
import {ConnectionCircle} from "@/components/wrappers/common/connection-circle";
|
||||
import {formatDateLastContact} from "@/utils/date-formatting";
|
||||
import {ConnectionCircle} from "@/components/wrappers/common/connection-circle";
|
||||
|
||||
export type agentCardProps = {
|
||||
data: any
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"use client"
|
||||
|
||||
import {Button} from "@/components/ui/button"
|
||||
import {
|
||||
Dialog,
|
||||
|
||||
@@ -6,7 +6,7 @@ import {useMutation} from "@tanstack/react-query";
|
||||
import {toast} from "sonner";
|
||||
|
||||
import {backupButtonAction} from "@/components/wrappers/dashboard/backup/backup-button/backup-button.action";
|
||||
import {ButtonWithLoading} from "@/components/wrappers/common/button/ButtonWithLoading/ButtonWithLoading";
|
||||
import {ButtonWithLoading} from "@/components/wrappers/common/button/button-with-loading";
|
||||
|
||||
export type BackupButtonProps = {
|
||||
databaseId: string
|
||||
|
||||
@@ -7,6 +7,8 @@ import {Button} from "@/components/ui/button";
|
||||
import {Form, FormControl, FormField, FormItem, FormLabel, FormMessage, useZodForm} from "@/components/ui/form";
|
||||
import {Input} from "@/components/ui/input";
|
||||
import {OrganizationSchema} from "@/components/wrappers/dashboard/organization/organization.schema";
|
||||
import {createOrganizationAction} from "@/components/wrappers/dashboard/organization/organization.action";
|
||||
import {useRouter} from "next/navigation";
|
||||
|
||||
export type createOrganizationModalProps = {
|
||||
children: any
|
||||
@@ -17,12 +19,16 @@ export function CreateOrganizationModal(props: createOrganizationModalProps) {
|
||||
|
||||
const {children} = props;
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const form = useZodForm({
|
||||
schema: OrganizationSchema,
|
||||
});
|
||||
|
||||
const mutation = useMutation({
|
||||
mutationFn: async (values: OrganizationSchema) => {
|
||||
const result = await createOrganizationAction(values)
|
||||
router.refresh()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -61,6 +67,20 @@ export function CreateOrganizationModal(props: createOrganizationModalProps) {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="slug"
|
||||
defaultValue=""
|
||||
render={({field}) => (
|
||||
<FormItem>
|
||||
<FormLabel>Slug</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormMessage/>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</Form>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import {useEffect, useState} from "react";
|
||||
|
||||
import {ComboBox} from "@/components/wrappers/common/combobox";
|
||||
import {Organization} from "@prisma/client";
|
||||
import {getCurrentOrganizationSlug, setCurrentOrganizationSlug} from "@/features/dashboard/organization-cookie";
|
||||
import {getCurrentOrganizationId, setCurrentOrganizationId} from "@/features/dashboard/organization-cookie";
|
||||
import {useSidebar} from "@/components/ui/sidebar";
|
||||
|
||||
export type organizationComboBoxProps = {
|
||||
@@ -17,42 +17,42 @@ export function OrganizationCombobox(props: organizationComboBoxProps) {
|
||||
|
||||
// const {organizationId, moveToAnotherOrganization} = useStore((state) => state);
|
||||
|
||||
const [organizationSlug, setOrganizationSlug] = useState<string>()
|
||||
const [organizationId, setOrganizationId] = useState<string>()
|
||||
|
||||
const {organizations, defaultOrganization} = props
|
||||
|
||||
useEffect(() => {
|
||||
getCurrentOrganizationSlug().then(slug => {
|
||||
getCurrentOrganizationId().then(id => {
|
||||
|
||||
if (slug == "") {
|
||||
setOrganizationSlug(defaultOrganization.slug)
|
||||
setCurrentOrganizationSlug(defaultOrganization.slug)
|
||||
if (id == "") {
|
||||
setOrganizationId(defaultOrganization.id)
|
||||
setCurrentOrganizationId(defaultOrganization.id)
|
||||
} else {
|
||||
setOrganizationSlug(slug)
|
||||
const organization = organizations.find(organization => organization.slug === slug)
|
||||
setOrganizationId(id)
|
||||
const organization = organizations.find(organization => organization.id === id)
|
||||
if (!organization) {
|
||||
setOrganizationSlug(defaultOrganization.slug)
|
||||
setCurrentOrganizationSlug(defaultOrganization.slug)
|
||||
setOrganizationId(defaultOrganization.id)
|
||||
setCurrentOrganizationId(defaultOrganization.id)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}, [organizationSlug])
|
||||
}, [organizationId])
|
||||
|
||||
const values = organizations.map(organization => {
|
||||
return ({
|
||||
value: organization.slug,
|
||||
value: organization.id,
|
||||
label: organization.name,
|
||||
})
|
||||
})
|
||||
|
||||
const onValueChange = (slug: string) => {
|
||||
if (organizationSlug !== slug) {
|
||||
setOrganizationSlug(slug)
|
||||
setCurrentOrganizationSlug(slug)
|
||||
const onValueChange = (id: string) => {
|
||||
if (organizationId !== id) {
|
||||
setOrganizationId(id)
|
||||
setCurrentOrganizationId(id)
|
||||
}
|
||||
}
|
||||
const { state, isMobile } = useSidebar();
|
||||
const {state, isMobile} = useSidebar();
|
||||
|
||||
|
||||
return (
|
||||
@@ -61,7 +61,7 @@ export function OrganizationCombobox(props: organizationComboBoxProps) {
|
||||
<ComboBox
|
||||
sideBar
|
||||
values={values}
|
||||
defaultValue={organizationSlug}
|
||||
defaultValue={organizationId}
|
||||
onValueChange={onValueChange}/>
|
||||
)}
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
"use server"
|
||||
|
||||
import {ActionError, userAction} from "@/safe-actions";
|
||||
import {prisma} from "@/prisma";
|
||||
import {OrganizationSchema} from "@/components/wrappers/dashboard/organization/organization.schema";
|
||||
import {ServerActionResult} from "@/types/action-type";
|
||||
import {Organization} from "@prisma/client";
|
||||
|
||||
|
||||
const verifySlugUniqueness = async (slug: string) => {
|
||||
const slugExists = await prisma.organization.count({
|
||||
where: {
|
||||
slug: slug
|
||||
},
|
||||
})
|
||||
|
||||
if (slugExists) {
|
||||
throw new ActionError("Slug already exists.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const createOrganizationAction = userAction
|
||||
.schema(OrganizationSchema)
|
||||
.action(async ({parsedInput, ctx}): Promise<ServerActionResult<Organization>> => {
|
||||
|
||||
try {
|
||||
|
||||
await verifySlugUniqueness(parsedInput.slug)
|
||||
|
||||
const organization = await prisma.organization.create({
|
||||
data: {
|
||||
...parsedInput
|
||||
}
|
||||
})
|
||||
|
||||
await prisma.userOrganization.create({
|
||||
data: {
|
||||
userId: ctx.user.id,
|
||||
organizationId: organization.id
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
value: organization,
|
||||
actionSuccess: {
|
||||
message: "Organization has been successfully created.",
|
||||
messageParams: {organizationId: organization.id},
|
||||
},
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error creating organization:", error);
|
||||
return {
|
||||
success: false,
|
||||
actionError: {
|
||||
message: "Failed to create organization.",
|
||||
status: 500,
|
||||
cause: error.message ?? "Unknown error",
|
||||
messageParams: {message: "Error creating the organization"},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
});
|
||||
@@ -3,6 +3,7 @@ import {z} from "zod";
|
||||
|
||||
export const OrganizationSchema = z.object({
|
||||
name: z.string(),
|
||||
slug: z.string(),
|
||||
});
|
||||
|
||||
export type OrganizationSchema = z.infer<typeof OrganizationSchema>;
|
||||
|
||||
+2
-1
@@ -1,9 +1,10 @@
|
||||
"use client"
|
||||
|
||||
import {useMutation} from "@tanstack/react-query";
|
||||
import {signOutAction} from "@/features/auth/auth.action";
|
||||
import {ButtonWithConfirm} from "@/components/wrappers/common/button/ButtonWithConfirm/ButtonWithConfirm";
|
||||
import {deleteUserAction} from "@/components/wrappers/dashboard/profile/ButtonDeleteAccount/delete-account.action";
|
||||
import {Trash2} from "lucide-react";
|
||||
import {ButtonWithConfirm} from "@/components/wrappers/common/button/button-with-confirm";
|
||||
|
||||
export type ButtonDeleteAccountProps = {
|
||||
text? : string
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
"use client"
|
||||
import {ButtonWithConfirm} from "@/components/wrappers/common/button/ButtonWithConfirm/ButtonWithConfirm";
|
||||
|
||||
import {Trash2} from "lucide-react";
|
||||
import {ButtonWithConfirm} from "@/components/wrappers/common/button/button-with-confirm";
|
||||
|
||||
export type ButtonDeleteProjectProps = {
|
||||
text? : string
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
import {Tabs, TabsContent, TabsList, TabsTrigger} from "@/components/ui/tabs";
|
||||
import {DataTableWithPagination} from "@/components/wrappers/common/table/data-table-with-pagination";
|
||||
import {backupColumns} from "@/features/backup/columns";
|
||||
import {restoreColumns} from "@/features/restore/columns";
|
||||
import {Backup, Database, Restoration} from "@prisma/client";
|
||||
import {useEffect} from "react";
|
||||
import {useRouter} from "next/navigation";
|
||||
import {eventUpdate} from "@/types/events";
|
||||
import {backupColumns} from "@/features/dashboard/backup/columns";
|
||||
import {restoreColumns} from "@/features/dashboard/restore/columns";
|
||||
|
||||
export type DatabaseTabsProps = {
|
||||
backups: Backup[]
|
||||
|
||||
@@ -10,7 +10,7 @@ import {useRouter} from "next/navigation";
|
||||
import {useState} from "react";
|
||||
import {Trash2} from "lucide-react";
|
||||
import {deleteUserAction} from "@/components/wrappers/dashboard/profile/ButtonDeleteAccount/delete-account.action";
|
||||
import {ButtonWithLoading} from "@/components/wrappers/common/button/ButtonWithLoading/ButtonWithLoading";
|
||||
import {ButtonWithLoading} from "@/components/wrappers/common/button/button-with-loading";
|
||||
|
||||
export const usersColumns: ColumnDef<User>[] = [
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client"
|
||||
|
||||
import {ColumnDef} from "@tanstack/react-table"
|
||||
import {StatusBadge} from "@/components/wrappers/common/status-badge";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -15,9 +14,10 @@ import {ReloadIcon} from "@radix-ui/react-icons";
|
||||
import {Backup} from "@prisma/client";
|
||||
import {getFileUrlPresignedLocal} from "@/features/upload/private/upload.action";
|
||||
import {useMutation} from "@tanstack/react-query";
|
||||
import {createRestorationAction} from "@/features/restore/restore.action";
|
||||
import {createRestorationAction} from "@/features/dashboard/restore/restore.action";
|
||||
import {toast} from "sonner";
|
||||
import {useRouter} from "next/navigation";
|
||||
import {StatusBadge} from "@/components/wrappers/common/status-badge";
|
||||
import {TooltipCustom} from "@/components/wrappers/common/tooltipCustom/TooltipCustom";
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ import {cookies} from 'next/headers';
|
||||
|
||||
const COOKIE_NAME = 'PORTABASE_ORGANIZATION_SLUG';
|
||||
|
||||
export async function getCurrentOrganizationSlug() {
|
||||
return (await cookies()).get(COOKIE_NAME)?.value || "default";
|
||||
export async function getCurrentOrganizationId() {
|
||||
return (await cookies()).get(COOKIE_NAME)?.value || "";
|
||||
}
|
||||
|
||||
export async function setCurrentOrganizationSlug(slug: string) {
|
||||
export async function setCurrentOrganizationId(slug: string) {
|
||||
return (await cookies()).set(COOKIE_NAME, slug).get(COOKIE_NAME)?.value;
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client"
|
||||
|
||||
import {ColumnDef} from "@tanstack/react-table"
|
||||
import {StatusBadge} from "@/components/wrappers/common/status-badge";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -13,6 +12,7 @@ import {Button} from "@/components/ui/button";
|
||||
import {MoreHorizontal} from "lucide-react";
|
||||
import {ReloadIcon} from "@radix-ui/react-icons";
|
||||
import {Restoration} from "@prisma/client";
|
||||
import {StatusBadge} from "@/components/wrappers/common/status-badge";
|
||||
|
||||
|
||||
export const restoreColumns: ColumnDef<Restoration>[] = [
|
||||
Reference in New Issue
Block a user