mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
Working on the organization system.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import {PageParams} from "@/types/next";
|
||||
import {RegisterForm} from "@/components/wrappers/auth/Register/register-form/RegisterForm";
|
||||
import {RegisterForm} from "@/components/wrappers/auth/register/register-form/register-form";
|
||||
|
||||
export default async function RoutePage(props: PageParams<{}>) {
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import {PageParams} from "@/types/next";
|
||||
import {Page, PageContent, PageHeader, PageTitle} from "@/features/layout/page";
|
||||
import {notFound} from "next/navigation";
|
||||
import {RestoreForm} from "@/components/wrappers/dashboard/database/RestoreForm";
|
||||
import {currentUser} from "@/lib/auth/current-user";
|
||||
|
||||
import {db} from "@/db";
|
||||
import {eq} from "drizzle-orm";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
|
||||
export default async function RoutePage(
|
||||
props: PageParams<{
|
||||
databaseId: string;
|
||||
}>
|
||||
) {
|
||||
const {databaseId} = await props.params;
|
||||
|
||||
const user = await currentUser();
|
||||
if (!user) notFound();
|
||||
|
||||
const [dbToRestore] = await db.select().from(drizzleDb.schemas.database).where(eq(drizzleDb.schemas.database.id, databaseId));
|
||||
|
||||
if (!dbToRestore) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const dbsOfSameType = await db.select().from(drizzleDb.schemas.database).where(eq(drizzleDb.schemas.database.dbms!, dbToRestore.dbms!));
|
||||
const successfulBackups = await db.select().from(drizzleDb.schemas.backup).where(eq(drizzleDb.schemas.backup.status, "success"));
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<PageHeader>
|
||||
<PageTitle>Restore {dbToRestore.name}</PageTitle>
|
||||
</PageHeader>
|
||||
<PageContent>
|
||||
<RestoreForm databaseToRestore={dbToRestore} databases={dbsOfSameType} backups={successfulBackups}/>
|
||||
</PageContent>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
+3
-2
@@ -4,14 +4,15 @@ import { notFound } from "next/navigation";
|
||||
import { DatabaseForm } from "@/components/wrappers/dashboard/database/DatabaseForm/DatabaseForm";
|
||||
|
||||
import { db } from "@/db";
|
||||
import { database } from "@/db/schema";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
export default async function RoutePage(props: PageParams<{ databaseId: string }>) {
|
||||
const { databaseId } = await props.params;
|
||||
|
||||
const dbItem = await db.query.database.findFirst({
|
||||
where: eq(database.id, databaseId),
|
||||
where: eq(drizzleDb.schemas.database.id, databaseId),
|
||||
});
|
||||
|
||||
if (!dbItem) {
|
||||
+10
-10
@@ -9,13 +9,13 @@ import { CronButton } from "@/components/wrappers/dashboard/database/CronButton/
|
||||
|
||||
import { db } from "@/db";
|
||||
import { eq, and } from "drizzle-orm";
|
||||
import { backup as drizzleBackup, database as drizzleDatabase, restoration as drizzleRestoration } from "@/db/schema";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
export default async function RoutePage(props: PageParams<{ databaseId: string }>) {
|
||||
const { databaseId } = await props.params;
|
||||
|
||||
const dbItem = await db.query.database.findFirst({
|
||||
where: eq(drizzleDatabase.id, databaseId),
|
||||
where: eq(drizzleDb.schemas.database.id, databaseId),
|
||||
});
|
||||
|
||||
if (!dbItem) {
|
||||
@@ -23,7 +23,7 @@ export default async function RoutePage(props: PageParams<{ databaseId: string }
|
||||
}
|
||||
|
||||
const backups = await db.query.backup.findMany({
|
||||
where: eq(drizzleBackup.databaseId, dbItem.id),
|
||||
where: eq(drizzleDb.schemas.backup.databaseId, dbItem.id),
|
||||
with: {
|
||||
restorations: true,
|
||||
},
|
||||
@@ -31,7 +31,7 @@ export default async function RoutePage(props: PageParams<{ databaseId: string }
|
||||
});
|
||||
|
||||
const restorations = await db.query.restoration.findMany({
|
||||
where: eq(drizzleRestoration.databaseId, dbItem.id),
|
||||
where: eq(drizzleDb.schemas.restoration.databaseId, dbItem.id),
|
||||
orderBy: (r, { desc }) => [desc(r.createdAt)],
|
||||
});
|
||||
|
||||
@@ -40,14 +40,14 @@ export default async function RoutePage(props: PageParams<{ databaseId: string }
|
||||
|
||||
const [totalBackups, successfulBackups] = await Promise.all([
|
||||
db
|
||||
.select({ count: drizzleBackup.id })
|
||||
.from(drizzleBackup)
|
||||
.where(eq(drizzleBackup.databaseId, dbItem.id))
|
||||
.select({ count: drizzleDb.schemas.backup.id })
|
||||
.from(drizzleDb.schemas.backup)
|
||||
.where(eq(drizzleDb.schemas.backup.databaseId, dbItem.id))
|
||||
.then((rows) => rows.length),
|
||||
db
|
||||
.select({ count: drizzleBackup.id })
|
||||
.from(drizzleBackup)
|
||||
.where(and(eq(drizzleBackup.databaseId, dbItem.id), eq(drizzleBackup.status, "success")))
|
||||
.select({ count: drizzleDb.schemas.backup.id })
|
||||
.from(drizzleDb.schemas.backup)
|
||||
.where(and(eq(drizzleDb.schemas.backup.databaseId, dbItem.id), eq(drizzleDb.schemas.backup.status, "success")))
|
||||
.then((rows) => rows.length),
|
||||
]);
|
||||
|
||||
+14
-13
@@ -1,17 +1,18 @@
|
||||
import { notFound } from "next/navigation";
|
||||
import { PageParams } from "@/types/next";
|
||||
import { Page, PageContent, PageHeader, PageTitle } from "@/features/layout/page";
|
||||
import { ProjectForm } from "@/components/wrappers/dashboard/projects/ProjectsForm/ProjectForm";
|
||||
import {notFound} from "next/navigation";
|
||||
import {PageParams} from "@/types/next";
|
||||
import {Page, PageContent, PageHeader, PageTitle} from "@/features/layout/page";
|
||||
import {ProjectForm} from "@/components/wrappers/dashboard/projects/ProjectsForm/ProjectForm";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
import { db } from "@/db";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { project as drizzleProject, organization as drizzleOrganization, DatabaseWith } from "@/db/schema";
|
||||
import {db} from "@/db";
|
||||
import {eq} from "drizzle-orm";
|
||||
import {DatabaseWith} from "@/db/schema/06_database";
|
||||
|
||||
export default async function RoutePage(props: PageParams<{ projectId: string }>) {
|
||||
const { projectId } = await props.params;
|
||||
const {projectId} = await props.params;
|
||||
|
||||
const proj = await db.query.project.findFirst({
|
||||
where: eq(drizzleProject.id, projectId),
|
||||
where: eq(drizzleDb.schemas.project.id, projectId),
|
||||
with: {
|
||||
databases: true,
|
||||
},
|
||||
@@ -23,7 +24,7 @@ export default async function RoutePage(props: PageParams<{ projectId: string }>
|
||||
|
||||
//
|
||||
const org = await db.query.organization.findFirst({
|
||||
where: eq(drizzleOrganization.slug, "default"),
|
||||
where: eq(drizzleDb.schemas.organization.slug, "default"),
|
||||
});
|
||||
|
||||
if (!org) {
|
||||
@@ -32,14 +33,14 @@ export default async function RoutePage(props: PageParams<{ projectId: string }>
|
||||
|
||||
const availableDatabases = (
|
||||
await db.query.database.findMany({
|
||||
where: (db, { or, eq, isNull }) => or(isNull(db.projectId), eq(db.projectId, proj.id)),
|
||||
where: (db, {or, eq, isNull}) => or(isNull(db.projectId), eq(db.projectId, proj.id)),
|
||||
with: {
|
||||
agent: true,
|
||||
project: true,
|
||||
backups: true,
|
||||
restorations: true,
|
||||
},
|
||||
orderBy: (db, { desc }) => [desc(db.createdAt)],
|
||||
orderBy: (db, {desc}) => [desc(db.createdAt)],
|
||||
})
|
||||
).filter((db): db is DatabaseWith => db.project !== null);
|
||||
|
||||
@@ -52,7 +53,7 @@ export default async function RoutePage(props: PageParams<{ projectId: string }>
|
||||
<ProjectForm
|
||||
organization={org}
|
||||
databases={availableDatabases}
|
||||
defaultValues={{ name: proj.name, slug: proj.slug, databases: proj.databases.map((db) => db.id) }}
|
||||
defaultValues={{name: proj.name, slug: proj.slug, databases: proj.databases.map((db) => db.id)}}
|
||||
projectId={proj.id}
|
||||
/>
|
||||
</PageContent>
|
||||
+12
-7
@@ -10,19 +10,24 @@ import { notFound } from "next/navigation";
|
||||
|
||||
import { db } from "@/db";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { organization as drizzleOrganization } from "@/db/schema";
|
||||
import {getOrganization} from "@/lib/auth/auth";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
export default async function RoutePage(props: PageParams<{ slug: string; projectId: string }>) {
|
||||
const { slug: organizationSlug, projectId } = await props.params;
|
||||
export default async function RoutePage(props: PageParams<{
|
||||
// slug: string;
|
||||
projectId: string
|
||||
}>) {
|
||||
const {
|
||||
// slug: organizationSlug,
|
||||
projectId } = await props.params;
|
||||
|
||||
const organization = await getOrganization({organizationSlug});
|
||||
const organization = await getOrganization({});
|
||||
|
||||
if (!organization || organization?.slug !== organizationSlug) {
|
||||
if (!organization) {
|
||||
notFound();
|
||||
}
|
||||
const org = await db.query.organization.findFirst({
|
||||
where: eq(drizzleOrganization.slug, organization.slug),
|
||||
where: eq(drizzleDb.schemas.organization.slug, organization.slug),
|
||||
});
|
||||
|
||||
if (!org) notFound();
|
||||
@@ -56,7 +61,7 @@ export default async function RoutePage(props: PageParams<{ slug: string; projec
|
||||
{proj.databases.length > 0 ? (
|
||||
<CardsWithPagination
|
||||
data={proj.databases}
|
||||
organizationSlug={organizationSlug}
|
||||
organizationSlug={organization.slug}
|
||||
cardItem={ProjectDatabaseCard}
|
||||
cardsPerPage={4}
|
||||
numberOfColumns={1}
|
||||
+6
-6
@@ -3,16 +3,16 @@ import {Page, PageContent, PageHeader, PageTitle} from "@/features/layout/page";
|
||||
import {ProjectForm} from "@/components/wrappers/dashboard/projects/ProjectsForm/ProjectForm";
|
||||
import {notFound} from "next/navigation";
|
||||
import {db} from "@/db";
|
||||
import {DatabaseWith, organization as drizzleOrganization} from "@/db/schema";
|
||||
import {eq} from "drizzle-orm";
|
||||
import {getOrganization} from "@/lib/auth/auth";
|
||||
import * as drizzleDb from "@/db";
|
||||
import {DatabaseWith} from "@/db/schema/06_database";
|
||||
|
||||
export default async function RoutePage(props: PageParams<{ slug: string }>) {
|
||||
const {slug: organizationSlug} = await props.params;
|
||||
export default async function RoutePage(props: PageParams<{ }>) {
|
||||
|
||||
const organization = await getOrganization({organizationSlug});
|
||||
const organization = await getOrganization({});
|
||||
|
||||
if (!organization || organization?.slug !== organizationSlug) {
|
||||
if (!organization ) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ export default async function RoutePage(props: PageParams<{ slug: string }>) {
|
||||
).filter((db) => db.project !== null) as DatabaseWith[];
|
||||
|
||||
const org = await db.query.organization.findFirst({
|
||||
where: eq(drizzleOrganization.slug, organization.slug),
|
||||
where: eq(drizzleDb.schemas.organization.slug, organization.slug),
|
||||
});
|
||||
|
||||
if (!org) notFound();
|
||||
+6
-7
@@ -9,12 +9,11 @@ import {db} from "@/db";
|
||||
import {notFound} from "next/navigation";
|
||||
import {getOrganization} from "@/lib/auth/auth";
|
||||
|
||||
export default async function RoutePage(props: PageParams<{ slug: string }>) {
|
||||
const {slug: organizationSlug} = await props.params;
|
||||
export default async function RoutePage(props: PageParams<{ }>) {
|
||||
|
||||
const organization = await getOrganization({organizationSlug});
|
||||
const organization = await getOrganization({});
|
||||
|
||||
if (!organization || organization?.slug !== organizationSlug) {
|
||||
if (!organization) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
@@ -35,7 +34,7 @@ export default async function RoutePage(props: PageParams<{ slug: string }>) {
|
||||
<PageTitle>Projects</PageTitle>
|
||||
{projects.length > 0 && (
|
||||
<PageActions>
|
||||
<Link href={`/dashboard/${organizationSlug}/projects/new`}>
|
||||
<Link href={`/dashboard/projects/new`}>
|
||||
<Button>+ Create Project</Button>
|
||||
</Link>
|
||||
</PageActions>
|
||||
@@ -44,11 +43,11 @@ export default async function RoutePage(props: PageParams<{ slug: string }>) {
|
||||
|
||||
<PageContent className="mt-10">
|
||||
{projects.length > 0 ? (
|
||||
<CardsWithPagination organizationSlug={organizationSlug} data={projects} cardItem={ProjectCard}
|
||||
<CardsWithPagination organizationSlug={organization.slug} data={projects} cardItem={ProjectCard}
|
||||
cardsPerPage={4} numberOfColumns={1}/>
|
||||
) : (
|
||||
<Link
|
||||
href={`/dashboard/${organizationSlug}/projects/new`}
|
||||
href={`/dashboard/projects/new`}
|
||||
className=" flex item-center justify-center border-2 border-dashed transition-colors border-primary p-8 lg:p-12 w-full rounded-md"
|
||||
>
|
||||
Create new Project
|
||||
+10
-10
@@ -7,7 +7,7 @@ import { getCurrentOrganizationSlug } from "@/features/dashboard/organization-co
|
||||
import { notFound } from "next/navigation";
|
||||
import { db } from "@/db";
|
||||
import { asc, count, eq, inArray } from "drizzle-orm";
|
||||
import { organization as drizzleOrganization, project as drizzleProject, backup as drizzleBackup } from "@/db/schema";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
export default async function RoutePage(props: PageParams<{ slug: string }>) {
|
||||
const { slug: organizationSlug } = await props.params;
|
||||
@@ -18,13 +18,13 @@ export default async function RoutePage(props: PageParams<{ slug: string }>) {
|
||||
}
|
||||
|
||||
const org = await db.query.organization.findFirst({
|
||||
where: eq(drizzleOrganization.slug, currentOrganizationSlug),
|
||||
where: eq(drizzleDb.schemas.organization.slug, currentOrganizationSlug),
|
||||
});
|
||||
|
||||
if (!org) notFound();
|
||||
|
||||
const projects = await db.query.project.findMany({
|
||||
where: eq(drizzleProject.organizationId, org.id),
|
||||
where: eq(drizzleDb.schemas.project.organizationId, org.id),
|
||||
});
|
||||
|
||||
const projectsCount = projects.length;
|
||||
@@ -34,19 +34,19 @@ export default async function RoutePage(props: PageParams<{ slug: string }>) {
|
||||
id: true,
|
||||
createdAt: true,
|
||||
},
|
||||
orderBy: [asc(drizzleBackup.id)],
|
||||
orderBy: [asc(drizzleDb.schemas.backup.id)],
|
||||
});
|
||||
|
||||
const backupsRate = await db
|
||||
.select({
|
||||
createdAt: drizzleBackup.createdAt,
|
||||
status: drizzleBackup.status,
|
||||
createdAt: drizzleDb.schemas.backup.createdAt,
|
||||
status: drizzleDb.schemas.backup.status,
|
||||
_count: count(),
|
||||
})
|
||||
.from(drizzleBackup)
|
||||
.where(inArray(drizzleBackup.status, ["success", "failed"]))
|
||||
.groupBy(drizzleBackup.createdAt, drizzleBackup.status)
|
||||
.orderBy(drizzleBackup.createdAt);
|
||||
.from(drizzleDb.schemas.backup)
|
||||
.where(inArray(drizzleDb.schemas.backup.status, ["success", "failed"]))
|
||||
.groupBy(drizzleDb.schemas.backup.createdAt, drizzleDb.schemas.backup.status)
|
||||
.orderBy(drizzleDb.schemas.backup.createdAt);
|
||||
|
||||
return (
|
||||
<Page>
|
||||
@@ -1,41 +0,0 @@
|
||||
import { PageParams } from "@/types/next";
|
||||
import { Page, PageContent, PageHeader, PageTitle } from "@/features/layout/page";
|
||||
import { notFound } from "next/navigation";
|
||||
import { RestoreForm } from "@/components/wrappers/dashboard/database/RestoreForm";
|
||||
import { currentUser } from "@/lib/auth/current-user";
|
||||
|
||||
import { db } from "@/db";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { database, backup } from "@/db/schema";
|
||||
|
||||
export default async function RoutePage(
|
||||
props: PageParams<{
|
||||
databaseId: string;
|
||||
}>
|
||||
) {
|
||||
const { databaseId } = await props.params;
|
||||
|
||||
const user = await currentUser();
|
||||
if (!user) notFound();
|
||||
|
||||
const [dbToRestore] = await db.select().from(database).where(eq(database.id, databaseId));
|
||||
|
||||
if (!dbToRestore) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const dbsOfSameType = await db.select().from(database).where(eq(database.dbms!, dbToRestore.dbms!));
|
||||
|
||||
const successfulBackups = await db.select().from(backup).where(eq(backup.status, "success"));
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<PageHeader>
|
||||
<PageTitle>Restore {dbToRestore.name}</PageTitle>
|
||||
</PageHeader>
|
||||
<PageContent>
|
||||
<RestoreForm databaseToRestore={dbToRestore} databases={dbsOfSameType} backups={successfulBackups} />
|
||||
</PageContent>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
@@ -1,23 +1,22 @@
|
||||
import React from "react";
|
||||
import { redirect } from "next/navigation";
|
||||
import {redirect} from "next/navigation";
|
||||
|
||||
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
|
||||
import { AppSidebar } from "@/components/wrappers/dashboard/sideBar/app-sidebar";
|
||||
import { Header } from "@/features/layout/Header";
|
||||
import { currentUser } from "@/lib/auth/current-user";
|
||||
import {SidebarInset, SidebarProvider} from "@/components/ui/sidebar";
|
||||
import {AppSidebar} from "@/components/wrappers/dashboard/sideBar/app-sidebar";
|
||||
import {Header} from "@/features/layout/Header";
|
||||
import {currentUser} from "@/lib/auth/current-user";
|
||||
|
||||
export default async function Layout({ children }: { children: React.ReactNode }) {
|
||||
export default async function Layout({children}: { children: React.ReactNode }) {
|
||||
const user = await currentUser();
|
||||
|
||||
if (!user) redirect("/login");
|
||||
|
||||
return (
|
||||
<>
|
||||
<SidebarProvider>
|
||||
<div className="flex flex-col lg:flex-row w-full">
|
||||
<AppSidebar />
|
||||
<AppSidebar/>
|
||||
<SidebarInset>
|
||||
<Header />
|
||||
<Header/>
|
||||
<main className="h-full">{children}</main>
|
||||
</SidebarInset>
|
||||
</div>
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
import { PageParams } from "@/types/next";
|
||||
import { Page, PageActions, PageContent, PageHeader, PageTitle } from "@/features/layout/page";
|
||||
import { notFound } from "next/navigation";
|
||||
import { UserForm } from "@/components/wrappers/dashboard/profile/UserForm/UserForm";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { ButtonDeleteAccount } from "@/components/wrappers/dashboard/profile/ButtonDeleteAccount/ButtonDeleteAccount";
|
||||
import { AvatarWithUpload } from "@/components/wrappers/dashboard/profile/Avatar/AvatarWithUpload";
|
||||
import { currentUser } from "@/lib/auth/current-user";
|
||||
import {PageParams} from "@/types/next";
|
||||
import {Page, PageActions, PageContent, PageHeader, PageTitle} from "@/features/layout/page";
|
||||
import {notFound} from "next/navigation";
|
||||
import {UserForm} from "@/components/wrappers/dashboard/profile/UserForm/UserForm";
|
||||
import {Badge} from "@/components/ui/badge";
|
||||
import {ButtonDeleteAccount} from "@/components/wrappers/dashboard/profile/ButtonDeleteAccount/ButtonDeleteAccount";
|
||||
import {AvatarWithUpload} from "@/components/wrappers/dashboard/profile/Avatar/AvatarWithUpload";
|
||||
import {currentUser} from "@/lib/auth/current-user";
|
||||
import {getAccounts, getSessions} from "@/lib/auth/auth";
|
||||
//import { getAccounts, getSessions } from "@/lib/auth/auth";
|
||||
|
||||
export default async function RoutePage(props: PageParams<{}>) {
|
||||
const user = await currentUser();
|
||||
|
||||
console.log("my user",user);
|
||||
if (!user) {
|
||||
return notFound();
|
||||
}
|
||||
|
||||
|
||||
if (user.role !== "user" && user.role !== "admin" && user.role !== "superadmin") {
|
||||
return notFound();
|
||||
}
|
||||
|
||||
// const sessions = await getSessions();
|
||||
// const accounts = await getAccounts();
|
||||
// const sessions = await getSessions();
|
||||
// const accounts = await getAccounts();
|
||||
|
||||
return (
|
||||
<Page>
|
||||
@@ -41,7 +43,7 @@ export default async function RoutePage(props: PageParams<{}>) {
|
||||
<Badge className="ml-3 hidden lg:block">{user.role}</Badge>
|
||||
</PageTitle>
|
||||
<PageActions className="mt-2 hidden sm:block">
|
||||
<ButtonDeleteAccount text="Delete my account" />
|
||||
<ButtonDeleteAccount text="Delete my account"/>
|
||||
</PageActions>
|
||||
</div>
|
||||
<PageContent>
|
||||
@@ -54,7 +56,7 @@ export default async function RoutePage(props: PageParams<{}>) {
|
||||
}}
|
||||
/>
|
||||
<div className="mt-4 sm:hidden">
|
||||
<ButtonDeleteAccount text="Delete my account" />
|
||||
<ButtonDeleteAccount text="Delete my account"/>
|
||||
</div>
|
||||
</PageContent>
|
||||
</Page>
|
||||
|
||||
+6
-1
@@ -1,5 +1,10 @@
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
export default async function NotFound() {
|
||||
redirect("/dashboard/profile");
|
||||
// redirect("/dashboard/profile");
|
||||
return(
|
||||
<>
|
||||
Error
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
"use server";
|
||||
import { RegisterSchema } from "@/components/wrappers/auth/Register/register-form/register-form.schema";
|
||||
import { action } from "@/safe-actions";
|
||||
import { signUp } from "@/lib/auth/auth-client";
|
||||
import { db } from "@/db";
|
||||
import { user as drizzleUser } from "@/db/schema/01_user";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
export const registerUserAction = action.schema(RegisterSchema).action(async ({ parsedInput }: { parsedInput: typeof RegisterSchema._type }) => {
|
||||
const [user] = await db.select().from(drizzleUser).where(eq(drizzleUser.email, parsedInput.email)).limit(1);
|
||||
|
||||
if (!user && parsedInput.password === parsedInput.confirmPassword) {
|
||||
const { data, error } = await signUp.email({
|
||||
email: parsedInput.email,
|
||||
password: parsedInput.password,
|
||||
name: parsedInput.name,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw new Error(error.message);
|
||||
}
|
||||
|
||||
return {
|
||||
data: data?.user,
|
||||
};
|
||||
}
|
||||
throw new Error("An error occured while creating user");
|
||||
});
|
||||
@@ -26,6 +26,7 @@ export const LoginForm = (props: loginFormProps) => {
|
||||
const form = useZodForm({
|
||||
schema: LoginSchema,
|
||||
});
|
||||
|
||||
const mutation = useMutation({
|
||||
mutationFn: async (values: LoginType) => {
|
||||
const { error } = await signIn.email(values, {
|
||||
|
||||
+15
-14
@@ -11,36 +11,37 @@ 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/register-form/register-form.schema";
|
||||
import { registerUserAction } from "@/components/wrappers/auth/Register/register-form/register-form.action";
|
||||
import { RegisterSchema, RegisterType } from "@/components/wrappers/auth/register/register-form/register-form.schema";
|
||||
import { PasswordInput } from "@/components/wrappers/auth/PaswordInput/password-input";
|
||||
import {signUp} from "@/lib/auth/auth-client";
|
||||
|
||||
export type registerFormProps = {
|
||||
defaultValues?: RegisterType;
|
||||
};
|
||||
|
||||
export const RegisterForm = (props: registerFormProps) => {
|
||||
|
||||
const form = useZodForm({
|
||||
schema: RegisterSchema,
|
||||
});
|
||||
const router = useRouter();
|
||||
const mutation = useMutation({
|
||||
mutationFn: async (values: RegisterType) => {
|
||||
console.log(values);
|
||||
const createUser = await registerUserAction(values);
|
||||
console.log(createUser);
|
||||
const data = createUser?.data?.data;
|
||||
if (createUser?.serverError || !data) {
|
||||
console.log(createUser?.serverError);
|
||||
toast.error(createUser?.serverError);
|
||||
return;
|
||||
}
|
||||
toast.success(`Success`);
|
||||
router.push(`/login`);
|
||||
router.refresh();
|
||||
await signUp.email(values, {
|
||||
onSuccess: () => {
|
||||
toast.success(`Success`);
|
||||
router.push(`/login`);
|
||||
router.refresh();
|
||||
},
|
||||
onError: (error) => {
|
||||
console.log(error);
|
||||
toast.error(error.error.message);
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<Card>
|
||||
+3
-3
@@ -2,9 +2,9 @@
|
||||
import { userAction } from "@/safe-actions";
|
||||
import { z } from "zod";
|
||||
import { EmailFormSchema } from "@/components/wrappers/dashboard/admin/AdminEmailTab/EmailForm/email-form.schema";
|
||||
import { setting as drizzleSetting } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "@/db";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
export const updateEmailSettingsAction = userAction
|
||||
.schema(
|
||||
@@ -17,11 +17,11 @@ export const updateEmailSettingsAction = userAction
|
||||
const { name, data } = parsedInput;
|
||||
|
||||
const [updatedSettings] = await db
|
||||
.update(drizzleSetting)
|
||||
.update(drizzleDb.schemas.setting)
|
||||
.set({
|
||||
...data,
|
||||
})
|
||||
.where(eq(drizzleSetting.name, name))
|
||||
.where(eq(drizzleDb.schemas.setting.name, name))
|
||||
.returning();
|
||||
|
||||
return {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { sendEmail } from "@/utils/email-helper";
|
||||
import TestEmailSettings from "../../../../../../emails/TestEmailSettings";
|
||||
import { render } from "@react-email/render";
|
||||
import { toast } from "sonner";
|
||||
import { Setting } from "@/db/schema";
|
||||
import {Setting} from "@/db/schema/00_setting";
|
||||
|
||||
export type SettingsEmailTabProps = {
|
||||
settings: Setting;
|
||||
|
||||
@@ -10,7 +10,7 @@ import { checkConnexionToS3 } from "@/features/upload/public/upload.action";
|
||||
import { toast } from "sonner";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { updateStorageSettingsAction } from "@/components/wrappers/dashboard/admin/AdminStorageTab/StorageS3Form/s3-form.action";
|
||||
import { Setting } from "@/db/schema";
|
||||
import {Setting} from "@/db/schema/00_setting";
|
||||
|
||||
export type SettingsStorageTabProps = {
|
||||
settings: Setting;
|
||||
|
||||
+5
-5
@@ -3,9 +3,9 @@
|
||||
import { userAction } from "@/safe-actions";
|
||||
import { z } from "zod";
|
||||
import { db } from "@/db";
|
||||
import { setting as drizzleSetting } from "@/db/schema";
|
||||
import { S3FormSchema, StorageSwitchSchema } from "@/components/wrappers/dashboard/admin/AdminStorageTab/StorageS3Form/s3-form.schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
export const updateS3SettingsAction = userAction
|
||||
.schema(
|
||||
@@ -18,9 +18,9 @@ export const updateS3SettingsAction = userAction
|
||||
const { name, data } = parsedInput;
|
||||
|
||||
const [updatedSettings] = await db
|
||||
.update(drizzleSetting)
|
||||
.update(drizzleDb.schemas.setting)
|
||||
.set({ ...data })
|
||||
.where(eq(drizzleSetting.name, name))
|
||||
.where(eq(drizzleDb.schemas.setting.name, name))
|
||||
.returning();
|
||||
|
||||
return {
|
||||
@@ -39,9 +39,9 @@ export const updateStorageSettingsAction = userAction
|
||||
const { name, data } = parsedInput;
|
||||
|
||||
const [updatedSettings] = await db
|
||||
.update(drizzleSetting)
|
||||
.update(drizzleDb.schemas.setting)
|
||||
.set({ ...data })
|
||||
.where(eq(drizzleSetting.name, name))
|
||||
.where(eq(drizzleDb.schemas.setting.name, name))
|
||||
.returning();
|
||||
|
||||
return {
|
||||
|
||||
@@ -4,8 +4,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { SettingsEmailTab } from "@/components/wrappers/dashboard/admin/AdminEmailTab/SettingsEmailTab";
|
||||
import { SettingsStorageTab } from "@/components/wrappers/dashboard/admin/AdminStorageTab/SettingsStorageTab";
|
||||
import { AdminUsersTable } from "@/components/wrappers/dashboard/admin/admin-user-table";
|
||||
import { Setting } from "@/db/schema";
|
||||
import { User } from "@/db/schema/01_user";
|
||||
import {Setting} from "@/db/schema/00_setting";
|
||||
|
||||
export type AdminTabsProps = {
|
||||
users: User[];
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||
import Link from "next/link";
|
||||
import { formatDateLastContact } from "@/utils/date-formatting";
|
||||
import { ConnectionCircle } from "@/components/wrappers/common/connection-circle";
|
||||
import { Agent } from "@/db/schema";
|
||||
import {Agent} from "@/db/schema/07_agent";
|
||||
|
||||
export type agentCardProps = {
|
||||
data: Agent;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use client";
|
||||
import { generateEdgeKey } from "@/utils/edge_key";
|
||||
import { getServerUrl } from "@/utils/get-server-url";
|
||||
import { PasswordInput } from "@/components/wrappers/auth/PaswordInput/password-input";
|
||||
import { useState } from "react";
|
||||
import { CopyButton } from "@/components/wrappers/common/button/copy-button";
|
||||
import { Agent } from "@/db/schema";
|
||||
import {generateEdgeKey} from "@/utils/edge_key";
|
||||
import {getServerUrl} from "@/utils/get-server-url";
|
||||
import {PasswordInput} from "@/components/wrappers/auth/PaswordInput/password-input";
|
||||
import {useState} from "react";
|
||||
import {CopyButton} from "@/components/wrappers/common/button/copy-button";
|
||||
import {Agent} from "@/db/schema/07_agent";
|
||||
|
||||
export type AgentCardKeyProps = {
|
||||
agent: Agent;
|
||||
@@ -22,7 +22,7 @@ export const AgentCardKey = (props: AgentCardKeyProps) => {
|
||||
setCode(edge_key);
|
||||
}}
|
||||
/>
|
||||
<CopyButton className="mt-5" value={code} />
|
||||
<CopyButton className="mt-5" value={code}/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,12 +4,12 @@ import { AgentSchema } from "@/components/wrappers/dashboard/agent/AgentForm/age
|
||||
import { z } from "zod";
|
||||
import { eq, and, ne, count } from "drizzle-orm";
|
||||
import { db } from "@/db";
|
||||
import { agent } from "@/db/schema";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
const verifySlugUniqueness = async (slug: string, agentId?: string) => {
|
||||
const conditions = agentId ? and(eq(agent.slug, slug), ne(agent.id, agentId)) : eq(agent.slug, slug);
|
||||
const conditions = agentId ? and(eq(drizzleDb.schemas.agent.slug, slug), ne(drizzleDb.schemas.agent.id, agentId)) : eq(drizzleDb.schemas.agent.slug, slug);
|
||||
|
||||
const [countResult] = await db.select({ count: count() }).from(agent).where(conditions);
|
||||
const [countResult] = await db.select({ count: count() }).from(drizzleDb.schemas.agent).where(conditions);
|
||||
|
||||
if (countResult.count > 0) {
|
||||
throw new ActionError("Slug already exists");
|
||||
@@ -19,7 +19,7 @@ const verifySlugUniqueness = async (slug: string, agentId?: string) => {
|
||||
export const createAgentAction = userAction.schema(AgentSchema).action(async ({ parsedInput }) => {
|
||||
await verifySlugUniqueness(parsedInput.slug);
|
||||
|
||||
const [createdAgent] = await db.insert(agent).values(parsedInput).returning();
|
||||
const [createdAgent] = await db.insert(drizzleDb.schemas.agent).values(parsedInput).returning();
|
||||
|
||||
return {
|
||||
data: createdAgent,
|
||||
@@ -36,7 +36,7 @@ export const updateAgentAction = userAction
|
||||
.action(async ({ parsedInput }) => {
|
||||
await verifySlugUniqueness(parsedInput.data.slug, parsedInput.id);
|
||||
|
||||
const [updatedAgent] = await db.update(agent).set(parsedInput.data).where(eq(agent.id, parsedInput.id)).returning();
|
||||
const [updatedAgent] = await db.update(drizzleDb.schemas.agent).set(parsedInput.data).where(eq(drizzleDb.schemas.agent.id, parsedInput.id)).returning();
|
||||
|
||||
return {
|
||||
data: updatedAgent,
|
||||
|
||||
@@ -8,7 +8,7 @@ import { PropsWithChildren } from "react";
|
||||
import { CopyButton } from "@/components/wrappers/common/button/copy-button";
|
||||
import { getServerUrl } from "@/utils/get-server-url";
|
||||
import { CodeSnippet } from "@/components/wrappers/code-snippet/CodeSnippet";
|
||||
import { Agent } from "@/db/schema";
|
||||
import {Agent} from "@/db/schema/07_agent";
|
||||
|
||||
export type agentRegistrationDialogProps = PropsWithChildren<{
|
||||
agent: Agent;
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
import { z } from "zod";
|
||||
import { userAction } from "@/safe-actions";
|
||||
import { db } from "@/db";
|
||||
import { backup } from "@/db/schema";
|
||||
import { ServerActionResult } from "@/types/action-type";
|
||||
import { Backup } from "@/db/schema";
|
||||
import * as drizzleDb from "@/db";
|
||||
import {Backup} from "@/db/schema/06_database";
|
||||
|
||||
export const backupButtonAction = userAction.schema(z.string()).action(async ({ parsedInput }): Promise<ServerActionResult<Backup>> => {
|
||||
try {
|
||||
const [createdBackup] = await db
|
||||
.insert(backup)
|
||||
.insert(drizzleDb.schemas.backup)
|
||||
.values({
|
||||
databaseId: parsedInput,
|
||||
status: "waiting",
|
||||
|
||||
@@ -11,7 +11,7 @@ import { useMutation } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { updateDatabaseBackupPolicyAction } from "@/components/wrappers/dashboard/database/CronButton/cron.action";
|
||||
import { Database } from "@/db/schema";
|
||||
import {Database} from "@/db/schema/06_database";
|
||||
|
||||
export type CronButtonProps = {
|
||||
database: Database;
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useRouter } from "next/navigation";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { Database } from "@/db/schema";
|
||||
import {Database} from "@/db/schema/06_database";
|
||||
|
||||
export type CronInputProps = {
|
||||
database: Database;
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
import { userAction } from "@/safe-actions";
|
||||
import { z } from "zod";
|
||||
import { db } from "@/db";
|
||||
import { database } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
export const updateDatabaseBackupPolicyAction = userAction
|
||||
.schema(
|
||||
@@ -17,11 +17,11 @@ export const updateDatabaseBackupPolicyAction = userAction
|
||||
const cronPolicy = parsedInput.backupPolicy === "" ? null : parsedInput.backupPolicy;
|
||||
|
||||
const [updated] = await db
|
||||
.update(database)
|
||||
.update(drizzleDb.schemas.database)
|
||||
.set({
|
||||
backupPolicy: cronPolicy,
|
||||
})
|
||||
.where(eq(database.id, parsedInput.databaseId))
|
||||
.where(eq(drizzleDb.schemas.database.id, parsedInput.databaseId))
|
||||
.returning()
|
||||
.execute();
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
import { z } from "zod";
|
||||
import { userAction } from "@/safe-actions";
|
||||
import { db } from "@/db";
|
||||
import { database } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { DatabaseSchema } from "@/components/wrappers/dashboard/database/DatabaseForm/form-database.schema";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
export const updateDatabaseAction = userAction
|
||||
.schema(
|
||||
@@ -15,7 +15,7 @@ export const updateDatabaseAction = userAction
|
||||
})
|
||||
)
|
||||
.action(async ({ parsedInput }) => {
|
||||
const [updated] = await db.update(database).set(parsedInput.data).where(eq(database.id, parsedInput.id)).returning().execute();
|
||||
const [updated] = await db.update(drizzleDb.schemas.database).set(parsedInput.data).where(eq(drizzleDb.schemas.database.id, parsedInput.id)).returning().execute();
|
||||
|
||||
return updated;
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ import { authClient } from "@/lib/auth/auth-client";
|
||||
|
||||
export function OrganizationCombobox() {
|
||||
const router = useRouter();
|
||||
const { state } = useSidebar();
|
||||
|
||||
const { data: organizations } = authClient.useListOrganizations();
|
||||
const { data: activeOrganization } = authClient.useActiveOrganization();
|
||||
@@ -27,10 +28,9 @@ export function OrganizationCombobox() {
|
||||
await authClient.organization.setActive({
|
||||
organizationSlug: slug,
|
||||
});
|
||||
router.replace(`/dashboard/${slug}/home`);
|
||||
// router.replace(`/dashboard/${slug}/home`);
|
||||
router.refresh();
|
||||
};
|
||||
const { state } = useSidebar();
|
||||
|
||||
return <>{state === "expanded" && <ComboBox sideBar values={values} defaultValue={activeOrganization?.slug} onValueChange={onValueChange} />}</>;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
"use server";
|
||||
import { db } from "@/db";
|
||||
import { user as drizzleUser } from "@/db/schema";
|
||||
import { userAction } from "@/safe-actions";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { z } from "zod";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
|
||||
export const updateImageUserAction = userAction.schema(z.string()).action(async ({ parsedInput, ctx }) => {
|
||||
const [updatedUser] = await db.update(drizzleUser).set({ image: parsedInput }).where(eq(drizzleUser.id, ctx.user.id)).returning();
|
||||
const [updatedUser] = await db.update(drizzleDb.schemas.user).set({ image: parsedInput }).where(eq(drizzleDb.schemas.user.id, ctx.user.id)).returning();
|
||||
|
||||
return {
|
||||
data: updatedUser,
|
||||
|
||||
+4
-3
@@ -3,22 +3,23 @@ import { userAction } from "@/safe-actions";
|
||||
import { z } from "zod";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { db } from "@/db";
|
||||
import { user as drizzleUser } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
|
||||
export const deleteUserAction = userAction.schema(z.string()).action(async ({ parsedInput, ctx }) => {
|
||||
const userId = parsedInput.length > 0 ? parsedInput : ctx.user.id;
|
||||
const uuid = uuidv4();
|
||||
|
||||
const [updatedUser] = await db
|
||||
.update(drizzleUser)
|
||||
.update(drizzleDb.schemas.user)
|
||||
.set({
|
||||
email: `${uuid}@portabase.com`,
|
||||
name: `${uuid}`,
|
||||
//deleted: true,
|
||||
//todo: add deleted
|
||||
})
|
||||
.where(eq(drizzleUser.id, userId))
|
||||
.where(eq(drizzleDb.schemas.user.id, userId))
|
||||
.returning();
|
||||
|
||||
return {
|
||||
|
||||
@@ -3,8 +3,8 @@ import { userAction } from "@/safe-actions";
|
||||
import { z } from "zod";
|
||||
import { UserSchema } from "@/components/wrappers/dashboard/profile/UserForm/user-form.schema";
|
||||
import { db } from "@/db";
|
||||
import { user as drizzleUser } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
export const updateUserAction = userAction
|
||||
.schema(
|
||||
@@ -14,8 +14,7 @@ export const updateUserAction = userAction
|
||||
})
|
||||
)
|
||||
.action(async ({ parsedInput }) => {
|
||||
const [updatedUser] = await db.update(drizzleUser).set(parsedInput.data).where(eq(drizzleUser.id, parsedInput.id)).returning();
|
||||
|
||||
const [updatedUser] = await db.update(drizzleDb.schemas.user).set(parsedInput.data).where(eq(drizzleDb.schemas.user.id, parsedInput.id)).returning();
|
||||
return {
|
||||
data: updatedUser,
|
||||
};
|
||||
|
||||
+12
-12
@@ -1,24 +1,24 @@
|
||||
"use server";
|
||||
|
||||
import { userAction } from "@/safe-actions";
|
||||
import { z } from "zod";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { ServerActionResult } from "@/types/action-type";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "@/db";
|
||||
import { project } from "@/db/schema";
|
||||
import {userAction} from "@/safe-actions";
|
||||
import {z} from "zod";
|
||||
import {v4 as uuidv4} from "uuid";
|
||||
import {ServerActionResult} from "@/types/action-type";
|
||||
import {eq} from "drizzle-orm";
|
||||
import {db} from "@/db";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
export const deleteProjectAction = userAction.schema(z.string()).action(async ({ parsedInput }): Promise<ServerActionResult<typeof project.$inferSelect>> => {
|
||||
export const deleteProjectAction = userAction.schema(z.string()).action(async ({parsedInput}): Promise<ServerActionResult<typeof drizzleDb.schemas.project.$inferSelect>> => {
|
||||
try {
|
||||
const uuid = uuidv4();
|
||||
|
||||
const updatedProjects = await db
|
||||
.update(project)
|
||||
.update(drizzleDb.schemas.project)
|
||||
.set({
|
||||
isArchived: true,
|
||||
slug: uuid,
|
||||
})
|
||||
.where(eq(project.id, parsedInput))
|
||||
.where(eq(drizzleDb.schemas.project.id, parsedInput))
|
||||
.returning();
|
||||
|
||||
const updatedProject = updatedProjects[0];
|
||||
@@ -32,7 +32,7 @@ export const deleteProjectAction = userAction.schema(z.string()).action(async ({
|
||||
value: updatedProject,
|
||||
actionSuccess: {
|
||||
message: "Projects has been successfully archived.",
|
||||
messageParams: { projectId: parsedInput },
|
||||
messageParams: {projectId: parsedInput},
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
@@ -42,7 +42,7 @@ export const deleteProjectAction = userAction.schema(z.string()).action(async ({
|
||||
message: "Failed to archive Projects.",
|
||||
status: 500,
|
||||
cause: error instanceof Error ? error.message : "Unknown error",
|
||||
messageParams: { projectId: parsedInput },
|
||||
messageParams: {projectId: parsedInput},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { eventUpdate } from "@/types/events";
|
||||
import { backupColumns } from "@/features/dashboard/backup/columns";
|
||||
import { restoreColumns } from "@/features/dashboard/restore/columns";
|
||||
import { DataTable } from "@/components/wrappers/common/table/data-table";
|
||||
import { Backup, Database, Restoration } from "@/db/schema";
|
||||
import {Backup, Database, Restoration} from "@/db/schema/06_database";
|
||||
|
||||
export type DatabaseTabsProps = {
|
||||
backups: Backup[];
|
||||
|
||||
@@ -5,7 +5,7 @@ import Image from "next/image";
|
||||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||
import { ConnectionCircle } from "@/components/wrappers/common/connection-circle";
|
||||
import { formatDateLastContact } from "@/utils/date-formatting";
|
||||
import { Database } from "@/db/schema";
|
||||
import {Database} from "@/db/schema/06_database";
|
||||
|
||||
export type projectDatabaseCardProps = {
|
||||
data: Database;
|
||||
|
||||
@@ -11,7 +11,8 @@ import { createProjectAction, updateProjectAction } from "@/components/wrappers/
|
||||
import { useRouter } from "next/navigation";
|
||||
import { MultiSelect } from "@/components/wrappers/common/multiselect/multi-select";
|
||||
import { toast } from "sonner";
|
||||
import { DatabaseWith, Organization } from "@/db/schema";
|
||||
import {DatabaseWith} from "@/db/schema/06_database";
|
||||
import {Organization} from "@/db/schema/02_organization";
|
||||
|
||||
export type projectFormProps = {
|
||||
defaultValues?: ProjectType;
|
||||
|
||||
@@ -4,9 +4,11 @@ import { userAction } from "@/safe-actions";
|
||||
import { ProjectSchema } from "@/components/wrappers/dashboard/projects/ProjectsForm/ProjectForm.schema";
|
||||
import { z } from "zod";
|
||||
import { ServerActionResult } from "@/types/action-type";
|
||||
import { Database, database as drizzleDatabase, project as drizzleProject, Project } from "@/db/schema";
|
||||
import { db } from "@/db";
|
||||
import { eq, inArray } from "drizzle-orm";
|
||||
import {Project} from "@/db/schema/05_project";
|
||||
import * as drizzleDb from "@/db";
|
||||
import {Database} from "@/db/schema/06_database";
|
||||
|
||||
export const createProjectAction = userAction
|
||||
.schema(
|
||||
@@ -18,7 +20,7 @@ export const createProjectAction = userAction
|
||||
.action(async ({ parsedInput }): Promise<ServerActionResult<Project>> => {
|
||||
try {
|
||||
const [createdProject] = await db
|
||||
.insert(drizzleProject)
|
||||
.insert(drizzleDb.schemas.project)
|
||||
.values({
|
||||
name: parsedInput.data.name,
|
||||
slug: parsedInput.data.slug,
|
||||
@@ -27,7 +29,7 @@ export const createProjectAction = userAction
|
||||
.returning();
|
||||
|
||||
if (parsedInput.data.databases.length > 0) {
|
||||
await db.update(drizzleDatabase).set({ projectId: createdProject.id }).where(inArray(drizzleDatabase.id, parsedInput.data.databases));
|
||||
await db.update(drizzleDb.schemas.database).set({ projectId: createdProject.id }).where(inArray(drizzleDb.schemas.database.id, parsedInput.data.databases));
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -62,7 +64,7 @@ export const updateProjectAction = userAction
|
||||
.action(async ({ parsedInput }): Promise<ServerActionResult<Project>> => {
|
||||
try {
|
||||
const existing = await db.query.project.findFirst({
|
||||
where: eq(drizzleProject.id, parsedInput.projectId),
|
||||
where: eq(drizzleDb.schemas.project.id, parsedInput.projectId),
|
||||
with: {
|
||||
databases: true,
|
||||
},
|
||||
@@ -79,20 +81,20 @@ export const updateProjectAction = userAction
|
||||
const databasesToRemove = existingDbIds.filter((id: string) => !newDbIds.includes(id));
|
||||
|
||||
if (databasesToAdd.length > 0) {
|
||||
await db.update(drizzleDatabase).set({ projectId: parsedInput.projectId }).where(inArray(drizzleDatabase.id, databasesToAdd));
|
||||
await db.update(drizzleDb.schemas.database).set({ projectId: parsedInput.projectId }).where(inArray(drizzleDb.schemas.database.id, databasesToAdd));
|
||||
}
|
||||
|
||||
if (databasesToRemove.length > 0) {
|
||||
await db.update(drizzleDatabase).set({ projectId: null }).where(inArray(drizzleDatabase.id, databasesToRemove));
|
||||
await db.update(drizzleDb.schemas.database).set({ projectId: null }).where(inArray(drizzleDb.schemas.database.id, databasesToRemove));
|
||||
}
|
||||
|
||||
const [updatedProject] = await db
|
||||
.update(drizzleProject)
|
||||
.update(drizzleDb.schemas.project)
|
||||
.set({
|
||||
name: parsedInput.data.name,
|
||||
slug: parsedInput.data.slug,
|
||||
})
|
||||
.where(eq(drizzleProject.id, parsedInput.projectId))
|
||||
.where(eq(drizzleDb.schemas.project.id, parsedInput.projectId))
|
||||
.returning();
|
||||
|
||||
return {
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
|
||||
import { updateUserOrganizationAction } from "@/components/wrappers/dashboard/settings/SettingsUsersTab/settings-user-tab.action";
|
||||
import { OrganizationMember } from "@/db/schema/02_organization";
|
||||
import {OrganizationMember} from "@/db/schema/03_member";
|
||||
|
||||
export const usersColumns: ColumnDef<OrganizationMember>[] = [
|
||||
{
|
||||
|
||||
@@ -32,9 +32,8 @@ export async function AppSidebar() {
|
||||
const organization = await getOrganization({organizationId: member.organizationId});
|
||||
|
||||
//todo: à revoir
|
||||
console.log("organization", organization);
|
||||
|
||||
console.log("membrer", member);
|
||||
console.log("aoaoaoaoaoa", organization);
|
||||
|
||||
return (
|
||||
<Sidebar collapsible="icon">
|
||||
|
||||
+53
-6
@@ -1,13 +1,60 @@
|
||||
import "dotenv/config";
|
||||
import { drizzle } from "drizzle-orm/node-postgres";
|
||||
import {drizzle} from "drizzle-orm/node-postgres";
|
||||
|
||||
import * as settings from "./schema/00_setting";
|
||||
import * as user from "./schema/01_user";
|
||||
import * as organisation from "./schema/02_organization";
|
||||
import * as invitation from "./schema/03_member";
|
||||
import * as member from "./schema/04_invitation";
|
||||
import * as project from "./schema/05_project";
|
||||
import * as agent from "./schema/07_agent";
|
||||
import * as database from "./schema/06_database";
|
||||
|
||||
|
||||
import {Pool} from "pg";
|
||||
|
||||
// Do not delete
|
||||
import dotenv from "dotenv";
|
||||
import { env } from "@/env.mjs";
|
||||
import * as schema from "./schema";
|
||||
import {migrate} from "drizzle-orm/node-postgres/migrator";
|
||||
|
||||
dotenv.config({
|
||||
path: ".env",
|
||||
});
|
||||
|
||||
export const db = drizzle(env.DATABASE_URL!, {
|
||||
schema,
|
||||
const pool = new Pool({
|
||||
connectionString: process.env.DATABASE_URL!,
|
||||
});
|
||||
|
||||
export const schemas = {
|
||||
...settings,
|
||||
...user,
|
||||
...organisation,
|
||||
...invitation,
|
||||
...member,
|
||||
...project,
|
||||
...agent,
|
||||
...database
|
||||
};
|
||||
|
||||
export const db = drizzle({
|
||||
client: pool,
|
||||
logger: true,
|
||||
schema: schemas,
|
||||
});
|
||||
|
||||
export async function makeMigration() {
|
||||
if (process.env.NODE_ENV != "development") {
|
||||
const pool = new Pool({
|
||||
connectionString: process.env.DATABASE_URL!,
|
||||
});
|
||||
|
||||
const database = drizzle({client: pool});
|
||||
|
||||
console.log("Running migrations...");
|
||||
try {
|
||||
await migrate(database, {migrationsFolder: "./src/db/migrations"});
|
||||
console.log("Migrations applied successfully.");
|
||||
} catch (error) {
|
||||
console.error("Error applying migrations:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
export * from "./schema/00_setting";
|
||||
export { user, session, userRelations } from "./schema/01_user";
|
||||
export type { Organization } from "./schema/02_organization";
|
||||
export { organization, member as organizationMember, invitation as organizationInvitation } from "./schema/02_organization";
|
||||
export * from "./schema/03_project";
|
||||
export * from "./schema/04_agent";
|
||||
export * from "./schema/05_database";
|
||||
@@ -2,8 +2,10 @@ import { relations } from "drizzle-orm";
|
||||
import { boolean, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
|
||||
import { createSelectSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { project } from "./03_project";
|
||||
import { member, invitation, organization } from "./02_organization";
|
||||
import { project } from "./05_project";
|
||||
import {member} from "@/db/schema/03_member";
|
||||
import {invitation} from "@/db/schema/04_invitation";
|
||||
import {organization} from "@/db/schema/02_organization";
|
||||
|
||||
export const user = pgTable("user", {
|
||||
id: uuid("id").defaultRandom().primaryKey(),
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
|
||||
import { user } from "./01_user";
|
||||
import { relations } from "drizzle-orm";
|
||||
import { project } from "./03_project";
|
||||
import { project } from "./05_project";
|
||||
import { createSelectSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import {invitation} from "@/db/schema/04_invitation";
|
||||
import {member} from "@/db/schema/03_member";
|
||||
|
||||
export const organization = pgTable("organization", {
|
||||
id: uuid("id").defaultRandom().primaryKey(),
|
||||
@@ -15,32 +16,6 @@ export const organization = pgTable("organization", {
|
||||
metadata: text("metadata"),
|
||||
});
|
||||
|
||||
export const member = pgTable("member", {
|
||||
id: uuid("id").defaultRandom().primaryKey(),
|
||||
organizationId: uuid("organization_id")
|
||||
.notNull()
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
userId: uuid("user_id")
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: "cascade" }),
|
||||
role: text("role").notNull(),
|
||||
createdAt: timestamp("created_at").notNull().defaultNow(),
|
||||
updatedAt: timestamp("updated_at"),
|
||||
});
|
||||
|
||||
export const invitation = pgTable("invitation", {
|
||||
id: uuid("id").defaultRandom().primaryKey(),
|
||||
organizationId: uuid("organization_id")
|
||||
.notNull()
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
email: text("email").notNull(),
|
||||
role: text("role"),
|
||||
status: text("status").notNull(),
|
||||
expiresAt: timestamp("expires_at").notNull(),
|
||||
inviterId: uuid("inviter_id")
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const organizationRelations = relations(organization, ({ many }) => ({
|
||||
members: many(member),
|
||||
@@ -48,33 +23,8 @@ export const organizationRelations = relations(organization, ({ many }) => ({
|
||||
projects: many(project),
|
||||
}));
|
||||
|
||||
export const memberRelations = relations(member, ({ one }) => ({
|
||||
user: one(user, {
|
||||
fields: [member.userId],
|
||||
references: [user.id],
|
||||
}),
|
||||
organization: one(organization, {
|
||||
fields: [member.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const invitationRelations = relations(invitation, ({ one }) => ({
|
||||
organization: one(organization, {
|
||||
fields: [invitation.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
inviter: one(user, {
|
||||
fields: [invitation.inviterId],
|
||||
references: [user.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const organizationSchema = createSelectSchema(organization);
|
||||
export type Organization = z.infer<typeof organizationSchema>;
|
||||
|
||||
export const organizationMemberSchema = createSelectSchema(member);
|
||||
export type OrganizationMember = z.infer<typeof organizationMemberSchema>;
|
||||
|
||||
export const organizationInvitationSchema = createSelectSchema(invitation);
|
||||
export type OrganizationInvitation = z.infer<typeof organizationInvitationSchema>;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import {pgTable, text, timestamp, uuid} from "drizzle-orm/pg-core";
|
||||
import {user} from "@/db/schema/01_user";
|
||||
import {organization} from "@/db/schema/02_organization";
|
||||
import {relations} from "drizzle-orm";
|
||||
import {createSelectSchema} from "drizzle-zod";
|
||||
import {z} from "zod";
|
||||
|
||||
|
||||
export const member = pgTable("member", {
|
||||
id: uuid("id").defaultRandom().primaryKey(),
|
||||
organizationId: uuid("organization_id")
|
||||
.notNull()
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
userId: uuid("user_id")
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: "cascade" }),
|
||||
role: text("role").notNull(),
|
||||
createdAt: timestamp("created_at").notNull().defaultNow(),
|
||||
updatedAt: timestamp("updated_at"),
|
||||
});
|
||||
|
||||
export const memberRelations = relations(member, ({ one }) => ({
|
||||
user: one(user, {
|
||||
fields: [member.userId],
|
||||
references: [user.id],
|
||||
}),
|
||||
organization: one(organization, {
|
||||
fields: [member.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
|
||||
export const organizationMemberSchema = createSelectSchema(member);
|
||||
export type OrganizationMember = z.infer<typeof organizationMemberSchema>;
|
||||
@@ -0,0 +1,39 @@
|
||||
import {relations} from "drizzle-orm";
|
||||
import {user} from "@/db/schema/01_user";
|
||||
import {organization} from "@/db/schema/02_organization";
|
||||
import {createSelectSchema} from "drizzle-zod";
|
||||
import {z} from "zod";
|
||||
import {pgTable, text, timestamp, uuid} from "drizzle-orm/pg-core";
|
||||
|
||||
|
||||
export const invitation = pgTable("invitation", {
|
||||
id: uuid("id").defaultRandom().primaryKey(),
|
||||
organizationId: uuid("organization_id")
|
||||
.notNull()
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
email: text("email").notNull(),
|
||||
role: text("role"),
|
||||
status: text("status").notNull(),
|
||||
expiresAt: timestamp("expires_at").notNull(),
|
||||
inviterId: uuid("inviter_id")
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
|
||||
|
||||
export const invitationRelations = relations(invitation, ({ one }) => ({
|
||||
organization: one(organization, {
|
||||
fields: [invitation.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
inviter: one(user, {
|
||||
fields: [invitation.inviterId],
|
||||
references: [user.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
|
||||
|
||||
export const organizationInvitationSchema = createSelectSchema(invitation);
|
||||
export type OrganizationInvitation = z.infer<typeof organizationInvitationSchema>;
|
||||
@@ -3,7 +3,7 @@ import { relations } from "drizzle-orm";
|
||||
import { Organization, organization } from "./02_organization";
|
||||
import { createSelectSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
import { Database, database } from "./05_database";
|
||||
import { Database, database } from "./06_database";
|
||||
|
||||
export const project = pgTable("projects", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
@@ -1,6 +1,6 @@
|
||||
import { pgTable, text, boolean, timestamp, uuid, integer, pgEnum, uniqueIndex } from "drizzle-orm/pg-core";
|
||||
import { Agent, agent } from "./04_agent";
|
||||
import { Project, project } from "./03_project";
|
||||
import { Agent, agent } from "./07_agent";
|
||||
import { Project, project } from "./05_project";
|
||||
import { relations } from "drizzle-orm";
|
||||
import { dbmsEnum, statusEnum } from "./types";
|
||||
import { createSelectSchema } from "drizzle-zod";
|
||||
@@ -6,7 +6,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { MoreHorizontal } from "lucide-react";
|
||||
import { ReloadIcon } from "@radix-ui/react-icons";
|
||||
import { StatusBadge } from "@/components/wrappers/common/status-badge";
|
||||
import { Restoration } from "@/db/schema";
|
||||
import {Restoration} from "@/db/schema/06_database";
|
||||
|
||||
export const restoreColumns: ColumnDef<Restoration>[] = [
|
||||
{
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { userAction } from "@/safe-actions";
|
||||
import { z } from "zod";
|
||||
import { ServerActionResult } from "@/types/action-type";
|
||||
import { Backup, backup, Restoration, restoration } from "@/db/schema";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
import { db } from "@/db";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import {Backup, Restoration} from "@/db/schema/06_database";
|
||||
|
||||
export const deleteBackupAction = userAction
|
||||
.schema(
|
||||
@@ -15,14 +17,14 @@ export const deleteBackupAction = userAction
|
||||
.action(async ({ parsedInput }): Promise<ServerActionResult<Backup>> => {
|
||||
try {
|
||||
await db
|
||||
.delete(backup)
|
||||
.where(and(eq(backup.id, parsedInput.backupId), eq(backup.databaseId, parsedInput.databaseId)))
|
||||
.delete(drizzleDb.schemas.backup)
|
||||
.where(and(eq(drizzleDb.schemas.backup.id, parsedInput.backupId), eq(drizzleDb.schemas.backup.databaseId, parsedInput.databaseId)))
|
||||
.execute();
|
||||
|
||||
const backupExists = await db
|
||||
.select()
|
||||
.from(backup)
|
||||
.where(and(eq(backup.id, parsedInput.backupId), eq(backup.databaseId, parsedInput.databaseId)))
|
||||
.from(drizzleDb.schemas.backup)
|
||||
.where(and(eq(drizzleDb.schemas.backup.id, parsedInput.backupId), eq(drizzleDb.schemas.backup.databaseId, parsedInput.databaseId)))
|
||||
.execute();
|
||||
|
||||
if (backupExists.length === 0) {
|
||||
@@ -68,7 +70,7 @@ export const createRestorationAction = userAction
|
||||
try {
|
||||
// Insert new restoration into the database
|
||||
const restorationData = await db
|
||||
.insert(restoration)
|
||||
.insert(drizzleDb.schemas.restoration)
|
||||
.values({
|
||||
databaseId: parsedInput.databaseId,
|
||||
backupId: parsedInput.backupId,
|
||||
|
||||
@@ -9,9 +9,10 @@ import { checkMinioAlive, createPublicBucket, saveFileInBucket } from "@/utils/s
|
||||
//@ts-ignore
|
||||
import { UploadedObjectInfo } from "minio/src/internal/type";
|
||||
import { getServerUrl } from "@/utils/get-server-url";
|
||||
import { setting as drizzleSetting, Setting } from "@/db/schema";
|
||||
import { db } from "@/db";
|
||||
import { eq } from "drizzle-orm";
|
||||
import {Setting} from "@/db/schema/00_setting";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
export const uploadImageAction = userAction.schema(z.instanceof(FormData)).action(async ({ parsedInput: formData, ctx }) => {
|
||||
const file = formData.get("file") as File;
|
||||
@@ -21,8 +22,7 @@ export const uploadImageAction = userAction.schema(z.instanceof(FormData)).actio
|
||||
const arrayBuffer = await file.arrayBuffer();
|
||||
const buffer = Buffer.from(arrayBuffer);
|
||||
|
||||
const [settings] = await db.select().from(drizzleSetting).where(eq(drizzleSetting.name, "system")).limit(1);
|
||||
|
||||
const [settings] = await db.select().from(drizzleDb.schemas.setting).where(eq(drizzleDb.schemas.setting.name, "system")).limit(1);
|
||||
if (!settings) {
|
||||
throw new Error("System settings not found.");
|
||||
}
|
||||
|
||||
+108
-22
@@ -5,19 +5,14 @@ import {env} from "@/env.mjs";
|
||||
import {nextCookies} from "better-auth/next-js";
|
||||
import {admin as adminPlugin, openAPI, organization} from "better-auth/plugins";
|
||||
import {ac, admin, orgAdmin, orgMember, orgOwner, pending, superadmin, user} from "@/lib/auth/permissions";
|
||||
|
||||
import * as drizzleDb from "@/db";
|
||||
import {headers} from "next/headers";
|
||||
import {count, eq} from "drizzle-orm";
|
||||
import * as drizzleUser from "@/db/schema/01_user";
|
||||
import * as drizzleOrganization from "@/db/schema/02_organization";
|
||||
|
||||
export const auth = betterAuth({
|
||||
database: drizzleAdapter(db, {
|
||||
provider: "pg",
|
||||
schema: {
|
||||
...drizzleUser,
|
||||
...drizzleOrganization,
|
||||
},
|
||||
schema: drizzleDb.schemas,
|
||||
}),
|
||||
emailAndPassword: {
|
||||
enabled: true,
|
||||
@@ -51,7 +46,7 @@ export const auth = betterAuth({
|
||||
}),
|
||||
adminPlugin({
|
||||
adminRoles: ["admin", "superadmin"],
|
||||
defaultRole: (await db.select({ count: count() }).from(drizzleUser["user"]))[0].count === 0 ? "superadmin" : "pending",
|
||||
defaultRole: "pending",
|
||||
ac,
|
||||
roles: {
|
||||
admin,
|
||||
@@ -75,6 +70,67 @@ export const auth = betterAuth({
|
||||
},
|
||||
},
|
||||
},
|
||||
databaseHooks: {
|
||||
user: {
|
||||
create: {
|
||||
async before(user, context) {
|
||||
const userCount = (await db.select({count: count()}).from(drizzleDb.schemas.user))[0].count;
|
||||
const role = userCount === 0 ? "superadmin" : "pending";
|
||||
|
||||
return {
|
||||
data: {
|
||||
...user,
|
||||
role,
|
||||
},
|
||||
};
|
||||
},
|
||||
async after(user, context) {
|
||||
const userCount = (await db.select({count: count()}).from(drizzleDb.schemas.user))[0].count;
|
||||
|
||||
if (userCount === 1) {
|
||||
const defaultOrgSlug = "default"; // change this if your default org has a different slug
|
||||
const defaultOrg = await db.query.organization.findFirst({
|
||||
where: eq(drizzleDb.schemas.organization.slug, defaultOrgSlug),
|
||||
});
|
||||
|
||||
if (defaultOrg) {
|
||||
await db.insert(drizzleDb.schemas.member).values({
|
||||
userId: user.id,
|
||||
organizationId: defaultOrg.id,
|
||||
role: "orgOwner",
|
||||
});
|
||||
} else {
|
||||
console.warn("Default organization not found. Cannot assign member.");
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
session: {
|
||||
create: {
|
||||
before: async (session, context) => {
|
||||
const userId = session.userId;
|
||||
|
||||
const memberships = await db.query.member.findMany({
|
||||
where: eq(drizzleDb.schemas.member.userId, userId),
|
||||
});
|
||||
|
||||
if (!memberships.length) {
|
||||
// Fail the login attempt explicitly
|
||||
throw new Error("User is not part of any organization.");
|
||||
}
|
||||
|
||||
const firstOrgId = memberships[0].organizationId;
|
||||
|
||||
return {
|
||||
data: {
|
||||
activeOrganizationId: firstOrgId,
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
session: {
|
||||
additionalFields: {
|
||||
activeOrganizationId: {
|
||||
@@ -165,14 +221,15 @@ export const getSession = async () => {
|
||||
|
||||
export const revokeSession = async (e: string) => {
|
||||
try {
|
||||
const { status } = await auth.api.revokeSession({
|
||||
const {status} = await auth.api.revokeSession({
|
||||
body: {
|
||||
token: e,
|
||||
},
|
||||
headers: await headers(),
|
||||
});
|
||||
return status;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
}
|
||||
};
|
||||
|
||||
export const getAccounts = async () => {
|
||||
@@ -183,7 +240,7 @@ export const getAccounts = async () => {
|
||||
|
||||
export const unlinkAccount = async (provider: string, account: string) => {
|
||||
try {
|
||||
const { status } = await auth.api.unlinkAccount({
|
||||
const {status} = await auth.api.unlinkAccount({
|
||||
body: {
|
||||
providerId: provider,
|
||||
accountId: account,
|
||||
@@ -192,26 +249,53 @@ export const unlinkAccount = async (provider: string, account: string) => {
|
||||
});
|
||||
|
||||
return status;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// export const getOrganization = async ({
|
||||
// organizationId,
|
||||
// organizationSlug,
|
||||
// }: {
|
||||
// organizationId?: string;
|
||||
// organizationSlug?: string;
|
||||
// }) => {
|
||||
// const query = organizationId
|
||||
// ? {organizationId}
|
||||
// : {organizationSlug};
|
||||
//
|
||||
// console.log(query);
|
||||
//
|
||||
// try {
|
||||
// return await auth.api.getFullOrganization({
|
||||
// headers: await headers(),
|
||||
// // query,
|
||||
// });
|
||||
// } catch (e) {
|
||||
// console.error(e);
|
||||
// return null;
|
||||
// }
|
||||
// };
|
||||
export const getOrganization = async ({
|
||||
organizationId,
|
||||
organizationSlug,
|
||||
}: {
|
||||
organizationId?: string;
|
||||
organizationSlug?: string;
|
||||
}) => {
|
||||
const query = organizationId
|
||||
? { organizationId }
|
||||
: { organizationSlug };
|
||||
} = {}) => {
|
||||
const query =
|
||||
organizationId != null
|
||||
? { organizationId }
|
||||
: organizationSlug != null
|
||||
? { organizationSlug }
|
||||
: undefined;
|
||||
|
||||
console.log(query);
|
||||
|
||||
try {
|
||||
return await auth.api.getFullOrganization({
|
||||
headers: await headers(),
|
||||
query,
|
||||
...(query ? { query } : {}),
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
@@ -224,13 +308,14 @@ export const listOrganizations = async () => {
|
||||
return await auth.api.listOrganizations({
|
||||
headers: await headers(),
|
||||
});
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
}
|
||||
};
|
||||
|
||||
export const getLastOrganizationOrFirst = async (userId: string) => {
|
||||
try {
|
||||
const organizations = await db.query.organizationMember.findMany({
|
||||
where: eq(drizzleOrganization.member.userId, userId),
|
||||
const organizations = await db.query.organization.findMany({
|
||||
where: eq(drizzleDb.schemas.member.userId, userId),
|
||||
});
|
||||
|
||||
if (organizations.length > 0) {
|
||||
@@ -260,7 +345,7 @@ export const createOrganization = async (name: string, slug: string) => {
|
||||
|
||||
export const checkSlugOrganization = async (slug: string) => {
|
||||
try {
|
||||
const { status } = await auth.api.checkOrganizationSlug({
|
||||
const {status} = await auth.api.checkOrganizationSlug({
|
||||
headers: await headers(),
|
||||
body: {
|
||||
slug,
|
||||
@@ -278,6 +363,7 @@ export const getActiveMember = async () => {
|
||||
const member = await auth.api.getActiveMember({
|
||||
headers: await headers(),
|
||||
});
|
||||
console.log(member);
|
||||
|
||||
return member;
|
||||
} catch (e) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"use server";
|
||||
|
||||
import { db } from "@/db";
|
||||
import { setting as drizzleSetting } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import nodemailer from "nodemailer";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
type Payload = {
|
||||
to: string;
|
||||
@@ -33,8 +33,8 @@ type EmailMassProps = {
|
||||
export const sendEmail = async (data: Payload) => {
|
||||
const settings = await db
|
||||
.select()
|
||||
.from(drizzleSetting)
|
||||
.where(eq(drizzleSetting.name, "system"))
|
||||
.from(drizzleDb.schemas.setting)
|
||||
.where(eq(drizzleDb.schemas.setting.name, "system"))
|
||||
.then((res) => res[0]);
|
||||
|
||||
if (!settings) {
|
||||
|
||||
+7
-6
@@ -1,7 +1,8 @@
|
||||
import { env } from "@/env.mjs";
|
||||
import { db } from "@/db";
|
||||
import { setting, organization } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import * as drizzleDb from "@/db";
|
||||
|
||||
|
||||
export function init() {
|
||||
consoleAscii();
|
||||
@@ -32,14 +33,14 @@ async function createSettingsIfNotExist() {
|
||||
S3BucketName: env.S3_BUCKET_NAME ?? null,
|
||||
};
|
||||
|
||||
const [existing] = await db.select().from(setting).where(eq(setting.name, "system")).limit(1);
|
||||
const [existing] = await db.select().from(drizzleDb.schemas.setting).where(eq(drizzleDb.schemas.setting.name, "system")).limit(1);
|
||||
|
||||
if (!existing) {
|
||||
console.log("====Init Setting : Create ====");
|
||||
await db.insert(setting).values(configSettings);
|
||||
await db.insert(drizzleDb.schemas.setting).values(configSettings);
|
||||
} else {
|
||||
console.log("====Init Setting : Update ====");
|
||||
await db.update(setting).set(configSettings).where(eq(setting.name, "system"));
|
||||
await db.update(drizzleDb.schemas.setting).set(configSettings).where(eq(drizzleDb.schemas.setting.name, "system"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,11 +51,11 @@ async function createDefaultOrganization() {
|
||||
createdAt: new Date(),
|
||||
};
|
||||
|
||||
const [existing] = await db.select().from(organization).where(eq(organization.slug, "default")).limit(1);
|
||||
const [existing] = await db.select().from(drizzleDb.schemas.organization).where(eq(drizzleDb.schemas.organization.slug, "default")).limit(1);
|
||||
|
||||
if (!existing) {
|
||||
console.log("==== Creating default Organization... ====\n");
|
||||
await db.insert(organization).values(defaultOrganizationConf);
|
||||
await db.insert(drizzleDb.schemas.organization).values(defaultOrganizationConf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as Minio from "minio";
|
||||
import { env } from "@/env.mjs";
|
||||
import {env} from "@/env.mjs";
|
||||
import internal from "node:stream";
|
||||
import { db } from "@/db";
|
||||
import { setting as drizzleSetting } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import {db} from "@/db";
|
||||
import * as drizzleDb from "@/db";
|
||||
import {eq} from "drizzle-orm";
|
||||
|
||||
// const settings = await prisma.settings.findUnique({
|
||||
// where:{
|
||||
@@ -40,8 +40,8 @@ import { eq } from "drizzle-orm";
|
||||
async function getS3Client() {
|
||||
const settings = await db
|
||||
.select()
|
||||
.from(drizzleSetting)
|
||||
.where(eq(drizzleSetting.name, "system"))
|
||||
.from(drizzleDb.schemas.setting)
|
||||
.where(eq(drizzleDb.schemas.setting.name, "system"))
|
||||
.then((res) => res[0]);
|
||||
|
||||
if (!settings) {
|
||||
@@ -57,13 +57,13 @@ async function getS3Client() {
|
||||
const s3Client =
|
||||
env.NODE_ENV === "production"
|
||||
? new Minio.Client({
|
||||
...baseConfig,
|
||||
})
|
||||
...baseConfig,
|
||||
})
|
||||
: new Minio.Client({
|
||||
...baseConfig,
|
||||
port: Number(env.S3_PORT ?? 0),
|
||||
useSSL: env.S3_USE_SSL === "true",
|
||||
});
|
||||
...baseConfig,
|
||||
port: Number(env.S3_PORT ?? 0),
|
||||
useSSL: env.S3_USE_SSL === "true",
|
||||
});
|
||||
|
||||
return s3Client;
|
||||
}
|
||||
@@ -75,10 +75,10 @@ export async function checkMinioAlive() {
|
||||
// Try to list buckets to check connectivity
|
||||
const buckets = await s3Client.listBuckets();
|
||||
console.log("MinIO is up and running. Buckets:", buckets);
|
||||
return { message: true };
|
||||
return {message: true};
|
||||
} catch (error) {
|
||||
console.error("Error connecting to MinIO:", error);
|
||||
return { error: error };
|
||||
return {error: error};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,11 @@ export async function createBucketIfNotExists(bucketName: string) {
|
||||
* @param fileName name of the file
|
||||
* @param file file to save
|
||||
*/
|
||||
export async function saveFileInBucket({ bucketName, fileName, file }: { bucketName: string; fileName: string; file: Buffer | internal.Readable }) {
|
||||
export async function saveFileInBucket({bucketName, fileName, file}: {
|
||||
bucketName: string;
|
||||
fileName: string;
|
||||
file: Buffer | internal.Readable
|
||||
}) {
|
||||
// Check if Minio is Alive
|
||||
await checkMinioAlive();
|
||||
// Create bucket if it doesn't exist
|
||||
@@ -128,7 +132,7 @@ export async function saveFileInBucket({ bucketName, fileName, file }: { bucketN
|
||||
* @param fileName name of the file
|
||||
* @returns true if file exists, false if not
|
||||
*/
|
||||
export async function checkFileExistsInBucket({ bucketName, fileName }: { bucketName: string; fileName: string }) {
|
||||
export async function checkFileExistsInBucket({bucketName, fileName}: { bucketName: string; fileName: string }) {
|
||||
const s3Client = await getS3Client();
|
||||
|
||||
try {
|
||||
@@ -145,10 +149,10 @@ export async function checkFileExistsInBucket({ bucketName, fileName }: { bucket
|
||||
* @returns promise with array of presigned urls
|
||||
*/
|
||||
export async function createPresignedUrlToUpload({
|
||||
bucketName,
|
||||
fileName,
|
||||
expiry = 60 * 60, // 1 hour
|
||||
}: {
|
||||
bucketName,
|
||||
fileName,
|
||||
expiry = 60 * 60, // 1 hour
|
||||
}: {
|
||||
bucketName: string;
|
||||
fileName: string;
|
||||
expiry?: number;
|
||||
@@ -161,7 +165,7 @@ export async function createPresignedUrlToUpload({
|
||||
}
|
||||
|
||||
// Function to create a bucket and make it public
|
||||
export async function createPublicBucket({ bucketName }: { bucketName: string }) {
|
||||
export async function createPublicBucket({bucketName}: { bucketName: string }) {
|
||||
const s3Client = await getS3Client();
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user