broken
This commit is contained in:
parent
c552d0dc8f
commit
f9afa2501d
20 changed files with 212 additions and 215 deletions
|
@ -1,7 +1,7 @@
|
||||||
## Example .env
|
## Example .env
|
||||||
```
|
```
|
||||||
# If not using docker, use 0.0.0.0:8000
|
# If not using docker, use 0.0.0.0:8000
|
||||||
DB_PORT=surrealdb:8000
|
DB_URL_PORT=surrealdb:8000
|
||||||
DB_USER=root
|
DB_USER=root
|
||||||
DB_PASSWORD=root
|
DB_PASSWORD=root
|
||||||
```
|
```
|
||||||
|
|
43
package-lock.json
generated
43
package-lock.json
generated
|
@ -26,7 +26,7 @@
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"react-hook-form": "^7.50.1",
|
"react-hook-form": "^7.50.1",
|
||||||
"surrealdb.js": "^0.11.0",
|
"surrealdb.js": "^0.11.0",
|
||||||
"swr": "^2.2.4",
|
"swr": "^2.2.5",
|
||||||
"tailwind-merge": "^2.2.1",
|
"tailwind-merge": "^2.2.1",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"ws": "^8.16.0",
|
"ws": "^8.16.0",
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/prop-types": "^15.7.11",
|
"@types/prop-types": "^15.7.11",
|
||||||
"@types/react": "^18.2.55",
|
"@types/react": "^18.2.56",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
"autoprefixer": "^10.4.17",
|
"autoprefixer": "^10.4.17",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"prettier-plugin-tailwindcss": "^0.5.11",
|
"prettier-plugin-tailwindcss": "^0.5.11",
|
||||||
"tailwindcss": "^3.4.1",
|
"tailwindcss": "^3.4.1",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@aashutoshrathi/word-wrap": {
|
"node_modules/@aashutoshrathi/word-wrap": {
|
||||||
|
@ -1274,9 +1274,9 @@
|
||||||
"devOptional": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "18.2.55",
|
"version": "18.2.56",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.55.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.56.tgz",
|
||||||
"integrity": "sha512-Y2Tz5P4yz23brwm2d7jNon39qoAtMMmalOQv6+fEFt1mT+FcM3D841wDpoUvFXhaYenuROCy3FZYqdTjM7qVyA==",
|
"integrity": "sha512-NpwHDMkS/EFZF2dONFQHgkPRwhvgq/OAvIaGQzxGSBmaeR++kTg6njr15Vatz0/2VcCEwJQFi6Jf4Q0qBu0rLA==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
|
@ -1888,9 +1888,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001587",
|
"version": "1.0.30001588",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz",
|
||||||
"integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==",
|
"integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
|
@ -2176,9 +2176,9 @@
|
||||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
|
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.4.671",
|
"version": "1.4.673",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.671.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz",
|
||||||
"integrity": "sha512-UUlE+/rWbydmp+FW8xlnnTA5WNA0ZZd2XL8CuMS72rh+k4y1f8+z6yk3UQhEwqHQWj6IBdL78DwWOdGMvYfQyA==",
|
"integrity": "sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/emoji-regex": {
|
"node_modules/emoji-regex": {
|
||||||
|
@ -5291,9 +5291,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/swr": {
|
"node_modules/swr": {
|
||||||
"version": "2.2.4",
|
"version": "2.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/swr/-/swr-2.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/swr/-/swr-2.2.5.tgz",
|
||||||
"integrity": "sha512-njiZ/4RiIhoOlAaLYDqwz5qH/KZXVilRLvomrx83HjzCWTfa+InyfAjv05PSFxnmLzZkNO9ZfvgoqzAaEI4sGQ==",
|
"integrity": "sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"client-only": "^0.0.1",
|
"client-only": "^0.0.1",
|
||||||
"use-sync-external-store": "^1.2.0"
|
"use-sync-external-store": "^1.2.0"
|
||||||
|
@ -5494,16 +5494,17 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typed-array-byte-offset": {
|
"node_modules/typed-array-byte-offset": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.1.tgz",
|
||||||
"integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==",
|
"integrity": "sha512-tcqKMrTRXjqvHN9S3553NPCaGL0VPgFI92lXszmrE8DMhiDPLBYLlvo8Uu4WZAAX/aGqp/T1sbA4ph8EWjDF9Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"available-typed-arrays": "^1.0.5",
|
"available-typed-arrays": "^1.0.6",
|
||||||
"call-bind": "^1.0.2",
|
"call-bind": "^1.0.7",
|
||||||
"for-each": "^0.3.3",
|
"for-each": "^0.3.3",
|
||||||
|
"gopd": "^1.0.1",
|
||||||
"has-proto": "^1.0.1",
|
"has-proto": "^1.0.1",
|
||||||
"is-typed-array": "^1.1.10"
|
"is-typed-array": "^1.1.13"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"react-hook-form": "^7.50.1",
|
"react-hook-form": "^7.50.1",
|
||||||
"surrealdb.js": "^0.11.0",
|
"surrealdb.js": "^0.11.0",
|
||||||
"swr": "^2.2.4",
|
"swr": "^2.2.5",
|
||||||
"tailwind-merge": "^2.2.1",
|
"tailwind-merge": "^2.2.1",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"ws": "^8.16.0",
|
"ws": "^8.16.0",
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/prop-types": "^15.7.11",
|
"@types/prop-types": "^15.7.11",
|
||||||
"@types/react": "^18.2.55",
|
"@types/react": "^18.2.56",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
"autoprefixer": "^10.4.17",
|
"autoprefixer": "^10.4.17",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
|
|
|
@ -2,17 +2,17 @@
|
||||||
import { initConnection } from "@/components/db-utils";
|
import { initConnection } from "@/components/db-utils";
|
||||||
|
|
||||||
export async function querydb(slug: string) {
|
export async function querydb(slug: string) {
|
||||||
try {
|
try {
|
||||||
let db = await initConnection();
|
let db = await initConnection();
|
||||||
let long_url = await db.query(`
|
let long_url = await db.query(`
|
||||||
update url:[$id] set clicks = clicks + 1 ;
|
update url:[$id] set clicks = clicks + 1 ;
|
||||||
select * from url:[$id];
|
select * from url:[$id];
|
||||||
`, { id: slug });
|
`, { id: slug });
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
long_url = long_url[0][0].long_url;
|
long_url = long_url[0][0].long_url;
|
||||||
return long_url;
|
return long_url;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,14 @@
|
||||||
import { notFound, redirect } from "next/navigation";
|
import { notFound, redirect } from "next/navigation";
|
||||||
import { querydb } from "./db";
|
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 } }) {
|
export default async function Page({ params }: { params: { slug: string } }) {
|
||||||
if (params.slug == "favicon.ico") {
|
if (params.slug == "favicon.ico") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let long_url = await querydb(params.slug);
|
let long_url = await querydb(params.slug);
|
||||||
if (long_url == undefined) {
|
if (long_url == undefined) {
|
||||||
return notFound();
|
return notFound();
|
||||||
}
|
}
|
||||||
redirect(`https://${long_url}`);
|
redirect(`https://${long_url}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ import {
|
||||||
} from "@/components/ui/popover";
|
} from "@/components/ui/popover";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { CopyIcon } from "@radix-ui/react-icons";
|
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 { useForm } from "react-hook-form";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { querydb } from "./db";
|
import { querydb } from "./db";
|
||||||
|
@ -33,23 +33,16 @@ const initialState = {
|
||||||
url: null,
|
url: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
function SubmitButton() {
|
|
||||||
const { pending } = useFormStatus();
|
|
||||||
return (
|
|
||||||
<Button type="submit">Submit</Button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function CreateCard() {
|
export default function CreateCard() {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const [state, formAction] = useFormState(querydb, initialState);
|
let [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: {
|
||||||
url: "",
|
url: "",
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const handleCopyUrl = () => {
|
const handleCopyUrl = () => {
|
||||||
if (state && state.url) {
|
if (state && state.url) {
|
||||||
|
@ -80,7 +73,7 @@ export default function CreateCard() {
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
{/* @ts-ignore */}
|
{/* @ts-ignore */}
|
||||||
<form action={form.handleSubmit(formAction)} className="space-y-8">
|
<form id="url_form" action={form.handleSubmit(formAction)} className="space-y-8">
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="url"
|
name="url"
|
||||||
|
@ -94,12 +87,12 @@ export default function CreateCard() {
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<SubmitButton />
|
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|
||||||
<CardFooter>
|
<CardFooter className="flex flex-row gap-4">
|
||||||
|
<Button type="submit" form="url_form">Submit</Button>
|
||||||
{state && state.url && (
|
{state && state.url && (
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger>
|
<PopoverTrigger>
|
||||||
|
|
|
@ -3,24 +3,30 @@ import { initConnection } from "@/components/db-utils";
|
||||||
import { formSchema } from "./schema";
|
import { formSchema } from "./schema";
|
||||||
|
|
||||||
export async function querydb(prevState: any, formData: FormData) {
|
export async function querydb(prevState: any, formData: FormData) {
|
||||||
const values = formSchema.safeParse(formData)
|
try {
|
||||||
if (!values.success) {
|
const values = formSchema.safeParse(formData)
|
||||||
return { error: values.error };
|
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: <future> { 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: <future> { time::now() }
|
|
||||||
} return id[0];
|
|
||||||
`, { long_url: long_url });
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
url = url[0][0].id;
|
|
||||||
|
|
||||||
return { url: url };
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
"use server";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
export const formSchema = z.object({
|
export const formSchema = z.object({
|
||||||
url: z.string().min(4,
|
url: z.string().min(4,
|
||||||
{ message: "The URL must be at least 4 characters long" }
|
{ message: "The URL must be at least 4 characters long" }
|
||||||
).max(100
|
).max(100
|
||||||
, { message: "The URL must be at most 100 characters long" }),
|
, { message: "The URL must be at most 100 characters long" }),
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
"use client";
|
"use client";
|
||||||
import CardGrid from "@/components/card-grid";
|
import CardGrid from "@/components/card-grid";
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle
|
CardTitle
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
|
|
||||||
export default function GlobalError({
|
export default function GlobalError({
|
||||||
error,
|
error,
|
||||||
}: {
|
}: {
|
||||||
error: Error & { digest?: string }
|
error: Error & { digest?: string }
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<CardGrid max_rows={1}>
|
<CardGrid max_rows={1}>
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-center text-2xl text-red-400">Error</CardTitle>
|
<CardTitle className="text-center text-2xl text-red-400">Error</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
</Card>
|
</Card>
|
||||||
</CardGrid>
|
</CardGrid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Nav from "@/components/Nav";
|
import Nav from "@/components/nav";
|
||||||
import { ThemeProvider } from "@/components/theme-provider";
|
import { ThemeProvider } from "@/components/theme-provider";
|
||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { Roboto_Mono } from "next/font/google";
|
import { Roboto_Mono } from "next/font/google";
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
"use client";
|
"use client";
|
||||||
import CardGrid from "@/components/card-grid";
|
import CardGrid from "@/components/card-grid";
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle
|
CardTitle
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
|
|
||||||
export default function GlobalError({
|
export default function GlobalError({
|
||||||
error,
|
error,
|
||||||
}: {
|
}: {
|
||||||
error: Error & { digest?: string }
|
error: Error & { digest?: string }
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<CardGrid max_rows={1}>
|
<CardGrid max_rows={1}>
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-center text-2xl text-red-400">404 - Not Found</CardTitle>
|
<CardTitle className="text-center text-2xl text-red-400">404 - Not Found</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
</Card>
|
</Card>
|
||||||
</CardGrid>
|
</CardGrid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ export async function querydb() {
|
||||||
order by clicks desc
|
order by clicks desc
|
||||||
limit 50;
|
limit 50;
|
||||||
`);
|
`);
|
||||||
|
|
||||||
return stats;
|
return stats;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
"use client";
|
"use client";
|
||||||
import CardGrid from "@/components/card-grid";
|
import CardGrid from "@/components/card-grid";
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle
|
CardTitle
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
|
|
||||||
export default function GlobalError({
|
export default function GlobalError({
|
||||||
error,
|
error,
|
||||||
}: {
|
}: {
|
||||||
error: Error & { digest?: string }
|
error: Error & { digest?: string }
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<CardGrid max_rows={1}>
|
<CardGrid max_rows={1}>
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-1xl text-amber-400">Loading...</CardTitle>
|
<CardTitle className="text-1xl text-amber-400">Loading...</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
</Card>
|
</Card>
|
||||||
</CardGrid>
|
</CardGrid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
"use server";
|
||||||
import CardGrid from "@/components/card-grid";
|
import CardGrid from "@/components/card-grid";
|
||||||
import { Card } from "@/components/ui/card";
|
import { Card } from "@/components/ui/card";
|
||||||
import { columns } from "./columns";
|
import { columns } from "./columns";
|
||||||
|
@ -5,37 +6,37 @@ import { DataTable } from "./data-table";
|
||||||
import { querydb } from "./db";
|
import { querydb } from "./db";
|
||||||
|
|
||||||
export default async function StatsPage() {
|
export default async function StatsPage() {
|
||||||
let data = await querydb();
|
let data = await querydb();
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
data = data[0];
|
data = data[0];
|
||||||
|
|
||||||
if (data !== undefined) {
|
if (data !== undefined) {
|
||||||
const formatDate = (dateString: string | number | Date) => {
|
const formatDate = (dateString: string | number | Date) => {
|
||||||
const date = new Date(dateString);
|
const date = new Date(dateString);
|
||||||
const day = String(date.getDate()).padStart(2, '0');
|
const day = String(date.getDate()).padStart(2, '0');
|
||||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
const year = String(date.getFullYear()).slice(-2);
|
const year = String(date.getFullYear()).slice(-2);
|
||||||
return `${month}/${day}/${year}`;
|
return `${month}/${day}/${year}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
data = data.map(item => ({
|
data = data.map(item => ({
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
...item,
|
...item,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
date_accessed: formatDate(item.date_accessed),
|
date_accessed: formatDate(item.date_accessed),
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
date_added: formatDate(item.date_added),
|
date_added: formatDate(item.date_added),
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
id: item.id.replace(/^url:\['(.*)'\]$/, '$1')
|
id: item.id.replace(/^url:\['(.*)'\]$/, '$1')
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CardGrid max_rows={1}>
|
<CardGrid max_rows={1}>
|
||||||
<Card>
|
<Card>
|
||||||
{/* @ts-ignore */}
|
{/* @ts-ignore */}
|
||||||
<DataTable columns={columns} data={data} />
|
<DataTable columns={columns} data={data} />
|
||||||
</Card>
|
</Card>
|
||||||
</CardGrid>
|
</CardGrid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
"use server";
|
||||||
import DarkModeToggle from "@/components/dark-mode-toggle";
|
import DarkModeToggle from "@/components/dark-mode-toggle";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
export default function Nav() {
|
export default async function Nav() {
|
||||||
return (
|
return (
|
||||||
<nav className="relative flex flex-row place-items-center gap-4 p-2 px-4 font-medium border-b">
|
<nav className="relative flex flex-row place-items-center gap-4 p-2 px-4 font-medium border-b">
|
||||||
<div className="text-2xl">
|
<div className="text-2xl">
|
||||||
|
|
|
@ -1,43 +1,44 @@
|
||||||
|
"use client";
|
||||||
export default function CardGrid({
|
export default function CardGrid({
|
||||||
max_rows = 4,
|
max_rows = 4,
|
||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
max_rows?: number;
|
max_rows?: number;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
}) {
|
}) {
|
||||||
let baseClassName = `hidden items-start justify-center gap-6 rounded-lg p-8 md:grid`;
|
let baseClassName = `hidden items-start justify-center gap-6 rounded-lg p-8 md:grid`;
|
||||||
|
|
||||||
switch (max_rows) {
|
switch (max_rows) {
|
||||||
case 1:
|
case 1:
|
||||||
baseClassName += " md:grid-cols-1 ";
|
baseClassName += " md:grid-cols-1 ";
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
baseClassName += " md:grid-cols-1 lg:grid-cols-2 ";
|
baseClassName += " md:grid-cols-1 lg:grid-cols-2 ";
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
baseClassName += " md:grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 ";
|
baseClassName += " md:grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 ";
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
baseClassName += " md:grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 ";
|
baseClassName += " md:grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 ";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (className == undefined) {
|
if (className == undefined) {
|
||||||
className = baseClassName;
|
className = baseClassName;
|
||||||
} else {
|
} else {
|
||||||
className = baseClassName + className;
|
className = baseClassName + className;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`hidden items-start justify-center gap-6 rounded-lg p-8 md:grid " ${className}`}
|
className={`hidden items-start justify-center gap-6 rounded-lg p-8 md:grid " ${className}`}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use client";;
|
"use client";
|
||||||
import { MoonIcon, SunIcon } from "@radix-ui/react-icons";
|
import { MoonIcon, SunIcon } from "@radix-ui/react-icons";
|
||||||
import { useTheme } from "next-themes";
|
import { useTheme } from "next-themes";
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,21 @@
|
||||||
import { Surreal } from 'surrealdb.js';
|
"use server";
|
||||||
require('dotenv');
|
import "dotenv";
|
||||||
|
import { Surreal } from "surrealdb.js";
|
||||||
const db = new Surreal();
|
const db = new Surreal();
|
||||||
|
|
||||||
export async function initConnection(): Promise<Surreal> {
|
export async function initConnection(): Promise<Surreal> {
|
||||||
try {
|
try {
|
||||||
db.connect("http://" + process.env.DB_PORT + "/rpc", {
|
db.connect("http://" + process.env.DB_URL_PORT + "/rpc", {
|
||||||
namespace: 'url',
|
namespace: "url",
|
||||||
database: 'url',
|
database: "url",
|
||||||
|
auth: {
|
||||||
|
username: process.env.DB_USER || "root",
|
||||||
|
password: process.env.DB_PASSWORD || "root",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error("ERROR", e);
|
||||||
|
}
|
||||||
|
|
||||||
// @ts-ignore
|
return db;
|
||||||
auth: {
|
|
||||||
username: process.env.DB_USER,
|
|
||||||
password: process.env.DB_PASSWORD,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
console.error('ERROR', e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return db;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use client";;
|
"use client";
|
||||||
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
||||||
import { type ThemeProviderProps } from "next-themes/dist/types";
|
import { type ThemeProviderProps } from "next-themes/dist/types";
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
"next-env.d.ts",
|
"next-env.d.ts",
|
||||||
"**/*.ts",
|
"**/*.ts",
|
||||||
"**/*.tsx",
|
"**/*.tsx",
|
||||||
".next/types/**/*.ts"
|
".next/types/**/*.ts",
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules"
|
"node_modules"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue