1
1
import { invariantResponse } from '@epic-web/invariant'
2
- import { type MetaFunction , type LoaderFunctionArgs } from '@remix-run/node'
2
+ import { type LoaderFunctionArgs , type MetaFunction } from '@remix-run/node'
3
3
import {
4
4
Link ,
5
5
json ,
6
6
useLoaderData ,
7
7
useMatches ,
8
- useNavigate ,
9
8
useOutlet ,
10
9
} from '@remix-run/react'
11
10
import { useEffect , useRef } from 'react'
12
11
import { GeneralErrorBoundary } from '#app/components/error-boundary.js'
13
- import { floatingToolbarClassName } from '#app/components/floating-toolbar.js'
14
- import { Button } from '#app/components/ui/button.js'
15
12
import { Icon } from '#app/components/ui/icon.js'
16
- import {
17
- Tabs ,
18
- TabsContent ,
19
- TabsList ,
20
- TabsTrigger ,
21
- } from '#app/components/ui/tabs.js'
22
13
import { SimpleTooltip } from '#app/components/ui/tooltip.js'
23
14
import { requireUserId } from '#app/utils/auth.server.js'
24
15
import { getHints } from '#app/utils/client-hints.js'
@@ -68,39 +59,24 @@ export default function RecipientRoute() {
68
59
const data = useLoaderData < typeof loader > ( )
69
60
const firstLinkRef = useRef < HTMLAnchorElement | null > ( null )
70
61
const outlet = useOutlet ( )
71
- const navigate = useNavigate ( )
72
62
const matches = useMatches ( )
73
63
const lastMatch = matches [ matches . length - 1 ]
74
64
const idPortion = lastMatch ?. id . split ( '.' ) ?. at ( - 1 ) ?? '.'
75
- const tab = idPortion === 'index' ? '.' : idPortion
65
+ const currentPath = idPortion === 'index' ? '.' : idPortion
76
66
77
67
useEffect ( ( ) => {
78
68
firstLinkRef . current ?. focus ( )
79
69
} , [ data . recipient . id ] )
80
70
81
71
useEffect ( ( ) => {
82
- if ( tab === '.' ) firstLinkRef . current ?. focus ( )
83
- } , [ tab ] )
84
-
85
- // The links are just for progressive enhancement. We disable their default
86
- function handleLinkClick ( event : React . MouseEvent < HTMLAnchorElement > ) {
87
- if ( event . metaKey ) {
88
- // TODO: this doesn't seem to be preventing the tab from switching properly
89
- event . stopPropagation ( )
90
- } else {
91
- event . preventDefault ( )
92
- }
93
- }
72
+ if ( currentPath === '.' ) firstLinkRef . current ?. focus ( )
73
+ } , [ currentPath ] )
94
74
95
75
return (
96
- < Tabs
97
- defaultValue = "."
98
- onValueChange = { newValue => navigate ( newValue ) }
99
- value = { tab }
100
- >
101
- < div className = "absolute inset-0 flex flex-col px-10" >
102
- < h2 className = "mb-2 h-36 pt-12 text-h2 lg:mb-6" >
103
- { data . recipient . name }
76
+ < div className = "px-10 py-6" >
77
+ < div className = "flex flex-col justify-between gap-4 md:flex-row" >
78
+ < div className = "mb-2 pt-12 lg:mb-6" >
79
+ < h2 className = "text-h2" > { data . recipient . name } </ h2 >
104
80
< small className = "flex gap-1 text-sm font-normal text-secondary-foreground" >
105
81
{ data . recipient . phoneNumber }
106
82
{ data . optedOut ? (
@@ -122,52 +98,54 @@ export default function RecipientRoute() {
122
98
</ button >
123
99
</ SimpleTooltip >
124
100
</ small >
125
- </ h2 >
126
- < div className = "absolute left-3 right-3 top-[8.7rem] rounded-lg bg-muted/80 px-2 py-2 shadow-xl shadow-accent backdrop-blur-sm" >
127
- < TabsList className = "grid w-full grid-cols-3 bg-transparent" >
128
- < TabsTrigger value = "." asChild >
129
- < Link
130
- to = "."
131
- preventScrollReset
132
- onClick = { handleLinkClick }
133
- ref = { firstLinkRef }
134
- >
135
- Upcoming
136
- </ Link >
137
- </ TabsTrigger >
138
- < TabsTrigger value = "new" asChild >
139
- < Link to = "new" preventScrollReset onClick = { handleLinkClick } >
140
- New
141
- </ Link >
142
- </ TabsTrigger >
143
- < TabsTrigger value = "past" asChild >
144
- < Link to = "past" preventScrollReset onClick = { handleLinkClick } >
145
- Past
146
- </ Link >
147
- </ TabsTrigger >
148
- </ TabsList >
149
- </ div >
150
- < div className = "overflow-y-auto px-4 py-24" >
151
- < TabsContent value = "." > { outlet } </ TabsContent >
152
- < TabsContent value = "new" > { outlet } </ TabsContent >
153
- < TabsContent value = "past" > { outlet } </ TabsContent >
154
- </ div >
155
- < div className = { floatingToolbarClassName } >
156
- < div className = "grid flex-1 grid-cols-2 justify-end gap-2 min-[525px]:flex md:gap-4" >
157
- < Button
158
- asChild
159
- className = "min-[525px]:max-md:aspect-square min-[525px]:max-md:px-0"
160
- >
161
- < Link to = "edit" >
162
- < Icon name = "pencil-1" className = "scale-125 max-md:scale-150" >
163
- < span className = "max-md:hidden" > Edit</ span >
164
- </ Icon >
165
- </ Link >
166
- </ Button >
167
- </ div >
168
101
</ div >
102
+ < nav >
103
+ < Link
104
+ to = "."
105
+ className = { `flex items-center gap-2 rounded-md px-3 py-2 transition-colors ${
106
+ currentPath === '.'
107
+ ? 'bg-accent text-accent-foreground'
108
+ : 'hover:bg-accent/50'
109
+ } `}
110
+ ref = { firstLinkRef }
111
+ >
112
+ < Icon name = "clock" > Upcoming</ Icon >
113
+ </ Link >
114
+ < Link
115
+ to = "new"
116
+ className = { `flex items-center gap-2 rounded-md px-3 py-2 transition-colors ${
117
+ currentPath === 'new'
118
+ ? 'bg-accent text-accent-foreground'
119
+ : 'hover:bg-accent/50'
120
+ } `}
121
+ >
122
+ < Icon name = "plus" > New</ Icon >
123
+ </ Link >
124
+ < Link
125
+ to = "past"
126
+ className = { `flex items-center gap-2 rounded-md px-3 py-2 transition-colors ${
127
+ currentPath === 'past'
128
+ ? 'bg-accent text-accent-foreground'
129
+ : 'hover:bg-accent/50'
130
+ } `}
131
+ >
132
+ < Icon name = "chevron-down" > Past</ Icon >
133
+ </ Link >
134
+
135
+ < Link
136
+ to = "edit"
137
+ className = { `flex items-center gap-2 rounded-md px-3 py-2 transition-colors ${
138
+ currentPath === 'past'
139
+ ? 'bg-accent text-accent-foreground'
140
+ : 'hover:bg-accent/50'
141
+ } `}
142
+ >
143
+ < Icon name = "pencil-1" > Edit</ Icon >
144
+ </ Link >
145
+ </ nav >
169
146
</ div >
170
- </ Tabs >
147
+ < div className = "overflow-y-auto px-4 py-6" > { outlet } </ div >
148
+ </ div >
171
149
)
172
150
}
173
151
0 commit comments