1- import type { MetaFunction } from "@remix-run/node" ;
1+ import type { LoaderFunctionArgs , MetaFunction } from "@remix-run/node" ;
2+ import { json , Link as RemixLink , useLoaderData , useRouteLoaderData } from "@remix-run/react" ;
3+ import { cookieStorage } from "~/services/session.server" ;
4+ import { User } from "~/types/User" ;
5+ import { AlertWidget } from "~/components/AlertWidget" ;
6+ import type { AlertMessage } from "~/types/AlertMessage" ;
7+ import { db } from "~/db/connection.server" ;
8+ import { regex_link } from "~/db/schema" ;
9+ import { LinkTagUrlBuilder } from "~/util/LinkTagUrlBuilder" ;
10+ import { TagList } from "~/components/TagList" ;
11+ import { authenticator } from "~/services/auth.server" ;
12+ import { PiLockKey } from "react-icons/pi" ;
13+ import { AdminIcon } from "~/components/AdminIcon" ;
214
315export const meta : MetaFunction = ( ) => {
416 return [
@@ -7,13 +19,77 @@ export const meta: MetaFunction = () => {
719 ] ;
820} ;
921
22+ export async function loader ( { request } : LoaderFunctionArgs ) {
23+ // Retrieves the current session from the incoming request's Cookie header
24+ const session = await cookieStorage . getSession ( request . headers . get ( "Cookie" ) ) ;
25+
26+ // Retrieve the session value set in the previous request
27+ const message = session . get ( "message" ) ;
28+ console . log ( "loader message" , JSON . stringify ( message ) ) ;
29+
30+ const links = await db . select ( ) . from ( regex_link ) ;
31+
32+ const user = authenticator . isAuthenticated ( request ) ;
33+
34+
35+ // Commit the session and return the message
36+ return json (
37+ { links, message, user } ,
38+ {
39+ headers : {
40+ "Set-Cookie" : await cookieStorage . commitSession ( session ) ,
41+ } ,
42+ }
43+ ) ;
44+ }
1045export default function Index ( ) {
46+ const user = useRouteLoaderData < User | null > ( "root" ) ;
47+ const data = useLoaderData < typeof loader > ( ) ;
48+
49+ console . log ( "func message" , JSON . stringify ( data ) ) ;
50+
51+ const message = data . message as AlertMessage | undefined ;
52+
53+ const links = data . links ;
54+
1155 return (
1256 < >
13- < h1 className = "py-2" > Links</ h1 >
14- < div className = "alert alert-info" >
15- Coming soon...
57+ < div className = "d-flex justify-content-between align-items-center" >
58+ < h1 className = "py-2" > Links</ h1 >
59+ { user && user . isAdmin ?
60+ < div >
61+ < RemixLink to = "/links/add.html" className = "btn btn-primary mx-1" > < AdminIcon /> Add</ RemixLink >
62+ < RemixLink to = "/links/import.html" className = "btn btn-primary mx-1" > < AdminIcon /> Import</ RemixLink >
63+ </ div >
64+ : null }
1665 </ div >
66+ { message ? < AlertWidget alert = { message } /> : null }
67+ { links . length == 0 ? < div className = "alert alert-warning" > No links found</ div > :
68+ < table className = "table table-striped table-hover" >
69+ < thead className = "d-none" >
70+ < tr >
71+ < th > Description</ th >
72+ < th > Tags</ th >
73+ </ tr >
74+ </ thead >
75+ < tbody >
76+ { links . map ( link => (
77+ < tr key = { link . rxl_id } >
78+ < td > < a href = { link . rxl_url } > { link . rxl_title } </ a > </ td >
79+ < td className = "text-end" >
80+ < TagList tags = { link . rxl_tags } urlBuilder = { LinkTagUrlBuilder } />
81+ { user && user . isAdmin ?
82+ < >
83+ < RemixLink to = { `/links/edit.html?rxl_id=${ link . rxl_id } ` } className = "btn btn-sm btn-secondary mx-1" > < AdminIcon /> Edit</ RemixLink >
84+ < RemixLink to = { `/links/delete.html?rxl_id=${ link . rxl_id } ` } className = "btn btn-sm btn-secondary mx-1" > < AdminIcon /> Delete</ RemixLink >
85+ </ >
86+ : null }
87+ </ td >
88+ </ tr >
89+ ) ) }
90+ </ tbody >
91+ </ table >
92+ }
1793 </ >
1894 ) ;
1995}
0 commit comments