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:
alphaeusmote
2025-04-09 23:57:26 +00:00
parent 760550cf03
commit 7823f21eb2
4 changed files with 167 additions and 22 deletions
+101 -3
View File
@@ -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>