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