Working on settings Page. Adding init function on next.js startup.

This commit is contained in:
charles-gauthereau
2024-11-16 22:00:22 +01:00
parent b8218dcf85
commit b9a56188ae
16 changed files with 382 additions and 26 deletions
@@ -0,0 +1,66 @@
"use client";
import {Card, CardContent} from "@/components/ui/card";
import {
FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useZodForm
} from "@/components/ui/form";
import {Input} from "@/components/ui/input";
import {Form} from "@/components/ui/form"
import {Button} from "@/components/ui/button";
import {useMutation} from "@tanstack/react-query";
import {TooltipProvider} from "@/components/ui/tooltip";
import {
EmailFormSchema,
EmailFormType
} from "@/components/wrappers/Dashboard/Settings/SettingsEmailTab/EmailForm/email-form.schema";
export type EmailFormProps = {
defaultValues?: EmailFormType;
}
export const EmailForm = (props: EmailFormProps) => {
const form = useZodForm({
schema: EmailFormSchema,
});
const mutation = useMutation({
mutationFn: async (values: EmailFormType) => {
}
})
return (
<TooltipProvider>
<Card>
<CardContent>
<Form form={form}
className="flex flex-col gap-4 mt-3"
onSubmit={async (values) => {
await mutation.mutateAsync(values);
}}
>
<FormField
control={form.control}
name="smtpFrom"
render={({field}) => (
<FormItem>
<FormLabel>From Email *</FormLabel>
<FormControl>
<Input
placeholder={"exemple@portabase.com"} {...field} />
</FormControl>
<FormDescription>{"The email from where the email will be send"}</FormDescription>
<FormMessage/>
</FormItem>
)}
/>
<Button>
Save
</Button>
</Form>
</CardContent>
</Card>
</TooltipProvider>
)
}
@@ -0,0 +1,11 @@
import {z} from "zod";
export const EmailFormSchema = z.object({
smtpPassword: z.string(),
smtpFrom: z.string(),
smtpHost: z.string(),
smtpPort: z.string(),
smtpUser: z.string(),
});
export type EmailFormType = z.infer<typeof EmailFormSchema>;
@@ -0,0 +1,12 @@
import {EmailForm} from "@/components/wrappers/Dashboard/Settings/SettingsEmailTab/EmailForm/EmailForm";
export type SettingsEmailTabProps = {}
export const SettingsEmailTab = (props:SettingsEmailTabProps) => {
return(
<div>
<EmailForm/>
</div>
)
}
@@ -0,0 +1,49 @@
import {Alert, AlertDescription, AlertTitle} from "@/components/ui/alert";
import {Info} from "lucide-react";
import {Switch} from "@/components/ui/switch";
import {Label} from "@/components/ui/label";
import {StorageS3Form} from "@/components/wrappers/Dashboard/Settings/SettingsStorageTab/StorageS3Form/StorageS3Form";
import {useState} from "react";
import {Settings} from "@prisma/client";
export type SettingsStorageTabProps = {
settings: Settings
}
export const SettingsStorageTab = (props: SettingsStorageTabProps) => {
const [isSwitched, setIsSwitched] = useState<boolean>(props.settings.storage !== "local");
return (
<div className="flex flex-col h-full py-4">
<h1>Settings for Portabase storage</h1>
<Alert className="mt-3">
<Info className="h-4 w-4"/>
<AlertTitle>Informations</AlertTitle>
<AlertDescription>
Actually you can only store you data in one place : s3 compatible or in local.
For exemple you cannot choose to store images in one place and .dump files in another.
</AlertDescription>
</Alert>
<div className="flex flex-col h-full py-4 ">
<div className="flex items-center space-x-2">
<Label htmlFor="storage-mode">Storage Mode (Local/s3 compatible)</Label>
<Switch
checked={isSwitched}
onCheckedChange={() => {
setIsSwitched(!isSwitched);
}}
id="storage-mode"/>
</div>
{isSwitched && (
<div className="mt-5">
<StorageS3Form/>
</div>
)}
</div>
</div>
)
}
@@ -0,0 +1,110 @@
"use client";
import {Card, CardContent} from "@/components/ui/card";
import {
FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useZodForm
} from "@/components/ui/form";
import {Input} from "@/components/ui/input";
import {Form} from "@/components/ui/form"
import {Button} from "@/components/ui/button";
import {useMutation} from "@tanstack/react-query";
import {TooltipProvider} from "@/components/ui/tooltip";
import {
S3FormSchema,
S3FormType
} from "@/components/wrappers/Dashboard/Settings/SettingsStorageTab/StorageS3Form/s3-form.schema";
export type S3FormProps = {
defaultValues?: S3FormType;
}
export const StorageS3Form = (props: S3FormProps) => {
const form = useZodForm({
schema: S3FormSchema,
});
const mutation = useMutation({
mutationFn: async (values: S3FormType) => {
}
})
return (
<TooltipProvider>
<Card>
<CardContent>
<Form form={form}
className="flex flex-col gap-4 mt-3"
onSubmit={async (values) => {
await mutation.mutateAsync(values);
}}
>
<FormField
control={form.control}
name="s3EndPointUrl"
render={({field}) => (
<FormItem>
<FormLabel>Endpoint Url *</FormLabel>
<FormControl>
<Input
placeholder={"s3.eu-west-3.amazonaws.com"} {...field} />
</FormControl>
<FormDescription>{"Your s3 compatible url"}</FormDescription>
<FormMessage/>
</FormItem>
)}
/>
<FormField
control={form.control}
name="s3AccessKeyId"
render={({field}) => (
<FormItem>
<FormLabel>Access Key *</FormLabel>
<FormControl>
<Input
placeholder={"The access key token"} {...field} />
</FormControl>
<FormDescription>{"Add your access key"}</FormDescription>
<FormMessage/>
</FormItem>
)}
/>
<FormField
control={form.control}
name="s3SecretAccessKey"
render={({field}) => (
<FormItem>
<FormLabel>Secret Key *</FormLabel>
<FormControl>
<Input
placeholder={"The secret key token"} {...field} />
</FormControl>
<FormDescription>{"Add your secret key"}</FormDescription>
<FormMessage/>
</FormItem>
)}
/>
<FormField
control={form.control}
name="S3BucketName"
render={({field}) => (
<FormItem>
<FormLabel>Bucket name *</FormLabel>
<FormControl>
<Input
placeholder={"my-bucket"} {...field} />
</FormControl>
<FormDescription>{"The bucket name where you want to store your data"}</FormDescription>
<FormMessage/>
</FormItem>
)}
/>
<Button>
Save
</Button>
</Form>
</CardContent>
</Card>
</TooltipProvider>
)
}
@@ -0,0 +1,10 @@
import {z} from "zod";
export const S3FormSchema = z.object({
s3EndPointUrl: z.string(),
s3AccessKeyId: z.string(),
s3SecretAccessKey: z.string(),
S3BucketName: z.string(),
});
export type S3FormType = z.infer<typeof S3FormSchema>;
@@ -2,19 +2,19 @@
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 {User, Settings} from "@prisma/client";
import {backupColumns} from "@/features/backup/columns";
import {SettingsEmailTab} from "@/components/wrappers/Dashboard/Settings/SettingsEmailTab/SettingsEmailTab";
import {SettingsStorageTab} from "@/components/wrappers/Dashboard/Settings/SettingsStorageTab/SettingsStorageTab";
export type SettingsTabsProps = {
users: User[];
settings: Settings;
}
export const SettingsTabs = (props: SettingsTabsProps) => {
return(
<Tabs defaultValue="informations" >
<TabsList className="w-full" >
@@ -24,13 +24,24 @@ export const SettingsTabs = (props: SettingsTabsProps) => {
<TabsTrigger className="w-full" value="storage">Storage</TabsTrigger>
</TabsList>
<TabsContent value="informations">
ok
<div className="flex flex-1 flex-col gap-4 py-4">
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
<div className="aspect-video rounded-xl bg-muted/50"/>
<div className="aspect-video rounded-xl bg-muted/50"/>
<div className="aspect-video rounded-xl bg-muted/50"/>
</div>
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min"/>
</div>
</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>
<TabsContent value="email">
<SettingsEmailTab/>
</TabsContent>
<TabsContent value="storage">
<SettingsStorageTab settings={props.settings}/>
</TabsContent>
</Tabs>
)
}