1+ import type { LoaderFunctionArgs , MetaFunction } from "@remix-run/node" ;
2+ import { json , Link as RemixLink , useLoaderData , useParams , useRouteLoaderData } from "@remix-run/react" ;
3+ import { desc , sql } from "drizzle-orm" ;
4+
5+ import { cookieStorage } from "~/services/session.server" ;
6+ import { User } from "~/types/User" ;
7+ import { AlertWidget } from "~/components/AlertWidget" ;
8+ import type { AlertMessage } from "~/types/AlertMessage" ;
9+ import { dborm } from "~/db/connection.server" ;
10+ import { regex_link } from "~/db/schema" ;
11+ import { authenticator } from "~/services/auth.server" ;
12+ import { AdminIcon } from "~/components/AdminIcon" ;
13+ import LinksTable from "~/components/LinksTable" ;
14+ import { PiArrowFatUpBold , PiCaretLeftBold , PiCaretRightBold } from "react-icons/pi" ;
15+
16+ export const meta : MetaFunction = ( { params } ) => {
17+ return [
18+ { title : `Links Archive for ${ params . year } - Regex Zone` } ,
19+ ] ;
20+ } ;
21+
22+ const MIN_YEAR = 2007 ;
23+
24+ export async function loader ( { request, params } : LoaderFunctionArgs ) {
25+ // Retrieves the current session from the incoming request's Cookie header
26+ const session = await cookieStorage . getSession ( request . headers . get ( "Cookie" ) ) ;
27+
28+ // Retrieve the session value set in the previous request
29+ const message = session . get ( "message" ) ;
30+ console . log ( "loader message" , JSON . stringify ( message ) ) ;
31+
32+ if ( ! params || ! params . year || ! / ^ 2 \d { 3 } $ / . test ( params . year ) ) {
33+ throw new Error ( "Invalid year" ) ;
34+ }
35+
36+ const links = await dborm . select ( )
37+ . from ( regex_link )
38+ . where ( sql `EXTRACT(YEAR FROM ${ regex_link . rxl_created_at } ) = ${ params . year } ` )
39+ . orderBy ( desc ( regex_link . rxl_created_at ) ) ;
40+
41+ const user = authenticator . isAuthenticated ( request ) ;
42+
43+
44+ // Commit the session and return the message
45+ return json (
46+ { links, message, user } ,
47+ {
48+ headers : {
49+ "Set-Cookie" : await cookieStorage . commitSession ( session ) ,
50+ } ,
51+ }
52+ ) ;
53+ }
54+ export default function Index ( ) {
55+ const params = useParams ( ) ;
56+ const user = useRouteLoaderData < User | null > ( "root" ) ;
57+ const data = useLoaderData < typeof loader > ( ) ;
58+
59+ const currentYear = new Date ( ) . getFullYear ( ) ;
60+ const year = parseInt ( params . year || currentYear . toString ( ) ) ;
61+
62+
63+ console . log ( "func message" , JSON . stringify ( data ) ) ;
64+
65+ const message = data . message as AlertMessage | undefined ;
66+
67+ const links = data . links as unknown as typeof regex_link . $inferSelect [ ] ;
68+
69+ return (
70+ < >
71+ < div className = "d-flex justify-content-between align-items-center" >
72+ < h1 className = "py-2" > Links Archive for { year } </ h1 >
73+ < div >
74+ { year > MIN_YEAR ? < RemixLink to = { `/links/archive/${ year - 1 } /` } className = "btn btn-primary mx-1" > < PiCaretLeftBold /> { year - 1 } </ RemixLink > : null }
75+ < RemixLink to = "/links/archive/" className = "btn btn-primary" > < PiArrowFatUpBold /> </ RemixLink >
76+ { year < currentYear ? < RemixLink to = { `/links/archive/${ year + 1 } /` } className = "btn btn-primary mx-1" > { year + 1 } < PiCaretRightBold /> </ RemixLink > : null }
77+ </ div >
78+ </ div >
79+ { message ? < AlertWidget alert = { message } /> : null }
80+ { links . length == 0
81+ ? < AlertWidget alert = { { type : "danger" , message : `No links for ${ year } ` } } />
82+ : < LinksTable currentUrl = { `/links/archive/${ year } /` } links = { links } isAdmin = { user ?. isAdmin } />
83+ }
84+ </ >
85+ ) ;
86+ }
0 commit comments