Add notification settings with SMTP, Telegram, and Discord options in Settings component

This commit is contained in:
headlessdev 2025-04-17 14:02:54 +02:00
parent cecc5e0bab
commit 2fd8e50f7f
4 changed files with 128 additions and 19 deletions

View File

@ -46,6 +46,8 @@ import {
AlertDialogTitle, AlertDialogTitle,
AlertDialogTrigger, AlertDialogTrigger,
} from "@/components/ui/alert-dialog" } from "@/components/ui/alert-dialog"
import { Label } from "@/components/ui/label";
import { Checkbox } from "@/components/ui/checkbox";
export default function Settings() { export default function Settings() {
const { theme, setTheme } = useTheme(); const { theme, setTheme } = useTheme();
@ -63,6 +65,8 @@ export default function Settings() {
const [passwordSuccess, setPasswordSuccess] = useState<boolean>(false) const [passwordSuccess, setPasswordSuccess] = useState<boolean>(false)
const [emailSuccess, setEmailSuccess] = useState<boolean>(false) const [emailSuccess, setEmailSuccess] = useState<boolean>(false)
const [notificationType, setNotificationType] = useState<string>("")
const changeEmail = async () => { const changeEmail = async () => {
setEmailErrorVisible(false); setEmailErrorVisible(false);
setEmailSuccess(false); setEmailSuccess(false);
@ -324,7 +328,7 @@ export default function Settings() {
<AlertDialogContent> <AlertDialogContent>
<AlertDialogTitle>Add Notification</AlertDialogTitle> <AlertDialogTitle>Add Notification</AlertDialogTitle>
<AlertDialogDescription> <AlertDialogDescription>
<Select> <Select value={notificationType} onValueChange={(value: string) => setNotificationType(value)}>
<SelectTrigger className="w-full"> <SelectTrigger className="w-full">
<SelectValue placeholder="Notification Type" /> <SelectValue placeholder="Notification Type" />
</SelectTrigger> </SelectTrigger>
@ -333,11 +337,67 @@ export default function Settings() {
<SelectItem value="telegram">Telegram</SelectItem> <SelectItem value="telegram">Telegram</SelectItem>
<SelectItem value="discord">Discord</SelectItem> <SelectItem value="discord">Discord</SelectItem>
</SelectContent> </SelectContent>
{notificationType === "smtp" && (
<div className="mt-4 space-y-2">
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="smtpHost">SMTP Host</Label>
<Input type="text" id="smtpHost" placeholder="e.g. smtp.example.com" />
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="smtpPort">SMTP Port</Label>
<Input type="number" id="smtpPort" placeholder="e.g. 456" />
</div>
<div className="flex gap-2">
<Checkbox id="smtpSecure" className="w-4 h-4" />
<Label htmlFor="smtpSecure">Secure Connection</Label>
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="smtpUser">SMTP Username</Label>
<Input type="text" id="smtpUser" placeholder="e.g. email_admin" />
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="smtpPass">SMTP Password</Label>
<Input type="password" id="smtpPass" placeholder="* * * * * * * *" />
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="smtpFrom">SMTP From</Label>
<Input type="email" id="smtpFrom" placeholder="e.g. admin@example.com" />
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="smtpTo">SMTP To</Label>
<Input type="email" id="smtpTo" placeholder="e.g. private@example.com" />
</div>
</div>
)}
{notificationType === "telegram" && (
<div className="mt-4 space-y-2">
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="telegramToken">Bot Token</Label>
<Input type="text" id="telegramToken" placeholder="" />
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="telegramChatId">Chat ID</Label>
<Input type="text" id="telegramChatId" placeholder="" />
</div>
</div>
)}
{notificationType === "discord" && (
<div className="mt-4">
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="discordWebhook">Webhook URL</Label>
<Input type="text" id="discordWebhook" placeholder="" />
</div>
</div>
)}
</Select> </Select>
</AlertDialogDescription> </AlertDialogDescription>
<AlertDialogFooter> <AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel> <AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction>Continue</AlertDialogAction> <AlertDialogAction>Add</AlertDialogAction>
</AlertDialogFooter> </AlertDialogFooter>
</AlertDialogContent> </AlertDialogContent>
</AlertDialog> </AlertDialog>

View File

@ -0,0 +1,32 @@
"use client"
import * as React from "react"
import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
import { CheckIcon } from "lucide-react"
import { cn } from "@/lib/utils"
function Checkbox({
className,
...props
}: React.ComponentProps<typeof CheckboxPrimitive.Root>) {
return (
<CheckboxPrimitive.Root
data-slot="checkbox"
className={cn(
"peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
>
<CheckboxPrimitive.Indicator
data-slot="checkbox-indicator"
className="flex items-center justify-center text-current transition-none"
>
<CheckIcon className="size-3.5" />
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root>
)
}
export { Checkbox }

50
package-lock.json generated
View File

@ -1,17 +1,18 @@
{ {
"name": "corecontrol", "name": "corecontrol",
"version": "0.0.4", "version": "0.0.5",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "corecontrol", "name": "corecontrol",
"version": "0.0.4", "version": "0.0.5",
"dependencies": { "dependencies": {
"@prisma/client": "^6.6.0", "@prisma/client": "^6.6.0",
"@prisma/extension-accelerate": "^1.3.0", "@prisma/extension-accelerate": "^1.3.0",
"@radix-ui/react-accordion": "^1.2.4", "@radix-ui/react-accordion": "^1.2.4",
"@radix-ui/react-alert-dialog": "^1.1.7", "@radix-ui/react-alert-dialog": "^1.1.7",
"@radix-ui/react-checkbox": "^1.1.5",
"@radix-ui/react-dialog": "^1.1.7", "@radix-ui/react-dialog": "^1.1.7",
"@radix-ui/react-dropdown-menu": "^2.1.7", "@radix-ui/react-dropdown-menu": "^2.1.7",
"@radix-ui/react-label": "^2.1.3", "@radix-ui/react-label": "^2.1.3",
@ -1240,6 +1241,36 @@
} }
} }
}, },
"node_modules/@radix-ui/react-checkbox": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.5.tgz",
"integrity": "sha512-B0gYIVxl77KYDR25AY9EGe/G//ef85RVBIxQvK+m5pxAC7XihAc/8leMHhDvjvhDu02SBSb6BuytlWr/G7F3+g==",
"license": "MIT",
"dependencies": {
"@radix-ui/primitive": "1.1.2",
"@radix-ui/react-compose-refs": "1.1.2",
"@radix-ui/react-context": "1.1.2",
"@radix-ui/react-presence": "1.1.3",
"@radix-ui/react-primitive": "2.0.3",
"@radix-ui/react-use-controllable-state": "1.1.1",
"@radix-ui/react-use-previous": "1.1.1",
"@radix-ui/react-use-size": "1.1.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-collapsible": { "node_modules/@radix-ui/react-collapsible": {
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.4.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.4.tgz",
@ -4545,21 +4576,6 @@
"optional": true "optional": true
} }
} }
},
"node_modules/@next/swc-win32-x64-msvc": {
"version": "15.3.0",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.3.0.tgz",
"integrity": "sha512-vHUQS4YVGJPmpjn7r5lEZuMhK5UQBNBRSB+iGDvJjaNk649pTIcRluDWNb9siunyLLiu/LDPHfvxBtNamyuLTw==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
} }
} }
} }

View File

@ -13,6 +13,7 @@
"@prisma/extension-accelerate": "^1.3.0", "@prisma/extension-accelerate": "^1.3.0",
"@radix-ui/react-accordion": "^1.2.4", "@radix-ui/react-accordion": "^1.2.4",
"@radix-ui/react-alert-dialog": "^1.1.7", "@radix-ui/react-alert-dialog": "^1.1.7",
"@radix-ui/react-checkbox": "^1.1.5",
"@radix-ui/react-dialog": "^1.1.7", "@radix-ui/react-dialog": "^1.1.7",
"@radix-ui/react-dropdown-menu": "^2.1.7", "@radix-ui/react-dropdown-menu": "^2.1.7",
"@radix-ui/react-label": "^2.1.3", "@radix-ui/react-label": "^2.1.3",