diff --git a/README.md b/README.md index 59a8425..46fb4be 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## Example .env ``` # If not using docker, use 0.0.0.0:8000 -DB_PORT=surrealdb:8000 +DB_URL_PORT=surrealdb:8000 DB_USER=root DB_PASSWORD=root ``` diff --git a/package-lock.json b/package-lock.json index fab9901..0436252 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "react-dom": "^18", "react-hook-form": "^7.50.1", "surrealdb.js": "^0.11.0", - "swr": "^2.2.4", + "swr": "^2.2.5", "tailwind-merge": "^2.2.1", "tailwindcss-animate": "^1.0.7", "ws": "^8.16.0", @@ -35,7 +35,7 @@ "devDependencies": { "@types/node": "^20", "@types/prop-types": "^15.7.11", - "@types/react": "^18.2.55", + "@types/react": "^18.2.56", "@types/react-dom": "^18", "autoprefixer": "^10.4.17", "eslint": "^8", @@ -44,7 +44,7 @@ "prettier": "^3.2.5", "prettier-plugin-tailwindcss": "^0.5.11", "tailwindcss": "^3.4.1", - "typescript": "^5.3.3" + "typescript": "^5" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -1274,9 +1274,9 @@ "devOptional": true }, "node_modules/@types/react": { - "version": "18.2.55", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.55.tgz", - "integrity": "sha512-Y2Tz5P4yz23brwm2d7jNon39qoAtMMmalOQv6+fEFt1mT+FcM3D841wDpoUvFXhaYenuROCy3FZYqdTjM7qVyA==", + "version": "18.2.56", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.56.tgz", + "integrity": "sha512-NpwHDMkS/EFZF2dONFQHgkPRwhvgq/OAvIaGQzxGSBmaeR++kTg6njr15Vatz0/2VcCEwJQFi6Jf4Q0qBu0rLA==", "devOptional": true, "dependencies": { "@types/prop-types": "*", @@ -1888,9 +1888,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001587", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz", - "integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==", + "version": "1.0.30001588", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz", + "integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==", "funding": [ { "type": "opencollective", @@ -2176,9 +2176,9 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/electron-to-chromium": { - "version": "1.4.671", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.671.tgz", - "integrity": "sha512-UUlE+/rWbydmp+FW8xlnnTA5WNA0ZZd2XL8CuMS72rh+k4y1f8+z6yk3UQhEwqHQWj6IBdL78DwWOdGMvYfQyA==", + "version": "1.4.673", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz", + "integrity": "sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==", "dev": true }, "node_modules/emoji-regex": { @@ -5291,9 +5291,9 @@ } }, "node_modules/swr": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/swr/-/swr-2.2.4.tgz", - "integrity": "sha512-njiZ/4RiIhoOlAaLYDqwz5qH/KZXVilRLvomrx83HjzCWTfa+InyfAjv05PSFxnmLzZkNO9ZfvgoqzAaEI4sGQ==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.2.5.tgz", + "integrity": "sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==", "dependencies": { "client-only": "^0.0.1", "use-sync-external-store": "^1.2.0" @@ -5494,16 +5494,17 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.1.tgz", + "integrity": "sha512-tcqKMrTRXjqvHN9S3553NPCaGL0VPgFI92lXszmrE8DMhiDPLBYLlvo8Uu4WZAAX/aGqp/T1sbA4ph8EWjDF9Q==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.7", "for-each": "^0.3.3", + "gopd": "^1.0.1", "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" diff --git a/package.json b/package.json index 892d6a9..04a6a1c 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "react-dom": "^18", "react-hook-form": "^7.50.1", "surrealdb.js": "^0.11.0", - "swr": "^2.2.4", + "swr": "^2.2.5", "tailwind-merge": "^2.2.1", "tailwindcss-animate": "^1.0.7", "ws": "^8.16.0", @@ -36,7 +36,7 @@ "devDependencies": { "@types/node": "^20", "@types/prop-types": "^15.7.11", - "@types/react": "^18.2.55", + "@types/react": "^18.2.56", "@types/react-dom": "^18", "autoprefixer": "^10.4.17", "eslint": "^8", diff --git a/src/app/[slug]/db.tsx b/src/app/[slug]/db.tsx index bcb4db2..c3d6617 100644 --- a/src/app/[slug]/db.tsx +++ b/src/app/[slug]/db.tsx @@ -2,17 +2,17 @@ import { initConnection } from "@/components/db-utils"; export async function querydb(slug: string) { - try { - let db = await initConnection(); - let long_url = await db.query(` + try { + let db = await initConnection(); + let long_url = await db.query(` update url:[$id] set clicks = clicks + 1 ; select * from url:[$id]; `, { id: slug }); - // @ts-ignore - long_url = long_url[0][0].long_url; - return long_url; - } catch (e) { - return; - } + // @ts-ignore + long_url = long_url[0][0].long_url; + return long_url; + } catch (e) { + return; + } } diff --git a/src/app/[slug]/page.tsx b/src/app/[slug]/page.tsx index 7b0f42a..0b4a5d1 100644 --- a/src/app/[slug]/page.tsx +++ b/src/app/[slug]/page.tsx @@ -2,18 +2,14 @@ import { notFound, redirect } from "next/navigation"; import { querydb } from "./db"; -// export default function Page({ params }: { params: { slug: string } }) { -// redirect(`https://${params.slug}`) -// } - export default async function Page({ params }: { params: { slug: string } }) { - if (params.slug == "favicon.ico") { - return; - } + if (params.slug == "favicon.ico") { + return; + } - let long_url = await querydb(params.slug); - if (long_url == undefined) { - return notFound(); - } - redirect(`https://${long_url}`); + let long_url = await querydb(params.slug); + if (long_url == undefined) { + return notFound(); + } + redirect(`https://${long_url}`); } diff --git a/src/app/create/create.tsx b/src/app/create/create.tsx index da6dad3..0391ce4 100644 --- a/src/app/create/create.tsx +++ b/src/app/create/create.tsx @@ -23,7 +23,7 @@ import { } from "@/components/ui/popover"; import { zodResolver } from "@hookform/resolvers/zod"; import { CopyIcon } from "@radix-ui/react-icons"; -import { useFormState, useFormStatus } from "react-dom"; +import { useFormState } from "react-dom"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { querydb } from "./db"; @@ -33,23 +33,16 @@ const initialState = { url: null, } -function SubmitButton() { - const { pending } = useFormStatus(); - return ( - - ); -} - export default function CreateCard() { // @ts-ignore - const [state, formAction] = useFormState(querydb, initialState); + let [state, formAction] = useFormState(querydb, initialState); const form = useForm>({ resolver: zodResolver(formSchema), defaultValues: { url: "", }, - }) + }); const handleCopyUrl = () => { if (state && state.url) { @@ -80,7 +73,7 @@ export default function CreateCard() {
{/* @ts-ignore */} - + )} /> -
- + + {state && state.url && ( diff --git a/src/app/create/db.tsx b/src/app/create/db.tsx index 102e47c..4a76e96 100644 --- a/src/app/create/db.tsx +++ b/src/app/create/db.tsx @@ -3,24 +3,30 @@ import { initConnection } from "@/components/db-utils"; import { formSchema } from "./schema"; export async function querydb(prevState: any, formData: FormData) { - const values = formSchema.safeParse(formData) - if (!values.success) { - return { error: values.error }; + try { + const values = formSchema.safeParse(formData) + if (!values.success) { + return { error: values.error }; + } + const long_url = values.data.url; + + let db = await initConnection(); + console.log(db); + let url = await db.query(` + create url:[rand::string(8)] CONTENT { + long_url: string::replace(string::replace($long_url, "https://", ""), "http://", ""), + clicks: 0, + date_added: time::now(), + date_accessed: { time::now() } + } return id[0]; + `, { long_url: long_url }); + + // @ts-ignore + url = url[0][0].id; + console.log("URL", url); + + return { url: url }; + } catch (e) { + return; } - const long_url = values.data.url; - - let db = await initConnection(); - let url = await db.query(` - create url:[rand::string(8)] CONTENT { - long_url: string::replace(string::replace($long_url, "https://", ""), "http://", ""), - clicks: 0, - date_added: time::now(), - date_accessed: { time::now() } - } return id[0]; - `, { long_url: long_url }); - - // @ts-ignore - url = url[0][0].id; - - return { url: url }; } diff --git a/src/app/create/schema.tsx b/src/app/create/schema.tsx index 44f7611..4e099f9 100644 --- a/src/app/create/schema.tsx +++ b/src/app/create/schema.tsx @@ -1,8 +1,9 @@ +"use server"; 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" }), -}); \ No newline at end of file + 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" }), +}); diff --git a/src/app/global-error.tsx b/src/app/global-error.tsx index 6489b83..602bff1 100644 --- a/src/app/global-error.tsx +++ b/src/app/global-error.tsx @@ -1,23 +1,23 @@ "use client"; import CardGrid from "@/components/card-grid"; import { - Card, - CardHeader, - CardTitle + Card, + CardHeader, + CardTitle } from "@/components/ui/card"; export default function GlobalError({ - error, + error, }: { - error: Error & { digest?: string } + error: Error & { digest?: string } }) { - return ( - - - - Error - - - - ); + return ( + + + + Error + + + + ); } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 3d262c9..7077f7a 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,4 +1,4 @@ -import Nav from "@/components/Nav"; +import Nav from "@/components/nav"; import { ThemeProvider } from "@/components/theme-provider"; import type { Metadata } from "next"; import { Roboto_Mono } from "next/font/google"; diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx index 0cd7cd6..8db8326 100644 --- a/src/app/not-found.tsx +++ b/src/app/not-found.tsx @@ -1,23 +1,23 @@ "use client"; import CardGrid from "@/components/card-grid"; import { - Card, - CardHeader, - CardTitle + Card, + CardHeader, + CardTitle } from "@/components/ui/card"; export default function GlobalError({ - error, + error, }: { - error: Error & { digest?: string } + error: Error & { digest?: string } }) { - return ( - - - - 404 - Not Found - - - - ); + return ( + + + + 404 - Not Found + + + + ); } diff --git a/src/app/stats/db.tsx b/src/app/stats/db.tsx index 77e7a2a..6379895 100644 --- a/src/app/stats/db.tsx +++ b/src/app/stats/db.tsx @@ -9,7 +9,6 @@ export async function querydb() { order by clicks desc limit 50; `); - return stats; } catch (e) { return; diff --git a/src/app/stats/loading.tsx b/src/app/stats/loading.tsx index edb2a52..30e8fe6 100644 --- a/src/app/stats/loading.tsx +++ b/src/app/stats/loading.tsx @@ -1,23 +1,23 @@ "use client"; import CardGrid from "@/components/card-grid"; import { - Card, - CardHeader, - CardTitle + Card, + CardHeader, + CardTitle } from "@/components/ui/card"; export default function GlobalError({ - error, + error, }: { - error: Error & { digest?: string } + error: Error & { digest?: string } }) { - return ( - - - - Loading... - - - - ); + return ( + + + + Loading... + + + + ); } diff --git a/src/app/stats/page.tsx b/src/app/stats/page.tsx index 243c9ca..590ad57 100644 --- a/src/app/stats/page.tsx +++ b/src/app/stats/page.tsx @@ -1,3 +1,4 @@ +"use server"; import CardGrid from "@/components/card-grid"; import { Card } from "@/components/ui/card"; import { columns } from "./columns"; @@ -5,37 +6,37 @@ import { DataTable } from "./data-table"; import { querydb } from "./db"; export default async function StatsPage() { - let data = await querydb(); - // @ts-ignore - data = data[0]; + let data = await querydb(); + // @ts-ignore + data = data[0]; - if (data !== undefined) { - const formatDate = (dateString: string | number | Date) => { - const date = new Date(dateString); - const day = String(date.getDate()).padStart(2, '0'); - const month = String(date.getMonth() + 1).padStart(2, '0'); - const year = String(date.getFullYear()).slice(-2); - return `${month}/${day}/${year}`; - }; + if (data !== undefined) { + const formatDate = (dateString: string | number | Date) => { + const date = new Date(dateString); + const day = String(date.getDate()).padStart(2, '0'); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const year = String(date.getFullYear()).slice(-2); + return `${month}/${day}/${year}`; + }; - data = data.map(item => ({ - // @ts-ignore - ...item, - // @ts-ignore - date_accessed: formatDate(item.date_accessed), - // @ts-ignore - date_added: formatDate(item.date_added), - // @ts-ignore - id: item.id.replace(/^url:\['(.*)'\]$/, '$1') - })); - } + data = data.map(item => ({ + // @ts-ignore + ...item, + // @ts-ignore + date_accessed: formatDate(item.date_accessed), + // @ts-ignore + date_added: formatDate(item.date_added), + // @ts-ignore + id: item.id.replace(/^url:\['(.*)'\]$/, '$1') + })); + } - return ( - - - {/* @ts-ignore */} - - - - ); + return ( + + + {/* @ts-ignore */} + + + + ); } diff --git a/src/components/Nav.tsx b/src/components/Nav.tsx index 7641b08..89f9f59 100644 --- a/src/components/Nav.tsx +++ b/src/components/Nav.tsx @@ -1,7 +1,8 @@ +"use server"; import DarkModeToggle from "@/components/dark-mode-toggle"; import Link from "next/link"; -export default function Nav() { +export default async function Nav() { return (