Updated forms
This commit is contained in:
@@ -23,9 +23,9 @@ function AdvancedUrlForm() {
|
|||||||
resolver: zodResolver(advancedUrlSchema),
|
resolver: zodResolver(advancedUrlSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
url: "",
|
url: "",
|
||||||
slug: "",
|
slug: null,
|
||||||
title: "",
|
title: null,
|
||||||
maxVisits: 0,
|
maxVisits: null,
|
||||||
expDate: undefined,
|
expDate: undefined,
|
||||||
forwardQueryParams: true,
|
forwardQueryParams: true,
|
||||||
crawlable: false
|
crawlable: false
|
||||||
@@ -71,7 +71,7 @@ function AdvancedUrlForm() {
|
|||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Custom Slug (Optional)</FormLabel>
|
<FormLabel>Custom Slug (Optional)</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input placeholder="my-custom-link" {...field} />
|
<Input placeholder="my-custom-link" {...field} value={field.value ?? ""} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormDescription>
|
<FormDescription>
|
||||||
A unique identifier for your short link (max 10 characters).
|
A unique identifier for your short link (max 10 characters).
|
||||||
@@ -133,7 +133,7 @@ function AdvancedUrlForm() {
|
|||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Title (Optional)</FormLabel>
|
<FormLabel>Title (Optional)</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input placeholder="My Link Title" {...field} />
|
<Input placeholder="My Link Title" {...field} value={field.value ?? ""} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormDescription>
|
<FormDescription>
|
||||||
A descriptive title for your link (max 100 characters).
|
A descriptive title for your link (max 100 characters).
|
||||||
@@ -153,7 +153,13 @@ function AdvancedUrlForm() {
|
|||||||
type="number"
|
type="number"
|
||||||
placeholder="100"
|
placeholder="100"
|
||||||
{...field}
|
{...field}
|
||||||
onChange={(e) => field.onChange(e.target.value ? parseInt(e.target.value) : undefined)}
|
value={field.value ?? ""}
|
||||||
|
onChange={e =>
|
||||||
|
field.onChange(
|
||||||
|
isNaN(e.target.valueAsNumber)
|
||||||
|
? null
|
||||||
|
: e.target.valueAsNumber
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormDescription>
|
<FormDescription>
|
||||||
@@ -205,11 +211,11 @@ function EditUrlForm({ data }: { data: typeof urls.$inferSelect }) {
|
|||||||
defaultValues: {
|
defaultValues: {
|
||||||
url: data.url,
|
url: data.url,
|
||||||
slug: data.slug,
|
slug: data.slug,
|
||||||
title: data.title || "",
|
title: data.title || null,
|
||||||
maxVisits: data.maxVisits || undefined,
|
maxVisits: data.maxVisits || null,
|
||||||
expDate: data.expDate || undefined,
|
expDate: data.expDate || undefined,
|
||||||
forwardQueryParams: data.forwardQueryParams || undefined,
|
forwardQueryParams: data.forwardQueryParams,
|
||||||
crawlable: data.crawlable || undefined
|
crawlable: data.crawlable
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -318,7 +324,7 @@ function EditUrlForm({ data }: { data: typeof urls.$inferSelect }) {
|
|||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Title</FormLabel>
|
<FormLabel>Title</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input placeholder="My Link Title" {...field} />
|
<Input placeholder="My Link Title" {...field} value={field.value ?? ""} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormDescription>
|
<FormDescription>
|
||||||
A descriptive title for your link (max 100 characters).
|
A descriptive title for your link (max 100 characters).
|
||||||
@@ -338,8 +344,13 @@ function EditUrlForm({ data }: { data: typeof urls.$inferSelect }) {
|
|||||||
type="number"
|
type="number"
|
||||||
placeholder="100"
|
placeholder="100"
|
||||||
{...field}
|
{...field}
|
||||||
value={field.value || ""}
|
value={field.value ?? ""}
|
||||||
onChange={(e) => field.onChange(e.target.value ? parseInt(e.target.value) : undefined)}
|
onChange={e =>
|
||||||
|
field.onChange(
|
||||||
|
isNaN(e.target.valueAsNumber)
|
||||||
|
? null
|
||||||
|
: e.target.valueAsNumber
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormDescription>
|
<FormDescription>
|
||||||
|
|||||||
@@ -12,15 +12,11 @@ import { cn } from "@/lib/utils"
|
|||||||
interface DatePickerProps {
|
interface DatePickerProps {
|
||||||
value?: Date
|
value?: Date
|
||||||
onChange?: (date: Date | undefined) => void
|
onChange?: (date: Date | undefined) => void
|
||||||
disabled?: boolean
|
|
||||||
className?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DatePicker({
|
export function DatePicker({
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange
|
||||||
disabled = false,
|
|
||||||
className
|
|
||||||
}: DatePickerProps) {
|
}: DatePickerProps) {
|
||||||
return (
|
return (
|
||||||
<Popover>
|
<Popover>
|
||||||
@@ -29,10 +25,8 @@ export function DatePicker({
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
className={cn(
|
className={cn(
|
||||||
"w-full justify-start text-left font-normal",
|
"w-full justify-start text-left font-normal",
|
||||||
!value && "text-muted-foreground",
|
!value && "text-muted-foreground"
|
||||||
className
|
|
||||||
)}
|
)}
|
||||||
disabled={disabled}
|
|
||||||
>
|
>
|
||||||
<CalendarIcon className="mr-2 h-4 w-4" />
|
<CalendarIcon className="mr-2 h-4 w-4" />
|
||||||
{value ? format(value, "PPP") : <span>Pick a date</span>}
|
{value ? format(value, "PPP") : <span>Pick a date</span>}
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ export const urls = pgTable("urls", {
|
|||||||
title: varchar("title"),
|
title: varchar("title"),
|
||||||
maxVisits: integer("max_visits"),
|
maxVisits: integer("max_visits"),
|
||||||
expDate: timestamp("exp_date", { withTimezone: true }),
|
expDate: timestamp("exp_date", { withTimezone: true }),
|
||||||
forwardQueryParams: boolean("forward_query_params").default(true),
|
forwardQueryParams: boolean("forward_query_params").notNull().default(true),
|
||||||
crawlable: boolean("crawable").default(false),
|
crawlable: boolean("crawable").notNull().default(false),
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt
|
updatedAt
|
||||||
}, (t) => {
|
}, (t) => {
|
||||||
|
|||||||
@@ -7,20 +7,20 @@ export const urlFormSchema = z.object({
|
|||||||
|
|
||||||
export const advancedUrlSchema = z.object({
|
export const advancedUrlSchema = z.object({
|
||||||
url: z.string().url("Please enter a valid URL"),
|
url: z.string().url("Please enter a valid URL"),
|
||||||
slug: z.string().max(10, "Slug must be 10 characters or less"),
|
slug: z.string().max(10, "Slug must be 10 characters or less").transform(v => v.trim() === "" ? null : v).nullable(),
|
||||||
title: z.string().max(100, "Title must be 100 characters or less"),
|
title: z.string().max(100, "Title must be 100 characters or less").transform(v => v.trim() === "" ? null : v).nullable(),
|
||||||
maxVisits: z.number().int(),
|
maxVisits: z.number().int().positive().nullable(),
|
||||||
expDate: z.date().optional(),
|
expDate: z.date().optional(),
|
||||||
forwardQueryParams: z.boolean(),
|
forwardQueryParams: z.boolean(),
|
||||||
crawlable: z.boolean(),
|
crawlable: z.boolean(),
|
||||||
})
|
})
|
||||||
|
|
||||||
export const editUrlSchema = z.object({
|
export const editUrlSchema = z.object({
|
||||||
url: z.string().url("Please enter a valid URL").optional(),
|
url: z.string().url("Please enter a valid URL"),
|
||||||
slug: z.string().max(10, "Slug must be 10 characters or less").optional(),
|
slug: z.string().max(10, "Slug must be 10 characters or less"),
|
||||||
title: z.string().max(100, "Title must be 100 characters or less").optional(),
|
title: z.string().max(100, "Title must be 100 characters or less").transform(v => v.trim() === "" ? null : v).nullable(),
|
||||||
maxVisits: z.number().int().optional(),
|
maxVisits: z.number().int().positive().nullable(),
|
||||||
expDate: z.date().optional(),
|
expDate: z.date().optional(),
|
||||||
forwardQueryParams: z.boolean().optional(),
|
forwardQueryParams: z.boolean(),
|
||||||
crawlable: z.boolean().optional(),
|
crawlable: z.boolean(),
|
||||||
})
|
})
|
||||||
Reference in New Issue
Block a user