db create fix
This commit is contained in:
parent
809fe18090
commit
b15cac7ed0
6 changed files with 1853 additions and 7262 deletions
8982
package-lock.json
generated
8982
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -14,6 +14,7 @@
|
||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
"@radix-ui/react-label": "^2.0.2",
|
"@radix-ui/react-label": "^2.0.2",
|
||||||
"@radix-ui/react-navigation-menu": "^1.1.4",
|
"@radix-ui/react-navigation-menu": "^1.1.4",
|
||||||
|
"@radix-ui/react-popover": "^1.0.7",
|
||||||
"@radix-ui/react-select": "^2.0.0",
|
"@radix-ui/react-select": "^2.0.0",
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-slot": "^1.0.2",
|
||||||
"@tanstack/react-table": "^8.12.0",
|
"@tanstack/react-table": "^8.12.0",
|
||||||
|
|
|
@ -1,19 +1,24 @@
|
||||||
"use server";
|
"use server";
|
||||||
import { z } from "zod";
|
import { initConnection } from "@/components/db-utils";
|
||||||
import { formSchema } from "./page";
|
import { formSchema } from "./schema";
|
||||||
|
|
||||||
export async function querydb(values: z.infer<typeof formSchema>) {
|
export async function querydb(prevState: any, formData: FormData) {
|
||||||
// let db = await initConnection();
|
const values = formSchema.safeParse({ url: formData.get("url") })
|
||||||
// let url = await db.query(`
|
if (!values.success) {
|
||||||
// create url:[rand::string(8)] CONTENT {
|
return { error: values.error };
|
||||||
// long_url: string::replace($long_url, "http://", "https://"),
|
}
|
||||||
// clicks: 0,
|
const long_url = values.data.url;
|
||||||
// date_added: time::now(),
|
|
||||||
// date_accessed: <future> { time::now() }
|
|
||||||
// } return id[0];
|
|
||||||
// `, { long_url: values.url });
|
|
||||||
let url = "test";
|
|
||||||
|
|
||||||
console.log(values.url, url)
|
let db = await initConnection();
|
||||||
return url;
|
let url = await db.query(`
|
||||||
|
create url:[rand::string(8)] CONTENT {
|
||||||
|
long_url: string::replace($long_url, "http://", "https://"),
|
||||||
|
clicks: 0,
|
||||||
|
date_added: time::now(),
|
||||||
|
date_accessed: <future> { time::now() }
|
||||||
|
} return id[0];
|
||||||
|
`, { long_url: long_url });
|
||||||
|
|
||||||
|
console.log(long_url, url)
|
||||||
|
return { url: url };
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
|
CardFooter,
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle
|
CardTitle
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
|
@ -15,24 +16,33 @@ import {
|
||||||
FormMessage
|
FormMessage
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/components/ui/popover";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { useFormState } from "react-dom";
|
import { CopyIcon } from "@radix-ui/react-icons";
|
||||||
|
import { useFormState, useFormStatus } from "react-dom";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { querydb } from "./db";
|
import { querydb } from "./db";
|
||||||
|
import { formSchema } from "./schema";
|
||||||
|
|
||||||
export const formSchema = z.object({
|
|
||||||
url: z.string().min(4,
|
|
||||||
{ message: "The URL must be at least 4 characters long" }
|
|
||||||
).max(100
|
|
||||||
, { message: "The URL must be at most 100 characters long" }),
|
|
||||||
});
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
message: null,
|
url: null,
|
||||||
|
}
|
||||||
|
|
||||||
|
function SubmitButton() {
|
||||||
|
const { pending } = useFormStatus();
|
||||||
|
return (
|
||||||
|
<Button type="submit">Submit</Button>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const [state, formAction] = useFormState(querydb, initialState);
|
const [state, formAction] = useFormState(querydb, initialState);
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
const form = useForm<z.infer<typeof formSchema>>({
|
||||||
resolver: zodResolver(formSchema),
|
resolver: zodResolver(formSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
|
@ -40,12 +50,22 @@ export default function Home() {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const handleCopyUrl = () => {
|
||||||
|
if (state && state.url) {
|
||||||
|
navigator.clipboard.writeText(state.url)
|
||||||
|
.catch(err => {
|
||||||
|
console.error('Failed to copy URL to clipboard:', err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="hidden items-start justify-center gap-6 rounded-lg p-8 md:grid lg:grid-cols-1 xl:grid-cols-1">
|
<div className="hidden items-start justify-center gap-6 rounded-lg p-8 md:grid lg:grid-cols-3 xl:grid-cols-3">
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>Create a Shortened URL</CardTitle>
|
<CardTitle>Create a Shortened URL</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form action={form.handleSubmit(querydb)} className="space-y-8">
|
<form action={form.handleSubmit(querydb)} className="space-y-8">
|
||||||
|
@ -62,11 +82,27 @@ export default function Home() {
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Button type="submit">Submit</Button>
|
<SubmitButton />
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|
||||||
|
<CardFooter>
|
||||||
|
{state && state.url && (
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger>
|
||||||
|
<Button onClick={handleCopyUrl}>
|
||||||
|
<CopyIcon className="mr-2 h-4 w-4" /> Copy Url
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent>
|
||||||
|
<p className="text-lg">
|
||||||
|
Url added to clipboard
|
||||||
|
</p>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
)}
|
||||||
|
</CardFooter>
|
||||||
</Card>
|
</Card>
|
||||||
</div >
|
</div >
|
||||||
);
|
);
|
||||||
|
|
8
src/app/create/schema.tsx
Normal file
8
src/app/create/schema.tsx
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
export const formSchema = z.object({
|
||||||
|
url: z.string().min(4,
|
||||||
|
{ message: "The URL must be at least 4 characters long" }
|
||||||
|
).max(100
|
||||||
|
, { message: "The URL must be at most 100 characters long" }),
|
||||||
|
});
|
31
src/components/ui/popover.tsx
Normal file
31
src/components/ui/popover.tsx
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import * as React from "react"
|
||||||
|
import * as PopoverPrimitive from "@radix-ui/react-popover"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Popover = PopoverPrimitive.Root
|
||||||
|
|
||||||
|
const PopoverTrigger = PopoverPrimitive.Trigger
|
||||||
|
|
||||||
|
const PopoverAnchor = PopoverPrimitive.Anchor
|
||||||
|
|
||||||
|
const PopoverContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof PopoverPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
|
||||||
|
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
|
||||||
|
<PopoverPrimitive.Portal>
|
||||||
|
<PopoverPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
align={align}
|
||||||
|
sideOffset={sideOffset}
|
||||||
|
className={cn(
|
||||||
|
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</PopoverPrimitive.Portal>
|
||||||
|
))
|
||||||
|
PopoverContent.displayName = PopoverPrimitive.Content.displayName
|
||||||
|
|
||||||
|
export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }
|
Loading…
Add table
Add a link
Reference in a new issue