mirror of
https://github.com/freedbygrace/DynamoDNS.git
synced 2026-08-11 18:56:52 +00:00
Enhance theme switching and add organization creation
Replit-Commit-Author: Agent Replit-Commit-Session-Id: 9111ef36-26c8-4085-84ca-a35dc1fec1b5 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7083d608-d6d3-4a6a-9a27-6286c5109627/582dd4fe-d503-4ab1-81ab-a04bba654cf7.jpg
This commit is contained in:
@@ -53,7 +53,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { Loader2, Moon, Sun, Lock } from "lucide-react";
|
||||
import { Loader2, Moon, Sun, Lock, Laptop } from "lucide-react";
|
||||
|
||||
// Organization form schema
|
||||
const organizationFormSchema = z.object({
|
||||
@@ -61,6 +61,12 @@ const organizationFormSchema = z.object({
|
||||
isActive: z.boolean().default(true),
|
||||
});
|
||||
|
||||
// Create organization form schema
|
||||
const createOrganizationFormSchema = z.object({
|
||||
name: z.string().min(1, "Organization name is required"),
|
||||
isActive: z.boolean().default(true),
|
||||
});
|
||||
|
||||
// Account form schema
|
||||
const accountFormSchema = z.object({
|
||||
username: z.string().min(3, "Username must be at least 3 characters"),
|
||||
@@ -82,10 +88,19 @@ export default function SettingsPage() {
|
||||
const { toast } = useToast();
|
||||
const { user } = useAuth();
|
||||
const { theme, setTheme } = useTheme();
|
||||
const { currentOrganization, setCurrentOrganization } = useOrganization();
|
||||
const { currentOrganization, setCurrentOrganization, createOrganizationMutation } = useOrganization();
|
||||
|
||||
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
|
||||
|
||||
// Create organization form
|
||||
const createOrganizationForm = useForm<z.infer<typeof createOrganizationFormSchema>>({
|
||||
resolver: zodResolver(createOrganizationFormSchema),
|
||||
defaultValues: {
|
||||
name: "",
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
|
||||
// Fetch organization data
|
||||
const { data: organization } = useQuery<Organization>({
|
||||
queryKey: ["/api/organizations", currentOrganization?.id],
|
||||
@@ -434,6 +449,77 @@ export default function SettingsPage() {
|
||||
</Card>
|
||||
) : (
|
||||
<>
|
||||
{user?.role === "admin" && (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Create New Organization</CardTitle>
|
||||
<CardDescription>
|
||||
Add a new organization to your account
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Form {...createOrganizationForm}>
|
||||
<form
|
||||
onSubmit={createOrganizationForm.handleSubmit((data) => {
|
||||
createOrganizationMutation.mutate(data);
|
||||
createOrganizationForm.reset();
|
||||
})}
|
||||
className="space-y-4"
|
||||
>
|
||||
<FormField
|
||||
control={createOrganizationForm.control}
|
||||
name="name"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Organization Name</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} placeholder="Enter organization name" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={createOrganizationForm.control}
|
||||
name="isActive"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-4">
|
||||
<div className="space-y-0.5">
|
||||
<FormLabel className="text-base">Active Status</FormLabel>
|
||||
<FormDescription>
|
||||
Enable this organization upon creation
|
||||
</FormDescription>
|
||||
</div>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
disabled={createOrganizationMutation.isPending}
|
||||
>
|
||||
{createOrganizationMutation.isPending ? (
|
||||
<>
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
Creating...
|
||||
</>
|
||||
) : (
|
||||
"Create Organization"
|
||||
)}
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Organization Details</CardTitle>
|
||||
@@ -546,7 +632,7 @@ export default function SettingsPage() {
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Select your preferred theme appearance
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-4 pt-2">
|
||||
<div className="grid grid-cols-3 gap-4 pt-2">
|
||||
<div
|
||||
className={`flex flex-col items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground cursor-pointer ${
|
||||
theme === "light" ? "border-primary" : ""
|
||||
@@ -571,6 +657,18 @@ export default function SettingsPage() {
|
||||
<p className="text-xs text-muted-foreground">Dark background with light text</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`flex flex-col items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground cursor-pointer ${
|
||||
theme === "system" ? "border-primary" : ""
|
||||
}`}
|
||||
onClick={() => setTheme("system")}
|
||||
>
|
||||
<Laptop className="h-6 w-6 mb-3" />
|
||||
<div className="space-y-1 text-center">
|
||||
<h3 className="font-medium">System</h3>
|
||||
<p className="text-xs text-muted-foreground">Follow your system preference</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
Reference in New Issue
Block a user