styled edit form
This commit is contained in:
@@ -16,7 +16,9 @@ import {
|
||||
CardHeader,
|
||||
} from "@/components/ui/card";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Modal } from "@/components/ui/modal";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -82,7 +84,7 @@ export default function UsersList({ user }: UrlListProps) {
|
||||
});
|
||||
|
||||
const { mutate } = useSWRConfig();
|
||||
const { data, error, isLoading } = useSWR<{ total: number; list: User[] }>(
|
||||
const { data, isLoading } = useSWR<{ total: number; list: User[] }>(
|
||||
`/api/user/admin?page=${currentPage}&size=${pageSize}&email=${searchParams.email}&userName=${searchParams.userName}`,
|
||||
fetcher,
|
||||
{
|
||||
@@ -122,16 +124,6 @@ export default function UsersList({ user }: UrlListProps) {
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{isShowForm && (
|
||||
<UserForm
|
||||
user={{ id: user.id, name: user.name || "" }}
|
||||
isShowForm={isShowForm}
|
||||
setShowForm={setShowForm}
|
||||
type="edit"
|
||||
initData={currentEditUser}
|
||||
onRefresh={handleRefresh}
|
||||
/>
|
||||
)}
|
||||
<div className="mb-2 flex-row items-center gap-2 space-y-2 sm:flex sm:space-y-0">
|
||||
<div className="relative w-full">
|
||||
<Input
|
||||
@@ -257,7 +249,7 @@ export default function UsersList({ user }: UrlListProps) {
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell className="col-span-1 hidden justify-center sm:flex">
|
||||
<StatusDot status={user.active} />
|
||||
<Switch defaultChecked={user.active === 1} />
|
||||
</TableCell>
|
||||
<TableCell className="col-span-1 hidden justify-center sm:flex">
|
||||
{timeAgo(user.createdAt || "")}
|
||||
@@ -299,6 +291,21 @@ export default function UsersList({ user }: UrlListProps) {
|
||||
</Table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Modal
|
||||
className="md:max-w-2xl"
|
||||
showModal={isShowForm}
|
||||
setShowModal={setShowForm}
|
||||
>
|
||||
<UserForm
|
||||
user={{ id: user.id, name: user.name || "" }}
|
||||
isShowForm={isShowForm}
|
||||
setShowForm={setShowForm}
|
||||
type="edit"
|
||||
initData={currentEditUser}
|
||||
onRefresh={handleRefresh}
|
||||
/>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Modal } from "@/components/ui/modal";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import {
|
||||
@@ -190,17 +191,6 @@ export default function UserRecordsList({ user, action }: RecordListProps) {
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{isShowForm && (
|
||||
<RecordForm
|
||||
user={{ id: user.id, name: user.name || "" }}
|
||||
isShowForm={isShowForm}
|
||||
setShowForm={setShowForm}
|
||||
type={formType}
|
||||
initData={currentEditRecord}
|
||||
action={action}
|
||||
onRefresh={handleRefresh}
|
||||
/>
|
||||
)}
|
||||
<Table>
|
||||
<TableHeader className="bg-gray-100/50 dark:bg-primary-foreground">
|
||||
<TableRow className="grid grid-cols-3 items-center sm:grid-cols-8">
|
||||
@@ -351,6 +341,22 @@ export default function UserRecordsList({ user, action }: RecordListProps) {
|
||||
</Table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Modal
|
||||
className="md:max-w-2xl"
|
||||
showModal={isShowForm}
|
||||
setShowModal={setShowForm}
|
||||
>
|
||||
<RecordForm
|
||||
user={{ id: user.id, name: user.name || "" }}
|
||||
isShowForm={isShowForm}
|
||||
setShowForm={setShowForm}
|
||||
type={formType}
|
||||
initData={currentEditRecord}
|
||||
action={action}
|
||||
onRefresh={handleRefresh}
|
||||
/>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,11 +23,6 @@ import {
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import {
|
||||
HoverCard,
|
||||
HoverCardContent,
|
||||
HoverCardTrigger,
|
||||
} from "@/components/ui/hover-card";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Modal } from "@/components/ui/modal";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
@@ -46,10 +41,8 @@ import {
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import StatusDot from "@/components/dashboard/status-dot";
|
||||
import { FormType } from "@/components/forms/record-form";
|
||||
import { UrlForm } from "@/components/forms/url-form";
|
||||
import { BlurImg } from "@/components/shared/blur-image";
|
||||
import { CopyButton } from "@/components/shared/copy-button";
|
||||
import { EmptyPlaceholder } from "@/components/shared/empty-placeholder";
|
||||
import { Icons } from "@/components/shared/icons";
|
||||
@@ -105,9 +98,6 @@ export default function UserUrlsList({ user, action }: UrlListProps) {
|
||||
const [pageSize, setPageSize] = useState(10);
|
||||
const [isShowStats, setShowStats] = useState(false);
|
||||
const [isShowQrcode, setShowQrcode] = useState(false);
|
||||
const [qrcodeInfo, setQrcodeInfo] = useState({
|
||||
payload: "",
|
||||
});
|
||||
const [selectedUrl, setSelectedUrl] = useState<ShortUrlFormData | null>(null);
|
||||
const [searchParams, setSearchParams] = useState({
|
||||
slug: "",
|
||||
@@ -191,17 +181,6 @@ export default function UserUrlsList({ user, action }: UrlListProps) {
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{isShowForm && (
|
||||
<UrlForm
|
||||
user={{ id: user.id, name: user.name || "" }}
|
||||
isShowForm={isShowForm}
|
||||
setShowForm={setShowForm}
|
||||
type={formType}
|
||||
initData={currentEditUrl}
|
||||
action={action}
|
||||
onRefresh={handleRefresh}
|
||||
/>
|
||||
)}
|
||||
<div className="mb-2 flex-row items-center gap-2 space-y-2 sm:flex sm:space-y-0">
|
||||
<div className="relative w-full">
|
||||
<Input
|
||||
@@ -392,12 +371,6 @@ export default function UserUrlsList({ user, action }: UrlListProps) {
|
||||
setShowForm(false);
|
||||
setFormType("edit");
|
||||
setShowForm(!isShowForm);
|
||||
if (!isShowForm) {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
<p className="hidden sm:block">Edit</p>
|
||||
@@ -464,6 +437,7 @@ export default function UserUrlsList({ user, action }: UrlListProps) {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* QR code editor */}
|
||||
<Modal
|
||||
className="md:max-w-lg"
|
||||
showModal={isShowQrcode}
|
||||
@@ -476,6 +450,23 @@ export default function UserUrlsList({ user, action }: UrlListProps) {
|
||||
/>
|
||||
)}
|
||||
</Modal>
|
||||
|
||||
{/* Url form */}
|
||||
<Modal
|
||||
className="md:max-w-2xl"
|
||||
showModal={isShowForm}
|
||||
setShowModal={setShowForm}
|
||||
>
|
||||
<UrlForm
|
||||
user={{ id: user.id, name: user.name || "" }}
|
||||
isShowForm={isShowForm}
|
||||
setShowForm={setShowForm}
|
||||
type={formType}
|
||||
initData={currentEditUrl}
|
||||
action={action}
|
||||
onRefresh={handleRefresh}
|
||||
/>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,14 +3,24 @@ import React from "react";
|
||||
interface SectionColumnsType {
|
||||
title: string;
|
||||
children: React.ReactNode;
|
||||
required?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function FormSectionColumns({ title, children }: SectionColumnsType) {
|
||||
export function FormSectionColumns({
|
||||
title,
|
||||
children,
|
||||
required,
|
||||
className,
|
||||
}: SectionColumnsType) {
|
||||
return (
|
||||
<div className="grid grid-cols-1 items-center gap-x-12 gap-y-2 py-2">
|
||||
<h2 className="col-span-4 text-base font-semibold leading-none">
|
||||
{title}
|
||||
</h2>
|
||||
<div className="grid w-full grid-cols-1 items-center gap-x-12 gap-y-2 py-2">
|
||||
<div className="col-span-4 flex items-start gap-0.5 text-sm leading-none">
|
||||
<h2 className="font-semibold">{title}</h2>
|
||||
{required && (
|
||||
<span className="text-neutral-500 dark:text-neutral-300">*</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="col-span-6">{children}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "../ui/select";
|
||||
import { Switch } from "../ui/switch";
|
||||
|
||||
export type FormData = CreateDNSRecord;
|
||||
|
||||
@@ -155,13 +156,13 @@ export function RecordForm({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mb-4 rounded-lg border border-dashed shadow-sm animate-in fade-in-50">
|
||||
<div>
|
||||
<div className="rounded-t-lg bg-muted px-4 py-2 text-lg font-semibold">
|
||||
{type === "add" ? "Create" : "Edit"} record
|
||||
</div>
|
||||
<form className="p-4" onSubmit={onSubmit}>
|
||||
<div className="items-center justify-start gap-4 md:flex">
|
||||
<FormSectionColumns title="Type">
|
||||
<FormSectionColumns title="Type" required>
|
||||
<Select
|
||||
onValueChange={(value: RecordType) => {
|
||||
setValue("type", value);
|
||||
@@ -183,12 +184,12 @@ export function RecordForm({
|
||||
</Select>
|
||||
<p className="p-1 text-[13px] text-muted-foreground">Required.</p>
|
||||
</FormSectionColumns>
|
||||
<FormSectionColumns title="Name">
|
||||
<FormSectionColumns title="Name" required>
|
||||
<div className="flex w-full items-center gap-2">
|
||||
<Label className="sr-only" htmlFor="name">
|
||||
Name (required)
|
||||
</Label>
|
||||
<div className="relative">
|
||||
<div className="relative w-full">
|
||||
<Input
|
||||
id="name"
|
||||
className="flex-1 shadow-inner"
|
||||
@@ -215,6 +216,32 @@ export function RecordForm({
|
||||
)}
|
||||
</div>
|
||||
</FormSectionColumns>
|
||||
</div>
|
||||
|
||||
<div className="items-center justify-start gap-4 md:flex">
|
||||
<FormSectionColumns title="TTL" required>
|
||||
<Select
|
||||
onValueChange={(value: string) => {
|
||||
setValue("ttl", Number(value));
|
||||
}}
|
||||
name="ttl"
|
||||
defaultValue={String(initData?.ttl || 1)}
|
||||
>
|
||||
<SelectTrigger className="w-full shadow-inner">
|
||||
<SelectValue placeholder="Select a time" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{TTL_ENUMS.map((ttl) => (
|
||||
<SelectItem key={ttl.value} value={ttl.value}>
|
||||
{ttl.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="p-1 text-[13px] text-muted-foreground">
|
||||
Optional. Time To Live.
|
||||
</p>
|
||||
</FormSectionColumns>
|
||||
<FormSectionColumns
|
||||
title={
|
||||
currentRecordType === "CNAME"
|
||||
@@ -254,29 +281,6 @@ export function RecordForm({
|
||||
</div>
|
||||
|
||||
<div className="items-center justify-start gap-4 md:flex">
|
||||
<FormSectionColumns title="TTL">
|
||||
<Select
|
||||
onValueChange={(value: string) => {
|
||||
setValue("ttl", Number(value));
|
||||
}}
|
||||
name="ttl"
|
||||
defaultValue={String(initData?.ttl || 1)}
|
||||
>
|
||||
<SelectTrigger className="w-full shadow-inner">
|
||||
<SelectValue placeholder="Select a time" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{TTL_ENUMS.map((ttl) => (
|
||||
<SelectItem key={ttl.value} value={ttl.value}>
|
||||
{ttl.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="p-1 text-[13px] text-muted-foreground">
|
||||
Optional. Time To Live.
|
||||
</p>
|
||||
</FormSectionColumns>
|
||||
<FormSectionColumns title="Comment">
|
||||
<div className="flex items-center gap-2">
|
||||
<Label className="sr-only" htmlFor="comment">
|
||||
@@ -293,15 +297,17 @@ export function RecordForm({
|
||||
Enter your comment here (up to 100 characters)
|
||||
</p>
|
||||
</FormSectionColumns>
|
||||
{/* <FormSectionColumns title="Proxy">
|
||||
<div className="flex w-full items-center gap-2">
|
||||
<Label className="sr-only" htmlFor="proxy">
|
||||
Proxy
|
||||
</Label>
|
||||
<Switch id="proxied" {...register("proxied")} />
|
||||
</div>
|
||||
<p className="p-1 text-[13px] text-muted-foreground">Proxy status</p>
|
||||
</FormSectionColumns> */}
|
||||
<FormSectionColumns title="Proxy">
|
||||
<div className="flex w-full items-center gap-2">
|
||||
<Label className="sr-only" htmlFor="proxy">
|
||||
Proxy
|
||||
</Label>
|
||||
<Switch id="proxied" {...register("proxied")} />
|
||||
</div>
|
||||
<p className="p-1 text-[13px] text-muted-foreground">
|
||||
Proxy status
|
||||
</p>
|
||||
</FormSectionColumns>
|
||||
</div>
|
||||
|
||||
{/* Action buttons */}
|
||||
|
||||
@@ -154,13 +154,13 @@ export function UrlForm({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mb-4 rounded-lg border border-dashed shadow-sm animate-in fade-in-50">
|
||||
<div>
|
||||
<div className="rounded-t-lg bg-muted px-4 py-2 text-lg font-semibold">
|
||||
{type === "add" ? "Create" : "Edit"} short link
|
||||
</div>
|
||||
<form className="p-4" onSubmit={onSubmit}>
|
||||
<div className="items-center justify-start gap-4 md:flex">
|
||||
<FormSectionColumns title="Target URL">
|
||||
<FormSectionColumns title="Target URL" required>
|
||||
<div className="flex w-full items-center gap-2">
|
||||
<Label className="sr-only" htmlFor="target">
|
||||
Target
|
||||
@@ -184,13 +184,13 @@ export function UrlForm({
|
||||
)}
|
||||
</div>
|
||||
</FormSectionColumns>
|
||||
<FormSectionColumns title="Short Link">
|
||||
<FormSectionColumns title="Short Link" required>
|
||||
<div className="flex w-full items-center gap-2">
|
||||
<Label className="sr-only" htmlFor="url">
|
||||
Url
|
||||
</Label>
|
||||
|
||||
<div className="relative flex items-center">
|
||||
<div className="relative flex w-full items-center">
|
||||
<Select
|
||||
onValueChange={(value: string) => {
|
||||
setValue("prefix", value);
|
||||
@@ -210,12 +210,9 @@ export function UrlForm({
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{/* <span className="pointer-events-none absolute left-20 whitespace-nowrap text-sm text-gray-400">
|
||||
/s/
|
||||
</span> */}
|
||||
<Input
|
||||
id="url"
|
||||
className="w-3/5 flex-1 rounded-none pl-[8px] shadow-inner"
|
||||
className="w-full rounded-none pl-[8px] shadow-inner"
|
||||
size={20}
|
||||
{...register("url")}
|
||||
disabled={type === "edit"}
|
||||
@@ -276,7 +273,7 @@ export function UrlForm({
|
||||
)}
|
||||
</div>
|
||||
</FormSectionColumns>
|
||||
<FormSectionColumns title="Expiration">
|
||||
<FormSectionColumns title="Expiration" required>
|
||||
<Select
|
||||
onValueChange={(value: string) => {
|
||||
setValue("expiration", value);
|
||||
@@ -285,7 +282,7 @@ export function UrlForm({
|
||||
defaultValue={initData?.expiration || "-1"}
|
||||
>
|
||||
<SelectTrigger className="w-full shadow-inner">
|
||||
<SelectValue placeholder="Select a time" />
|
||||
<SelectValue placeholder="Select a time range" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{EXPIRATION_ENUMS.map((e) => (
|
||||
|
||||
+127
-125
@@ -111,142 +111,144 @@ export function UserForm({
|
||||
};
|
||||
|
||||
return (
|
||||
<form
|
||||
className="mb-4 rounded-lg border border-dashed p-4 shadow-sm animate-in fade-in-50"
|
||||
onSubmit={onSubmit}
|
||||
>
|
||||
<div className="items-center justify-start gap-4 md:flex">
|
||||
<FormSectionColumns title="Email">
|
||||
<div className="flex w-full items-center gap-2">
|
||||
<Label className="sr-only" htmlFor="email">
|
||||
Email
|
||||
<div>
|
||||
<div className="rounded-t-lg bg-muted px-4 py-2 text-lg font-semibold">
|
||||
Edit User
|
||||
</div>
|
||||
<form className="max-w-2xl p-4" onSubmit={onSubmit}>
|
||||
<div className="items-center justify-start gap-4 md:flex">
|
||||
<FormSectionColumns title="Email" required>
|
||||
<div className="flex w-full items-center gap-2">
|
||||
<Label className="sr-only" htmlFor="email">
|
||||
Email
|
||||
</Label>
|
||||
<Input
|
||||
id="email"
|
||||
className="flex-1 shadow-inner"
|
||||
size={32}
|
||||
disabled
|
||||
{...register("email")}
|
||||
/>
|
||||
</div>
|
||||
{errors?.email && (
|
||||
<p className="p-1 text-[13px] text-red-600">
|
||||
{errors.email.message}
|
||||
</p>
|
||||
)}
|
||||
</FormSectionColumns>
|
||||
<FormSectionColumns title="Name">
|
||||
<Label className="sr-only" htmlFor="name">
|
||||
Name
|
||||
</Label>
|
||||
<Input
|
||||
id="email"
|
||||
id="name"
|
||||
className="flex-1 shadow-inner"
|
||||
size={32}
|
||||
disabled
|
||||
{...register("email")}
|
||||
size={20}
|
||||
{...register("name")}
|
||||
/>
|
||||
</div>
|
||||
{errors?.email && (
|
||||
<p className="p-1 text-[13px] text-red-600">
|
||||
{errors.email.message}
|
||||
</p>
|
||||
)}
|
||||
</FormSectionColumns>
|
||||
<FormSectionColumns title="Name">
|
||||
<Label className="sr-only" htmlFor="name">
|
||||
Name
|
||||
</Label>
|
||||
<Input
|
||||
id="name"
|
||||
className="flex-1 shadow-inner"
|
||||
size={20}
|
||||
{...register("name")}
|
||||
/>
|
||||
{errors?.name && (
|
||||
<p className="p-1 text-[13px] text-red-600">
|
||||
{errors.name.message}
|
||||
</p>
|
||||
)}
|
||||
</FormSectionColumns>
|
||||
<FormSectionColumns title="Active">
|
||||
<div className="flex w-full items-center gap-2">
|
||||
<Label className="sr-only" htmlFor="active">
|
||||
Active
|
||||
</Label>
|
||||
<Switch
|
||||
id="active"
|
||||
{...register("active")}
|
||||
defaultChecked={initData?.active === 1}
|
||||
onCheckedChange={(value) => setValue("active", value ? 1 : 0)}
|
||||
/>
|
||||
</div>
|
||||
</FormSectionColumns>
|
||||
</div>
|
||||
{errors?.name && (
|
||||
<p className="p-1 text-[13px] text-red-600">
|
||||
{errors.name.message}
|
||||
</p>
|
||||
)}
|
||||
</FormSectionColumns>
|
||||
</div>
|
||||
|
||||
<div className="items-center justify-start gap-4 md:flex">
|
||||
<FormSectionColumns title="Role">
|
||||
<Select
|
||||
onValueChange={(value: string) => {
|
||||
setValue("role", value as UserRole);
|
||||
}}
|
||||
name="role"
|
||||
defaultValue={`${initData?.role}` || "USER"}
|
||||
>
|
||||
<SelectTrigger className="w-full shadow-inner">
|
||||
<SelectValue placeholder="Select a role" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{ROLE_ENUM.map((role) => (
|
||||
<SelectItem key={role.value} value={role.value}>
|
||||
{role.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormSectionColumns>
|
||||
<FormSectionColumns title="Plan">
|
||||
<Select
|
||||
onValueChange={(value: string) => {
|
||||
setValue("team", value);
|
||||
}}
|
||||
name="team"
|
||||
defaultValue={`${initData?.team}` || "free"}
|
||||
>
|
||||
<SelectTrigger className="w-full shadow-inner">
|
||||
<SelectValue placeholder="Select a plan" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{["free", "premium", "business"].map((role) => (
|
||||
<SelectItem key={role} value={role}>
|
||||
{role}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormSectionColumns>
|
||||
</div>
|
||||
<div className="items-center justify-start gap-4 md:flex">
|
||||
<FormSectionColumns title="Role">
|
||||
<Select
|
||||
onValueChange={(value: string) => {
|
||||
setValue("role", value as UserRole);
|
||||
}}
|
||||
name="role"
|
||||
defaultValue={`${initData?.role}` || "USER"}
|
||||
>
|
||||
<SelectTrigger className="w-full shadow-inner">
|
||||
<SelectValue placeholder="Select a role" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{ROLE_ENUM.map((role) => (
|
||||
<SelectItem key={role.value} value={role.value}>
|
||||
{role.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormSectionColumns>
|
||||
<FormSectionColumns title="Plan">
|
||||
<Select
|
||||
onValueChange={(value: string) => {
|
||||
setValue("team", value);
|
||||
}}
|
||||
name="team"
|
||||
defaultValue={`${initData?.team}` || "free"}
|
||||
>
|
||||
<SelectTrigger className="w-full shadow-inner">
|
||||
<SelectValue placeholder="Select a plan" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{["free", "premium", "business"].map((role) => (
|
||||
<SelectItem key={role} value={role}>
|
||||
{role}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormSectionColumns>
|
||||
<FormSectionColumns title="Active">
|
||||
<div className="flex w-full items-center gap-2">
|
||||
<Label className="sr-only" htmlFor="active">
|
||||
Active
|
||||
</Label>
|
||||
<Switch
|
||||
id="active"
|
||||
{...register("active")}
|
||||
defaultChecked={initData?.active === 1}
|
||||
onCheckedChange={(value) => setValue("active", value ? 1 : 0)}
|
||||
/>
|
||||
</div>
|
||||
</FormSectionColumns>
|
||||
</div>
|
||||
|
||||
{/* Action buttons */}
|
||||
<div className="mt-3 flex justify-end gap-3">
|
||||
{type === "edit" && (
|
||||
{/* Action buttons */}
|
||||
<div className="mt-3 flex justify-end gap-3">
|
||||
{type === "edit" && (
|
||||
<Button
|
||||
type="button"
|
||||
variant="destructive"
|
||||
className="mr-auto w-[80px] px-0"
|
||||
onClick={() => handleDelete()}
|
||||
disabled={isDeleting}
|
||||
>
|
||||
{isDeleting ? (
|
||||
<Icons.spinner className="size-4 animate-spin" />
|
||||
) : (
|
||||
<p>Delete</p>
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
type="button"
|
||||
variant="destructive"
|
||||
className="mr-auto w-[80px] px-0"
|
||||
onClick={() => handleDelete()}
|
||||
disabled={isDeleting}
|
||||
type="reset"
|
||||
variant="outline"
|
||||
className="w-[80px] px-0"
|
||||
onClick={() => setShowForm(false)}
|
||||
>
|
||||
{isDeleting ? (
|
||||
Cancle
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="blue"
|
||||
disabled={isPending}
|
||||
className="w-[80px] shrink-0 px-0"
|
||||
>
|
||||
{isPending ? (
|
||||
<Icons.spinner className="size-4 animate-spin" />
|
||||
) : (
|
||||
<p>Delete</p>
|
||||
<p>{type === "edit" ? "Update" : "Save"}</p>
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
type="reset"
|
||||
variant="outline"
|
||||
className="w-[80px] px-0"
|
||||
onClick={() => setShowForm(false)}
|
||||
>
|
||||
Cancle
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="blue"
|
||||
disabled={isPending}
|
||||
className="w-[80px] shrink-0 px-0"
|
||||
>
|
||||
{isPending ? (
|
||||
<Icons.spinner className="size-4 animate-spin" />
|
||||
) : (
|
||||
<p>{type === "edit" ? "Update" : "Save"}</p>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ export default async function HeroLanding() {
|
||||
</h1>
|
||||
|
||||
<p className="max-w-2xl text-balance text-muted-foreground sm:text-lg">
|
||||
Link shortening, domain hosting, email receivers or senders <br /> and
|
||||
screenshot api, everything you need to build better.
|
||||
Link shortening, domain hosting, email manager and <br />
|
||||
open api, everything you need to build better.
|
||||
</p>
|
||||
|
||||
<div className="flex items-center justify-center gap-4">
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user