mirror of
https://github.com/fosrl/pangolin.git
synced 2025-07-06 03:55:04 +02:00
small visual enhancements to icons
This commit is contained in:
parent
5388c5d5b4
commit
45e1bff2e0
28 changed files with 299 additions and 138 deletions
|
@ -15,7 +15,6 @@ import {
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
FormControl,
|
FormControl,
|
||||||
|
@ -24,7 +23,12 @@ import {
|
||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { LockIcon, KeyIcon, UserIcon, Binary, Key, User } from "lucide-react";
|
import { LockIcon, UserIcon, Binary, Key, User } from "lucide-react";
|
||||||
|
import {
|
||||||
|
InputOTP,
|
||||||
|
InputOTPGroup,
|
||||||
|
InputOTPSlot,
|
||||||
|
} from "@app/components/ui/input-otp";
|
||||||
|
|
||||||
const pinSchema = z.object({
|
const pinSchema = z.object({
|
||||||
pin: z
|
pin: z
|
||||||
|
@ -34,12 +38,16 @@ const pinSchema = z.object({
|
||||||
});
|
});
|
||||||
|
|
||||||
const passwordSchema = z.object({
|
const passwordSchema = z.object({
|
||||||
email: z.string().email({ message: "Please enter a valid email address" }),
|
|
||||||
password: z
|
password: z
|
||||||
.string()
|
.string()
|
||||||
.min(8, { message: "Password must be at least 8 characters long" }),
|
.min(8, { message: "Password must be at least 8 characters long" }),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const userSchema = z.object({
|
||||||
|
email: z.string().email(),
|
||||||
|
password: z.string().min(1),
|
||||||
|
});
|
||||||
|
|
||||||
export default function ResourceAuthPortal() {
|
export default function ResourceAuthPortal() {
|
||||||
const [activeTab, setActiveTab] = useState("pin");
|
const [activeTab, setActiveTab] = useState("pin");
|
||||||
|
|
||||||
|
@ -52,6 +60,13 @@ export default function ResourceAuthPortal() {
|
||||||
|
|
||||||
const passwordForm = useForm<z.infer<typeof passwordSchema>>({
|
const passwordForm = useForm<z.infer<typeof passwordSchema>>({
|
||||||
resolver: zodResolver(passwordSchema),
|
resolver: zodResolver(passwordSchema),
|
||||||
|
defaultValues: {
|
||||||
|
password: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const userForm = useForm<z.infer<typeof userSchema>>({
|
||||||
|
resolver: zodResolver(userSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
email: "",
|
email: "",
|
||||||
password: "",
|
password: "",
|
||||||
|
@ -77,9 +92,9 @@ export default function ResourceAuthPortal() {
|
||||||
<div className="w-full max-w-md mx-auto">
|
<div className="w-full max-w-md mx-auto">
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>Welcome Back</CardTitle>
|
<CardTitle>Authentication Required</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription>
|
||||||
Choose your preferred login method
|
Choose your preferred method
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
|
@ -92,7 +107,7 @@ export default function ResourceAuthPortal() {
|
||||||
<Key className="w-4 h-4 mr-1" /> Password
|
<Key className="w-4 h-4 mr-1" /> Password
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger value="sso">
|
<TabsTrigger value="sso">
|
||||||
<User className="w-4 h-4 mr-1" /> SSO
|
<User className="w-4 h-4 mr-1" /> User
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
<TabsContent value="pin">
|
<TabsContent value="pin">
|
||||||
|
@ -106,20 +121,44 @@ export default function ResourceAuthPortal() {
|
||||||
name="pin"
|
name="pin"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Enter PIN</FormLabel>
|
<FormLabel>
|
||||||
|
Enter 6-digit PIN
|
||||||
|
</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<div className="flex justify-center">
|
||||||
placeholder="Enter your 6-digit PIN"
|
<InputOTP
|
||||||
type="password"
|
maxLength={6}
|
||||||
{...field}
|
{...field}
|
||||||
/>
|
>
|
||||||
|
<InputOTPGroup className="flex">
|
||||||
|
<InputOTPSlot
|
||||||
|
index={0}
|
||||||
|
/>
|
||||||
|
<InputOTPSlot
|
||||||
|
index={1}
|
||||||
|
/>
|
||||||
|
<InputOTPSlot
|
||||||
|
index={2}
|
||||||
|
/>
|
||||||
|
<InputOTPSlot
|
||||||
|
index={3}
|
||||||
|
/>
|
||||||
|
<InputOTPSlot
|
||||||
|
index={4}
|
||||||
|
/>
|
||||||
|
<InputOTPSlot
|
||||||
|
index={5}
|
||||||
|
/>
|
||||||
|
</InputOTPGroup>
|
||||||
|
</InputOTP>
|
||||||
|
</div>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Button type="submit" className="w-full">
|
<Button type="submit" className="w-full">
|
||||||
<KeyIcon className="w-4 h-4 mr-2" />
|
<LockIcon className="w-4 h-4 mr-2" />
|
||||||
Login with PIN
|
Login with PIN
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -129,27 +168,10 @@ export default function ResourceAuthPortal() {
|
||||||
<Form {...passwordForm}>
|
<Form {...passwordForm}>
|
||||||
<form
|
<form
|
||||||
onSubmit={passwordForm.handleSubmit(
|
onSubmit={passwordForm.handleSubmit(
|
||||||
onPasswordSubmit
|
onPasswordSubmit,
|
||||||
)}
|
)}
|
||||||
className="space-y-4"
|
className="space-y-4"
|
||||||
>
|
>
|
||||||
<FormField
|
|
||||||
control={passwordForm.control}
|
|
||||||
name="email"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>Email</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input
|
|
||||||
placeholder="Enter your email"
|
|
||||||
type="email"
|
|
||||||
{...field}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
<FormField
|
||||||
control={passwordForm.control}
|
control={passwordForm.control}
|
||||||
name="password"
|
name="password"
|
||||||
|
@ -158,7 +180,7 @@ export default function ResourceAuthPortal() {
|
||||||
<FormLabel>Password</FormLabel>
|
<FormLabel>Password</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Enter your password"
|
placeholder="Enter password"
|
||||||
type="password"
|
type="password"
|
||||||
{...field}
|
{...field}
|
||||||
/>
|
/>
|
||||||
|
@ -175,31 +197,73 @@ export default function ResourceAuthPortal() {
|
||||||
</Form>
|
</Form>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="sso">
|
<TabsContent value="sso">
|
||||||
<div className="space-y-4">
|
<Form {...userForm}>
|
||||||
<p className="text-sm text-muted-foreground">
|
<form
|
||||||
Click the button below to login with your
|
onSubmit={userForm.handleSubmit(
|
||||||
organization's SSO provider.
|
(values) => {
|
||||||
</p>
|
console.log(
|
||||||
<Button
|
"User authentication",
|
||||||
onClick={handleSSOAuth}
|
values,
|
||||||
className="w-full"
|
);
|
||||||
|
// Implement user authentication logic here
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
className="space-y-4"
|
||||||
>
|
>
|
||||||
<UserIcon className="w-4 h-4 mr-2" />
|
<FormField
|
||||||
Login with SSO
|
control={userForm.control}
|
||||||
</Button>
|
name="email"
|
||||||
</div>
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Email</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="Enter email"
|
||||||
|
type="email"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={userForm.control}
|
||||||
|
name="password"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Password</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="Enter password"
|
||||||
|
type="password"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Button type="submit" className="w-full">
|
||||||
|
<LockIcon className="w-4 h-4 mr-2" />
|
||||||
|
Login as User
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardFooter className="flex justify-center">
|
</Card>
|
||||||
|
{activeTab === "sso" && (
|
||||||
|
<div className="flex justify-center mt-4">
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
Don't have an account?{" "}
|
Don't have an account?{" "}
|
||||||
<a href="#" className="underline">
|
<a href="#" className="underline">
|
||||||
Sign up
|
Sign up
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</CardFooter>
|
</div>
|
||||||
</Card>
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,7 +123,7 @@ export default function CreateRoleForm({
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
onSubmit={form.handleSubmit(onSubmit)}
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
className="space-y-6"
|
className="space-y-8:w"
|
||||||
id="create-role-form"
|
id="create-role-form"
|
||||||
>
|
>
|
||||||
<FormField
|
<FormField
|
||||||
|
|
|
@ -155,7 +155,7 @@ export default function DeleteRoleForm({
|
||||||
</CredenzaDescription>
|
</CredenzaDescription>
|
||||||
</CredenzaHeader>
|
</CredenzaHeader>
|
||||||
<CredenzaBody>
|
<CredenzaBody>
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<p>
|
<p>
|
||||||
You're about to delete the{" "}
|
You're about to delete the{" "}
|
||||||
|
@ -170,7 +170,7 @@ export default function DeleteRoleForm({
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
onSubmit={form.handleSubmit(onSubmit)}
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
className="space-y-6"
|
className="space-y-8"
|
||||||
id="remove-role-form"
|
id="remove-role-form"
|
||||||
>
|
>
|
||||||
<FormField
|
<FormField
|
||||||
|
|
|
@ -110,7 +110,7 @@ export default function AccessControlsPage() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
<SettingsSectionTitle
|
<SettingsSectionTitle
|
||||||
title="Access Controls"
|
title="Access Controls"
|
||||||
description="Manage what this user can access and do in the organization"
|
description="Manage what this user can access and do in the organization"
|
||||||
|
@ -120,7 +120,7 @@ export default function AccessControlsPage() {
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
onSubmit={form.handleSubmit(onSubmit)}
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
className="space-y-6"
|
className="space-y-8"
|
||||||
>
|
>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import {
|
||||||
BreadcrumbSeparator,
|
BreadcrumbSeparator,
|
||||||
} from "@/components/ui/breadcrumb";
|
} from "@/components/ui/breadcrumb";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { ArrowLeft } from "lucide-react";
|
|
||||||
|
|
||||||
interface UserLayoutProps {
|
interface UserLayoutProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
|
@ -30,7 +29,7 @@ export default async function UserLayoutProps(props: UserLayoutProps) {
|
||||||
try {
|
try {
|
||||||
const res = await internal.get<AxiosResponse<GetOrgUserResponse>>(
|
const res = await internal.get<AxiosResponse<GetOrgUserResponse>>(
|
||||||
`/org/${params.orgId}/user/${params.userId}`,
|
`/org/${params.orgId}/user/${params.userId}`,
|
||||||
await authCookieHeader()
|
await authCookieHeader(),
|
||||||
);
|
);
|
||||||
user = res.data.data;
|
user = res.data.data;
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -48,15 +47,17 @@ export default async function UserLayoutProps(props: UserLayoutProps) {
|
||||||
<>
|
<>
|
||||||
<OrgUserProvider orgUser={user}>
|
<OrgUserProvider orgUser={user}>
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<Link
|
<Breadcrumb>
|
||||||
href="../../"
|
<BreadcrumbList>
|
||||||
className="text-muted-foreground hover:underline"
|
<BreadcrumbItem>
|
||||||
>
|
<Link href="../../">Users</Link>
|
||||||
<div className="flex flex-row items-center gap-1">
|
</BreadcrumbItem>
|
||||||
<ArrowLeft className="w-4 h-4" />{" "}
|
<BreadcrumbSeparator />
|
||||||
<span>All Users</span>
|
<BreadcrumbItem>
|
||||||
</div>
|
<BreadcrumbPage>{user.email}</BreadcrumbPage>
|
||||||
</Link>
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-0.5 select-none mb-6">
|
<div className="space-y-0.5 select-none mb-6">
|
||||||
|
|
|
@ -171,7 +171,7 @@ export default function InviteUserForm({ open, setOpen }: InviteUserFormProps) {
|
||||||
</CredenzaDescription>
|
</CredenzaDescription>
|
||||||
</CredenzaHeader>
|
</CredenzaHeader>
|
||||||
<CredenzaBody>
|
<CredenzaBody>
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
{!inviteLink && (
|
{!inviteLink && (
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
|
|
|
@ -3,6 +3,14 @@
|
||||||
import api from "@app/api";
|
import api from "@app/api";
|
||||||
import { Avatar, AvatarFallback } from "@app/components/ui/avatar";
|
import { Avatar, AvatarFallback } from "@app/components/ui/avatar";
|
||||||
import { Button } from "@app/components/ui/button";
|
import { Button } from "@app/components/ui/button";
|
||||||
|
import {
|
||||||
|
Command,
|
||||||
|
CommandEmpty,
|
||||||
|
CommandGroup,
|
||||||
|
CommandInput,
|
||||||
|
CommandItem,
|
||||||
|
CommandList,
|
||||||
|
} from "@app/components/ui/command";
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
|
@ -12,6 +20,11 @@ import {
|
||||||
DropdownMenuSeparator,
|
DropdownMenuSeparator,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "@app/components/ui/dropdown-menu";
|
} from "@app/components/ui/dropdown-menu";
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@app/components/ui/popover";
|
||||||
import {
|
import {
|
||||||
Select,
|
Select,
|
||||||
SelectContent,
|
SelectContent,
|
||||||
|
@ -21,10 +34,12 @@ import {
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@app/components/ui/select";
|
} from "@app/components/ui/select";
|
||||||
import { useToast } from "@app/hooks/useToast";
|
import { useToast } from "@app/hooks/useToast";
|
||||||
import { formatAxiosError } from "@app/lib/utils";
|
import { cn, formatAxiosError } from "@app/lib/utils";
|
||||||
import { ListOrgsResponse } from "@server/routers/org";
|
import { ListOrgsResponse } from "@server/routers/org";
|
||||||
|
import { Check, ChevronsUpDown } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
type HeaderProps = {
|
type HeaderProps = {
|
||||||
name?: string;
|
name?: string;
|
||||||
|
@ -36,6 +51,8 @@ type HeaderProps = {
|
||||||
export default function Header({ email, orgName, name, orgs }: HeaderProps) {
|
export default function Header({ email, orgName, name, orgs }: HeaderProps) {
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
function getInitials() {
|
function getInitials() {
|
||||||
|
@ -125,7 +142,68 @@ export default function Header({ email, orgName, name, orgs }: HeaderProps) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Select
|
<Popover open={open} onOpenChange={setOpen}>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="lg"
|
||||||
|
role="combobox"
|
||||||
|
aria-expanded={open}
|
||||||
|
className="w-full md:w-[200px] h-12 px-3 py-4"
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-between w-full">
|
||||||
|
<div className="flex flex-col items-start">
|
||||||
|
<span className="font-bold text-sm">
|
||||||
|
Organization
|
||||||
|
</span>
|
||||||
|
<span className="text-sm text-muted-foreground">
|
||||||
|
{orgName
|
||||||
|
? orgs.find(
|
||||||
|
(org) =>
|
||||||
|
org.name === orgName,
|
||||||
|
)?.name
|
||||||
|
: "Select organization..."}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<ChevronsUpDown className="h-4 w-4 shrink-0 opacity-50" />
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="[100px] md:w-[180px] p-0">
|
||||||
|
<Command>
|
||||||
|
<CommandInput placeholder="Search..." />
|
||||||
|
<CommandEmpty>
|
||||||
|
No organization found.
|
||||||
|
</CommandEmpty>
|
||||||
|
<CommandGroup>
|
||||||
|
<CommandList>
|
||||||
|
{orgs.map((org) => (
|
||||||
|
<CommandItem
|
||||||
|
key={org.orgId}
|
||||||
|
onSelect={(currentValue) => {
|
||||||
|
router.push(
|
||||||
|
`/${org.orgId}/settings`,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Check
|
||||||
|
className={cn(
|
||||||
|
"mr-2 h-4 w-4",
|
||||||
|
orgName === org.name
|
||||||
|
? "opacity-100"
|
||||||
|
: "opacity-0",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{org.name}
|
||||||
|
</CommandItem>
|
||||||
|
))}
|
||||||
|
</CommandList>
|
||||||
|
</CommandGroup>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
|
{/* <Select
|
||||||
defaultValue={orgName}
|
defaultValue={orgName}
|
||||||
onValueChange={(val) => {
|
onValueChange={(val) => {
|
||||||
router.push(`/${val}/settings`);
|
router.push(`/${val}/settings`);
|
||||||
|
@ -146,7 +224,7 @@ export default function Header({ email, orgName, name, orgs }: HeaderProps) {
|
||||||
))}
|
))}
|
||||||
</SelectGroup>
|
</SelectGroup>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -46,7 +46,7 @@ export default function GeneralPage() {
|
||||||
title="Delete organization"
|
title="Delete organization"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
{orgUser.isOwner ? (
|
{orgUser.isOwner ? (
|
||||||
<Button onClick={() => setIsDeleteModalOpen(true)}>
|
<Button onClick={() => setIsDeleteModalOpen(true)}>
|
||||||
Delete Organization
|
Delete Organization
|
||||||
|
|
|
@ -22,22 +22,22 @@ const topNavItems = [
|
||||||
{
|
{
|
||||||
title: "Sites",
|
title: "Sites",
|
||||||
href: "/{orgId}/settings/sites",
|
href: "/{orgId}/settings/sites",
|
||||||
icon: <Combine className="h-5 w-5" />,
|
icon: <Combine className="h-4 w-4" />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Resources",
|
title: "Resources",
|
||||||
href: "/{orgId}/settings/resources",
|
href: "/{orgId}/settings/resources",
|
||||||
icon: <Waypoints className="h-5 w-5" />,
|
icon: <Waypoints className="h-4 w-4" />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Access",
|
title: "Access",
|
||||||
href: "/{orgId}/settings/access",
|
href: "/{orgId}/settings/access",
|
||||||
icon: <Users className="h-5 w-5" />,
|
icon: <Users className="h-4 w-4" />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "General",
|
title: "General",
|
||||||
href: "/{orgId}/settings/general",
|
href: "/{orgId}/settings/general",
|
||||||
icon: <Settings className="h-5 w-5" />,
|
icon: <Settings className="h-4 w-4" />,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -257,11 +257,11 @@ export default function ResourceAuthenticationPage() {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="space-y-12 lg:max-w-2xl">
|
<div className="space-y-12">
|
||||||
<section className="space-y-6">
|
<section className="space-y-8">
|
||||||
<SettingsSectionTitle
|
<SettingsSectionTitle
|
||||||
title="Users & Roles"
|
title="Users & Roles"
|
||||||
description="Configure who can visit this resource (only applicable if SSO is used)"
|
description="Configure which users can access this resource (only applicable if SSO enabled)"
|
||||||
size="1xl"
|
size="1xl"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -275,9 +275,7 @@ export default function ResourceAuthenticationPage() {
|
||||||
<Label htmlFor="sso-toggle">Allow SSO</Label>
|
<Label htmlFor="sso-toggle">Allow SSO</Label>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-muted-foreground text-sm">
|
<span className="text-muted-foreground text-sm">
|
||||||
Users will be able to access the resource if they're
|
Existing users will only have to login once for all
|
||||||
logged into the dashboard and have access to the
|
|
||||||
resource. Users will only have to login once for all
|
|
||||||
resources that have SSO enabled.
|
resources that have SSO enabled.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -287,7 +285,7 @@ export default function ResourceAuthenticationPage() {
|
||||||
onSubmit={usersRolesForm.handleSubmit(
|
onSubmit={usersRolesForm.handleSubmit(
|
||||||
onSubmitUsersRoles,
|
onSubmitUsersRoles,
|
||||||
)}
|
)}
|
||||||
className="space-y-6"
|
className="space-y-8"
|
||||||
>
|
>
|
||||||
<FormField
|
<FormField
|
||||||
control={usersRolesForm.control}
|
control={usersRolesForm.control}
|
||||||
|
@ -336,9 +334,9 @@ export default function ResourceAuthenticationPage() {
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormDescription>
|
<FormDescription>
|
||||||
Users with these roles will be able
|
These roles will be able to access
|
||||||
to access this resource. Admins can
|
this resource. Admins can always
|
||||||
always access this resource.
|
access this resource.
|
||||||
</FormDescription>
|
</FormDescription>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
@ -414,10 +412,10 @@ export default function ResourceAuthenticationPage() {
|
||||||
|
|
||||||
<Separator />
|
<Separator />
|
||||||
|
|
||||||
<section className="space-y-6">
|
<section className="space-y-8">
|
||||||
<SettingsSectionTitle
|
<SettingsSectionTitle
|
||||||
title="Authentication Methods"
|
title="Authentication Methods"
|
||||||
description="You can also allow users to access the resource via the below methods"
|
description="You can also anyone to access the resource via the below methods"
|
||||||
size="1xl"
|
size="1xl"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -349,7 +349,7 @@ export default function ReverseProxyTargets(props: {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="space-y-12">
|
<div className="space-y-12">
|
||||||
<section className="space-y-6 lg:max-w-2xl">
|
<section className="space-y-8">
|
||||||
<SettingsSectionTitle
|
<SettingsSectionTitle
|
||||||
title="SSL"
|
title="SSL"
|
||||||
description="Setup SSL to secure your connections with LetsEncrypt certificates"
|
description="Setup SSL to secure your connections with LetsEncrypt certificates"
|
||||||
|
@ -366,23 +366,24 @@ export default function ReverseProxyTargets(props: {
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<hr className="lg:max-w-2xl" />
|
<hr />
|
||||||
|
|
||||||
<section className="space-y-6">
|
<section className="space-y-8">
|
||||||
<SettingsSectionTitle
|
<SettingsSectionTitle
|
||||||
title="Targets"
|
title="Targets"
|
||||||
description="Setup targets to route traffic to your services"
|
description="Setup targets to route traffic to your services"
|
||||||
size="1xl"
|
size="1xl"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
<Form {...addTargetForm}>
|
<Form {...addTargetForm}>
|
||||||
<form
|
<form
|
||||||
onSubmit={addTargetForm.handleSubmit(
|
onSubmit={addTargetForm.handleSubmit(
|
||||||
addTarget as any,
|
addTarget as any,
|
||||||
)}
|
)}
|
||||||
|
className="space-y-8"
|
||||||
>
|
>
|
||||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||||
<FormField
|
<FormField
|
||||||
control={addTargetForm.control}
|
control={addTargetForm.control}
|
||||||
name="ip"
|
name="ip"
|
||||||
|
|
|
@ -118,8 +118,8 @@ export default function GeneralForm() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="lg:max-w-2xl space-y-12">
|
<div className="space-y-12 lg:max-w-2xl">
|
||||||
<section className="space-y-6">
|
<section className="space-y-8">
|
||||||
<SettingsSectionTitle
|
<SettingsSectionTitle
|
||||||
title="General Settings"
|
title="General Settings"
|
||||||
description="Configure the general settings for this resource"
|
description="Configure the general settings for this resource"
|
||||||
|
@ -129,7 +129,7 @@ export default function GeneralForm() {
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
onSubmit={form.handleSubmit(onSubmit)}
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
className="space-y-6"
|
className="space-y-8"
|
||||||
>
|
>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|
|
@ -8,13 +8,21 @@ import { AxiosResponse } from "axios";
|
||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
import { authCookieHeader } from "@app/api/cookies";
|
import { authCookieHeader } from "@app/api/cookies";
|
||||||
import { SidebarSettings } from "@app/components/SidebarSettings";
|
import { SidebarSettings } from "@app/components/SidebarSettings";
|
||||||
import Link from "next/link";
|
import { Cloud, Settings, Shield } from "lucide-react";
|
||||||
import { ArrowLeft, Cloud, Settings, Shield } from "lucide-react";
|
|
||||||
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
||||||
import { GetOrgResponse } from "@server/routers/org";
|
import { GetOrgResponse } from "@server/routers/org";
|
||||||
import OrgProvider from "@app/providers/OrgProvider";
|
import OrgProvider from "@app/providers/OrgProvider";
|
||||||
import { cache } from "react";
|
import { cache } from "react";
|
||||||
import ResourceInfoBox from "./components/ResourceInfoBox";
|
import ResourceInfoBox from "./components/ResourceInfoBox";
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from "@app/components/ui/breadcrumb";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
interface ResourceLayoutProps {
|
interface ResourceLayoutProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
|
@ -31,7 +39,7 @@ export default async function ResourceLayout(props: ResourceLayoutProps) {
|
||||||
try {
|
try {
|
||||||
const res = await internal.get<AxiosResponse<GetResourceResponse>>(
|
const res = await internal.get<AxiosResponse<GetResourceResponse>>(
|
||||||
`/resource/${params.resourceId}`,
|
`/resource/${params.resourceId}`,
|
||||||
await authCookieHeader()
|
await authCookieHeader(),
|
||||||
);
|
);
|
||||||
resource = res.data.data;
|
resource = res.data.data;
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -60,8 +68,8 @@ export default async function ResourceLayout(props: ResourceLayoutProps) {
|
||||||
const getOrg = cache(async () =>
|
const getOrg = cache(async () =>
|
||||||
internal.get<AxiosResponse<GetOrgResponse>>(
|
internal.get<AxiosResponse<GetOrgResponse>>(
|
||||||
`/org/${params.orgId}`,
|
`/org/${params.orgId}`,
|
||||||
await authCookieHeader()
|
await authCookieHeader(),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
const res = await getOrg();
|
const res = await getOrg();
|
||||||
org = res.data.data;
|
org = res.data.data;
|
||||||
|
@ -94,15 +102,17 @@ export default async function ResourceLayout(props: ResourceLayoutProps) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<Link
|
<Breadcrumb>
|
||||||
href="../../"
|
<BreadcrumbList>
|
||||||
className="text-muted-foreground hover:underline"
|
<BreadcrumbItem>
|
||||||
>
|
<Link href="../">Resources</Link>
|
||||||
<div className="flex flex-row items-center gap-1">
|
</BreadcrumbItem>
|
||||||
<ArrowLeft className="w-4 h-4" />{" "}
|
<BreadcrumbSeparator />
|
||||||
<span>All Resources</span>
|
<BreadcrumbItem>
|
||||||
</div>
|
<BreadcrumbPage>{resource.name}</BreadcrumbPage>
|
||||||
</Link>
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<SettingsSectionTitle
|
<SettingsSectionTitle
|
||||||
|
@ -112,10 +122,7 @@ export default async function ResourceLayout(props: ResourceLayoutProps) {
|
||||||
|
|
||||||
<OrgProvider org={org}>
|
<OrgProvider org={org}>
|
||||||
<ResourceProvider resource={resource} authInfo={authInfo}>
|
<ResourceProvider resource={resource} authInfo={authInfo}>
|
||||||
<SidebarSettings
|
<SidebarSettings sidebarNavItems={sidebarNavItems}>
|
||||||
sidebarNavItems={sidebarNavItems}
|
|
||||||
limitWidth={false}
|
|
||||||
>
|
|
||||||
<div className="mb-8 lg:max-w-2xl">
|
<div className="mb-8 lg:max-w-2xl">
|
||||||
<ResourceInfoBox />
|
<ResourceInfoBox />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -64,7 +64,7 @@ export default function GeneralPage() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
<SettingsSectionTitle
|
<SettingsSectionTitle
|
||||||
title="General Settings"
|
title="General Settings"
|
||||||
description="Configure the general settings for this site"
|
description="Configure the general settings for this site"
|
||||||
|
@ -74,7 +74,7 @@ export default function GeneralPage() {
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
onSubmit={form.handleSubmit(onSubmit)}
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
className="space-y-6"
|
className="space-y-8"
|
||||||
>
|
>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|
|
@ -8,6 +8,13 @@ import { SidebarSettings } from "@app/components/SidebarSettings";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { ArrowLeft } from "lucide-react";
|
import { ArrowLeft } from "lucide-react";
|
||||||
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from "@app/components/ui/breadcrumb";
|
||||||
|
|
||||||
interface SettingsLayoutProps {
|
interface SettingsLayoutProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
|
@ -23,7 +30,7 @@ export default async function SettingsLayout(props: SettingsLayoutProps) {
|
||||||
try {
|
try {
|
||||||
const res = await internal.get<AxiosResponse<GetSiteResponse>>(
|
const res = await internal.get<AxiosResponse<GetSiteResponse>>(
|
||||||
`/org/${params.orgId}/site/${params.niceId}`,
|
`/org/${params.orgId}/site/${params.niceId}`,
|
||||||
await authCookieHeader()
|
await authCookieHeader(),
|
||||||
);
|
);
|
||||||
site = res.data.data;
|
site = res.data.data;
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -39,15 +46,18 @@ export default async function SettingsLayout(props: SettingsLayoutProps) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="mb-4">
|
<div className="mb-4 flex-row">
|
||||||
<Link
|
<Breadcrumb>
|
||||||
href="../../"
|
<BreadcrumbList>
|
||||||
className="text-muted-foreground hover:underline"
|
<BreadcrumbItem>
|
||||||
>
|
<Link href="../../">Sites</Link>
|
||||||
<div className="flex flex-row items-center gap-1">
|
</BreadcrumbItem>
|
||||||
<ArrowLeft className="w-4 h-4" /> <span>All Sites</span>
|
<BreadcrumbSeparator />
|
||||||
</div>
|
<BreadcrumbItem>
|
||||||
</Link>
|
<BreadcrumbPage>{site.name}</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<SettingsSectionTitle
|
<SettingsSectionTitle
|
||||||
|
|
|
@ -191,11 +191,11 @@ sh get-docker.sh`;
|
||||||
</CredenzaDescription>
|
</CredenzaDescription>
|
||||||
</CredenzaHeader>
|
</CredenzaHeader>
|
||||||
<CredenzaBody>
|
<CredenzaBody>
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
onSubmit={form.handleSubmit(onSubmit)}
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
className="space-y-6"
|
className="space-y-8"
|
||||||
id="create-site-form"
|
id="create-site-form"
|
||||||
>
|
>
|
||||||
<FormField
|
<FormField
|
||||||
|
|
|
@ -27,6 +27,7 @@ import { api } from "@app/api";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { AxiosResponse } from "axios";
|
import { AxiosResponse } from "axios";
|
||||||
import { formatAxiosError } from "@app/lib/utils";
|
import { formatAxiosError } from "@app/lib/utils";
|
||||||
|
import { LockIcon } from "lucide-react";
|
||||||
|
|
||||||
type LoginFormProps = {
|
type LoginFormProps = {
|
||||||
redirect?: string;
|
redirect?: string;
|
||||||
|
@ -108,7 +109,7 @@ export default function LoginForm({ redirect }: LoginFormProps) {
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
onSubmit={form.handleSubmit(onSubmit)}
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
className="space-y-6"
|
className="space-y-8"
|
||||||
>
|
>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
@ -153,6 +154,7 @@ export default function LoginForm({ redirect }: LoginFormProps) {
|
||||||
className="w-full"
|
className="w-full"
|
||||||
loading={loading}
|
loading={loading}
|
||||||
>
|
>
|
||||||
|
<LockIcon className="w-4 h-4 mr-2" />
|
||||||
Login
|
Login
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -111,7 +111,7 @@ export default function SignupForm({ redirect }: SignupFormProps) {
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
onSubmit={form.handleSubmit(onSubmit)}
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
className="space-y-6"
|
className="space-y-8"
|
||||||
>
|
>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|
|
@ -134,7 +134,7 @@ export default function VerifyEmailForm({
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
onSubmit={form.handleSubmit(onSubmit)}
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
className="space-y-6"
|
className="space-y-8"
|
||||||
>
|
>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { AccountForm } from "./account-form"
|
||||||
|
|
||||||
export default function SettingsAccountPage() {
|
export default function SettingsAccountPage() {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-lg font-medium">Account</h3>
|
<h3 className="text-lg font-medium">Account</h3>
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { AppearanceForm } from "./appearance-form"
|
||||||
|
|
||||||
export default function SettingsAppearancePage() {
|
export default function SettingsAppearancePage() {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-lg font-medium">Appearance</h3>
|
<h3 className="text-lg font-medium">Appearance</h3>
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { DisplayForm } from "./display-form"
|
||||||
|
|
||||||
export default function SettingsDisplayPage() {
|
export default function SettingsDisplayPage() {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-lg font-medium">Display</h3>
|
<h3 className="text-lg font-medium">Display</h3>
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
|
|
|
@ -56,7 +56,7 @@ export default function SettingsLayout({ children }: SettingsLayoutProps) {
|
||||||
className="hidden dark:block"
|
className="hidden dark:block"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="hidden space-y-6 p-10 pb-16 md:block">
|
<div className="hidden space-y-8 p-10 pb-16 md:block">
|
||||||
<div className="space-y-0.5">
|
<div className="space-y-0.5">
|
||||||
<h2 className="text-2xl font-bold tracking-tight">Settings</h2>
|
<h2 className="text-2xl font-bold tracking-tight">Settings</h2>
|
||||||
<p className="text-muted-foreground">
|
<p className="text-muted-foreground">
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { NotificationsForm } from "./notifications-form"
|
||||||
|
|
||||||
export default function SettingsNotificationsPage() {
|
export default function SettingsNotificationsPage() {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-lg font-medium">Notifications</h3>
|
<h3 className="text-lg font-medium">Notifications</h3>
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { ProfileForm } from "@app/components/profile-form"
|
||||||
|
|
||||||
export default function SettingsProfilePage() {
|
export default function SettingsProfilePage() {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-lg font-medium">Profile</h3>
|
<h3 className="text-lg font-medium">Profile</h3>
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
|
|
|
@ -206,7 +206,7 @@ export default function StepperForm() {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{currentStep === "site" && (
|
{currentStep === "site" && (
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="siteName">Site Name</Label>
|
<Label htmlFor="siteName">Site Name</Label>
|
||||||
<Input
|
<Input
|
||||||
|
@ -222,7 +222,7 @@ export default function StepperForm() {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{currentStep === "resources" && (
|
{currentStep === "resources" && (
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="resourceName">
|
<Label htmlFor="resourceName">
|
||||||
Resource Name
|
Resource Name
|
||||||
|
|
|
@ -11,7 +11,7 @@ export default function SettingsSectionTitle({
|
||||||
}: SettingsSectionTitleProps) {
|
}: SettingsSectionTitleProps) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`space-y-0.5 select-none ${!size || size === "2xl" ? "mb-12" : ""}`}
|
className={`space-y-0.5 select-none ${!size || size === "2xl" ? "mb-6 md:mb-12" : ""}`}
|
||||||
>
|
>
|
||||||
<h2
|
<h2
|
||||||
className={`text-${
|
className={`text-${
|
||||||
|
|
|
@ -21,8 +21,8 @@ export function SidebarSettings({
|
||||||
limitWidth,
|
limitWidth,
|
||||||
}: SideBarSettingsProps) {
|
}: SideBarSettingsProps) {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6 0 pb-16k">
|
<div className="space-y-8 0 pb-16k">
|
||||||
<div className="flex flex-col space-y-6 lg:flex-row lg:space-x-32 lg:space-y-0">
|
<div className="flex flex-col space-y-8 lg:flex-row lg:space-x-32 lg:space-y-0">
|
||||||
<aside className="-mx-4 lg:w-1/5">
|
<aside className="-mx-4 lg:w-1/5">
|
||||||
<SidebarNav items={sidebarNavItems} disabled={disabled} />
|
<SidebarNav items={sidebarNavItems} disabled={disabled} />
|
||||||
</aside>
|
</aside>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue