mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
Starting working on settings Page.
This commit is contained in:
@@ -6,13 +6,13 @@ import {prisma} from "@/prisma";
|
|||||||
export default async function Layout({children}: { children: React.ReactNode }) {
|
export default async function Layout({children}: { children: React.ReactNode }) {
|
||||||
|
|
||||||
const user = await currentUser()
|
const user = await currentUser()
|
||||||
const userInfo = await prisma.user.findUnique({
|
// const userInfo = await prisma.user.findUnique({
|
||||||
where: {
|
// where: {
|
||||||
email: user.email
|
// email: user?.email
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
|
//
|
||||||
if(userInfo){
|
if(user){
|
||||||
redirect('/dashboard')
|
redirect('/dashboard')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,24 @@
|
|||||||
import {PageParams} from "@/types/next";
|
import {PageParams} from "@/types/next";
|
||||||
import {Page, PageContent, PageHeader, PageTitle} from "@/features/layout/page";
|
import {Page, PageContent, PageDescription, PageHeader, PageTitle} from "@/features/layout/page";
|
||||||
|
import {prisma} from "@/prisma";
|
||||||
|
import {requiredCurrentUser} from "@/auth/current-user";
|
||||||
|
import {DataTableWithPagination} from "@/components/wrappers/table/data-table-with-pagination";
|
||||||
|
import {usersColumns} from "@/components/wrappers/Dashboard/Settings/SettingsTabs/columns-users";
|
||||||
|
import {SettingsTabs} from "@/components/wrappers/Dashboard/Settings/SettingsTabs/SettingsTabs";
|
||||||
|
|
||||||
|
|
||||||
export default async function RoutePage(props: PageParams<{}>) {
|
export default async function RoutePage(props: PageParams<{}>) {
|
||||||
|
const user = await requiredCurrentUser()
|
||||||
|
|
||||||
|
|
||||||
|
const users = await prisma.user.findMany({
|
||||||
|
where:{
|
||||||
|
id: {
|
||||||
|
not: user.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
@@ -11,8 +27,11 @@ export default async function RoutePage(props: PageParams<{}>) {
|
|||||||
Settings
|
Settings
|
||||||
</PageTitle>
|
</PageTitle>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
|
<PageDescription>
|
||||||
|
Manage your Portabase settings
|
||||||
|
</PageDescription>
|
||||||
<PageContent>
|
<PageContent>
|
||||||
content
|
<SettingsTabs users={users}/>
|
||||||
</PageContent>
|
</PageContent>
|
||||||
</Page>
|
</Page>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Settings" ADD COLUMN "s3EndPointUrl" TEXT;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Settings" ADD COLUMN "smtpFrom" TEXT,
|
||||||
|
ADD COLUMN "smtpHost" TEXT,
|
||||||
|
ADD COLUMN "smtpPassword" TEXT,
|
||||||
|
ADD COLUMN "smtpPort" TEXT,
|
||||||
|
ADD COLUMN "smtpUser" TEXT;
|
||||||
@@ -135,7 +135,13 @@ enum TypeStorage {
|
|||||||
model Settings {
|
model Settings {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
storage TypeStorage @default(local)
|
storage TypeStorage @default(local)
|
||||||
|
s3EndPointUrl String?
|
||||||
s3AccessKeyId String?
|
s3AccessKeyId String?
|
||||||
s3SecretAccessKey String?
|
s3SecretAccessKey String?
|
||||||
S3BucketName String?
|
S3BucketName String?
|
||||||
|
smtpPassword String?
|
||||||
|
smtpFrom String?
|
||||||
|
smtpHost String?
|
||||||
|
smtpPort String?
|
||||||
|
smtpUser String?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
"use client"
|
||||||
|
import {Tabs, TabsContent, TabsList, TabsTrigger} from "@/components/ui/tabs";
|
||||||
|
import {DataTableWithPagination} from "@/components/wrappers/table/data-table-with-pagination";
|
||||||
|
import {usersColumns} from "@/components/wrappers/Dashboard/Settings/SettingsTabs/columns-users";
|
||||||
|
import {User} from "@prisma/client";
|
||||||
|
import {backupColumns} from "@/features/backup/columns";
|
||||||
|
|
||||||
|
|
||||||
|
export type SettingsTabsProps = {
|
||||||
|
users: User[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SettingsTabs = (props: SettingsTabsProps) => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return(
|
||||||
|
<Tabs defaultValue="informations" >
|
||||||
|
<TabsList className="w-full" >
|
||||||
|
<TabsTrigger className="w-full" value="informations">Informations</TabsTrigger>
|
||||||
|
<TabsTrigger className="w-full" value="users">Users</TabsTrigger>
|
||||||
|
<TabsTrigger className="w-full" value="email">Email</TabsTrigger>
|
||||||
|
<TabsTrigger className="w-full" value="storage">Storage</TabsTrigger>
|
||||||
|
</TabsList>
|
||||||
|
<TabsContent value="informations">
|
||||||
|
ok
|
||||||
|
</TabsContent>
|
||||||
|
<TabsContent value="users" className="h-full justify-between">
|
||||||
|
<DataTableWithPagination columns={usersColumns} data={props.users}/>
|
||||||
|
</TabsContent>
|
||||||
|
<TabsContent value="email">Change your password here.</TabsContent>
|
||||||
|
<TabsContent value="storage">Change your password here.</TabsContent>
|
||||||
|
</Tabs>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import {ColumnDef} from "@tanstack/react-table"
|
||||||
|
import {Badge} from "@/components/ui/badge";
|
||||||
|
import {User} from "@prisma/client";
|
||||||
|
|
||||||
|
export const usersColumns: ColumnDef<User>[] = [
|
||||||
|
{
|
||||||
|
accessorKey: "id",
|
||||||
|
header: "Id",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "name",
|
||||||
|
header: "Name"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "email",
|
||||||
|
header: "Email"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "createdAt",
|
||||||
|
header: "Created At",
|
||||||
|
cell: ({row}) => {
|
||||||
|
return new Date(row.getValue("createdAt")).toLocaleString("fr-FR");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "authMethod",
|
||||||
|
header: "Method",
|
||||||
|
cell: ({row}) => {
|
||||||
|
return <Badge variant="outline">{row.getValue("authMethod")}</Badge>
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -3,14 +3,16 @@ import {SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem} from
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import {cn} from "@/lib/utils";
|
import {cn} from "@/lib/utils";
|
||||||
import {buttonVariants} from "@/components/ui/button";
|
import {buttonVariants} from "@/components/ui/button";
|
||||||
import {PropsWithChildren, useState} from "react";
|
import {PropsWithChildren, useEffect, useState} from "react";
|
||||||
import {ChartArea, Home, Settings, ShieldHalf} from "lucide-react";
|
import {ChartArea, Home, Settings, ShieldHalf} from "lucide-react";
|
||||||
|
import {usePathname} from "next/navigation";
|
||||||
|
|
||||||
export type SidebarMenuCustomProps = {}
|
export type SidebarMenuCustomProps = {}
|
||||||
|
|
||||||
export const SidebarMenuCustom = (props: SidebarMenuCustomProps) => {
|
export const SidebarMenuCustom = (props: SidebarMenuCustomProps) => {
|
||||||
|
|
||||||
const BASE_URL = "/dashboard";
|
const BASE_URL = "/dashboard";
|
||||||
|
const pathname = usePathname();
|
||||||
// Menu items.
|
// Menu items.
|
||||||
const items = [
|
const items = [
|
||||||
{
|
{
|
||||||
@@ -35,6 +37,14 @@ export const SidebarMenuCustom = (props: SidebarMenuCustomProps) => {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const currentUrl = pathname;
|
||||||
|
const currentItem = items.find((item) => `${BASE_URL}/${item.url}` === currentUrl);
|
||||||
|
if (currentItem) {
|
||||||
|
setActiveItem(currentItem.title);
|
||||||
|
}
|
||||||
|
}, [pathname]);
|
||||||
|
|
||||||
const [activeItem, setActiveItem] = useState(items[0].title);
|
const [activeItem, setActiveItem] = useState(items[0].title);
|
||||||
const handleItemClick = (title: string) => {
|
const handleItemClick = (title: string) => {
|
||||||
setActiveItem(title);
|
setActiveItem(title);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export function DataTableWithPagination<TData, TValue>({columns, data}: DataTabl
|
|||||||
const [sorting, setSorting] = useState<SortingState>([])
|
const [sorting, setSorting] = useState<SortingState>([])
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data,
|
data: data,
|
||||||
columns,
|
columns,
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
getPaginationRowModel: getPaginationRowModel(),
|
getPaginationRowModel: getPaginationRowModel(),
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ export type dataTableProps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const DataTable = ({table}: dataTableProps) => {
|
export const DataTable = ({table}: dataTableProps) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
@@ -43,7 +42,7 @@ export const DataTable = ({table}: dataTableProps) => {
|
|||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={table.columns.length} className="h-24 text-center">
|
<TableCell colSpan={table.getAllColumns().length} className="h-24 text-center">
|
||||||
No results.
|
No results.
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const PageTitle = twx.h1((props) => [
|
|||||||
|
|
||||||
|
|
||||||
export const PageDescription = twx.h2((props) => [
|
export const PageDescription = twx.h2((props) => [
|
||||||
cn(`text-s mb-6 text-gray-700`, props.className),
|
cn(`text-s mb-6 `, props.className),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user