157 lines
4.4 KiB
TypeScript
157 lines
4.4 KiB
TypeScript
"use client"
|
|
|
|
import { useState } from "react"
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from "@/components/ui/dialog"
|
|
import { Button } from "@/components/ui/button"
|
|
import { Label } from "@/components/ui/label"
|
|
import { Input } from "@/components/ui/input"
|
|
import { Textarea } from "@/components/ui/textarea"
|
|
import { Switch } from "@/components/ui/switch"
|
|
import { createUser } from "@/app/protected/(admin)/dashboard/user-management/action"
|
|
import { toast } from "sonner"
|
|
|
|
|
|
interface AddUserDialogProps {
|
|
open: boolean
|
|
onOpenChange: (open: boolean) => void
|
|
onUserAdded: () => void
|
|
}
|
|
|
|
export function AddUserDialog({ open, onOpenChange, onUserAdded }: AddUserDialogProps) {
|
|
const [loading, setLoading] = useState(false)
|
|
const [formData, setFormData] = useState({
|
|
email: "",
|
|
password: "",
|
|
phone: "",
|
|
metadata: "{}",
|
|
emailConfirm: true,
|
|
})
|
|
|
|
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
|
const { name, value } = e.target
|
|
setFormData((prev) => ({ ...prev, [name]: value }))
|
|
}
|
|
|
|
const handleSwitchChange = (checked: boolean) => {
|
|
setFormData((prev) => ({ ...prev, emailConfirm: checked }))
|
|
}
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault()
|
|
setLoading(true)
|
|
|
|
try {
|
|
let metadata = {}
|
|
try {
|
|
metadata = JSON.parse(formData.metadata)
|
|
} catch (error) {
|
|
toast.error("Invalid JSON. Please check your metadata format.")
|
|
setLoading(false)
|
|
return
|
|
}
|
|
|
|
await createUser({
|
|
email: formData.email,
|
|
password: formData.password,
|
|
phone: formData.phone,
|
|
user_metadata: metadata,
|
|
email_confirm: formData.emailConfirm,
|
|
})
|
|
|
|
toast.success("User created successfully.")
|
|
onUserAdded()
|
|
onOpenChange(false)
|
|
setFormData({
|
|
email: "",
|
|
password: "",
|
|
phone: "",
|
|
metadata: "{}",
|
|
emailConfirm: true,
|
|
})
|
|
} catch (error) {
|
|
toast.error("Failed to create user.")
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent className="sm:max-w-md">
|
|
<DialogHeader>
|
|
<DialogTitle>Add User</DialogTitle>
|
|
<DialogDescription>
|
|
Create a new user account with email and password.
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
<form onSubmit={handleSubmit} className="space-y-4">
|
|
<div className="space-y-2">
|
|
<Label htmlFor="email">Email *</Label>
|
|
<Input
|
|
id="email"
|
|
name="email"
|
|
type="email"
|
|
required
|
|
value={formData.email}
|
|
onChange={handleInputChange}
|
|
/>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label htmlFor="password">Password *</Label>
|
|
<Input
|
|
id="password"
|
|
name="password"
|
|
type="password"
|
|
required
|
|
value={formData.password}
|
|
onChange={handleInputChange}
|
|
/>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label htmlFor="phone">Phone</Label>
|
|
<Input
|
|
id="phone"
|
|
name="phone"
|
|
value={formData.phone}
|
|
onChange={handleInputChange}
|
|
/>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label htmlFor="metadata">Metadata (JSON)</Label>
|
|
<Textarea
|
|
id="metadata"
|
|
name="metadata"
|
|
value={formData.metadata}
|
|
onChange={handleInputChange}
|
|
className="font-mono text-sm"
|
|
/>
|
|
</div>
|
|
<div className="flex items-center space-x-2">
|
|
<Switch
|
|
id="email-confirm"
|
|
checked={formData.emailConfirm}
|
|
onCheckedChange={handleSwitchChange}
|
|
/>
|
|
<Label htmlFor="email-confirm">Auto-confirm email</Label>
|
|
</div>
|
|
<DialogFooter>
|
|
<Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
|
|
Cancel
|
|
</Button>
|
|
<Button type="submit" disabled={loading}>
|
|
{loading ? "Creating..." : "Create User"}
|
|
</Button>
|
|
</DialogFooter>
|
|
</form>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|