1
+ import type { HeadersFunction , LoaderFunctionArgs , ActionFunctionArgs } from "@remix-run/node" ;
2
+ import { json } from '@remix-run/node' ;
3
+ import { MetaFunction , useLoaderData , isRouteErrorResponse , useRouteError } from "@remix-run/react" ;
4
+ import type { ShouldRevalidateFunction } from "@remix-run/react" ;
5
+ import { Button } from "#app/components/ui/button" ;
6
+ import { Card } from "#app/components/ui/card" ;
7
+ import { Avatar , AvatarFallback , AvatarImage } from "#app/components/ui/avatar"
8
+
9
+
10
+ interface VCActivityType {
11
+ id : number
12
+ activeFlag : string
13
+ status : string
14
+ playerFirstName : string
15
+ playerLastName : string
16
+ playerPosition : string
17
+ playerWeightLbs : number
18
+ playerHeightInches : number
19
+ playerEligibilityYear : string
20
+ }
21
+
22
+ export const meta : MetaFunction = ( { data } ) => [
23
+
24
+ { title : data ? 'lucasb.dev | BucNation' : 'Error | lucasb.dev' } ,
25
+ {
26
+ name : 'description' ,
27
+ content : `A page dedicated to East Tennessee State Basketball` ,
28
+ } ,
29
+
30
+ ] ;
31
+
32
+ export const headers : HeadersFunction = ( ) => (
33
+ {
34
+ // your headers here
35
+ }
36
+ ) ;
37
+
38
+ export const loader = async ( { request } : LoaderFunctionArgs ) => {
39
+ const reqHeaders = {
40
+ Pb : "MV7mOE51zp9clOm7" ,
41
+ "User-Agent" :
42
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" ,
43
+ } ;
44
+
45
+ const response = await fetch ( "https://api.verbalcommits.com/vc/schools/chart/etsu" , {
46
+ headers : reqHeaders ,
47
+ } ) ;
48
+ const data = await response . json ( ) as VCActivityType [ ] ;
49
+ const filteredResults = data . filter ( ( d ) => d . status === 'ENROLLMENT' ) ;
50
+
51
+ return json ( { roster : filteredResults } ) ;
52
+ } ;
53
+
54
+ export const action = async ( { request } : ActionFunctionArgs ) => {
55
+ return null ;
56
+ } ;
57
+
58
+ const heightFromInches = ( total : number ) => {
59
+ const feet = Math . floor ( total / 12 ) ;
60
+ const inches = total % 12 ;
61
+ return `${ feet } '${ inches } "` ;
62
+ }
63
+
64
+ export default function BucNation ( ) {
65
+ const data = useLoaderData < typeof loader > ( ) ;
66
+
67
+ /* const games = [
68
+ {
69
+ opponent: "Los Angeles Lakers",
70
+ date: "October 18, 2023",
71
+ score: {
72
+ home: 112,
73
+ away: 104,
74
+ },
75
+ image: "/opponent1.jpg",
76
+ }]; */
77
+
78
+ return (
79
+ < div className = "w-full max-w-6xl mx-auto py-8 px-4 md:px-6" >
80
+ < header className = "flex items-center justify-between mb-8" >
81
+ < div className = "flex items-center gap-4" >
82
+ < img src = "https://upload.wikimedia.org/wikipedia/commons/thumb/a/ab/East_Tennessee_State_Buccaneers_logo.svg/400px-East_Tennessee_State_Buccaneers_logo.svg.png" alt = "ETSU Team Logo" width = { 40 } height = { 40 } className = "w-10 h-10" />
83
+ < h1 className = "text-2xl font-bold" > East Tennessee State < span className = "text-yellow-500" > Buccaneers</ span > Basketball</ h1 >
84
+ </ div >
85
+ < div className = "flex items-center gap-4" >
86
+ < Button variant = "outline" size = "sm" >
87
+ Schedule
88
+ </ Button >
89
+ < Button variant = "outline" size = "sm" >
90
+ Stats
91
+ </ Button >
92
+ </ div >
93
+ </ header >
94
+ < div className = "grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6" >
95
+ { data . roster . map ( ( r ) => {
96
+ return (
97
+ < Card className = "p-4" key = { r . id } >
98
+ < div className = "flex items-center gap-4" >
99
+ < Avatar >
100
+ < AvatarImage src = "/placeholder.svg" alt = { `${ r . playerFirstName } ${ r . playerLastName } ` } />
101
+ < AvatarFallback > { r . playerFirstName [ 0 ] . toUpperCase ( ) } { r . playerLastName [ 0 ] . toUpperCase ( ) } </ AvatarFallback >
102
+ </ Avatar >
103
+ < div >
104
+ < h3 className = "text-lg font-semibold" > { r . playerFirstName } { r . playerLastName } </ h3 >
105
+ < p className = "text-gray-500 dark:text-gray-400" > { r . playerPosition } | { heightFromInches ( r . playerHeightInches ) } | { r . playerWeightLbs } Lbs</ p >
106
+ </ div >
107
+ </ div >
108
+ </ Card >
109
+ )
110
+ } ) }
111
+ </ div >
112
+ { /*<h2 className="my-8 text-xl font-bold">Schedule</h2>
113
+ <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
114
+ {games.map((game, index) => (
115
+ <Card key={index} className="p-4">
116
+ <div className="flex flex-col gap-4">
117
+ <div className="flex items-center justify-between">
118
+ <div className="flex items-center gap-4">
119
+ <img
120
+ src="/placeholder.svg"
121
+ alt={`Opponent ${index + 1}`}
122
+ width={40}
123
+ height={40}
124
+ className="w-10 h-10 rounded-full"
125
+ />
126
+ <div>
127
+ <h3 className="text-lg font-semibold">{game.opponent}</h3>
128
+ <p className="text-gray-500 dark:text-gray-400">{game.date}</p>
129
+ </div>
130
+ </div>
131
+ <div className="flex items-center gap-2">
132
+ <div className="text-lg font-semibold">{game.score.home}</div>
133
+ <div className="text-lg font-semibold">{game.score.away}</div>
134
+ </div>
135
+ </div>
136
+ </div>
137
+ </Card>
138
+ ))}
139
+ </div>*/ }
140
+ </ div >
141
+ ) ;
142
+ }
143
+
144
+ export function ErrorBoundary ( ) {
145
+ const error = useRouteError ( ) ;
146
+ if ( isRouteErrorResponse ( error ) ) {
147
+ return < div />
148
+ }
149
+ return < div />
150
+ }
151
+
152
+ export const shouldRevalidate : ShouldRevalidateFunction = ( ) => {
153
+ return true ;
154
+ } ;
0 commit comments