diff --git a/elysia/src/index.ts b/elysia/src/index.ts index ea3943d..4e45484 100644 --- a/elysia/src/index.ts +++ b/elysia/src/index.ts @@ -3,6 +3,7 @@ import { nanoid } from 'nanoid' import { db } from './database' import { createLinkSchema } from './zodSchema' import { cors } from '@elysiajs/cors' +import { jsonArrayFrom } from 'kysely/helpers/postgres' const app = new Elysia().use(cors()) @@ -67,6 +68,30 @@ app.get( } ) +app.get('/link/:shortenerCode', async ({ params: { shortenerCode } }) => { + const shorteners = await db + .selectFrom('shortener') + .select((shortener) => [ + 'id', + 'code', + 'link', + 'created_at', + jsonArrayFrom( + shortener + .selectFrom('visitor') + .select([ + 'visitor.created_at as visited_at', + 'visitor.country', + ]) + .whereRef('visitor.shortener_id', '=', 'shortener.id') + ).as('visitors'), + ]) + .where('code', '=', shortenerCode) + .execute() + + return { shorteners } +}) + app.listen(3000) console.log( diff --git a/react-frontend/src/App.tsx b/react-frontend/src/App.tsx index 45bbef3..53861fd 100644 --- a/react-frontend/src/App.tsx +++ b/react-frontend/src/App.tsx @@ -21,13 +21,22 @@ import { TableHeader, TableRow, } from '@/components/ui/table' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Toaster } from '@/components/ui/toaster' import { useToast } from '@/components/ui/use-toast' -import { Copy, Loader2 } from 'lucide-react' +import { Copy, Loader2, MoreHorizontal, Settings } from 'lucide-react' import { useEffect, useState } from 'react' +import { useNavigate } from 'react-router-dom' const backend_url = import.meta.env.VITE_BACKEND_URL ?? 'http://192.168.100.40:3000' @@ -167,6 +176,7 @@ const ShortenerTable = ({ description: `Copied ${backend_url + '/' + code} To Clipboard`, }) } + const navigate = useNavigate() return ( @@ -184,6 +194,7 @@ const ShortenerTable = ({ Link Shortener + @@ -201,6 +212,36 @@ const ShortenerTable = ({ + + + + + + + + Actions + + + { + navigate( + '/dashboard/' + + shortener.code + ) + }}> + + View Details + + + {' '} + )) ) : ( diff --git a/react-frontend/src/main.tsx b/react-frontend/src/main.tsx index 4279aac..dd9f1fd 100644 --- a/react-frontend/src/main.tsx +++ b/react-frontend/src/main.tsx @@ -3,6 +3,7 @@ import ReactDOM from 'react-dom/client' import App from './App.tsx' import './index.css' import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom' +import Dashboard from './pages/dashboard.tsx' ReactDOM.createRoot(document.getElementById('root')!).render( @@ -17,6 +18,10 @@ ReactDOM.createRoot(document.getElementById('root')!).render( index element={} /> + } + /> ([]) + const [isLoading, setIsLoading] = useState(false) + const { shortenerId } = useParams() + + const getShorteners = async () => { + setIsLoading(true) + const response = await fetch(backend_url + '/link/' + shortenerId, { + method: 'GET', + }) + + const data = (await response.json()).shorteners as Shortener[] + console.log(data) + + setShorteners(data) + setIsLoading(false) + } + + useEffect(() => { + if (!shorteners.length) { + getShorteners() + } + }, []) + + return ( + + + + ) +}